Merge r21-4-11-chise-0_20-=ucs.
[chise/xemacs-chise.git.1] / src / device-gtk.c
1 /* Device functions for X windows.
2    Copyright (C) 1994, 1995 Board of Trustees, University of Illinois.
3    Copyright (C) 1994, 1995 Free Software Foundation, Inc.
4
5 This file is part of XEmacs.
6
7 XEmacs is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
10 later version.
11
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with XEmacs; see the file COPYING.  If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22 /* Synched up with: Not in FSF. */
23
24 /* Original authors: Jamie Zawinski and the FSF */
25 /* Rewritten by Ben Wing and Chuck Thompson. */
26 /* Gtk flavor written by William Perry */
27
28 #include <config.h>
29 #include "lisp.h"
30
31 #include "console-gtk.h"
32 #include "gccache-gtk.h"
33 #include "glyphs-gtk.h"
34 #include "objects-gtk.h"
35 #include "gtk-xemacs.h"
36
37 #include "buffer.h"
38 #include "events.h"
39 #include "faces.h"
40 #include "frame.h"
41 #include "redisplay.h"
42 #include "sysdep.h"
43 #include "window.h"
44 #include "elhash.h"
45
46 #include "sysfile.h"
47 #include "systime.h"
48
49 #ifdef HAVE_GNOME
50 #include <libgnomeui/libgnomeui.h>
51 #endif
52
53 #ifdef HAVE_BONOBO
54 #include <bonobo.h>
55 #endif
56
57 Lisp_Object Vdefault_gtk_device;
58
59 /* Qdisplay in general.c */
60 Lisp_Object Qinit_pre_gtk_win, Qinit_post_gtk_win;
61
62 /* The application class of Emacs. */
63 Lisp_Object Vgtk_emacs_application_class;
64
65 Lisp_Object Vgtk_initial_argv_list; /* #### ugh! */
66 Lisp_Object Vgtk_initial_geometry;
67
68 static void gtk_device_init_x_specific_cruft (struct device *d);
69
70 \f
71 /************************************************************************/
72 /*                          helper functions                            */
73 /************************************************************************/
74
75 struct device *
76 decode_gtk_device (Lisp_Object device)
77 {
78   XSETDEVICE (device, decode_device (device));
79   CHECK_GTK_DEVICE (device);
80   return XDEVICE (device);
81 }
82
83 \f
84 /************************************************************************/
85 /*                    initializing a GTK connection                     */
86 /************************************************************************/
87 extern Lisp_Object
88 xemacs_gtk_convert_color(GdkColor *c, GtkWidget *w);
89
90 extern Lisp_Object __get_gtk_font_truename (GdkFont *gdk_font, int expandp);
91
92 #define convert_font(f) __get_gtk_font_truename (f, 0)
93
94 static void
95 allocate_gtk_device_struct (struct device *d)
96 {
97   d->device_data = xnew_and_zero (struct gtk_device);
98   DEVICE_GTK_DATA (d)->x_keysym_map_hashtable = Qnil;
99 }
100
101 static void
102 gtk_init_device_class (struct device *d)
103 {
104   if (DEVICE_GTK_DEPTH(d) > 2)
105     {
106       switch (DEVICE_GTK_VISUAL(d)->type)
107         {
108         case GDK_VISUAL_STATIC_GRAY:
109         case GDK_VISUAL_GRAYSCALE:
110           DEVICE_CLASS (d) = Qgrayscale;
111           break;
112         default:
113           DEVICE_CLASS (d) = Qcolor;
114         }
115     }
116   else
117     DEVICE_CLASS (d) = Qmono;
118 }
119
120 #ifdef HAVE_GDK_IMLIB_INIT
121 extern void gdk_imlib_init(void);
122 #endif
123
124 extern void emacs_gtk_selection_handle (GtkWidget *,
125                                         GtkSelectionData *selection_data,
126                                         guint info,
127                                         guint time_stamp,
128                                         gpointer data);
129 extern void emacs_gtk_selection_clear_event_handle (GtkWidget *widget,
130                                                     GdkEventSelection *event,
131                                                     gpointer data);
132 extern void emacs_gtk_selection_received (GtkWidget *widget,
133                                           GtkSelectionData *selection_data,
134                                           gpointer user_data);
135
136 #ifdef HAVE_BONOBO
137 static CORBA_ORB orb;
138 #endif
139
140 DEFUN ("gtk-init", Fgtk_init, 1, 1, 0, /*
141 Initialize the GTK subsystem.
142 ARGS is a standard list of command-line arguments.
143
144 No effect if called more than once.  Called automatically when
145 creating the first GTK device.  Must be called manually from batch
146 mode.
147 */
148        (args))
149 {
150   int argc;
151   char **argv;
152   static int done;
153
154   if (done)
155     {
156       return (Qt);
157     }
158
159   make_argc_argv (args, &argc, &argv);
160
161   slow_down_interrupts ();
162 #ifdef HAVE_GNOME
163 #ifdef INFODOCK
164   gnome_init ("InfoDock", EMACS_VERSION, argc, argv);
165 #else
166   gnome_init ("XEmacs", EMACS_VERSION, argc, argv);
167 #endif /* INFODOCK */
168 #else
169   gtk_init (&argc, &argv);
170 #endif
171
172 #ifdef HAVE_BONOBO
173   orb = oaf_init (argc, argv);
174
175   if (bonobo_init (orb, NULL, NULL) == FALSE)
176     {
177       g_warning ("Could not initialize bonobo...");
178     }
179
180   bonobo_activate ();
181 #endif
182
183   speed_up_interrupts ();
184
185   free_argc_argv (argv);
186   return (Qt);
187 }
188
189 static void
190 gtk_init_device (struct device *d, Lisp_Object props)
191 {
192   Lisp_Object device;
193   Lisp_Object display;
194   GtkWidget *app_shell = NULL;
195   GdkVisual *visual = NULL;
196   GdkColormap *cmap = NULL;
197
198   XSETDEVICE (device, d);
199
200   /* gtk_init() and even gtk_check_init() are so brain dead that
201      getting an empty argv array causes them to abort. */
202   if (NILP (Vgtk_initial_argv_list))
203     {
204       signal_simple_error ("gtk-initial-argv-list must be set before creating Gtk devices", Vgtk_initial_argv_list);
205       return;
206     }
207
208   allocate_gtk_device_struct (d);
209   display = DEVICE_CONNECTION (d);
210
211   /* Attempt to load a site-specific gtkrc */
212   {
213     Lisp_Object gtkrc = Fexpand_file_name (build_string ("gtkrc"), Vdata_directory);
214     gchar **default_files = gtk_rc_get_default_files ();
215     gint num_files;
216
217     if (STRINGP (gtkrc))
218       {
219         /* Found one, load it up! */
220         gchar **new_rc_files = NULL;
221         int ctr;
222
223         for (num_files = 0; default_files[num_files]; num_files++);
224
225         new_rc_files = xnew_array_and_zero (gchar *, num_files + 3);
226
227         new_rc_files[0] = XSTRING_DATA (gtkrc);
228         for (ctr = 1; default_files[ctr-1]; ctr++)
229           new_rc_files[ctr] = g_strdup (default_files[ctr-1]);
230
231         gtk_rc_set_default_files (new_rc_files);
232
233         for (ctr = 1; new_rc_files[ctr]; ctr++)
234           free(new_rc_files[ctr]);
235
236         xfree (new_rc_files);
237       }
238   }
239
240   Fgtk_init (Vgtk_initial_argv_list);
241
242 #ifdef __FreeBSD__
243   gdk_set_use_xshm (FALSE);
244 #endif
245
246   /* We attempt to load this file so that the user can set
247   ** gtk-initial-geometry and not need GNOME & session management to
248   ** set their default frame size.  It also avoids the flicker
249   ** associated with setting the frame size in your .emacs file.
250   */
251   call4 (Qload, build_string ("~/.xemacs/gtk-options.el"), Qt, Qt, Qt);
252
253 #ifdef HAVE_GDK_IMLIB_INIT
254   /* Some themes in Gtk are so lame (most notably the Pixmap theme)
255      that they rely on gdk_imlib, but don't call its initialization
256      routines.  This makes them USELESS for non-gnome applications.
257      So we bend over backwards to try and make them work.  Losers. */
258   gdk_imlib_init ();
259 #endif
260
261   if (NILP (DEVICE_NAME (d)))
262     DEVICE_NAME (d) = display;
263
264   /* Always search for the best visual */
265   visual = gdk_visual_get_best();
266   cmap = gdk_colormap_new (visual, TRUE);
267
268   DEVICE_GTK_VISUAL (d) = visual;
269   DEVICE_GTK_COLORMAP (d) = cmap;
270   DEVICE_GTK_DEPTH (d) = visual->depth;
271
272   {
273     GtkWidget *w = gtk_window_new (GTK_WINDOW_TOPLEVEL);
274
275     app_shell = gtk_xemacs_new (NULL);
276     gtk_container_add (GTK_CONTAINER (w), app_shell);
277
278     gtk_widget_realize (w);
279   }
280
281   DEVICE_GTK_APP_SHELL (d) = app_shell;
282
283   /* Realize the app_shell so that its window exists for GC creation
284      purposes */
285   gtk_widget_realize (GTK_WIDGET (app_shell));
286
287   /* Need to set up some selection handlers */
288   gtk_selection_add_target (GTK_WIDGET (app_shell), GDK_SELECTION_PRIMARY,
289                             GDK_SELECTION_TYPE_STRING, 0);
290   gtk_selection_add_target (GTK_WIDGET (app_shell),
291                             gdk_atom_intern("CLIPBOARD", FALSE),
292                             GDK_SELECTION_TYPE_STRING, 0);
293   
294   gtk_signal_connect (GTK_OBJECT (app_shell), "selection_get",
295                       GTK_SIGNAL_FUNC (emacs_gtk_selection_handle), NULL);
296   gtk_signal_connect (GTK_OBJECT (app_shell), "selection_clear_event",
297                       GTK_SIGNAL_FUNC (emacs_gtk_selection_clear_event_handle),
298                       NULL);
299   gtk_signal_connect (GTK_OBJECT (app_shell), "selection_received",
300                       GTK_SIGNAL_FUNC (emacs_gtk_selection_received), NULL);
301
302   DEVICE_GTK_WM_COMMAND_FRAME (d) = Qnil;
303
304   gtk_init_modifier_mapping (d);
305
306   gtk_device_init_x_specific_cruft (d);
307
308   init_baud_rate (d);
309   init_one_device (d);
310
311   DEVICE_GTK_GC_CACHE (d) = make_gc_cache (GTK_WIDGET (app_shell));
312   DEVICE_GTK_GRAY_PIXMAP (d) = NULL;
313
314   gtk_init_device_class (d);
315
316   /* Run the elisp side of the X device initialization. */
317   call0 (Qinit_pre_gtk_win);
318 }
319
320 static void
321 gtk_finish_init_device (struct device *d, Lisp_Object props)
322 {
323   call0 (Qinit_post_gtk_win);
324 }
325
326 static void
327 gtk_mark_device (struct device *d)
328 {
329   mark_object (DEVICE_GTK_WM_COMMAND_FRAME (d));
330   mark_object (DEVICE_GTK_DATA (d)->x_keysym_map_hashtable);
331 }
332
333 \f
334 /************************************************************************/
335 /*                       closing an X connection                        */
336 /************************************************************************/
337
338 static void
339 free_gtk_device_struct (struct device *d)
340 {
341   xfree (d->device_data);
342 }
343
344 static void
345 gtk_delete_device (struct device *d)
346 {
347   Lisp_Object device;
348
349 #ifdef FREE_CHECKING
350   extern void (*__free_hook)();
351   int checking_free;
352 #endif
353
354   XSETDEVICE (device, d);
355   if (1)
356     {
357 #ifdef FREE_CHECKING
358       checking_free = (__free_hook != 0);
359
360       /* Disable strict free checking, to avoid bug in X library */
361       if (checking_free)
362         disable_strict_free_check ();
363 #endif
364
365       free_gc_cache (DEVICE_GTK_GC_CACHE (d));
366
367 #ifdef FREE_CHECKING
368       if (checking_free)
369         enable_strict_free_check ();
370 #endif
371     }
372
373   if (EQ (device, Vdefault_gtk_device))
374     {
375       Lisp_Object devcons, concons;
376       /* #### handle deleting last X device */
377       Vdefault_gtk_device = Qnil;
378       DEVICE_LOOP_NO_BREAK (devcons, concons)
379         {
380           if (DEVICE_GTK_P (XDEVICE (XCAR (devcons))) &&
381               !EQ (device, XCAR (devcons)))
382             {
383               Vdefault_gtk_device = XCAR (devcons);
384               goto double_break;
385             }
386         }
387     }
388  double_break:
389   free_gtk_device_struct (d);
390 }
391
392 \f
393 /************************************************************************/
394 /*                              handle X errors                         */
395 /************************************************************************/
396
397 const char *
398 gtk_event_name (GdkEventType event_type)
399 {
400   GtkEnumValue *vals = gtk_type_enum_get_values (GTK_TYPE_GDK_EVENT_TYPE);
401
402   while (vals && (vals->value != event_type)) vals++;
403
404   if (vals)
405     return (vals->value_nick);
406
407   return (NULL);
408 }
409
410 \f
411 /************************************************************************/
412 /*                   display information functions                      */
413 /************************************************************************/
414
415 DEFUN ("default-gtk-device", Fdefault_gtk_device, 0, 0, 0, /*
416 Return the default GTK device for resourcing.
417 This is the first-created GTK device that still exists.
418 */
419        ())
420 {
421   return Vdefault_gtk_device;
422 }
423
424 DEFUN ("gtk-display-visual-class", Fgtk_display_visual_class, 0, 1, 0, /*
425 Return the visual class of the GTK display DEVICE is using.
426 The returned value will be one of the symbols `static-gray', `gray-scale',
427 `static-color', `pseudo-color', `true-color', or `direct-color'.
428 */
429        (device))
430 {
431   GdkVisual *vis = DEVICE_GTK_VISUAL (decode_gtk_device (device));
432   switch (vis->type)
433     {
434     case GDK_VISUAL_STATIC_GRAY:  return intern ("static-gray");
435     case GDK_VISUAL_GRAYSCALE:    return intern ("gray-scale");
436     case GDK_VISUAL_STATIC_COLOR: return intern ("static-color");
437     case GDK_VISUAL_PSEUDO_COLOR: return intern ("pseudo-color");
438     case GDK_VISUAL_TRUE_COLOR:   return intern ("true-color");
439     case GDK_VISUAL_DIRECT_COLOR: return intern ("direct-color");
440     default:
441       error ("display has an unknown visual class");
442       return Qnil;      /* suppress compiler warning */
443     }
444 }
445
446 DEFUN ("gtk-display-visual-depth", Fgtk_display_visual_depth, 0, 1, 0, /*
447 Return the bitplane depth of the visual the GTK display DEVICE is using.
448 */
449        (device))
450 {
451    return make_int (DEVICE_GTK_DEPTH (decode_gtk_device (device)));
452 }
453
454 static Lisp_Object
455 gtk_device_system_metrics (struct device *d,
456                            enum device_metrics m)
457 {
458 #if 0
459   GtkStyle *style = gtk_widget_get_style (GTK_WIDGET (DEVICE_GTK_APP_SHELL (d)));
460
461   style = gtk_style_attach (style, w);
462 #endif
463   
464   switch (m)
465     {
466     case DM_size_device:
467       return Fcons (make_int (gdk_screen_width ()),
468                     make_int (gdk_screen_height ()));
469     case DM_size_device_mm:
470       return Fcons (make_int (gdk_screen_width_mm ()),
471                     make_int (gdk_screen_height_mm ()));
472     case DM_num_color_cells:
473       return make_int (gdk_colormap_get_system_size ());
474     case DM_num_bit_planes:
475       return make_int (DEVICE_GTK_DEPTH (d));
476
477 #if 0
478     case DM_color_default:
479     case DM_color_select:
480     case DM_color_balloon:
481     case DM_color_3d_face:
482     case DM_color_3d_light:
483     case DM_color_3d_dark:
484     case DM_color_menu:
485     case DM_color_menu_highlight:
486     case DM_color_menu_button:
487     case DM_color_menu_disabled:
488     case DM_color_toolbar:
489     case DM_color_scrollbar:
490     case DM_color_desktop:
491     case DM_color_workspace:
492     case DM_font_default:
493     case DM_font_menubar:
494     case DM_font_dialog:
495     case DM_size_cursor:
496     case DM_size_scrollbar:
497     case DM_size_menu:
498     case DM_size_toolbar:
499     case DM_size_toolbar_button:
500     case DM_size_toolbar_border:
501     case DM_size_icon:
502     case DM_size_icon_small:
503     case DM_size_workspace:
504     case DM_device_dpi:
505     case DM_mouse_buttons:
506     case DM_swap_buttons:
507     case DM_show_sounds:
508     case DM_slow_device:
509     case DM_security:
510 #endif
511     default: /* No such device metric property for GTK devices  */
512       return Qunbound;
513     }
514 }
515
516 DEFUN ("gtk-keysym-on-keyboard-p", Fgtk_keysym_on_keyboard_p, 1, 2, 0, /*
517 Return true if KEYSYM names a key on the keyboard of DEVICE.
518 More precisely, return true if some keystroke (possibly including modifiers)
519 on the keyboard of DEVICE keys generates KEYSYM.
520 Valid keysyms are listed in the files /usr/include/X11/keysymdef.h and in
521 /usr/lib/X11/XKeysymDB, or whatever the equivalents are on your system.
522 The keysym name can be provided in two forms:
523 - if keysym is a string, it must be the name as known to X windows.
524 - if keysym is a symbol, it must be the name as known to XEmacs.
525 The two names differ in capitalization and underscoring.
526 */
527        (keysym, device))
528 {
529   struct device *d = decode_device (device);
530
531   if (!DEVICE_GTK_P (d))
532     signal_simple_error ("Not a GTK device", device);
533
534   return (NILP (Fgethash (keysym, DEVICE_GTK_DATA (d)->x_keysym_map_hashtable, Qnil)) ?
535           Qnil : Qt);
536 }
537
538 \f
539 /************************************************************************/
540 /*                          grabs and ungrabs                           */
541 /************************************************************************/
542
543 DEFUN ("gtk-grab-pointer", Fgtk_grab_pointer, 0, 3, 0, /*
544 Grab the pointer and restrict it to its current window.
545 If optional DEVICE argument is nil, the default device will be used.
546 If optional CURSOR argument is non-nil, change the pointer shape to that
547  until `gtk-ungrab-pointer' is called (it should be an object returned by the
548  `make-cursor-glyph' function).
549 If the second optional argument IGNORE-KEYBOARD is non-nil, ignore all
550   keyboard events during the grab.
551 Returns t if the grab is successful, nil otherwise.
552 */
553        (device, cursor, ignore_keyboard))
554 {
555   GdkWindow *w;
556   int result;
557   struct device *d = decode_gtk_device (device);
558
559   if (!NILP (cursor))
560     {
561       CHECK_POINTER_GLYPH (cursor);
562       cursor = glyph_image_instance (cursor, device, ERROR_ME, 0);
563     }
564
565   /* We should call gdk_pointer_grab() and (possibly) gdk_keyboard_grab() here instead */
566   w = GET_GTK_WIDGET_WINDOW (FRAME_GTK_TEXT_WIDGET (device_selected_frame (d)));
567
568   result = gdk_pointer_grab (w, FALSE,
569                              GDK_POINTER_MOTION_MASK |
570                              GDK_POINTER_MOTION_HINT_MASK |
571                              GDK_BUTTON1_MOTION_MASK |
572                              GDK_BUTTON2_MOTION_MASK |
573                              GDK_BUTTON3_MOTION_MASK |
574                              GDK_BUTTON_PRESS_MASK |
575                              GDK_BUTTON_RELEASE_MASK,
576                              w,
577                              NULL, /* #### BILL!!! Need to create a GdkCursor * as necessary! */
578                              GDK_CURRENT_TIME);
579
580   return (result == 0) ? Qt : Qnil;
581 }
582
583 DEFUN ("gtk-ungrab-pointer", Fgtk_ungrab_pointer, 0, 1, 0, /*
584 Release a pointer grab made with `gtk-grab-pointer'.
585 If optional first arg DEVICE is nil the default device is used.
586 If it is t the pointer will be released on all GTK devices.
587 */
588        (device))
589 {
590   if (!EQ (device, Qt))
591     {
592         gdk_pointer_ungrab (GDK_CURRENT_TIME);
593     }
594   else
595     {
596       Lisp_Object devcons, concons;
597
598       DEVICE_LOOP_NO_BREAK (devcons, concons)
599         {
600           struct device *d = XDEVICE (XCAR (devcons));
601
602           if (DEVICE_GTK_P (d))
603               gdk_pointer_ungrab (GDK_CURRENT_TIME);
604         }
605     }
606   return Qnil;
607 }
608
609 DEFUN ("gtk-grab-keyboard", Fgtk_grab_keyboard, 0, 1, 0, /*
610 Grab the keyboard on the given device (defaulting to the selected one).
611 So long as the keyboard is grabbed, all keyboard events will be delivered
612 to emacs -- it is not possible for other clients to eavesdrop on them.
613 Ungrab the keyboard with `gtk-ungrab-keyboard' (use an unwind-protect).
614 Returns t if the grab is successful, nil otherwise.
615 */
616        (device))
617 {
618   struct device *d = decode_gtk_device (device);
619   GdkWindow *w = GET_GTK_WIDGET_WINDOW (FRAME_GTK_TEXT_WIDGET (device_selected_frame (d)));
620
621   gdk_keyboard_grab (w, FALSE, GDK_CURRENT_TIME );
622
623   return Qt;
624 }
625
626 DEFUN ("gtk-ungrab-keyboard", Fgtk_ungrab_keyboard, 0, 1, 0, /*
627 Release a keyboard grab made with `gtk-grab-keyboard'.
628 */
629        (device))
630 {
631   gdk_keyboard_ungrab (GDK_CURRENT_TIME);
632   return Qnil;
633 }
634
635 \f
636 /************************************************************************/
637 /*                              Style Info                              */
638 /************************************************************************/
639 DEFUN ("gtk-style-info", Fgtk_style_info, 0, 1, 0, /*
640 Get the style information for a Gtk device.
641 */
642        (device))
643 {
644   struct device *d = decode_device (device);
645   GtkStyle *style = NULL;
646   Lisp_Object result = Qnil;
647   GtkWidget *app_shell = GTK_WIDGET (DEVICE_GTK_APP_SHELL (d));
648   GdkWindow *w = GET_GTK_WIDGET_WINDOW (app_shell);
649
650   if (!DEVICE_GTK_P (d))
651     return (Qnil);
652
653   style = gtk_widget_get_style (app_shell);
654   style = gtk_style_attach (style, w);
655
656   if (!style) return (Qnil);
657
658 #define FROB_COLOR(slot, name) \
659  result = nconc2 (result, \
660                 list2 (intern (name), \
661                 list5 (xemacs_gtk_convert_color (&style->slot[GTK_STATE_NORMAL], app_shell),\
662                         xemacs_gtk_convert_color (&style->slot[GTK_STATE_ACTIVE], app_shell),\
663                         xemacs_gtk_convert_color (&style->slot[GTK_STATE_PRELIGHT], app_shell),\
664                         xemacs_gtk_convert_color (&style->slot[GTK_STATE_SELECTED], app_shell),\
665                         xemacs_gtk_convert_color (&style->slot[GTK_STATE_INSENSITIVE], app_shell))))
666
667   FROB_COLOR (fg, "foreground");
668   FROB_COLOR (bg, "background");
669   FROB_COLOR (light, "light");
670   FROB_COLOR (dark, "dark");
671   FROB_COLOR (mid, "mid");
672   FROB_COLOR (text, "text");
673   FROB_COLOR (base, "base");
674 #undef FROB_COLOR
675
676   result = nconc2 (result, list2 (Qfont, convert_font (style->font)));
677
678 #define FROB_PIXMAP(state) (style->rc_style->bg_pixmap_name[state] ? build_string (style->rc_style->bg_pixmap_name[state]) : Qnil)
679
680   if (style->rc_style)
681     result = nconc2 (result, list2 (Qbackground,
682                                     list5 ( FROB_PIXMAP (GTK_STATE_NORMAL),
683                                             FROB_PIXMAP (GTK_STATE_ACTIVE),
684                                             FROB_PIXMAP (GTK_STATE_PRELIGHT),
685                                             FROB_PIXMAP (GTK_STATE_SELECTED),
686                                             FROB_PIXMAP (GTK_STATE_INSENSITIVE))));
687 #undef FROB_PIXMAP
688
689   return (result);
690 }
691
692 \f
693 /************************************************************************/
694 /*                            initialization                            */
695 /************************************************************************/
696
697 void
698 syms_of_device_gtk (void)
699 {
700   DEFSUBR (Fdefault_gtk_device);
701   DEFSUBR (Fgtk_keysym_on_keyboard_p);
702   DEFSUBR (Fgtk_display_visual_class);
703   DEFSUBR (Fgtk_display_visual_depth);
704   DEFSUBR (Fgtk_style_info);
705   DEFSUBR (Fgtk_grab_pointer);
706   DEFSUBR (Fgtk_ungrab_pointer);
707   DEFSUBR (Fgtk_grab_keyboard);
708   DEFSUBR (Fgtk_ungrab_keyboard);
709   DEFSUBR (Fgtk_init);
710
711   defsymbol (&Qinit_pre_gtk_win, "init-pre-gtk-win");
712   defsymbol (&Qinit_post_gtk_win, "init-post-gtk-win");
713 }
714
715 void
716 console_type_create_device_gtk (void)
717 {
718   CONSOLE_HAS_METHOD (gtk, init_device);
719   CONSOLE_HAS_METHOD (gtk, finish_init_device);
720   CONSOLE_HAS_METHOD (gtk, mark_device);
721   CONSOLE_HAS_METHOD (gtk, delete_device);
722   CONSOLE_HAS_METHOD (gtk, device_system_metrics);
723   /* CONSOLE_IMPLEMENTATION_FLAGS (gtk, XDEVIMPF_PIXEL_GEOMETRY); */
724   /* I inserted the above commented out statement, as the original
725      implementation of gtk_device_implementation_flags(), which I
726      deleted, contained commented out XDEVIMPF_PIXEL_GEOMETRY - kkm*/
727 }
728
729 void
730 vars_of_device_gtk (void)
731 {
732   Fprovide (Qgtk);
733
734   staticpro (&Vdefault_gtk_device);
735
736   DEFVAR_LISP ("gtk-initial-argv-list", &Vgtk_initial_argv_list /*
737 You don't want to know.
738 This is used during startup to communicate the remaining arguments in
739 `command-line-args-left' to the C code, which passes the args to
740 the GTK initialization code, which removes some args, and then the
741 args are placed back into `gtk-initial-arg-list' and thence into
742 `command-line-args-left'.  Perhaps `command-line-args-left' should
743 just reside in C.
744 */ );
745
746   DEFVAR_LISP ("gtk-initial-geometry", &Vgtk_initial_geometry /*
747 You don't want to know.
748 This is used during startup to communicate the default geometry to GTK.
749 */ );
750
751   Vdefault_gtk_device = Qnil;
752   Vgtk_initial_geometry = Qnil;
753   Vgtk_initial_argv_list = Qnil;
754 }
755
756 #include <gdk/gdkx.h>
757 static void
758 gtk_device_init_x_specific_cruft (struct device *d)
759 {
760   DEVICE_INFD (d) = DEVICE_OUTFD (d) = ConnectionNumber (GDK_DISPLAY ());
761 }