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.
5 This file is part of XEmacs.
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
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
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. */
22 /* Synched up with: Not in FSF. */
24 /* Original authors: Jamie Zawinski and the FSF */
25 /* Rewritten by Ben Wing and Chuck Thompson. */
26 /* Gtk flavor written by William Perry */
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"
41 #include "redisplay.h"
50 #include <libgnomeui/libgnomeui.h>
57 Lisp_Object Vdefault_gtk_device;
59 /* Qdisplay in general.c */
60 Lisp_Object Qinit_pre_gtk_win, Qinit_post_gtk_win;
62 /* The application class of Emacs. */
63 Lisp_Object Vgtk_emacs_application_class;
65 Lisp_Object Vgtk_initial_argv_list; /* #### ugh! */
66 Lisp_Object Vgtk_initial_geometry;
68 static void gtk_device_init_x_specific_cruft (struct device *d);
71 /************************************************************************/
72 /* helper functions */
73 /************************************************************************/
76 decode_gtk_device (Lisp_Object device)
78 XSETDEVICE (device, decode_device (device));
79 CHECK_GTK_DEVICE (device);
80 return XDEVICE (device);
84 /************************************************************************/
85 /* initializing a GTK connection */
86 /************************************************************************/
88 xemacs_gtk_convert_color(GdkColor *c, GtkWidget *w);
90 extern Lisp_Object __get_gtk_font_truename (GdkFont *gdk_font, int expandp);
92 #define convert_font(f) __get_gtk_font_truename (f, 0)
95 allocate_gtk_device_struct (struct device *d)
97 d->device_data = xnew_and_zero (struct gtk_device);
98 DEVICE_GTK_DATA (d)->x_keysym_map_hashtable = Qnil;
102 gtk_init_device_class (struct device *d)
104 if (DEVICE_GTK_DEPTH(d) > 2)
106 switch (DEVICE_GTK_VISUAL(d)->type)
108 case GDK_VISUAL_STATIC_GRAY:
109 case GDK_VISUAL_GRAYSCALE:
110 DEVICE_CLASS (d) = Qgrayscale;
113 DEVICE_CLASS (d) = Qcolor;
117 DEVICE_CLASS (d) = Qmono;
120 #ifdef HAVE_GDK_IMLIB_INIT
121 extern void gdk_imlib_init(void);
124 extern void emacs_gtk_selection_handle (GtkWidget *,
125 GtkSelectionData *selection_data,
129 extern void emacs_gtk_selection_clear_event_handle (GtkWidget *widget,
130 GdkEventSelection *event,
132 extern void emacs_gtk_selection_received (GtkWidget *widget,
133 GtkSelectionData *selection_data,
137 static CORBA_ORB orb;
140 DEFUN ("gtk-init", Fgtk_init, 1, 1, 0, /*
141 Initialize the GTK subsystem.
142 ARGS is a standard list of command-line arguments.
144 No effect if called more than once. Called automatically when
145 creating the first GTK device. Must be called manually from batch
159 make_argc_argv (args, &argc, &argv);
161 slow_down_interrupts ();
164 gnome_init ("InfoDock", EMACS_VERSION, argc, argv);
166 gnome_init ("XEmacs", EMACS_VERSION, argc, argv);
167 #endif /* INFODOCK */
169 gtk_init (&argc, &argv);
173 orb = oaf_init (argc, argv);
175 if (bonobo_init (orb, NULL, NULL) == FALSE)
177 g_warning ("Could not initialize bonobo...");
183 speed_up_interrupts ();
185 free_argc_argv (argv);
190 gtk_init_device (struct device *d, Lisp_Object props)
194 GtkWidget *app_shell = NULL;
195 GdkVisual *visual = NULL;
196 GdkColormap *cmap = NULL;
198 XSETDEVICE (device, d);
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))
204 signal_simple_error ("gtk-initial-argv-list must be set before creating Gtk devices", Vgtk_initial_argv_list);
208 allocate_gtk_device_struct (d);
209 display = DEVICE_CONNECTION (d);
211 /* Attempt to load a site-specific gtkrc */
213 Lisp_Object gtkrc = Fexpand_file_name (build_string ("gtkrc"), Vdata_directory);
214 gchar **default_files = gtk_rc_get_default_files ();
219 /* Found one, load it up! */
220 gchar **new_rc_files = NULL;
223 for (num_files = 0; default_files[num_files]; num_files++);
225 new_rc_files = xnew_array_and_zero (gchar *, num_files + 3);
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]);
231 gtk_rc_set_default_files (new_rc_files);
233 for (ctr = 1; new_rc_files[ctr]; ctr++)
234 free(new_rc_files[ctr]);
236 xfree (new_rc_files);
240 Fgtk_init (Vgtk_initial_argv_list);
243 gdk_set_use_xshm (FALSE);
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.
251 call4 (Qload, build_string ("~/.xemacs/gtk-options.el"), Qt, Qt, Qt);
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. */
261 if (NILP (DEVICE_NAME (d)))
262 DEVICE_NAME (d) = display;
264 /* Always search for the best visual */
265 visual = gdk_visual_get_best();
266 cmap = gdk_colormap_new (visual, TRUE);
268 DEVICE_GTK_VISUAL (d) = visual;
269 DEVICE_GTK_COLORMAP (d) = cmap;
270 DEVICE_GTK_DEPTH (d) = visual->depth;
273 GtkWidget *w = gtk_window_new (GTK_WINDOW_TOPLEVEL);
275 app_shell = gtk_xemacs_new (NULL);
276 gtk_container_add (GTK_CONTAINER (w), app_shell);
278 gtk_widget_realize (w);
281 DEVICE_GTK_APP_SHELL (d) = app_shell;
283 /* Realize the app_shell so that its window exists for GC creation
285 gtk_widget_realize (GTK_WIDGET (app_shell));
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);
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),
299 gtk_signal_connect (GTK_OBJECT (app_shell), "selection_received",
300 GTK_SIGNAL_FUNC (emacs_gtk_selection_received), NULL);
302 DEVICE_GTK_WM_COMMAND_FRAME (d) = Qnil;
304 gtk_init_modifier_mapping (d);
306 gtk_device_init_x_specific_cruft (d);
311 DEVICE_GTK_GC_CACHE (d) = make_gc_cache (GTK_WIDGET (app_shell));
312 DEVICE_GTK_GRAY_PIXMAP (d) = NULL;
314 gtk_init_device_class (d);
316 /* Run the elisp side of the X device initialization. */
317 call0 (Qinit_pre_gtk_win);
321 gtk_finish_init_device (struct device *d, Lisp_Object props)
323 call0 (Qinit_post_gtk_win);
327 gtk_mark_device (struct device *d)
329 mark_object (DEVICE_GTK_WM_COMMAND_FRAME (d));
330 mark_object (DEVICE_GTK_DATA (d)->x_keysym_map_hashtable);
334 /************************************************************************/
335 /* closing an X connection */
336 /************************************************************************/
339 free_gtk_device_struct (struct device *d)
341 xfree (d->device_data);
345 gtk_delete_device (struct device *d)
350 extern void (*__free_hook)();
354 XSETDEVICE (device, d);
358 checking_free = (__free_hook != 0);
360 /* Disable strict free checking, to avoid bug in X library */
362 disable_strict_free_check ();
365 free_gc_cache (DEVICE_GTK_GC_CACHE (d));
369 enable_strict_free_check ();
373 if (EQ (device, Vdefault_gtk_device))
375 Lisp_Object devcons, concons;
376 /* #### handle deleting last X device */
377 Vdefault_gtk_device = Qnil;
378 DEVICE_LOOP_NO_BREAK (devcons, concons)
380 if (DEVICE_GTK_P (XDEVICE (XCAR (devcons))) &&
381 !EQ (device, XCAR (devcons)))
383 Vdefault_gtk_device = XCAR (devcons);
389 free_gtk_device_struct (d);
393 /************************************************************************/
394 /* handle X errors */
395 /************************************************************************/
398 gtk_event_name (GdkEventType event_type)
400 GtkEnumValue *vals = gtk_type_enum_get_values (GTK_TYPE_GDK_EVENT_TYPE);
402 while (vals && (vals->value != event_type)) vals++;
405 return (vals->value_nick);
411 /************************************************************************/
412 /* display information functions */
413 /************************************************************************/
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.
421 return Vdefault_gtk_device;
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'.
431 GdkVisual *vis = DEVICE_GTK_VISUAL (decode_gtk_device (device));
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");
441 error ("display has an unknown visual class");
442 return Qnil; /* suppress compiler warning */
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.
451 return make_int (DEVICE_GTK_DEPTH (decode_gtk_device (device)));
455 gtk_device_system_metrics (struct device *d,
456 enum device_metrics m)
459 GtkStyle *style = gtk_widget_get_style (GTK_WIDGET (DEVICE_GTK_APP_SHELL (d)));
461 style = gtk_style_attach (style, w);
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));
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:
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:
496 case DM_size_scrollbar:
498 case DM_size_toolbar:
499 case DM_size_toolbar_button:
500 case DM_size_toolbar_border:
502 case DM_size_icon_small:
503 case DM_size_workspace:
505 case DM_mouse_buttons:
506 case DM_swap_buttons:
511 default: /* No such device metric property for GTK devices */
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.
529 struct device *d = decode_device (device);
531 if (!DEVICE_GTK_P (d))
532 signal_simple_error ("Not a GTK device", device);
534 return (NILP (Fgethash (keysym, DEVICE_GTK_DATA (d)->x_keysym_map_hashtable, Qnil)) ?
539 /************************************************************************/
540 /* grabs and ungrabs */
541 /************************************************************************/
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.
553 (device, cursor, ignore_keyboard))
557 struct device *d = decode_gtk_device (device);
561 CHECK_POINTER_GLYPH (cursor);
562 cursor = glyph_image_instance (cursor, device, ERROR_ME, 0);
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)));
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,
577 NULL, /* #### BILL!!! Need to create a GdkCursor * as necessary! */
580 return (result == 0) ? Qt : Qnil;
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.
590 if (!EQ (device, Qt))
592 gdk_pointer_ungrab (GDK_CURRENT_TIME);
596 Lisp_Object devcons, concons;
598 DEVICE_LOOP_NO_BREAK (devcons, concons)
600 struct device *d = XDEVICE (XCAR (devcons));
602 if (DEVICE_GTK_P (d))
603 gdk_pointer_ungrab (GDK_CURRENT_TIME);
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.
618 struct device *d = decode_gtk_device (device);
619 GdkWindow *w = GET_GTK_WIDGET_WINDOW (FRAME_GTK_TEXT_WIDGET (device_selected_frame (d)));
621 gdk_keyboard_grab (w, FALSE, GDK_CURRENT_TIME );
626 DEFUN ("gtk-ungrab-keyboard", Fgtk_ungrab_keyboard, 0, 1, 0, /*
627 Release a keyboard grab made with `gtk-grab-keyboard'.
631 gdk_keyboard_ungrab (GDK_CURRENT_TIME);
636 /************************************************************************/
638 /************************************************************************/
639 DEFUN ("gtk-style-info", Fgtk_style_info, 0, 1, 0, /*
640 Get the style information for a Gtk device.
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);
650 if (!DEVICE_GTK_P (d))
653 style = gtk_widget_get_style (app_shell);
654 style = gtk_style_attach (style, w);
656 if (!style) return (Qnil);
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))))
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");
676 result = nconc2 (result, list2 (Qfont, convert_font (style->font)));
678 #define FROB_PIXMAP(state) (style->rc_style->bg_pixmap_name[state] ? build_string (style->rc_style->bg_pixmap_name[state]) : Qnil)
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))));
693 /************************************************************************/
695 /************************************************************************/
698 syms_of_device_gtk (void)
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);
711 defsymbol (&Qinit_pre_gtk_win, "init-pre-gtk-win");
712 defsymbol (&Qinit_post_gtk_win, "init-post-gtk-win");
716 console_type_create_device_gtk (void)
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*/
730 vars_of_device_gtk (void)
734 staticpro (&Vdefault_gtk_device);
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
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.
751 Vdefault_gtk_device = Qnil;
752 Vgtk_initial_geometry = Qnil;
753 Vgtk_initial_argv_list = Qnil;
756 #include <gdk/gdkx.h>
758 gtk_device_init_x_specific_cruft (struct device *d)
760 DEVICE_INFD (d) = DEVICE_OUTFD (d) = ConnectionNumber (GDK_DISPLAY ());