[patch] allow GDK and GTK to use a "foreign" display



The following two patches allow GTK/GDK to be used with an X
connection created by some other means. The patch does not contain
header declarations of the new functions:

       gtk_init_display (int *argc, char ***argv, void *display);
       gdk_init_display (int *argc, char ***argv, Display *display);

       gtk_init_check_display (int *argc, char ***argv, void *display);
       gdk_init_check_display (int *argc, char ***argv, Display *display);

I compiled the hello world example from the tutorial, adding:

        Display *display;

	display = XOpenDisplay (NULL);

	/* This is called in all GTK applications. Arguments are parsed
           * from the command line and are returned to the application. */
	gtk_init_display (&argc, &argv, display);
          
It works fine. Not much of a test, but you get the idea.

Why do I want this patch to be included in GDK/GTK ? Dynamically
loaded plugins that use GTK but don't know whether or not the
application that loads them does. Thus, the plugin either has to call
the current gtk_init(), and run into problems with the app having 2 X
server connections (can this even be done?); better: the host can pass
it the server connection, and the plugin can then set up GDK/GTK to use it.

NOTE: the patch is not finished, because gdk_display_name() will not
work correctly at this time. However, I would like to get feedback on
the possibility of this becoming part of the library.

--p

----------------------------------------------------------------------

*** /usr/local/src/gtk+-1.2.0/gtk/gtkmain.c	Wed Feb 24 17:04:00 1999
--- gtkmain.c	Wed May 24 09:59:08 2000
***************
*** 175,182 ****
  
  
  gboolean
! gtk_init_check (int	 *argc,
! 		char   ***argv)
  {
    extern void gtk_object_post_arg_parsing_init (void);
    GSList *gtk_modules = NULL;
--- 175,183 ----
  
  
  gboolean
! gtk_init_check_display (int	 *argc,
! 			char   ***argv,
! 			void     *display)
  {
    extern void gtk_object_post_arg_parsing_init (void);
    GSList *gtk_modules = NULL;
***************
*** 196,202 ****
    /* Initialize "gdk". We pass along the 'argc' and 'argv'
     *  parameters as they contain information that GDK uses
     */
!   if (!gdk_init_check (argc, argv))
      return FALSE;
  
    gdk_event_handler_set ((GdkEventFunc)gtk_main_do_event, NULL, NULL);
--- 197,203 ----
    /* Initialize "gdk". We pass along the 'argc' and 'argv'
     *  parameters as they contain information that GDK uses
     */
!   if (!gdk_init_check_display (argc, argv, display))
      return FALSE;
  
    gdk_event_handler_set ((GdkEventFunc)gtk_main_do_event, NULL, NULL);
***************
*** 416,427 ****
--- 417,445 ----
    return TRUE;
  }
  
+ gboolean
+ gtk_init_check (int	 *argc,
+ 		char   ***argv)
+ {
+    return gtk_init_check_display (argc, argv, 0);
+ }
+ 
  void
  gtk_init (int *argc, char ***argv)
  {
    if (!gtk_init_check (argc, argv))
      {
        g_warning ("cannot open display: %s", gdk_get_display ());
+       exit(1);
+     }
+ }
+ 
+ void
+ gtk_init_display (int *argc, char ***argv, void *display)
+ {
+   if (!gtk_init_check_display (argc, argv, display))
+     {
+       g_warning ("cannot use display: %s", gdk_get_display ());
        exit(1);
      }
  }

*** /usr/local/src/gtk+-1.2.0/gdk/gdk.c	Wed May 24 09:35:56 2000
--- gdk.c	Wed May 24 09:46:56 2000
***************
*** 113,118 ****
--- 113,119 ----
  						     *	the user in milliseconds.
  						     */
  static gint autorepeat;
+ static gint synchronize;
  
  static GSList *gdk_error_traps = NULL;               /* List of error traps */
  static GSList *gdk_error_trap_free_list = NULL;      /* Free list */
***************
*** 130,192 ****
  
  #endif /* G_ENABLE_DEBUG */
  
! /*
!  *--------------------------------------------------------------
!  * gdk_init_heck
!  *
!  *   Initialize the library for use.
!  *
!  * Arguments:
!  *   "argc" is the number of arguments.
!  *   "argv" is an array of strings.
!  *
!  * Results:
!  *   "argc" and "argv" are modified to reflect any arguments
!  *   which were not handled. (Such arguments should either
!  *   be handled by the application or dismissed). If initialization
!  *   fails, returns FALSE, otherwise TRUE.
!  *
!  * Side effects:
!  *   The library is initialized.
!  *
!  *--------------------------------------------------------------
!  */
  
- gboolean
- gdk_init_check (int	 *argc,
- 		char ***argv)
  {
    XKeyboardState keyboard_state;
-   gint synchronize;
-   gint i, j, k;
    XClassHint *class_hint;
!   gchar **argv_orig = NULL;
!   gint argc_orig = 0;
!   
!   if (gdk_initialized)
!     return TRUE;
    
!   if (g_thread_supported ())
!     gdk_threads_mutex = g_mutex_new ();
    
!   if (argc && argv)
      {
!       argc_orig = *argc;
!       
!       argv_orig = g_malloc ((argc_orig + 1) * sizeof (char*));
!       for (i = 0; i < argc_orig; i++)
! 	argv_orig[i] = g_strdup ((*argv)[i]);
!       argv_orig[argc_orig] = NULL;
      }
    
!   X_GETTIMEOFDAY (&start);
    
!   gdk_display_name = NULL;
    
!   XSetErrorHandler (gdk_x_error);
!   XSetIOErrorHandler (gdk_x_io_error);
    
!   synchronize = FALSE;
    
  #ifdef G_ENABLE_DEBUG
    {
--- 131,222 ----
  
  #endif /* G_ENABLE_DEBUG */
  
! static int
! gdk_x_connect ()
! 
! {
!   XSetErrorHandler (gdk_x_error);
!   XSetIOErrorHandler (gdk_x_io_error);
!   
!   gdk_display = XOpenDisplay (gdk_display_name);
!   if (!gdk_display)
!     return FALSE;
!   return TRUE;
! }
! 
! static int
! gdk_x_use_connection (Display *d)
! 
! {
!    gdk_display = d;
! /* XXX how to do this ?
!    gdk_display_name = XDisplayName ();
! */
! }
! 
! static int
! gdk_post_connect (int argc, char **argv)
  
  {
    XKeyboardState keyboard_state;
    XClassHint *class_hint;
! 
!   if (synchronize)
!     XSynchronize (gdk_display, True);
    
!   gdk_screen = DefaultScreen (gdk_display);
!   gdk_root_window = RootWindow (gdk_display, gdk_screen);
    
!   gdk_leader_window = XCreateSimpleWindow(gdk_display, gdk_root_window,
! 					  10, 10, 10, 10, 0, 0 , 0);
!   class_hint = XAllocClassHint();
!   class_hint->res_name = g_get_prgname ();
!   if (gdk_progclass == NULL)
      {
!       gdk_progclass = g_strdup (g_get_prgname ());
!       gdk_progclass[0] = toupper (gdk_progclass[0]);
      }
+   class_hint->res_class = gdk_progclass;
+   XmbSetWMProperties (gdk_display, gdk_leader_window,
+                       NULL, NULL, argv, argc, 
+                       NULL, NULL, class_hint);
+   XFree (class_hint);
    
!   gdk_wm_delete_window = XInternAtom (gdk_display, "WM_DELETE_WINDOW", True);
!   gdk_wm_take_focus = XInternAtom (gdk_display, "WM_TAKE_FOCUS", True);
!   gdk_wm_protocols = XInternAtom (gdk_display, "WM_PROTOCOLS", True);
!   gdk_wm_window_protocols[0] = gdk_wm_delete_window;
!   gdk_wm_window_protocols[1] = gdk_wm_take_focus;
!   gdk_selection_property = XInternAtom (gdk_display, "GDK_SELECTION", False);
    
!   XGetKeyboardControl (gdk_display, &keyboard_state);
!   autorepeat = keyboard_state.global_auto_repeat;
    
!   timer.tv_sec = 0;
!   timer.tv_usec = 0;
!   timerp = NULL;
    
!   g_atexit (gdk_exit_func);
!   
!   gdk_events_init ();
!   gdk_visual_init ();
!   gdk_window_init ();
!   gdk_image_init ();
!   gdk_input_init ();
!   gdk_dnd_init ();
! 
! #ifdef USE_XIM
!   gdk_im_open ();
! #endif
!   
! }
! 
! static void
! gdk_process_args (int *argc,
! 		  char ***argv)
! 
! {
!   gint i, j, k;
    
  #ifdef G_ENABLE_DEBUG
    {
***************
*** 376,449 ****
      }
    
    GDK_NOTE (MISC, g_message ("progname: \"%s\"", g_get_prgname ()));
    
!   gdk_display = XOpenDisplay (gdk_display_name);
!   if (!gdk_display)
!     return FALSE;
    
!   if (synchronize)
!     XSynchronize (gdk_display, True);
    
!   gdk_screen = DefaultScreen (gdk_display);
!   gdk_root_window = RootWindow (gdk_display, gdk_screen);
    
!   gdk_leader_window = XCreateSimpleWindow(gdk_display, gdk_root_window,
! 					  10, 10, 10, 10, 0, 0 , 0);
!   class_hint = XAllocClassHint();
!   class_hint->res_name = g_get_prgname ();
!   if (gdk_progclass == NULL)
      {
!       gdk_progclass = g_strdup (g_get_prgname ());
!       gdk_progclass[0] = toupper (gdk_progclass[0]);
      }
!   class_hint->res_class = gdk_progclass;
!   XmbSetWMProperties (gdk_display, gdk_leader_window,
!                       NULL, NULL, argv_orig, argc_orig, 
!                       NULL, NULL, class_hint);
!   XFree (class_hint);
!   
    for (i = 0; i < argc_orig; i++)
      g_free(argv_orig[i]);
    g_free(argv_orig);
-   
-   gdk_wm_delete_window = XInternAtom (gdk_display, "WM_DELETE_WINDOW", True);
-   gdk_wm_take_focus = XInternAtom (gdk_display, "WM_TAKE_FOCUS", True);
-   gdk_wm_protocols = XInternAtom (gdk_display, "WM_PROTOCOLS", True);
-   gdk_wm_window_protocols[0] = gdk_wm_delete_window;
-   gdk_wm_window_protocols[1] = gdk_wm_take_focus;
-   gdk_selection_property = XInternAtom (gdk_display, "GDK_SELECTION", False);
-   
-   XGetKeyboardControl (gdk_display, &keyboard_state);
-   autorepeat = keyboard_state.global_auto_repeat;
-   
-   timer.tv_sec = 0;
-   timer.tv_usec = 0;
-   timerp = NULL;
-   
-   g_atexit (gdk_exit_func);
-   
-   gdk_events_init ();
-   gdk_visual_init ();
-   gdk_window_init ();
-   gdk_image_init ();
-   gdk_input_init ();
-   gdk_dnd_init ();
  
- #ifdef USE_XIM
-   gdk_im_open ();
- #endif
-   
    gdk_initialized = 1;
  
    return TRUE;
  }
  
  void
  gdk_init (int *argc, char ***argv)
  {
    if (!gdk_init_check (argc, argv))
      {
        g_warning ("cannot open display: %s", gdk_get_display ());
        exit(1);
      }
  }
--- 406,523 ----
      }
    
    GDK_NOTE (MISC, g_message ("progname: \"%s\"", g_get_prgname ()));
+ }  
+ 
+ 
+ /*
+  *--------------------------------------------------------------
+  * gdk_init_check_display
+  *
+  *   Initialize the library for use.
+  *
+  * Arguments:
+  *   "argc" is the number of arguments.
+  *   "argv" is an array of strings.
+  *   "display" is a pointer to an X11 Display type, and can be NULL
+  *
+  * Results:
+  *   "argc" and "argv" are modified to reflect any arguments
+  *   which were not handled. (Such arguments should either
+  *   be handled by the application or dismissed). If initialization
+  *   fails, returns FALSE, otherwise TRUE.
+  *
+  *   if "display" was NULL, a connection to the default X server 
+  *   will be attempted, and FALSE returned if this fails.
+  *
+  *   if "display" was not NULL, the existing connection to an X server 
+  *   implied by "display" will be used. Note that if this path is
+  *   followed, GDK does not install any X Error or IO handlers, since
+  *   it assumes that whatever setup the connection to the display
+  *   has done this.
+  *
+  * Side effects:
+  *   The library is initialized.
+  *
+  *--------------------------------------------------------------
+  */
+ 
+ gboolean
+ gdk_init_check_display (int	*argc,
+ 			char  ***argv,
+ 			Display *display)
+ {
+   gchar **argv_orig = NULL;
+   gint argc_orig = 0;
+   gint i;
+ 
+   if (gdk_initialized)
+     return TRUE;
    
!   if (g_thread_supported ())
!     gdk_threads_mutex = g_mutex_new ();
! 
!   X_GETTIMEOFDAY (&start);
    
!   gdk_display_name = NULL;
!   synchronize = FALSE;
! 
!   if (argc && argv)
!     {
!       argc_orig = *argc;
!       
!       argv_orig = g_malloc ((argc_orig + 1) * sizeof (char*));
!       for (i = 0; i < argc_orig; i++)
! 	argv_orig[i] = g_strdup ((*argv)[i]);
!       argv_orig[argc_orig] = NULL;
!     }
    
!   gdk_process_args (argc, argv);
    
!   if (display) 
      {
!       if (!gdk_x_use_connection (display))
!         return FALSE;
!     } 
!   else 
!     {
!       if (!gdk_x_connect()) 
!         return FALSE;
      }
! 
!   gdk_post_connect (argc_orig, argv_orig);	  
! 
    for (i = 0; i < argc_orig; i++)
      g_free(argv_orig[i]);
    g_free(argv_orig);
  
    gdk_initialized = 1;
  
    return TRUE;
  }
  
+ gboolean
+ gdk_init_check (int	*argc,
+ 		char  ***argv)
+ {
+    return gdk_init_check_display (argc, argv, 0);
+ }	
+ 
  void
  gdk_init (int *argc, char ***argv)
  {
    if (!gdk_init_check (argc, argv))
      {
        g_warning ("cannot open display: %s", gdk_get_display ());
+       exit(1);
+     }
+ }
+ 
+ void
+ gdk_init_display (int *argc, char ***argv, Display *d)
+ {
+   if (!gdk_init_check_display (argc, argv, d))
+     {
+       g_warning ("cannot use display: %s", gdk_get_display ());
        exit(1);
      }
  }




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