]> Pileus Git - ~andy/gtk/blob - gdk/gdk.c
introspection: Remove redundant include
[~andy/gtk] / gdk / gdk.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 "gdkmain.h"
30
31 #include "gdkinternals.h"
32 #include "gdkintl.h"
33
34 #ifndef HAVE_XCONVERTCASE
35 #include "gdkkeysyms.h"
36 #endif
37
38 #include <string.h>
39 #include <stdlib.h>
40
41
42 /**
43  * SECTION:general
44  * @Short_description: Library initialization and miscellaneous functions
45  * @Title: General
46  *
47  * This section describes the GDK initialization functions and miscellaneous
48  * utility functions.
49  */
50
51 /**
52  * GDK_WINDOWING_X11:
53  *
54  * The #GDK_WINDOWING_X11 macro is defined if the X11 backend
55  * is supported.
56  *
57  * Use this macro to guard code that is specific to the X11-backend.
58  * Since GDK may be configured with multiple backends, an additional
59  * runtime check for the used backend is recommended:
60  *
61  * |[
62  * #ifdef GDK_WINDOWING_X11
63  *   if (GDK_IS_X11_DISPLAY (display))
64  *     {
65  *       /&ast; make X11-specific calls here &ast;/
66  *     }
67  *   else
68  * #endif
69  * #ifdef GDK_WINDOWING_QUARTZ
70  *   if (GDK_IS_QUARTZ_DISPLAY (display))
71  *     {
72  *       /&ast; make Quartz-specific calls here &ast/
73  *     }
74  *   else
75  * #endif
76  *   g_error ("Unsupported GDK backend");
77  * ]|
78  */
79
80 /**
81  * GDK_WINDOWING_WIN32:
82  *
83  * The #GDK_WINDOWING_WIN32 macro is defined if the Win32 backend
84  * is supported.
85  */
86
87 /**
88  * GDK_WINDOWING_QUARTZ:
89  *
90  * The #GDK_WINDOWING_QUARTZ macro is defined if the Quartz backend
91  * is supported.
92  */
93
94 typedef struct _GdkPredicate  GdkPredicate;
95
96 struct _GdkPredicate
97 {
98   GdkEventFunc func;
99   gpointer data;
100 };
101
102 typedef struct _GdkThreadsDispatch GdkThreadsDispatch;
103
104 struct _GdkThreadsDispatch
105 {
106   GSourceFunc func;
107   gpointer data;
108   GDestroyNotify destroy;
109 };
110
111
112 /* Private variable declarations
113  */
114 static int gdk_initialized = 0;                     /* 1 if the library is initialized,
115                                                      * 0 otherwise.
116                                                      */
117
118 static gchar  *gdk_progclass = NULL;
119
120 static GMutex *gdk_threads_mutex = NULL;            /* Global GDK lock */
121
122 static GCallback gdk_threads_lock = NULL;
123 static GCallback gdk_threads_unlock = NULL;
124
125 #ifdef G_ENABLE_DEBUG
126 static const GDebugKey gdk_debug_keys[] = {
127   {"events",        GDK_DEBUG_EVENTS},
128   {"misc",          GDK_DEBUG_MISC},
129   {"dnd",           GDK_DEBUG_DND},
130   {"xim",           GDK_DEBUG_XIM},
131   {"nograbs",       GDK_DEBUG_NOGRABS},
132   {"input",         GDK_DEBUG_INPUT},
133   {"cursor",        GDK_DEBUG_CURSOR},
134   {"multihead",     GDK_DEBUG_MULTIHEAD},
135   {"xinerama",      GDK_DEBUG_XINERAMA},
136   {"draw",          GDK_DEBUG_DRAW},
137   {"eventloop",     GDK_DEBUG_EVENTLOOP}
138 };
139
140 static gboolean
141 gdk_arg_debug_cb (const char *key, const char *value, gpointer user_data, GError **error)
142 {
143   guint debug_value = g_parse_debug_string (value,
144                                             (GDebugKey *) gdk_debug_keys,
145                                             G_N_ELEMENTS (gdk_debug_keys));
146
147   if (debug_value == 0 && value != NULL && strcmp (value, "") != 0)
148     {
149       g_set_error (error,
150                    G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
151                    _("Error parsing option --gdk-debug"));
152       return FALSE;
153     }
154
155   _gdk_debug_flags |= debug_value;
156
157   return TRUE;
158 }
159
160 static gboolean
161 gdk_arg_no_debug_cb (const char *key, const char *value, gpointer user_data, GError **error)
162 {
163   guint debug_value = g_parse_debug_string (value,
164                                             (GDebugKey *) gdk_debug_keys,
165                                             G_N_ELEMENTS (gdk_debug_keys));
166
167   if (debug_value == 0 && value != NULL && strcmp (value, "") != 0)
168     {
169       g_set_error (error,
170                    G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
171                    _("Error parsing option --gdk-no-debug"));
172       return FALSE;
173     }
174
175   _gdk_debug_flags &= ~debug_value;
176
177   return TRUE;
178 }
179 #endif /* G_ENABLE_DEBUG */
180
181 static gboolean
182 gdk_arg_class_cb (const char *key, const char *value, gpointer user_data, GError **error)
183 {
184   gdk_set_program_class (value);
185
186   return TRUE;
187 }
188
189 static gboolean
190 gdk_arg_name_cb (const char *key, const char *value, gpointer user_data, GError **error)
191 {
192   g_set_prgname (value);
193
194   return TRUE;
195 }
196
197 static const GOptionEntry gdk_args[] = {
198   { "class",        0, 0,                     G_OPTION_ARG_CALLBACK, gdk_arg_class_cb,
199     /* Description of --class=CLASS in --help output */        N_("Program class as used by the window manager"),
200     /* Placeholder in --class=CLASS in --help output */        N_("CLASS") },
201   { "name",         0, 0,                     G_OPTION_ARG_CALLBACK, gdk_arg_name_cb,
202     /* Description of --name=NAME in --help output */          N_("Program name as used by the window manager"),
203     /* Placeholder in --name=NAME in --help output */          N_("NAME") },
204   { "display",      0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_STRING,   &_gdk_display_name,
205     /* Description of --display=DISPLAY in --help output */    N_("X display to use"),
206     /* Placeholder in --display=DISPLAY in --help output */    N_("DISPLAY") },
207 #ifdef G_ENABLE_DEBUG
208   { "gdk-debug",    0, 0, G_OPTION_ARG_CALLBACK, gdk_arg_debug_cb,  
209     /* Description of --gdk-debug=FLAGS in --help output */    N_("GDK debugging flags to set"),
210     /* Placeholder in --gdk-debug=FLAGS in --help output */    N_("FLAGS") },
211   { "gdk-no-debug", 0, 0, G_OPTION_ARG_CALLBACK, gdk_arg_no_debug_cb, 
212     /* Description of --gdk-no-debug=FLAGS in --help output */ N_("GDK debugging flags to unset"),
213     /* Placeholder in --gdk-no-debug=FLAGS in --help output */ N_("FLAGS") },
214 #endif 
215   { NULL }
216 };
217
218 /**
219  * gdk_add_option_entries_libgtk_only:
220  * @group: An option group.
221  *
222  * Appends gdk option entries to the passed in option group. This is
223  * not public API and must not be used by applications.
224  */
225 void
226 gdk_add_option_entries_libgtk_only (GOptionGroup *group)
227 {
228   g_option_group_add_entries (group, gdk_args);
229 }
230
231 void
232 gdk_pre_parse_libgtk_only (void)
233 {
234   gdk_initialized = TRUE;
235
236   /* We set the fallback program class here, rather than lazily in
237    * gdk_get_program_class, since we don't want -name to override it.
238    */
239   gdk_progclass = g_strdup (g_get_prgname ());
240   if (gdk_progclass && gdk_progclass[0])
241     gdk_progclass[0] = g_ascii_toupper (gdk_progclass[0]);
242   
243 #ifdef G_ENABLE_DEBUG
244   {
245     gchar *debug_string = getenv("GDK_DEBUG");
246     if (debug_string != NULL)
247       _gdk_debug_flags = g_parse_debug_string (debug_string,
248                                               (GDebugKey *) gdk_debug_keys,
249                                               G_N_ELEMENTS (gdk_debug_keys));
250   }
251 #endif  /* G_ENABLE_DEBUG */
252
253   if (getenv ("GDK_NATIVE_WINDOWS"))
254     {
255       _gdk_native_windows = TRUE;
256       /* Ensure that this is not propagated to spawned applications */
257       g_unsetenv ("GDK_NATIVE_WINDOWS");
258     }
259
260   g_type_init ();
261
262   /* Do any setup particular to the windowing system */
263   gdk_display_manager_get ();
264 }
265
266   
267 /**
268  * gdk_parse_args:
269  * @argc: the number of command line arguments.
270  * @argv: (inout) (array length=argc): the array of command line arguments.
271  * 
272  * Parse command line arguments, and store for future
273  * use by calls to gdk_display_open().
274  *
275  * Any arguments used by GDK are removed from the array and @argc and @argv are
276  * updated accordingly.
277  *
278  * You shouldn't call this function explicitely if you are using
279  * gtk_init(), gtk_init_check(), gdk_init(), or gdk_init_check().
280  *
281  * Since: 2.2
282  **/
283 void
284 gdk_parse_args (int    *argc,
285                 char ***argv)
286 {
287   GOptionContext *option_context;
288   GOptionGroup *option_group;
289   GError *error = NULL;
290
291   if (gdk_initialized)
292     return;
293
294   gdk_pre_parse_libgtk_only ();
295
296   option_context = g_option_context_new (NULL);
297   g_option_context_set_ignore_unknown_options (option_context, TRUE);
298   g_option_context_set_help_enabled (option_context, FALSE);
299   option_group = g_option_group_new (NULL, NULL, NULL, NULL, NULL);
300   g_option_context_set_main_group (option_context, option_group);
301
302   g_option_group_add_entries (option_group, gdk_args);
303
304   if (!g_option_context_parse (option_context, argc, argv, &error))
305     {
306       g_warning ("%s", error->message);
307       g_error_free (error);
308     }
309   g_option_context_free (option_context);
310
311   GDK_NOTE (MISC, g_message ("progname: \"%s\"", g_get_prgname ()));
312 }
313
314 /**
315  * gdk_get_display_arg_name:
316  *
317  * Gets the display name specified in the command line arguments passed
318  * to gdk_init() or gdk_parse_args(), if any.
319  *
320  * Returns: the display name, if specified explicitely, otherwise %NULL
321  *   this string is owned by GTK+ and must not be modified or freed.
322  *
323  * Since: 2.2
324  */
325 G_CONST_RETURN gchar *
326 gdk_get_display_arg_name (void)
327 {
328   if (!_gdk_display_arg_name)
329     _gdk_display_arg_name = g_strdup (_gdk_display_name);
330
331    return _gdk_display_arg_name;
332 }
333
334 /**
335  * gdk_display_open_default_libgtk_only:
336  *
337  * Opens the default display specified by command line arguments or
338  * environment variables, sets it as the default display, and returns
339  * it.  gdk_parse_args must have been called first. If the default
340  * display has previously been set, simply returns that. An internal
341  * function that should not be used by applications.
342  *
343  * Return value: (transfer none): the default display, if it could be
344  *   opened, otherwise %NULL.
345  **/
346 GdkDisplay *
347 gdk_display_open_default_libgtk_only (void)
348 {
349   GdkDisplay *display;
350
351   g_return_val_if_fail (gdk_initialized, NULL);
352
353   display = gdk_display_get_default ();
354   if (display)
355     return display;
356
357   display = gdk_display_open (gdk_get_display_arg_name ());
358
359   return display;
360 }
361
362 /**
363  * gdk_init_check:
364  * @argc: (inout): the number of command line arguments.
365  * @argv: (array length=argc) (inout): the array of command line arguments.
366  *
367  * Initializes the GDK library and connects to the windowing system,
368  * returning %TRUE on success.
369  *
370  * Any arguments used by GDK are removed from the array and @argc and @argv
371  * are updated accordingly.
372  *
373  * GTK+ initializes GDK in gtk_init() and so this function is not usually
374  * needed by GTK+ applications.
375  *
376  * Returns: %TRUE if initialization succeeded.
377  */
378 gboolean
379 gdk_init_check (int    *argc,
380                 char ***argv)
381 {
382   gdk_parse_args (argc, argv);
383
384   return gdk_display_open_default_libgtk_only () != NULL;
385 }
386
387
388 /**
389  * gdk_init:
390  * @argc: (inout): the number of command line arguments.
391  * @argv: (array length=argc) (inout): the array of command line arguments.
392  *
393  * Initializes the GDK library and connects to the windowing system.
394  * If initialization fails, a warning message is output and the application
395  * terminates with a call to <literal>exit(1)</literal>.
396  *
397  * Any arguments used by GDK are removed from the array and @argc and @argv
398  * are updated accordingly.
399  *
400  * GTK+ initializes GDK in gtk_init() and so this function is not usually
401  * needed by GTK+ applications.
402  */
403 void
404 gdk_init (int *argc, char ***argv)
405 {
406   if (!gdk_init_check (argc, argv))
407     {
408       const char *display_name = gdk_get_display_arg_name ();
409       g_warning ("cannot open display: %s", display_name ? display_name : "");
410       exit(1);
411     }
412 }
413
414
415
416 /**
417  * SECTION:threads
418  * @Short_description: Functions for using GDK in multi-threaded programs
419  * @Title: Threads
420  *
421  * For thread safety, GDK relies on the thread primitives in GLib,
422  * and on the thread-safe GLib main loop.
423  *
424  * GLib is completely thread safe (all global data is automatically
425  * locked), but individual data structure instances are not automatically
426  * locked for performance reasons. So e.g. you must coordinate
427  * accesses to the same #GHashTable from multiple threads.
428  *
429  * GTK+ is "thread aware" but not thread safe &mdash; it provides a
430  * global lock controlled by gdk_threads_enter()/gdk_threads_leave()
431  * which protects all use of GTK+. That is, only one thread can use GTK+
432  * at any given time.
433  *
434  * Unfortunately the above holds with the X11 backend only. With the
435  * Win32 backend, GDK calls should not be attempted from multiple threads
436  * at all.
437  *
438  * You must call g_thread_init() and gdk_threads_init() before executing
439  * any other GTK+ or GDK functions in a threaded GTK+ program.
440  *
441  * Idles, timeouts, and input functions from GLib, such as g_idle_add(), are
442  * executed outside of the main GTK+ lock.
443  * So, if you need to call GTK+ inside of such a callback, you must surround
444  * the callback with a gdk_threads_enter()/gdk_threads_leave() pair or use
445  * gdk_threads_add_idle_full() which does this for you.
446  * However, event dispatching from the mainloop is still executed within
447  * the main GTK+ lock, so callback functions connected to event signals
448  * like #GtkWidget::button-press-event, do not need thread protection.
449  *
450  * In particular, this means, if you are writing widgets that might
451  * be used in threaded programs, you <emphasis>must</emphasis> surround
452  * timeouts and idle functions in this matter.
453  *
454  * As always, you must also surround any calls to GTK+ not made within
455  * a signal handler with a gdk_threads_enter()/gdk_threads_leave() pair.
456  *
457  * Before calling gdk_threads_leave() from a thread other
458  * than your main thread, you probably want to call gdk_flush()
459  * to send all pending commands to the windowing system.
460  * (The reason you don't need to do this from the main thread
461  * is that GDK always automatically flushes pending commands
462  * when it runs out of incoming events to process and has
463  * to sleep while waiting for more events.)
464  *
465  * A minimal main program for a threaded GTK+ application
466  * looks like:
467  * <informalexample>
468  * <programlisting role="C">
469  * int
470  * main (int argc, char *argv[])
471  * {
472  *   GtkWidget *window;
473  *
474  *   g_thread_init (NULL);
475  *   gdk_threads_init (<!-- -->);
476  *   gdk_threads_enter (<!-- -->);
477  *
478  *   gtk_init (&argc, &argv);
479  *
480  *   window = create_window (<!-- -->);
481  *   gtk_widget_show (window);
482  *
483  *   gtk_main (<!-- -->);
484  *   gdk_threads_leave (<!-- -->);
485  *
486  *   return 0;
487  * }
488  * </programlisting>
489  * </informalexample>
490  *
491  * Callbacks require a bit of attention. Callbacks from GTK+ signals
492  * are made within the GTK+ lock. However callbacks from GLib (timeouts,
493  * IO callbacks, and idle functions) are made outside of the GTK+
494  * lock. So, within a signal handler you do not need to call
495  * gdk_threads_enter(), but within the other types of callbacks, you
496  * do.
497  *
498  * Erik Mouw contributed the following code example to
499  * illustrate how to use threads within GTK+ programs.
500  * <informalexample>
501  * <programlisting role="C">
502  * /<!---->*-------------------------------------------------------------------------
503  *  * Filename:      gtk-thread.c
504  *  * Version:       0.99.1
505  *  * Copyright:     Copyright (C) 1999, Erik Mouw
506  *  * Author:        Erik Mouw &lt;J.A.K.Mouw@its.tudelft.nl&gt;
507  *  * Description:   GTK threads example.
508  *  * Created at:    Sun Oct 17 21:27:09 1999
509  *  * Modified by:   Erik Mouw &lt;J.A.K.Mouw@its.tudelft.nl&gt;
510  *  * Modified at:   Sun Oct 24 17:21:41 1999
511  *  *-----------------------------------------------------------------------*<!---->/
512  * /<!---->*
513  *  * Compile with:
514  *  *
515  *  * cc -o gtk-thread gtk-thread.c `gtk-config --cflags --libs gthread`
516  *  *
517  *  * Thanks to Sebastian Wilhelmi and Owen Taylor for pointing out some
518  *  * bugs.
519  *  *
520  *  *<!---->/
521  *
522  * #include <stdio.h>
523  * #include <stdlib.h>
524  * #include <unistd.h>
525  * #include <time.h>
526  * #include <gtk/gtk.h>
527  * #include <glib.h>
528  * #include <pthread.h>
529  *
530  * #define YES_IT_IS    (1)
531  * #define NO_IT_IS_NOT (0)
532  *
533  * typedef struct
534  * {
535  *   GtkWidget *label;
536  *   int what;
537  * } yes_or_no_args;
538  *
539  * G_LOCK_DEFINE_STATIC (yes_or_no);
540  * static volatile int yes_or_no = YES_IT_IS;
541  *
542  * void destroy (GtkWidget *widget, gpointer data)
543  * {
544  *   gtk_main_quit (<!-- -->);
545  * }
546  *
547  * void *argument_thread (void *args)
548  * {
549  *   yes_or_no_args *data = (yes_or_no_args *)args;
550  *   gboolean say_something;
551  *
552  *   for (;;)
553  *     {
554  *       /<!---->* sleep a while *<!---->/
555  *       sleep(rand(<!-- -->) / (RAND_MAX / 3) + 1);
556  *
557  *       /<!---->* lock the yes_or_no_variable *<!---->/
558  *       G_LOCK(yes_or_no);
559  *
560  *       /<!---->* do we have to say something? *<!---->/
561  *       say_something = (yes_or_no != data->what);
562  *
563  *       if(say_something)
564  *      {
565  *        /<!---->* set the variable *<!---->/
566  *        yes_or_no = data->what;
567  *      }
568  *
569  *       /<!---->* Unlock the yes_or_no variable *<!---->/
570  *       G_UNLOCK (yes_or_no);
571  *
572  *       if (say_something)
573  *      {
574  *        /<!---->* get GTK thread lock *<!---->/
575  *        gdk_threads_enter (<!-- -->);
576  *
577  *        /<!---->* set label text *<!---->/
578  *        if(data->what == YES_IT_IS)
579  *          gtk_label_set_text (GTK_LABEL (data->label), "O yes, it is!");
580  *        else
581  *          gtk_label_set_text (GTK_LABEL (data->label), "O no, it isn't!");
582  *
583  *        /<!---->* release GTK thread lock *<!---->/
584  *        gdk_threads_leave (<!-- -->);
585  *      }
586  *     }
587  *
588  *   return NULL;
589  * }
590  *
591  * int main (int argc, char *argv[])
592  * {
593  *   GtkWidget *window;
594  *   GtkWidget *label;
595  *   yes_or_no_args yes_args, no_args;
596  *   pthread_t no_tid, yes_tid;
597  *
598  *   /<!---->* init threads *<!---->/
599  *   g_thread_init (NULL);
600  *   gdk_threads_init (<!-- -->);
601  *   gdk_threads_enter (<!-- -->);
602  *
603  *   /<!---->* init gtk *<!---->/
604  *   gtk_init(&argc, &argv);
605  *
606  *   /<!---->* init random number generator *<!---->/
607  *   srand ((unsigned int) time (NULL));
608  *
609  *   /<!---->* create a window *<!---->/
610  *   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
611  *
612  *   g_signal_connect (window, "destroy", G_CALLBACK (destroy), NULL);
613  *
614  *   gtk_container_set_border_width (GTK_CONTAINER (window), 10);
615  *
616  *   /<!---->* create a label *<!---->/
617  *   label = gtk_label_new ("And now for something completely different ...");
618  *   gtk_container_add (GTK_CONTAINER (window), label);
619  *
620  *   /<!---->* show everything *<!---->/
621  *   gtk_widget_show (label);
622  *   gtk_widget_show (window);
623  *
624  *   /<!---->* create the threads *<!---->/
625  *   yes_args.label = label;
626  *   yes_args.what = YES_IT_IS;
627  *   pthread_create (&yes_tid, NULL, argument_thread, &yes_args);
628  *
629  *   no_args.label = label;
630  *   no_args.what = NO_IT_IS_NOT;
631  *   pthread_create (&no_tid, NULL, argument_thread, &no_args);
632  *
633  *   /<!---->* enter the GTK main loop *<!---->/
634  *   gtk_main (<!-- -->);
635  *   gdk_threads_leave (<!-- -->);
636  *
637  *   return 0;
638  * }
639  * </programlisting>
640  * </informalexample>
641  */
642
643
644 /**
645  * gdk_threads_enter:
646  *
647  * This macro marks the beginning of a critical section in which GDK and
648  * GTK+ functions can be called safely and without causing race
649  * conditions.  Only one thread at a time can be in such a critial
650  * section.
651  */
652 void
653 gdk_threads_enter (void)
654 {
655   if (gdk_threads_lock)
656     (*gdk_threads_lock) ();
657 }
658
659 /**
660  * gdk_threads_leave:
661  *
662  * Leaves a critical region begun with gdk_threads_enter().
663  */
664 void
665 gdk_threads_leave (void)
666 {
667   if (gdk_threads_unlock)
668     (*gdk_threads_unlock) ();
669 }
670
671 static void
672 gdk_threads_impl_lock (void)
673 {
674   if (gdk_threads_mutex)
675     g_mutex_lock (gdk_threads_mutex);
676 }
677
678 static void
679 gdk_threads_impl_unlock (void)
680 {
681   if (gdk_threads_mutex)
682     g_mutex_unlock (gdk_threads_mutex);
683 }
684
685 /**
686  * gdk_threads_init:
687  *
688  * Initializes GDK so that it can be used from multiple threads
689  * in conjunction with gdk_threads_enter() and gdk_threads_leave().
690  * g_thread_init() must be called previous to this function.
691  *
692  * This call must be made before any use of the main loop from
693  * GTK+; to be safe, call it before gtk_init().
694  **/
695 void
696 gdk_threads_init (void)
697 {
698   if (!g_thread_supported ())
699     g_error ("g_thread_init() must be called before gdk_threads_init()");
700
701   gdk_threads_mutex = g_mutex_new ();
702   if (!gdk_threads_lock)
703     gdk_threads_lock = gdk_threads_impl_lock;
704   if (!gdk_threads_unlock)
705     gdk_threads_unlock = gdk_threads_impl_unlock;
706 }
707
708 /**
709  * gdk_threads_set_lock_functions: (skip)
710  * @enter_fn:   function called to guard GDK
711  * @leave_fn: function called to release the guard
712  *
713  * Allows the application to replace the standard method that
714  * GDK uses to protect its data structures. Normally, GDK
715  * creates a single #GMutex that is locked by gdk_threads_enter(),
716  * and released by gdk_threads_leave(); using this function an
717  * application provides, instead, a function @enter_fn that is
718  * called by gdk_threads_enter() and a function @leave_fn that is
719  * called by gdk_threads_leave().
720  *
721  * The functions must provide at least same locking functionality
722  * as the default implementation, but can also do extra application
723  * specific processing.
724  *
725  * As an example, consider an application that has its own recursive
726  * lock that when held, holds the GTK+ lock as well. When GTK+ unlocks
727  * the GTK+ lock when entering a recursive main loop, the application
728  * must temporarily release its lock as well.
729  *
730  * Most threaded GTK+ apps won't need to use this method.
731  *
732  * This method must be called before gdk_threads_init(), and cannot
733  * be called multiple times.
734  *
735  * Since: 2.4
736  **/
737 void
738 gdk_threads_set_lock_functions (GCallback enter_fn,
739                                 GCallback leave_fn)
740 {
741   g_return_if_fail (gdk_threads_lock == NULL &&
742                     gdk_threads_unlock == NULL);
743
744   gdk_threads_lock = enter_fn;
745   gdk_threads_unlock = leave_fn;
746 }
747
748 static gboolean
749 gdk_threads_dispatch (gpointer data)
750 {
751   GdkThreadsDispatch *dispatch = data;
752   gboolean ret = FALSE;
753
754   GDK_THREADS_ENTER ();
755
756   if (!g_source_is_destroyed (g_main_current_source ()))
757     ret = dispatch->func (dispatch->data);
758
759   GDK_THREADS_LEAVE ();
760
761   return ret;
762 }
763
764 static void
765 gdk_threads_dispatch_free (gpointer data)
766 {
767   GdkThreadsDispatch *dispatch = data;
768
769   if (dispatch->destroy && dispatch->data)
770     dispatch->destroy (dispatch->data);
771
772   g_slice_free (GdkThreadsDispatch, data);
773 }
774
775
776 /**
777  * gdk_threads_add_idle_full:
778  * @priority: the priority of the idle source. Typically this will be in the
779  *            range between #G_PRIORITY_DEFAULT_IDLE and #G_PRIORITY_HIGH_IDLE
780  * @function: function to call
781  * @data:     data to pass to @function
782  * @notify: (allow-none):   function to call when the idle is removed, or %NULL
783  *
784  * Adds a function to be called whenever there are no higher priority
785  * events pending.  If the function returns %FALSE it is automatically
786  * removed from the list of event sources and will not be called again.
787  *
788  * This variant of g_idle_add_full() calls @function with the GDK lock
789  * held. It can be thought of a MT-safe version for GTK+ widgets for the 
790  * following use case, where you have to worry about idle_callback()
791  * running in thread A and accessing @self after it has been finalized
792  * in thread B:
793  *
794  * |[
795  * static gboolean
796  * idle_callback (gpointer data)
797  * {
798  *    /&ast; gdk_threads_enter(); would be needed for g_idle_add() &ast;/
799  *
800  *    SomeWidget *self = data;
801  *    /&ast; do stuff with self &ast;/
802  *
803  *    self->idle_id = 0;
804  *
805  *    /&ast; gdk_threads_leave(); would be needed for g_idle_add() &ast;/
806  *    return FALSE;
807  * }
808  *
809  * static void
810  * some_widget_do_stuff_later (SomeWidget *self)
811  * {
812  *    self->idle_id = gdk_threads_add_idle (idle_callback, self)
813  *    /&ast; using g_idle_add() here would require thread protection in the callback &ast;/
814  * }
815  *
816  * static void
817  * some_widget_finalize (GObject *object)
818  * {
819  *    SomeWidget *self = SOME_WIDGET (object);
820  *    if (self->idle_id)
821  *      g_source_remove (self->idle_id);
822  *    G_OBJECT_CLASS (parent_class)->finalize (object);
823  * }
824  * ]|
825  *
826  * Return value: the ID (greater than 0) of the event source.
827  *
828  * Since: 2.12
829  * Rename to: gdk_threads_add_idle
830  */
831 guint
832 gdk_threads_add_idle_full (gint           priority,
833                            GSourceFunc    function,
834                            gpointer       data,
835                            GDestroyNotify notify)
836 {
837   GdkThreadsDispatch *dispatch;
838
839   g_return_val_if_fail (function != NULL, 0);
840
841   dispatch = g_slice_new (GdkThreadsDispatch);
842   dispatch->func = function;
843   dispatch->data = data;
844   dispatch->destroy = notify;
845
846   return g_idle_add_full (priority,
847                           gdk_threads_dispatch,
848                           dispatch,
849                           gdk_threads_dispatch_free);
850 }
851
852 /**
853  * gdk_threads_add_idle: (skip)
854  * @function: function to call
855  * @data:     data to pass to @function
856  *
857  * A wrapper for the common usage of gdk_threads_add_idle_full() 
858  * assigning the default priority, #G_PRIORITY_DEFAULT_IDLE.
859  *
860  * See gdk_threads_add_idle_full().
861  *
862  * Return value: the ID (greater than 0) of the event source.
863  * 
864  * Since: 2.12
865  */
866 guint
867 gdk_threads_add_idle (GSourceFunc    function,
868                       gpointer       data)
869 {
870   return gdk_threads_add_idle_full (G_PRIORITY_DEFAULT_IDLE,
871                                     function, data, NULL);
872 }
873
874
875 /**
876  * gdk_threads_add_timeout_full:
877  * @priority: the priority of the timeout source. Typically this will be in the
878  *            range between #G_PRIORITY_DEFAULT_IDLE and #G_PRIORITY_HIGH_IDLE.
879  * @interval: the time between calls to the function, in milliseconds
880  *             (1/1000ths of a second)
881  * @function: function to call
882  * @data:     data to pass to @function
883  * @notify: (allow-none):   function to call when the timeout is removed, or %NULL
884  *
885  * Sets a function to be called at regular intervals holding the GDK lock,
886  * with the given priority.  The function is called repeatedly until it 
887  * returns %FALSE, at which point the timeout is automatically destroyed 
888  * and the function will not be called again.  The @notify function is
889  * called when the timeout is destroyed.  The first call to the
890  * function will be at the end of the first @interval.
891  *
892  * Note that timeout functions may be delayed, due to the processing of other
893  * event sources. Thus they should not be relied on for precise timing.
894  * After each call to the timeout function, the time of the next
895  * timeout is recalculated based on the current time and the given interval
896  * (it does not try to 'catch up' time lost in delays).
897  *
898  * This variant of g_timeout_add_full() can be thought of a MT-safe version 
899  * for GTK+ widgets for the following use case:
900  *
901  * |[
902  * static gboolean timeout_callback (gpointer data)
903  * {
904  *    SomeWidget *self = data;
905  *    
906  *    /&ast; do stuff with self &ast;/
907  *    
908  *    self->timeout_id = 0;
909  *    
910  *    return FALSE;
911  * }
912  *  
913  * static void some_widget_do_stuff_later (SomeWidget *self)
914  * {
915  *    self->timeout_id = g_timeout_add (timeout_callback, self)
916  * }
917  *  
918  * static void some_widget_finalize (GObject *object)
919  * {
920  *    SomeWidget *self = SOME_WIDGET (object);
921  *    
922  *    if (self->timeout_id)
923  *      g_source_remove (self->timeout_id);
924  *    
925  *    G_OBJECT_CLASS (parent_class)->finalize (object);
926  * }
927  * ]|
928  *
929  * Return value: the ID (greater than 0) of the event source.
930  * 
931  * Since: 2.12
932  * Rename to: gdk_threads_add_timeout
933  */
934 guint
935 gdk_threads_add_timeout_full (gint           priority,
936                               guint          interval,
937                               GSourceFunc    function,
938                               gpointer       data,
939                               GDestroyNotify notify)
940 {
941   GdkThreadsDispatch *dispatch;
942
943   g_return_val_if_fail (function != NULL, 0);
944
945   dispatch = g_slice_new (GdkThreadsDispatch);
946   dispatch->func = function;
947   dispatch->data = data;
948   dispatch->destroy = notify;
949
950   return g_timeout_add_full (priority, 
951                              interval,
952                              gdk_threads_dispatch, 
953                              dispatch, 
954                              gdk_threads_dispatch_free);
955 }
956
957 /**
958  * gdk_threads_add_timeout: (skip)
959  * @interval: the time between calls to the function, in milliseconds
960  *             (1/1000ths of a second)
961  * @function: function to call
962  * @data:     data to pass to @function
963  *
964  * A wrapper for the common usage of gdk_threads_add_timeout_full() 
965  * assigning the default priority, #G_PRIORITY_DEFAULT.
966  *
967  * See gdk_threads_add_timeout_full().
968  * 
969  * Return value: the ID (greater than 0) of the event source.
970  *
971  * Since: 2.12
972  */
973 guint
974 gdk_threads_add_timeout (guint       interval,
975                          GSourceFunc function,
976                          gpointer    data)
977 {
978   return gdk_threads_add_timeout_full (G_PRIORITY_DEFAULT,
979                                        interval, function, data, NULL);
980 }
981
982
983 /**
984  * gdk_threads_add_timeout_seconds_full:
985  * @priority: the priority of the timeout source. Typically this will be in the
986  *            range between #G_PRIORITY_DEFAULT_IDLE and #G_PRIORITY_HIGH_IDLE.
987  * @interval: the time between calls to the function, in seconds
988  * @function: function to call
989  * @data:     data to pass to @function
990  * @notify: (allow-none): function to call when the timeout is removed, or %NULL
991  *
992  * A variant of gdk_threads_add_timeout_full() with second-granularity.
993  * See g_timeout_add_seconds_full() for a discussion of why it is
994  * a good idea to use this function if you don't need finer granularity.
995  *
996  *  Return value: the ID (greater than 0) of the event source.
997  * 
998  * Since: 2.14
999  * Rename to: gdk_threads_add_timeout_seconds
1000  */
1001 guint
1002 gdk_threads_add_timeout_seconds_full (gint           priority,
1003                                       guint          interval,
1004                                       GSourceFunc    function,
1005                                       gpointer       data,
1006                                       GDestroyNotify notify)
1007 {
1008   GdkThreadsDispatch *dispatch;
1009
1010   g_return_val_if_fail (function != NULL, 0);
1011
1012   dispatch = g_slice_new (GdkThreadsDispatch);
1013   dispatch->func = function;
1014   dispatch->data = data;
1015   dispatch->destroy = notify;
1016
1017   return g_timeout_add_seconds_full (priority, 
1018                                      interval,
1019                                      gdk_threads_dispatch, 
1020                                      dispatch, 
1021                                      gdk_threads_dispatch_free);
1022 }
1023
1024 /**
1025  * gdk_threads_add_timeout_seconds: (skip)
1026  * @interval: the time between calls to the function, in seconds
1027  * @function: function to call
1028  * @data:     data to pass to @function
1029  *
1030  * A wrapper for the common usage of gdk_threads_add_timeout_seconds_full() 
1031  * assigning the default priority, #G_PRIORITY_DEFAULT.
1032  *
1033  * For details, see gdk_threads_add_timeout_full().
1034  * 
1035  * Return value: the ID (greater than 0) of the event source.
1036  *
1037  * Since: 2.14
1038  */
1039 guint
1040 gdk_threads_add_timeout_seconds (guint       interval,
1041                                  GSourceFunc function,
1042                                  gpointer    data)
1043 {
1044   return gdk_threads_add_timeout_seconds_full (G_PRIORITY_DEFAULT,
1045                                                interval, function, data, NULL);
1046 }
1047
1048 /**
1049  * gdk_get_program_class:
1050  *
1051  * Gets the program class. Unless the program class has explicitly
1052  * been set with gdk_set_program_class() or with the <option>--class</option>
1053  * commandline option, the default value is the program name (determined
1054  * with g_get_prgname()) with the first character converted to uppercase.
1055  *
1056  * Returns: the program class.
1057  */
1058 G_CONST_RETURN char *
1059 gdk_get_program_class (void)
1060 {
1061   return gdk_progclass;
1062 }
1063
1064 /**
1065  * gdk_set_program_class:
1066  * @program_class: a string.
1067  *
1068  * Sets the program class. The X11 backend uses the program class to set
1069  * the class name part of the <literal>WM_CLASS</literal> property on
1070  * toplevel windows; see the ICCCM.
1071  */
1072 void
1073 gdk_set_program_class (const char *program_class)
1074 {
1075   g_free (gdk_progclass);
1076
1077   gdk_progclass = g_strdup (program_class);
1078 }
1079
1080 /**
1081  * gdk_disable_multidevice:
1082  *
1083  * Disables multidevice support in GDK. This call must happen prior
1084  * to gdk_display_open(), gtk_init(), gtk_init_with_args() or
1085  * gtk_init_check() in order to take effect.
1086  *
1087  * Most common GTK+ applications won't ever need to call this. Only
1088  * applications that do mixed GDK/Xlib calls could want to disable
1089  * multidevice support if such Xlib code deals with input devices in
1090  * any way and doesn't observe the presence of XInput 2.
1091  *
1092  * Since: 3.0
1093  */
1094 void
1095 gdk_disable_multidevice (void)
1096 {
1097   if (gdk_initialized)
1098     return;
1099
1100   _gdk_disable_multidevice = TRUE;
1101 }