]> Pileus Git - ~andy/gtk/blob - gdk/x11/gdkmain-x11.c
3c5f7de8af7f1082dda4f57ab4b803c657a8be8d
[~andy/gtk] / gdk / x11 / gdkmain-x11.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 #include "config.h"
28
29 #include <glib/gprintf.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <unistd.h>
33 #include <limits.h>
34 #include <errno.h>
35
36 #include <X11/Xatom.h>
37 #include <X11/Xlib.h>
38 #include <X11/Xutil.h>
39
40 #ifdef HAVE_XKB
41 #include <X11/XKBlib.h>
42 #endif
43
44 #include "gdk.h"
45
46 #include "gdkx.h"
47 #include "gdkdisplay-x11.h"
48 #include "gdkinternals.h"
49 #include "gdkregion-generic.h"
50 #include "gdkinputprivate.h"
51
52 #include <pango/pangox.h>
53
54 typedef struct _GdkPredicate  GdkPredicate;
55 typedef struct _GdkErrorTrap  GdkErrorTrap;
56
57 struct _GdkPredicate
58 {
59   GdkEventFunc func;
60   gpointer data;
61 };
62
63 struct _GdkErrorTrap
64 {
65   int (*old_handler) (Display *, XErrorEvent *);
66   gint error_warnings;
67   gint error_code;
68 };
69
70 /* 
71  * Private function declarations
72  */
73
74 #ifndef HAVE_XCONVERTCASE
75 static void      gdkx_XConvertCase      (KeySym        symbol,
76                                          KeySym       *lower,
77                                          KeySym       *upper);
78 #define XConvertCase gdkx_XConvertCase
79 #endif
80
81 static int          gdk_x_error                  (Display     *display, 
82                                                   XErrorEvent *error);
83 static int          gdk_x_io_error               (Display     *display);
84
85 /* Private variable declarations
86  */
87 static GSList *gdk_error_traps = NULL;               /* List of error traps */
88 static GSList *gdk_error_trap_free_list = NULL;      /* Free list */
89
90 GdkArgDesc _gdk_windowing_args[] = {
91   { "sync",        GDK_ARG_BOOL,     &_gdk_synchronize,     (GdkArgFunc)NULL },
92   { NULL }
93 };
94
95 void
96 _gdk_windowing_init (gint    *argc,
97                      gchar ***argv)
98 {
99   _gdk_x11_initialize_locale ();
100   
101   XSetErrorHandler (gdk_x_error);
102   XSetIOErrorHandler (gdk_x_io_error);
103
104   _gdk_selection_property = gdk_atom_intern ("GDK_SELECTION", FALSE);
105 }
106
107 void
108 gdk_set_use_xshm (gboolean use_xshm)
109 {
110 }
111
112 gboolean
113 gdk_get_use_xshm (void)
114 {
115   return GDK_DISPLAY_X11 (gdk_display_get_default ())->use_xshm;
116 }
117
118 static GdkGrabStatus
119 gdk_x11_convert_grab_status (gint status)
120 {
121   switch (status)
122     {
123     case GrabSuccess:
124       return GDK_GRAB_SUCCESS;
125     case AlreadyGrabbed:
126       return GDK_GRAB_ALREADY_GRABBED;
127     case GrabInvalidTime:
128       return GDK_GRAB_INVALID_TIME;
129     case GrabNotViewable:
130       return GDK_GRAB_NOT_VIEWABLE;
131     case GrabFrozen:
132       return GDK_GRAB_FROZEN;
133     }
134
135   g_assert_not_reached();
136
137   return 0;
138 }
139
140 /*
141  *--------------------------------------------------------------
142  * gdk_pointer_grab
143  *
144  *   Grabs the pointer to a specific window
145  *
146  * Arguments:
147  *   "window" is the window which will receive the grab
148  *   "owner_events" specifies whether events will be reported as is,
149  *     or relative to "window"
150  *   "event_mask" masks only interesting events
151  *   "confine_to" limits the cursor movement to the specified window
152  *   "cursor" changes the cursor for the duration of the grab
153  *   "time" specifies the time
154  *
155  * Results:
156  *
157  * Side effects:
158  *   requires a corresponding call to gdk_pointer_ungrab
159  *
160  *--------------------------------------------------------------
161  */
162
163 GdkGrabStatus
164 gdk_pointer_grab (GdkWindow *     window,
165                   gboolean        owner_events,
166                   GdkEventMask    event_mask,
167                   GdkWindow *     confine_to,
168                   GdkCursor *     cursor,
169                   guint32         time)
170 {
171   gint return_val;
172   GdkCursorPrivate *cursor_private;
173   guint xevent_mask;
174   Window xwindow;
175   Window xconfine_to;
176   Cursor xcursor;
177   unsigned long serial;
178   int i;
179   
180   g_return_val_if_fail (window != NULL, 0);
181   g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
182   g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0);
183   
184   cursor_private = (GdkCursorPrivate*) cursor;
185   
186   xwindow = GDK_WINDOW_XID (window);
187   serial = NextRequest (GDK_WINDOW_XDISPLAY (window));
188   
189   if (!confine_to || GDK_WINDOW_DESTROYED (confine_to))
190     xconfine_to = None;
191   else
192     xconfine_to = GDK_WINDOW_XID (confine_to);
193   
194   if (!cursor)
195     xcursor = None;
196   else
197     xcursor = cursor_private->xcursor;
198   
199   
200   xevent_mask = 0;
201   for (i = 0; i < _gdk_nenvent_masks; i++)
202     {
203       if (event_mask & (1 << (i + 1)))
204         xevent_mask |= _gdk_event_mask_table[i];
205     }
206   
207   return_val = _gdk_input_grab_pointer (window,
208                                         owner_events,
209                                         event_mask,
210                                         confine_to,
211                                         time);
212
213   if (return_val == GrabSuccess)
214     {
215       if (!GDK_WINDOW_DESTROYED (window))
216         {
217 #ifdef G_ENABLE_DEBUG
218           if (_gdk_debug_flags & GDK_DEBUG_NOGRABS)
219             return_val = GrabSuccess;
220           else
221 #endif
222             return_val = XGrabPointer (GDK_WINDOW_XDISPLAY (window),
223                                        xwindow,
224                                        owner_events,
225                                        xevent_mask,
226                                        GrabModeAsync, GrabModeAsync,
227                                        xconfine_to,
228                                        xcursor,
229                                        time);
230         }
231       else
232         return_val = AlreadyGrabbed;
233     }
234   
235   if (return_val == GrabSuccess)
236     {
237       GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window));
238       display_x11->pointer_xgrab_window = (GdkWindowObject *)window;
239       display_x11->pointer_xgrab_serial = serial;
240       display_x11->pointer_xgrab_owner_events = owner_events;
241     }
242
243   return gdk_x11_convert_grab_status (return_val);
244 }
245
246 /**
247  * gdk_pointer_grab_info_libgtk_only:
248  * @display: the #GdkDisplay for which to get the grab information
249  * @grab_window: location to store current grab window
250  * @owner_events: location to store boolean indicating whether
251  *   the @owner_events flag to gdk_pointer_grab() was %TRUE.
252  * 
253  * Determines information about the current pointer grab.
254  * This is not public API and must not be used by applications.
255  * 
256  * Return value: %TRUE if this application currently has the
257  *  pointer grabbed.
258  **/
259 gboolean
260 gdk_pointer_grab_info_libgtk_only (GdkDisplay *display,
261                                    GdkWindow **grab_window,
262                                    gboolean   *owner_events)
263 {
264   GdkDisplayX11 *display_x11;
265   
266   g_return_val_if_fail (GDK_IS_DISPLAY (display), False);
267
268   display_x11 = GDK_DISPLAY_X11 (display);
269
270   if (display_x11->pointer_xgrab_window)
271     {
272       if (grab_window)
273         *grab_window = (GdkWindow *)display_x11->pointer_xgrab_window;
274       if (owner_events)
275         *owner_events = display_x11->pointer_xgrab_owner_events;
276
277       return TRUE;
278     }
279   else
280     return FALSE;
281 }
282
283 /*
284  *--------------------------------------------------------------
285  * gdk_keyboard_grab
286  *
287  *   Grabs the keyboard to a specific window
288  *
289  * Arguments:
290  *   "window" is the window which will receive the grab
291  *   "owner_events" specifies whether events will be reported as is,
292  *     or relative to "window"
293  *   "time" specifies the time
294  *
295  * Results:
296  *
297  * Side effects:
298  *   requires a corresponding call to gdk_keyboard_ungrab
299  *
300  *--------------------------------------------------------------
301  */
302
303 GdkGrabStatus
304 gdk_keyboard_grab (GdkWindow *     window,
305                    gboolean        owner_events,
306                    guint32         time)
307 {
308   gint return_val;
309   unsigned long serial;
310   
311   g_return_val_if_fail (window != NULL, 0);
312   g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
313   
314   serial = NextRequest (GDK_WINDOW_XDISPLAY (window));
315
316   if (!GDK_WINDOW_DESTROYED (window))
317     {
318 #ifdef G_ENABLE_DEBUG
319       if (_gdk_debug_flags & GDK_DEBUG_NOGRABS)
320         return_val = GrabSuccess;
321       else
322 #endif
323         return_val = XGrabKeyboard (GDK_WINDOW_XDISPLAY (window),
324                                     GDK_WINDOW_XID (window),
325                                     owner_events,
326                                     GrabModeAsync, GrabModeAsync,
327                                     time);
328     }
329   else
330     return_val = AlreadyGrabbed;
331
332   if (return_val == GrabSuccess)
333     {
334       GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (gdk_drawable_get_display (window));
335       display_x11->keyboard_xgrab_window = (GdkWindowObject *)window;
336       display_x11->keyboard_xgrab_serial = serial;
337       display_x11->keyboard_xgrab_owner_events = owner_events;
338     }
339
340   return gdk_x11_convert_grab_status (return_val);
341 }
342
343 /**
344  * gdk_keyboard_grab_info_libgtk_only:
345  * @display: the display for which to get the grab information
346  * @grab_window: location to store current grab window
347  * @owner_events: location to store boolean indicating whether
348  *   the @owner_events flag to gdk_keyboard_grab() was %TRUE.
349  * 
350  * Determines information about the current keyboard grab.
351  * This is not public API and must not be used by applications.
352  * 
353  * Return value: %TRUE if this application currently has the
354  *  keyboard grabbed.
355  **/
356 gboolean
357 gdk_keyboard_grab_info_libgtk_only (GdkDisplay *display,
358                                     GdkWindow **grab_window,
359                                     gboolean   *owner_events)
360 {
361   GdkDisplayX11 *display_x11;
362   
363   g_return_val_if_fail (GDK_IS_DISPLAY (display), False);
364
365   display_x11 = GDK_DISPLAY_X11 (display);
366
367   if (display_x11->keyboard_xgrab_window)
368     {
369       if (grab_window)
370         *grab_window = (GdkWindow *)display_x11->keyboard_xgrab_window;
371       if (owner_events)
372         *owner_events = display_x11->keyboard_xgrab_owner_events;
373
374       return TRUE;
375     }
376   else
377     return FALSE;
378 }
379
380 /**
381  * _gdk_xgrab_check_unmap:
382  * @window: a #GdkWindow
383  * @serial: serial from Unmap event (or from NextRequest(display)
384  *   if the unmap is being done by this client.)
385  * 
386  * Checks to see if an unmap request or event causes the current
387  * grab window to become not viewable, and if so, clear the
388  * the pointer we keep to it.
389  **/
390 void
391 _gdk_xgrab_check_unmap (GdkWindow *window,
392                         gulong     serial)
393 {
394   GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (gdk_drawable_get_display (window));
395   
396   if (display_x11->pointer_xgrab_window && 
397       serial >= display_x11->pointer_xgrab_serial)
398     {
399       GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
400       GdkWindowObject *tmp = display_x11->pointer_xgrab_window;
401
402       while (tmp && tmp != private)
403         tmp = tmp->parent;
404
405       if (tmp)
406         display_x11->pointer_xgrab_window = NULL;  
407     }
408
409   if (display_x11->keyboard_xgrab_window &&
410       serial >= display_x11->keyboard_xgrab_serial)
411     {
412       GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
413       GdkWindowObject *tmp = display_x11->keyboard_xgrab_window;
414       
415
416       while (tmp && tmp != private)
417         tmp = tmp->parent;
418
419       if (tmp)
420         display_x11->keyboard_xgrab_window = NULL;  
421     }
422 }
423
424 /**
425  * _gdk_xgrab_check_destroy:
426  * @window: a #GdkWindow
427  * 
428  * Checks to see if window is the current grab window, and if
429  * so, clear the current grab window.
430  **/
431 void
432 _gdk_xgrab_check_destroy (GdkWindow *window)
433 {
434   GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (gdk_drawable_get_display (window));
435   
436   if ((GdkWindowObject *)window == display_x11->pointer_xgrab_window)
437      display_x11->pointer_xgrab_window = NULL;
438
439   if ((GdkWindowObject *)window ==  display_x11->keyboard_xgrab_window)
440      display_x11->keyboard_xgrab_window = NULL;
441 }
442
443 void
444 _gdk_windowing_display_set_sm_client_id (GdkDisplay  *display,
445                                          const gchar *sm_client_id)
446 {
447   GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
448
449   if (display->closed)
450     return;
451
452   if (sm_client_id && strcmp (sm_client_id, ""))
453     {
454       XChangeProperty (display_x11->xdisplay, display_x11->leader_window,
455                        gdk_x11_get_xatom_by_name_for_display (display, "SM_CLIENT_ID"),
456                        XA_STRING, 8, PropModeReplace, sm_client_id,
457                        strlen (sm_client_id));
458     }
459   else
460     XDeleteProperty (display_x11->xdisplay, display_x11->leader_window,
461                      gdk_x11_get_xatom_by_name_for_display (display, "SM_CLIENT_ID"));
462 }
463
464 /* Close all open displays
465  */
466 void
467 _gdk_windowing_exit (void)
468 {
469   GSList *tmp_list = _gdk_displays;
470     
471   while (tmp_list)
472     {
473       XCloseDisplay (GDK_DISPLAY_XDISPLAY (tmp_list->data));
474       
475       tmp_list = tmp_list->next;
476   }
477 }
478
479 /*
480  *--------------------------------------------------------------
481  * gdk_x_error
482  *
483  *   The X error handling routine.
484  *
485  * Arguments:
486  *   "display" is the X display the error orignated from.
487  *   "error" is the XErrorEvent that we are handling.
488  *
489  * Results:
490  *   Either we were expecting some sort of error to occur,
491  *   in which case we set the "_gdk_error_code" flag, or this
492  *   error was unexpected, in which case we will print an
493  *   error message and exit. (Since trying to continue will
494  *   most likely simply lead to more errors).
495  *
496  * Side effects:
497  *
498  *--------------------------------------------------------------
499  */
500
501 static int
502 gdk_x_error (Display     *display,
503              XErrorEvent *error)
504 {
505   if (error->error_code)
506     {
507       if (_gdk_error_warnings)
508         {
509           gchar buf[64];
510           gchar *msg;
511           
512           XGetErrorText (display, error->error_code, buf, 63);
513
514           msg =
515             g_strdup_printf ("The program '%s' received an X Window System error.\n"
516                              "This probably reflects a bug in the program.\n"
517                              "The error was '%s'.\n"
518                              "  (Details: serial %ld error_code %d request_code %d minor_code %d)\n"
519                              "  (Note to programmers: normally, X errors are reported asynchronously;\n"
520                              "   that is, you will receive the error a while after causing it.\n"
521                              "   To debug your program, run it with the --sync command line\n"
522                              "   option to change this behavior. You can then get a meaningful\n"
523                              "   backtrace from your debugger if you break on the gdk_x_error() function.)",
524                              g_get_prgname (),
525                              buf,
526                              error->serial, 
527                              error->error_code, 
528                              error->request_code,
529                              error->minor_code);
530           
531 #ifdef G_ENABLE_DEBUG     
532           g_error ("%s", msg);
533 #else /* !G_ENABLE_DEBUG */
534           g_fprintf (stderr, "%s\n", msg);
535
536           exit (1);
537 #endif /* G_ENABLE_DEBUG */
538         }
539       _gdk_error_code = error->error_code;
540     }
541   
542   return 0;
543 }
544
545 /*
546  *--------------------------------------------------------------
547  * gdk_x_io_error
548  *
549  *   The X I/O error handling routine.
550  *
551  * Arguments:
552  *   "display" is the X display the error orignated from.
553  *
554  * Results:
555  *   An X I/O error basically means we lost our connection
556  *   to the X server. There is not much we can do to
557  *   continue, so simply print an error message and exit.
558  *
559  * Side effects:
560  *
561  *--------------------------------------------------------------
562  */
563
564 static int
565 gdk_x_io_error (Display *display)
566 {
567   /* This is basically modelled after the code in XLib. We need
568    * an explicit error handler here, so we can disable our atexit()
569    * which would otherwise cause a nice segfault.
570    * We fprintf(stderr, instead of g_warning() because g_warning()
571    * could possibly be redirected to a dialog
572    */
573   if (errno == EPIPE)
574     {
575       g_fprintf (stderr,
576                "The application '%s' lost its connection to the display %s;\n"
577                "most likely the X server was shut down or you killed/destroyed\n"
578                "the application.\n",
579                g_get_prgname (),
580                display ? DisplayString (display) : gdk_get_display_arg_name ());
581     }
582   else
583     {
584       g_fprintf (stderr, "%s: Fatal IO error %d (%s) on X server %s.\n",
585                g_get_prgname (),
586                errno, g_strerror (errno),
587                display ? DisplayString (display) : gdk_get_display_arg_name ());
588     }
589
590   exit(1);
591 }
592
593 /*************************************************************
594  * gdk_error_trap_push:
595  *     Push an error trap. X errors will be trapped until
596  *     the corresponding gdk_error_pop(), which will return
597  *     the error code, if any.
598  *   arguments:
599  *     
600  *   results:
601  *************************************************************/
602
603 void
604 gdk_error_trap_push (void)
605 {
606   GSList *node;
607   GdkErrorTrap *trap;
608
609   if (gdk_error_trap_free_list)
610     {
611       node = gdk_error_trap_free_list;
612       gdk_error_trap_free_list = gdk_error_trap_free_list->next;
613     }
614   else
615     {
616       node = g_slist_alloc ();
617       node->data = g_new (GdkErrorTrap, 1);
618     }
619
620   node->next = gdk_error_traps;
621   gdk_error_traps = node;
622   
623   trap = node->data;
624   trap->old_handler = XSetErrorHandler (gdk_x_error);
625   trap->error_code = _gdk_error_code;
626   trap->error_warnings = _gdk_error_warnings;
627
628   _gdk_error_code = 0;
629   _gdk_error_warnings = 0;
630 }
631
632 /*************************************************************
633  * gdk_error_trap_pop:
634  *     Pop an error trap added with gdk_error_push()
635  *   arguments:
636  *     
637  *   results:
638  *     0, if no error occured, otherwise the error code.
639  *************************************************************/
640
641 gint
642 gdk_error_trap_pop (void)
643 {
644   GSList *node;
645   GdkErrorTrap *trap;
646   gint result;
647
648   g_return_val_if_fail (gdk_error_traps != NULL, 0);
649
650   node = gdk_error_traps;
651   gdk_error_traps = gdk_error_traps->next;
652
653   node->next = gdk_error_trap_free_list;
654   gdk_error_trap_free_list = node;
655   
656   result = _gdk_error_code;
657   
658   trap = node->data;
659   _gdk_error_code = trap->error_code;
660   _gdk_error_warnings = trap->error_warnings;
661   XSetErrorHandler (trap->old_handler);
662   
663   return result;
664 }
665
666 gchar *
667 gdk_get_display (void)
668 {
669   return g_strdup (gdk_display_get_name (gdk_display_get_default ()));
670 }
671
672 /**
673  * _gdk_send_xevent:
674  * @display: #GdkDisplay which @window is on
675  * @window: window ID to which to send the event
676  * @propagate: %TRUE if the event should be propagated if the target window
677  *             doesn't handle it.
678  * @event_mask: event mask to match against, or 0 to send it to @window
679  *              without regard to event masks.
680  * @event_send: #XEvent to send
681  * 
682  * Send an event, like XSendEvent(), but trap errors and check
683  * the result.
684  * 
685  * Return value: %TRUE if sending the event succeeded.
686  **/
687 gint 
688 _gdk_send_xevent (GdkDisplay *display,
689                   Window      window, 
690                   gboolean    propagate, 
691                   glong       event_mask,
692                   XEvent     *event_send)
693 {
694   gboolean result;
695
696   if (display->closed)
697     return FALSE;
698
699   gdk_error_trap_push ();
700   result = XSendEvent (GDK_DISPLAY_XDISPLAY (display), window, 
701                        propagate, event_mask, event_send);
702   XSync (GDK_DISPLAY_XDISPLAY (display), False);
703   
704   return result && gdk_error_trap_pop() == Success;
705 }
706
707 void
708 _gdk_region_get_xrectangles (GdkRegion   *region,
709                              gint         x_offset,
710                              gint         y_offset,
711                              XRectangle **rects,
712                              gint        *n_rects)
713 {
714   XRectangle *rectangles = g_new (XRectangle, region->numRects);
715   GdkRegionBox *boxes = region->rects;
716   gint i;
717   
718   for (i = 0; i < region->numRects; i++)
719     {
720       rectangles[i].x = CLAMP (boxes[i].x1 + x_offset, G_MINSHORT, G_MAXSHORT);
721       rectangles[i].y = CLAMP (boxes[i].y1 + y_offset, G_MINSHORT, G_MAXSHORT);
722       rectangles[i].width = CLAMP (boxes[i].x2 + x_offset, G_MINSHORT, G_MAXSHORT) - rectangles[i].x;
723       rectangles[i].height = CLAMP (boxes[i].y2 + y_offset, G_MINSHORT, G_MAXSHORT) - rectangles[i].y;
724     }
725
726   *rects = rectangles;
727   *n_rects = region->numRects;
728 }
729
730 /**
731  * gdk_x11_grab_server:
732  * 
733  * Call gdk_x11_display_grab() on the default display. 
734  * To ungrab the server again, use gdk_x11_ungrab_server(). 
735  *
736  * gdk_x11_grab_server()/gdk_x11_ungrab_server() calls can be nested.
737  **/ 
738 void
739 gdk_x11_grab_server ()
740 {
741   gdk_x11_display_grab (gdk_display_get_default ());
742 }
743
744 /**
745  * gdk_x11_ungrab_server:
746  *
747  * Ungrab the default display after it has been grabbed with 
748  * gdk_x11_grab_server(). 
749  **/
750 void
751 gdk_x11_ungrab_server ()
752 {
753   gdk_x11_display_ungrab (gdk_display_get_default ());
754 }
755
756 /**
757  * gdk_x11_get_default_screen:
758  * 
759  * Gets the default GTK+ screen number.
760  * 
761  * Return value: returns the screen number specified by
762  *   the --display command line option or the DISPLAY environment
763  *   variable when gdk_init() calls XOpenDisplay().
764  **/
765 gint
766 gdk_x11_get_default_screen (void)
767 {
768   return gdk_screen_get_number (gdk_screen_get_default ());
769 }
770
771 /**
772  * gdk_x11_get_default_root_xwindow:
773  * 
774  * Gets the root window of the default screen 
775  * (see gdk_x11_get_default_screen()).  
776  * 
777  * Return value: an Xlib <type>Window</type>.
778  **/
779 Window
780 gdk_x11_get_default_root_xwindow (void)
781 {
782   return GDK_SCREEN_XROOTWIN (gdk_screen_get_default ());
783 }
784
785 /**
786  * gdk_x11_get_default_xdisplay:
787  * 
788  * Gets the default GTK+ display.
789  * 
790  * Return value: the Xlib <type>Display*</type> for the display
791  * specified in the <option>--display</option> command line option 
792  * or the <envar>DISPLAY</envar> environment variable.
793  **/
794 Display *
795 gdk_x11_get_default_xdisplay (void)
796 {
797   return GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
798 }
799
800