]> Pileus Git - ~andy/gtk/blob - gdk/x11/gdkmain-x11.c
2a7e49d25da5c0ade93f47f2bbed29800f0c6754
[~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 <stdio.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_windowing_set_default_display (GdkDisplay *display)
109 {
110   if (display)
111     gdk_display = GDK_DISPLAY_XDISPLAY (display);
112   else
113     gdk_display = NULL;
114 }
115
116 void
117 gdk_set_use_xshm (gboolean use_xshm)
118 {
119 }
120
121 gboolean
122 gdk_get_use_xshm (void)
123 {
124   return GDK_DISPLAY_X11 (gdk_display_get_default ())->use_xshm;
125 }
126
127 static GdkGrabStatus
128 gdk_x11_convert_grab_status (gint status)
129 {
130   switch (status)
131     {
132     case GrabSuccess:
133       return GDK_GRAB_SUCCESS;
134     case AlreadyGrabbed:
135       return GDK_GRAB_ALREADY_GRABBED;
136     case GrabInvalidTime:
137       return GDK_GRAB_INVALID_TIME;
138     case GrabNotViewable:
139       return GDK_GRAB_NOT_VIEWABLE;
140     case GrabFrozen:
141       return GDK_GRAB_FROZEN;
142     }
143
144   g_assert_not_reached();
145
146   return 0;
147 }
148
149 /*
150  *--------------------------------------------------------------
151  * gdk_pointer_grab
152  *
153  *   Grabs the pointer to a specific window
154  *
155  * Arguments:
156  *   "window" is the window which will receive the grab
157  *   "owner_events" specifies whether events will be reported as is,
158  *     or relative to "window"
159  *   "event_mask" masks only interesting events
160  *   "confine_to" limits the cursor movement to the specified window
161  *   "cursor" changes the cursor for the duration of the grab
162  *   "time" specifies the time
163  *
164  * Results:
165  *
166  * Side effects:
167  *   requires a corresponding call to gdk_pointer_ungrab
168  *
169  *--------------------------------------------------------------
170  */
171
172 GdkGrabStatus
173 gdk_pointer_grab (GdkWindow *     window,
174                   gboolean        owner_events,
175                   GdkEventMask    event_mask,
176                   GdkWindow *     confine_to,
177                   GdkCursor *     cursor,
178                   guint32         time)
179 {
180   gint return_val;
181   GdkCursorPrivate *cursor_private;
182   guint xevent_mask;
183   Window xwindow;
184   Window xconfine_to;
185   Cursor xcursor;
186   unsigned long serial;
187   int i;
188   
189   g_return_val_if_fail (window != NULL, 0);
190   g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
191   g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0);
192   
193   cursor_private = (GdkCursorPrivate*) cursor;
194   
195   xwindow = GDK_WINDOW_XID (window);
196   serial = NextRequest (GDK_WINDOW_XDISPLAY (window));
197   
198   if (!confine_to || GDK_WINDOW_DESTROYED (confine_to))
199     xconfine_to = None;
200   else
201     xconfine_to = GDK_WINDOW_XID (confine_to);
202   
203   if (!cursor)
204     xcursor = None;
205   else
206     xcursor = cursor_private->xcursor;
207   
208   
209   xevent_mask = 0;
210   for (i = 0; i < _gdk_nenvent_masks; i++)
211     {
212       if (event_mask & (1 << (i + 1)))
213         xevent_mask |= _gdk_event_mask_table[i];
214     }
215   
216   return_val = _gdk_input_grab_pointer (window,
217                                         owner_events,
218                                         event_mask,
219                                         confine_to,
220                                         time);
221
222   if (return_val == GrabSuccess)
223     {
224       if (!GDK_WINDOW_DESTROYED (window))
225         {
226 #ifdef G_ENABLE_DEBUG
227           if (_gdk_debug_flags & GDK_DEBUG_NOGRABS)
228             return_val = GrabSuccess;
229           else
230 #endif
231             return_val = XGrabPointer (GDK_WINDOW_XDISPLAY (window),
232                                        xwindow,
233                                        owner_events,
234                                        xevent_mask,
235                                        GrabModeAsync, GrabModeAsync,
236                                        xconfine_to,
237                                        xcursor,
238                                        time);
239         }
240       else
241         return_val = AlreadyGrabbed;
242     }
243   
244   if (return_val == GrabSuccess)
245     {
246       GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window));
247       display_x11->pointer_xgrab_window = (GdkWindowObject *)window;
248       display_x11->pointer_xgrab_serial = serial;
249       display_x11->pointer_xgrab_owner_events = owner_events;
250     }
251
252   return gdk_x11_convert_grab_status (return_val);
253 }
254
255 /**
256  * gdk_pointer_grab_info_libgtk_only:
257  * @display: the #GdkDisplay for which to get the grab information
258  * @grab_window: location to store current grab window
259  * @owner_events: location to store boolean indicating whether
260  *   the @owner_events flag to gdk_pointer_grab() was %TRUE.
261  * 
262  * Determines information about the current pointer grab.
263  * This is not public API and must not be used by applications.
264  * 
265  * Return value: %TRUE if this application currently has the
266  *  pointer grabbed.
267  **/
268 gboolean
269 gdk_pointer_grab_info_libgtk_only (GdkDisplay *display,
270                                    GdkWindow **grab_window,
271                                    gboolean   *owner_events)
272 {
273   GdkDisplayX11 *display_x11;
274   
275   g_return_val_if_fail (GDK_IS_DISPLAY (display), False);
276
277   display_x11 = GDK_DISPLAY_X11 (display);
278
279   if (display_x11->pointer_xgrab_window)
280     {
281       if (grab_window)
282         *grab_window = (GdkWindow *)display_x11->pointer_xgrab_window;
283       if (owner_events)
284         *owner_events = display_x11->pointer_xgrab_owner_events;
285
286       return TRUE;
287     }
288   else
289     return FALSE;
290 }
291
292 /*
293  *--------------------------------------------------------------
294  * gdk_keyboard_grab
295  *
296  *   Grabs the keyboard to a specific window
297  *
298  * Arguments:
299  *   "window" is the window which will receive the grab
300  *   "owner_events" specifies whether events will be reported as is,
301  *     or relative to "window"
302  *   "time" specifies the time
303  *
304  * Results:
305  *
306  * Side effects:
307  *   requires a corresponding call to gdk_keyboard_ungrab
308  *
309  *--------------------------------------------------------------
310  */
311
312 GdkGrabStatus
313 gdk_keyboard_grab (GdkWindow *     window,
314                    gboolean        owner_events,
315                    guint32         time)
316 {
317   gint return_val;
318   unsigned long serial;
319   
320   g_return_val_if_fail (window != NULL, 0);
321   g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
322   
323   serial = NextRequest (GDK_WINDOW_XDISPLAY (window));
324
325   if (!GDK_WINDOW_DESTROYED (window))
326     {
327 #ifdef G_ENABLE_DEBUG
328       if (_gdk_debug_flags & GDK_DEBUG_NOGRABS)
329         return_val = GrabSuccess;
330       else
331 #endif
332         return_val = XGrabKeyboard (GDK_WINDOW_XDISPLAY (window),
333                                     GDK_WINDOW_XID (window),
334                                     owner_events,
335                                     GrabModeAsync, GrabModeAsync,
336                                     time);
337     }
338   else
339     return_val = AlreadyGrabbed;
340
341   if (return_val == GrabSuccess)
342     {
343       GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (gdk_drawable_get_display (window));
344       display_x11->keyboard_xgrab_window = (GdkWindowObject *)window;
345       display_x11->keyboard_xgrab_serial = serial;
346       display_x11->keyboard_xgrab_owner_events = owner_events;
347     }
348
349   return gdk_x11_convert_grab_status (return_val);
350 }
351
352 /**
353  * gdk_keyboard_grab_info_libgtk_only:
354  * @display: the display for which to get the grab information
355  * @grab_window: location to store current grab window
356  * @owner_events: location to store boolean indicating whether
357  *   the @owner_events flag to gdk_keyboard_grab() was %TRUE.
358  * 
359  * Determines information about the current keyboard grab.
360  * This is not public API and must not be used by applications.
361  * 
362  * Return value: %TRUE if this application currently has the
363  *  keyboard grabbed.
364  **/
365 gboolean
366 gdk_keyboard_grab_info_libgtk_only (GdkDisplay *display,
367                                     GdkWindow **grab_window,
368                                     gboolean   *owner_events)
369 {
370   GdkDisplayX11 *display_x11;
371   
372   g_return_val_if_fail (GDK_IS_DISPLAY (display), False);
373
374   display_x11 = GDK_DISPLAY_X11 (display);
375
376   if (display_x11->keyboard_xgrab_window)
377     {
378       if (grab_window)
379         *grab_window = (GdkWindow *)display_x11->keyboard_xgrab_window;
380       if (owner_events)
381         *owner_events = display_x11->keyboard_xgrab_owner_events;
382
383       return TRUE;
384     }
385   else
386     return FALSE;
387 }
388
389 /**
390  * _gdk_xgrab_check_unmap:
391  * @window: a #GdkWindow
392  * @serial: serial from Unmap event (or from NextRequest(display)
393  *   if the unmap is being done by this client.)
394  * 
395  * Checks to see if an unmap request or event causes the current
396  * grab window to become not viewable, and if so, clear the
397  * the pointer we keep to it.
398  **/
399 void
400 _gdk_xgrab_check_unmap (GdkWindow *window,
401                         gulong     serial)
402 {
403   GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (gdk_drawable_get_display (window));
404   
405   if (display_x11->pointer_xgrab_window && 
406       serial >= display_x11->pointer_xgrab_serial)
407     {
408       GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
409       GdkWindowObject *tmp = display_x11->pointer_xgrab_window;
410
411       while (tmp && tmp != private)
412         tmp = tmp->parent;
413
414       if (tmp)
415         display_x11->pointer_xgrab_window = NULL;  
416     }
417
418   if (display_x11->keyboard_xgrab_window &&
419       serial >= display_x11->keyboard_xgrab_serial)
420     {
421       GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
422       GdkWindowObject *tmp = display_x11->keyboard_xgrab_window;
423       
424
425       while (tmp && tmp != private)
426         tmp = tmp->parent;
427
428       if (tmp)
429         display_x11->keyboard_xgrab_window = NULL;  
430     }
431 }
432
433 /**
434  * _gdk_xgrab_check_destroy:
435  * @window: a #GdkWindow
436  * 
437  * Checks to see if window is the current grab window, and if
438  * so, clear the current grab window.
439  **/
440 void
441 _gdk_xgrab_check_destroy (GdkWindow *window)
442 {
443   GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (gdk_drawable_get_display (window));
444   
445   if ((GdkWindowObject *)window == display_x11->pointer_xgrab_window)
446      display_x11->pointer_xgrab_window = NULL;
447
448   if ((GdkWindowObject *)window ==  display_x11->keyboard_xgrab_window)
449      display_x11->keyboard_xgrab_window = NULL;
450 }
451
452 /**
453  * gdk_display_set_sm_client_id:
454  * @display: a #GdkDisplay
455  * @sm_client_id: the client id assigned by the session manager when the
456  *    connection was opened, or %NULL to remove the property.
457  * 
458  * Sets the <literal>SM_CLIENT_ID</literal> property on the application's leader window
459  * so that the window manager can save the application's state using the X11R6 ICCCM
460  * session management protocol.
461  *
462  * See the X Session Management Library documentation for more information on
463  * session management and the Inter-Client Communication Conventions Manual
464  * (ICCCM) for information on the <literal>WM_CLIENT_LEADER</literal> property. 
465  * (Both documents are part of the X Window System distribution.)
466  **/
467 void
468 gdk_display_set_sm_client_id (GdkDisplay  *display,
469                               const gchar *sm_client_id)
470 {
471   GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
472
473   if (display->closed)
474     return;
475
476   if (sm_client_id && strcmp (sm_client_id, ""))
477     {
478       XChangeProperty (display_x11->xdisplay, display_x11->leader_window,
479                        gdk_x11_get_xatom_by_name_for_display (display, "SM_CLIENT_ID"),
480                        XA_STRING, 8, PropModeReplace, sm_client_id,
481                        strlen (sm_client_id));
482     }
483   else
484     XDeleteProperty (display_x11->xdisplay, display_x11->leader_window,
485                      gdk_x11_get_xatom_by_name_for_display (display, "SM_CLIENT_ID"));
486 }
487
488 /* Close all open displays
489  */
490 void
491 _gdk_windowing_exit (void)
492 {
493   GSList *tmp_list = _gdk_displays;
494     
495   while (tmp_list)
496     {
497       XCloseDisplay (GDK_DISPLAY_XDISPLAY (tmp_list->data));
498       
499       tmp_list = tmp_list->next;
500   }
501 }
502
503 /*
504  *--------------------------------------------------------------
505  * gdk_x_error
506  *
507  *   The X error handling routine.
508  *
509  * Arguments:
510  *   "display" is the X display the error orignated from.
511  *   "error" is the XErrorEvent that we are handling.
512  *
513  * Results:
514  *   Either we were expecting some sort of error to occur,
515  *   in which case we set the "_gdk_error_code" flag, or this
516  *   error was unexpected, in which case we will print an
517  *   error message and exit. (Since trying to continue will
518  *   most likely simply lead to more errors).
519  *
520  * Side effects:
521  *
522  *--------------------------------------------------------------
523  */
524
525 static int
526 gdk_x_error (Display     *display,
527              XErrorEvent *error)
528 {
529   if (error->error_code)
530     {
531       if (_gdk_error_warnings)
532         {
533           gchar buf[64];
534           gchar *msg;
535           
536           XGetErrorText (display, error->error_code, buf, 63);
537
538           msg =
539             g_strdup_printf ("The program '%s' received an X Window System error.\n"
540                              "This probably reflects a bug in the program.\n"
541                              "The error was '%s'.\n"
542                              "  (Details: serial %ld error_code %d request_code %d minor_code %d)\n"
543                              "  (Note to programmers: normally, X errors are reported asynchronously;\n"
544                              "   that is, you will receive the error a while after causing it.\n"
545                              "   To debug your program, run it with the --sync command line\n"
546                              "   option to change this behavior. You can then get a meaningful\n"
547                              "   backtrace from your debugger if you break on the gdk_x_error() function.)",
548                              g_get_prgname (),
549                              buf,
550                              error->serial, 
551                              error->error_code, 
552                              error->request_code,
553                              error->minor_code);
554           
555 #ifdef G_ENABLE_DEBUG     
556           g_error ("%s", msg);
557 #else /* !G_ENABLE_DEBUG */
558           fprintf (stderr, "%s\n", msg);
559
560           exit(1);
561 #endif /* G_ENABLE_DEBUG */
562         }
563       _gdk_error_code = error->error_code;
564     }
565   
566   return 0;
567 }
568
569 /*
570  *--------------------------------------------------------------
571  * gdk_x_io_error
572  *
573  *   The X I/O error handling routine.
574  *
575  * Arguments:
576  *   "display" is the X display the error orignated from.
577  *
578  * Results:
579  *   An X I/O error basically means we lost our connection
580  *   to the X server. There is not much we can do to
581  *   continue, so simply print an error message and exit.
582  *
583  * Side effects:
584  *
585  *--------------------------------------------------------------
586  */
587
588 static int
589 gdk_x_io_error (Display *display)
590 {
591   /* This is basically modelled after the code in XLib. We need
592    * an explicit error handler here, so we can disable our atexit()
593    * which would otherwise cause a nice segfault.
594    * We fprintf(stderr, instead of g_warning() because g_warning()
595    * could possibly be redirected to a dialog
596    */
597   if (errno == EPIPE)
598     {
599       fprintf (stderr,
600                "The application '%s' lost its connection to the display %s;\n"
601                "most likely the X server was shut down or you killed/destroyed\n"
602                "the application.\n",
603                g_get_prgname (),
604                display ? DisplayString (display) : gdk_get_display_arg_name ());
605     }
606   else
607     {
608       fprintf (stderr, "%s: Fatal IO error %d (%s) on X server %s.\n",
609                g_get_prgname (),
610                errno, g_strerror (errno),
611                display ? DisplayString (display) : gdk_get_display_arg_name ());
612     }
613
614   exit(1);
615 }
616
617 /*************************************************************
618  * gdk_error_trap_push:
619  *     Push an error trap. X errors will be trapped until
620  *     the corresponding gdk_error_pop(), which will return
621  *     the error code, if any.
622  *   arguments:
623  *     
624  *   results:
625  *************************************************************/
626
627 void
628 gdk_error_trap_push (void)
629 {
630   GSList *node;
631   GdkErrorTrap *trap;
632
633   if (gdk_error_trap_free_list)
634     {
635       node = gdk_error_trap_free_list;
636       gdk_error_trap_free_list = gdk_error_trap_free_list->next;
637     }
638   else
639     {
640       node = g_slist_alloc ();
641       node->data = g_new (GdkErrorTrap, 1);
642     }
643
644   node->next = gdk_error_traps;
645   gdk_error_traps = node;
646   
647   trap = node->data;
648   trap->old_handler = XSetErrorHandler (gdk_x_error);
649   trap->error_code = _gdk_error_code;
650   trap->error_warnings = _gdk_error_warnings;
651
652   _gdk_error_code = 0;
653   _gdk_error_warnings = 0;
654 }
655
656 /*************************************************************
657  * gdk_error_trap_pop:
658  *     Pop an error trap added with gdk_error_push()
659  *   arguments:
660  *     
661  *   results:
662  *     0, if no error occured, otherwise the error code.
663  *************************************************************/
664
665 gint
666 gdk_error_trap_pop (void)
667 {
668   GSList *node;
669   GdkErrorTrap *trap;
670   gint result;
671
672   g_return_val_if_fail (gdk_error_traps != NULL, 0);
673
674   node = gdk_error_traps;
675   gdk_error_traps = gdk_error_traps->next;
676
677   node->next = gdk_error_trap_free_list;
678   gdk_error_trap_free_list = node;
679   
680   result = _gdk_error_code;
681   
682   trap = node->data;
683   _gdk_error_code = trap->error_code;
684   _gdk_error_warnings = trap->error_warnings;
685   XSetErrorHandler (trap->old_handler);
686   
687   return result;
688 }
689
690 gchar *
691 gdk_get_display (void)
692 {
693   return g_strdup (gdk_display_get_name (gdk_display_get_default ()));
694 }
695
696 /**
697  * _gdk_send_xevent:
698  * @display: #GdkDisplay which @window is on
699  * @window: window ID to which to send the event
700  * @propagate: %TRUE if the event should be propagated if the target window
701  *             doesn't handle it.
702  * @event_mask: event mask to match against, or 0 to send it to @window
703  *              without regard to event masks.
704  * @event_send: #XEvent to send
705  * 
706  * Send an event, like XSendEvent(), but trap errors and check
707  * the result.
708  * 
709  * Return value: %TRUE if sending the event succeeded.
710  **/
711 gint 
712 _gdk_send_xevent (GdkDisplay *display,
713                   Window      window, 
714                   gboolean    propagate, 
715                   glong       event_mask,
716                   XEvent     *event_send)
717 {
718   gboolean result;
719
720   if (display->closed)
721     return FALSE;
722
723   gdk_error_trap_push ();
724   result = XSendEvent (GDK_DISPLAY_XDISPLAY (display), window, 
725                        propagate, event_mask, event_send);
726   XSync (GDK_DISPLAY_XDISPLAY (display), False);
727   
728   return result && gdk_error_trap_pop() == Success;
729 }
730
731 void
732 _gdk_region_get_xrectangles (GdkRegion   *region,
733                              gint         x_offset,
734                              gint         y_offset,
735                              XRectangle **rects,
736                              gint        *n_rects)
737 {
738   XRectangle *rectangles = g_new (XRectangle, region->numRects);
739   GdkRegionBox *boxes = region->rects;
740   gint i;
741   
742   for (i = 0; i < region->numRects; i++)
743     {
744       rectangles[i].x = CLAMP (boxes[i].x1 + x_offset, G_MINSHORT, G_MAXSHORT);
745       rectangles[i].y = CLAMP (boxes[i].y1 + y_offset, G_MINSHORT, G_MAXSHORT);
746       rectangles[i].width = CLAMP (boxes[i].x2 + x_offset, G_MINSHORT, G_MAXSHORT) - rectangles[i].x;
747       rectangles[i].height = CLAMP (boxes[i].y2 + y_offset, G_MINSHORT, G_MAXSHORT) - rectangles[i].y;
748     }
749
750   *rects = rectangles;
751   *n_rects = region->numRects;
752 }
753
754 void
755 gdk_x11_grab_server ()
756 {
757   gdk_x11_display_grab (gdk_display_get_default ());
758 }
759
760 void
761 gdk_x11_ungrab_server ()
762 {
763   gdk_x11_display_ungrab (gdk_display_get_default ());
764 }
765
766 /**
767  * gdk_x11_get_default_screen:
768  * 
769  * Gets the default GTK+ screen number.
770  * 
771  * Return value: returns the screen number specified by
772  *   the --display command line option or the DISPLAY environment
773  *   variable when gdk_init() calls XOpenDisplay().
774  **/
775 gint
776 gdk_x11_get_default_screen (void)
777 {
778   return gdk_screen_get_number (gdk_screen_get_default ());
779 }
780
781 Window
782 gdk_x11_get_default_root_xwindow (void)
783 {
784   return GDK_SCREEN_XROOTWIN (gdk_screen_get_default ());
785 }
786
787 Display *
788 gdk_x11_get_default_xdisplay (void)
789 {
790   return GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
791 }