diff -ru smalltalk-2.0.9.old/blox/gtk/BloxGTK.c smalltalk-2.0.9/blox/gtk/BloxGTK.c --- smalltalk-2.0.9.old/blox/gtk/BloxGTK.c 2002-07-14 04:45:57.000000000 -0700 +++ smalltalk-2.0.9/blox/gtk/BloxGTK.c 2003-01-14 00:05:54.000000000 -0800 @@ -67,13 +67,73 @@ #include #include #include +#include +#include #ifdef STDC_HEADERS #include #include #endif -static VMProxy *vmProxy; +#include "BloxGTK.h" + +static GHashTable *eventDataHash = NULL; +static GHashTable *callBackHash = NULL; +static lt_dlhandle supportHandle; + +gint bloxGtkDestroyFinalSignalHandler(GtkWidget *widget, gpointer data); + + +void +bloxGtkConnectSignal(OOP widget, char *event_name, OOP event_handler, OOP user_data) { + eventData *data; + eventData *newEventData; + char *widgetClassName; + GtkWidget *cWidget = vmProxy->OOPToCObject(widget); + void *signalFunc = NULL; + GtkType currentType; + + newEventData = (eventData *)malloc(sizeof(eventData)); + newEventData->eventHandler = event_handler; + vmProxy->registerOOP(event_handler); + newEventData->data = user_data; + vmProxy->registerOOP(user_data); + newEventData->next = NULL; + + currentType = GTK_OBJECT_TYPE(cWidget); + widgetClassName = gtk_type_name(currentType); + signalFunc = g_hash_table_lookup(g_hash_table_lookup(callBackHash, widgetClassName), event_name); + + while(signalFunc == NULL && strcmp(widgetClassName, "GtkObject") != 0) { + currentType = gtk_type_parent(currentType); + widgetClassName = gtk_type_name(currentType); + signalFunc = g_hash_table_lookup(g_hash_table_lookup(callBackHash, widgetClassName), event_name); + } + + if(signalFunc == NULL) { + return; + } + + gtk_signal_connect(GTK_OBJECT(cWidget), event_name, GTK_SIGNAL_FUNC(signalFunc), newEventData); + + if(eventDataHash == NULL) { + eventDataHash = g_hash_table_new(g_direct_hash, g_direct_equal); + } + + data = g_hash_table_lookup(eventDataHash, cWidget); + if(data == NULL) { + g_hash_table_insert(eventDataHash, cWidget, newEventData); + + gtk_signal_connect_after(GTK_OBJECT(cWidget), "destroy", + GTK_SIGNAL_FUNC(bloxGtkDestroyFinalSignalHandler), NULL); + } else { + while(data->next != NULL) { + data = data->next; + } + data->next = newEventData; + } +} + void bloxGtkInit() @@ -82,6 +142,34 @@ gchar *argvArray[] = { "gst", NULL }; gchar **argv = argvArray; gtk_init (&argc, &argv); + + lt_dlinit(); + supportHandle = lt_dlopen(".libs/blox-gtk-support.so"); + if(supportHandle == NULL) { + printf("Couldn't open support module: \"%s\"\n", lt_dlerror()); + return; + } + callBackHash = bloxGtkCreateCallBackHash(); +} + + +gint +bloxGtkDestroyFinalSignalHandler(GtkWidget *widget, gpointer data) +{ + eventData *eD, *nextEventData; + + eD = g_hash_table_lookup(eventDataHash, widget); + if(eD != NULL) g_hash_table_remove(eventDataHash, widget); + + while(eD != NULL) { + nextEventData = eD->next; + vmProxy->unregisterOOP(eD->eventHandler); + vmProxy->unregisterOOP(eD->data); + free(eD); + eD = nextEventData; + } + + return(FALSE); } @@ -91,4 +179,13 @@ { vmProxy = proxy; vmProxy->defineCFunc("bloxGtkInit", bloxGtkInit); + vmProxy->defineCFunc("bloxGtkConnectSignal", bloxGtkConnectSignal); + + eventDataHash = NULL; +} + +VMProxy* +bloxGtkGetVmProxy() +{ + return vmProxy; } Only in smalltalk-2.0.9/blox/gtk: BloxGTK.h.in diff -ru smalltalk-2.0.9.old/blox/gtk/GtkDecl.st.in smalltalk-2.0.9/blox/gtk/GtkDecl.st.in --- smalltalk-2.0.9.old/blox/gtk/GtkDecl.st.in 2002-07-14 04:45:57.000000000 -0700 +++ smalltalk-2.0.9/blox/gtk/GtkDecl.st.in 2003-01-14 00:05:02.000000000 -0800 @@ -35,6 +35,7 @@ DLD addLibrary: 'libgdk'! DLD addLibrary: 'libgtk'! +DLD addModule: 'blox-gtk'! Blox addSubspace: #Gtk! Namespace current: Blox Gtk! diff -ru smalltalk-2.0.9.old/blox/gtk/Makefile.am smalltalk-2.0.9/blox/gtk/Makefile.am --- smalltalk-2.0.9.old/blox/gtk/Makefile.am 2002-07-14 04:45:57.000000000 -0700 +++ smalltalk-2.0.9/blox/gtk/Makefile.am 2003-01-14 00:05:02.000000000 -0800 @@ -1,21 +1,31 @@ bloxgtkdir = $(pkgdatadir)/blox/gtk if HAVE_GTK -noinst_SCRIPTS = structs funcs make_enums +noinst_SCRIPTS = structs funcs make_enums make_signal_funcs make_callback_hash bloxgtk_DATA = GtkDecl.st -CLEANFILES = $(noinst_SCRIPTS) $(bloxgtk_DATA) +bloxgtk_header_in = BloxGTK.h.in +bloxgtk_header_file = BloxGTK.h +bloxgtk_generated_c_files = BloxGTKSignalFuncs.c BloxGTKInitCallbackHash.c +CLEANFILES = $(noinst_SCRIPTS) $(bloxgtk_DATA) $(bloxgtk_header_file) $(bloxgtk_generated_c_files) endif EXTRA_DIST = GtkDecl.st.in proof.st \ structs.awk funcs.awk make_enums.awk order.awk -EXTRA_LTLIBRARIES = libblox-gtk.la -pkglib_LTLIBRARIES = @MODULES_GTK@ -libblox_gtk_la_LDFLAGS = -module -rpath $(pkglibdir) -no-undefined \ - -release $(VERSION) -libblox_gtk_la_SOURCES = BloxGTK.c +EXTRA_LTLIBRARIES = blox-gtk.la +pkglib_LTLIBRARIES = blox-gtk-support.la @MODULES_GTK@ +blox_gtk_la_LDFLAGS = -module -rpath $(pkglibdir) -no-undefined \ + -release $(VERSION) --export-dynamic +blox_gtk_la_SOURCES = BloxGTK.c +blox_gtk_la_LIBADD = $(GLIB_LIBS) $(GTK_LIBS) + +blox_gtk_support_la_LDFLAGS = -module -rpath $(pkglibdir) -no-undefined \ + -release $(VERSION) --export-dynamic +blox_gtk_support_la_SOURCES = $(bloxgtk_generated_c_files) +blox_gtk_support_la_LIBADD = $(GLIB_LIBS) $(GTK_LIBS) -INCLUDES = -I$(top_srcdir)/libgst -I$(top_srcdir)/lib-src $(TCL_INCLUDES) + +INCLUDES = -I$(top_srcdir)/libgst -I$(top_srcdir)/lib-src -I$(top_srcdir)/libltdl $(TCL_INCLUDES) AM_CFLAGS = $(GLIB_CFLAGS) $(GTK_CFLAGS) @@ -69,6 +79,8 @@ structs: $(srcdir)/structs.awk funcs: $(srcdir)/funcs.awk make_enums: $(srcdir)/make_enums.awk +make_signal_funcs: $(srcdir)/make_signal_funcs.awk +make_callback_hash: $(srcdir)/make_callback_hash.awk order: $(srcdir)/order.awk # ------------------------------------- @@ -81,19 +93,33 @@ GtkDecl.st: $(srcdir)/GtkDecl.st.in $(noinst_PROGRAMS) .order structs funcs (echo \"Don\'t modify this file, edit GtkDecl.st.in instead\!\"; \ - sed -ne '/\$/q' -e p $<; \ + sed -ne '/^\$$/q' -e p $< && \ builddir=`pwd`; \ cd $(GTK_HEADERS) && \ $$builddir/structs `cat $$builddir/.order` && \ $$builddir/enums && \ - $$builddir/funcs `cat $$builddir/.order`; - sed '1,/\$/d' $<) > $@ + $$builddir/funcs `cat $$builddir/.order` && \ + sed '1,/^\$$/d' $$builddir/$<) > $@ enums.c: .order make_enums builddir=`pwd`; \ cd $(GTK_HEADERS) && \ $$builddir/make_enums `cat $$builddir/.order` > $$builddir/enums.c +BloxGTK.h: +BloxGTKSignalFuncs.c: make_signal_funcs make_callback_hash .order + sed -ne '/^\$$/q' -e p $(bloxgtk_header_in) > $(bloxgtk_header_file) + (builddir=`pwd`; \ + cd $(GTK_HEADERS) && \ + $$builddir/make_signal_funcs -v header_file=$$builddir/$(bloxgtk_header_file) \ + `cat $$builddir/.order`) > $@ + sed '1,/^\$$/d' $(bloxgtk_header_in) >> $(bloxgtk_header_file) + +BloxGTKInitCallbackHash.c: make_callback_hash .order + (builddir=`pwd`; \ + cd $(GTK_HEADERS) && \ + $$builddir/make_callback_hash `cat $$builddir/.order`) > $@ + .order: timestamp timestamp: order Makefile.am builddir=`pwd`; \ diff -ru smalltalk-2.0.9.old/blox/gtk/funcs.awk smalltalk-2.0.9/blox/gtk/funcs.awk --- smalltalk-2.0.9.old/blox/gtk/funcs.awk 2002-07-14 04:45:57.000000000 -0700 +++ smalltalk-2.0.9/blox/gtk/funcs.awk 2003-01-14 00:05:02.000000000 -0800 @@ -36,7 +36,7 @@ ######################################################################## BEGIN { - FS = "[ \(\t]+" + FS = "[ (\t]+" type["void"] = "#void" type["int"] = "#int" @@ -191,10 +191,10 @@ continue if (i < 5 && self) - decl = decl " self" + decl = decl " #self" else if (substr(tst, 1, 3) == "...") - decl = decl " variadic" + decl = decl " #variadic" else if ( index( tst, "," ) > 0 || index( tst, ")" ) > 0 ) decl = decl " " ctype( strip( last ), tst ) Only in smalltalk-2.0.9/blox/gtk: make_callback_hash.awk diff -ru smalltalk-2.0.9.old/blox/gtk/make_enums.awk smalltalk-2.0.9/blox/gtk/make_enums.awk --- smalltalk-2.0.9.old/blox/gtk/make_enums.awk 2002-07-14 04:45:57.000000000 -0700 +++ smalltalk-2.0.9/blox/gtk/make_enums.awk 2003-01-14 00:05:02.000000000 -0800 @@ -35,6 +35,11 @@ # ######################################################################## +BEGIN { + print "#include " + print "#include " +} + FNR == 1 { enum_class = substr(smalltalkize(toupper(FILENAME)), 1, 3) print "#include <" FILENAME ">" @@ -55,13 +60,15 @@ if ($1 == "/*") { do getline - while ($1 != "*/") - getline + while ($0 !~ /\*\/$/) { + getline + } } if (/[A-Z]/) { sub(/,/, "", $1) declaration[$1] = "" +# print ">>> " $1 ": " NR } getline } Only in smalltalk-2.0.9/blox/gtk: make_signal_funcs.awk diff -ru smalltalk-2.0.9.old/blox/gtk/structs.awk smalltalk-2.0.9/blox/gtk/structs.awk --- smalltalk-2.0.9.old/blox/gtk/structs.awk 2002-07-14 04:45:58.000000000 -0700 +++ smalltalk-2.0.9/blox/gtk/structs.awk 2003-01-14 00:05:02.000000000 -0800 @@ -171,6 +171,14 @@ print "\tclassVariableNames: ''" print "\tpoolDictionaries: ''" print "\tcategory: 'Gtk'!\n" + + if (name == "GtkWidget") { + print "GtkWidget" + print "\tdefineCFunc: 'bloxGtkConnectSignal'" + print "\twithSelectorArgs: 'connectSignal: name withHandler: eventHandler withEventData: eventData'" + print "\treturning: #void" + print "\targs: #( #selfSmalltalk #string #smalltalk #smalltalk )!" + } } function parse_struct (parent, name)