Bug 544088 - Export XtClient methods. r=karlt
authorMartin Stransky <stransky@redhat.com>
Thu, 12 Jul 2012 19:28:53 -0400
changeset 100916 b778d551c9e56b1a7aefd6230f54d526ab3a1b34
parent 100915 de697e323b394b9e9d346003db7288b97a6d89b4
child 100917 4b9414cba94d0e85d60b9700e7b96a77f18bade9
push id18
push usershu@rfrn.org
push dateMon, 06 Aug 2012 22:42:45 +0000
reviewerskarlt
bugs544088
milestone16.0a1
Bug 544088 - Export XtClient methods. r=karlt
widget/gtkxtbin/gtk2xtbin.c
widget/gtkxtbin/gtk2xtbin.h
--- a/widget/gtkxtbin/gtk2xtbin.c
+++ b/widget/gtkxtbin/gtk2xtbin.c
@@ -38,40 +38,25 @@
 static void            gtk_xtbin_class_init (GtkXtBinClass *klass);
 static void            gtk_xtbin_init       (GtkXtBin      *xtbin);
 static void            gtk_xtbin_realize    (GtkWidget      *widget);
 static void            gtk_xtbin_unrealize    (GtkWidget      *widget);
 static void            gtk_xtbin_destroy    (GtkObject      *object);
 static void            gtk_xtbin_shutdown   (GtkObject      *object);
 
 /* Xt aware XEmbed */
-static void       xt_client_init      (XtClient * xtclient, 
-                                       Visual *xtvisual, 
-                                       Colormap xtcolormap, 
-                                       int xtdepth);
-static void       xt_client_create    (XtClient * xtclient, 
-                                       Window embeder, 
-                                       int height, 
-                                       int width );
-static void       xt_client_unrealize (XtClient* xtclient);
-static void       xt_client_destroy   (XtClient* xtclient);
-static void       xt_client_set_info  (Widget xtplug, 
-                                       unsigned long flags);
-static void       xt_client_event_handler (Widget w, 
-                                           XtPointer client_data, 
-                                           XEvent *event);
 static void       xt_client_handle_xembed_message (Widget w, 
                                                    XtPointer client_data, 
                                                    XEvent *event);
-static void       xt_client_focus_listener       (Widget w, 
-                                                   XtPointer user_data, 
-                                                   XEvent *event);
 static void       xt_add_focus_listener( Widget w, XtPointer user_data );
 static void       xt_add_focus_listener_tree ( Widget treeroot, XtPointer user_data); 
 static void       xt_remove_focus_listener(Widget w, XtPointer user_data);
+static void       xt_client_event_handler (Widget w, XtPointer client_data, XEvent *event);
+static void       xt_client_focus_listener (Widget w, XtPointer user_data, XEvent *event);
+static void       xt_client_set_info (Widget xtplug, unsigned long flags);
 static void       send_xembed_message (XtClient *xtclient,
                                        long message, 
                                        long detail, 
                                        long data1, 
                                        long data2,
                                        long time);  
 static int        error_handler       (Display *display, 
                                        XErrorEvent *error);
@@ -304,54 +289,18 @@ gtk_xtbin_new (GdkWindow *parent_window,
      */
 #ifdef DEBUG_XTBIN
     printf("gtk_xtbin_init: XtOpenDisplay() returned NULL.\n");
 #endif
     g_free (xtbin);
     return (GtkWidget *)NULL;
   }
 
-  /* If this is the first running widget, hook this display into the
-     mainloop */
-  if (0 == num_widgets) {
-    int           cnumber;
-    /*
-     * hook Xt event loop into the glib event loop.
-     */
-
-    /* the assumption is that gtk_init has already been called */
-    GSource* gs = g_source_new(&xt_event_funcs, sizeof(GSource));
-      if (!gs) {
-       return NULL;
-      }
-    
-    g_source_set_priority(gs, GDK_PRIORITY_EVENTS);
-    g_source_set_can_recurse(gs, TRUE);
-    tag = g_source_attach(gs, (GMainContext*)NULL);
-#ifdef VMS
-    cnumber = XConnectionNumber(xtdisplay);
-#else
-    cnumber = ConnectionNumber(xtdisplay);
-#endif
-    xt_event_poll_fd.fd = cnumber;
-    xt_event_poll_fd.events = G_IO_IN; 
-    xt_event_poll_fd.revents = 0;    /* hmm... is this correct? */
-
-    g_main_context_add_poll ((GMainContext*)NULL, 
-                             &xt_event_poll_fd, 
-                             G_PRIORITY_LOW);
-    /* add a timer so that we can poll and process Xt timers */
-    xt_polling_timer_id =
-      g_timeout_add(25,
-                    (GtkFunction)xt_event_polling_timer_callback,
-                    xtdisplay);
-  }
-
-  /* Bump up our usage count */
-  num_widgets++;
+  /* Launch X event loop */
+  xt_client_xloop_create();
 
   /* Build the hierachy */
   xtbin->xtdisplay = xtbin->xtclient.xtdisplay;
   gtk_widget_set_parent_window(GTK_WIDGET(xtbin), parent_window);
   gdk_window_get_user_data(xtbin->parent_window, &user_data);
   if (user_data)
     gtk_container_add(GTK_CONTAINER(user_data), GTK_WIDGET(xtbin));
 
@@ -452,41 +401,29 @@ gtk_xtbin_destroy (GtkObject *object)
 
   xtbin = GTK_XTBIN (object);
 
   if(xtbin->xtwindow) {
     /* remove the event handler */
     xt_client_destroy(&(xtbin->xtclient));
     xtbin->xtwindow = 0;
 
-    num_widgets--; /* reduce our usage count */
-
-    /* If this is the last running widget, remove the Xt display
-       connection from the mainloop */
-    if (0 == num_widgets) {
-#ifdef DEBUG_XTBIN
-      printf("removing the Xt connection from the main loop\n");
-#endif
-      g_main_context_remove_poll((GMainContext*)NULL, &xt_event_poll_fd);
-      g_source_remove(tag);
-
-      g_source_remove(xt_polling_timer_id);
-      xt_polling_timer_id = 0;
-    }
+    /* stop X event loop */
+    xt_client_xloop_destroy();
   }
 
   GTK_OBJECT_CLASS(parent_class)->destroy(object);
 }
 
 /*
 * Following is the implementation of Xt XEmbedded for client side
 */
 
 /* Initial Xt plugin */
-static void
+void
 xt_client_init( XtClient * xtclient, 
                 Visual *xtvisual, 
                 Colormap xtcolormap,
                 int xtdepth)
 {
   XtAppContext  app_context;
   char         *mArgv[1];
   int           mArgc = 0;
@@ -516,19 +453,97 @@ xt_client_init( XtClient * xtclient,
       xt_is_initialized = TRUE;
   }
   xtclient->xtdisplay  = xtdisplay;
   xtclient->xtvisual   = xtvisual;
   xtclient->xtcolormap = xtcolormap;
   xtclient->xtdepth    = xtdepth;
 }
 
+void
+xt_client_xloop_create(void)
+{
+  /* If this is the first running widget, hook this display into the
+     mainloop */
+  if (0 == num_widgets) {
+    int           cnumber;
+
+    /* Set up xtdisplay in case we're missing one */
+    if (!xtdisplay) {
+      (void)xt_client_get_display();
+    }
+
+    /*
+     * hook Xt event loop into the glib event loop.
+     */
+    /* the assumption is that gtk_init has already been called */
+    GSource* gs = g_source_new(&xt_event_funcs, sizeof(GSource));
+      if (!gs) {
+       return NULL;
+      }
+    
+    g_source_set_priority(gs, GDK_PRIORITY_EVENTS);
+    g_source_set_can_recurse(gs, TRUE);
+    tag = g_source_attach(gs, (GMainContext*)NULL);
+#ifdef VMS
+    cnumber = XConnectionNumber(xtdisplay);
+#else
+    cnumber = ConnectionNumber(xtdisplay);
+#endif
+    xt_event_poll_fd.fd = cnumber;
+    xt_event_poll_fd.events = G_IO_IN; 
+    xt_event_poll_fd.revents = 0;    /* hmm... is this correct? */
+
+    g_main_context_add_poll ((GMainContext*)NULL, 
+                             &xt_event_poll_fd, 
+                             G_PRIORITY_LOW);
+    /* add a timer so that we can poll and process Xt timers */
+    xt_polling_timer_id =
+      g_timeout_add(25,
+                    (GtkFunction)xt_event_polling_timer_callback,
+                    xtdisplay);
+  }
+
+  /* Bump up our usage count */
+  num_widgets++;
+}
+
+void
+xt_client_xloop_destroy(void)
+{
+  num_widgets--; /* reduce our usage count */
+
+  /* If this is the last running widget, remove the Xt display
+     connection from the mainloop */
+  if (0 == num_widgets) {
+#ifdef DEBUG_XTBIN
+    printf("removing the Xt connection from the main loop\n");
+#endif
+    g_main_context_remove_poll((GMainContext*)NULL, &xt_event_poll_fd);
+    g_source_remove(tag);
+
+    g_source_remove(xt_polling_timer_id);
+    xt_polling_timer_id = 0;
+  }
+}
+
+/* Get Xt Client display */
+Display	*
+xt_client_get_display(void)
+{
+  if (!xtdisplay) {
+    XtClient tmp;
+    xt_client_init(&tmp,NULL,0,0);
+  }
+  return xtdisplay;
+}
+
 /* Create the Xt client widgets
 *  */
-static void
+void
 xt_client_create ( XtClient* xtclient , 
                    Window embedderid, 
                    int height, 
                    int width ) 
 {
   int           n;
   Arg           args[6];
   Widget        child_widget;
@@ -594,17 +609,17 @@ xt_client_create ( XtClient* xtclient ,
   XtAddEventHandler(child_widget, 
                     SubstructureNotifyMask | ButtonReleaseMask, 
                     TRUE, 
                     (XtEventHandler)xt_client_focus_listener, 
                     xtclient);
   XSync(xtclient->xtdisplay, FALSE);
 }
 
-static void
+void
 xt_client_unrealize ( XtClient* xtclient )
 {
 #if XlibSpecificationRelease >= 6
   XtUnregisterDrawable(xtclient->xtdisplay,
                        xtclient->top_widget->core.window);
 #else
   _XtUnregisterWindow(xtclient->top_widget->core.window,
                       xtclient->top_widget);
@@ -613,28 +628,28 @@ xt_client_unrealize ( XtClient* xtclient
   /* flush the queue before we returning origin top_widget->core.window
      or we can get X error since the window is gone */
   XSync(xtclient->xtdisplay, False);
 
   xtclient->top_widget->core.window = xtclient->oldwindow;
   XtUnrealizeWidget(xtclient->top_widget);
 }
 
-static void            
+void            
 xt_client_destroy   (XtClient* xtclient)
 {
   if(xtclient->top_widget) {
     XtRemoveEventHandler(xtclient->child_widget, 0x0FFFFF, TRUE, 
                          (XtEventHandler)xt_client_event_handler, xtclient);
     XtDestroyWidget(xtclient->top_widget);
     xtclient->top_widget = NULL;
   }
 }
 
-static void         
+void         
 xt_client_set_info (Widget xtplug, unsigned long flags)
 {
   unsigned long buffer[2];
 
   Atom infoAtom = XInternAtom(XtDisplay(xtplug), "_XEMBED_INFO", False); 
 
   buffer[1] = 0;                /* Protocol version */
   buffer[1] = flags;
@@ -701,17 +716,17 @@ xt_client_handle_xembed_message(Widget w
       XSync( XtDisplay(xtplug->child_widget), False);
     }
     break;
   default:
     break;
   } /* End of XEmbed Message */
 }
 
-static void         
+void         
 xt_client_event_handler( Widget w, XtPointer client_data, XEvent *event)
 {
   XtClient *xtplug = (XtClient*)client_data;
   
   switch(event->type)
     {
     case ClientMessage:
       /* Handle xembed message */
@@ -801,17 +816,17 @@ untrap_error(void)
   if(trapped_error_code) {
 #ifdef DEBUG_XTBIN
     printf("Get X Window Error = %d\n", trapped_error_code);
 #endif
   }
   return trapped_error_code;
 }
 
-static void         
+void         
 xt_client_focus_listener( Widget w, XtPointer user_data, XEvent *event)
 {
   Display *dpy = XtDisplay(w);
   XtClient *xtclient = user_data;
   Window win = XtWindow(w);
 
   switch(event->type)
     {
--- a/widget/gtkxtbin/gtk2xtbin.h
+++ b/widget/gtkxtbin/gtk2xtbin.h
@@ -115,13 +115,22 @@ typedef struct _CorePart {
     Boolean         visible;            /* is window mapped and not occluded?*/
     Boolean         mapped_when_managed;/* map window if it's managed?       */
 } CorePart;
 
 typedef struct _WidgetRec {
     CorePart    core;
  } WidgetRec, CoreRec;   
 
+/* Exported functions, used by Xt plugins */
+void xt_client_create(XtClient * xtclient, Window embeder, int height, int width);
+void xt_client_unrealize(XtClient* xtclient);
+void xt_client_destroy(XtClient* xtclient);
+void xt_client_init(XtClient * xtclient, Visual *xtvisual, Colormap xtcolormap, int xtdepth);
+void xt_client_xloop_create(void);
+void xt_client_xloop_destroy(void);
+Display * xt_client_get_display(void);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
 #endif /* __GTK_XTBIN_H__ */