From 6dc130cd15575e99f5b1dd5a2b2f2ba6263b65cb Mon Sep 17 00:00:00 2001 From: edgrif <edgrif> Date: Mon, 29 Mar 2010 10:22:56 +0000 Subject: [PATCH] change realize to map-event and test for drawable, makes sure window is there. sort out property notify - wrong event string. --- src/zmapUtils/zmapXRemoteUtils.c | 159 +++++++++++++++++++------------ 1 file changed, 98 insertions(+), 61 deletions(-) diff --git a/src/zmapUtils/zmapXRemoteUtils.c b/src/zmapUtils/zmapXRemoteUtils.c index da14fb50a..149bb77c6 100755 --- a/src/zmapUtils/zmapXRemoteUtils.c +++ b/src/zmapUtils/zmapXRemoteUtils.c @@ -23,19 +23,23 @@ * Ed Griffiths (Sanger Institute, UK) edgrif@sanger.ac.uk, * Roy Storey (Sanger Institute, UK) rds@sanger.ac.uk * - * Description: + * Description: Provides utility functions for xremote stuff...actually should + * stuff really be here...maybe it should all be in + * zmapControl/remote....???? * - * Exported functions: See XXXXXXXXXXXXX.h + * Exported functions: See ZMap/zmapUtilsXRemote.h * HISTORY: - * Last edited: Oct 20 14:17 2009 (edgrif) + * Last edited: Mar 29 11:20 2010 (edgrif) * Created: Tue Jul 10 09:09:53 2007 (rds) - * CVS info: $Id: zmapXRemoteUtils.c,v 1.10 2010-03-04 15:11:33 mh17 Exp $ + * CVS info: $Id: zmapXRemoteUtils.c,v 1.11 2010-03-29 10:22:56 edgrif Exp $ *------------------------------------------------------------------- */ #include <ZMap/zmapUtilsXRemote.h> #include <ZMap/zmapUtils.h> + + /* This data struct gets passed to the PropertyEvent Handler which * processes the event and if it's a valid event (for us!) execute the * callback with the data. @@ -48,35 +52,52 @@ typedef struct _ZMapXRemoteNotifyDataStruct ZMapXRemoteCallback post_cb; /* The callback which does something when the property notify event happens */ gulong begin_handler_id; gulong end_handler_id; + + guint expose_handler_id ; + guint property_handler_id ; + + Window xwindow_id; /* isn't their a window id property of the xremote? */ char *app_name, *req_name, *res_name; } ZMapXRemoteNotifyDataStruct, *ZMapXRemoteNotifyData; -#define BEGIN_EVENT_TYPE "realize" -#define END_EVENT_TYPE "unrealize" -//#define BEGIN_EVENT_TYPE "map" -//#define END_EVENT_TYPE "unmap" + +#define BEGIN_EVENT_TYPE "map-event" +#define END_EVENT_TYPE "unmap-event" static gboolean zmapXRemotePropertyNotifyEvent(GtkWidget *widget, GdkEventProperty *ev, gpointer user_data); -static void destroy_property_notify_data(GtkWidget *widget, gpointer user_data); -static void begin_handler(GtkWidget *widget, gpointer realize_data); -static void end_handler(GtkWidget *widget, gpointer realize_data); +static gboolean destroy_property_notify_data(GtkWidget *widget, gpointer user_data); +static gboolean begin_handler(GtkWidget *widget, GdkEvent *event, gpointer realize_data); +static gboolean end_handler(GtkWidget *widget, GdkEvent *event, gpointer realize_data); + + +/* Local globals */ static gboolean events_debug_G = FALSE ; + + + +/* + * External functions + */ + + void zMapXRemoteInitialiseWidget(GtkWidget *widget, char *app, char *request, char *response, ZMapXRemoteCallback callback, gpointer user_data) { zMapXRemoteInitialiseWidgetFull(widget, app, request, response, callback, NULL, user_data); + return ; } + void zMapXRemoteInitialiseWidgetFull(GtkWidget *widget, char *app, char *request, char *response, ZMapXRemoteCallback callback, ZMapXRemoteCallback post_callback, gpointer user_data) { - ZMapXRemoteNotifyData notify_data; + ZMapXRemoteNotifyData notify_data ; notify_data = g_new0(ZMapXRemoteNotifyDataStruct, 1); notify_data->xremote = NULL; @@ -88,35 +109,43 @@ void zMapXRemoteInitialiseWidgetFull(GtkWidget *widget, char *app, char *request notify_data->req_name = g_strdup(request); notify_data->res_name = g_strdup(response); - notify_data->begin_handler_id = 0; /* make sure this really is zeroed */ - notify_data->end_handler_id = 0; /* make sure this really is zeroed */ - notify_data->xwindow_id = 0; - - if(GTK_WIDGET_REALIZED(widget) != TRUE) + /* If the widget and more importantly the window for the widget is on the screen + * then fine, otherwise we need to attach signal handlers and wait until it is + * because otherwise we cannot do the property stuff which _must_ have a window. */ + if (GTK_WIDGET_DRAWABLE(widget)) + { + begin_handler(widget, NULL, notify_data); + } + else { + if(events_debug_G) + printf("Widget %p , X Window 0x0 NOT DRAWABLE YET\n", widget) ; + + g_signal_connect(G_OBJECT(widget), BEGIN_EVENT_TYPE, G_CALLBACK(begin_handler), notify_data); g_signal_connect(G_OBJECT(widget), END_EVENT_TYPE, G_CALLBACK(end_handler), notify_data); - g_signal_connect(G_OBJECT(widget), "destroy", + g_signal_connect(G_OBJECT(widget), "destroy-event", G_CALLBACK(destroy_property_notify_data), notify_data); } - else - begin_handler(widget, notify_data); + return ; } -unsigned long zMapXRemoteWidgetGetXID(GtkWidget *widget) + + +Window zMapXRemoteWidgetGetXID(GtkWidget *widget) { - unsigned long id = 0; + Window id = 0; - if(GTK_WIDGET_REALIZED(widget) == TRUE) - id = GDK_DRAWABLE_XID(widget->window); + if (GTK_WIDGET_DRAWABLE(widget)) + id = GDK_DRAWABLE_XID(widget->window) ; else - zMapLogCritical("GtkWidget '%p' not realized. Bad xremote things will happen.", widget); + zMapLogCritical("GtkWidget '%p' not realized. Bad xremote things will happen.", widget) ; - return id; + return id ; } gboolean zMapXRemoteValidateStatusCode(int *code) @@ -203,7 +232,13 @@ gboolean zMapXRemoteXMLGenericClientStartCB(gpointer user_data, } -/* INTERNAL */ + + + +/* + * INTERNAL + */ + static gboolean zmapXRemotePropertyNotifyEvent(GtkWidget *widget, GdkEventProperty *ev, gpointer user_data) { @@ -213,10 +248,10 @@ static gboolean zmapXRemotePropertyNotifyEvent(GtkWidget *widget, GdkEventProper event_atom = gdk_x11_atom_to_xatom(ev->atom); - if(zMapXRemoteHandlePropertyNotify(notify_data->xremote, - event_atom, ev->state, - notify_data->callback, - notify_data->data)) + if (zMapXRemoteHandlePropertyNotify(notify_data->xremote, + event_atom, ev->state, + notify_data->callback, + notify_data->data)) { char *request = "dummy request"; int code; @@ -230,12 +265,13 @@ static gboolean zmapXRemotePropertyNotifyEvent(GtkWidget *widget, GdkEventProper return result; } -static void destroy_property_notify_data(GtkWidget *widget, gpointer user_data) +static gboolean destroy_property_notify_data(GtkWidget *widget, gpointer user_data) { ZMapXRemoteNotifyData notify_data = (ZMapXRemoteNotifyData)user_data; if(notify_data->xremote) zMapXRemoteDestroy(notify_data->xremote); + notify_data->callback = NULL; notify_data->data = NULL; @@ -248,75 +284,76 @@ static void destroy_property_notify_data(GtkWidget *widget, gpointer user_data) g_free(notify_data); - return ; + return FALSE ; } + + /* This is now always installed so that we can handle the * gtk_widget_reparent stuff which destroys widget->window. Note how * we need to call gtk_widget_add_events each time ;) */ -static void begin_handler(GtkWidget *widget, gpointer begin_data) +static gboolean begin_handler(GtkWidget *widget, GdkEvent *event, gpointer begin_data) { ZMapXRemoteNotifyData notify_data = (ZMapXRemoteNotifyData)begin_data; + + if(events_debug_G) + printf("Widget %p, X Window 0x%lx received " BEGIN_EVENT_TYPE " event\n", + widget, GDK_DRAWABLE_XID(widget->window)) ; + externalPerl = FALSE; if(events_debug_G) printf("Widget %p Received " BEGIN_EVENT_TYPE " event\n", widget); - zMapAssert(GTK_WIDGET_NO_WINDOW(widget) == FALSE); - - if(GTK_WIDGET_REALIZED(widget) && !(GTK_WIDGET_NO_WINDOW(widget))) + if (GTK_WIDGET_DRAWABLE(widget)) { Window id = (Window)GDK_DRAWABLE_XID(widget->window); - if(events_debug_G) + if (events_debug_G) printf("Widget %p has Window 0x%lx\n", widget, id); - /* Moving this (add_events) BEFORE the call to InitServer stops - * some Xlib BadWindow errors (turn on debugging in zmapXRemote 2 c - * them). This doesn't feel right, but I couldn't bear the - * thought of having to store a handler id for an expose_event - * in the zmap struct just so I could use it over realize in - * much the same way as the zmapWindow code does. This - * definitely points to some problem with GTK2. The Widget - * reports it's realized GTK_WIDGET_REALIZED(widget) has a - * window id, but then the XChangeProperty() fails in the - * zmapXRemote code. Hmmm. If this continues to be a problem - * then I'll change it to use expose. Only appeared on Linux. */ /* Makes sure we actually get the events!!!! Use add_events as set_events needs to be done BEFORE realize */ gtk_widget_add_events(widget, GDK_PROPERTY_CHANGE_MASK) ; - if(notify_data->xwindow_id != id) + if (notify_data->xwindow_id != id) { - if(notify_data->xremote) + if (notify_data->property_handler_id) + g_signal_handler_disconnect(widget, notify_data->property_handler_id) ; + + if (notify_data->xremote) zMapXRemoteDestroy(notify_data->xremote); - notify_data->xremote = zMapXRemoteNew(); + + notify_data->xremote = zMapXRemoteNew(GDK_DISPLAY()); zMapXRemoteInitServer(notify_data->xremote, id, notify_data->app_name, notify_data->req_name, notify_data->res_name); - notify_data->xwindow_id = id; /* record this for later */ + notify_data->xwindow_id = id ; /* record this for later */ - g_signal_connect(G_OBJECT(widget), "property_notify_event", - G_CALLBACK(zmapXRemotePropertyNotifyEvent), - (gpointer)notify_data); + notify_data->property_handler_id = g_signal_connect(G_OBJECT(widget), "property-notify-event", + G_CALLBACK(zmapXRemotePropertyNotifyEvent), + (gpointer)notify_data) ; } else { - printf("Nothing to do here...\n"); + if(events_debug_G) + printf("Nothing to do here...\n"); } } - return ; + return FALSE ; } -static void end_handler(GtkWidget *widget, gpointer end_data) + +static gboolean end_handler(GtkWidget *widget, GdkEvent *event, gpointer end_data) { - if(events_debug_G) + + if (events_debug_G) printf("Widget %p Received " END_EVENT_TYPE " event\n", widget); - return ; + return FALSE ; } -- GitLab