]> Pileus Git - ~andy/gtk/blob - gdk/gdk.c
Miscellaneous string fixes
[~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 <string.h>
30 #include <stdlib.h>
31
32 #include "gdk.h"
33 #include "gdkinternals.h"
34 #include "gdkintl.h"
35
36 #ifndef HAVE_XCONVERTCASE
37 #include "gdkkeysyms.h"
38 #endif
39
40 typedef struct _GdkPredicate  GdkPredicate;
41
42 struct _GdkPredicate
43 {
44   GdkEventFunc func;
45   gpointer data;
46 };
47
48 typedef struct _GdkThreadsDispatch GdkThreadsDispatch;
49
50 struct _GdkThreadsDispatch
51 {
52   GSourceFunc func;
53   gpointer data;
54   GDestroyNotify destroy;
55 };
56
57
58 /* Private variable declarations
59  */
60 static int gdk_initialized = 0;                     /* 1 if the library is initialized,
61                                                      * 0 otherwise.
62                                                      */
63
64 static gchar  *gdk_progclass = NULL;
65
66 #ifdef G_ENABLE_DEBUG
67 static const GDebugKey gdk_debug_keys[] = {
68   {"events",        GDK_DEBUG_EVENTS},
69   {"misc",          GDK_DEBUG_MISC},
70   {"dnd",           GDK_DEBUG_DND},
71   {"xim",           GDK_DEBUG_XIM},
72   {"nograbs",       GDK_DEBUG_NOGRABS},
73   {"colormap",      GDK_DEBUG_COLORMAP},
74   {"gc",            GDK_DEBUG_GC},
75   {"pixmap",        GDK_DEBUG_PIXMAP},
76   {"image",         GDK_DEBUG_IMAGE},
77   {"input",         GDK_DEBUG_INPUT},
78   {"cursor",        GDK_DEBUG_CURSOR},
79   {"multihead",     GDK_DEBUG_MULTIHEAD},
80   {"xinerama",      GDK_DEBUG_XINERAMA},
81   {"draw",          GDK_DEBUG_DRAW},
82   {"eventloop",     GDK_DEBUG_EVENTLOOP}
83 };
84
85 static const int gdk_ndebug_keys = G_N_ELEMENTS (gdk_debug_keys);
86
87 #endif /* G_ENABLE_DEBUG */
88
89 #ifdef G_ENABLE_DEBUG
90 static gboolean
91 gdk_arg_debug_cb (const char *key, const char *value, gpointer user_data, GError **error)
92 {
93   guint debug_value = g_parse_debug_string (value,
94                                             (GDebugKey *) gdk_debug_keys,
95                                             gdk_ndebug_keys);
96
97   if (debug_value == 0 && value != NULL && strcmp (value, "") != 0)
98     {
99       g_set_error (error, 
100                    G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
101                    _("Error parsing option --gdk-debug"));
102       return FALSE;
103     }
104
105   _gdk_debug_flags |= debug_value;
106
107   return TRUE;
108 }
109
110 static gboolean
111 gdk_arg_no_debug_cb (const char *key, const char *value, gpointer user_data, GError **error)
112 {
113   guint debug_value = g_parse_debug_string (value,
114                                             (GDebugKey *) gdk_debug_keys,
115                                             gdk_ndebug_keys);
116
117   if (debug_value == 0 && value != NULL && strcmp (value, "") != 0)
118     {
119       g_set_error (error, 
120                    G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
121                    _("Error parsing option --gdk-no-debug"));
122       return FALSE;
123     }
124
125   _gdk_debug_flags &= ~debug_value;
126
127   return TRUE;
128 }
129 #endif /* G_ENABLE_DEBUG */
130
131 static gboolean
132 gdk_arg_class_cb (const char *key, const char *value, gpointer user_data, GError **error)
133 {
134   gdk_set_program_class (value);
135
136   return TRUE;
137 }
138
139 static gboolean
140 gdk_arg_name_cb (const char *key, const char *value, gpointer user_data, GError **error)
141 {
142   g_set_prgname (value);
143
144   return TRUE;
145 }
146
147 static const GOptionEntry gdk_args[] = {
148   { "class",        0, 0,                     G_OPTION_ARG_CALLBACK, gdk_arg_class_cb,
149     /* Description of --class=CLASS in --help output */        N_("Program class as used by the window manager"),
150     /* Placeholder in --class=CLASS in --help output */        N_("CLASS") },
151   { "name",         0, 0,                     G_OPTION_ARG_CALLBACK, gdk_arg_name_cb,
152     /* Description of --name=NAME in --help output */          N_("Program name as used by the window manager"),
153     /* Placeholder in --name=NAME in --help output */          N_("NAME") },
154   { "display",      0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_STRING,   &_gdk_display_name,
155     /* Description of --display=DISPLAY in --help output */    N_("X display to use"),
156     /* Placeholder in --display=DISPLAY in --help output */    N_("DISPLAY") },
157   { "screen",       0, 0, G_OPTION_ARG_INT,      &_gdk_screen_number,
158     /* Description of --screen=SCREEN in --help output */      N_("X screen to use"),
159     /* Placeholder in --screen=SCREEN in --help output */      N_("SCREEN") },
160 #ifdef G_ENABLE_DEBUG
161   { "gdk-debug",    0, 0, G_OPTION_ARG_CALLBACK, gdk_arg_debug_cb,  
162     /* Description of --gdk-debug=FLAGS in --help output */    N_("GDK debugging flags to set"),
163     /* Placeholder in --gdk-debug=FLAGS in --help output */    N_("FLAGS") },
164   { "gdk-no-debug", 0, 0, G_OPTION_ARG_CALLBACK, gdk_arg_no_debug_cb, 
165     /* Description of --gdk-no-debug=FLAGS in --help output */ N_("GDK debugging flags to unset"),
166     /* Placeholder in --gdk-no-debug=FLAGS in --help output */ N_("FLAGS") },
167 #endif 
168   { NULL }
169 };
170
171 /**
172  * gdk_add_option_entries_libgtk_only:
173  * @group: An option group.
174  * 
175  * Appends gdk option entries to the passed in option group. This is
176  * not public API and must not be used by applications.
177  **/
178 void
179 gdk_add_option_entries_libgtk_only (GOptionGroup *group)
180 {
181   g_option_group_add_entries (group, gdk_args);
182   g_option_group_add_entries (group, _gdk_windowing_args);
183 }
184
185 void
186 gdk_pre_parse_libgtk_only (void)
187 {
188   gdk_initialized = TRUE;
189
190   /* We set the fallback program class here, rather than lazily in
191    * gdk_get_program_class, since we don't want -name to override it.
192    */
193   gdk_progclass = g_strdup (g_get_prgname ());
194   if (gdk_progclass && gdk_progclass[0])
195     gdk_progclass[0] = g_ascii_toupper (gdk_progclass[0]);
196   
197 #ifdef G_ENABLE_DEBUG
198   {
199     gchar *debug_string = getenv("GDK_DEBUG");
200     if (debug_string != NULL)
201       _gdk_debug_flags = g_parse_debug_string (debug_string,
202                                               (GDebugKey *) gdk_debug_keys,
203                                               gdk_ndebug_keys);
204   }
205 #endif  /* G_ENABLE_DEBUG */
206
207   if (getenv ("GDK_NATIVE_WINDOWS"))
208     {
209       _gdk_native_windows = TRUE;
210       /* Ensure that this is not propagated
211          to spawned applications */
212       g_unsetenv ("GDK_NATIVE_WINDOWS");
213     }
214
215   g_type_init ();
216
217   /* Do any setup particular to the windowing system
218    */
219   _gdk_windowing_init ();  
220 }
221
222   
223 /**
224  * gdk_parse_args:
225  * @argc: the number of command line arguments.
226  * @argv: the array of command line arguments.
227  * 
228  * Parse command line arguments, and store for future
229  * use by calls to gdk_display_open().
230  *
231  * Any arguments used by GDK are removed from the array and @argc and @argv are
232  * updated accordingly.
233  *
234  * You shouldn't call this function explicitely if you are using
235  * gtk_init(), gtk_init_check(), gdk_init(), or gdk_init_check().
236  *
237  * Since: 2.2
238  **/
239 void
240 gdk_parse_args (int    *argc,
241                 char ***argv)
242 {
243   GOptionContext *option_context;
244   GOptionGroup *option_group;
245   GError *error = NULL;
246
247   if (gdk_initialized)
248     return;
249
250   gdk_pre_parse_libgtk_only ();
251   
252   option_context = g_option_context_new (NULL);
253   g_option_context_set_ignore_unknown_options (option_context, TRUE);
254   g_option_context_set_help_enabled (option_context, FALSE);
255   option_group = g_option_group_new (NULL, NULL, NULL, NULL, NULL);
256   g_option_context_set_main_group (option_context, option_group);
257   
258   g_option_group_add_entries (option_group, gdk_args);
259   g_option_group_add_entries (option_group, _gdk_windowing_args);
260
261   if (!g_option_context_parse (option_context, argc, argv, &error))
262     {
263       g_warning ("%s", error->message);
264       g_error_free (error);
265     }
266   g_option_context_free (option_context);
267
268   GDK_NOTE (MISC, g_message ("progname: \"%s\"", g_get_prgname ()));
269 }
270
271 /** 
272  * gdk_get_display_arg_name:
273  *
274  * Gets the display name specified in the command line arguments passed
275  * to gdk_init() or gdk_parse_args(), if any.
276  *
277  * Returns: the display name, if specified explicitely, otherwise %NULL
278  *   this string is owned by GTK+ and must not be modified or freed.
279  *
280  * Since: 2.2
281  */
282 G_CONST_RETURN gchar *
283 gdk_get_display_arg_name (void)
284 {
285   if (!_gdk_display_arg_name)
286     {
287       if (_gdk_screen_number >= 0)
288         _gdk_display_arg_name = _gdk_windowing_substitute_screen_number (_gdk_display_name, _gdk_screen_number);
289       else
290         _gdk_display_arg_name = g_strdup (_gdk_display_name);
291    }
292
293    return _gdk_display_arg_name;
294 }
295
296 /**
297  * gdk_display_open_default_libgtk_only:
298  * 
299  * Opens the default display specified by command line arguments or
300  * environment variables, sets it as the default display, and returns
301  * it.  gdk_parse_args must have been called first. If the default
302  * display has previously been set, simply returns that. An internal
303  * function that should not be used by applications.
304  * 
305  * Return value: the default display, if it could be opened,
306  *   otherwise %NULL.
307  **/
308 GdkDisplay *
309 gdk_display_open_default_libgtk_only (void)
310 {
311   GdkDisplay *display;
312
313   g_return_val_if_fail (gdk_initialized, NULL);
314   
315   display = gdk_display_get_default ();
316   if (display)
317     return display;
318
319   display = gdk_display_open (gdk_get_display_arg_name ());
320
321   if (!display && _gdk_screen_number >= 0)
322     {
323       g_free (_gdk_display_arg_name);
324       _gdk_display_arg_name = g_strdup (_gdk_display_name);
325       
326       display = gdk_display_open (_gdk_display_name);
327     }
328   
329   if (display)
330     gdk_display_manager_set_default_display (gdk_display_manager_get (),
331                                              display);
332   
333   return display;
334 }
335
336 /**
337  * gdk_init_check:
338  * @argc: (inout):
339  * @argv: (array length=argc) (inout):
340  *
341  *   Initialize the library for use.
342  *
343  * Arguments:
344  *   "argc" is the number of arguments.
345  *   "argv" is an array of strings.
346  *
347  * Results:
348  *   "argc" and "argv" are modified to reflect any arguments
349  *   which were not handled. (Such arguments should either
350  *   be handled by the application or dismissed). If initialization
351  *   fails, returns FALSE, otherwise TRUE.
352  *
353  * Side effects:
354  *   The library is initialized.
355  *
356  *--------------------------------------------------------------
357  */
358 gboolean
359 gdk_init_check (int    *argc,
360                 char ***argv)
361 {
362   gdk_parse_args (argc, argv);
363
364   return gdk_display_open_default_libgtk_only () != NULL;
365 }
366
367
368 /**
369  * gdk_init:
370  * @argc: (inout):
371  * @argv: (array length=argc) (inout):
372  */
373 void
374 gdk_init (int *argc, char ***argv)
375 {
376   if (!gdk_init_check (argc, argv))
377     {
378       const char *display_name = gdk_get_display_arg_name ();
379       g_warning ("cannot open display: %s", display_name ? display_name : "");
380       exit(1);
381     }
382 }
383
384 void
385 gdk_threads_enter (void)
386 {
387   GDK_THREADS_ENTER ();
388 }
389
390 void
391 gdk_threads_leave (void)
392 {
393   GDK_THREADS_LEAVE ();
394 }
395
396 static void
397 gdk_threads_impl_lock (void)
398 {
399   if (gdk_threads_mutex)
400     g_mutex_lock (gdk_threads_mutex);
401 }
402
403 static void
404 gdk_threads_impl_unlock (void)
405 {
406   if (gdk_threads_mutex)
407     g_mutex_unlock (gdk_threads_mutex);
408 }
409
410 /**
411  * gdk_threads_init:
412  * 
413  * Initializes GDK so that it can be used from multiple threads
414  * in conjunction with gdk_threads_enter() and gdk_threads_leave().
415  * g_thread_init() must be called previous to this function.
416  *
417  * This call must be made before any use of the main loop from
418  * GTK+; to be safe, call it before gtk_init().
419  **/
420 void
421 gdk_threads_init (void)
422 {
423   if (!g_thread_supported ())
424     g_error ("g_thread_init() must be called before gdk_threads_init()");
425
426   gdk_threads_mutex = g_mutex_new ();
427   if (!gdk_threads_lock)
428     gdk_threads_lock = gdk_threads_impl_lock;
429   if (!gdk_threads_unlock)
430     gdk_threads_unlock = gdk_threads_impl_unlock;
431 }
432
433 /**
434  * gdk_threads_set_lock_functions:
435  * @enter_fn:   function called to guard GDK
436  * @leave_fn: function called to release the guard
437  *
438  * Allows the application to replace the standard method that
439  * GDK uses to protect its data structures. Normally, GDK
440  * creates a single #GMutex that is locked by gdk_threads_enter(),
441  * and released by gdk_threads_leave(); using this function an
442  * application provides, instead, a function @enter_fn that is
443  * called by gdk_threads_enter() and a function @leave_fn that is
444  * called by gdk_threads_leave().
445  *
446  * The functions must provide at least same locking functionality
447  * as the default implementation, but can also do extra application
448  * specific processing.
449  *
450  * As an example, consider an application that has its own recursive
451  * lock that when held, holds the GTK+ lock as well. When GTK+ unlocks
452  * the GTK+ lock when entering a recursive main loop, the application
453  * must temporarily release its lock as well.
454  *
455  * Most threaded GTK+ apps won't need to use this method.
456  *
457  * This method must be called before gdk_threads_init(), and cannot
458  * be called multiple times.
459  *
460  * Since: 2.4
461  **/
462 void
463 gdk_threads_set_lock_functions (GCallback enter_fn,
464                                 GCallback leave_fn)
465 {
466   g_return_if_fail (gdk_threads_lock == NULL &&
467                     gdk_threads_unlock == NULL);
468
469   gdk_threads_lock = enter_fn;
470   gdk_threads_unlock = leave_fn;
471 }
472
473 static gboolean
474 gdk_threads_dispatch (gpointer data)
475 {
476   GdkThreadsDispatch *dispatch = data;
477   gboolean ret = FALSE;
478
479   GDK_THREADS_ENTER ();
480
481   if (!g_source_is_destroyed (g_main_current_source ()))
482     ret = dispatch->func (dispatch->data);
483
484   GDK_THREADS_LEAVE ();
485
486   return ret;
487 }
488
489 static void
490 gdk_threads_dispatch_free (gpointer data)
491 {
492   GdkThreadsDispatch *dispatch = data;
493
494   if (dispatch->destroy && dispatch->data)
495     dispatch->destroy (dispatch->data);
496
497   g_slice_free (GdkThreadsDispatch, data);
498 }
499
500
501 /**
502  * gdk_threads_add_idle_full:
503  * @priority: the priority of the idle source. Typically this will be in the
504  *            range btweeen #G_PRIORITY_DEFAULT_IDLE and #G_PRIORITY_HIGH_IDLE
505  * @function: function to call
506  * @data:     data to pass to @function
507  * @notify: (allow-none):   function to call when the idle is removed, or %NULL
508  *
509  * Adds a function to be called whenever there are no higher priority
510  * events pending.  If the function returns %FALSE it is automatically
511  * removed from the list of event sources and will not be called again.
512  *
513  * This variant of g_idle_add_full() calls @function with the GDK lock
514  * held. It can be thought of a MT-safe version for GTK+ widgets for the 
515  * following use case, where you have to worry about idle_callback()
516  * running in thread A and accessing @self after it has been finalized
517  * in thread B:
518  *
519  * |[
520  * static gboolean
521  * idle_callback (gpointer data)
522  * {
523  *    /&ast; gdk_threads_enter(); would be needed for g_idle_add() &ast;/
524  *
525  *    SomeWidget *self = data;
526  *    /&ast; do stuff with self &ast;/
527  *
528  *    self->idle_id = 0;
529  *
530  *    /&ast; gdk_threads_leave(); would be needed for g_idle_add() &ast;/
531  *    return FALSE;
532  * }
533  *
534  * static void
535  * some_widget_do_stuff_later (SomeWidget *self)
536  * {
537  *    self->idle_id = gdk_threads_add_idle (idle_callback, self)
538  *    /&ast; using g_idle_add() here would require thread protection in the callback &ast;/
539  * }
540  *
541  * static void
542  * some_widget_finalize (GObject *object)
543  * {
544  *    SomeWidget *self = SOME_WIDGET (object);
545  *    if (self->idle_id)
546  *      g_source_remove (self->idle_id);
547  *    G_OBJECT_CLASS (parent_class)->finalize (object);
548  * }
549  * ]|
550  *
551  * Return value: the ID (greater than 0) of the event source.
552  *
553  * Since: 2.12
554  */
555 guint
556 gdk_threads_add_idle_full (gint           priority,
557                            GSourceFunc    function,
558                            gpointer       data,
559                            GDestroyNotify notify)
560 {
561   GdkThreadsDispatch *dispatch;
562
563   g_return_val_if_fail (function != NULL, 0);
564
565   dispatch = g_slice_new (GdkThreadsDispatch);
566   dispatch->func = function;
567   dispatch->data = data;
568   dispatch->destroy = notify;
569
570   return g_idle_add_full (priority,
571                           gdk_threads_dispatch,
572                           dispatch,
573                           gdk_threads_dispatch_free);
574 }
575
576 /**
577  * gdk_threads_add_idle:
578  * @function: function to call
579  * @data:     data to pass to @function
580  *
581  * A wrapper for the common usage of gdk_threads_add_idle_full() 
582  * assigning the default priority, #G_PRIORITY_DEFAULT_IDLE.
583  *
584  * See gdk_threads_add_idle_full().
585  *
586  * Return value: the ID (greater than 0) of the event source.
587  * 
588  * Since: 2.12
589  */
590 guint
591 gdk_threads_add_idle (GSourceFunc    function,
592                       gpointer       data)
593 {
594   return gdk_threads_add_idle_full (G_PRIORITY_DEFAULT_IDLE,
595                                     function, data, NULL);
596 }
597
598
599 /**
600  * gdk_threads_add_timeout_full:
601  * @priority: the priority of the timeout source. Typically this will be in the
602  *            range between #G_PRIORITY_DEFAULT_IDLE and #G_PRIORITY_HIGH_IDLE.
603  * @interval: the time between calls to the function, in milliseconds
604  *             (1/1000ths of a second)
605  * @function: function to call
606  * @data:     data to pass to @function
607  * @notify: (allow-none):   function to call when the timeout is removed, or %NULL
608  *
609  * Sets a function to be called at regular intervals holding the GDK lock,
610  * with the given priority.  The function is called repeatedly until it 
611  * returns %FALSE, at which point the timeout is automatically destroyed 
612  * and the function will not be called again.  The @notify function is
613  * called when the timeout is destroyed.  The first call to the
614  * function will be at the end of the first @interval.
615  *
616  * Note that timeout functions may be delayed, due to the processing of other
617  * event sources. Thus they should not be relied on for precise timing.
618  * After each call to the timeout function, the time of the next
619  * timeout is recalculated based on the current time and the given interval
620  * (it does not try to 'catch up' time lost in delays).
621  *
622  * This variant of g_timeout_add_full() can be thought of a MT-safe version 
623  * for GTK+ widgets for the following use case:
624  *
625  * |[
626  * static gboolean timeout_callback (gpointer data)
627  * {
628  *    SomeWidget *self = data;
629  *    
630  *    /&ast; do stuff with self &ast;/
631  *    
632  *    self->timeout_id = 0;
633  *    
634  *    return FALSE;
635  * }
636  *  
637  * static void some_widget_do_stuff_later (SomeWidget *self)
638  * {
639  *    self->timeout_id = g_timeout_add (timeout_callback, self)
640  * }
641  *  
642  * static void some_widget_finalize (GObject *object)
643  * {
644  *    SomeWidget *self = SOME_WIDGET (object);
645  *    
646  *    if (self->timeout_id)
647  *      g_source_remove (self->timeout_id);
648  *    
649  *    G_OBJECT_CLASS (parent_class)->finalize (object);
650  * }
651  * ]|
652  *
653  * Return value: the ID (greater than 0) of the event source.
654  * 
655  * Since: 2.12
656  */
657 guint
658 gdk_threads_add_timeout_full (gint           priority,
659                               guint          interval,
660                               GSourceFunc    function,
661                               gpointer       data,
662                               GDestroyNotify notify)
663 {
664   GdkThreadsDispatch *dispatch;
665
666   g_return_val_if_fail (function != NULL, 0);
667
668   dispatch = g_slice_new (GdkThreadsDispatch);
669   dispatch->func = function;
670   dispatch->data = data;
671   dispatch->destroy = notify;
672
673   return g_timeout_add_full (priority, 
674                              interval,
675                              gdk_threads_dispatch, 
676                              dispatch, 
677                              gdk_threads_dispatch_free);
678 }
679
680 /**
681  * gdk_threads_add_timeout:
682  * @interval: the time between calls to the function, in milliseconds
683  *             (1/1000ths of a second)
684  * @function: function to call
685  * @data:     data to pass to @function
686  *
687  * A wrapper for the common usage of gdk_threads_add_timeout_full() 
688  * assigning the default priority, #G_PRIORITY_DEFAULT.
689  *
690  * See gdk_threads_add_timeout_full().
691  * 
692  * Return value: the ID (greater than 0) of the event source.
693  *
694  * Since: 2.12
695  */
696 guint
697 gdk_threads_add_timeout (guint       interval,
698                          GSourceFunc function,
699                          gpointer    data)
700 {
701   return gdk_threads_add_timeout_full (G_PRIORITY_DEFAULT,
702                                        interval, function, data, NULL);
703 }
704
705
706 /**
707  * gdk_threads_add_timeout_seconds_full:
708  * @priority: the priority of the timeout source. Typically this will be in the
709  *            range between #G_PRIORITY_DEFAULT_IDLE and #G_PRIORITY_HIGH_IDLE.
710  * @interval: the time between calls to the function, in seconds
711  * @function: function to call
712  * @data:     data to pass to @function
713  * @notify: (allow-none):   function to call when the timeout is removed, or %NULL
714  *
715  * A variant of gdk_threads_add_timout_full() with second-granularity.
716  * See g_timeout_add_seconds_full() for a discussion of why it is
717  * a good idea to use this function if you don't need finer granularity.
718  *
719  *  Return value: the ID (greater than 0) of the event source.
720  * 
721  * Since: 2.14
722  */
723 guint
724 gdk_threads_add_timeout_seconds_full (gint           priority,
725                                       guint          interval,
726                                       GSourceFunc    function,
727                                       gpointer       data,
728                                       GDestroyNotify notify)
729 {
730   GdkThreadsDispatch *dispatch;
731
732   g_return_val_if_fail (function != NULL, 0);
733
734   dispatch = g_slice_new (GdkThreadsDispatch);
735   dispatch->func = function;
736   dispatch->data = data;
737   dispatch->destroy = notify;
738
739   return g_timeout_add_seconds_full (priority, 
740                                      interval,
741                                      gdk_threads_dispatch, 
742                                      dispatch, 
743                                      gdk_threads_dispatch_free);
744 }
745
746 /**
747  * gdk_threads_add_timeout_seconds:
748  * @interval: the time between calls to the function, in seconds
749  * @function: function to call
750  * @data:     data to pass to @function
751  *
752  * A wrapper for the common usage of gdk_threads_add_timeout_seconds_full() 
753  * assigning the default priority, #G_PRIORITY_DEFAULT.
754  *
755  * For details, see gdk_threads_add_timeout_full().
756  * 
757  * Return value: the ID (greater than 0) of the event source.
758  *
759  * Since: 2.14
760  */
761 guint
762 gdk_threads_add_timeout_seconds (guint       interval,
763                                  GSourceFunc function,
764                                  gpointer    data)
765 {
766   return gdk_threads_add_timeout_seconds_full (G_PRIORITY_DEFAULT,
767                                                interval, function, data, NULL);
768 }
769
770
771 G_CONST_RETURN char *
772 gdk_get_program_class (void)
773 {
774   return gdk_progclass;
775 }
776
777 void
778 gdk_set_program_class (const char *program_class)
779 {
780   g_free (gdk_progclass);
781
782   gdk_progclass = g_strdup (program_class);
783 }
784
785 /**
786  * gdk_enable_multidevice:
787  *
788  * Enables multidevice support in GDK. This call must happen prior
789  * to gdk_display_open(), gtk_init(), gtk_init_with_args() or
790  * gtk_init_check() in order to take effect.
791  *
792  * Note that individual #GdkWindow<!-- -->s still need to explicitly
793  * enable multidevice awareness through gdk_window_set_support_multidevice().
794  *
795  * This function must be called before initializing GDK.
796  *
797  * Since: 3.0
798  **/
799 void
800 gdk_enable_multidevice (void)
801 {
802   if (gdk_initialized)
803     return;
804
805   _gdk_enable_multidevice = TRUE;
806 }