[Glade-devel] reverse-libglade



--y0ulUmNC+osPPQO6
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi,

I've been thinking about the following for some time now, but I doubt
I'll really ever make any progress on it, so I thought I'd share my
plans and ask for feedback from the list.

I was interested in writing a 'reverse libglade', that is, a library
which would extract from a traditional GTK program a .glade file.

It would be loaded via LD_PRELOAD and have wrappers around all the main
GTK procedures. These would then construct in memory a structure
representing the UI (perhaps directly using the data structures from the
glade code, although I never got as far as looking at it for
suitability) before passing over control to the 'proper' GTK procedure
in each case.

Output and various options would be controlled via environment
variables.

I'm attaching proxy.c, which is a 10 minute attempt at generalising the
wrapper stuff, and the Makefile used to build and apply it, and a small
dummy gtk program which can be used in conjunction. This really doesn't
amount to much.

The point of such a tool would be to aid in refactoring old programs
which implemented their UI's directly in GTK. I also intended to use it
in order to convert a Java/SWT program to a native/GTK program.

Has anyone attempted anything similar, or is anyone interested in
persuing this work?

Many thanks,

-- 
Jon Dowland
http://jon.dowland.name/

--y0ulUmNC+osPPQO6
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=Makefile

#!/usr/bin/make -f

CC=gcc
FLAGS=`pkg-config --cflags --libs gtk+-2.0`

.SUFFIXES: .c .exe

steal-gtk.so.1.0.0: steal-gtk.o
        $(CC) -shared -Wl,-soname,steal-gtk.so.1 -o steal-gtk.so.1.0.0 steal-gtk.o

steal-gtk.o: proxy.c
        $(CC) -o steal-gtk.o -g -c -fPIC -Wall $(FLAGS) proxy.c

clean:
        for i in `ls -1 a.out *.exe core *.o *.so *.so.?.?.?`; do echo $1 && rm $1; done

.c.exe: $*.c
        $(CC) $*.c -o $*.exe $(FLAGS)

run: steal-gtk.so.1.0.0 hello2.exe
        LD_PRELOAD=./steal-gtk.so.1.0.0 ./hello2.exe

--y0ulUmNC+osPPQO6
Content-Type: text/x-csrc; charset=us-ascii
Content-Disposition: attachment; filename="proxy.c"

#define _GNU_SOURCE

#include <stdio.h>
#include <dlfcn.h>

#include <gtk/gtk.h>

/*
 * some functions left to wrap
 * all from libgtk2.0
 */
//void gtk_container_set_border_width(GtkContainer *container, guint border_width);
//void gtk_widget_show(GtkWidget *widget);
//void gtk_main(void);
//GtkWidget* gtk_button_new_with_label(const gchar *label);

/*
 * assigns function `name' to the function pointer `real_name'
 * returns `ret' on error (can be blank)
 */
#define resolve(name, ret) {                                         \
        if(0 == real_##name) real_##name = dlsym(RTLD_NEXT, #name);  \
        if(NULL != dlerror()) {                                      \
                fprintf(stderr, "can't get ahold of real "#name"\n");\
                return ret;                                          \
        }                                                            \
}

void gtk_init(int * argc, char ***argv) {
        static int (*real_gtk_init)(int *, char ***) = 0;
        resolve(gtk_init, );

        printf("this is the fake gtk_init here!\n");
        real_gtk_init(argc, argv);
}

GtkWidget* gtk_window_new(GtkWindowType type) {
        static GtkWidget* (*real_gtk_window_new)(GtkWindowType) = 0;
        resolve(gtk_window_new, NULL);

        printf("this is the fake gtk_window_new!\n");
        return real_gtk_window_new(type);
}

#undef resolve

--y0ulUmNC+osPPQO6
Content-Type: text/x-csrc; charset=us-ascii
Content-Disposition: attachment; filename="hello2.c"

#include <gtk/gtk.h>

static void callback(GtkWidget *widget, gpointer data) {
        g_print ("%s got pressed\n", (gchar *) data);
}

static gboolean delete_event(GtkWidget *widget,GdkEvent *event,gpointer data) {
        gtk_main_quit();
        return FALSE;
}

int main(int argc, char **argv) {
        GtkWidget *window;
        GtkWidget *button;
        GtkWidget *box;

        gtk_init(&argc, &argv);

        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        gtk_window_set_title(GTK_WINDOW(window), "Hello Buttons!");
        gtk_container_set_border_width(GTK_CONTAINER(window), 10);

        /*
         * X Events
         */
        g_signal_connect(G_OBJECT (window), "delete_event", 
                         G_CALLBACK(delete_event), NULL);


        box = gtk_hbox_new(FALSE, 0);
        gtk_container_add(GTK_CONTAINER(window), box);

        /* button 1 */
        button = gtk_button_new_with_label("button 1");
        g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(callback),
                        (gpointer) "button 1");
                                             /* expand,fill, padding */
        gtk_box_pack_start(GTK_BOX(box), button, TRUE, TRUE, 0);
        gtk_widget_show(button);

        /* button 2 */
        button = gtk_button_new_with_label("button 2");
        g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(callback),
                        (gpointer) "button 2");
        gtk_box_pack_start(GTK_BOX(box), button, TRUE, TRUE, 0);
        gtk_widget_show(button);

        gtk_widget_show(box);
        gtk_widget_show(window);
        gtk_main();

        return 0;
}

--y0ulUmNC+osPPQO6--




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]