Merge with trunk
[emacs.git] / src / xfns.c
blob95404729d72dbb4b7abde905a6fb792ce8ff7afe
1 /* Functions for the X window system.
3 Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
4 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
5 Free Software Foundation, Inc.
7 This file is part of GNU Emacs.
9 GNU Emacs is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 GNU Emacs is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
22 #include <config.h>
23 #include <stdio.h>
24 #include <math.h>
25 #include <setjmp.h>
26 #include <ctype.h>
28 #ifdef HAVE_UNISTD_H
29 #include <unistd.h>
30 #endif
32 /* This makes the fields of a Display accessible, in Xlib header files. */
34 #define XLIB_ILLEGAL_ACCESS
36 #include "lisp.h"
37 #include "xterm.h"
38 #include "frame.h"
39 #include "window.h"
40 #include "buffer.h"
41 #include "intervals.h"
42 #include "dispextern.h"
43 #include "keyboard.h"
44 #include "blockinput.h"
45 #include <epaths.h>
46 #include "character.h"
47 #include "charset.h"
48 #include "coding.h"
49 #include "fontset.h"
50 #include "systime.h"
51 #include "termhooks.h"
52 #include "atimer.h"
53 #include "termchar.h"
54 #include "font.h"
56 #ifdef HAVE_X_WINDOWS
58 #include <ctype.h>
59 #include <sys/types.h>
60 #include <sys/stat.h>
62 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */
63 #include "bitmaps/gray.xbm"
64 #else
65 #include <X11/bitmaps/gray>
66 #endif
68 #include "xsettings.h"
70 #ifdef USE_GTK
71 #include "gtkutil.h"
72 #endif
74 #ifdef USE_X_TOOLKIT
75 #include <X11/Shell.h>
77 #ifndef USE_MOTIF
78 #ifdef HAVE_XAW3D
79 #include <X11/Xaw3d/Paned.h>
80 #include <X11/Xaw3d/Label.h>
81 #else /* !HAVE_XAW3D */
82 #include <X11/Xaw/Paned.h>
83 #include <X11/Xaw/Label.h>
84 #endif /* HAVE_XAW3D */
85 #endif /* USE_MOTIF */
87 #ifdef USG
88 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
89 #include <X11/Xos.h>
90 #define USG
91 #else
92 #include <X11/Xos.h>
93 #endif
95 #include "widget.h"
97 #include "../lwlib/lwlib.h"
99 #ifdef USE_MOTIF
100 #include <Xm/Xm.h>
101 #include <Xm/DialogS.h>
102 #include <Xm/FileSB.h>
103 #include <Xm/List.h>
104 #include <Xm/TextF.h>
105 #endif
107 #ifdef USE_LUCID
108 #include "../lwlib/xlwmenu.h"
109 #endif
111 #if !defined(NO_EDITRES)
112 #define HACK_EDITRES
113 extern void _XEditResCheckMessages ();
114 #endif /* not defined NO_EDITRES */
116 /* Unique id counter for widgets created by the Lucid Widget Library. */
118 extern LWLIB_ID widget_id_tick;
120 extern void free_frame_menubar ();
121 extern double atof ();
123 #ifdef USE_MOTIF
125 /* LessTif/Motif version info. */
127 static Lisp_Object Vmotif_version_string;
129 #endif /* USE_MOTIF */
131 #endif /* USE_X_TOOLKIT */
133 #ifdef USE_GTK
135 /* GTK+ version info */
137 static Lisp_Object Vgtk_version_string;
139 #endif /* USE_GTK */
141 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
143 /* The gray bitmap `bitmaps/gray'. This is done because xterm.c uses
144 it, and including `bitmaps/gray' more than once is a problem when
145 config.h defines `static' as an empty replacement string. */
147 int gray_bitmap_width = gray_width;
148 int gray_bitmap_height = gray_height;
149 char *gray_bitmap_bits = gray_bits;
151 /* Non-zero means prompt with the old GTK file selection dialog. */
153 int x_gtk_use_old_file_dialog;
155 /* If non-zero, by default show hidden files in the GTK file chooser. */
157 int x_gtk_show_hidden_files;
159 /* If non-zero, don't show additional help text in the GTK file chooser. */
161 int x_gtk_file_dialog_help_text;
163 /* If non-zero, don't collapse to tool bar when it is detached. */
165 int x_gtk_whole_detached_tool_bar;
167 /* If non-zero, use Gtk+ tooltips. */
169 static int x_gtk_use_system_tooltips;
171 /* The background and shape of the mouse pointer, and shape when not
172 over text or in the modeline. */
174 Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
175 Lisp_Object Vx_hourglass_pointer_shape;
177 /* The shape when over mouse-sensitive text. */
179 Lisp_Object Vx_sensitive_text_pointer_shape;
181 /* If non-nil, the pointer shape to indicate that windows can be
182 dragged horizontally. */
184 Lisp_Object Vx_window_horizontal_drag_shape;
186 /* Color of chars displayed in cursor box. */
188 Lisp_Object Vx_cursor_fore_pixel;
190 /* Nonzero if using X. */
192 static int x_in_use;
194 /* Non nil if no window manager is in use. */
196 Lisp_Object Vx_no_window_manager;
198 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
200 Lisp_Object Vx_pixel_size_width_font_regexp;
202 Lisp_Object Qnone;
203 Lisp_Object Qsuppress_icon;
204 Lisp_Object Qundefined_color;
205 Lisp_Object Qcompound_text, Qcancel_timer;
206 Lisp_Object Qfont_param;
208 #if GLYPH_DEBUG
209 int image_cache_refcount, dpyinfo_refcount;
210 #endif
212 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
213 char *x_last_font_name;
214 #endif
217 /* Error if we are not connected to X. */
219 void
220 check_x (void)
222 if (! x_in_use)
223 error ("X windows are not in use or not initialized");
226 /* Nonzero if we can use mouse menus.
227 You should not call this unless HAVE_MENUS is defined. */
230 have_menus_p (void)
232 return x_in_use;
235 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
236 and checking validity for X. */
238 FRAME_PTR
239 check_x_frame (Lisp_Object frame)
241 FRAME_PTR f;
243 if (NILP (frame))
244 frame = selected_frame;
245 CHECK_LIVE_FRAME (frame);
246 f = XFRAME (frame);
247 if (! FRAME_X_P (f))
248 error ("Non-X frame used");
249 return f;
252 /* Let the user specify an X display with a Lisp object.
253 OBJECT may be nil, a frame or a terminal object.
254 nil stands for the selected frame--or, if that is not an X frame,
255 the first X display on the list. */
257 struct x_display_info *
258 check_x_display_info (Lisp_Object object)
260 struct x_display_info *dpyinfo = NULL;
262 if (NILP (object))
264 struct frame *sf = XFRAME (selected_frame);
266 if (FRAME_X_P (sf) && FRAME_LIVE_P (sf))
267 dpyinfo = FRAME_X_DISPLAY_INFO (sf);
268 else if (x_display_list != 0)
269 dpyinfo = x_display_list;
270 else
271 error ("X windows are not in use or not initialized");
273 else if (TERMINALP (object))
275 struct terminal *t = get_terminal (object, 1);
277 if (t->type != output_x_window)
278 error ("Terminal %d is not an X display", XINT (object));
280 dpyinfo = t->display_info.x;
282 else if (STRINGP (object))
283 dpyinfo = x_display_info_for_name (object);
284 else
286 FRAME_PTR f = check_x_frame (object);
287 dpyinfo = FRAME_X_DISPLAY_INFO (f);
290 return dpyinfo;
294 /* Return the Emacs frame-object corresponding to an X window.
295 It could be the frame's main window or an icon window. */
297 /* This function can be called during GC, so use GC_xxx type test macros. */
299 struct frame *
300 x_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
302 Lisp_Object tail, frame;
303 struct frame *f;
305 if (wdesc == None) return 0;
307 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
309 frame = XCAR (tail);
310 if (!FRAMEP (frame))
311 continue;
312 f = XFRAME (frame);
313 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
314 continue;
315 if (f->output_data.x->hourglass_window == wdesc)
316 return f;
317 #ifdef USE_X_TOOLKIT
318 if ((f->output_data.x->edit_widget
319 && XtWindow (f->output_data.x->edit_widget) == wdesc)
320 /* A tooltip frame? */
321 || (!f->output_data.x->edit_widget
322 && FRAME_X_WINDOW (f) == wdesc)
323 || f->output_data.x->icon_desc == wdesc)
324 return f;
325 #else /* not USE_X_TOOLKIT */
326 #ifdef USE_GTK
327 if (f->output_data.x->edit_widget)
329 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
330 struct x_output *x = f->output_data.x;
331 if (gwdesc != 0 && gwdesc == x->edit_widget)
332 return f;
334 #endif /* USE_GTK */
335 if (FRAME_X_WINDOW (f) == wdesc
336 || f->output_data.x->icon_desc == wdesc)
337 return f;
338 #endif /* not USE_X_TOOLKIT */
340 return 0;
343 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
344 /* Like x_window_to_frame but also compares the window with the widget's
345 windows. */
347 struct frame *
348 x_any_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
350 Lisp_Object tail, frame;
351 struct frame *f, *found;
352 struct x_output *x;
354 if (wdesc == None) return NULL;
356 found = NULL;
357 for (tail = Vframe_list; CONSP (tail) && !found; tail = XCDR (tail))
359 frame = XCAR (tail);
360 if (!FRAMEP (frame))
361 continue;
363 f = XFRAME (frame);
364 if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) == dpyinfo)
366 /* This frame matches if the window is any of its widgets. */
367 x = f->output_data.x;
368 if (x->hourglass_window == wdesc)
369 found = f;
370 else if (x->widget)
372 #ifdef USE_GTK
373 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
374 if (gwdesc != 0
375 && gtk_widget_get_toplevel (gwdesc) == x->widget)
376 found = f;
377 #else
378 if (wdesc == XtWindow (x->widget)
379 || wdesc == XtWindow (x->column_widget)
380 || wdesc == XtWindow (x->edit_widget))
381 found = f;
382 /* Match if the window is this frame's menubar. */
383 else if (lw_window_is_in_menubar (wdesc, x->menubar_widget))
384 found = f;
385 #endif
387 else if (FRAME_X_WINDOW (f) == wdesc)
388 /* A tooltip frame. */
389 found = f;
393 return found;
396 /* Likewise, but consider only the menu bar widget. */
398 struct frame *
399 x_menubar_window_to_frame (struct x_display_info *dpyinfo, XEvent *event)
401 Window wdesc = event->xany.window;
402 Lisp_Object tail, frame;
403 struct frame *f;
404 struct x_output *x;
406 if (wdesc == None) return 0;
408 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
410 frame = XCAR (tail);
411 if (!FRAMEP (frame))
412 continue;
413 f = XFRAME (frame);
414 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
415 continue;
416 x = f->output_data.x;
417 #ifdef USE_GTK
418 if (x->menubar_widget && xg_event_is_for_menubar (f, event))
419 return f;
420 #else
421 /* Match if the window is this frame's menubar. */
422 if (x->menubar_widget
423 && lw_window_is_in_menubar (wdesc, x->menubar_widget))
424 return f;
425 #endif
427 return 0;
430 /* Return the frame whose principal (outermost) window is WDESC.
431 If WDESC is some other (smaller) window, we return 0. */
433 struct frame *
434 x_top_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
436 Lisp_Object tail, frame;
437 struct frame *f;
438 struct x_output *x;
440 if (wdesc == None) return 0;
442 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
444 frame = XCAR (tail);
445 if (!FRAMEP (frame))
446 continue;
447 f = XFRAME (frame);
448 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
449 continue;
450 x = f->output_data.x;
452 if (x->widget)
454 /* This frame matches if the window is its topmost widget. */
455 #ifdef USE_GTK
456 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
457 if (gwdesc == x->widget)
458 return f;
459 #else
460 if (wdesc == XtWindow (x->widget))
461 return f;
462 #if 0 /* I don't know why it did this,
463 but it seems logically wrong,
464 and it causes trouble for MapNotify events. */
465 /* Match if the window is this frame's menubar. */
466 if (x->menubar_widget
467 && wdesc == XtWindow (x->menubar_widget))
468 return f;
469 #endif
470 #endif
472 else if (FRAME_X_WINDOW (f) == wdesc)
473 /* Tooltip frame. */
474 return f;
476 return 0;
478 #endif /* USE_X_TOOLKIT || USE_GTK */
482 static void x_default_font_parameter (struct frame *, Lisp_Object);
484 static Lisp_Object unwind_create_frame (Lisp_Object);
485 static Lisp_Object unwind_create_tip_frame (Lisp_Object);
487 void x_set_foreground_color (struct frame *, Lisp_Object, Lisp_Object);
488 static void x_set_wait_for_wm (struct frame *, Lisp_Object, Lisp_Object);
489 void x_set_background_color (struct frame *, Lisp_Object, Lisp_Object);
490 void x_set_mouse_color (struct frame *, Lisp_Object, Lisp_Object);
491 void x_set_cursor_color (struct frame *, Lisp_Object, Lisp_Object);
492 void x_set_border_color (struct frame *, Lisp_Object, Lisp_Object);
493 void x_set_cursor_type (struct frame *, Lisp_Object, Lisp_Object);
494 void x_set_icon_type (struct frame *, Lisp_Object, Lisp_Object);
495 void x_set_icon_name (struct frame *, Lisp_Object, Lisp_Object);
496 void x_explicitly_set_name (struct frame *, Lisp_Object, Lisp_Object);
497 void x_set_menu_bar_lines (struct frame *, Lisp_Object, Lisp_Object);
498 void x_set_title (struct frame *, Lisp_Object, Lisp_Object);
499 void x_set_tool_bar_lines (struct frame *, Lisp_Object, Lisp_Object);
500 void x_set_scroll_bar_foreground (struct frame *, Lisp_Object,
501 Lisp_Object);
502 void x_set_scroll_bar_background (struct frame *, Lisp_Object,
503 Lisp_Object);
504 static Lisp_Object x_default_scroll_bar_color_parameter (struct frame *,
505 Lisp_Object,
506 Lisp_Object,
507 const char *, const char *,
508 int);
511 /* Store the screen positions of frame F into XPTR and YPTR.
512 These are the positions of the containing window manager window,
513 not Emacs's own window. */
515 void
516 x_real_positions (FRAME_PTR f, int *xptr, int *yptr)
518 int win_x, win_y, outer_x, outer_y;
519 int real_x = 0, real_y = 0;
520 int had_errors = 0;
521 Window win = f->output_data.x->parent_desc;
523 BLOCK_INPUT;
525 x_catch_errors (FRAME_X_DISPLAY (f));
527 if (win == FRAME_X_DISPLAY_INFO (f)->root_window)
528 win = FRAME_OUTER_WINDOW (f);
530 /* This loop traverses up the containment tree until we hit the root
531 window. Window managers may intersect many windows between our window
532 and the root window. The window we find just before the root window
533 should be the outer WM window. */
534 for (;;)
536 Window wm_window, rootw;
537 Window *tmp_children;
538 unsigned int tmp_nchildren;
539 int success;
541 success = XQueryTree (FRAME_X_DISPLAY (f), win, &rootw,
542 &wm_window, &tmp_children, &tmp_nchildren);
544 had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
546 /* Don't free tmp_children if XQueryTree failed. */
547 if (! success)
548 break;
550 XFree ((char *) tmp_children);
552 if (wm_window == rootw || had_errors)
553 break;
555 win = wm_window;
558 if (! had_errors)
560 unsigned int ign;
561 Window child, rootw;
563 /* Get the real coordinates for the WM window upper left corner */
564 XGetGeometry (FRAME_X_DISPLAY (f), win,
565 &rootw, &real_x, &real_y, &ign, &ign, &ign, &ign);
567 /* Translate real coordinates to coordinates relative to our
568 window. For our window, the upper left corner is 0, 0.
569 Since the upper left corner of the WM window is outside
570 our window, win_x and win_y will be negative:
572 ------------------ ---> x
573 | title |
574 | ----------------- v y
575 | | our window
577 XTranslateCoordinates (FRAME_X_DISPLAY (f),
579 /* From-window, to-window. */
580 FRAME_X_DISPLAY_INFO (f)->root_window,
581 FRAME_X_WINDOW (f),
583 /* From-position, to-position. */
584 real_x, real_y, &win_x, &win_y,
586 /* Child of win. */
587 &child);
589 if (FRAME_X_WINDOW (f) == FRAME_OUTER_WINDOW (f))
591 outer_x = win_x;
592 outer_y = win_y;
594 else
596 XTranslateCoordinates (FRAME_X_DISPLAY (f),
598 /* From-window, to-window. */
599 FRAME_X_DISPLAY_INFO (f)->root_window,
600 FRAME_OUTER_WINDOW (f),
602 /* From-position, to-position. */
603 real_x, real_y, &outer_x, &outer_y,
605 /* Child of win. */
606 &child);
609 had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
612 x_uncatch_errors ();
614 UNBLOCK_INPUT;
616 if (had_errors) return;
618 f->x_pixels_diff = -win_x;
619 f->y_pixels_diff = -win_y;
621 FRAME_X_OUTPUT (f)->x_pixels_outer_diff = -outer_x;
622 FRAME_X_OUTPUT (f)->y_pixels_outer_diff = -outer_y;
624 *xptr = real_x;
625 *yptr = real_y;
631 /* Gamma-correct COLOR on frame F. */
633 void
634 gamma_correct (struct frame *f, XColor *color)
636 if (f->gamma)
638 color->red = pow (color->red / 65535.0, f->gamma) * 65535.0 + 0.5;
639 color->green = pow (color->green / 65535.0, f->gamma) * 65535.0 + 0.5;
640 color->blue = pow (color->blue / 65535.0, f->gamma) * 65535.0 + 0.5;
645 /* Decide if color named COLOR_NAME is valid for use on frame F. If
646 so, return the RGB values in COLOR. If ALLOC_P is non-zero,
647 allocate the color. Value is zero if COLOR_NAME is invalid, or
648 no color could be allocated. */
651 x_defined_color (struct frame *f, const char *color_name,
652 XColor *color, int alloc_p)
654 int success_p = 0;
655 Display *dpy = FRAME_X_DISPLAY (f);
656 Colormap cmap = FRAME_X_COLORMAP (f);
658 BLOCK_INPUT;
659 #ifdef USE_GTK
660 success_p = xg_check_special_colors (f, color_name, color);
661 #endif
662 if (!success_p)
663 success_p = XParseColor (dpy, cmap, color_name, color);
664 if (success_p && alloc_p)
665 success_p = x_alloc_nearest_color (f, cmap, color);
666 UNBLOCK_INPUT;
668 return success_p;
672 /* Return the pixel color value for color COLOR_NAME on frame F. If F
673 is a monochrome frame, return MONO_COLOR regardless of what ARG says.
674 Signal an error if color can't be allocated. */
677 x_decode_color (FRAME_PTR f, Lisp_Object color_name, int mono_color)
679 XColor cdef;
681 CHECK_STRING (color_name);
683 #if 0 /* Don't do this. It's wrong when we're not using the default
684 colormap, it makes freeing difficult, and it's probably not
685 an important optimization. */
686 if (strcmp (SDATA (color_name), "black") == 0)
687 return BLACK_PIX_DEFAULT (f);
688 else if (strcmp (SDATA (color_name), "white") == 0)
689 return WHITE_PIX_DEFAULT (f);
690 #endif
692 /* Return MONO_COLOR for monochrome frames. */
693 if (FRAME_X_DISPLAY_INFO (f)->n_planes == 1)
694 return mono_color;
696 /* x_defined_color is responsible for coping with failures
697 by looking for a near-miss. */
698 if (x_defined_color (f, SDATA (color_name), &cdef, 1))
699 return cdef.pixel;
701 signal_error ("Undefined color", color_name);
706 /* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
707 the previous value of that parameter, NEW_VALUE is the new value.
708 See also the comment of wait_for_wm in struct x_output. */
710 static void
711 x_set_wait_for_wm (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
713 f->output_data.x->wait_for_wm = !NILP (new_value);
716 static void
717 x_set_tool_bar_position (struct frame *f,
718 Lisp_Object new_value,
719 Lisp_Object old_value)
721 if (! EQ (new_value, Qleft) && ! EQ (new_value, Qright)
722 && ! EQ (new_value, Qbottom) && ! EQ (new_value, Qtop))
723 return;
724 if (EQ (new_value, old_value)) return;
726 #ifdef USE_GTK
727 if (xg_change_toolbar_position (f, new_value))
728 f->tool_bar_position = new_value;
729 #endif
732 #ifdef USE_GTK
734 /* Set icon from FILE for frame F. By using GTK functions the icon
735 may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
738 xg_set_icon (FRAME_PTR f, Lisp_Object file)
740 int result = 0;
741 Lisp_Object found;
743 found = x_find_image_file (file);
745 if (! NILP (found))
747 GdkPixbuf *pixbuf;
748 GError *err = NULL;
749 char *filename = (char *) SDATA (found);
750 BLOCK_INPUT;
752 pixbuf = gdk_pixbuf_new_from_file (filename, &err);
754 if (pixbuf)
756 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
757 pixbuf);
758 g_object_unref (pixbuf);
760 result = 1;
762 else
763 g_error_free (err);
765 UNBLOCK_INPUT;
768 return result;
772 xg_set_icon_from_xpm_data (FRAME_PTR f, const char **data)
774 int result = 0;
775 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data (data);
777 if (!pixbuf)
778 return 0;
780 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), pixbuf);
781 g_object_unref (pixbuf);
782 return 1;
784 #endif /* USE_GTK */
787 /* Functions called only from `x_set_frame_param'
788 to set individual parameters.
790 If FRAME_X_WINDOW (f) is 0,
791 the frame is being created and its X-window does not exist yet.
792 In that case, just record the parameter's new value
793 in the standard place; do not attempt to change the window. */
795 void
796 x_set_foreground_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
798 struct x_output *x = f->output_data.x;
799 unsigned long fg, old_fg;
801 fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
802 old_fg = FRAME_FOREGROUND_PIXEL (f);
803 FRAME_FOREGROUND_PIXEL (f) = fg;
805 if (FRAME_X_WINDOW (f) != 0)
807 Display *dpy = FRAME_X_DISPLAY (f);
809 BLOCK_INPUT;
810 XSetForeground (dpy, x->normal_gc, fg);
811 XSetBackground (dpy, x->reverse_gc, fg);
813 if (x->cursor_pixel == old_fg)
815 unload_color (f, x->cursor_pixel);
816 x->cursor_pixel = x_copy_color (f, fg);
817 XSetBackground (dpy, x->cursor_gc, x->cursor_pixel);
820 UNBLOCK_INPUT;
822 update_face_from_frame_parameter (f, Qforeground_color, arg);
824 if (FRAME_VISIBLE_P (f))
825 redraw_frame (f);
828 unload_color (f, old_fg);
831 void
832 x_set_background_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
834 struct x_output *x = f->output_data.x;
835 unsigned long bg;
837 bg = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
838 unload_color (f, FRAME_BACKGROUND_PIXEL (f));
839 FRAME_BACKGROUND_PIXEL (f) = bg;
841 if (FRAME_X_WINDOW (f) != 0)
843 Display *dpy = FRAME_X_DISPLAY (f);
845 BLOCK_INPUT;
846 XSetBackground (dpy, x->normal_gc, bg);
847 XSetForeground (dpy, x->reverse_gc, bg);
848 XSetWindowBackground (dpy, FRAME_X_WINDOW (f), bg);
849 XSetForeground (dpy, x->cursor_gc, bg);
851 #ifdef USE_GTK
852 xg_set_background_color (f, bg);
853 #endif
855 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
856 toolkit scroll bars. */
858 Lisp_Object bar;
859 for (bar = FRAME_SCROLL_BARS (f);
860 !NILP (bar);
861 bar = XSCROLL_BAR (bar)->next)
863 Window window = XSCROLL_BAR (bar)->x_window;
864 XSetWindowBackground (dpy, window, bg);
867 #endif /* USE_TOOLKIT_SCROLL_BARS */
869 UNBLOCK_INPUT;
870 update_face_from_frame_parameter (f, Qbackground_color, arg);
872 if (FRAME_VISIBLE_P (f))
873 redraw_frame (f);
877 static Cursor
878 make_invisible_cursor (struct frame *f)
880 Display *dpy = FRAME_X_DISPLAY (f);
881 static char const no_data[] = { 0 };
882 Pixmap pix;
883 XColor col;
884 Cursor c;
886 x_catch_errors (dpy);
887 pix = XCreateBitmapFromData (dpy, FRAME_X_DISPLAY_INFO (f)->root_window,
888 no_data, 1, 1);
889 if (! x_had_errors_p (dpy) && pix != None)
891 col.pixel = 0;
892 col.red = col.green = col.blue = 0;
893 col.flags = DoRed | DoGreen | DoBlue;
894 c = XCreatePixmapCursor (dpy, pix, pix, &col, &col, 0, 0);
895 if (x_had_errors_p (dpy) || c == None)
896 c = 0;
897 XFreePixmap (dpy, pix);
900 x_uncatch_errors ();
902 return c;
905 void
906 x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
908 struct x_output *x = f->output_data.x;
909 Display *dpy = FRAME_X_DISPLAY (f);
910 Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
911 Cursor hourglass_cursor, horizontal_drag_cursor;
912 unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
913 unsigned long mask_color = FRAME_BACKGROUND_PIXEL (f);
915 /* Don't let pointers be invisible. */
916 if (mask_color == pixel)
918 x_free_colors (f, &pixel, 1);
919 pixel = x_copy_color (f, FRAME_FOREGROUND_PIXEL (f));
922 unload_color (f, x->mouse_pixel);
923 x->mouse_pixel = pixel;
925 BLOCK_INPUT;
927 /* It's not okay to crash if the user selects a screwy cursor. */
928 x_catch_errors (dpy);
930 if (!NILP (Vx_pointer_shape))
932 CHECK_NUMBER (Vx_pointer_shape);
933 cursor = XCreateFontCursor (dpy, XINT (Vx_pointer_shape));
935 else
936 cursor = XCreateFontCursor (dpy, XC_xterm);
937 x_check_errors (dpy, "bad text pointer cursor: %s");
939 if (!NILP (Vx_nontext_pointer_shape))
941 CHECK_NUMBER (Vx_nontext_pointer_shape);
942 nontext_cursor
943 = XCreateFontCursor (dpy, XINT (Vx_nontext_pointer_shape));
945 else
946 nontext_cursor = XCreateFontCursor (dpy, XC_left_ptr);
947 x_check_errors (dpy, "bad nontext pointer cursor: %s");
949 if (!NILP (Vx_hourglass_pointer_shape))
951 CHECK_NUMBER (Vx_hourglass_pointer_shape);
952 hourglass_cursor
953 = XCreateFontCursor (dpy, XINT (Vx_hourglass_pointer_shape));
955 else
956 hourglass_cursor = XCreateFontCursor (dpy, XC_watch);
957 x_check_errors (dpy, "bad hourglass pointer cursor: %s");
959 if (!NILP (Vx_mode_pointer_shape))
961 CHECK_NUMBER (Vx_mode_pointer_shape);
962 mode_cursor = XCreateFontCursor (dpy, XINT (Vx_mode_pointer_shape));
964 else
965 mode_cursor = XCreateFontCursor (dpy, XC_xterm);
966 x_check_errors (dpy, "bad modeline pointer cursor: %s");
968 if (!NILP (Vx_sensitive_text_pointer_shape))
970 CHECK_NUMBER (Vx_sensitive_text_pointer_shape);
971 hand_cursor
972 = XCreateFontCursor (dpy, XINT (Vx_sensitive_text_pointer_shape));
974 else
975 hand_cursor = XCreateFontCursor (dpy, XC_hand2);
977 if (!NILP (Vx_window_horizontal_drag_shape))
979 CHECK_NUMBER (Vx_window_horizontal_drag_shape);
980 horizontal_drag_cursor
981 = XCreateFontCursor (dpy, XINT (Vx_window_horizontal_drag_shape));
983 else
984 horizontal_drag_cursor
985 = XCreateFontCursor (dpy, XC_sb_h_double_arrow);
987 /* Check and report errors with the above calls. */
988 x_check_errors (dpy, "can't set cursor shape: %s");
989 x_uncatch_errors ();
992 XColor fore_color, back_color;
994 fore_color.pixel = x->mouse_pixel;
995 x_query_color (f, &fore_color);
996 back_color.pixel = mask_color;
997 x_query_color (f, &back_color);
999 XRecolorCursor (dpy, cursor, &fore_color, &back_color);
1000 XRecolorCursor (dpy, nontext_cursor, &fore_color, &back_color);
1001 XRecolorCursor (dpy, mode_cursor, &fore_color, &back_color);
1002 XRecolorCursor (dpy, hand_cursor, &fore_color, &back_color);
1003 XRecolorCursor (dpy, hourglass_cursor, &fore_color, &back_color);
1004 XRecolorCursor (dpy, horizontal_drag_cursor, &fore_color, &back_color);
1007 if (FRAME_X_WINDOW (f) != 0)
1008 XDefineCursor (dpy, FRAME_X_WINDOW (f),
1009 f->output_data.x->current_cursor = cursor);
1011 if (FRAME_X_DISPLAY_INFO (f)->invisible_cursor == 0)
1012 FRAME_X_DISPLAY_INFO (f)->invisible_cursor = make_invisible_cursor (f);
1014 if (cursor != x->text_cursor
1015 && x->text_cursor != 0)
1016 XFreeCursor (dpy, x->text_cursor);
1017 x->text_cursor = cursor;
1019 if (nontext_cursor != x->nontext_cursor
1020 && x->nontext_cursor != 0)
1021 XFreeCursor (dpy, x->nontext_cursor);
1022 x->nontext_cursor = nontext_cursor;
1024 if (hourglass_cursor != x->hourglass_cursor
1025 && x->hourglass_cursor != 0)
1026 XFreeCursor (dpy, x->hourglass_cursor);
1027 x->hourglass_cursor = hourglass_cursor;
1029 if (mode_cursor != x->modeline_cursor
1030 && x->modeline_cursor != 0)
1031 XFreeCursor (dpy, f->output_data.x->modeline_cursor);
1032 x->modeline_cursor = mode_cursor;
1034 if (hand_cursor != x->hand_cursor
1035 && x->hand_cursor != 0)
1036 XFreeCursor (dpy, x->hand_cursor);
1037 x->hand_cursor = hand_cursor;
1039 if (horizontal_drag_cursor != x->horizontal_drag_cursor
1040 && x->horizontal_drag_cursor != 0)
1041 XFreeCursor (dpy, x->horizontal_drag_cursor);
1042 x->horizontal_drag_cursor = horizontal_drag_cursor;
1044 XFlush (dpy);
1045 UNBLOCK_INPUT;
1047 update_face_from_frame_parameter (f, Qmouse_color, arg);
1050 void
1051 x_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1053 unsigned long fore_pixel, pixel;
1054 int fore_pixel_allocated_p = 0, pixel_allocated_p = 0;
1055 struct x_output *x = f->output_data.x;
1057 if (!NILP (Vx_cursor_fore_pixel))
1059 fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
1060 WHITE_PIX_DEFAULT (f));
1061 fore_pixel_allocated_p = 1;
1063 else
1064 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1066 pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1067 pixel_allocated_p = 1;
1069 /* Make sure that the cursor color differs from the background color. */
1070 if (pixel == FRAME_BACKGROUND_PIXEL (f))
1072 if (pixel_allocated_p)
1074 x_free_colors (f, &pixel, 1);
1075 pixel_allocated_p = 0;
1078 pixel = x->mouse_pixel;
1079 if (pixel == fore_pixel)
1081 if (fore_pixel_allocated_p)
1083 x_free_colors (f, &fore_pixel, 1);
1084 fore_pixel_allocated_p = 0;
1086 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1090 unload_color (f, x->cursor_foreground_pixel);
1091 if (!fore_pixel_allocated_p)
1092 fore_pixel = x_copy_color (f, fore_pixel);
1093 x->cursor_foreground_pixel = fore_pixel;
1095 unload_color (f, x->cursor_pixel);
1096 if (!pixel_allocated_p)
1097 pixel = x_copy_color (f, pixel);
1098 x->cursor_pixel = pixel;
1100 if (FRAME_X_WINDOW (f) != 0)
1102 BLOCK_INPUT;
1103 XSetBackground (FRAME_X_DISPLAY (f), x->cursor_gc, x->cursor_pixel);
1104 XSetForeground (FRAME_X_DISPLAY (f), x->cursor_gc, fore_pixel);
1105 UNBLOCK_INPUT;
1107 if (FRAME_VISIBLE_P (f))
1109 x_update_cursor (f, 0);
1110 x_update_cursor (f, 1);
1114 update_face_from_frame_parameter (f, Qcursor_color, arg);
1117 /* Set the border-color of frame F to pixel value PIX.
1118 Note that this does not fully take effect if done before
1119 F has an x-window. */
1121 void
1122 x_set_border_pixel (struct frame *f, int pix)
1124 unload_color (f, f->output_data.x->border_pixel);
1125 f->output_data.x->border_pixel = pix;
1127 if (FRAME_X_WINDOW (f) != 0 && f->border_width > 0)
1129 BLOCK_INPUT;
1130 XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1131 (unsigned long)pix);
1132 UNBLOCK_INPUT;
1134 if (FRAME_VISIBLE_P (f))
1135 redraw_frame (f);
1139 /* Set the border-color of frame F to value described by ARG.
1140 ARG can be a string naming a color.
1141 The border-color is used for the border that is drawn by the X server.
1142 Note that this does not fully take effect if done before
1143 F has an x-window; it must be redone when the window is created.
1145 Note: this is done in two routines because of the way X10 works.
1147 Note: under X11, this is normally the province of the window manager,
1148 and so emacs' border colors may be overridden. */
1150 void
1151 x_set_border_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1153 int pix;
1155 CHECK_STRING (arg);
1156 pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1157 x_set_border_pixel (f, pix);
1158 update_face_from_frame_parameter (f, Qborder_color, arg);
1162 void
1163 x_set_cursor_type (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
1165 set_frame_cursor_types (f, arg);
1167 /* Make sure the cursor gets redrawn. */
1168 cursor_type_changed = 1;
1171 void
1172 x_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1174 int result;
1176 if (STRINGP (arg))
1178 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1179 return;
1181 else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
1182 return;
1184 BLOCK_INPUT;
1185 if (NILP (arg))
1186 result = x_text_icon (f,
1187 (char *) SDATA ((!NILP (f->icon_name)
1188 ? f->icon_name
1189 : f->name)));
1190 else
1191 result = x_bitmap_icon (f, arg);
1193 if (result)
1195 UNBLOCK_INPUT;
1196 error ("No icon window available");
1199 XFlush (FRAME_X_DISPLAY (f));
1200 UNBLOCK_INPUT;
1203 void
1204 x_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1206 int result;
1208 if (STRINGP (arg))
1210 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1211 return;
1213 else if (!NILP (arg) || NILP (oldval))
1214 return;
1216 f->icon_name = arg;
1218 if (f->output_data.x->icon_bitmap != 0)
1219 return;
1221 BLOCK_INPUT;
1223 result = x_text_icon (f,
1224 (char *) SDATA ((!NILP (f->icon_name)
1225 ? f->icon_name
1226 : !NILP (f->title)
1227 ? f->title
1228 : f->name)));
1230 if (result)
1232 UNBLOCK_INPUT;
1233 error ("No icon window available");
1236 XFlush (FRAME_X_DISPLAY (f));
1237 UNBLOCK_INPUT;
1241 void
1242 x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1244 int nlines;
1245 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
1246 int olines = FRAME_MENU_BAR_LINES (f);
1247 #endif
1249 /* Right now, menu bars don't work properly in minibuf-only frames;
1250 most of the commands try to apply themselves to the minibuffer
1251 frame itself, and get an error because you can't switch buffers
1252 in or split the minibuffer window. */
1253 if (FRAME_MINIBUF_ONLY_P (f))
1254 return;
1256 if (INTEGERP (value))
1257 nlines = XINT (value);
1258 else
1259 nlines = 0;
1261 /* Make sure we redisplay all windows in this frame. */
1262 windows_or_buffers_changed++;
1264 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1265 FRAME_MENU_BAR_LINES (f) = 0;
1266 if (nlines)
1268 FRAME_EXTERNAL_MENU_BAR (f) = 1;
1269 if (FRAME_X_P (f) && f->output_data.x->menubar_widget == 0)
1270 /* Make sure next redisplay shows the menu bar. */
1271 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
1273 else
1275 if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
1276 free_frame_menubar (f);
1277 FRAME_EXTERNAL_MENU_BAR (f) = 0;
1278 if (FRAME_X_P (f))
1279 f->output_data.x->menubar_widget = 0;
1281 #else /* not USE_X_TOOLKIT && not USE_GTK */
1282 FRAME_MENU_BAR_LINES (f) = nlines;
1283 resize_frame_windows (f, FRAME_LINES (f), 0);
1285 /* If the menu bar height gets changed, the internal border below
1286 the top margin has to be cleared. Also, if the menu bar gets
1287 larger, the area for the added lines has to be cleared except for
1288 the first menu bar line that is to be drawn later. */
1289 if (nlines != olines)
1291 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1292 int width = FRAME_PIXEL_WIDTH (f);
1293 int y;
1295 /* height can be zero here. */
1296 if (height > 0 && width > 0)
1298 y = FRAME_TOP_MARGIN_HEIGHT (f);
1300 BLOCK_INPUT;
1301 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1302 0, y, width, height, False);
1303 UNBLOCK_INPUT;
1306 if (nlines > 1 && nlines > olines)
1308 y = (olines == 0 ? 1 : olines) * FRAME_LINE_HEIGHT (f);
1309 height = nlines * FRAME_LINE_HEIGHT (f) - y;
1311 BLOCK_INPUT;
1312 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1313 0, y, width, height, False);
1314 UNBLOCK_INPUT;
1317 if (nlines == 0 && WINDOWP (f->menu_bar_window))
1318 clear_glyph_matrix (XWINDOW (f->menu_bar_window)->current_matrix);
1320 #endif /* not USE_X_TOOLKIT && not USE_GTK */
1321 adjust_glyphs (f);
1322 run_window_configuration_change_hook (f);
1326 /* Set the number of lines used for the tool bar of frame F to VALUE.
1327 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1328 is the old number of tool bar lines. This function changes the
1329 height of all windows on frame F to match the new tool bar height.
1330 The frame's height doesn't change. */
1332 void
1333 x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1335 int delta, nlines, root_height;
1336 Lisp_Object root_window;
1338 /* Treat tool bars like menu bars. */
1339 if (FRAME_MINIBUF_ONLY_P (f))
1340 return;
1342 /* Use VALUE only if an integer >= 0. */
1343 if (INTEGERP (value) && XINT (value) >= 0)
1344 nlines = XFASTINT (value);
1345 else
1346 nlines = 0;
1348 #ifdef USE_GTK
1349 FRAME_TOOL_BAR_LINES (f) = 0;
1350 if (nlines)
1352 FRAME_EXTERNAL_TOOL_BAR (f) = 1;
1353 if (FRAME_X_P (f) && f->output_data.x->toolbar_widget == 0)
1354 /* Make sure next redisplay shows the tool bar. */
1355 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
1356 update_frame_tool_bar (f);
1358 else
1360 if (FRAME_EXTERNAL_TOOL_BAR (f))
1361 free_frame_tool_bar (f);
1362 FRAME_EXTERNAL_TOOL_BAR (f) = 0;
1365 return;
1366 #endif
1368 /* Make sure we redisplay all windows in this frame. */
1369 ++windows_or_buffers_changed;
1371 delta = nlines - FRAME_TOOL_BAR_LINES (f);
1373 /* Don't resize the tool-bar to more than we have room for. */
1374 root_window = FRAME_ROOT_WINDOW (f);
1375 root_height = WINDOW_TOTAL_LINES (XWINDOW (root_window));
1376 if (root_height - delta < 1)
1378 delta = root_height - 1;
1379 nlines = FRAME_TOOL_BAR_LINES (f) + delta;
1382 FRAME_TOOL_BAR_LINES (f) = nlines;
1383 resize_frame_windows (f, FRAME_LINES (f), 0);
1384 adjust_glyphs (f);
1386 /* We also have to make sure that the internal border at the top of
1387 the frame, below the menu bar or tool bar, is redrawn when the
1388 tool bar disappears. This is so because the internal border is
1389 below the tool bar if one is displayed, but is below the menu bar
1390 if there isn't a tool bar. The tool bar draws into the area
1391 below the menu bar. */
1392 if (FRAME_X_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0)
1394 clear_frame (f);
1395 clear_current_matrices (f);
1398 /* If the tool bar gets smaller, the internal border below it
1399 has to be cleared. It was formerly part of the display
1400 of the larger tool bar, and updating windows won't clear it. */
1401 if (delta < 0)
1403 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1404 int width = FRAME_PIXEL_WIDTH (f);
1405 int y = (FRAME_MENU_BAR_LINES (f) + nlines) * FRAME_LINE_HEIGHT (f);
1407 /* height can be zero here. */
1408 if (height > 0 && width > 0)
1410 BLOCK_INPUT;
1411 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1412 0, y, width, height, False);
1413 UNBLOCK_INPUT;
1416 if (WINDOWP (f->tool_bar_window))
1417 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1420 run_window_configuration_change_hook (f);
1425 /* Set the foreground color for scroll bars on frame F to VALUE.
1426 VALUE should be a string, a color name. If it isn't a string or
1427 isn't a valid color name, do nothing. OLDVAL is the old value of
1428 the frame parameter. */
1430 void
1431 x_set_scroll_bar_foreground (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1433 unsigned long pixel;
1435 if (STRINGP (value))
1436 pixel = x_decode_color (f, value, BLACK_PIX_DEFAULT (f));
1437 else
1438 pixel = -1;
1440 if (f->output_data.x->scroll_bar_foreground_pixel != -1)
1441 unload_color (f, f->output_data.x->scroll_bar_foreground_pixel);
1443 f->output_data.x->scroll_bar_foreground_pixel = pixel;
1444 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1446 /* Remove all scroll bars because they have wrong colors. */
1447 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1448 (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1449 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1450 (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1452 update_face_from_frame_parameter (f, Qscroll_bar_foreground, value);
1453 redraw_frame (f);
1458 /* Set the background color for scroll bars on frame F to VALUE VALUE
1459 should be a string, a color name. If it isn't a string or isn't a
1460 valid color name, do nothing. OLDVAL is the old value of the frame
1461 parameter. */
1463 void
1464 x_set_scroll_bar_background (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1466 unsigned long pixel;
1468 if (STRINGP (value))
1469 pixel = x_decode_color (f, value, WHITE_PIX_DEFAULT (f));
1470 else
1471 pixel = -1;
1473 if (f->output_data.x->scroll_bar_background_pixel != -1)
1474 unload_color (f, f->output_data.x->scroll_bar_background_pixel);
1476 #ifdef USE_TOOLKIT_SCROLL_BARS
1477 /* Scrollbar shadow colors. */
1478 if (f->output_data.x->scroll_bar_top_shadow_pixel != -1)
1480 unload_color (f, f->output_data.x->scroll_bar_top_shadow_pixel);
1481 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
1483 if (f->output_data.x->scroll_bar_bottom_shadow_pixel != -1)
1485 unload_color (f, f->output_data.x->scroll_bar_bottom_shadow_pixel);
1486 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
1488 #endif /* USE_TOOLKIT_SCROLL_BARS */
1490 f->output_data.x->scroll_bar_background_pixel = pixel;
1491 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1493 /* Remove all scroll bars because they have wrong colors. */
1494 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1495 (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1496 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1497 (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1499 update_face_from_frame_parameter (f, Qscroll_bar_background, value);
1500 redraw_frame (f);
1505 /* Encode Lisp string STRING as a text in a format appropriate for
1506 XICCC (X Inter Client Communication Conventions).
1508 This can call Lisp code, so callers must GCPRO.
1510 If STRING contains only ASCII characters, do no conversion and
1511 return the string data of STRING. Otherwise, encode the text by
1512 CODING_SYSTEM, and return a newly allocated memory area which
1513 should be freed by `xfree' by a caller.
1515 SELECTIONP non-zero means the string is being encoded for an X
1516 selection, so it is safe to run pre-write conversions (which
1517 may run Lisp code).
1519 Store the byte length of resulting text in *TEXT_BYTES.
1521 If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
1522 which means that the `encoding' of the result can be `STRING'.
1523 Otherwise store 0 in *STRINGP, which means that the `encoding' of
1524 the result should be `COMPOUND_TEXT'. */
1526 static unsigned char *
1527 x_encode_text (Lisp_Object string, Lisp_Object coding_system, int selectionp, int *text_bytes, int *stringp, int *freep)
1529 int result = string_xstring_p (string);
1530 struct coding_system coding;
1532 if (result == 0)
1534 /* No multibyte character in OBJ. We need not encode it. */
1535 *text_bytes = SBYTES (string);
1536 *stringp = 1;
1537 *freep = 0;
1538 return SDATA (string);
1541 setup_coding_system (coding_system, &coding);
1542 coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK);
1543 /* We suppress producing escape sequences for composition. */
1544 coding.common_flags &= ~CODING_ANNOTATION_MASK;
1545 coding.dst_bytes = SCHARS (string) * 2;
1546 coding.destination = (unsigned char *) xmalloc (coding.dst_bytes);
1547 encode_coding_object (&coding, string, 0, 0,
1548 SCHARS (string), SBYTES (string), Qnil);
1549 *text_bytes = coding.produced;
1550 *stringp = (result == 1 || !EQ (coding_system, Qcompound_text));
1551 *freep = 1;
1552 return coding.destination;
1556 /* Set the WM name to NAME for frame F. Also set the icon name.
1557 If the frame already has an icon name, use that, otherwise set the
1558 icon name to NAME. */
1560 static void
1561 x_set_name_internal (FRAME_PTR f, Lisp_Object name)
1563 if (FRAME_X_WINDOW (f))
1565 BLOCK_INPUT;
1567 XTextProperty text, icon;
1568 int bytes, stringp;
1569 int do_free_icon_value = 0, do_free_text_value = 0;
1570 Lisp_Object coding_system;
1571 Lisp_Object encoded_name;
1572 Lisp_Object encoded_icon_name;
1573 struct gcpro gcpro1;
1575 /* As ENCODE_UTF_8 may cause GC and relocation of string data,
1576 we use it before x_encode_text that may return string data. */
1577 GCPRO1 (name);
1578 encoded_name = ENCODE_UTF_8 (name);
1579 UNGCPRO;
1581 coding_system = Qcompound_text;
1582 /* Note: Encoding strategy
1584 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1585 text.encoding. But, there are non-internationalized window
1586 managers which don't support that encoding. So, if NAME
1587 contains only ASCII and 8859-1 characters, encode it by
1588 iso-latin-1, and use "STRING" in text.encoding hoping that
1589 such window managers at least analyze this format correctly,
1590 i.e. treat 8-bit bytes as 8859-1 characters.
1592 We may also be able to use "UTF8_STRING" in text.encoding
1593 in the future which can encode all Unicode characters.
1594 But, for the moment, there's no way to know that the
1595 current window manager supports it or not.
1597 Either way, we also set the _NET_WM_NAME and _NET_WM_ICON_NAME
1598 properties. Per the EWMH specification, those two properties
1599 are always UTF8_STRING. This matches what gtk_window_set_title()
1600 does in the USE_GTK case. */
1601 text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp,
1602 &do_free_text_value);
1603 text.encoding = (stringp ? XA_STRING
1604 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1605 text.format = 8;
1606 text.nitems = bytes;
1608 if (!STRINGP (f->icon_name))
1610 icon = text;
1611 encoded_icon_name = encoded_name;
1613 else
1615 /* See the above comment "Note: Encoding strategy". */
1616 icon.value = x_encode_text (f->icon_name, coding_system, 0,
1617 &bytes, &stringp, &do_free_icon_value);
1618 icon.encoding = (stringp ? XA_STRING
1619 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1620 icon.format = 8;
1621 icon.nitems = bytes;
1623 encoded_icon_name = ENCODE_UTF_8 (f->icon_name);
1626 #ifdef USE_GTK
1627 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
1628 (char *) SDATA (encoded_name));
1629 #else /* not USE_GTK */
1630 XSetWMName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &text);
1631 XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
1632 FRAME_X_DISPLAY_INFO (f)->Xatom_net_wm_name,
1633 FRAME_X_DISPLAY_INFO (f)->Xatom_UTF8_STRING,
1634 8, PropModeReplace,
1635 (char *) SDATA (encoded_name),
1636 SBYTES (encoded_name));
1637 #endif /* not USE_GTK */
1639 XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &icon);
1640 XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
1641 FRAME_X_DISPLAY_INFO (f)->Xatom_net_wm_icon_name,
1642 FRAME_X_DISPLAY_INFO (f)->Xatom_UTF8_STRING,
1643 8, PropModeReplace,
1644 (char *) SDATA (encoded_icon_name),
1645 SBYTES (encoded_icon_name));
1647 if (do_free_icon_value)
1648 xfree (icon.value);
1649 if (do_free_text_value)
1650 xfree (text.value);
1652 UNBLOCK_INPUT;
1656 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1657 x_id_name.
1659 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1660 name; if NAME is a string, set F's name to NAME and set
1661 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1663 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1664 suggesting a new name, which lisp code should override; if
1665 F->explicit_name is set, ignore the new name; otherwise, set it. */
1667 void
1668 x_set_name (struct frame *f, Lisp_Object name, int explicit)
1670 /* Make sure that requests from lisp code override requests from
1671 Emacs redisplay code. */
1672 if (explicit)
1674 /* If we're switching from explicit to implicit, we had better
1675 update the mode lines and thereby update the title. */
1676 if (f->explicit_name && NILP (name))
1677 update_mode_lines = 1;
1679 f->explicit_name = ! NILP (name);
1681 else if (f->explicit_name)
1682 return;
1684 /* If NAME is nil, set the name to the x_id_name. */
1685 if (NILP (name))
1687 /* Check for no change needed in this very common case
1688 before we do any consing. */
1689 if (!strcmp (FRAME_X_DISPLAY_INFO (f)->x_id_name,
1690 SDATA (f->name)))
1691 return;
1692 name = build_string (FRAME_X_DISPLAY_INFO (f)->x_id_name);
1694 else
1695 CHECK_STRING (name);
1697 /* Don't change the name if it's already NAME. */
1698 if (! NILP (Fstring_equal (name, f->name)))
1699 return;
1701 f->name = name;
1703 /* For setting the frame title, the title parameter should override
1704 the name parameter. */
1705 if (! NILP (f->title))
1706 name = f->title;
1708 x_set_name_internal (f, name);
1711 /* This function should be called when the user's lisp code has
1712 specified a name for the frame; the name will override any set by the
1713 redisplay code. */
1714 void
1715 x_explicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
1717 x_set_name (f, arg, 1);
1720 /* This function should be called by Emacs redisplay code to set the
1721 name; names set this way will never override names set by the user's
1722 lisp code. */
1723 void
1724 x_implicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
1726 x_set_name (f, arg, 0);
1729 /* Change the title of frame F to NAME.
1730 If NAME is nil, use the frame name as the title. */
1732 void
1733 x_set_title (struct frame *f, Lisp_Object name, Lisp_Object old_name)
1735 /* Don't change the title if it's already NAME. */
1736 if (EQ (name, f->title))
1737 return;
1739 update_mode_lines = 1;
1741 f->title = name;
1743 if (NILP (name))
1744 name = f->name;
1745 else
1746 CHECK_STRING (name);
1748 x_set_name_internal (f, name);
1751 void
1752 x_set_scroll_bar_default_width (struct frame *f)
1754 int wid = FRAME_COLUMN_WIDTH (f);
1756 #ifdef USE_TOOLKIT_SCROLL_BARS
1757 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
1758 int width = 16 + 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM;
1759 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (width + wid - 1) / wid;
1760 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = width;
1761 #else
1762 /* Make the actual width at least 14 pixels and a multiple of a
1763 character width. */
1764 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
1766 /* Use all of that space (aside from required margins) for the
1767 scroll bar. */
1768 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 0;
1769 #endif
1773 /* Record in frame F the specified or default value according to ALIST
1774 of the parameter named PROP (a Lisp symbol). If no value is
1775 specified for PROP, look for an X default for XPROP on the frame
1776 named NAME. If that is not found either, use the value DEFLT. */
1778 static Lisp_Object
1779 x_default_scroll_bar_color_parameter (struct frame *f,
1780 Lisp_Object alist, Lisp_Object prop,
1781 const char *xprop, const char *xclass,
1782 int foreground_p)
1784 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
1785 Lisp_Object tem;
1787 tem = x_get_arg (dpyinfo, alist, prop, xprop, xclass, RES_TYPE_STRING);
1788 if (EQ (tem, Qunbound))
1790 #ifdef USE_TOOLKIT_SCROLL_BARS
1792 /* See if an X resource for the scroll bar color has been
1793 specified. */
1794 tem = display_x_get_resource (dpyinfo,
1795 build_string (foreground_p
1796 ? "foreground"
1797 : "background"),
1798 empty_unibyte_string,
1799 build_string ("verticalScrollBar"),
1800 empty_unibyte_string);
1801 if (!STRINGP (tem))
1803 /* If nothing has been specified, scroll bars will use a
1804 toolkit-dependent default. Because these defaults are
1805 difficult to get at without actually creating a scroll
1806 bar, use nil to indicate that no color has been
1807 specified. */
1808 tem = Qnil;
1811 #else /* not USE_TOOLKIT_SCROLL_BARS */
1813 tem = Qnil;
1815 #endif /* not USE_TOOLKIT_SCROLL_BARS */
1818 x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));
1819 return tem;
1825 #ifdef USE_X_TOOLKIT
1827 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
1828 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
1829 already be present because of the toolkit (Motif adds some of them,
1830 for example, but Xt doesn't). */
1832 static void
1833 hack_wm_protocols (FRAME_PTR f, Widget widget)
1835 Display *dpy = XtDisplay (widget);
1836 Window w = XtWindow (widget);
1837 int need_delete = 1;
1838 int need_focus = 1;
1839 int need_save = 1;
1841 BLOCK_INPUT;
1843 Atom type;
1844 unsigned char *catoms;
1845 int format = 0;
1846 unsigned long nitems = 0;
1847 unsigned long bytes_after;
1849 if ((XGetWindowProperty (dpy, w,
1850 FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
1851 (long)0, (long)100, False, XA_ATOM,
1852 &type, &format, &nitems, &bytes_after,
1853 &catoms)
1854 == Success)
1855 && format == 32 && type == XA_ATOM)
1857 Atom *atoms = (Atom *) catoms;
1858 while (nitems > 0)
1860 nitems--;
1861 if (atoms[nitems]
1862 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window)
1863 need_delete = 0;
1864 else if (atoms[nitems]
1865 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus)
1866 need_focus = 0;
1867 else if (atoms[nitems]
1868 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself)
1869 need_save = 0;
1872 if (catoms)
1873 XFree (catoms);
1876 Atom props [10];
1877 int count = 0;
1878 if (need_delete)
1879 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window;
1880 if (need_focus)
1881 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus;
1882 if (need_save)
1883 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
1884 if (count)
1885 XChangeProperty (dpy, w, FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
1886 XA_ATOM, 32, PropModeAppend,
1887 (unsigned char *) props, count);
1889 UNBLOCK_INPUT;
1891 #endif
1895 /* Support routines for XIC (X Input Context). */
1897 #ifdef HAVE_X_I18N
1899 static XFontSet xic_create_xfontset (struct frame *);
1900 static XIMStyle best_xim_style (XIMStyles *, XIMStyles *);
1903 /* Supported XIM styles, ordered by preference. */
1905 static XIMStyle supported_xim_styles[] =
1907 XIMPreeditPosition | XIMStatusArea,
1908 XIMPreeditPosition | XIMStatusNothing,
1909 XIMPreeditPosition | XIMStatusNone,
1910 XIMPreeditNothing | XIMStatusArea,
1911 XIMPreeditNothing | XIMStatusNothing,
1912 XIMPreeditNothing | XIMStatusNone,
1913 XIMPreeditNone | XIMStatusArea,
1914 XIMPreeditNone | XIMStatusNothing,
1915 XIMPreeditNone | XIMStatusNone,
1920 /* Create an X fontset on frame F with base font name BASE_FONTNAME. */
1922 const char xic_defaut_fontset[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
1924 /* Create an Xt fontset spec from the name of a base font.
1925 If `motif' is True use the Motif syntax. */
1926 char *
1927 xic_create_fontsetname (const char *base_fontname, int motif)
1929 const char *sep = motif ? ";" : ",";
1930 char *fontsetname;
1932 /* Make a fontset name from the base font name. */
1933 if (xic_defaut_fontset == base_fontname)
1934 { /* There is no base font name, use the default. */
1935 int len = strlen (base_fontname) + 2;
1936 fontsetname = xmalloc (len);
1937 memset (fontsetname, 0, len);
1938 strcpy (fontsetname, base_fontname);
1940 else
1942 /* Make a fontset name from the base font name.
1943 The font set will be made of the following elements:
1944 - the base font.
1945 - the base font where the charset spec is replaced by -*-*.
1946 - the same but with the family also replaced with -*-*-. */
1947 const char *p = base_fontname;
1948 int i;
1950 for (i = 0; *p; p++)
1951 if (*p == '-') i++;
1952 if (i != 14)
1953 { /* As the font name doesn't conform to XLFD, we can't
1954 modify it to generalize it to allcs and allfamilies.
1955 Use the specified font plus the default. */
1956 int len = strlen (base_fontname) + strlen (xic_defaut_fontset) + 3;
1957 fontsetname = xmalloc (len);
1958 memset (fontsetname, 0, len);
1959 strcpy (fontsetname, base_fontname);
1960 strcat (fontsetname, sep);
1961 strcat (fontsetname, xic_defaut_fontset);
1963 else
1965 int len;
1966 const char *p1 = NULL, *p2 = NULL, *p3 = NULL;
1967 char *font_allcs = NULL;
1968 char *font_allfamilies = NULL;
1969 char *font_all = NULL;
1970 const char *allcs = "*-*-*-*-*-*-*";
1971 const char *allfamilies = "-*-*-";
1972 const char *all = "*-*-*-*-";
1973 char *base;
1975 for (i = 0, p = base_fontname; i < 8; p++)
1977 if (*p == '-')
1979 i++;
1980 if (i == 3)
1981 p1 = p + 1;
1982 else if (i == 7)
1983 p2 = p + 1;
1984 else if (i == 6)
1985 p3 = p + 1;
1988 /* If base_fontname specifies ADSTYLE, make it a
1989 wildcard. */
1990 if (*p3 != '*')
1992 int diff = (p2 - p3) - 2;
1994 base = alloca (strlen (base_fontname) + 1);
1995 memcpy (base, base_fontname, p3 - base_fontname);
1996 base[p3 - base_fontname] = '*';
1997 base[(p3 - base_fontname) + 1] = '-';
1998 strcpy (base + (p3 - base_fontname) + 2, p2);
1999 p = base + (p - base_fontname) - diff;
2000 p1 = base + (p1 - base_fontname);
2001 p2 = base + (p2 - base_fontname) - diff;
2002 base_fontname = base;
2005 /* Build the font spec that matches all charsets. */
2006 len = p - base_fontname + strlen (allcs) + 1;
2007 font_allcs = (char *) alloca (len);
2008 memset (font_allcs, 0, len);
2009 memcpy (font_allcs, base_fontname, p - base_fontname);
2010 strcat (font_allcs, allcs);
2012 /* Build the font spec that matches all families and
2013 add-styles. */
2014 len = p - p1 + strlen (allcs) + strlen (allfamilies) + 1;
2015 font_allfamilies = (char *) alloca (len);
2016 memset (font_allfamilies, 0, len);
2017 strcpy (font_allfamilies, allfamilies);
2018 memcpy (font_allfamilies + strlen (allfamilies), p1, p - p1);
2019 strcat (font_allfamilies, allcs);
2021 /* Build the font spec that matches all. */
2022 len = p - p2 + strlen (allcs) + strlen (all) + strlen (allfamilies) + 1;
2023 font_all = (char *) alloca (len);
2024 memset (font_all, 0, len);
2025 strcpy (font_all, allfamilies);
2026 strcat (font_all, all);
2027 memcpy (font_all + strlen (all) + strlen (allfamilies), p2, p - p2);
2028 strcat (font_all, allcs);
2030 /* Build the actual font set name. */
2031 len = strlen (base_fontname) + strlen (font_allcs)
2032 + strlen (font_allfamilies) + strlen (font_all) + 5;
2033 fontsetname = xmalloc (len);
2034 memset (fontsetname, 0, len);
2035 strcpy (fontsetname, base_fontname);
2036 strcat (fontsetname, sep);
2037 strcat (fontsetname, font_allcs);
2038 strcat (fontsetname, sep);
2039 strcat (fontsetname, font_allfamilies);
2040 strcat (fontsetname, sep);
2041 strcat (fontsetname, font_all);
2044 if (motif)
2045 strcat (fontsetname, ":");
2046 return fontsetname;
2049 #ifdef DEBUG_XIC_FONTSET
2050 static void
2051 print_fontset_result (xfs, name, missing_list, missing_count)
2052 XFontSet xfs;
2053 char *name;
2054 char **missing_list;
2055 int missing_count;
2057 if (xfs)
2058 fprintf (stderr, "XIC Fontset created: %s\n", name);
2059 else
2061 fprintf (stderr, "XIC Fontset failed: %s\n", name);
2062 while (missing_count-- > 0)
2064 fprintf (stderr, " missing: %s\n", *missing_list);
2065 missing_list++;
2070 #endif
2072 static XFontSet
2073 xic_create_xfontset (struct frame *f)
2075 XFontSet xfs = NULL;
2076 struct font *font = FRAME_FONT (f);
2077 int pixel_size = font->pixel_size;
2078 Lisp_Object rest, frame;
2080 /* See if there is another frame already using same fontset. */
2081 FOR_EACH_FRAME (rest, frame)
2083 struct frame *cf = XFRAME (frame);
2085 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
2086 && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f)
2087 && FRAME_FONT (f)
2088 && FRAME_FONT (f)->pixel_size == pixel_size)
2090 xfs = FRAME_XIC_FONTSET (cf);
2091 break;
2095 if (! xfs)
2097 char buf[256];
2098 char **missing_list;
2099 int missing_count;
2100 char *def_string;
2101 const char *xlfd_format = "-*-*-medium-r-normal--%d-*-*-*-*-*";
2103 sprintf (buf, xlfd_format, pixel_size);
2104 missing_list = NULL;
2105 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
2106 &missing_list, &missing_count, &def_string);
2107 #ifdef DEBUG_XIC_FONTSET
2108 print_fontset_result (xfs, buf, missing_list, missing_count);
2109 #endif
2110 if (missing_list)
2111 XFreeStringList (missing_list);
2112 if (! xfs)
2114 /* List of pixel sizes most likely available. Find one that
2115 is closest to pixel_size. */
2116 int sizes[] = {0, 8, 10, 11, 12, 14, 17, 18, 20, 24, 26, 34, 0};
2117 int *smaller, *larger;
2119 for (smaller = sizes; smaller[1]; smaller++)
2120 if (smaller[1] >= pixel_size)
2121 break;
2122 larger = smaller + 1;
2123 if (*larger == pixel_size)
2124 larger++;
2125 while (*smaller || *larger)
2127 int this_size;
2129 if (! *larger)
2130 this_size = *smaller--;
2131 else if (! *smaller)
2132 this_size = *larger++;
2133 else if (pixel_size - *smaller < *larger - pixel_size)
2134 this_size = *smaller--;
2135 else
2136 this_size = *larger++;
2137 sprintf (buf, xlfd_format, this_size);
2138 missing_list = NULL;
2139 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
2140 &missing_list, &missing_count, &def_string);
2141 #ifdef DEBUG_XIC_FONTSET
2142 print_fontset_result (xfs, buf, missing_list, missing_count);
2143 #endif
2144 if (missing_list)
2145 XFreeStringList (missing_list);
2146 if (xfs)
2147 break;
2150 if (! xfs)
2152 const char *last_resort = "-*-*-*-r-normal--*-*-*-*-*-*";
2154 missing_list = NULL;
2155 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), last_resort,
2156 &missing_list, &missing_count, &def_string);
2157 #ifdef DEBUG_XIC_FONTSET
2158 print_fontset_result (xfs, last_resort, missing_list, missing_count);
2159 #endif
2160 if (missing_list)
2161 XFreeStringList (missing_list);
2166 return xfs;
2169 /* Free the X fontset of frame F if it is the last frame using it. */
2171 void
2172 xic_free_xfontset (struct frame *f)
2174 Lisp_Object rest, frame;
2175 int shared_p = 0;
2177 if (!FRAME_XIC_FONTSET (f))
2178 return;
2180 /* See if there is another frame sharing the same fontset. */
2181 FOR_EACH_FRAME (rest, frame)
2183 struct frame *cf = XFRAME (frame);
2184 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
2185 && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f)
2186 && FRAME_XIC_FONTSET (cf) == FRAME_XIC_FONTSET (f))
2188 shared_p = 1;
2189 break;
2193 if (!shared_p)
2194 /* The fontset is not used anymore. It is safe to free it. */
2195 XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f));
2197 if (FRAME_XIC_BASE_FONTNAME (f))
2198 xfree (FRAME_XIC_BASE_FONTNAME (f));
2199 FRAME_XIC_BASE_FONTNAME (f) = NULL;
2200 FRAME_XIC_FONTSET (f) = NULL;
2204 /* Value is the best input style, given user preferences USER (already
2205 checked to be supported by Emacs), and styles supported by the
2206 input method XIM. */
2208 static XIMStyle
2209 best_xim_style (XIMStyles *user, XIMStyles *xim)
2211 int i, j;
2213 for (i = 0; i < user->count_styles; ++i)
2214 for (j = 0; j < xim->count_styles; ++j)
2215 if (user->supported_styles[i] == xim->supported_styles[j])
2216 return user->supported_styles[i];
2218 /* Return the default style. */
2219 return XIMPreeditNothing | XIMStatusNothing;
2222 /* Create XIC for frame F. */
2224 static XIMStyle xic_style;
2226 void
2227 create_frame_xic (struct frame *f)
2229 XIM xim;
2230 XIC xic = NULL;
2231 XFontSet xfs = NULL;
2233 if (FRAME_XIC (f))
2234 return;
2236 /* Create X fontset. */
2237 xfs = xic_create_xfontset (f);
2238 xim = FRAME_X_XIM (f);
2239 if (xim)
2241 XRectangle s_area;
2242 XPoint spot;
2243 XVaNestedList preedit_attr;
2244 XVaNestedList status_attr;
2246 s_area.x = 0; s_area.y = 0; s_area.width = 1; s_area.height = 1;
2247 spot.x = 0; spot.y = 1;
2249 /* Determine XIC style. */
2250 if (xic_style == 0)
2252 XIMStyles supported_list;
2253 supported_list.count_styles = (sizeof supported_xim_styles
2254 / sizeof supported_xim_styles[0]);
2255 supported_list.supported_styles = supported_xim_styles;
2256 xic_style = best_xim_style (&supported_list,
2257 FRAME_X_XIM_STYLES (f));
2260 preedit_attr = XVaCreateNestedList (0,
2261 XNFontSet, xfs,
2262 XNForeground,
2263 FRAME_FOREGROUND_PIXEL (f),
2264 XNBackground,
2265 FRAME_BACKGROUND_PIXEL (f),
2266 (xic_style & XIMPreeditPosition
2267 ? XNSpotLocation
2268 : NULL),
2269 &spot,
2270 NULL);
2271 status_attr = XVaCreateNestedList (0,
2272 XNArea,
2273 &s_area,
2274 XNFontSet,
2275 xfs,
2276 XNForeground,
2277 FRAME_FOREGROUND_PIXEL (f),
2278 XNBackground,
2279 FRAME_BACKGROUND_PIXEL (f),
2280 NULL);
2282 xic = XCreateIC (xim,
2283 XNInputStyle, xic_style,
2284 XNClientWindow, FRAME_X_WINDOW (f),
2285 XNFocusWindow, FRAME_X_WINDOW (f),
2286 XNStatusAttributes, status_attr,
2287 XNPreeditAttributes, preedit_attr,
2288 NULL);
2289 XFree (preedit_attr);
2290 XFree (status_attr);
2293 FRAME_XIC (f) = xic;
2294 FRAME_XIC_STYLE (f) = xic_style;
2295 FRAME_XIC_FONTSET (f) = xfs;
2299 /* Destroy XIC and free XIC fontset of frame F, if any. */
2301 void
2302 free_frame_xic (struct frame *f)
2304 if (FRAME_XIC (f) == NULL)
2305 return;
2307 XDestroyIC (FRAME_XIC (f));
2308 xic_free_xfontset (f);
2310 FRAME_XIC (f) = NULL;
2314 /* Place preedit area for XIC of window W's frame to specified
2315 pixel position X/Y. X and Y are relative to window W. */
2317 void
2318 xic_set_preeditarea (struct window *w, int x, int y)
2320 struct frame *f = XFRAME (w->frame);
2321 XVaNestedList attr;
2322 XPoint spot;
2324 spot.x = WINDOW_TO_FRAME_PIXEL_X (w, x) + WINDOW_LEFT_FRINGE_WIDTH (w);
2325 spot.y = WINDOW_TO_FRAME_PIXEL_Y (w, y) + FONT_BASE (FRAME_FONT (f));
2326 attr = XVaCreateNestedList (0, XNSpotLocation, &spot, NULL);
2327 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2328 XFree (attr);
2332 /* Place status area for XIC in bottom right corner of frame F.. */
2334 void
2335 xic_set_statusarea (struct frame *f)
2337 XIC xic = FRAME_XIC (f);
2338 XVaNestedList attr;
2339 XRectangle area;
2340 XRectangle *needed;
2342 /* Negotiate geometry of status area. If input method has existing
2343 status area, use its current size. */
2344 area.x = area.y = area.width = area.height = 0;
2345 attr = XVaCreateNestedList (0, XNAreaNeeded, &area, NULL);
2346 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2347 XFree (attr);
2349 attr = XVaCreateNestedList (0, XNAreaNeeded, &needed, NULL);
2350 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2351 XFree (attr);
2353 if (needed->width == 0) /* Use XNArea instead of XNAreaNeeded */
2355 attr = XVaCreateNestedList (0, XNArea, &needed, NULL);
2356 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2357 XFree (attr);
2360 area.width = needed->width;
2361 area.height = needed->height;
2362 area.x = FRAME_PIXEL_WIDTH (f) - area.width - FRAME_INTERNAL_BORDER_WIDTH (f);
2363 area.y = (FRAME_PIXEL_HEIGHT (f) - area.height
2364 - FRAME_MENUBAR_HEIGHT (f)
2365 - FRAME_TOOLBAR_TOP_HEIGHT (f)
2366 - FRAME_INTERNAL_BORDER_WIDTH (f));
2367 XFree (needed);
2369 attr = XVaCreateNestedList (0, XNArea, &area, NULL);
2370 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2371 XFree (attr);
2375 /* Set X fontset for XIC of frame F, using base font name
2376 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2378 void
2379 xic_set_xfontset (struct frame *f, const char *base_fontname)
2381 XVaNestedList attr;
2382 XFontSet xfs;
2384 xic_free_xfontset (f);
2386 xfs = xic_create_xfontset (f);
2388 attr = XVaCreateNestedList (0, XNFontSet, xfs, NULL);
2389 if (FRAME_XIC_STYLE (f) & XIMPreeditPosition)
2390 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2391 if (FRAME_XIC_STYLE (f) & XIMStatusArea)
2392 XSetICValues (FRAME_XIC (f), XNStatusAttributes, attr, NULL);
2393 XFree (attr);
2395 FRAME_XIC_FONTSET (f) = xfs;
2398 #endif /* HAVE_X_I18N */
2402 #ifdef USE_X_TOOLKIT
2404 /* Create and set up the X widget for frame F. */
2406 static void
2407 x_window (struct frame *f, long window_prompting, int minibuffer_only)
2409 XClassHint class_hints;
2410 XSetWindowAttributes attributes;
2411 unsigned long attribute_mask;
2412 Widget shell_widget;
2413 Widget pane_widget;
2414 Widget frame_widget;
2415 Arg al [25];
2416 int ac;
2418 BLOCK_INPUT;
2420 /* Use the resource name as the top-level widget name
2421 for looking up resources. Make a non-Lisp copy
2422 for the window manager, so GC relocation won't bother it.
2424 Elsewhere we specify the window name for the window manager. */
2427 char *str = (char *) SDATA (Vx_resource_name);
2428 f->namebuf = (char *) xmalloc (strlen (str) + 1);
2429 strcpy (f->namebuf, str);
2432 ac = 0;
2433 XtSetArg (al[ac], XtNallowShellResize, 1); ac++;
2434 XtSetArg (al[ac], XtNinput, 1); ac++;
2435 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2436 XtSetArg (al[ac], XtNborderWidth, f->border_width); ac++;
2437 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2438 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2439 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2440 shell_widget = XtAppCreateShell (f->namebuf, EMACS_CLASS,
2441 applicationShellWidgetClass,
2442 FRAME_X_DISPLAY (f), al, ac);
2444 f->output_data.x->widget = shell_widget;
2445 /* maybe_set_screen_title_format (shell_widget); */
2447 pane_widget = lw_create_widget ("main", "pane", widget_id_tick++,
2448 (widget_value *) NULL,
2449 shell_widget, False,
2450 (lw_callback) NULL,
2451 (lw_callback) NULL,
2452 (lw_callback) NULL,
2453 (lw_callback) NULL);
2455 ac = 0;
2456 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2457 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2458 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2459 XtSetArg (al[ac], XtNborderWidth, 0); ac++;
2460 XtSetValues (pane_widget, al, ac);
2461 f->output_data.x->column_widget = pane_widget;
2463 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2464 the emacs screen when changing menubar. This reduces flickering. */
2466 ac = 0;
2467 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2468 XtSetArg (al[ac], XtNshowGrip, 0); ac++;
2469 XtSetArg (al[ac], XtNallowResize, 1); ac++;
2470 XtSetArg (al[ac], XtNresizeToPreferred, 1); ac++;
2471 XtSetArg (al[ac], XtNemacsFrame, f); ac++;
2472 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2473 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2474 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2475 XtSetArg (al[ac], XtNborderWidth, 0); ac++;
2476 frame_widget = XtCreateWidget (f->namebuf, emacsFrameClass, pane_widget,
2477 al, ac);
2479 f->output_data.x->edit_widget = frame_widget;
2481 XtManageChild (frame_widget);
2483 /* Do some needed geometry management. */
2485 int len;
2486 char *tem, shell_position[32];
2487 Arg al[10];
2488 int ac = 0;
2489 int extra_borders = 0;
2490 int menubar_size
2491 = (f->output_data.x->menubar_widget
2492 ? (f->output_data.x->menubar_widget->core.height
2493 + f->output_data.x->menubar_widget->core.border_width)
2494 : 0);
2496 #if 0 /* Experimentally, we now get the right results
2497 for -geometry -0-0 without this. 24 Aug 96, rms. */
2498 if (FRAME_EXTERNAL_MENU_BAR (f))
2500 Dimension ibw = 0;
2501 XtVaGetValues (pane_widget, XtNinternalBorderWidth, &ibw, NULL);
2502 menubar_size += ibw;
2504 #endif
2506 f->output_data.x->menubar_height = menubar_size;
2508 #ifndef USE_LUCID
2509 /* Motif seems to need this amount added to the sizes
2510 specified for the shell widget. The Athena/Lucid widgets don't.
2511 Both conclusions reached experimentally. -- rms. */
2512 XtVaGetValues (f->output_data.x->edit_widget, XtNinternalBorderWidth,
2513 &extra_borders, NULL);
2514 extra_borders *= 2;
2515 #endif
2517 /* Convert our geometry parameters into a geometry string
2518 and specify it.
2519 Note that we do not specify here whether the position
2520 is a user-specified or program-specified one.
2521 We pass that information later, in x_wm_set_size_hints. */
2523 int left = f->left_pos;
2524 int xneg = window_prompting & XNegative;
2525 int top = f->top_pos;
2526 int yneg = window_prompting & YNegative;
2527 if (xneg)
2528 left = -left;
2529 if (yneg)
2530 top = -top;
2532 if (window_prompting & USPosition)
2533 sprintf (shell_position, "=%dx%d%c%d%c%d",
2534 FRAME_PIXEL_WIDTH (f) + extra_borders,
2535 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders,
2536 (xneg ? '-' : '+'), left,
2537 (yneg ? '-' : '+'), top);
2538 else
2540 sprintf (shell_position, "=%dx%d",
2541 FRAME_PIXEL_WIDTH (f) + extra_borders,
2542 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders);
2544 /* Setting x and y when the position is not specified in
2545 the geometry string will set program position in the WM hints.
2546 If Emacs had just one program position, we could set it in
2547 fallback resources, but since each make-frame call can specify
2548 different program positions, this is easier. */
2549 XtSetArg (al[ac], XtNx, left); ac++;
2550 XtSetArg (al[ac], XtNy, top); ac++;
2554 len = strlen (shell_position) + 1;
2555 /* We don't free this because we don't know whether
2556 it is safe to free it while the frame exists.
2557 It isn't worth the trouble of arranging to free it
2558 when the frame is deleted. */
2559 tem = (char *) xmalloc (len);
2560 strncpy (tem, shell_position, len);
2561 XtSetArg (al[ac], XtNgeometry, tem); ac++;
2562 XtSetValues (shell_widget, al, ac);
2565 XtManageChild (pane_widget);
2566 XtRealizeWidget (shell_widget);
2568 if (FRAME_X_EMBEDDED_P (f))
2569 XReparentWindow (FRAME_X_DISPLAY (f), XtWindow (shell_widget),
2570 f->output_data.x->parent_desc, 0, 0);
2572 FRAME_X_WINDOW (f) = XtWindow (frame_widget);
2574 validate_x_resource_name ();
2576 class_hints.res_name = (char *) SDATA (Vx_resource_name);
2577 class_hints.res_class = (char *) SDATA (Vx_resource_class);
2578 XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints);
2580 #ifdef HAVE_X_I18N
2581 FRAME_XIC (f) = NULL;
2582 if (use_xim)
2583 create_frame_xic (f);
2584 #endif
2586 f->output_data.x->wm_hints.input = True;
2587 f->output_data.x->wm_hints.flags |= InputHint;
2588 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2589 &f->output_data.x->wm_hints);
2591 hack_wm_protocols (f, shell_widget);
2593 #ifdef HACK_EDITRES
2594 XtAddEventHandler (shell_widget, 0, True, _XEditResCheckMessages, 0);
2595 #endif
2597 /* Do a stupid property change to force the server to generate a
2598 PropertyNotify event so that the event_stream server timestamp will
2599 be initialized to something relevant to the time we created the window.
2601 XChangeProperty (XtDisplay (frame_widget), XtWindow (frame_widget),
2602 FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
2603 XA_ATOM, 32, PropModeAppend,
2604 (unsigned char*) NULL, 0);
2606 /* Make all the standard events reach the Emacs frame. */
2607 attributes.event_mask = STANDARD_EVENT_SET;
2609 #ifdef HAVE_X_I18N
2610 if (FRAME_XIC (f))
2612 /* XIM server might require some X events. */
2613 unsigned long fevent = NoEventMask;
2614 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2615 attributes.event_mask |= fevent;
2617 #endif /* HAVE_X_I18N */
2619 attribute_mask = CWEventMask;
2620 XChangeWindowAttributes (XtDisplay (shell_widget), XtWindow (shell_widget),
2621 attribute_mask, &attributes);
2623 XtMapWidget (frame_widget);
2625 /* x_set_name normally ignores requests to set the name if the
2626 requested name is the same as the current name. This is the one
2627 place where that assumption isn't correct; f->name is set, but
2628 the X server hasn't been told. */
2630 Lisp_Object name;
2631 int explicit = f->explicit_name;
2633 f->explicit_name = 0;
2634 name = f->name;
2635 f->name = Qnil;
2636 x_set_name (f, name, explicit);
2639 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2640 f->output_data.x->current_cursor
2641 = f->output_data.x->text_cursor);
2643 UNBLOCK_INPUT;
2645 /* This is a no-op, except under Motif. Make sure main areas are
2646 set to something reasonable, in case we get an error later. */
2647 lw_set_main_areas (pane_widget, 0, frame_widget);
2650 #else /* not USE_X_TOOLKIT */
2651 #ifdef USE_GTK
2652 void
2653 x_window (FRAME_PTR f)
2655 if (! xg_create_frame_widgets (f))
2656 error ("Unable to create window");
2658 #ifdef HAVE_X_I18N
2659 FRAME_XIC (f) = NULL;
2660 if (use_xim)
2662 BLOCK_INPUT;
2663 create_frame_xic (f);
2664 if (FRAME_XIC (f))
2666 /* XIM server might require some X events. */
2667 unsigned long fevent = NoEventMask;
2668 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2670 if (fevent != NoEventMask)
2672 XSetWindowAttributes attributes;
2673 XWindowAttributes wattr;
2674 unsigned long attribute_mask;
2676 XGetWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2677 &wattr);
2678 attributes.event_mask = wattr.your_event_mask | fevent;
2679 attribute_mask = CWEventMask;
2680 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2681 attribute_mask, &attributes);
2684 UNBLOCK_INPUT;
2686 #endif
2689 #else /*! USE_GTK */
2690 /* Create and set up the X window for frame F. */
2692 void
2693 x_window (struct frame *f)
2695 XClassHint class_hints;
2696 XSetWindowAttributes attributes;
2697 unsigned long attribute_mask;
2699 attributes.background_pixel = FRAME_BACKGROUND_PIXEL (f);
2700 attributes.border_pixel = f->output_data.x->border_pixel;
2701 attributes.bit_gravity = StaticGravity;
2702 attributes.backing_store = NotUseful;
2703 attributes.save_under = True;
2704 attributes.event_mask = STANDARD_EVENT_SET;
2705 attributes.colormap = FRAME_X_COLORMAP (f);
2706 attribute_mask = (CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask
2707 | CWColormap);
2709 BLOCK_INPUT;
2710 FRAME_X_WINDOW (f)
2711 = XCreateWindow (FRAME_X_DISPLAY (f),
2712 f->output_data.x->parent_desc,
2713 f->left_pos,
2714 f->top_pos,
2715 FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
2716 f->border_width,
2717 CopyFromParent, /* depth */
2718 InputOutput, /* class */
2719 FRAME_X_VISUAL (f),
2720 attribute_mask, &attributes);
2722 #ifdef HAVE_X_I18N
2723 if (use_xim)
2725 create_frame_xic (f);
2726 if (FRAME_XIC (f))
2728 /* XIM server might require some X events. */
2729 unsigned long fevent = NoEventMask;
2730 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2731 attributes.event_mask |= fevent;
2732 attribute_mask = CWEventMask;
2733 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2734 attribute_mask, &attributes);
2737 #endif /* HAVE_X_I18N */
2739 validate_x_resource_name ();
2741 class_hints.res_name = (char *) SDATA (Vx_resource_name);
2742 class_hints.res_class = (char *) SDATA (Vx_resource_class);
2743 XSetClassHint (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &class_hints);
2745 /* The menubar is part of the ordinary display;
2746 it does not count in addition to the height of the window. */
2747 f->output_data.x->menubar_height = 0;
2749 /* This indicates that we use the "Passive Input" input model.
2750 Unless we do this, we don't get the Focus{In,Out} events that we
2751 need to draw the cursor correctly. Accursed bureaucrats.
2752 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2754 f->output_data.x->wm_hints.input = True;
2755 f->output_data.x->wm_hints.flags |= InputHint;
2756 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2757 &f->output_data.x->wm_hints);
2758 f->output_data.x->wm_hints.icon_pixmap = None;
2760 /* Request "save yourself" and "delete window" commands from wm. */
2762 Atom protocols[2];
2763 protocols[0] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window;
2764 protocols[1] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
2765 XSetWMProtocols (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), protocols, 2);
2768 /* x_set_name normally ignores requests to set the name if the
2769 requested name is the same as the current name. This is the one
2770 place where that assumption isn't correct; f->name is set, but
2771 the X server hasn't been told. */
2773 Lisp_Object name;
2774 int explicit = f->explicit_name;
2776 f->explicit_name = 0;
2777 name = f->name;
2778 f->name = Qnil;
2779 x_set_name (f, name, explicit);
2782 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2783 f->output_data.x->current_cursor
2784 = f->output_data.x->text_cursor);
2786 UNBLOCK_INPUT;
2788 if (FRAME_X_WINDOW (f) == 0)
2789 error ("Unable to create window");
2792 #endif /* not USE_GTK */
2793 #endif /* not USE_X_TOOLKIT */
2795 /* Verify that the icon position args for this window are valid. */
2797 static void
2798 x_icon_verify (struct frame *f, Lisp_Object parms)
2800 Lisp_Object icon_x, icon_y;
2802 /* Set the position of the icon. Note that twm groups all
2803 icons in an icon window. */
2804 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2805 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2806 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2808 CHECK_NUMBER (icon_x);
2809 CHECK_NUMBER (icon_y);
2811 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2812 error ("Both left and top icon corners of icon must be specified");
2815 /* Handle the icon stuff for this window. Perhaps later we might
2816 want an x_set_icon_position which can be called interactively as
2817 well. */
2819 static void
2820 x_icon (struct frame *f, Lisp_Object parms)
2822 Lisp_Object icon_x, icon_y;
2823 #if 0
2824 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2825 #endif
2827 /* Set the position of the icon. Note that twm groups all
2828 icons in an icon window. */
2829 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2830 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2831 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2833 CHECK_NUMBER (icon_x);
2834 CHECK_NUMBER (icon_y);
2836 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2837 error ("Both left and top icon corners of icon must be specified");
2839 BLOCK_INPUT;
2841 if (! EQ (icon_x, Qunbound))
2842 x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
2844 #if 0 /* x_get_arg removes the visibility parameter as a side effect,
2845 but x_create_frame still needs it. */
2846 /* Start up iconic or window? */
2847 x_wm_set_window_state
2848 (f, (EQ (x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL),
2849 Qicon)
2850 ? IconicState
2851 : NormalState));
2852 #endif
2854 x_text_icon (f, (char *) SDATA ((!NILP (f->icon_name)
2855 ? f->icon_name
2856 : f->name)));
2858 UNBLOCK_INPUT;
2861 /* Make the GCs needed for this window, setting the
2862 background, border and mouse colors; also create the
2863 mouse cursor and the gray border tile. */
2865 static void
2866 x_make_gc (struct frame *f)
2868 XGCValues gc_values;
2870 BLOCK_INPUT;
2872 /* Create the GCs of this frame.
2873 Note that many default values are used. */
2875 gc_values.foreground = FRAME_FOREGROUND_PIXEL (f);
2876 gc_values.background = FRAME_BACKGROUND_PIXEL (f);
2877 gc_values.line_width = 0; /* Means 1 using fast algorithm. */
2878 f->output_data.x->normal_gc
2879 = XCreateGC (FRAME_X_DISPLAY (f),
2880 FRAME_X_WINDOW (f),
2881 GCLineWidth | GCForeground | GCBackground,
2882 &gc_values);
2884 /* Reverse video style. */
2885 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2886 gc_values.background = FRAME_FOREGROUND_PIXEL (f);
2887 f->output_data.x->reverse_gc
2888 = XCreateGC (FRAME_X_DISPLAY (f),
2889 FRAME_X_WINDOW (f),
2890 GCForeground | GCBackground | GCLineWidth,
2891 &gc_values);
2893 /* Cursor has cursor-color background, background-color foreground. */
2894 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2895 gc_values.background = f->output_data.x->cursor_pixel;
2896 gc_values.fill_style = FillOpaqueStippled;
2897 f->output_data.x->cursor_gc
2898 = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2899 (GCForeground | GCBackground
2900 | GCFillStyle | GCLineWidth),
2901 &gc_values);
2903 /* Reliefs. */
2904 f->output_data.x->white_relief.gc = 0;
2905 f->output_data.x->black_relief.gc = 0;
2907 /* Create the gray border tile used when the pointer is not in
2908 the frame. Since this depends on the frame's pixel values,
2909 this must be done on a per-frame basis. */
2910 f->output_data.x->border_tile
2911 = (XCreatePixmapFromBitmapData
2912 (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
2913 gray_bits, gray_width, gray_height,
2914 FRAME_FOREGROUND_PIXEL (f),
2915 FRAME_BACKGROUND_PIXEL (f),
2916 DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
2918 UNBLOCK_INPUT;
2922 /* Free what was allocated in x_make_gc. */
2924 void
2925 x_free_gcs (struct frame *f)
2927 Display *dpy = FRAME_X_DISPLAY (f);
2929 BLOCK_INPUT;
2931 if (f->output_data.x->normal_gc)
2933 XFreeGC (dpy, f->output_data.x->normal_gc);
2934 f->output_data.x->normal_gc = 0;
2937 if (f->output_data.x->reverse_gc)
2939 XFreeGC (dpy, f->output_data.x->reverse_gc);
2940 f->output_data.x->reverse_gc = 0;
2943 if (f->output_data.x->cursor_gc)
2945 XFreeGC (dpy, f->output_data.x->cursor_gc);
2946 f->output_data.x->cursor_gc = 0;
2949 if (f->output_data.x->border_tile)
2951 XFreePixmap (dpy, f->output_data.x->border_tile);
2952 f->output_data.x->border_tile = 0;
2955 UNBLOCK_INPUT;
2959 /* Handler for signals raised during x_create_frame and
2960 x_create_top_frame. FRAME is the frame which is partially
2961 constructed. */
2963 static Lisp_Object
2964 unwind_create_frame (Lisp_Object frame)
2966 struct frame *f = XFRAME (frame);
2968 /* If frame is already dead, nothing to do. This can happen if the
2969 display is disconnected after the frame has become official, but
2970 before x_create_frame removes the unwind protect. */
2971 if (!FRAME_LIVE_P (f))
2972 return Qnil;
2974 /* If frame is ``official'', nothing to do. */
2975 if (!CONSP (Vframe_list) || !EQ (XCAR (Vframe_list), frame))
2977 #if GLYPH_DEBUG
2978 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2979 #endif
2981 x_free_frame_resources (f);
2983 #if GLYPH_DEBUG
2984 /* Check that reference counts are indeed correct. */
2985 xassert (dpyinfo->reference_count == dpyinfo_refcount);
2986 xassert (dpyinfo->image_cache->refcount == image_cache_refcount);
2987 #endif
2988 return Qt;
2991 return Qnil;
2995 static void
2996 x_default_font_parameter (struct frame *f, Lisp_Object parms)
2998 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2999 Lisp_Object font_param = x_get_arg (dpyinfo, parms, Qfont, NULL, NULL,
3000 RES_TYPE_STRING);
3001 Lisp_Object font = Qnil;
3002 if (EQ (font_param, Qunbound))
3003 font_param = Qnil;
3005 if (NILP (font_param))
3007 /* System font should take precedendce over X resources. We suggest this
3008 regardless of font-use-system-font because .emacs may not have been
3009 read yet. */
3010 const char *system_font = xsettings_get_system_font ();
3011 if (system_font)
3013 char *name = xstrdup (system_font);
3014 font = font_open_by_name (f, name);
3015 free (name);
3019 if (NILP (font))
3020 font = !NILP (font_param) ? font_param
3021 : x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
3023 if (! FONTP (font) && ! STRINGP (font))
3025 const char *names[]
3027 #ifdef HAVE_XFT
3028 /* This will find the normal Xft font. */
3029 "monospace-10",
3030 #endif
3031 "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
3032 "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3033 "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3034 /* This was formerly the first thing tried, but it finds
3035 too many fonts and takes too long. */
3036 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
3037 /* If those didn't work, look for something which will
3038 at least work. */
3039 "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
3040 "fixed",
3041 NULL };
3042 int i;
3044 for (i = 0; names[i]; i++)
3046 font = font_open_by_name (f, names[i]);
3047 if (! NILP (font))
3048 break;
3050 if (NILP (font))
3051 error ("No suitable font was found");
3053 else if (!NILP (font_param))
3055 /* Remember the explicit font parameter, so we can re-apply it after
3056 we've applied the `default' face settings. */
3057 x_set_frame_parameters (f, Fcons (Fcons (Qfont_param, font_param), Qnil));
3060 /* This call will make X resources override any system font setting. */
3061 x_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING);
3065 DEFUN ("x-wm-set-size-hint", Fx_wm_set_size_hint, Sx_wm_set_size_hint,
3066 0, 1, 0,
3067 doc: /* Send the size hints for frame FRAME to the window manager.
3068 If FRAME is nil, use the selected frame. */)
3069 (Lisp_Object frame)
3071 struct frame *f;
3072 if (NILP (frame))
3073 frame = selected_frame;
3074 f = XFRAME (frame);
3075 BLOCK_INPUT;
3076 if (FRAME_X_P (f))
3077 x_wm_set_size_hint (f, 0, 0);
3078 UNBLOCK_INPUT;
3079 return Qnil;
3082 static void
3083 set_machine_and_pid_properties (struct frame *f)
3085 /* See the above comment "Note: Encoding strategy". */
3086 XTextProperty text;
3087 int bytes, stringp;
3088 int do_free_text_value = 0;
3089 long pid = (long) getpid ();
3091 text.value = x_encode_text (Vsystem_name,
3092 Qcompound_text, 0, &bytes, &stringp,
3093 &do_free_text_value);
3094 text.encoding = (stringp ? XA_STRING
3095 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
3096 text.format = 8;
3097 text.nitems = bytes;
3098 XSetWMClientMachine (FRAME_X_DISPLAY (f),
3099 FRAME_OUTER_WINDOW (f),
3100 &text);
3101 if (do_free_text_value)
3102 xfree (text.value);
3104 XChangeProperty (FRAME_X_DISPLAY (f),
3105 FRAME_OUTER_WINDOW (f),
3106 XInternAtom (FRAME_X_DISPLAY (f),
3107 "_NET_WM_PID",
3108 False),
3109 XA_CARDINAL, 32, PropModeReplace,
3110 (unsigned char *) &pid, 1);
3113 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
3114 1, 1, 0,
3115 doc: /* Make a new X window, which is called a "frame" in Emacs terms.
3116 Return an Emacs frame object.
3117 PARMS is an alist of frame parameters.
3118 If the parameters specify that the frame should not have a minibuffer,
3119 and do not specify a specific minibuffer window to use,
3120 then `default-minibuffer-frame' must be a frame whose minibuffer can
3121 be shared by the new frame.
3123 This function is an internal primitive--use `make-frame' instead. */)
3124 (Lisp_Object parms)
3126 struct frame *f;
3127 Lisp_Object frame, tem;
3128 Lisp_Object name;
3129 int minibuffer_only = 0;
3130 long window_prompting = 0;
3131 int width, height;
3132 int count = SPECPDL_INDEX ();
3133 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
3134 Lisp_Object display;
3135 struct x_display_info *dpyinfo = NULL;
3136 Lisp_Object parent;
3137 struct kboard *kb;
3139 parms = Fcopy_alist (parms);
3141 /* Use this general default value to start with
3142 until we know if this frame has a specified name. */
3143 Vx_resource_name = Vinvocation_name;
3145 display = x_get_arg (dpyinfo, parms, Qterminal, 0, 0, RES_TYPE_NUMBER);
3146 if (EQ (display, Qunbound))
3147 display = x_get_arg (dpyinfo, parms, Qdisplay, 0, 0, RES_TYPE_STRING);
3148 if (EQ (display, Qunbound))
3149 display = Qnil;
3150 dpyinfo = check_x_display_info (display);
3151 kb = dpyinfo->terminal->kboard;
3153 if (!dpyinfo->terminal->name)
3154 error ("Terminal is not live, can't create new frames on it");
3156 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
3157 if (!STRINGP (name)
3158 && ! EQ (name, Qunbound)
3159 && ! NILP (name))
3160 error ("Invalid frame name--not a string or nil");
3162 if (STRINGP (name))
3163 Vx_resource_name = name;
3165 /* See if parent window is specified. */
3166 parent = x_get_arg (dpyinfo, parms, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
3167 if (EQ (parent, Qunbound))
3168 parent = Qnil;
3169 if (! NILP (parent))
3170 CHECK_NUMBER (parent);
3172 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
3173 /* No need to protect DISPLAY because that's not used after passing
3174 it to make_frame_without_minibuffer. */
3175 frame = Qnil;
3176 GCPRO4 (parms, parent, name, frame);
3177 tem = x_get_arg (dpyinfo, parms, Qminibuffer, "minibuffer", "Minibuffer",
3178 RES_TYPE_SYMBOL);
3179 if (EQ (tem, Qnone) || NILP (tem))
3180 f = make_frame_without_minibuffer (Qnil, kb, display);
3181 else if (EQ (tem, Qonly))
3183 f = make_minibuffer_frame ();
3184 minibuffer_only = 1;
3186 else if (WINDOWP (tem))
3187 f = make_frame_without_minibuffer (tem, kb, display);
3188 else
3189 f = make_frame (1);
3191 XSETFRAME (frame, f);
3193 /* Note that X Windows does support scroll bars. */
3194 FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
3196 f->terminal = dpyinfo->terminal;
3197 f->terminal->reference_count++;
3199 f->output_method = output_x_window;
3200 f->output_data.x = (struct x_output *) xmalloc (sizeof (struct x_output));
3201 memset (f->output_data.x, 0, sizeof (struct x_output));
3202 f->output_data.x->icon_bitmap = -1;
3203 FRAME_FONTSET (f) = -1;
3204 f->output_data.x->scroll_bar_foreground_pixel = -1;
3205 f->output_data.x->scroll_bar_background_pixel = -1;
3206 #ifdef USE_TOOLKIT_SCROLL_BARS
3207 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
3208 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
3209 #endif /* USE_TOOLKIT_SCROLL_BARS */
3211 f->icon_name
3212 = x_get_arg (dpyinfo, parms, Qicon_name, "iconName", "Title",
3213 RES_TYPE_STRING);
3214 if (! STRINGP (f->icon_name))
3215 f->icon_name = Qnil;
3217 FRAME_X_DISPLAY_INFO (f) = dpyinfo;
3219 /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe. */
3220 record_unwind_protect (unwind_create_frame, frame);
3221 #if GLYPH_DEBUG
3222 image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
3223 dpyinfo_refcount = dpyinfo->reference_count;
3224 #endif /* GLYPH_DEBUG */
3226 /* These colors will be set anyway later, but it's important
3227 to get the color reference counts right, so initialize them! */
3229 Lisp_Object black;
3230 struct gcpro gcpro1;
3232 /* Function x_decode_color can signal an error. Make
3233 sure to initialize color slots so that we won't try
3234 to free colors we haven't allocated. */
3235 FRAME_FOREGROUND_PIXEL (f) = -1;
3236 FRAME_BACKGROUND_PIXEL (f) = -1;
3237 f->output_data.x->cursor_pixel = -1;
3238 f->output_data.x->cursor_foreground_pixel = -1;
3239 f->output_data.x->border_pixel = -1;
3240 f->output_data.x->mouse_pixel = -1;
3242 black = build_string ("black");
3243 GCPRO1 (black);
3244 FRAME_FOREGROUND_PIXEL (f)
3245 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3246 FRAME_BACKGROUND_PIXEL (f)
3247 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3248 f->output_data.x->cursor_pixel
3249 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3250 f->output_data.x->cursor_foreground_pixel
3251 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3252 f->output_data.x->border_pixel
3253 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3254 f->output_data.x->mouse_pixel
3255 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3256 UNGCPRO;
3259 /* Specify the parent under which to make this X window. */
3261 if (!NILP (parent))
3263 f->output_data.x->parent_desc = (Window) XFASTINT (parent);
3264 f->output_data.x->explicit_parent = 1;
3266 else
3268 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
3269 f->output_data.x->explicit_parent = 0;
3272 /* Set the name; the functions to which we pass f expect the name to
3273 be set. */
3274 if (EQ (name, Qunbound) || NILP (name))
3276 f->name = build_string (dpyinfo->x_id_name);
3277 f->explicit_name = 0;
3279 else
3281 f->name = name;
3282 f->explicit_name = 1;
3283 /* use the frame's title when getting resources for this frame. */
3284 specbind (Qx_resource_name, name);
3287 f->resx = dpyinfo->resx;
3288 f->resy = dpyinfo->resy;
3290 #ifdef HAVE_FREETYPE
3291 #ifdef HAVE_XFT
3292 register_font_driver (&xftfont_driver, f);
3293 #else /* not HAVE_XFT */
3294 register_font_driver (&ftxfont_driver, f);
3295 #endif /* not HAVE_XFT */
3296 #endif /* HAVE_FREETYPE */
3297 register_font_driver (&xfont_driver, f);
3299 x_default_parameter (f, parms, Qfont_backend, Qnil,
3300 "fontBackend", "FontBackend", RES_TYPE_STRING);
3302 /* Extract the window parameters from the supplied values
3303 that are needed to determine window geometry. */
3304 x_default_font_parameter (f, parms);
3305 if (!FRAME_FONT (f))
3307 delete_frame (frame, Qnoelisp);
3308 error ("Invalid frame font");
3311 /* Frame contents get displaced if an embedded X window has a border. */
3312 if (! FRAME_X_EMBEDDED_P (f))
3313 x_default_parameter (f, parms, Qborder_width, make_number (0),
3314 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
3316 /* This defaults to 1 in order to match xterm. We recognize either
3317 internalBorderWidth or internalBorder (which is what xterm calls
3318 it). */
3319 if (NILP (Fassq (Qinternal_border_width, parms)))
3321 Lisp_Object value;
3323 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
3324 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
3325 if (! EQ (value, Qunbound))
3326 parms = Fcons (Fcons (Qinternal_border_width, value),
3327 parms);
3329 x_default_parameter (f, parms, Qinternal_border_width,
3330 #ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */
3331 make_number (0),
3332 #else
3333 make_number (1),
3334 #endif
3335 "internalBorderWidth", "internalBorderWidth",
3336 RES_TYPE_NUMBER);
3337 x_default_parameter (f, parms, Qvertical_scroll_bars,
3338 #if defined(USE_GTK) && defined(USE_TOOLKIT_SCROLL_BARS)
3339 Qright,
3340 #else
3341 Qleft,
3342 #endif
3343 "verticalScrollBars", "ScrollBars",
3344 RES_TYPE_SYMBOL);
3346 /* Also do the stuff which must be set before the window exists. */
3347 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
3348 "foreground", "Foreground", RES_TYPE_STRING);
3349 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
3350 "background", "Background", RES_TYPE_STRING);
3351 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
3352 "pointerColor", "Foreground", RES_TYPE_STRING);
3353 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
3354 "cursorColor", "Foreground", RES_TYPE_STRING);
3355 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
3356 "borderColor", "BorderColor", RES_TYPE_STRING);
3357 x_default_parameter (f, parms, Qscreen_gamma, Qnil,
3358 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
3359 x_default_parameter (f, parms, Qline_spacing, Qnil,
3360 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
3361 x_default_parameter (f, parms, Qleft_fringe, Qnil,
3362 "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
3363 x_default_parameter (f, parms, Qright_fringe, Qnil,
3364 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
3366 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_foreground,
3367 "scrollBarForeground",
3368 "ScrollBarForeground", 1);
3369 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_background,
3370 "scrollBarBackground",
3371 "ScrollBarBackground", 0);
3373 /* Init faces before x_default_parameter is called for scroll-bar
3374 parameters because that function calls x_set_scroll_bar_width,
3375 which calls change_frame_size, which calls Fset_window_buffer,
3376 which runs hooks, which call Fvertical_motion. At the end, we
3377 end up in init_iterator with a null face cache, which should not
3378 happen. */
3379 init_frame_faces (f);
3381 /* The X resources controlling the menu-bar and tool-bar are
3382 processed specially at startup, and reflected in the mode
3383 variables; ignore them here. */
3384 x_default_parameter (f, parms, Qmenu_bar_lines,
3385 NILP (Vmenu_bar_mode)
3386 ? make_number (0) : make_number (1),
3387 NULL, NULL, RES_TYPE_NUMBER);
3388 x_default_parameter (f, parms, Qtool_bar_lines,
3389 NILP (Vtool_bar_mode)
3390 ? make_number (0) : make_number (1),
3391 NULL, NULL, RES_TYPE_NUMBER);
3393 x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
3394 "bufferPredicate", "BufferPredicate",
3395 RES_TYPE_SYMBOL);
3396 x_default_parameter (f, parms, Qtitle, Qnil,
3397 "title", "Title", RES_TYPE_STRING);
3398 x_default_parameter (f, parms, Qwait_for_wm, Qt,
3399 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
3400 x_default_parameter (f, parms, Qfullscreen, Qnil,
3401 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
3402 x_default_parameter (f, parms, Qtool_bar_position,
3403 f->tool_bar_position, 0, 0, RES_TYPE_SYMBOL);
3405 /* Compute the size of the X window. */
3406 window_prompting = x_figure_window_size (f, parms, 1);
3408 tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
3409 f->no_split = minibuffer_only || EQ (tem, Qt);
3411 x_icon_verify (f, parms);
3413 /* Create the X widget or window. */
3414 #ifdef USE_X_TOOLKIT
3415 x_window (f, window_prompting, minibuffer_only);
3416 #else
3417 x_window (f);
3418 #endif
3420 x_icon (f, parms);
3421 x_make_gc (f);
3423 /* Now consider the frame official. */
3424 FRAME_X_DISPLAY_INFO (f)->reference_count++;
3425 Vframe_list = Fcons (frame, Vframe_list);
3427 /* We need to do this after creating the X window, so that the
3428 icon-creation functions can say whose icon they're describing. */
3429 x_default_parameter (f, parms, Qicon_type, Qt,
3430 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
3432 x_default_parameter (f, parms, Qauto_raise, Qnil,
3433 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3434 x_default_parameter (f, parms, Qauto_lower, Qnil,
3435 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3436 x_default_parameter (f, parms, Qcursor_type, Qbox,
3437 "cursorType", "CursorType", RES_TYPE_SYMBOL);
3438 x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
3439 "scrollBarWidth", "ScrollBarWidth",
3440 RES_TYPE_NUMBER);
3441 x_default_parameter (f, parms, Qalpha, Qnil,
3442 "alpha", "Alpha", RES_TYPE_NUMBER);
3444 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3445 Change will not be effected unless different from the current
3446 FRAME_LINES (f). */
3447 width = FRAME_COLS (f);
3448 height = FRAME_LINES (f);
3450 SET_FRAME_COLS (f, 0);
3451 FRAME_LINES (f) = 0;
3452 change_frame_size (f, height, width, 1, 0, 0);
3454 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3455 /* Create the menu bar. */
3456 if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
3458 /* If this signals an error, we haven't set size hints for the
3459 frame and we didn't make it visible. */
3460 initialize_frame_menubar (f);
3462 #ifndef USE_GTK
3463 /* This is a no-op, except under Motif where it arranges the
3464 main window for the widgets on it. */
3465 lw_set_main_areas (f->output_data.x->column_widget,
3466 f->output_data.x->menubar_widget,
3467 f->output_data.x->edit_widget);
3468 #endif /* not USE_GTK */
3470 #endif /* USE_X_TOOLKIT || USE_GTK */
3472 /* Tell the server what size and position, etc, we want, and how
3473 badly we want them. This should be done after we have the menu
3474 bar so that its size can be taken into account. */
3475 BLOCK_INPUT;
3476 x_wm_set_size_hint (f, window_prompting, 0);
3477 UNBLOCK_INPUT;
3479 /* Make the window appear on the frame and enable display, unless
3480 the caller says not to. However, with explicit parent, Emacs
3481 cannot control visibility, so don't try. */
3482 if (! f->output_data.x->explicit_parent)
3484 Lisp_Object visibility;
3486 visibility = x_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
3487 RES_TYPE_SYMBOL);
3488 if (EQ (visibility, Qunbound))
3489 visibility = Qt;
3491 if (EQ (visibility, Qicon))
3492 x_iconify_frame (f);
3493 else if (! NILP (visibility))
3494 x_make_frame_visible (f);
3495 else
3496 /* Must have been Qnil. */
3500 BLOCK_INPUT;
3502 /* Set machine name and pid for the purpose of window managers. */
3503 set_machine_and_pid_properties(f);
3505 /* Set the WM leader property. GTK does this itself, so this is not
3506 needed when using GTK. */
3507 if (dpyinfo->client_leader_window != 0)
3509 XChangeProperty (FRAME_X_DISPLAY (f),
3510 FRAME_OUTER_WINDOW (f),
3511 dpyinfo->Xatom_wm_client_leader,
3512 XA_WINDOW, 32, PropModeReplace,
3513 (unsigned char *) &dpyinfo->client_leader_window, 1);
3516 UNBLOCK_INPUT;
3518 /* Initialize `default-minibuffer-frame' in case this is the first
3519 frame on this terminal. */
3520 if (FRAME_HAS_MINIBUF_P (f)
3521 && (!FRAMEP (kb->Vdefault_minibuffer_frame)
3522 || !FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame))))
3523 kb->Vdefault_minibuffer_frame = frame;
3525 /* All remaining specified parameters, which have not been "used"
3526 by x_get_arg and friends, now go in the misc. alist of the frame. */
3527 for (tem = parms; CONSP (tem); tem = XCDR (tem))
3528 if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
3529 f->param_alist = Fcons (XCAR (tem), f->param_alist);
3531 UNGCPRO;
3533 /* Make sure windows on this frame appear in calls to next-window
3534 and similar functions. */
3535 Vwindow_list = Qnil;
3537 return unbind_to (count, frame);
3541 /* FRAME is used only to get a handle on the X display. We don't pass the
3542 display info directly because we're called from frame.c, which doesn't
3543 know about that structure. */
3545 Lisp_Object
3546 x_get_focus_frame (struct frame *frame)
3548 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (frame);
3549 Lisp_Object xfocus;
3550 if (! dpyinfo->x_focus_frame)
3551 return Qnil;
3553 XSETFRAME (xfocus, dpyinfo->x_focus_frame);
3554 return xfocus;
3558 /* In certain situations, when the window manager follows a
3559 click-to-focus policy, there seems to be no way around calling
3560 XSetInputFocus to give another frame the input focus .
3562 In an ideal world, XSetInputFocus should generally be avoided so
3563 that applications don't interfere with the window manager's focus
3564 policy. But I think it's okay to use when it's clearly done
3565 following a user-command. */
3567 DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
3568 doc: /* Set the input focus to FRAME.
3569 FRAME nil means use the selected frame. */)
3570 (Lisp_Object frame)
3572 struct frame *f = check_x_frame (frame);
3573 Display *dpy = FRAME_X_DISPLAY (f);
3575 BLOCK_INPUT;
3576 x_catch_errors (dpy);
3577 XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3578 RevertToParent, CurrentTime);
3579 x_ewmh_activate_frame (f);
3580 x_uncatch_errors ();
3581 UNBLOCK_INPUT;
3583 return Qnil;
3587 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
3588 doc: /* Internal function called by `color-defined-p', which see. */)
3589 (Lisp_Object color, Lisp_Object frame)
3591 XColor foo;
3592 FRAME_PTR f = check_x_frame (frame);
3594 CHECK_STRING (color);
3596 if (x_defined_color (f, SDATA (color), &foo, 0))
3597 return Qt;
3598 else
3599 return Qnil;
3602 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
3603 doc: /* Internal function called by `color-values', which see. */)
3604 (Lisp_Object color, Lisp_Object frame)
3606 XColor foo;
3607 FRAME_PTR f = check_x_frame (frame);
3609 CHECK_STRING (color);
3611 if (x_defined_color (f, SDATA (color), &foo, 0))
3612 return list3 (make_number (foo.red),
3613 make_number (foo.green),
3614 make_number (foo.blue));
3615 else
3616 return Qnil;
3619 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
3620 doc: /* Internal function called by `display-color-p', which see. */)
3621 (Lisp_Object terminal)
3623 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3625 if (dpyinfo->n_planes <= 2)
3626 return Qnil;
3628 switch (dpyinfo->visual->class)
3630 case StaticColor:
3631 case PseudoColor:
3632 case TrueColor:
3633 case DirectColor:
3634 return Qt;
3636 default:
3637 return Qnil;
3641 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
3642 0, 1, 0,
3643 doc: /* Return t if the X display supports shades of gray.
3644 Note that color displays do support shades of gray.
3645 The optional argument TERMINAL specifies which display to ask about.
3646 TERMINAL should be a terminal object, a frame or a display name (a string).
3647 If omitted or nil, that stands for the selected frame's display. */)
3648 (Lisp_Object terminal)
3650 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3652 if (dpyinfo->n_planes <= 1)
3653 return Qnil;
3655 switch (dpyinfo->visual->class)
3657 case StaticColor:
3658 case PseudoColor:
3659 case TrueColor:
3660 case DirectColor:
3661 case StaticGray:
3662 case GrayScale:
3663 return Qt;
3665 default:
3666 return Qnil;
3670 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
3671 0, 1, 0,
3672 doc: /* Return the width in pixels of the X display TERMINAL.
3673 The optional argument TERMINAL specifies which display to ask about.
3674 TERMINAL should be a terminal object, a frame or a display name (a string).
3675 If omitted or nil, that stands for the selected frame's display. */)
3676 (Lisp_Object terminal)
3678 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3680 return make_number (x_display_pixel_width (dpyinfo));
3683 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
3684 Sx_display_pixel_height, 0, 1, 0,
3685 doc: /* Return the height in pixels of the X display TERMINAL.
3686 The optional argument TERMINAL specifies which display to ask about.
3687 TERMINAL should be a terminal object, a frame or a display name (a string).
3688 If omitted or nil, that stands for the selected frame's display. */)
3689 (Lisp_Object terminal)
3691 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3693 return make_number (x_display_pixel_height (dpyinfo));
3696 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
3697 0, 1, 0,
3698 doc: /* Return the number of bitplanes of the X display TERMINAL.
3699 The optional argument TERMINAL specifies which display to ask about.
3700 TERMINAL should be a terminal object, a frame or a display name (a string).
3701 If omitted or nil, that stands for the selected frame's display. */)
3702 (Lisp_Object terminal)
3704 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3706 return make_number (dpyinfo->n_planes);
3709 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
3710 0, 1, 0,
3711 doc: /* Return the number of color cells of the X display TERMINAL.
3712 The optional argument TERMINAL specifies which display to ask about.
3713 TERMINAL should be a terminal object, a frame or a display name (a string).
3714 If omitted or nil, that stands for the selected frame's display. */)
3715 (Lisp_Object terminal)
3717 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3719 int nr_planes = DisplayPlanes (dpyinfo->display,
3720 XScreenNumberOfScreen (dpyinfo->screen));
3722 /* Truncate nr_planes to 24 to avoid integer overflow.
3723 Some displays says 32, but only 24 bits are actually significant.
3724 There are only very few and rare video cards that have more than
3725 24 significant bits. Also 24 bits is more than 16 million colors,
3726 it "should be enough for everyone". */
3727 if (nr_planes > 24) nr_planes = 24;
3729 return make_number (1 << nr_planes);
3732 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
3733 Sx_server_max_request_size,
3734 0, 1, 0,
3735 doc: /* Return the maximum request size of the X server of display TERMINAL.
3736 The optional argument TERMINAL specifies which display to ask about.
3737 TERMINAL should be a terminal object, a frame or a display name (a string).
3738 If omitted or nil, that stands for the selected frame's display. */)
3739 (Lisp_Object terminal)
3741 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3743 return make_number (MAXREQUEST (dpyinfo->display));
3746 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
3747 doc: /* Return the "vendor ID" string of the X server of display TERMINAL.
3748 \(Labelling every distributor as a "vendor" embodies the false assumption
3749 that operating systems cannot be developed and distributed noncommercially.)
3750 The optional argument TERMINAL specifies which display to ask about.
3751 TERMINAL should be a terminal object, a frame or a display name (a string).
3752 If omitted or nil, that stands for the selected frame's display. */)
3753 (Lisp_Object terminal)
3755 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3756 const char *vendor = ServerVendor (dpyinfo->display);
3758 if (! vendor) vendor = "";
3759 return build_string (vendor);
3762 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
3763 doc: /* Return the version numbers of the X server of display TERMINAL.
3764 The value is a list of three integers: the major and minor
3765 version numbers of the X Protocol in use, and the distributor-specific release
3766 number. See also the function `x-server-vendor'.
3768 The optional argument TERMINAL specifies which display to ask about.
3769 TERMINAL should be a terminal object, a frame or a display name (a string).
3770 If omitted or nil, that stands for the selected frame's display. */)
3771 (Lisp_Object terminal)
3773 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3774 Display *dpy = dpyinfo->display;
3776 return Fcons (make_number (ProtocolVersion (dpy)),
3777 Fcons (make_number (ProtocolRevision (dpy)),
3778 Fcons (make_number (VendorRelease (dpy)), Qnil)));
3781 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
3782 doc: /* Return the number of screens on the X server of display TERMINAL.
3783 The optional argument TERMINAL specifies which display to ask about.
3784 TERMINAL should be a terminal object, a frame or a display name (a string).
3785 If omitted or nil, that stands for the selected frame's display. */)
3786 (Lisp_Object terminal)
3788 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3790 return make_number (ScreenCount (dpyinfo->display));
3793 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
3794 doc: /* Return the height in millimeters of the X display TERMINAL.
3795 The optional argument TERMINAL specifies which display to ask about.
3796 TERMINAL should be a terminal object, a frame or a display name (a string).
3797 If omitted or nil, that stands for the selected frame's display. */)
3798 (Lisp_Object terminal)
3800 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3802 return make_number (HeightMMOfScreen (dpyinfo->screen));
3805 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
3806 doc: /* Return the width in millimeters of the X display TERMINAL.
3807 The optional argument TERMINAL specifies which display to ask about.
3808 TERMINAL should be a terminal object, a frame or a display name (a string).
3809 If omitted or nil, that stands for the selected frame's display. */)
3810 (Lisp_Object terminal)
3812 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3814 return make_number (WidthMMOfScreen (dpyinfo->screen));
3817 DEFUN ("x-display-backing-store", Fx_display_backing_store,
3818 Sx_display_backing_store, 0, 1, 0,
3819 doc: /* Return an indication of whether X display TERMINAL does backing store.
3820 The value may be `always', `when-mapped', or `not-useful'.
3821 The optional argument TERMINAL specifies which display to ask about.
3822 TERMINAL should be a terminal object, a frame or a display name (a string).
3823 If omitted or nil, that stands for the selected frame's display. */)
3824 (Lisp_Object terminal)
3826 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3827 Lisp_Object result;
3829 switch (DoesBackingStore (dpyinfo->screen))
3831 case Always:
3832 result = intern ("always");
3833 break;
3835 case WhenMapped:
3836 result = intern ("when-mapped");
3837 break;
3839 case NotUseful:
3840 result = intern ("not-useful");
3841 break;
3843 default:
3844 error ("Strange value for BackingStore parameter of screen");
3845 result = Qnil;
3848 return result;
3851 DEFUN ("x-display-visual-class", Fx_display_visual_class,
3852 Sx_display_visual_class, 0, 1, 0,
3853 doc: /* Return the visual class of the X display TERMINAL.
3854 The value is one of the symbols `static-gray', `gray-scale',
3855 `static-color', `pseudo-color', `true-color', or `direct-color'.
3857 The optional argument TERMINAL specifies which display to ask about.
3858 TERMINAL should a terminal object, a frame or a display name (a string).
3859 If omitted or nil, that stands for the selected frame's display. */)
3860 (Lisp_Object terminal)
3862 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3863 Lisp_Object result;
3865 switch (dpyinfo->visual->class)
3867 case StaticGray:
3868 result = intern ("static-gray");
3869 break;
3870 case GrayScale:
3871 result = intern ("gray-scale");
3872 break;
3873 case StaticColor:
3874 result = intern ("static-color");
3875 break;
3876 case PseudoColor:
3877 result = intern ("pseudo-color");
3878 break;
3879 case TrueColor:
3880 result = intern ("true-color");
3881 break;
3882 case DirectColor:
3883 result = intern ("direct-color");
3884 break;
3885 default:
3886 error ("Display has an unknown visual class");
3887 result = Qnil;
3890 return result;
3893 DEFUN ("x-display-save-under", Fx_display_save_under,
3894 Sx_display_save_under, 0, 1, 0,
3895 doc: /* Return t if the X display TERMINAL supports the save-under feature.
3896 The optional argument TERMINAL specifies which display to ask about.
3897 TERMINAL should be a terminal object, a frame or a display name (a string).
3898 If omitted or nil, that stands for the selected frame's display. */)
3899 (Lisp_Object terminal)
3901 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3903 if (DoesSaveUnders (dpyinfo->screen) == True)
3904 return Qt;
3905 else
3906 return Qnil;
3910 x_pixel_width (register struct frame *f)
3912 return FRAME_PIXEL_WIDTH (f);
3916 x_pixel_height (register struct frame *f)
3918 return FRAME_PIXEL_HEIGHT (f);
3922 x_char_width (register struct frame *f)
3924 return FRAME_COLUMN_WIDTH (f);
3928 x_char_height (register struct frame *f)
3930 return FRAME_LINE_HEIGHT (f);
3934 x_screen_planes (register struct frame *f)
3936 return FRAME_X_DISPLAY_INFO (f)->n_planes;
3941 /************************************************************************
3942 X Displays
3943 ************************************************************************/
3946 /* Mapping visual names to visuals. */
3948 static struct visual_class
3950 const char *name;
3951 int class;
3953 visual_classes[] =
3955 {"StaticGray", StaticGray},
3956 {"GrayScale", GrayScale},
3957 {"StaticColor", StaticColor},
3958 {"PseudoColor", PseudoColor},
3959 {"TrueColor", TrueColor},
3960 {"DirectColor", DirectColor},
3961 {NULL, 0}
3965 #ifndef HAVE_XSCREENNUMBEROFSCREEN
3967 /* Value is the screen number of screen SCR. This is a substitute for
3968 the X function with the same name when that doesn't exist. */
3971 XScreenNumberOfScreen (scr)
3972 register Screen *scr;
3974 Display *dpy = scr->display;
3975 int i;
3977 for (i = 0; i < dpy->nscreens; ++i)
3978 if (scr == dpy->screens + i)
3979 break;
3981 return i;
3984 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
3987 /* Select the visual that should be used on display DPYINFO. Set
3988 members of DPYINFO appropriately. Called from x_term_init. */
3990 void
3991 select_visual (struct x_display_info *dpyinfo)
3993 Display *dpy = dpyinfo->display;
3994 Screen *screen = dpyinfo->screen;
3995 Lisp_Object value;
3997 /* See if a visual is specified. */
3998 value = display_x_get_resource (dpyinfo,
3999 build_string ("visualClass"),
4000 build_string ("VisualClass"),
4001 Qnil, Qnil);
4002 if (STRINGP (value))
4004 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
4005 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
4006 depth, a decimal number. NAME is compared with case ignored. */
4007 char *s = (char *) alloca (SBYTES (value) + 1);
4008 char *dash;
4009 int i, class = -1;
4010 XVisualInfo vinfo;
4012 strcpy (s, SDATA (value));
4013 dash = strchr (s, '-');
4014 if (dash)
4016 dpyinfo->n_planes = atoi (dash + 1);
4017 *dash = '\0';
4019 else
4020 /* We won't find a matching visual with depth 0, so that
4021 an error will be printed below. */
4022 dpyinfo->n_planes = 0;
4024 /* Determine the visual class. */
4025 for (i = 0; visual_classes[i].name; ++i)
4026 if (xstrcasecmp (s, visual_classes[i].name) == 0)
4028 class = visual_classes[i].class;
4029 break;
4032 /* Look up a matching visual for the specified class. */
4033 if (class == -1
4034 || !XMatchVisualInfo (dpy, XScreenNumberOfScreen (screen),
4035 dpyinfo->n_planes, class, &vinfo))
4036 fatal ("Invalid visual specification `%s'", SDATA (value));
4038 dpyinfo->visual = vinfo.visual;
4040 else
4042 int n_visuals;
4043 XVisualInfo *vinfo, vinfo_template;
4045 dpyinfo->visual = DefaultVisualOfScreen (screen);
4047 vinfo_template.visualid = XVisualIDFromVisual (dpyinfo->visual);
4048 vinfo_template.screen = XScreenNumberOfScreen (screen);
4049 vinfo = XGetVisualInfo (dpy, VisualIDMask | VisualScreenMask,
4050 &vinfo_template, &n_visuals);
4051 if (n_visuals <= 0)
4052 fatal ("Can't get proper X visual info");
4054 dpyinfo->n_planes = vinfo->depth;
4055 XFree ((char *) vinfo);
4060 /* Return the X display structure for the display named NAME.
4061 Open a new connection if necessary. */
4063 struct x_display_info *
4064 x_display_info_for_name (Lisp_Object name)
4066 Lisp_Object names;
4067 struct x_display_info *dpyinfo;
4069 CHECK_STRING (name);
4071 #if 0
4072 if (! EQ (Vinitial_window_system, intern ("x")))
4073 error ("Not using X Windows"); /* That doesn't stop us anymore. */
4074 #endif
4076 for (dpyinfo = x_display_list, names = x_display_name_list;
4077 dpyinfo;
4078 dpyinfo = dpyinfo->next, names = XCDR (names))
4080 Lisp_Object tem;
4081 tem = Fstring_equal (XCAR (XCAR (names)), name);
4082 if (!NILP (tem))
4083 return dpyinfo;
4086 /* Use this general default value to start with. */
4087 Vx_resource_name = Vinvocation_name;
4089 validate_x_resource_name ();
4091 dpyinfo = x_term_init (name, (char *)0,
4092 (char *) SDATA (Vx_resource_name));
4094 if (dpyinfo == 0)
4095 error ("Cannot connect to X server %s", SDATA (name));
4097 x_in_use = 1;
4098 XSETFASTINT (Vwindow_system_version, 11);
4100 return dpyinfo;
4104 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
4105 1, 3, 0,
4106 doc: /* Open a connection to an X server.
4107 DISPLAY is the name of the display to connect to.
4108 Optional second arg XRM-STRING is a string of resources in xrdb format.
4109 If the optional third arg MUST-SUCCEED is non-nil,
4110 terminate Emacs if we can't open the connection. */)
4111 (Lisp_Object display, Lisp_Object xrm_string, Lisp_Object must_succeed)
4113 unsigned char *xrm_option;
4114 struct x_display_info *dpyinfo;
4116 CHECK_STRING (display);
4117 if (! NILP (xrm_string))
4118 CHECK_STRING (xrm_string);
4120 #if 0
4121 if (! EQ (Vinitial_window_system, intern ("x")))
4122 error ("Not using X Windows"); /* That doesn't stop us anymore. */
4123 #endif
4125 if (! NILP (xrm_string))
4126 xrm_option = (unsigned char *) SDATA (xrm_string);
4127 else
4128 xrm_option = (unsigned char *) 0;
4130 validate_x_resource_name ();
4132 /* This is what opens the connection and sets x_current_display.
4133 This also initializes many symbols, such as those used for input. */
4134 dpyinfo = x_term_init (display, xrm_option,
4135 (char *) SDATA (Vx_resource_name));
4137 if (dpyinfo == 0)
4139 if (!NILP (must_succeed))
4140 fatal ("Cannot connect to X server %s.\n\
4141 Check the DISPLAY environment variable or use `-d'.\n\
4142 Also use the `xauth' program to verify that you have the proper\n\
4143 authorization information needed to connect the X server.\n\
4144 An insecure way to solve the problem may be to use `xhost'.\n",
4145 SDATA (display));
4146 else
4147 error ("Cannot connect to X server %s", SDATA (display));
4150 x_in_use = 1;
4152 XSETFASTINT (Vwindow_system_version, 11);
4153 return Qnil;
4156 DEFUN ("x-close-connection", Fx_close_connection,
4157 Sx_close_connection, 1, 1, 0,
4158 doc: /* Close the connection to TERMINAL's X server.
4159 For TERMINAL, specify a terminal object, a frame or a display name (a
4160 string). If TERMINAL is nil, that stands for the selected frame's
4161 terminal. */)
4162 (Lisp_Object terminal)
4164 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4166 if (dpyinfo->reference_count > 0)
4167 error ("Display still has frames on it");
4169 x_delete_terminal (dpyinfo->terminal);
4171 return Qnil;
4174 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
4175 doc: /* Return the list of display names that Emacs has connections to. */)
4176 (void)
4178 Lisp_Object tail, result;
4180 result = Qnil;
4181 for (tail = x_display_name_list; CONSP (tail); tail = XCDR (tail))
4182 result = Fcons (XCAR (XCAR (tail)), result);
4184 return result;
4187 DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
4188 doc: /* If ON is non-nil, report X errors as soon as the erring request is made.
4189 This function only has an effect on X Windows. With MS Windows, it is
4190 defined but does nothing.
4192 If ON is nil, allow buffering of requests.
4193 Turning on synchronization prohibits the Xlib routines from buffering
4194 requests and seriously degrades performance, but makes debugging much
4195 easier.
4196 The optional second argument TERMINAL specifies which display to act on.
4197 TERMINAL should be a terminal object, a frame or a display name (a string).
4198 If TERMINAL is omitted or nil, that stands for the selected frame's display. */)
4199 (Lisp_Object on, Lisp_Object terminal)
4201 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4203 XSynchronize (dpyinfo->display, !EQ (on, Qnil));
4205 return Qnil;
4208 /* Wait for responses to all X commands issued so far for frame F. */
4210 void
4211 x_sync (FRAME_PTR f)
4213 BLOCK_INPUT;
4214 XSync (FRAME_X_DISPLAY (f), False);
4215 UNBLOCK_INPUT;
4219 /***********************************************************************
4220 Window properties
4221 ***********************************************************************/
4223 DEFUN ("x-change-window-property", Fx_change_window_property,
4224 Sx_change_window_property, 2, 6, 0,
4225 doc: /* Change window property PROP to VALUE on the X window of FRAME.
4226 PROP must be a string. VALUE may be a string or a list of conses,
4227 numbers and/or strings. If an element in the list is a string, it is
4228 converted to an atom and the value of the atom is used. If an element
4229 is a cons, it is converted to a 32 bit number where the car is the 16
4230 top bits and the cdr is the lower 16 bits.
4232 FRAME nil or omitted means use the selected frame.
4233 If TYPE is given and non-nil, it is the name of the type of VALUE.
4234 If TYPE is not given or nil, the type is STRING.
4235 FORMAT gives the size in bits of each element if VALUE is a list.
4236 It must be one of 8, 16 or 32.
4237 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
4238 If OUTER_P is non-nil, the property is changed for the outer X window of
4239 FRAME. Default is to change on the edit X window. */)
4240 (Lisp_Object prop, Lisp_Object value, Lisp_Object frame, Lisp_Object type, Lisp_Object format, Lisp_Object outer_p)
4242 struct frame *f = check_x_frame (frame);
4243 Atom prop_atom;
4244 Atom target_type = XA_STRING;
4245 int element_format = 8;
4246 unsigned char *data;
4247 int nelements;
4248 Window w;
4250 CHECK_STRING (prop);
4252 if (! NILP (format))
4254 CHECK_NUMBER (format);
4255 element_format = XFASTINT (format);
4257 if (element_format != 8 && element_format != 16
4258 && element_format != 32)
4259 error ("FORMAT must be one of 8, 16 or 32");
4262 if (CONSP (value))
4264 nelements = x_check_property_data (value);
4265 if (nelements == -1)
4266 error ("Bad data in VALUE, must be number, string or cons");
4268 if (element_format == 8)
4269 data = (unsigned char *) xmalloc (nelements);
4270 else if (element_format == 16)
4271 data = (unsigned char *) xmalloc (nelements*2);
4272 else /* format == 32 */
4273 /* The man page for XChangeProperty:
4274 "If the specified format is 32, the property data must be a
4275 long array."
4276 This applies even if long is more than 64 bits. The X library
4277 converts to 32 bits before sending to the X server. */
4278 data = (unsigned char *) xmalloc (nelements * sizeof(long));
4280 x_fill_property_data (FRAME_X_DISPLAY (f), value, data, element_format);
4282 else
4284 CHECK_STRING (value);
4285 data = SDATA (value);
4286 nelements = SCHARS (value);
4289 BLOCK_INPUT;
4290 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4291 if (! NILP (type))
4293 CHECK_STRING (type);
4294 target_type = XInternAtom (FRAME_X_DISPLAY (f), SDATA (type), False);
4297 if (! NILP (outer_p)) w = FRAME_OUTER_WINDOW (f);
4298 else w = FRAME_X_WINDOW (f);
4300 XChangeProperty (FRAME_X_DISPLAY (f), w,
4301 prop_atom, target_type, element_format, PropModeReplace,
4302 data, nelements);
4304 if (CONSP (value)) xfree (data);
4306 /* Make sure the property is set when we return. */
4307 XFlush (FRAME_X_DISPLAY (f));
4308 UNBLOCK_INPUT;
4310 return value;
4314 DEFUN ("x-delete-window-property", Fx_delete_window_property,
4315 Sx_delete_window_property, 1, 2, 0,
4316 doc: /* Remove window property PROP from X window of FRAME.
4317 FRAME nil or omitted means use the selected frame. Value is PROP. */)
4318 (Lisp_Object prop, Lisp_Object frame)
4320 struct frame *f = check_x_frame (frame);
4321 Atom prop_atom;
4323 CHECK_STRING (prop);
4324 BLOCK_INPUT;
4325 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4326 XDeleteProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), prop_atom);
4328 /* Make sure the property is removed when we return. */
4329 XFlush (FRAME_X_DISPLAY (f));
4330 UNBLOCK_INPUT;
4332 return prop;
4336 DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
4337 1, 6, 0,
4338 doc: /* Value is the value of window property PROP on FRAME.
4339 If FRAME is nil or omitted, use the selected frame.
4341 On MS Windows, this function only accepts the PROP and FRAME arguments.
4343 On X Windows, the following optional arguments are also accepted:
4344 If TYPE is nil or omitted, get the property as a string.
4345 Otherwise TYPE is the name of the atom that denotes the type expected.
4346 If SOURCE is non-nil, get the property on that window instead of from
4347 FRAME. The number 0 denotes the root window.
4348 If DELETE_P is non-nil, delete the property after retreiving it.
4349 If VECTOR_RET_P is non-nil, don't return a string but a vector of values.
4351 Value is nil if FRAME hasn't a property with name PROP or if PROP has
4352 no value of TYPE (always string in the MS Windows case). */)
4353 (Lisp_Object prop, Lisp_Object frame, Lisp_Object type, Lisp_Object source, Lisp_Object delete_p, Lisp_Object vector_ret_p)
4355 struct frame *f = check_x_frame (frame);
4356 Atom prop_atom;
4357 int rc;
4358 Lisp_Object prop_value = Qnil;
4359 unsigned char *tmp_data = NULL;
4360 Atom actual_type;
4361 Atom target_type = XA_STRING;
4362 int actual_format;
4363 unsigned long actual_size, bytes_remaining;
4364 Window target_window = FRAME_X_WINDOW (f);
4365 struct gcpro gcpro1;
4367 GCPRO1 (prop_value);
4368 CHECK_STRING (prop);
4370 if (! NILP (source))
4372 if (NUMBERP (source))
4374 if (FLOATP (source))
4375 target_window = (Window) XFLOAT (source);
4376 else
4377 target_window = XFASTINT (source);
4379 if (target_window == 0)
4380 target_window = FRAME_X_DISPLAY_INFO (f)->root_window;
4382 else if (CONSP (source))
4383 target_window = cons_to_long (source);
4386 BLOCK_INPUT;
4387 if (STRINGP (type))
4389 if (strcmp ("AnyPropertyType", SDATA (type)) == 0)
4390 target_type = AnyPropertyType;
4391 else
4392 target_type = XInternAtom (FRAME_X_DISPLAY (f), SDATA (type), False);
4395 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4396 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4397 prop_atom, 0, 0, False, target_type,
4398 &actual_type, &actual_format, &actual_size,
4399 &bytes_remaining, &tmp_data);
4400 if (rc == Success)
4402 int size = bytes_remaining;
4404 XFree (tmp_data);
4405 tmp_data = NULL;
4407 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4408 prop_atom, 0, bytes_remaining,
4409 ! NILP (delete_p), target_type,
4410 &actual_type, &actual_format,
4411 &actual_size, &bytes_remaining,
4412 &tmp_data);
4413 if (rc == Success && tmp_data)
4415 /* The man page for XGetWindowProperty says:
4416 "If the returned format is 32, the returned data is represented
4417 as a long array and should be cast to that type to obtain the
4418 elements."
4419 This applies even if long is more than 32 bits, the X library
4420 converts from 32 bit elements received from the X server to long
4421 and passes the long array to us. Thus, for that case memcpy can not
4422 be used. We convert to a 32 bit type here, because so much code
4423 assume on that.
4425 The bytes and offsets passed to XGetWindowProperty refers to the
4426 property and those are indeed in 32 bit quantities if format is
4427 32. */
4429 if (actual_format == 32 && actual_format < BITS_PER_LONG)
4431 unsigned long i;
4432 int *idata = (int *) tmp_data;
4433 long *ldata = (long *) tmp_data;
4435 for (i = 0; i < actual_size; ++i)
4436 idata[i] = (int) ldata[i];
4439 if (NILP (vector_ret_p))
4440 prop_value = make_string (tmp_data, size);
4441 else
4442 prop_value = x_property_data_to_lisp (f,
4443 tmp_data,
4444 actual_type,
4445 actual_format,
4446 actual_size);
4449 if (tmp_data) XFree (tmp_data);
4452 UNBLOCK_INPUT;
4453 UNGCPRO;
4454 return prop_value;
4459 /***********************************************************************
4460 Busy cursor
4461 ***********************************************************************/
4463 /* Timer function of hourglass_atimer. TIMER is equal to
4464 hourglass_atimer.
4466 Display an hourglass pointer on all frames by mapping the frames'
4467 hourglass_window. Set the hourglass_p flag in the frames'
4468 output_data.x structure to indicate that an hourglass cursor is
4469 shown on the frames. */
4471 void
4472 show_hourglass (struct atimer *timer)
4474 /* The timer implementation will cancel this timer automatically
4475 after this function has run. Set hourglass_atimer to null
4476 so that we know the timer doesn't have to be canceled. */
4477 hourglass_atimer = NULL;
4479 if (!hourglass_shown_p)
4481 Lisp_Object rest, frame;
4483 BLOCK_INPUT;
4485 FOR_EACH_FRAME (rest, frame)
4487 struct frame *f = XFRAME (frame);
4489 if (FRAME_LIVE_P (f) && FRAME_X_P (f) && FRAME_X_DISPLAY (f))
4491 Display *dpy = FRAME_X_DISPLAY (f);
4493 #ifdef USE_X_TOOLKIT
4494 if (f->output_data.x->widget)
4495 #else
4496 if (FRAME_OUTER_WINDOW (f))
4497 #endif
4499 f->output_data.x->hourglass_p = 1;
4501 if (!f->output_data.x->hourglass_window)
4503 unsigned long mask = CWCursor;
4504 XSetWindowAttributes attrs;
4505 #ifdef USE_GTK
4506 Window parent = FRAME_X_WINDOW (f);
4507 #else
4508 Window parent = FRAME_OUTER_WINDOW (f);
4509 #endif
4510 attrs.cursor = f->output_data.x->hourglass_cursor;
4512 f->output_data.x->hourglass_window
4513 = XCreateWindow (dpy, parent,
4514 0, 0, 32000, 32000, 0, 0,
4515 InputOnly,
4516 CopyFromParent,
4517 mask, &attrs);
4520 XMapRaised (dpy, f->output_data.x->hourglass_window);
4521 XFlush (dpy);
4526 hourglass_shown_p = 1;
4527 UNBLOCK_INPUT;
4532 /* Hide the hourglass pointer on all frames, if it is currently
4533 shown. */
4535 void
4536 hide_hourglass (void)
4538 if (hourglass_shown_p)
4540 Lisp_Object rest, frame;
4542 BLOCK_INPUT;
4543 FOR_EACH_FRAME (rest, frame)
4545 struct frame *f = XFRAME (frame);
4547 if (FRAME_X_P (f)
4548 /* Watch out for newly created frames. */
4549 && f->output_data.x->hourglass_window)
4551 XUnmapWindow (FRAME_X_DISPLAY (f),
4552 f->output_data.x->hourglass_window);
4553 /* Sync here because XTread_socket looks at the
4554 hourglass_p flag that is reset to zero below. */
4555 XSync (FRAME_X_DISPLAY (f), False);
4556 f->output_data.x->hourglass_p = 0;
4560 hourglass_shown_p = 0;
4561 UNBLOCK_INPUT;
4567 /***********************************************************************
4568 Tool tips
4569 ***********************************************************************/
4571 static Lisp_Object x_create_tip_frame (struct x_display_info *,
4572 Lisp_Object, Lisp_Object);
4573 static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
4574 Lisp_Object, int, int, int *, int *);
4576 /* The frame of a currently visible tooltip. */
4578 Lisp_Object tip_frame;
4580 /* If non-nil, a timer started that hides the last tooltip when it
4581 fires. */
4583 Lisp_Object tip_timer;
4584 Window tip_window;
4586 /* If non-nil, a vector of 3 elements containing the last args
4587 with which x-show-tip was called. See there. */
4589 Lisp_Object last_show_tip_args;
4591 /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
4593 Lisp_Object Vx_max_tooltip_size;
4596 static Lisp_Object
4597 unwind_create_tip_frame (Lisp_Object frame)
4599 Lisp_Object deleted;
4601 deleted = unwind_create_frame (frame);
4602 if (EQ (deleted, Qt))
4604 tip_window = None;
4605 tip_frame = Qnil;
4608 return deleted;
4612 /* Create a frame for a tooltip on the display described by DPYINFO.
4613 PARMS is a list of frame parameters. TEXT is the string to
4614 display in the tip frame. Value is the frame.
4616 Note that functions called here, esp. x_default_parameter can
4617 signal errors, for instance when a specified color name is
4618 undefined. We have to make sure that we're in a consistent state
4619 when this happens. */
4621 static Lisp_Object
4622 x_create_tip_frame (struct x_display_info *dpyinfo,
4623 Lisp_Object parms,
4624 Lisp_Object text)
4626 struct frame *f;
4627 Lisp_Object frame, tem;
4628 Lisp_Object name;
4629 long window_prompting = 0;
4630 int width, height;
4631 int count = SPECPDL_INDEX ();
4632 struct gcpro gcpro1, gcpro2, gcpro3;
4633 int face_change_count_before = face_change_count;
4634 Lisp_Object buffer;
4635 struct buffer *old_buffer;
4637 check_x ();
4639 if (!dpyinfo->terminal->name)
4640 error ("Terminal is not live, can't create new frames on it");
4642 parms = Fcopy_alist (parms);
4644 /* Get the name of the frame to use for resource lookup. */
4645 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
4646 if (!STRINGP (name)
4647 && !EQ (name, Qunbound)
4648 && !NILP (name))
4649 error ("Invalid frame name--not a string or nil");
4651 frame = Qnil;
4652 GCPRO3 (parms, name, frame);
4653 f = make_frame (1);
4654 XSETFRAME (frame, f);
4656 buffer = Fget_buffer_create (build_string (" *tip*"));
4657 Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer, Qnil);
4658 old_buffer = current_buffer;
4659 set_buffer_internal_1 (XBUFFER (buffer));
4660 current_buffer->truncate_lines = Qnil;
4661 specbind (Qinhibit_read_only, Qt);
4662 specbind (Qinhibit_modification_hooks, Qt);
4663 Ferase_buffer ();
4664 Finsert (1, &text);
4665 set_buffer_internal_1 (old_buffer);
4667 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
4668 record_unwind_protect (unwind_create_tip_frame, frame);
4670 f->terminal = dpyinfo->terminal;
4671 f->terminal->reference_count++;
4673 /* By setting the output method, we're essentially saying that
4674 the frame is live, as per FRAME_LIVE_P. If we get a signal
4675 from this point on, x_destroy_window might screw up reference
4676 counts etc. */
4677 f->output_method = output_x_window;
4678 f->output_data.x = (struct x_output *) xmalloc (sizeof (struct x_output));
4679 memset (f->output_data.x, 0, sizeof (struct x_output));
4680 f->output_data.x->icon_bitmap = -1;
4681 FRAME_FONTSET (f) = -1;
4682 f->output_data.x->scroll_bar_foreground_pixel = -1;
4683 f->output_data.x->scroll_bar_background_pixel = -1;
4684 #ifdef USE_TOOLKIT_SCROLL_BARS
4685 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
4686 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
4687 #endif /* USE_TOOLKIT_SCROLL_BARS */
4688 f->icon_name = Qnil;
4689 FRAME_X_DISPLAY_INFO (f) = dpyinfo;
4690 #if GLYPH_DEBUG
4691 image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
4692 dpyinfo_refcount = dpyinfo->reference_count;
4693 #endif /* GLYPH_DEBUG */
4694 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
4695 f->output_data.x->explicit_parent = 0;
4697 /* These colors will be set anyway later, but it's important
4698 to get the color reference counts right, so initialize them! */
4700 Lisp_Object black;
4701 struct gcpro gcpro1;
4703 /* Function x_decode_color can signal an error. Make
4704 sure to initialize color slots so that we won't try
4705 to free colors we haven't allocated. */
4706 FRAME_FOREGROUND_PIXEL (f) = -1;
4707 FRAME_BACKGROUND_PIXEL (f) = -1;
4708 f->output_data.x->cursor_pixel = -1;
4709 f->output_data.x->cursor_foreground_pixel = -1;
4710 f->output_data.x->border_pixel = -1;
4711 f->output_data.x->mouse_pixel = -1;
4713 black = build_string ("black");
4714 GCPRO1 (black);
4715 FRAME_FOREGROUND_PIXEL (f)
4716 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4717 FRAME_BACKGROUND_PIXEL (f)
4718 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4719 f->output_data.x->cursor_pixel
4720 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4721 f->output_data.x->cursor_foreground_pixel
4722 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4723 f->output_data.x->border_pixel
4724 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4725 f->output_data.x->mouse_pixel
4726 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4727 UNGCPRO;
4730 /* Set the name; the functions to which we pass f expect the name to
4731 be set. */
4732 if (EQ (name, Qunbound) || NILP (name))
4734 f->name = build_string (dpyinfo->x_id_name);
4735 f->explicit_name = 0;
4737 else
4739 f->name = name;
4740 f->explicit_name = 1;
4741 /* use the frame's title when getting resources for this frame. */
4742 specbind (Qx_resource_name, name);
4745 f->resx = dpyinfo->resx;
4746 f->resy = dpyinfo->resy;
4748 register_font_driver (&xfont_driver, f);
4749 #ifdef HAVE_FREETYPE
4750 #ifdef HAVE_XFT
4751 register_font_driver (&xftfont_driver, f);
4752 #else /* not HAVE_XFT */
4753 register_font_driver (&ftxfont_driver, f);
4754 #endif /* not HAVE_XFT */
4755 #endif /* HAVE_FREETYPE */
4757 x_default_parameter (f, parms, Qfont_backend, Qnil,
4758 "fontBackend", "FontBackend", RES_TYPE_STRING);
4760 /* Extract the window parameters from the supplied values that are
4761 needed to determine window geometry. */
4762 x_default_font_parameter (f, parms);
4764 x_default_parameter (f, parms, Qborder_width, make_number (0),
4765 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
4767 /* This defaults to 2 in order to match xterm. We recognize either
4768 internalBorderWidth or internalBorder (which is what xterm calls
4769 it). */
4770 if (NILP (Fassq (Qinternal_border_width, parms)))
4772 Lisp_Object value;
4774 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
4775 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
4776 if (! EQ (value, Qunbound))
4777 parms = Fcons (Fcons (Qinternal_border_width, value),
4778 parms);
4781 x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
4782 "internalBorderWidth", "internalBorderWidth",
4783 RES_TYPE_NUMBER);
4785 /* Also do the stuff which must be set before the window exists. */
4786 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
4787 "foreground", "Foreground", RES_TYPE_STRING);
4788 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
4789 "background", "Background", RES_TYPE_STRING);
4790 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
4791 "pointerColor", "Foreground", RES_TYPE_STRING);
4792 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
4793 "cursorColor", "Foreground", RES_TYPE_STRING);
4794 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
4795 "borderColor", "BorderColor", RES_TYPE_STRING);
4797 /* Init faces before x_default_parameter is called for scroll-bar
4798 parameters because that function calls x_set_scroll_bar_width,
4799 which calls change_frame_size, which calls Fset_window_buffer,
4800 which runs hooks, which call Fvertical_motion. At the end, we
4801 end up in init_iterator with a null face cache, which should not
4802 happen. */
4803 init_frame_faces (f);
4805 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
4807 window_prompting = x_figure_window_size (f, parms, 0);
4810 XSetWindowAttributes attrs;
4811 unsigned long mask;
4812 Atom type = FRAME_X_DISPLAY_INFO (f)->Xatom_net_window_type_tooltip;
4814 BLOCK_INPUT;
4815 mask = CWBackPixel | CWOverrideRedirect | CWEventMask;
4816 if (DoesSaveUnders (dpyinfo->screen))
4817 mask |= CWSaveUnder;
4819 /* Window managers look at the override-redirect flag to determine
4820 whether or net to give windows a decoration (Xlib spec, chapter
4821 3.2.8). */
4822 attrs.override_redirect = True;
4823 attrs.save_under = True;
4824 attrs.background_pixel = FRAME_BACKGROUND_PIXEL (f);
4825 /* Arrange for getting MapNotify and UnmapNotify events. */
4826 attrs.event_mask = StructureNotifyMask;
4827 tip_window
4828 = FRAME_X_WINDOW (f)
4829 = XCreateWindow (FRAME_X_DISPLAY (f),
4830 FRAME_X_DISPLAY_INFO (f)->root_window,
4831 /* x, y, width, height */
4832 0, 0, 1, 1,
4833 /* Border. */
4834 f->border_width,
4835 CopyFromParent, InputOutput, CopyFromParent,
4836 mask, &attrs);
4837 XChangeProperty (FRAME_X_DISPLAY (f), tip_window,
4838 FRAME_X_DISPLAY_INFO (f)->Xatom_net_window_type,
4839 XA_ATOM, 32, PropModeReplace,
4840 (unsigned char *)&type, 1);
4841 UNBLOCK_INPUT;
4844 x_make_gc (f);
4846 x_default_parameter (f, parms, Qauto_raise, Qnil,
4847 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
4848 x_default_parameter (f, parms, Qauto_lower, Qnil,
4849 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
4850 x_default_parameter (f, parms, Qcursor_type, Qbox,
4851 "cursorType", "CursorType", RES_TYPE_SYMBOL);
4853 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
4854 Change will not be effected unless different from the current
4855 FRAME_LINES (f). */
4856 width = FRAME_COLS (f);
4857 height = FRAME_LINES (f);
4858 SET_FRAME_COLS (f, 0);
4859 FRAME_LINES (f) = 0;
4860 change_frame_size (f, height, width, 1, 0, 0);
4862 /* Add `tooltip' frame parameter's default value. */
4863 if (NILP (Fframe_parameter (frame, Qtooltip)))
4864 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtooltip, Qt), Qnil));
4866 /* FIXME - can this be done in a similar way to normal frames?
4867 http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
4869 /* Set the `display-type' frame parameter before setting up faces. */
4871 Lisp_Object disptype;
4873 if (FRAME_X_DISPLAY_INFO (f)->n_planes == 1)
4874 disptype = intern ("mono");
4875 else if (FRAME_X_DISPLAY_INFO (f)->visual->class == GrayScale
4876 || FRAME_X_DISPLAY_INFO (f)->visual->class == StaticGray)
4877 disptype = intern ("grayscale");
4878 else
4879 disptype = intern ("color");
4881 if (NILP (Fframe_parameter (frame, Qdisplay_type)))
4882 Fmodify_frame_parameters (frame, Fcons (Fcons (Qdisplay_type, disptype),
4883 Qnil));
4886 /* Set up faces after all frame parameters are known. This call
4887 also merges in face attributes specified for new frames.
4889 Frame parameters may be changed if .Xdefaults contains
4890 specifications for the default font. For example, if there is an
4891 `Emacs.default.attributeBackground: pink', the `background-color'
4892 attribute of the frame get's set, which let's the internal border
4893 of the tooltip frame appear in pink. Prevent this. */
4895 Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
4897 /* Set tip_frame here, so that */
4898 tip_frame = frame;
4899 call2 (Qface_set_after_frame_default, frame, Qnil);
4901 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
4902 Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg),
4903 Qnil));
4906 f->no_split = 1;
4908 UNGCPRO;
4910 /* It is now ok to make the frame official even if we get an error
4911 below. And the frame needs to be on Vframe_list or making it
4912 visible won't work. */
4913 Vframe_list = Fcons (frame, Vframe_list);
4915 /* Now that the frame is official, it counts as a reference to
4916 its display. */
4917 FRAME_X_DISPLAY_INFO (f)->reference_count++;
4919 /* Setting attributes of faces of the tooltip frame from resources
4920 and similar will increment face_change_count, which leads to the
4921 clearing of all current matrices. Since this isn't necessary
4922 here, avoid it by resetting face_change_count to the value it
4923 had before we created the tip frame. */
4924 face_change_count = face_change_count_before;
4926 /* Discard the unwind_protect. */
4927 return unbind_to (count, frame);
4931 /* Compute where to display tip frame F. PARMS is the list of frame
4932 parameters for F. DX and DY are specified offsets from the current
4933 location of the mouse. WIDTH and HEIGHT are the width and height
4934 of the tooltip. Return coordinates relative to the root window of
4935 the display in *ROOT_X, and *ROOT_Y. */
4937 static void
4938 compute_tip_xy (struct frame *f, Lisp_Object parms, Lisp_Object dx, Lisp_Object dy, int width, int height, int *root_x, int *root_y)
4940 Lisp_Object left, top;
4941 int win_x, win_y;
4942 Window root, child;
4943 unsigned pmask;
4945 /* User-specified position? */
4946 left = Fcdr (Fassq (Qleft, parms));
4947 top = Fcdr (Fassq (Qtop, parms));
4949 /* Move the tooltip window where the mouse pointer is. Resize and
4950 show it. */
4951 if (!INTEGERP (left) || !INTEGERP (top))
4953 BLOCK_INPUT;
4954 XQueryPointer (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
4955 &root, &child, root_x, root_y, &win_x, &win_y, &pmask);
4956 UNBLOCK_INPUT;
4959 if (INTEGERP (top))
4960 *root_y = XINT (top);
4961 else if (*root_y + XINT (dy) <= 0)
4962 *root_y = 0; /* Can happen for negative dy */
4963 else if (*root_y + XINT (dy) + height
4964 <= x_display_pixel_height (FRAME_X_DISPLAY_INFO (f)))
4965 /* It fits below the pointer */
4966 *root_y += XINT (dy);
4967 else if (height + XINT (dy) <= *root_y)
4968 /* It fits above the pointer. */
4969 *root_y -= height + XINT (dy);
4970 else
4971 /* Put it on the top. */
4972 *root_y = 0;
4974 if (INTEGERP (left))
4975 *root_x = XINT (left);
4976 else if (*root_x + XINT (dx) <= 0)
4977 *root_x = 0; /* Can happen for negative dx */
4978 else if (*root_x + XINT (dx) + width
4979 <= x_display_pixel_width (FRAME_X_DISPLAY_INFO (f)))
4980 /* It fits to the right of the pointer. */
4981 *root_x += XINT (dx);
4982 else if (width + XINT (dx) <= *root_x)
4983 /* It fits to the left of the pointer. */
4984 *root_x -= width + XINT (dx);
4985 else
4986 /* Put it left-justified on the screen--it ought to fit that way. */
4987 *root_x = 0;
4991 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
4992 doc: /* Show STRING in a "tooltip" window on frame FRAME.
4993 A tooltip window is a small X window displaying a string.
4995 This is an internal function; Lisp code should call `tooltip-show'.
4997 FRAME nil or omitted means use the selected frame.
4999 PARMS is an optional list of frame parameters which can be used to
5000 change the tooltip's appearance.
5002 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
5003 means use the default timeout of 5 seconds.
5005 If the list of frame parameters PARAMS contains a `left' parameters,
5006 the tooltip is displayed at that x-position. Otherwise it is
5007 displayed at the mouse position, with offset DX added (default is 5 if
5008 DX isn't specified). Likewise for the y-position; if a `top' frame
5009 parameter is specified, it determines the y-position of the tooltip
5010 window, otherwise it is displayed at the mouse position, with offset
5011 DY added (default is -10).
5013 A tooltip's maximum size is specified by `x-max-tooltip-size'.
5014 Text larger than the specified size is clipped. */)
5015 (Lisp_Object string, Lisp_Object frame, Lisp_Object parms, Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy)
5017 struct frame *f;
5018 struct window *w;
5019 int root_x, root_y;
5020 struct buffer *old_buffer;
5021 struct text_pos pos;
5022 int i, width, height;
5023 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
5024 int old_windows_or_buffers_changed = windows_or_buffers_changed;
5025 int count = SPECPDL_INDEX ();
5027 specbind (Qinhibit_redisplay, Qt);
5029 GCPRO4 (string, parms, frame, timeout);
5031 CHECK_STRING (string);
5032 if (SCHARS (string) == 0)
5033 string = make_unibyte_string (" ", 1);
5035 f = check_x_frame (frame);
5036 if (NILP (timeout))
5037 timeout = make_number (5);
5038 else
5039 CHECK_NATNUM (timeout);
5041 if (NILP (dx))
5042 dx = make_number (5);
5043 else
5044 CHECK_NUMBER (dx);
5046 if (NILP (dy))
5047 dy = make_number (-10);
5048 else
5049 CHECK_NUMBER (dy);
5051 #ifdef USE_GTK
5052 if (x_gtk_use_system_tooltips)
5054 int ok;
5056 /* Hide a previous tip, if any. */
5057 Fx_hide_tip ();
5059 BLOCK_INPUT;
5060 if ((ok = xg_prepare_tooltip (f, string, &width, &height)) != 0)
5062 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
5063 xg_show_tooltip (f, root_x, root_y);
5064 /* This is used in Fx_hide_tip. */
5065 XSETFRAME (tip_frame, f);
5067 UNBLOCK_INPUT;
5068 if (ok) goto start_timer;
5070 #endif /* USE_GTK */
5072 if (NILP (last_show_tip_args))
5073 last_show_tip_args = Fmake_vector (make_number (3), Qnil);
5075 if (!NILP (tip_frame))
5077 Lisp_Object last_string = AREF (last_show_tip_args, 0);
5078 Lisp_Object last_frame = AREF (last_show_tip_args, 1);
5079 Lisp_Object last_parms = AREF (last_show_tip_args, 2);
5081 if (EQ (frame, last_frame)
5082 && !NILP (Fequal (last_string, string))
5083 && !NILP (Fequal (last_parms, parms)))
5085 struct frame *f = XFRAME (tip_frame);
5087 /* Only DX and DY have changed. */
5088 if (!NILP (tip_timer))
5090 Lisp_Object timer = tip_timer;
5091 tip_timer = Qnil;
5092 call1 (Qcancel_timer, timer);
5095 BLOCK_INPUT;
5096 compute_tip_xy (f, parms, dx, dy, FRAME_PIXEL_WIDTH (f),
5097 FRAME_PIXEL_HEIGHT (f), &root_x, &root_y);
5098 XMoveWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5099 root_x, root_y);
5100 UNBLOCK_INPUT;
5101 goto start_timer;
5105 /* Hide a previous tip, if any. */
5106 Fx_hide_tip ();
5108 ASET (last_show_tip_args, 0, string);
5109 ASET (last_show_tip_args, 1, frame);
5110 ASET (last_show_tip_args, 2, parms);
5112 /* Add default values to frame parameters. */
5113 if (NILP (Fassq (Qname, parms)))
5114 parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
5115 if (NILP (Fassq (Qinternal_border_width, parms)))
5116 parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
5117 if (NILP (Fassq (Qborder_width, parms)))
5118 parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
5119 if (NILP (Fassq (Qborder_color, parms)))
5120 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
5121 if (NILP (Fassq (Qbackground_color, parms)))
5122 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
5123 parms);
5125 /* Create a frame for the tooltip, and record it in the global
5126 variable tip_frame. */
5127 frame = x_create_tip_frame (FRAME_X_DISPLAY_INFO (f), parms, string);
5128 f = XFRAME (frame);
5130 /* Set up the frame's root window. */
5131 w = XWINDOW (FRAME_ROOT_WINDOW (f));
5132 w->left_col = w->top_line = make_number (0);
5134 if (CONSP (Vx_max_tooltip_size)
5135 && INTEGERP (XCAR (Vx_max_tooltip_size))
5136 && XINT (XCAR (Vx_max_tooltip_size)) > 0
5137 && INTEGERP (XCDR (Vx_max_tooltip_size))
5138 && XINT (XCDR (Vx_max_tooltip_size)) > 0)
5140 w->total_cols = XCAR (Vx_max_tooltip_size);
5141 w->total_lines = XCDR (Vx_max_tooltip_size);
5143 else
5145 w->total_cols = make_number (80);
5146 w->total_lines = make_number (40);
5149 FRAME_TOTAL_COLS (f) = XINT (w->total_cols);
5150 adjust_glyphs (f);
5151 w->pseudo_window_p = 1;
5153 /* Display the tooltip text in a temporary buffer. */
5154 old_buffer = current_buffer;
5155 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer));
5156 current_buffer->truncate_lines = Qnil;
5157 clear_glyph_matrix (w->desired_matrix);
5158 clear_glyph_matrix (w->current_matrix);
5159 SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
5160 try_window (FRAME_ROOT_WINDOW (f), pos, TRY_WINDOW_IGNORE_FONTS_CHANGE);
5162 /* Compute width and height of the tooltip. */
5163 width = height = 0;
5164 for (i = 0; i < w->desired_matrix->nrows; ++i)
5166 struct glyph_row *row = &w->desired_matrix->rows[i];
5167 struct glyph *last;
5168 int row_width;
5170 /* Stop at the first empty row at the end. */
5171 if (!row->enabled_p || !row->displays_text_p)
5172 break;
5174 /* Let the row go over the full width of the frame. */
5175 row->full_width_p = 1;
5177 row_width = row->pixel_width;
5178 /* There's a glyph at the end of rows that is used to place
5179 the cursor there. Don't include the width of this glyph. */
5180 if (row->used[TEXT_AREA])
5182 last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
5183 if (INTEGERP (last->object))
5184 row_width -= last->pixel_width;
5187 height += row->height;
5188 width = max (width, row_width);
5191 /* Add the frame's internal border to the width and height the X
5192 window should have. */
5193 height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5194 width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5196 /* Move the tooltip window where the mouse pointer is. Resize and
5197 show it. */
5198 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
5200 BLOCK_INPUT;
5201 XMoveResizeWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5202 root_x, root_y, width, height);
5203 XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
5204 UNBLOCK_INPUT;
5206 /* Draw into the window. */
5207 w->must_be_updated_p = 1;
5208 update_single_window (w, 1);
5210 /* Restore original current buffer. */
5211 set_buffer_internal_1 (old_buffer);
5212 windows_or_buffers_changed = old_windows_or_buffers_changed;
5214 start_timer:
5215 /* Let the tip disappear after timeout seconds. */
5216 tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
5217 intern ("x-hide-tip"));
5219 UNGCPRO;
5220 return unbind_to (count, Qnil);
5224 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
5225 doc: /* Hide the current tooltip window, if there is any.
5226 Value is t if tooltip was open, nil otherwise. */)
5227 (void)
5229 int count;
5230 Lisp_Object deleted, frame, timer;
5231 struct gcpro gcpro1, gcpro2;
5232 struct frame *f;
5234 /* Return quickly if nothing to do. */
5235 if (NILP (tip_timer) && NILP (tip_frame))
5236 return Qnil;
5238 frame = tip_frame;
5239 timer = tip_timer;
5240 GCPRO2 (frame, timer);
5241 tip_frame = tip_timer = deleted = Qnil;
5243 count = SPECPDL_INDEX ();
5244 specbind (Qinhibit_redisplay, Qt);
5245 specbind (Qinhibit_quit, Qt);
5247 if (!NILP (timer))
5248 call1 (Qcancel_timer, timer);
5250 #ifdef USE_GTK
5251 /* When using system tooltip, tip_frame is the Emacs frame on which
5252 the tip is shown. */
5253 f = XFRAME (frame);
5254 if (FRAME_LIVE_P (f) && xg_hide_tooltip (f))
5255 frame = Qnil;
5256 #endif
5258 if (FRAMEP (frame))
5260 delete_frame (frame, Qnil);
5261 deleted = Qt;
5263 #ifdef USE_LUCID
5264 /* Bloodcurdling hack alert: The Lucid menu bar widget's
5265 redisplay procedure is not called when a tip frame over menu
5266 items is unmapped. Redisplay the menu manually... */
5268 Widget w;
5269 f = SELECTED_FRAME ();
5270 w = f->output_data.x->menubar_widget;
5272 if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f)->screen)
5273 && w != NULL)
5275 BLOCK_INPUT;
5276 xlwmenu_redisplay (w);
5277 UNBLOCK_INPUT;
5280 #endif /* USE_LUCID */
5283 UNGCPRO;
5284 return unbind_to (count, deleted);
5289 /***********************************************************************
5290 File selection dialog
5291 ***********************************************************************/
5293 DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog,
5294 Sx_uses_old_gtk_dialog,
5295 0, 0, 0,
5296 doc: /* Return t if the old Gtk+ file selection dialog is used. */)
5297 (void)
5299 #ifdef USE_GTK
5300 if (use_dialog_box
5301 && use_file_dialog
5302 && have_menus_p ()
5303 && xg_uses_old_file_dialog ())
5304 return Qt;
5305 #endif
5306 return Qnil;
5310 #ifdef USE_MOTIF
5311 /* Callback for "OK" and "Cancel" on file selection dialog. */
5313 static void
5314 file_dialog_cb (Widget widget, XtPointer client_data, XtPointer call_data)
5316 int *result = (int *) client_data;
5317 XmAnyCallbackStruct *cb = (XmAnyCallbackStruct *) call_data;
5318 *result = cb->reason;
5322 /* Callback for unmapping a file selection dialog. This is used to
5323 capture the case where a dialog is closed via a window manager's
5324 closer button, for example. Using a XmNdestroyCallback didn't work
5325 in this case. */
5327 static void
5328 file_dialog_unmap_cb (Widget widget, XtPointer client_data, XtPointer call_data)
5330 int *result = (int *) client_data;
5331 *result = XmCR_CANCEL;
5334 static Lisp_Object
5335 clean_up_file_dialog (Lisp_Object arg)
5337 struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
5338 Widget dialog = (Widget) p->pointer;
5340 /* Clean up. */
5341 BLOCK_INPUT;
5342 XtUnmanageChild (dialog);
5343 XtDestroyWidget (dialog);
5344 x_menu_set_in_use (0);
5345 UNBLOCK_INPUT;
5347 return Qnil;
5351 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5352 doc: /* Read file name, prompting with PROMPT in directory DIR.
5353 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5354 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5355 or directory must exist.
5357 This function is only defined on MS Windows, and X Windows with the
5358 Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
5359 Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */)
5360 (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p)
5362 int result;
5363 struct frame *f = SELECTED_FRAME ();
5364 Lisp_Object file = Qnil;
5365 Lisp_Object decoded_file;
5366 Widget dialog, text, help;
5367 Arg al[10];
5368 int ac = 0;
5369 XmString dir_xmstring, pattern_xmstring;
5370 int count = SPECPDL_INDEX ();
5371 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5373 check_x ();
5375 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5377 if (popup_activated ())
5378 error ("Trying to use a menu from within a menu-entry");
5380 CHECK_STRING (prompt);
5381 CHECK_STRING (dir);
5383 /* Prevent redisplay. */
5384 specbind (Qinhibit_redisplay, Qt);
5386 BLOCK_INPUT;
5388 /* Create the dialog with PROMPT as title, using DIR as initial
5389 directory and using "*" as pattern. */
5390 dir = Fexpand_file_name (dir, Qnil);
5391 dir_xmstring = XmStringCreateLocalized (SDATA (dir));
5392 pattern_xmstring = XmStringCreateLocalized ("*");
5394 XtSetArg (al[ac], XmNtitle, SDATA (prompt)); ++ac;
5395 XtSetArg (al[ac], XmNdirectory, dir_xmstring); ++ac;
5396 XtSetArg (al[ac], XmNpattern, pattern_xmstring); ++ac;
5397 XtSetArg (al[ac], XmNresizePolicy, XmRESIZE_GROW); ++ac;
5398 XtSetArg (al[ac], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); ++ac;
5399 dialog = XmCreateFileSelectionDialog (f->output_data.x->widget,
5400 "fsb", al, ac);
5401 XmStringFree (dir_xmstring);
5402 XmStringFree (pattern_xmstring);
5404 /* Add callbacks for OK and Cancel. */
5405 XtAddCallback (dialog, XmNokCallback, file_dialog_cb,
5406 (XtPointer) &result);
5407 XtAddCallback (dialog, XmNcancelCallback, file_dialog_cb,
5408 (XtPointer) &result);
5409 XtAddCallback (dialog, XmNunmapCallback, file_dialog_unmap_cb,
5410 (XtPointer) &result);
5412 /* Remove the help button since we can't display help. */
5413 help = XmFileSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON);
5414 XtUnmanageChild (help);
5416 /* Mark OK button as default. */
5417 XtVaSetValues (XmFileSelectionBoxGetChild (dialog, XmDIALOG_OK_BUTTON),
5418 XmNshowAsDefault, True, NULL);
5420 /* If MUSTMATCH is non-nil, disable the file entry field of the
5421 dialog, so that the user must select a file from the files list
5422 box. We can't remove it because we wouldn't have a way to get at
5423 the result file name, then. */
5424 text = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5425 if (!NILP (mustmatch))
5427 Widget label;
5428 label = XmFileSelectionBoxGetChild (dialog, XmDIALOG_SELECTION_LABEL);
5429 XtSetSensitive (text, False);
5430 XtSetSensitive (label, False);
5433 /* Manage the dialog, so that list boxes get filled. */
5434 XtManageChild (dialog);
5436 if (STRINGP (default_filename))
5438 XmString default_xmstring;
5439 Widget wtext = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5440 Widget list = XmFileSelectionBoxGetChild (dialog, XmDIALOG_LIST);
5442 XmTextPosition last_pos = XmTextFieldGetLastPosition (wtext);
5443 XmTextFieldReplace (wtext, 0, last_pos,
5444 (SDATA (Ffile_name_nondirectory (default_filename))));
5446 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
5447 must include the path for this to work. */
5449 default_xmstring = XmStringCreateLocalized (SDATA (default_filename));
5451 if (XmListItemExists (list, default_xmstring))
5453 int item_pos = XmListItemPos (list, default_xmstring);
5454 /* Select the item and scroll it into view. */
5455 XmListSelectPos (list, item_pos, True);
5456 XmListSetPos (list, item_pos);
5459 XmStringFree (default_xmstring);
5462 record_unwind_protect (clean_up_file_dialog, make_save_value (dialog, 0));
5464 /* Process events until the user presses Cancel or OK. */
5465 x_menu_set_in_use (1);
5466 result = 0;
5467 while (result == 0)
5469 XEvent event;
5470 x_menu_wait_for_event (0);
5471 XtAppNextEvent (Xt_app_con, &event);
5472 if (event.type == KeyPress
5473 && FRAME_X_DISPLAY (f) == event.xkey.display)
5475 KeySym keysym = XLookupKeysym (&event.xkey, 0);
5477 /* Pop down on C-g. */
5478 if (keysym == XK_g && (event.xkey.state & ControlMask) != 0)
5479 XtUnmanageChild (dialog);
5482 (void) x_dispatch_event (&event, FRAME_X_DISPLAY (f));
5485 /* Get the result. */
5486 if (result == XmCR_OK)
5488 XmString text;
5489 String data;
5491 XtVaGetValues (dialog, XmNtextString, &text, NULL);
5492 XmStringGetLtoR (text, XmFONTLIST_DEFAULT_TAG, &data);
5493 XmStringFree (text);
5494 file = build_string (data);
5495 XtFree (data);
5497 else
5498 file = Qnil;
5500 UNBLOCK_INPUT;
5501 UNGCPRO;
5503 /* Make "Cancel" equivalent to C-g. */
5504 if (NILP (file))
5505 Fsignal (Qquit, Qnil);
5507 decoded_file = DECODE_FILE (file);
5509 return unbind_to (count, decoded_file);
5512 #endif /* USE_MOTIF */
5514 #ifdef USE_GTK
5516 static Lisp_Object
5517 clean_up_dialog (Lisp_Object arg)
5519 x_menu_set_in_use (0);
5521 return Qnil;
5524 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5525 doc: /* Read file name, prompting with PROMPT in directory DIR.
5526 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5527 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5528 or directory must exist.
5530 This function is only defined on MS Windows, and X Windows with the
5531 Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
5532 Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */)
5533 (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p)
5535 FRAME_PTR f = SELECTED_FRAME ();
5536 char *fn;
5537 Lisp_Object file = Qnil;
5538 Lisp_Object decoded_file;
5539 int count = SPECPDL_INDEX ();
5540 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5541 char *cdef_file;
5543 check_x ();
5545 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5547 if (popup_activated ())
5548 error ("Trying to use a menu from within a menu-entry");
5550 CHECK_STRING (prompt);
5551 CHECK_STRING (dir);
5553 /* Prevent redisplay. */
5554 specbind (Qinhibit_redisplay, Qt);
5555 record_unwind_protect (clean_up_dialog, Qnil);
5557 BLOCK_INPUT;
5559 if (STRINGP (default_filename))
5560 cdef_file = SDATA (default_filename);
5561 else
5562 cdef_file = SDATA (dir);
5564 fn = xg_get_file_name (f, SDATA (prompt), cdef_file,
5565 ! NILP (mustmatch),
5566 ! NILP (only_dir_p));
5568 if (fn)
5570 file = build_string (fn);
5571 xfree (fn);
5574 UNBLOCK_INPUT;
5575 UNGCPRO;
5577 /* Make "Cancel" equivalent to C-g. */
5578 if (NILP (file))
5579 Fsignal (Qquit, Qnil);
5581 decoded_file = DECODE_FILE (file);
5583 return unbind_to (count, decoded_file);
5587 #ifdef HAVE_FREETYPE
5589 DEFUN ("x-select-font", Fx_select_font, Sx_select_font, 0, 2, 0,
5590 doc: /* Read a font name using a GTK font selection dialog.
5591 Return a GTK-style font string corresponding to the selection.
5593 If FRAME is omitted or nil, it defaults to the selected frame. */)
5594 (Lisp_Object frame, Lisp_Object ignored)
5596 FRAME_PTR f = check_x_frame (frame);
5597 char *name;
5598 Lisp_Object font;
5599 Lisp_Object font_param;
5600 char *default_name = NULL;
5601 struct gcpro gcpro1, gcpro2;
5602 int count = SPECPDL_INDEX ();
5604 check_x ();
5606 if (popup_activated ())
5607 error ("Trying to use a menu from within a menu-entry");
5609 /* Prevent redisplay. */
5610 specbind (Qinhibit_redisplay, Qt);
5611 record_unwind_protect (clean_up_dialog, Qnil);
5613 BLOCK_INPUT;
5615 GCPRO2(font_param, font);
5617 XSETFONT (font, FRAME_FONT (f));
5618 font_param = Ffont_get (font, intern (":name"));
5619 if (STRINGP (font_param))
5620 default_name = xstrdup (SDATA (font_param));
5621 else
5623 font_param = Fframe_parameter (frame, Qfont_param);
5624 if (STRINGP (font_param))
5625 default_name = xstrdup (SDATA (font_param));
5628 if (default_name == NULL && x_last_font_name != NULL)
5629 default_name = xstrdup (x_last_font_name);
5631 /* Convert fontconfig names to Gtk names, i.e. remove - before number */
5632 if (default_name)
5634 char *p = strrchr (default_name, '-');
5635 if (p)
5637 char *ep = p+1;
5638 while (isdigit (*ep))
5639 ++ep;
5640 if (*ep == '\0') *p = ' ';
5644 name = xg_get_font_name (f, default_name);
5645 xfree (default_name);
5647 if (name)
5649 font = build_string (name);
5650 g_free (x_last_font_name);
5651 x_last_font_name = name;
5654 UNBLOCK_INPUT;
5656 if (NILP (font))
5657 Fsignal (Qquit, Qnil);
5659 return unbind_to (count, font);
5661 #endif /* HAVE_FREETYPE */
5663 #endif /* USE_GTK */
5666 /***********************************************************************
5667 Keyboard
5668 ***********************************************************************/
5670 #ifdef HAVE_XKBGETKEYBOARD
5671 #include <X11/XKBlib.h>
5672 #include <X11/keysym.h>
5673 #endif
5675 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p,
5676 Sx_backspace_delete_keys_p, 0, 1, 0,
5677 doc: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
5678 FRAME nil means use the selected frame.
5679 Value is t if we know that both keys are present, and are mapped to the
5680 usual X keysyms. Value is `lambda' if we cannot determine if both keys are
5681 present and mapped to the usual X keysyms. */)
5682 (Lisp_Object frame)
5684 #ifdef HAVE_XKBGETKEYBOARD
5685 XkbDescPtr kb;
5686 struct frame *f = check_x_frame (frame);
5687 Display *dpy = FRAME_X_DISPLAY (f);
5688 Lisp_Object have_keys;
5689 int major, minor, op, event, error;
5691 BLOCK_INPUT;
5693 /* Check library version in case we're dynamically linked. */
5694 major = XkbMajorVersion;
5695 minor = XkbMinorVersion;
5696 if (!XkbLibraryVersion (&major, &minor))
5698 UNBLOCK_INPUT;
5699 return Qlambda;
5702 /* Check that the server supports XKB. */
5703 major = XkbMajorVersion;
5704 minor = XkbMinorVersion;
5705 if (!XkbQueryExtension (dpy, &op, &event, &error, &major, &minor))
5707 UNBLOCK_INPUT;
5708 return Qlambda;
5711 /* In this code we check that the keyboard has physical keys with names
5712 that start with BKSP (Backspace) and DELE (Delete), and that they
5713 generate keysym XK_BackSpace and XK_Delete respectively.
5714 This function is used to test if normal-erase-is-backspace should be
5715 turned on.
5716 An alternative approach would be to just check if XK_BackSpace and
5717 XK_Delete are mapped to any key. But if any of those are mapped to
5718 some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the
5719 user doesn't know about it, it is better to return false here.
5720 It is more obvious to the user what to do if she/he has two keys
5721 clearly marked with names/symbols and one key does something not
5722 expected (i.e. she/he then tries the other).
5723 The cases where Backspace/Delete is mapped to some other key combination
5724 are rare, and in those cases, normal-erase-is-backspace can be turned on
5725 manually. */
5727 have_keys = Qnil;
5728 kb = XkbGetMap (dpy, XkbAllMapComponentsMask, XkbUseCoreKbd);
5729 if (kb)
5731 int delete_keycode = 0, backspace_keycode = 0, i;
5733 if (XkbGetNames (dpy, XkbAllNamesMask, kb) == Success)
5735 for (i = kb->min_key_code;
5736 (i < kb->max_key_code
5737 && (delete_keycode == 0 || backspace_keycode == 0));
5738 ++i)
5740 /* The XKB symbolic key names can be seen most easily in
5741 the PS file generated by `xkbprint -label name
5742 $DISPLAY'. */
5743 if (memcmp ("DELE", kb->names->keys[i].name, 4) == 0)
5744 delete_keycode = i;
5745 else if (memcmp ("BKSP", kb->names->keys[i].name, 4) == 0)
5746 backspace_keycode = i;
5749 XkbFreeNames (kb, 0, True);
5752 XkbFreeClientMap (kb, 0, True);
5754 if (delete_keycode
5755 && backspace_keycode
5756 && XKeysymToKeycode (dpy, XK_Delete) == delete_keycode
5757 && XKeysymToKeycode (dpy, XK_BackSpace) == backspace_keycode)
5758 have_keys = Qt;
5760 UNBLOCK_INPUT;
5761 return have_keys;
5762 #else /* not HAVE_XKBGETKEYBOARD */
5763 return Qlambda;
5764 #endif /* not HAVE_XKBGETKEYBOARD */
5769 /***********************************************************************
5770 Initialization
5771 ***********************************************************************/
5773 /* Keep this list in the same order as frame_parms in frame.c.
5774 Use 0 for unsupported frame parameters. */
5776 frame_parm_handler x_frame_parm_handlers[] =
5778 x_set_autoraise,
5779 x_set_autolower,
5780 x_set_background_color,
5781 x_set_border_color,
5782 x_set_border_width,
5783 x_set_cursor_color,
5784 x_set_cursor_type,
5785 x_set_font,
5786 x_set_foreground_color,
5787 x_set_icon_name,
5788 x_set_icon_type,
5789 x_set_internal_border_width,
5790 x_set_menu_bar_lines,
5791 x_set_mouse_color,
5792 x_explicitly_set_name,
5793 x_set_scroll_bar_width,
5794 x_set_title,
5795 x_set_unsplittable,
5796 x_set_vertical_scroll_bars,
5797 x_set_visibility,
5798 x_set_tool_bar_lines,
5799 x_set_scroll_bar_foreground,
5800 x_set_scroll_bar_background,
5801 x_set_screen_gamma,
5802 x_set_line_spacing,
5803 x_set_fringe_width,
5804 x_set_fringe_width,
5805 x_set_wait_for_wm,
5806 x_set_fullscreen,
5807 x_set_font_backend,
5808 x_set_alpha,
5809 x_set_sticky,
5810 x_set_tool_bar_position,
5813 void
5814 syms_of_xfns (void)
5816 /* This is zero if not using X windows. */
5817 x_in_use = 0;
5819 /* The section below is built by the lisp expression at the top of the file,
5820 just above where these variables are declared. */
5821 /*&&& init symbols here &&&*/
5822 Qnone = intern_c_string ("none");
5823 staticpro (&Qnone);
5824 Qsuppress_icon = intern_c_string ("suppress-icon");
5825 staticpro (&Qsuppress_icon);
5826 Qundefined_color = intern_c_string ("undefined-color");
5827 staticpro (&Qundefined_color);
5828 Qcompound_text = intern_c_string ("compound-text");
5829 staticpro (&Qcompound_text);
5830 Qcancel_timer = intern_c_string ("cancel-timer");
5831 staticpro (&Qcancel_timer);
5832 Qfont_param = intern_c_string ("font-parameter");
5833 staticpro (&Qfont_param);
5834 /* This is the end of symbol initialization. */
5836 /* Text property `display' should be nonsticky by default. */
5837 Vtext_property_default_nonsticky
5838 = Fcons (Fcons (Qdisplay, Qt), Vtext_property_default_nonsticky);
5841 Fput (Qundefined_color, Qerror_conditions,
5842 pure_cons (Qundefined_color, pure_cons (Qerror, Qnil)));
5843 Fput (Qundefined_color, Qerror_message,
5844 make_pure_c_string ("Undefined color"));
5846 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
5847 doc: /* The shape of the pointer when over text.
5848 Changing the value does not affect existing frames
5849 unless you set the mouse color. */);
5850 Vx_pointer_shape = Qnil;
5852 #if 0 /* This doesn't really do anything. */
5853 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape,
5854 doc: /* The shape of the pointer when not over text.
5855 This variable takes effect when you create a new frame
5856 or when you set the mouse color. */);
5857 #endif
5858 Vx_nontext_pointer_shape = Qnil;
5860 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape,
5861 doc: /* The shape of the pointer when Emacs is busy.
5862 This variable takes effect when you create a new frame
5863 or when you set the mouse color. */);
5864 Vx_hourglass_pointer_shape = Qnil;
5866 #if 0 /* This doesn't really do anything. */
5867 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape,
5868 doc: /* The shape of the pointer when over the mode line.
5869 This variable takes effect when you create a new frame
5870 or when you set the mouse color. */);
5871 #endif
5872 Vx_mode_pointer_shape = Qnil;
5874 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
5875 &Vx_sensitive_text_pointer_shape,
5876 doc: /* The shape of the pointer when over mouse-sensitive text.
5877 This variable takes effect when you create a new frame
5878 or when you set the mouse color. */);
5879 Vx_sensitive_text_pointer_shape = Qnil;
5881 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
5882 &Vx_window_horizontal_drag_shape,
5883 doc: /* Pointer shape to use for indicating a window can be dragged horizontally.
5884 This variable takes effect when you create a new frame
5885 or when you set the mouse color. */);
5886 Vx_window_horizontal_drag_shape = Qnil;
5888 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel,
5889 doc: /* A string indicating the foreground color of the cursor box. */);
5890 Vx_cursor_fore_pixel = Qnil;
5892 DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size,
5893 doc: /* Maximum size for tooltips.
5894 Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */);
5895 Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
5897 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
5898 doc: /* Non-nil if no X window manager is in use.
5899 Emacs doesn't try to figure this out; this is always nil
5900 unless you set it to something else. */);
5901 /* We don't have any way to find this out, so set it to nil
5902 and maybe the user would like to set it to t. */
5903 Vx_no_window_manager = Qnil;
5905 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
5906 &Vx_pixel_size_width_font_regexp,
5907 doc: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
5909 Since Emacs gets width of a font matching with this regexp from
5910 PIXEL_SIZE field of the name, font finding mechanism gets faster for
5911 such a font. This is especially effective for such large fonts as
5912 Chinese, Japanese, and Korean. */);
5913 Vx_pixel_size_width_font_regexp = Qnil;
5915 /* This is not ifdef:ed, so other builds than GTK can customize it. */
5916 DEFVAR_BOOL ("x-gtk-use-old-file-dialog", &x_gtk_use_old_file_dialog,
5917 doc: /* *Non-nil means prompt with the old GTK file selection dialog.
5918 If nil or if the file selection dialog is not available, the new GTK file
5919 chooser is used instead. To turn off all file dialogs set the
5920 variable `use-file-dialog'. */);
5921 x_gtk_use_old_file_dialog = 0;
5923 DEFVAR_BOOL ("x-gtk-show-hidden-files", &x_gtk_show_hidden_files,
5924 doc: /* *If non-nil, the GTK file chooser will by default show hidden files.
5925 Note that this is just the default, there is a toggle button on the file
5926 chooser to show or not show hidden files on a case by case basis. */);
5927 x_gtk_show_hidden_files = 0;
5929 DEFVAR_BOOL ("x-gtk-file-dialog-help-text", &x_gtk_file_dialog_help_text,
5930 doc: /* *If non-nil, the GTK file chooser will show additional help text.
5931 If more space for files in the file chooser dialog is wanted, set this to nil
5932 to turn the additional text off. */);
5933 x_gtk_file_dialog_help_text = 1;
5935 DEFVAR_BOOL ("x-gtk-whole-detached-tool-bar", &x_gtk_whole_detached_tool_bar,
5936 doc: /* *If non-nil, a detached tool bar is shown in full.
5937 The default is to just show an arrow and pressing on that arrow shows
5938 the tool bar buttons. */);
5939 x_gtk_whole_detached_tool_bar = 0;
5941 DEFVAR_BOOL ("x-gtk-use-system-tooltips", &x_gtk_use_system_tooltips,
5942 doc: /* *If non-nil with a Gtk+ built Emacs, the Gtk+ toolip is used.
5943 Otherwise use Emacs own tooltip implementation.
5944 When using Gtk+ tooltips, the tooltip face is not used. */);
5945 x_gtk_use_system_tooltips = 1;
5947 Fprovide (intern_c_string ("x"), Qnil);
5949 #ifdef USE_X_TOOLKIT
5950 Fprovide (intern_c_string ("x-toolkit"), Qnil);
5951 #ifdef USE_MOTIF
5952 Fprovide (intern_c_string ("motif"), Qnil);
5954 DEFVAR_LISP ("motif-version-string", &Vmotif_version_string,
5955 doc: /* Version info for LessTif/Motif. */);
5956 Vmotif_version_string = build_string (XmVERSION_STRING);
5957 #endif /* USE_MOTIF */
5958 #endif /* USE_X_TOOLKIT */
5960 #ifdef USE_GTK
5961 /* Provide x-toolkit also for GTK. Internally GTK does not use Xt so it
5962 is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
5963 But for a user it is a toolkit for X, and indeed, configure
5964 accepts --with-x-toolkit=gtk. */
5965 Fprovide (intern_c_string ("x-toolkit"), Qnil);
5966 Fprovide (intern_c_string ("gtk"), Qnil);
5967 Fprovide (intern_c_string ("move-toolbar"), Qnil);
5969 DEFVAR_LISP ("gtk-version-string", &Vgtk_version_string,
5970 doc: /* Version info for GTK+. */);
5972 char gtk_version[40];
5973 g_snprintf (gtk_version, sizeof (gtk_version), "%u.%u.%u",
5974 GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
5975 Vgtk_version_string = make_pure_string (gtk_version, strlen (gtk_version), strlen (gtk_version), 0);
5977 #endif /* USE_GTK */
5979 /* X window properties. */
5980 defsubr (&Sx_change_window_property);
5981 defsubr (&Sx_delete_window_property);
5982 defsubr (&Sx_window_property);
5984 defsubr (&Sxw_display_color_p);
5985 defsubr (&Sx_display_grayscale_p);
5986 defsubr (&Sxw_color_defined_p);
5987 defsubr (&Sxw_color_values);
5988 defsubr (&Sx_server_max_request_size);
5989 defsubr (&Sx_server_vendor);
5990 defsubr (&Sx_server_version);
5991 defsubr (&Sx_display_pixel_width);
5992 defsubr (&Sx_display_pixel_height);
5993 defsubr (&Sx_display_mm_width);
5994 defsubr (&Sx_display_mm_height);
5995 defsubr (&Sx_display_screens);
5996 defsubr (&Sx_display_planes);
5997 defsubr (&Sx_display_color_cells);
5998 defsubr (&Sx_display_visual_class);
5999 defsubr (&Sx_display_backing_store);
6000 defsubr (&Sx_display_save_under);
6001 defsubr (&Sx_wm_set_size_hint);
6002 defsubr (&Sx_create_frame);
6003 defsubr (&Sx_open_connection);
6004 defsubr (&Sx_close_connection);
6005 defsubr (&Sx_display_list);
6006 defsubr (&Sx_synchronize);
6007 defsubr (&Sx_focus_frame);
6008 defsubr (&Sx_backspace_delete_keys_p);
6010 /* Setting callback functions for fontset handler. */
6011 check_window_system_func = check_x;
6013 defsubr (&Sx_show_tip);
6014 defsubr (&Sx_hide_tip);
6015 tip_timer = Qnil;
6016 staticpro (&tip_timer);
6017 tip_frame = Qnil;
6018 staticpro (&tip_frame);
6020 last_show_tip_args = Qnil;
6021 staticpro (&last_show_tip_args);
6023 defsubr (&Sx_uses_old_gtk_dialog);
6024 #if defined (USE_MOTIF) || defined (USE_GTK)
6025 defsubr (&Sx_file_dialog);
6026 #endif
6028 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
6029 defsubr (&Sx_select_font);
6030 x_last_font_name = NULL;
6031 #endif
6034 #endif /* HAVE_X_WINDOWS */