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