Backport NEWS tweak from trunk
[emacs.git] / src / xfns.c
blob5dbc7053fd9ff87a22705cec098a5e42d65667af
1 /* Functions for the X window system.
3 Copyright (C) 1989, 1992-2014 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20 #include <config.h>
21 #include <stdio.h>
22 #include <math.h>
23 #include <unistd.h>
25 #include "lisp.h"
26 #include "xterm.h"
27 #include "frame.h"
28 #include "window.h"
29 #include "character.h"
30 #include "buffer.h"
31 #include "intervals.h"
32 #include "dispextern.h"
33 #include "keyboard.h"
34 #include "blockinput.h"
35 #include <epaths.h>
36 #include "charset.h"
37 #include "coding.h"
38 #include "fontset.h"
39 #include "systime.h"
40 #include "termhooks.h"
41 #include "atimer.h"
42 #include "termchar.h"
43 #include "font.h"
45 #include <sys/types.h>
46 #include <sys/stat.h>
48 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */
49 #include "bitmaps/gray.xbm"
50 #else
51 #include <X11/bitmaps/gray>
52 #endif
54 #include "xsettings.h"
56 #ifdef HAVE_XRANDR
57 #include <X11/extensions/Xrandr.h>
58 #endif
59 #ifdef HAVE_XINERAMA
60 #include <X11/extensions/Xinerama.h>
61 #endif
63 #ifdef USE_GTK
64 #include "gtkutil.h"
65 #endif
67 #ifdef USE_X_TOOLKIT
68 #include <X11/Shell.h>
70 #ifndef USE_MOTIF
71 #ifdef HAVE_XAW3D
72 #include <X11/Xaw3d/Paned.h>
73 #include <X11/Xaw3d/Label.h>
74 #else /* !HAVE_XAW3D */
75 #include <X11/Xaw/Paned.h>
76 #include <X11/Xaw/Label.h>
77 #endif /* HAVE_XAW3D */
78 #endif /* USE_MOTIF */
80 #ifdef USG
81 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
82 #include <X11/Xos.h>
83 #define USG
84 #ifdef USG /* Pacify gcc -Wunused-macros. */
85 #endif
86 #else
87 #include <X11/Xos.h>
88 #endif
90 #include "widget.h"
92 #include "../lwlib/lwlib.h"
94 #ifdef USE_MOTIF
95 #include <Xm/Xm.h>
96 #include <Xm/DialogS.h>
97 #include <Xm/FileSB.h>
98 #include <Xm/List.h>
99 #include <Xm/TextF.h>
100 #endif
102 #ifdef USE_LUCID
103 #include "../lwlib/xlwmenu.h"
104 #endif
106 #if !defined (NO_EDITRES)
107 #define HACK_EDITRES
108 extern void _XEditResCheckMessages (Widget, XtPointer, XEvent *, Boolean *);
109 #endif /* not defined NO_EDITRES */
111 /* Unique id counter for widgets created by the Lucid Widget Library. */
113 extern LWLIB_ID widget_id_tick;
115 #ifdef USE_MOTIF
117 #endif /* USE_MOTIF */
119 #endif /* USE_X_TOOLKIT */
121 #ifdef USE_GTK
123 #endif /* USE_GTK */
125 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
127 static Lisp_Object Qsuppress_icon;
128 static Lisp_Object Qundefined_color;
129 static Lisp_Object Qcompound_text, Qcancel_timer;
130 Lisp_Object Qfont_param;
132 #ifdef GLYPH_DEBUG
133 static ptrdiff_t image_cache_refcount;
134 static int dpyinfo_refcount;
135 #endif
137 static struct x_display_info *x_display_info_for_name (Lisp_Object);
139 /* Let the user specify an X display with a Lisp object.
140 OBJECT may be nil, a frame or a terminal object.
141 nil stands for the selected frame--or, if that is not an X frame,
142 the first X display on the list. */
144 struct x_display_info *
145 check_x_display_info (Lisp_Object object)
147 struct x_display_info *dpyinfo = NULL;
149 if (NILP (object))
151 struct frame *sf = XFRAME (selected_frame);
153 if (FRAME_X_P (sf) && FRAME_LIVE_P (sf))
154 dpyinfo = FRAME_DISPLAY_INFO (sf);
155 else if (x_display_list != 0)
156 dpyinfo = x_display_list;
157 else
158 error ("X windows are not in use or not initialized");
160 else if (TERMINALP (object))
162 struct terminal *t = get_terminal (object, 1);
164 if (t->type != output_x_window)
165 error ("Terminal %d is not an X display", t->id);
167 dpyinfo = t->display_info.x;
169 else if (STRINGP (object))
170 dpyinfo = x_display_info_for_name (object);
171 else
173 struct frame *f = decode_window_system_frame (object);
174 dpyinfo = FRAME_DISPLAY_INFO (f);
177 return dpyinfo;
180 /* Store the screen positions of frame F into XPTR and YPTR.
181 These are the positions of the containing window manager window,
182 not Emacs's own window. */
184 void
185 x_real_positions (struct frame *f, int *xptr, int *yptr)
187 int win_x, win_y, outer_x IF_LINT (= 0), outer_y IF_LINT (= 0);
188 int real_x = 0, real_y = 0;
189 int had_errors = 0;
190 Window win = f->output_data.x->parent_desc;
191 Atom actual_type;
192 unsigned long actual_size, bytes_remaining;
193 int rc, actual_format;
194 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
195 long max_len = 400;
196 Display *dpy = FRAME_X_DISPLAY (f);
197 unsigned char *tmp_data = NULL;
198 Atom target_type = XA_CARDINAL;
200 block_input ();
202 x_catch_errors (dpy);
204 if (win == dpyinfo->root_window)
205 win = FRAME_OUTER_WINDOW (f);
207 /* This loop traverses up the containment tree until we hit the root
208 window. Window managers may intersect many windows between our window
209 and the root window. The window we find just before the root window
210 should be the outer WM window. */
211 for (;;)
213 Window wm_window, rootw;
214 Window *tmp_children;
215 unsigned int tmp_nchildren;
216 int success;
218 success = XQueryTree (FRAME_X_DISPLAY (f), win, &rootw,
219 &wm_window, &tmp_children, &tmp_nchildren);
221 had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
223 /* Don't free tmp_children if XQueryTree failed. */
224 if (! success)
225 break;
227 XFree (tmp_children);
229 if (wm_window == rootw || had_errors)
230 break;
232 win = wm_window;
235 if (! had_errors)
237 unsigned int ign;
238 Window child, rootw;
240 /* Get the real coordinates for the WM window upper left corner */
241 XGetGeometry (FRAME_X_DISPLAY (f), win,
242 &rootw, &real_x, &real_y, &ign, &ign, &ign, &ign);
244 /* Translate real coordinates to coordinates relative to our
245 window. For our window, the upper left corner is 0, 0.
246 Since the upper left corner of the WM window is outside
247 our window, win_x and win_y will be negative:
249 ------------------ ---> x
250 | title |
251 | ----------------- v y
252 | | our window
254 XTranslateCoordinates (FRAME_X_DISPLAY (f),
256 /* From-window, to-window. */
257 FRAME_DISPLAY_INFO (f)->root_window,
258 FRAME_X_WINDOW (f),
260 /* From-position, to-position. */
261 real_x, real_y, &win_x, &win_y,
263 /* Child of win. */
264 &child);
266 if (FRAME_X_WINDOW (f) == FRAME_OUTER_WINDOW (f))
268 outer_x = win_x;
269 outer_y = win_y;
271 else
273 XTranslateCoordinates (FRAME_X_DISPLAY (f),
275 /* From-window, to-window. */
276 FRAME_DISPLAY_INFO (f)->root_window,
277 FRAME_OUTER_WINDOW (f),
279 /* From-position, to-position. */
280 real_x, real_y, &outer_x, &outer_y,
282 /* Child of win. */
283 &child);
286 had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
290 if (dpyinfo->root_window == f->output_data.x->parent_desc)
292 /* Try _NET_FRAME_EXTENTS if our parent is the root window. */
293 rc = XGetWindowProperty (dpy, win, dpyinfo->Xatom_net_frame_extents,
294 0, max_len, False, target_type,
295 &actual_type, &actual_format, &actual_size,
296 &bytes_remaining, &tmp_data);
298 if (rc == Success && actual_type == target_type && !x_had_errors_p (dpy)
299 && actual_size == 4 && actual_format == 32)
301 unsigned int ign;
302 Window rootw;
303 long *fe = (long *)tmp_data;
305 XGetGeometry (FRAME_X_DISPLAY (f), win,
306 &rootw, &real_x, &real_y, &ign, &ign, &ign, &ign);
307 outer_x = -fe[0];
308 outer_y = -fe[2];
309 real_x -= fe[0];
310 real_y -= fe[2];
314 if (tmp_data) XFree (tmp_data);
316 x_uncatch_errors ();
318 unblock_input ();
320 if (had_errors) return;
322 f->x_pixels_diff = -win_x;
323 f->y_pixels_diff = -win_y;
325 FRAME_X_OUTPUT (f)->x_pixels_outer_diff = -outer_x;
326 FRAME_X_OUTPUT (f)->y_pixels_outer_diff = -outer_y;
328 *xptr = real_x;
329 *yptr = real_y;
335 /* Gamma-correct COLOR on frame F. */
337 void
338 gamma_correct (struct frame *f, XColor *color)
340 if (f->gamma)
342 color->red = pow (color->red / 65535.0, f->gamma) * 65535.0 + 0.5;
343 color->green = pow (color->green / 65535.0, f->gamma) * 65535.0 + 0.5;
344 color->blue = pow (color->blue / 65535.0, f->gamma) * 65535.0 + 0.5;
349 /* Decide if color named COLOR_NAME is valid for use on frame F. If
350 so, return the RGB values in COLOR. If ALLOC_P,
351 allocate the color. Value is false if COLOR_NAME is invalid, or
352 no color could be allocated. */
354 bool
355 x_defined_color (struct frame *f, const char *color_name,
356 XColor *color, bool alloc_p)
358 bool success_p = 0;
359 Display *dpy = FRAME_X_DISPLAY (f);
360 Colormap cmap = FRAME_X_COLORMAP (f);
362 block_input ();
363 #ifdef USE_GTK
364 success_p = xg_check_special_colors (f, color_name, color);
365 #endif
366 if (!success_p)
367 success_p = XParseColor (dpy, cmap, color_name, color) != 0;
368 if (success_p && alloc_p)
369 success_p = x_alloc_nearest_color (f, cmap, color);
370 unblock_input ();
372 return success_p;
376 /* Return the pixel color value for color COLOR_NAME on frame F. If F
377 is a monochrome frame, return MONO_COLOR regardless of what ARG says.
378 Signal an error if color can't be allocated. */
380 static int
381 x_decode_color (struct frame *f, Lisp_Object color_name, int mono_color)
383 XColor cdef;
385 CHECK_STRING (color_name);
387 #if 0 /* Don't do this. It's wrong when we're not using the default
388 colormap, it makes freeing difficult, and it's probably not
389 an important optimization. */
390 if (strcmp (SDATA (color_name), "black") == 0)
391 return BLACK_PIX_DEFAULT (f);
392 else if (strcmp (SDATA (color_name), "white") == 0)
393 return WHITE_PIX_DEFAULT (f);
394 #endif
396 /* Return MONO_COLOR for monochrome frames. */
397 if (FRAME_DISPLAY_INFO (f)->n_planes == 1)
398 return mono_color;
400 /* x_defined_color is responsible for coping with failures
401 by looking for a near-miss. */
402 if (x_defined_color (f, SSDATA (color_name), &cdef, 1))
403 return cdef.pixel;
405 signal_error ("Undefined color", color_name);
410 /* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
411 the previous value of that parameter, NEW_VALUE is the new value.
412 See also the comment of wait_for_wm in struct x_output. */
414 static void
415 x_set_wait_for_wm (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
417 f->output_data.x->wait_for_wm = !NILP (new_value);
420 static void
421 x_set_tool_bar_position (struct frame *f,
422 Lisp_Object new_value,
423 Lisp_Object old_value)
425 if (! EQ (new_value, Qleft) && ! EQ (new_value, Qright)
426 && ! EQ (new_value, Qbottom) && ! EQ (new_value, Qtop))
427 return;
428 if (EQ (new_value, old_value)) return;
430 #ifdef USE_GTK
431 xg_change_toolbar_position (f, new_value);
432 fset_tool_bar_position (f, new_value);
433 #endif
436 #ifdef USE_GTK
438 /* Set icon from FILE for frame F. By using GTK functions the icon
439 may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
442 xg_set_icon (struct frame *f, Lisp_Object file)
444 int result = 0;
445 Lisp_Object found;
447 found = x_find_image_file (file);
449 if (! NILP (found))
451 GdkPixbuf *pixbuf;
452 GError *err = NULL;
453 char *filename = SSDATA (found);
454 block_input ();
456 pixbuf = gdk_pixbuf_new_from_file (filename, &err);
458 if (pixbuf)
460 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
461 pixbuf);
462 g_object_unref (pixbuf);
464 result = 1;
466 else
467 g_error_free (err);
469 unblock_input ();
472 return result;
476 xg_set_icon_from_xpm_data (struct frame *f, const char **data)
478 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data (data);
480 if (!pixbuf)
481 return 0;
483 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), pixbuf);
484 g_object_unref (pixbuf);
485 return 1;
487 #endif /* USE_GTK */
490 /* Functions called only from `x_set_frame_param'
491 to set individual parameters.
493 If FRAME_X_WINDOW (f) is 0,
494 the frame is being created and its X-window does not exist yet.
495 In that case, just record the parameter's new value
496 in the standard place; do not attempt to change the window. */
498 static void
499 x_set_foreground_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
501 struct x_output *x = f->output_data.x;
502 unsigned long fg, old_fg;
504 fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
505 old_fg = FRAME_FOREGROUND_PIXEL (f);
506 FRAME_FOREGROUND_PIXEL (f) = fg;
508 if (FRAME_X_WINDOW (f) != 0)
510 Display *dpy = FRAME_X_DISPLAY (f);
512 block_input ();
513 XSetForeground (dpy, x->normal_gc, fg);
514 XSetBackground (dpy, x->reverse_gc, fg);
516 if (x->cursor_pixel == old_fg)
518 unload_color (f, x->cursor_pixel);
519 x->cursor_pixel = x_copy_color (f, fg);
520 XSetBackground (dpy, x->cursor_gc, x->cursor_pixel);
523 unblock_input ();
525 update_face_from_frame_parameter (f, Qforeground_color, arg);
527 if (FRAME_VISIBLE_P (f))
528 redraw_frame (f);
531 unload_color (f, old_fg);
534 static void
535 x_set_background_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
537 struct x_output *x = f->output_data.x;
538 unsigned long bg;
540 bg = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
541 unload_color (f, FRAME_BACKGROUND_PIXEL (f));
542 FRAME_BACKGROUND_PIXEL (f) = bg;
544 if (FRAME_X_WINDOW (f) != 0)
546 Display *dpy = FRAME_X_DISPLAY (f);
548 block_input ();
549 XSetBackground (dpy, x->normal_gc, bg);
550 XSetForeground (dpy, x->reverse_gc, bg);
551 XSetWindowBackground (dpy, FRAME_X_WINDOW (f), bg);
552 XSetForeground (dpy, x->cursor_gc, bg);
554 #ifdef USE_GTK
555 xg_set_background_color (f, bg);
556 #endif
558 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
559 toolkit scroll bars. */
561 Lisp_Object bar;
562 for (bar = FRAME_SCROLL_BARS (f);
563 !NILP (bar);
564 bar = XSCROLL_BAR (bar)->next)
566 Window window = XSCROLL_BAR (bar)->x_window;
567 XSetWindowBackground (dpy, window, bg);
570 #endif /* USE_TOOLKIT_SCROLL_BARS */
572 unblock_input ();
573 update_face_from_frame_parameter (f, Qbackground_color, arg);
575 if (FRAME_VISIBLE_P (f))
576 redraw_frame (f);
580 static Cursor
581 make_invisible_cursor (struct frame *f)
583 Display *dpy = FRAME_X_DISPLAY (f);
584 static char const no_data[] = { 0 };
585 Pixmap pix;
586 XColor col;
587 Cursor c = 0;
589 x_catch_errors (dpy);
590 pix = XCreateBitmapFromData (dpy, FRAME_DISPLAY_INFO (f)->root_window,
591 no_data, 1, 1);
592 if (! x_had_errors_p (dpy) && pix != None)
594 Cursor pixc;
595 col.pixel = 0;
596 col.red = col.green = col.blue = 0;
597 col.flags = DoRed | DoGreen | DoBlue;
598 pixc = XCreatePixmapCursor (dpy, pix, pix, &col, &col, 0, 0);
599 if (! x_had_errors_p (dpy) && pixc != None)
600 c = pixc;
601 XFreePixmap (dpy, pix);
604 x_uncatch_errors ();
606 return c;
609 static void
610 x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
612 struct x_output *x = f->output_data.x;
613 Display *dpy = FRAME_X_DISPLAY (f);
614 Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
615 Cursor hourglass_cursor, horizontal_drag_cursor, vertical_drag_cursor;
616 unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
617 unsigned long mask_color = FRAME_BACKGROUND_PIXEL (f);
619 /* Don't let pointers be invisible. */
620 if (mask_color == pixel)
622 x_free_colors (f, &pixel, 1);
623 pixel = x_copy_color (f, FRAME_FOREGROUND_PIXEL (f));
626 unload_color (f, x->mouse_pixel);
627 x->mouse_pixel = pixel;
629 block_input ();
631 /* It's not okay to crash if the user selects a screwy cursor. */
632 x_catch_errors (dpy);
634 if (!NILP (Vx_pointer_shape))
636 CHECK_NUMBER (Vx_pointer_shape);
637 cursor = XCreateFontCursor (dpy, XINT (Vx_pointer_shape));
639 else
640 cursor = XCreateFontCursor (dpy, XC_xterm);
641 x_check_errors (dpy, "bad text pointer cursor: %s");
643 if (!NILP (Vx_nontext_pointer_shape))
645 CHECK_NUMBER (Vx_nontext_pointer_shape);
646 nontext_cursor
647 = XCreateFontCursor (dpy, XINT (Vx_nontext_pointer_shape));
649 else
650 nontext_cursor = XCreateFontCursor (dpy, XC_left_ptr);
651 x_check_errors (dpy, "bad nontext pointer cursor: %s");
653 if (!NILP (Vx_hourglass_pointer_shape))
655 CHECK_NUMBER (Vx_hourglass_pointer_shape);
656 hourglass_cursor
657 = XCreateFontCursor (dpy, XINT (Vx_hourglass_pointer_shape));
659 else
660 hourglass_cursor = XCreateFontCursor (dpy, XC_watch);
661 x_check_errors (dpy, "bad hourglass pointer cursor: %s");
663 if (!NILP (Vx_mode_pointer_shape))
665 CHECK_NUMBER (Vx_mode_pointer_shape);
666 mode_cursor = XCreateFontCursor (dpy, XINT (Vx_mode_pointer_shape));
668 else
669 mode_cursor = XCreateFontCursor (dpy, XC_xterm);
670 x_check_errors (dpy, "bad modeline pointer cursor: %s");
672 if (!NILP (Vx_sensitive_text_pointer_shape))
674 CHECK_NUMBER (Vx_sensitive_text_pointer_shape);
675 hand_cursor
676 = XCreateFontCursor (dpy, XINT (Vx_sensitive_text_pointer_shape));
678 else
679 hand_cursor = XCreateFontCursor (dpy, XC_hand2);
681 if (!NILP (Vx_window_horizontal_drag_shape))
683 CHECK_TYPE_RANGED_INTEGER (unsigned, Vx_window_horizontal_drag_shape);
684 horizontal_drag_cursor
685 = XCreateFontCursor (dpy, XINT (Vx_window_horizontal_drag_shape));
687 else
688 horizontal_drag_cursor
689 = XCreateFontCursor (dpy, XC_sb_h_double_arrow);
691 if (!NILP (Vx_window_vertical_drag_shape))
693 CHECK_NUMBER (Vx_window_vertical_drag_shape);
694 vertical_drag_cursor
695 = XCreateFontCursor (dpy, XINT (Vx_window_vertical_drag_shape));
697 else
698 vertical_drag_cursor
699 = XCreateFontCursor (dpy, XC_sb_v_double_arrow);
701 /* Check and report errors with the above calls. */
702 x_check_errors (dpy, "can't set cursor shape: %s");
703 x_uncatch_errors ();
706 XColor fore_color, back_color;
708 fore_color.pixel = x->mouse_pixel;
709 x_query_color (f, &fore_color);
710 back_color.pixel = mask_color;
711 x_query_color (f, &back_color);
713 XRecolorCursor (dpy, cursor, &fore_color, &back_color);
714 XRecolorCursor (dpy, nontext_cursor, &fore_color, &back_color);
715 XRecolorCursor (dpy, mode_cursor, &fore_color, &back_color);
716 XRecolorCursor (dpy, hand_cursor, &fore_color, &back_color);
717 XRecolorCursor (dpy, hourglass_cursor, &fore_color, &back_color);
718 XRecolorCursor (dpy, horizontal_drag_cursor, &fore_color, &back_color);
719 XRecolorCursor (dpy, vertical_drag_cursor, &fore_color, &back_color);
722 if (FRAME_X_WINDOW (f) != 0)
723 XDefineCursor (dpy, FRAME_X_WINDOW (f),
724 f->output_data.x->current_cursor = cursor);
726 if (FRAME_DISPLAY_INFO (f)->invisible_cursor == 0)
727 FRAME_DISPLAY_INFO (f)->invisible_cursor = make_invisible_cursor (f);
729 if (cursor != x->text_cursor
730 && x->text_cursor != 0)
731 XFreeCursor (dpy, x->text_cursor);
732 x->text_cursor = cursor;
734 if (nontext_cursor != x->nontext_cursor
735 && x->nontext_cursor != 0)
736 XFreeCursor (dpy, x->nontext_cursor);
737 x->nontext_cursor = nontext_cursor;
739 if (hourglass_cursor != x->hourglass_cursor
740 && x->hourglass_cursor != 0)
741 XFreeCursor (dpy, x->hourglass_cursor);
742 x->hourglass_cursor = hourglass_cursor;
744 if (mode_cursor != x->modeline_cursor
745 && x->modeline_cursor != 0)
746 XFreeCursor (dpy, f->output_data.x->modeline_cursor);
747 x->modeline_cursor = mode_cursor;
749 if (hand_cursor != x->hand_cursor
750 && x->hand_cursor != 0)
751 XFreeCursor (dpy, x->hand_cursor);
752 x->hand_cursor = hand_cursor;
754 if (horizontal_drag_cursor != x->horizontal_drag_cursor
755 && x->horizontal_drag_cursor != 0)
756 XFreeCursor (dpy, x->horizontal_drag_cursor);
757 x->horizontal_drag_cursor = horizontal_drag_cursor;
759 if (vertical_drag_cursor != x->vertical_drag_cursor
760 && x->vertical_drag_cursor != 0)
761 XFreeCursor (dpy, x->vertical_drag_cursor);
762 x->vertical_drag_cursor = vertical_drag_cursor;
764 XFlush (dpy);
765 unblock_input ();
767 update_face_from_frame_parameter (f, Qmouse_color, arg);
770 static void
771 x_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
773 unsigned long fore_pixel, pixel;
774 bool fore_pixel_allocated_p = 0, pixel_allocated_p = 0;
775 struct x_output *x = f->output_data.x;
777 if (!NILP (Vx_cursor_fore_pixel))
779 fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
780 WHITE_PIX_DEFAULT (f));
781 fore_pixel_allocated_p = 1;
783 else
784 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
786 pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
787 pixel_allocated_p = 1;
789 /* Make sure that the cursor color differs from the background color. */
790 if (pixel == FRAME_BACKGROUND_PIXEL (f))
792 if (pixel_allocated_p)
794 x_free_colors (f, &pixel, 1);
795 pixel_allocated_p = 0;
798 pixel = x->mouse_pixel;
799 if (pixel == fore_pixel)
801 if (fore_pixel_allocated_p)
803 x_free_colors (f, &fore_pixel, 1);
804 fore_pixel_allocated_p = 0;
806 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
810 unload_color (f, x->cursor_foreground_pixel);
811 if (!fore_pixel_allocated_p)
812 fore_pixel = x_copy_color (f, fore_pixel);
813 x->cursor_foreground_pixel = fore_pixel;
815 unload_color (f, x->cursor_pixel);
816 if (!pixel_allocated_p)
817 pixel = x_copy_color (f, pixel);
818 x->cursor_pixel = pixel;
820 if (FRAME_X_WINDOW (f) != 0)
822 block_input ();
823 XSetBackground (FRAME_X_DISPLAY (f), x->cursor_gc, x->cursor_pixel);
824 XSetForeground (FRAME_X_DISPLAY (f), x->cursor_gc, fore_pixel);
825 unblock_input ();
827 if (FRAME_VISIBLE_P (f))
829 x_update_cursor (f, 0);
830 x_update_cursor (f, 1);
834 update_face_from_frame_parameter (f, Qcursor_color, arg);
837 /* Set the border-color of frame F to pixel value PIX.
838 Note that this does not fully take effect if done before
839 F has an x-window. */
841 static void
842 x_set_border_pixel (struct frame *f, int pix)
844 unload_color (f, f->output_data.x->border_pixel);
845 f->output_data.x->border_pixel = pix;
847 if (FRAME_X_WINDOW (f) != 0 && f->border_width > 0)
849 block_input ();
850 XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), pix);
851 unblock_input ();
853 if (FRAME_VISIBLE_P (f))
854 redraw_frame (f);
858 /* Set the border-color of frame F to value described by ARG.
859 ARG can be a string naming a color.
860 The border-color is used for the border that is drawn by the X server.
861 Note that this does not fully take effect if done before
862 F has an x-window; it must be redone when the window is created.
864 Note: this is done in two routines because of the way X10 works.
866 Note: under X11, this is normally the province of the window manager,
867 and so emacs's border colors may be overridden. */
869 static void
870 x_set_border_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
872 int pix;
874 CHECK_STRING (arg);
875 pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
876 x_set_border_pixel (f, pix);
877 update_face_from_frame_parameter (f, Qborder_color, arg);
881 static void
882 x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
884 set_frame_cursor_types (f, arg);
887 static void
888 x_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
890 int result;
892 if (STRINGP (arg))
894 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
895 return;
897 else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
898 return;
900 block_input ();
901 if (NILP (arg))
902 result = x_text_icon (f,
903 SSDATA ((!NILP (f->icon_name)
904 ? f->icon_name
905 : f->name)));
906 else
907 result = x_bitmap_icon (f, arg);
909 if (result)
911 unblock_input ();
912 error ("No icon window available");
915 XFlush (FRAME_X_DISPLAY (f));
916 unblock_input ();
919 static void
920 x_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
922 int result;
924 if (STRINGP (arg))
926 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
927 return;
929 else if (!NILP (arg) || NILP (oldval))
930 return;
932 fset_icon_name (f, arg);
934 if (f->output_data.x->icon_bitmap != 0)
935 return;
937 block_input ();
939 result = x_text_icon (f,
940 SSDATA ((!NILP (f->icon_name)
941 ? f->icon_name
942 : !NILP (f->title)
943 ? f->title
944 : f->name)));
946 if (result)
948 unblock_input ();
949 error ("No icon window available");
952 XFlush (FRAME_X_DISPLAY (f));
953 unblock_input ();
957 void
958 x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
960 int nlines;
961 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
962 int olines = FRAME_MENU_BAR_LINES (f);
963 #endif
965 /* Right now, menu bars don't work properly in minibuf-only frames;
966 most of the commands try to apply themselves to the minibuffer
967 frame itself, and get an error because you can't switch buffers
968 in or split the minibuffer window. */
969 if (FRAME_MINIBUF_ONLY_P (f))
970 return;
972 if (TYPE_RANGED_INTEGERP (int, value))
973 nlines = XINT (value);
974 else
975 nlines = 0;
977 /* Make sure we redisplay all windows in this frame. */
978 windows_or_buffers_changed = 59;
980 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
981 FRAME_MENU_BAR_LINES (f) = 0;
982 FRAME_MENU_BAR_HEIGHT (f) = 0;
983 if (nlines)
985 FRAME_EXTERNAL_MENU_BAR (f) = 1;
986 if (FRAME_X_P (f) && f->output_data.x->menubar_widget == 0)
987 /* Make sure next redisplay shows the menu bar. */
988 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = 1;
990 else
992 if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
993 free_frame_menubar (f);
994 FRAME_EXTERNAL_MENU_BAR (f) = 0;
995 if (FRAME_X_P (f))
996 f->output_data.x->menubar_widget = 0;
998 #else /* not USE_X_TOOLKIT && not USE_GTK */
999 FRAME_MENU_BAR_LINES (f) = nlines;
1000 FRAME_MENU_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
1001 resize_frame_windows (f, FRAME_TEXT_HEIGHT (f), 0, 1);
1002 if (FRAME_X_WINDOW (f))
1003 x_clear_under_internal_border (f);
1005 /* If the menu bar height gets changed, the internal border below
1006 the top margin has to be cleared. Also, if the menu bar gets
1007 larger, the area for the added lines has to be cleared except for
1008 the first menu bar line that is to be drawn later. */
1009 if (nlines != olines)
1011 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1012 int width = FRAME_PIXEL_WIDTH (f);
1013 int y;
1015 /* height can be zero here. */
1016 if (FRAME_X_WINDOW (f) && height > 0 && width > 0)
1018 y = FRAME_TOP_MARGIN_HEIGHT (f);
1020 block_input ();
1021 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1022 0, y, width, height);
1023 unblock_input ();
1026 if (nlines > 1 && nlines > olines)
1028 y = (olines == 0 ? 1 : olines) * FRAME_LINE_HEIGHT (f);
1029 height = nlines * FRAME_LINE_HEIGHT (f) - y;
1031 block_input ();
1032 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1033 0, y, width, height);
1034 unblock_input ();
1037 if (nlines == 0 && WINDOWP (f->menu_bar_window))
1038 clear_glyph_matrix (XWINDOW (f->menu_bar_window)->current_matrix);
1040 #endif /* not USE_X_TOOLKIT && not USE_GTK */
1041 adjust_frame_glyphs (f);
1042 run_window_configuration_change_hook (f);
1046 /* Set the number of lines used for the tool bar of frame F to VALUE.
1047 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1048 is the old number of tool bar lines. This function changes the
1049 height of all windows on frame F to match the new tool bar height.
1050 The frame's height doesn't change. */
1052 void
1053 x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1055 int nlines;
1056 #if ! defined (USE_GTK)
1057 int delta, root_height;
1058 int unit = FRAME_LINE_HEIGHT (f);
1059 #endif
1061 /* Treat tool bars like menu bars. */
1062 if (FRAME_MINIBUF_ONLY_P (f))
1063 return;
1065 /* Use VALUE only if an int >= 0. */
1066 if (RANGED_INTEGERP (0, value, INT_MAX))
1067 nlines = XFASTINT (value);
1068 else
1069 nlines = 0;
1071 #ifdef USE_GTK
1073 FRAME_TOOL_BAR_LINES (f) = 0;
1074 FRAME_TOOL_BAR_HEIGHT (f) = 0;
1075 if (nlines)
1077 FRAME_EXTERNAL_TOOL_BAR (f) = 1;
1078 if (FRAME_X_P (f) && f->output_data.x->toolbar_widget == 0)
1079 /* Make sure next redisplay shows the tool bar. */
1080 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = 1;
1081 update_frame_tool_bar (f);
1083 else
1085 if (FRAME_EXTERNAL_TOOL_BAR (f))
1086 free_frame_tool_bar (f);
1087 FRAME_EXTERNAL_TOOL_BAR (f) = 0;
1090 #else /* !USE_GTK */
1092 /* Make sure we redisplay all windows in this frame. */
1093 windows_or_buffers_changed = 60;
1095 /* DELTA is in pixels now. */
1096 delta = (nlines - FRAME_TOOL_BAR_LINES (f)) * unit;
1098 /* Don't resize the tool-bar to more than we have room for. Note: The
1099 calculations below and the subsequent call to resize_frame_windows
1100 are inherently flawed because they can make the toolbar higher than
1101 the containing frame. */
1102 if (delta > 0)
1104 root_height = WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_ROOT_WINDOW (f)));
1105 if (root_height - delta < unit)
1107 delta = root_height - unit;
1108 /* When creating a new frame and toolbar mode is enabled, we
1109 need at least one toolbar line. */
1110 nlines = max (FRAME_TOOL_BAR_LINES (f) + delta / unit, 1);
1114 FRAME_TOOL_BAR_LINES (f) = nlines;
1115 FRAME_TOOL_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
1116 resize_frame_windows (f, FRAME_TEXT_HEIGHT (f), 0, 1);
1117 #if !defined USE_X_TOOLKIT && !defined USE_GTK
1118 if (FRAME_X_WINDOW (f))
1119 x_clear_under_internal_border (f);
1120 #endif
1121 adjust_frame_glyphs (f);
1123 /* We also have to make sure that the internal border at the top of
1124 the frame, below the menu bar or tool bar, is redrawn when the
1125 tool bar disappears. This is so because the internal border is
1126 below the tool bar if one is displayed, but is below the menu bar
1127 if there isn't a tool bar. The tool bar draws into the area
1128 below the menu bar. */
1129 if (FRAME_X_WINDOW (f) && FRAME_TOOL_BAR_HEIGHT (f) == 0)
1131 clear_frame (f);
1132 clear_current_matrices (f);
1135 /* If the tool bar gets smaller, the internal border below it
1136 has to be cleared. It was formerly part of the display
1137 of the larger tool bar, and updating windows won't clear it. */
1138 if (delta < 0)
1140 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1141 int width = FRAME_PIXEL_WIDTH (f);
1142 int y = nlines * unit;
1144 /* height can be zero here. */
1145 if (height > 0 && width > 0)
1147 block_input ();
1148 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1149 0, y, width, height);
1150 unblock_input ();
1153 if (WINDOWP (f->tool_bar_window))
1154 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1157 run_window_configuration_change_hook (f);
1158 #endif /* USE_GTK */
1162 /* Set the foreground color for scroll bars on frame F to VALUE.
1163 VALUE should be a string, a color name. If it isn't a string or
1164 isn't a valid color name, do nothing. OLDVAL is the old value of
1165 the frame parameter. */
1167 static void
1168 x_set_scroll_bar_foreground (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1170 unsigned long pixel;
1172 if (STRINGP (value))
1173 pixel = x_decode_color (f, value, BLACK_PIX_DEFAULT (f));
1174 else
1175 pixel = -1;
1177 if (f->output_data.x->scroll_bar_foreground_pixel != -1)
1178 unload_color (f, f->output_data.x->scroll_bar_foreground_pixel);
1180 f->output_data.x->scroll_bar_foreground_pixel = pixel;
1181 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1183 /* Remove all scroll bars because they have wrong colors. */
1184 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1185 (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1186 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1187 (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1189 update_face_from_frame_parameter (f, Qscroll_bar_foreground, value);
1190 redraw_frame (f);
1195 /* Set the background color for scroll bars on frame F to VALUE VALUE
1196 should be a string, a color name. If it isn't a string or isn't a
1197 valid color name, do nothing. OLDVAL is the old value of the frame
1198 parameter. */
1200 static void
1201 x_set_scroll_bar_background (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1203 unsigned long pixel;
1205 if (STRINGP (value))
1206 pixel = x_decode_color (f, value, WHITE_PIX_DEFAULT (f));
1207 else
1208 pixel = -1;
1210 if (f->output_data.x->scroll_bar_background_pixel != -1)
1211 unload_color (f, f->output_data.x->scroll_bar_background_pixel);
1213 #ifdef USE_TOOLKIT_SCROLL_BARS
1214 /* Scrollbar shadow colors. */
1215 if (f->output_data.x->scroll_bar_top_shadow_pixel != -1)
1217 unload_color (f, f->output_data.x->scroll_bar_top_shadow_pixel);
1218 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
1220 if (f->output_data.x->scroll_bar_bottom_shadow_pixel != -1)
1222 unload_color (f, f->output_data.x->scroll_bar_bottom_shadow_pixel);
1223 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
1225 #endif /* USE_TOOLKIT_SCROLL_BARS */
1227 f->output_data.x->scroll_bar_background_pixel = pixel;
1228 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1230 /* Remove all scroll bars because they have wrong colors. */
1231 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1232 (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1233 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1234 (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1236 update_face_from_frame_parameter (f, Qscroll_bar_background, value);
1237 redraw_frame (f);
1242 /* Encode Lisp string STRING as a text in a format appropriate for
1243 XICCC (X Inter Client Communication Conventions).
1245 This can call Lisp code, so callers must GCPRO.
1247 If STRING contains only ASCII characters, do no conversion and
1248 return the string data of STRING. Otherwise, encode the text by
1249 CODING_SYSTEM, and return a newly allocated memory area which
1250 should be freed by `xfree' by a caller.
1252 SELECTIONP non-zero means the string is being encoded for an X
1253 selection, so it is safe to run pre-write conversions (which
1254 may run Lisp code).
1256 Store the byte length of resulting text in *TEXT_BYTES.
1258 If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
1259 which means that the `encoding' of the result can be `STRING'.
1260 Otherwise store 0 in *STRINGP, which means that the `encoding' of
1261 the result should be `COMPOUND_TEXT'. */
1263 static unsigned char *
1264 x_encode_text (Lisp_Object string, Lisp_Object coding_system, int selectionp,
1265 ptrdiff_t *text_bytes, int *stringp, int *freep)
1267 int result = string_xstring_p (string);
1268 struct coding_system coding;
1270 if (result == 0)
1272 /* No multibyte character in OBJ. We need not encode it. */
1273 *text_bytes = SBYTES (string);
1274 *stringp = 1;
1275 *freep = 0;
1276 return SDATA (string);
1279 setup_coding_system (coding_system, &coding);
1280 coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK);
1281 /* We suppress producing escape sequences for composition. */
1282 coding.common_flags &= ~CODING_ANNOTATION_MASK;
1283 coding.destination = xnmalloc (SCHARS (string), 2);
1284 coding.dst_bytes = SCHARS (string) * 2;
1285 encode_coding_object (&coding, string, 0, 0,
1286 SCHARS (string), SBYTES (string), Qnil);
1287 *text_bytes = coding.produced;
1288 *stringp = (result == 1 || !EQ (coding_system, Qcompound_text));
1289 *freep = 1;
1290 return coding.destination;
1294 /* Set the WM name to NAME for frame F. Also set the icon name.
1295 If the frame already has an icon name, use that, otherwise set the
1296 icon name to NAME. */
1298 static void
1299 x_set_name_internal (struct frame *f, Lisp_Object name)
1301 if (FRAME_X_WINDOW (f))
1303 block_input ();
1305 XTextProperty text, icon;
1306 ptrdiff_t bytes;
1307 int stringp;
1308 int do_free_icon_value = 0, do_free_text_value = 0;
1309 Lisp_Object coding_system;
1310 Lisp_Object encoded_name;
1311 Lisp_Object encoded_icon_name;
1312 struct gcpro gcpro1;
1314 /* As ENCODE_UTF_8 may cause GC and relocation of string data,
1315 we use it before x_encode_text that may return string data. */
1316 GCPRO1 (name);
1317 encoded_name = ENCODE_UTF_8 (name);
1318 UNGCPRO;
1320 coding_system = Qcompound_text;
1321 /* Note: Encoding strategy
1323 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1324 text.encoding. But, there are non-internationalized window
1325 managers which don't support that encoding. So, if NAME
1326 contains only ASCII and 8859-1 characters, encode it by
1327 iso-latin-1, and use "STRING" in text.encoding hoping that
1328 such window managers at least analyze this format correctly,
1329 i.e. treat 8-bit bytes as 8859-1 characters.
1331 We may also be able to use "UTF8_STRING" in text.encoding
1332 in the future which can encode all Unicode characters.
1333 But, for the moment, there's no way to know that the
1334 current window manager supports it or not.
1336 Either way, we also set the _NET_WM_NAME and _NET_WM_ICON_NAME
1337 properties. Per the EWMH specification, those two properties
1338 are always UTF8_STRING. This matches what gtk_window_set_title()
1339 does in the USE_GTK case. */
1340 text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp,
1341 &do_free_text_value);
1342 text.encoding = (stringp ? XA_STRING
1343 : FRAME_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1344 text.format = 8;
1345 text.nitems = bytes;
1346 if (text.nitems != bytes)
1347 error ("Window name too large");
1349 if (!STRINGP (f->icon_name))
1351 icon = text;
1352 encoded_icon_name = encoded_name;
1354 else
1356 /* See the above comment "Note: Encoding strategy". */
1357 icon.value = x_encode_text (f->icon_name, coding_system, 0,
1358 &bytes, &stringp, &do_free_icon_value);
1359 icon.encoding = (stringp ? XA_STRING
1360 : FRAME_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1361 icon.format = 8;
1362 icon.nitems = bytes;
1363 if (icon.nitems != bytes)
1364 error ("Icon name too large");
1366 encoded_icon_name = ENCODE_UTF_8 (f->icon_name);
1369 #ifdef USE_GTK
1370 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
1371 SSDATA (encoded_name));
1372 #else /* not USE_GTK */
1373 XSetWMName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &text);
1374 XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
1375 FRAME_DISPLAY_INFO (f)->Xatom_net_wm_name,
1376 FRAME_DISPLAY_INFO (f)->Xatom_UTF8_STRING,
1377 8, PropModeReplace,
1378 SDATA (encoded_name),
1379 SBYTES (encoded_name));
1380 #endif /* not USE_GTK */
1382 XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &icon);
1383 XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
1384 FRAME_DISPLAY_INFO (f)->Xatom_net_wm_icon_name,
1385 FRAME_DISPLAY_INFO (f)->Xatom_UTF8_STRING,
1386 8, PropModeReplace,
1387 SDATA (encoded_icon_name),
1388 SBYTES (encoded_icon_name));
1390 if (do_free_icon_value)
1391 xfree (icon.value);
1392 if (do_free_text_value)
1393 xfree (text.value);
1395 unblock_input ();
1399 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1400 x_id_name.
1402 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1403 name; if NAME is a string, set F's name to NAME and set
1404 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1406 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1407 suggesting a new name, which lisp code should override; if
1408 F->explicit_name is set, ignore the new name; otherwise, set it. */
1410 static void
1411 x_set_name (struct frame *f, Lisp_Object name, int explicit)
1413 /* Make sure that requests from lisp code override requests from
1414 Emacs redisplay code. */
1415 if (explicit)
1417 /* If we're switching from explicit to implicit, we had better
1418 update the mode lines and thereby update the title. */
1419 if (f->explicit_name && NILP (name))
1420 update_mode_lines = 37;
1422 f->explicit_name = ! NILP (name);
1424 else if (f->explicit_name)
1425 return;
1427 /* If NAME is nil, set the name to the x_id_name. */
1428 if (NILP (name))
1430 /* Check for no change needed in this very common case
1431 before we do any consing. */
1432 if (!strcmp (FRAME_DISPLAY_INFO (f)->x_id_name,
1433 SSDATA (f->name)))
1434 return;
1435 name = build_string (FRAME_DISPLAY_INFO (f)->x_id_name);
1437 else
1438 CHECK_STRING (name);
1440 /* Don't change the name if it's already NAME. */
1441 if (! NILP (Fstring_equal (name, f->name)))
1442 return;
1444 fset_name (f, name);
1446 /* For setting the frame title, the title parameter should override
1447 the name parameter. */
1448 if (! NILP (f->title))
1449 name = f->title;
1451 x_set_name_internal (f, name);
1454 /* This function should be called when the user's lisp code has
1455 specified a name for the frame; the name will override any set by the
1456 redisplay code. */
1457 static void
1458 x_explicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1460 x_set_name (f, arg, 1);
1463 /* This function should be called by Emacs redisplay code to set the
1464 name; names set this way will never override names set by the user's
1465 lisp code. */
1466 void
1467 x_implicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1469 x_set_name (f, arg, 0);
1472 /* Change the title of frame F to NAME.
1473 If NAME is nil, use the frame name as the title. */
1475 static void
1476 x_set_title (struct frame *f, Lisp_Object name, Lisp_Object old_name)
1478 /* Don't change the title if it's already NAME. */
1479 if (EQ (name, f->title))
1480 return;
1482 update_mode_lines = 38;
1484 fset_title (f, name);
1486 if (NILP (name))
1487 name = f->name;
1488 else
1489 CHECK_STRING (name);
1491 x_set_name_internal (f, name);
1494 void
1495 x_set_scroll_bar_default_width (struct frame *f)
1497 int unit = FRAME_COLUMN_WIDTH (f);
1498 #ifdef USE_TOOLKIT_SCROLL_BARS
1499 #ifdef USE_GTK
1500 int minw = xg_get_default_scrollbar_width ();
1501 #else
1502 int minw = 16;
1503 #endif
1504 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
1505 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (minw + unit - 1) / unit;
1506 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = minw;
1507 #else
1508 /* The width of a non-toolkit scrollbar is at least 14 pixels and a
1509 multiple of the frame's character width. */
1510 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + unit - 1) / unit;
1511 FRAME_CONFIG_SCROLL_BAR_WIDTH (f)
1512 = FRAME_CONFIG_SCROLL_BAR_COLS (f) * unit;
1513 #endif
1517 /* Record in frame F the specified or default value according to ALIST
1518 of the parameter named PROP (a Lisp symbol). If no value is
1519 specified for PROP, look for an X default for XPROP on the frame
1520 named NAME. If that is not found either, use the value DEFLT. */
1522 static Lisp_Object
1523 x_default_scroll_bar_color_parameter (struct frame *f,
1524 Lisp_Object alist, Lisp_Object prop,
1525 const char *xprop, const char *xclass,
1526 int foreground_p)
1528 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
1529 Lisp_Object tem;
1531 tem = x_get_arg (dpyinfo, alist, prop, xprop, xclass, RES_TYPE_STRING);
1532 if (EQ (tem, Qunbound))
1534 #ifdef USE_TOOLKIT_SCROLL_BARS
1536 /* See if an X resource for the scroll bar color has been
1537 specified. */
1538 tem = display_x_get_resource (dpyinfo,
1539 build_string (foreground_p
1540 ? "foreground"
1541 : "background"),
1542 empty_unibyte_string,
1543 build_string ("verticalScrollBar"),
1544 empty_unibyte_string);
1545 if (!STRINGP (tem))
1547 /* If nothing has been specified, scroll bars will use a
1548 toolkit-dependent default. Because these defaults are
1549 difficult to get at without actually creating a scroll
1550 bar, use nil to indicate that no color has been
1551 specified. */
1552 tem = Qnil;
1555 #else /* not USE_TOOLKIT_SCROLL_BARS */
1557 tem = Qnil;
1559 #endif /* not USE_TOOLKIT_SCROLL_BARS */
1562 x_set_frame_parameters (f, list1 (Fcons (prop, tem)));
1563 return tem;
1569 #ifdef USE_X_TOOLKIT
1571 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
1572 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
1573 already be present because of the toolkit (Motif adds some of them,
1574 for example, but Xt doesn't). */
1576 static void
1577 hack_wm_protocols (struct frame *f, Widget widget)
1579 Display *dpy = XtDisplay (widget);
1580 Window w = XtWindow (widget);
1581 int need_delete = 1;
1582 int need_focus = 1;
1583 int need_save = 1;
1585 block_input ();
1587 Atom type;
1588 unsigned char *catoms;
1589 int format = 0;
1590 unsigned long nitems = 0;
1591 unsigned long bytes_after;
1593 if ((XGetWindowProperty (dpy, w,
1594 FRAME_DISPLAY_INFO (f)->Xatom_wm_protocols,
1595 (long)0, (long)100, False, XA_ATOM,
1596 &type, &format, &nitems, &bytes_after,
1597 &catoms)
1598 == Success)
1599 && format == 32 && type == XA_ATOM)
1601 Atom *atoms = (Atom *) catoms;
1602 while (nitems > 0)
1604 nitems--;
1605 if (atoms[nitems]
1606 == FRAME_DISPLAY_INFO (f)->Xatom_wm_delete_window)
1607 need_delete = 0;
1608 else if (atoms[nitems]
1609 == FRAME_DISPLAY_INFO (f)->Xatom_wm_take_focus)
1610 need_focus = 0;
1611 else if (atoms[nitems]
1612 == FRAME_DISPLAY_INFO (f)->Xatom_wm_save_yourself)
1613 need_save = 0;
1616 if (catoms)
1617 XFree (catoms);
1620 Atom props [10];
1621 int count = 0;
1622 if (need_delete)
1623 props[count++] = FRAME_DISPLAY_INFO (f)->Xatom_wm_delete_window;
1624 if (need_focus)
1625 props[count++] = FRAME_DISPLAY_INFO (f)->Xatom_wm_take_focus;
1626 if (need_save)
1627 props[count++] = FRAME_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
1628 if (count)
1629 XChangeProperty (dpy, w, FRAME_DISPLAY_INFO (f)->Xatom_wm_protocols,
1630 XA_ATOM, 32, PropModeAppend,
1631 (unsigned char *) props, count);
1633 unblock_input ();
1635 #endif
1639 /* Support routines for XIC (X Input Context). */
1641 #ifdef HAVE_X_I18N
1643 static XFontSet xic_create_xfontset (struct frame *);
1644 static XIMStyle best_xim_style (XIMStyles *, XIMStyles *);
1647 /* Supported XIM styles, ordered by preference. */
1649 static XIMStyle supported_xim_styles[] =
1651 XIMPreeditPosition | XIMStatusArea,
1652 XIMPreeditPosition | XIMStatusNothing,
1653 XIMPreeditPosition | XIMStatusNone,
1654 XIMPreeditNothing | XIMStatusArea,
1655 XIMPreeditNothing | XIMStatusNothing,
1656 XIMPreeditNothing | XIMStatusNone,
1657 XIMPreeditNone | XIMStatusArea,
1658 XIMPreeditNone | XIMStatusNothing,
1659 XIMPreeditNone | XIMStatusNone,
1664 #if defined HAVE_X_WINDOWS && defined USE_X_TOOLKIT
1665 /* Create an X fontset on frame F with base font name BASE_FONTNAME. */
1667 static const char xic_default_fontset[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
1669 /* Create an Xt fontset spec from the name of a base font.
1670 If `motif' is True use the Motif syntax. */
1671 char *
1672 xic_create_fontsetname (const char *base_fontname, int motif)
1674 const char *sep = motif ? ";" : ",";
1675 char *fontsetname;
1677 /* Make a fontset name from the base font name. */
1678 if (xic_default_fontset == base_fontname)
1680 /* There is no base font name, use the default. */
1681 fontsetname = xmalloc (strlen (base_fontname) + 2);
1682 strcpy (fontsetname, base_fontname);
1684 else
1686 /* Make a fontset name from the base font name.
1687 The font set will be made of the following elements:
1688 - the base font.
1689 - the base font where the charset spec is replaced by -*-*.
1690 - the same but with the family also replaced with -*-*-. */
1691 const char *p = base_fontname;
1692 ptrdiff_t i;
1694 for (i = 0; *p; p++)
1695 if (*p == '-') i++;
1696 if (i != 14)
1698 /* As the font name doesn't conform to XLFD, we can't
1699 modify it to generalize it to allcs and allfamilies.
1700 Use the specified font plus the default. */
1701 fontsetname = xmalloc (strlen (base_fontname)
1702 + strlen (xic_default_fontset) + 3);
1703 strcpy (fontsetname, base_fontname);
1704 strcat (fontsetname, sep);
1705 strcat (fontsetname, xic_default_fontset);
1707 else
1709 ptrdiff_t len;
1710 const char *p1 = NULL, *p2 = NULL, *p3 = NULL;
1711 char *font_allcs = NULL;
1712 char *font_allfamilies = NULL;
1713 char *font_all = NULL;
1714 const char *allcs = "*-*-*-*-*-*-*";
1715 const char *allfamilies = "-*-*-";
1716 const char *all = "*-*-*-*-";
1717 char *base;
1719 for (i = 0, p = base_fontname; i < 8; p++)
1721 if (*p == '-')
1723 i++;
1724 if (i == 3)
1725 p1 = p + 1;
1726 else if (i == 7)
1727 p2 = p + 1;
1728 else if (i == 6)
1729 p3 = p + 1;
1732 /* If base_fontname specifies ADSTYLE, make it a
1733 wildcard. */
1734 if (*p3 != '*')
1736 ptrdiff_t diff = (p2 - p3) - 2;
1738 base = alloca (strlen (base_fontname) + 1);
1739 memcpy (base, base_fontname, p3 - base_fontname);
1740 base[p3 - base_fontname] = '*';
1741 base[(p3 - base_fontname) + 1] = '-';
1742 strcpy (base + (p3 - base_fontname) + 2, p2);
1743 p = base + (p - base_fontname) - diff;
1744 p1 = base + (p1 - base_fontname);
1745 p2 = base + (p2 - base_fontname) - diff;
1746 base_fontname = base;
1749 /* Build the font spec that matches all charsets. */
1750 len = p - base_fontname + strlen (allcs) + 1;
1751 font_allcs = alloca (len);
1752 memcpy (font_allcs, base_fontname, p - base_fontname);
1753 strcat (font_allcs, allcs);
1755 /* Build the font spec that matches all families and
1756 add-styles. */
1757 len = p - p1 + strlen (allcs) + strlen (allfamilies) + 1;
1758 font_allfamilies = alloca (len);
1759 strcpy (font_allfamilies, allfamilies);
1760 memcpy (font_allfamilies + strlen (allfamilies), p1, p - p1);
1761 strcat (font_allfamilies, allcs);
1763 /* Build the font spec that matches all. */
1764 len = p - p2 + strlen (allcs) + strlen (all) + strlen (allfamilies) + 1;
1765 font_all = alloca (len);
1766 strcpy (font_all, allfamilies);
1767 strcat (font_all, all);
1768 memcpy (font_all + strlen (all) + strlen (allfamilies), p2, p - p2);
1769 strcat (font_all, allcs);
1771 /* Build the actual font set name. */
1772 len = strlen (base_fontname) + strlen (font_allcs)
1773 + strlen (font_allfamilies) + strlen (font_all) + 5;
1774 fontsetname = xmalloc (len);
1775 strcpy (fontsetname, base_fontname);
1776 strcat (fontsetname, sep);
1777 strcat (fontsetname, font_allcs);
1778 strcat (fontsetname, sep);
1779 strcat (fontsetname, font_allfamilies);
1780 strcat (fontsetname, sep);
1781 strcat (fontsetname, font_all);
1784 if (motif)
1785 return strcat (fontsetname, ":");
1786 return fontsetname;
1788 #endif /* HAVE_X_WINDOWS && USE_X_TOOLKIT */
1790 #ifdef DEBUG_XIC_FONTSET
1791 static void
1792 print_fontset_result (XFontSet xfs, char *name, char **missing_list,
1793 int missing_count)
1795 if (xfs)
1796 fprintf (stderr, "XIC Fontset created: %s\n", name);
1797 else
1799 fprintf (stderr, "XIC Fontset failed: %s\n", name);
1800 while (missing_count-- > 0)
1802 fprintf (stderr, " missing: %s\n", *missing_list);
1803 missing_list++;
1808 #endif
1810 static XFontSet
1811 xic_create_xfontset (struct frame *f)
1813 XFontSet xfs = NULL;
1814 struct font *font = FRAME_FONT (f);
1815 int pixel_size = font->pixel_size;
1816 Lisp_Object rest, frame;
1818 /* See if there is another frame already using same fontset. */
1819 FOR_EACH_FRAME (rest, frame)
1821 struct frame *cf = XFRAME (frame);
1823 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
1824 && FRAME_DISPLAY_INFO (cf) == FRAME_DISPLAY_INFO (f)
1825 && FRAME_FONT (f)
1826 && FRAME_FONT (f)->pixel_size == pixel_size)
1828 xfs = FRAME_XIC_FONTSET (cf);
1829 break;
1833 if (! xfs)
1835 char buf[256];
1836 char **missing_list;
1837 int missing_count;
1838 char *def_string;
1839 const char *xlfd_format = "-*-*-medium-r-normal--%d-*-*-*-*-*";
1841 sprintf (buf, xlfd_format, pixel_size);
1842 missing_list = NULL;
1843 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
1844 &missing_list, &missing_count, &def_string);
1845 #ifdef DEBUG_XIC_FONTSET
1846 print_fontset_result (xfs, buf, missing_list, missing_count);
1847 #endif
1848 if (missing_list)
1849 XFreeStringList (missing_list);
1850 if (! xfs)
1852 /* List of pixel sizes most likely available. Find one that
1853 is closest to pixel_size. */
1854 int sizes[] = {0, 8, 10, 11, 12, 14, 17, 18, 20, 24, 26, 34, 0};
1855 int *smaller, *larger;
1857 for (smaller = sizes; smaller[1]; smaller++)
1858 if (smaller[1] >= pixel_size)
1859 break;
1860 larger = smaller + 1;
1861 if (*larger == pixel_size)
1862 larger++;
1863 while (*smaller || *larger)
1865 int this_size;
1867 if (! *larger)
1868 this_size = *smaller--;
1869 else if (! *smaller)
1870 this_size = *larger++;
1871 else if (pixel_size - *smaller < *larger - pixel_size)
1872 this_size = *smaller--;
1873 else
1874 this_size = *larger++;
1875 sprintf (buf, xlfd_format, this_size);
1876 missing_list = NULL;
1877 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
1878 &missing_list, &missing_count, &def_string);
1879 #ifdef DEBUG_XIC_FONTSET
1880 print_fontset_result (xfs, buf, missing_list, missing_count);
1881 #endif
1882 if (missing_list)
1883 XFreeStringList (missing_list);
1884 if (xfs)
1885 break;
1888 if (! xfs)
1890 const char *last_resort = "-*-*-*-r-normal--*-*-*-*-*-*";
1892 missing_list = NULL;
1893 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), last_resort,
1894 &missing_list, &missing_count, &def_string);
1895 #ifdef DEBUG_XIC_FONTSET
1896 print_fontset_result (xfs, last_resort, missing_list, missing_count);
1897 #endif
1898 if (missing_list)
1899 XFreeStringList (missing_list);
1904 return xfs;
1907 /* Free the X fontset of frame F if it is the last frame using it. */
1909 void
1910 xic_free_xfontset (struct frame *f)
1912 Lisp_Object rest, frame;
1913 bool shared_p = 0;
1915 if (!FRAME_XIC_FONTSET (f))
1916 return;
1918 /* See if there is another frame sharing the same fontset. */
1919 FOR_EACH_FRAME (rest, frame)
1921 struct frame *cf = XFRAME (frame);
1922 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
1923 && FRAME_DISPLAY_INFO (cf) == FRAME_DISPLAY_INFO (f)
1924 && FRAME_XIC_FONTSET (cf) == FRAME_XIC_FONTSET (f))
1926 shared_p = 1;
1927 break;
1931 if (!shared_p)
1932 /* The fontset is not used anymore. It is safe to free it. */
1933 XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f));
1935 FRAME_XIC_FONTSET (f) = NULL;
1939 /* Value is the best input style, given user preferences USER (already
1940 checked to be supported by Emacs), and styles supported by the
1941 input method XIM. */
1943 static XIMStyle
1944 best_xim_style (XIMStyles *user, XIMStyles *xim)
1946 int i, j;
1948 for (i = 0; i < user->count_styles; ++i)
1949 for (j = 0; j < xim->count_styles; ++j)
1950 if (user->supported_styles[i] == xim->supported_styles[j])
1951 return user->supported_styles[i];
1953 /* Return the default style. */
1954 return XIMPreeditNothing | XIMStatusNothing;
1957 /* Create XIC for frame F. */
1959 static XIMStyle xic_style;
1961 void
1962 create_frame_xic (struct frame *f)
1964 XIM xim;
1965 XIC xic = NULL;
1966 XFontSet xfs = NULL;
1968 if (FRAME_XIC (f))
1969 return;
1971 /* Create X fontset. */
1972 xfs = xic_create_xfontset (f);
1973 xim = FRAME_X_XIM (f);
1974 if (xim)
1976 XRectangle s_area;
1977 XPoint spot;
1978 XVaNestedList preedit_attr;
1979 XVaNestedList status_attr;
1981 s_area.x = 0; s_area.y = 0; s_area.width = 1; s_area.height = 1;
1982 spot.x = 0; spot.y = 1;
1984 /* Determine XIC style. */
1985 if (xic_style == 0)
1987 XIMStyles supported_list;
1988 supported_list.count_styles = (sizeof supported_xim_styles
1989 / sizeof supported_xim_styles[0]);
1990 supported_list.supported_styles = supported_xim_styles;
1991 xic_style = best_xim_style (&supported_list,
1992 FRAME_X_XIM_STYLES (f));
1995 preedit_attr = XVaCreateNestedList (0,
1996 XNFontSet, xfs,
1997 XNForeground,
1998 FRAME_FOREGROUND_PIXEL (f),
1999 XNBackground,
2000 FRAME_BACKGROUND_PIXEL (f),
2001 (xic_style & XIMPreeditPosition
2002 ? XNSpotLocation
2003 : NULL),
2004 &spot,
2005 NULL);
2006 status_attr = XVaCreateNestedList (0,
2007 XNArea,
2008 &s_area,
2009 XNFontSet,
2010 xfs,
2011 XNForeground,
2012 FRAME_FOREGROUND_PIXEL (f),
2013 XNBackground,
2014 FRAME_BACKGROUND_PIXEL (f),
2015 NULL);
2017 xic = XCreateIC (xim,
2018 XNInputStyle, xic_style,
2019 XNClientWindow, FRAME_X_WINDOW (f),
2020 XNFocusWindow, FRAME_X_WINDOW (f),
2021 XNStatusAttributes, status_attr,
2022 XNPreeditAttributes, preedit_attr,
2023 NULL);
2024 XFree (preedit_attr);
2025 XFree (status_attr);
2028 FRAME_XIC (f) = xic;
2029 FRAME_XIC_STYLE (f) = xic_style;
2030 FRAME_XIC_FONTSET (f) = xfs;
2034 /* Destroy XIC and free XIC fontset of frame F, if any. */
2036 void
2037 free_frame_xic (struct frame *f)
2039 if (FRAME_XIC (f) == NULL)
2040 return;
2042 XDestroyIC (FRAME_XIC (f));
2043 xic_free_xfontset (f);
2045 FRAME_XIC (f) = NULL;
2049 /* Place preedit area for XIC of window W's frame to specified
2050 pixel position X/Y. X and Y are relative to window W. */
2052 void
2053 xic_set_preeditarea (struct window *w, int x, int y)
2055 struct frame *f = XFRAME (w->frame);
2056 XVaNestedList attr;
2057 XPoint spot;
2059 spot.x = WINDOW_TO_FRAME_PIXEL_X (w, x) + WINDOW_LEFT_FRINGE_WIDTH (w);
2060 spot.y = WINDOW_TO_FRAME_PIXEL_Y (w, y) + FONT_BASE (FRAME_FONT (f));
2061 attr = XVaCreateNestedList (0, XNSpotLocation, &spot, NULL);
2062 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2063 XFree (attr);
2067 /* Place status area for XIC in bottom right corner of frame F.. */
2069 void
2070 xic_set_statusarea (struct frame *f)
2072 XIC xic = FRAME_XIC (f);
2073 XVaNestedList attr;
2074 XRectangle area;
2075 XRectangle *needed;
2077 /* Negotiate geometry of status area. If input method has existing
2078 status area, use its current size. */
2079 area.x = area.y = area.width = area.height = 0;
2080 attr = XVaCreateNestedList (0, XNAreaNeeded, &area, NULL);
2081 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2082 XFree (attr);
2084 attr = XVaCreateNestedList (0, XNAreaNeeded, &needed, NULL);
2085 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2086 XFree (attr);
2088 if (needed->width == 0) /* Use XNArea instead of XNAreaNeeded */
2090 attr = XVaCreateNestedList (0, XNArea, &needed, NULL);
2091 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2092 XFree (attr);
2095 area.width = needed->width;
2096 area.height = needed->height;
2097 area.x = FRAME_PIXEL_WIDTH (f) - area.width - FRAME_INTERNAL_BORDER_WIDTH (f);
2098 area.y = (FRAME_PIXEL_HEIGHT (f) - area.height
2099 - FRAME_MENUBAR_HEIGHT (f)
2100 - FRAME_TOOLBAR_TOP_HEIGHT (f)
2101 - FRAME_INTERNAL_BORDER_WIDTH (f));
2102 XFree (needed);
2104 attr = XVaCreateNestedList (0, XNArea, &area, NULL);
2105 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2106 XFree (attr);
2110 /* Set X fontset for XIC of frame F, using base font name
2111 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2113 void
2114 xic_set_xfontset (struct frame *f, const char *base_fontname)
2116 XVaNestedList attr;
2117 XFontSet xfs;
2119 xic_free_xfontset (f);
2121 xfs = xic_create_xfontset (f);
2123 attr = XVaCreateNestedList (0, XNFontSet, xfs, NULL);
2124 if (FRAME_XIC_STYLE (f) & XIMPreeditPosition)
2125 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2126 if (FRAME_XIC_STYLE (f) & XIMStatusArea)
2127 XSetICValues (FRAME_XIC (f), XNStatusAttributes, attr, NULL);
2128 XFree (attr);
2130 FRAME_XIC_FONTSET (f) = xfs;
2133 #endif /* HAVE_X_I18N */
2137 #ifdef USE_X_TOOLKIT
2139 /* Create and set up the X widget for frame F. */
2141 static void
2142 x_window (struct frame *f, long window_prompting, int minibuffer_only)
2144 XClassHint class_hints;
2145 XSetWindowAttributes attributes;
2146 unsigned long attribute_mask;
2147 Widget shell_widget;
2148 Widget pane_widget;
2149 Widget frame_widget;
2150 Arg al [25];
2151 int ac;
2153 block_input ();
2155 /* Use the resource name as the top-level widget name
2156 for looking up resources. Make a non-Lisp copy
2157 for the window manager, so GC relocation won't bother it.
2159 Elsewhere we specify the window name for the window manager. */
2160 f->namebuf = xstrdup (SSDATA (Vx_resource_name));
2162 ac = 0;
2163 XtSetArg (al[ac], XtNallowShellResize, 1); ac++;
2164 XtSetArg (al[ac], XtNinput, 1); ac++;
2165 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2166 XtSetArg (al[ac], XtNborderWidth, f->border_width); ac++;
2167 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2168 XtSetArg (al[ac], XtNdepth, FRAME_DISPLAY_INFO (f)->n_planes); ac++;
2169 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2170 shell_widget = XtAppCreateShell (f->namebuf, EMACS_CLASS,
2171 applicationShellWidgetClass,
2172 FRAME_X_DISPLAY (f), al, ac);
2174 f->output_data.x->widget = shell_widget;
2175 /* maybe_set_screen_title_format (shell_widget); */
2177 pane_widget = lw_create_widget ("main", "pane", widget_id_tick++,
2178 NULL, shell_widget, False,
2179 NULL, NULL, NULL, NULL);
2181 ac = 0;
2182 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2183 XtSetArg (al[ac], XtNdepth, FRAME_DISPLAY_INFO (f)->n_planes); ac++;
2184 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2185 XtSetArg (al[ac], XtNborderWidth, 0); ac++;
2186 XtSetValues (pane_widget, al, ac);
2187 f->output_data.x->column_widget = pane_widget;
2189 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2190 the emacs screen when changing menubar. This reduces flickering. */
2192 ac = 0;
2193 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2194 XtSetArg (al[ac], XtNshowGrip, 0); ac++;
2195 XtSetArg (al[ac], XtNallowResize, 1); ac++;
2196 XtSetArg (al[ac], XtNresizeToPreferred, 1); ac++;
2197 XtSetArg (al[ac], XtNemacsFrame, f); ac++;
2198 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2199 XtSetArg (al[ac], XtNdepth, FRAME_DISPLAY_INFO (f)->n_planes); ac++;
2200 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2201 XtSetArg (al[ac], XtNborderWidth, 0); ac++;
2202 frame_widget = XtCreateWidget (f->namebuf, emacsFrameClass, pane_widget,
2203 al, ac);
2205 f->output_data.x->edit_widget = frame_widget;
2207 XtManageChild (frame_widget);
2209 /* Do some needed geometry management. */
2211 char *tem, shell_position[sizeof "=x++" + 4 * INT_STRLEN_BOUND (int)];
2212 Arg gal[10];
2213 int gac = 0;
2214 int extra_borders = 0;
2215 int menubar_size
2216 = (f->output_data.x->menubar_widget
2217 ? (f->output_data.x->menubar_widget->core.height
2218 + f->output_data.x->menubar_widget->core.border_width)
2219 : 0);
2221 #if 0 /* Experimentally, we now get the right results
2222 for -geometry -0-0 without this. 24 Aug 96, rms. */
2223 if (FRAME_EXTERNAL_MENU_BAR (f))
2225 Dimension ibw = 0;
2226 XtVaGetValues (pane_widget, XtNinternalBorderWidth, &ibw, NULL);
2227 menubar_size += ibw;
2229 #endif
2231 f->output_data.x->menubar_height = menubar_size;
2233 #ifndef USE_LUCID
2234 /* Motif seems to need this amount added to the sizes
2235 specified for the shell widget. The Athena/Lucid widgets don't.
2236 Both conclusions reached experimentally. -- rms. */
2237 XtVaGetValues (f->output_data.x->edit_widget, XtNinternalBorderWidth,
2238 &extra_borders, NULL);
2239 extra_borders *= 2;
2240 #endif
2242 /* Convert our geometry parameters into a geometry string
2243 and specify it.
2244 Note that we do not specify here whether the position
2245 is a user-specified or program-specified one.
2246 We pass that information later, in x_wm_set_size_hints. */
2248 int left = f->left_pos;
2249 int xneg = window_prompting & XNegative;
2250 int top = f->top_pos;
2251 int yneg = window_prompting & YNegative;
2252 if (xneg)
2253 left = -left;
2254 if (yneg)
2255 top = -top;
2257 if (window_prompting & USPosition)
2258 sprintf (shell_position, "=%dx%d%c%d%c%d",
2259 FRAME_PIXEL_WIDTH (f) + extra_borders,
2260 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders,
2261 (xneg ? '-' : '+'), left,
2262 (yneg ? '-' : '+'), top);
2263 else
2265 sprintf (shell_position, "=%dx%d",
2266 FRAME_PIXEL_WIDTH (f) + extra_borders,
2267 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders);
2269 /* Setting x and y when the position is not specified in
2270 the geometry string will set program position in the WM hints.
2271 If Emacs had just one program position, we could set it in
2272 fallback resources, but since each make-frame call can specify
2273 different program positions, this is easier. */
2274 XtSetArg (gal[gac], XtNx, left); gac++;
2275 XtSetArg (gal[gac], XtNy, top); gac++;
2279 /* We don't free this because we don't know whether
2280 it is safe to free it while the frame exists.
2281 It isn't worth the trouble of arranging to free it
2282 when the frame is deleted. */
2283 tem = xstrdup (shell_position);
2284 XtSetArg (gal[gac], XtNgeometry, tem); gac++;
2285 XtSetValues (shell_widget, gal, gac);
2288 XtManageChild (pane_widget);
2289 XtRealizeWidget (shell_widget);
2291 if (FRAME_X_EMBEDDED_P (f))
2292 XReparentWindow (FRAME_X_DISPLAY (f), XtWindow (shell_widget),
2293 f->output_data.x->parent_desc, 0, 0);
2295 FRAME_X_WINDOW (f) = XtWindow (frame_widget);
2297 validate_x_resource_name ();
2299 class_hints.res_name = SSDATA (Vx_resource_name);
2300 class_hints.res_class = SSDATA (Vx_resource_class);
2301 XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints);
2303 #ifdef HAVE_X_I18N
2304 FRAME_XIC (f) = NULL;
2305 if (use_xim)
2306 create_frame_xic (f);
2307 #endif
2309 f->output_data.x->wm_hints.input = True;
2310 f->output_data.x->wm_hints.flags |= InputHint;
2311 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2312 &f->output_data.x->wm_hints);
2314 hack_wm_protocols (f, shell_widget);
2316 #ifdef HACK_EDITRES
2317 XtAddEventHandler (shell_widget, 0, True, _XEditResCheckMessages, 0);
2318 #endif
2320 /* Do a stupid property change to force the server to generate a
2321 PropertyNotify event so that the event_stream server timestamp will
2322 be initialized to something relevant to the time we created the window.
2324 XChangeProperty (XtDisplay (frame_widget), XtWindow (frame_widget),
2325 FRAME_DISPLAY_INFO (f)->Xatom_wm_protocols,
2326 XA_ATOM, 32, PropModeAppend, NULL, 0);
2328 /* Make all the standard events reach the Emacs frame. */
2329 attributes.event_mask = STANDARD_EVENT_SET;
2331 #ifdef HAVE_X_I18N
2332 if (FRAME_XIC (f))
2334 /* XIM server might require some X events. */
2335 unsigned long fevent = NoEventMask;
2336 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2337 attributes.event_mask |= fevent;
2339 #endif /* HAVE_X_I18N */
2341 attribute_mask = CWEventMask;
2342 XChangeWindowAttributes (XtDisplay (shell_widget), XtWindow (shell_widget),
2343 attribute_mask, &attributes);
2345 XtMapWidget (frame_widget);
2347 /* x_set_name normally ignores requests to set the name if the
2348 requested name is the same as the current name. This is the one
2349 place where that assumption isn't correct; f->name is set, but
2350 the X server hasn't been told. */
2352 Lisp_Object name;
2353 int explicit = f->explicit_name;
2355 f->explicit_name = 0;
2356 name = f->name;
2357 fset_name (f, Qnil);
2358 x_set_name (f, name, explicit);
2361 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2362 f->output_data.x->current_cursor
2363 = f->output_data.x->text_cursor);
2365 unblock_input ();
2367 /* This is a no-op, except under Motif. Make sure main areas are
2368 set to something reasonable, in case we get an error later. */
2369 lw_set_main_areas (pane_widget, 0, frame_widget);
2372 #else /* not USE_X_TOOLKIT */
2373 #ifdef USE_GTK
2374 static void
2375 x_window (struct frame *f)
2377 if (! xg_create_frame_widgets (f))
2378 error ("Unable to create window");
2380 #ifdef HAVE_X_I18N
2381 FRAME_XIC (f) = NULL;
2382 if (use_xim)
2384 block_input ();
2385 create_frame_xic (f);
2386 if (FRAME_XIC (f))
2388 /* XIM server might require some X events. */
2389 unsigned long fevent = NoEventMask;
2390 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2392 if (fevent != NoEventMask)
2394 XSetWindowAttributes attributes;
2395 XWindowAttributes wattr;
2396 unsigned long attribute_mask;
2398 XGetWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2399 &wattr);
2400 attributes.event_mask = wattr.your_event_mask | fevent;
2401 attribute_mask = CWEventMask;
2402 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2403 attribute_mask, &attributes);
2406 unblock_input ();
2408 #endif
2411 #else /*! USE_GTK */
2412 /* Create and set up the X window for frame F. */
2414 static void
2415 x_window (struct frame *f)
2417 XClassHint class_hints;
2418 XSetWindowAttributes attributes;
2419 unsigned long attribute_mask;
2421 attributes.background_pixel = FRAME_BACKGROUND_PIXEL (f);
2422 attributes.border_pixel = f->output_data.x->border_pixel;
2423 attributes.bit_gravity = StaticGravity;
2424 attributes.backing_store = NotUseful;
2425 attributes.save_under = True;
2426 attributes.event_mask = STANDARD_EVENT_SET;
2427 attributes.colormap = FRAME_X_COLORMAP (f);
2428 attribute_mask = (CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask
2429 | CWColormap);
2431 block_input ();
2432 FRAME_X_WINDOW (f)
2433 = XCreateWindow (FRAME_X_DISPLAY (f),
2434 f->output_data.x->parent_desc,
2435 f->left_pos,
2436 f->top_pos,
2437 FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
2438 f->border_width,
2439 CopyFromParent, /* depth */
2440 InputOutput, /* class */
2441 FRAME_X_VISUAL (f),
2442 attribute_mask, &attributes);
2444 #ifdef HAVE_X_I18N
2445 if (use_xim)
2447 create_frame_xic (f);
2448 if (FRAME_XIC (f))
2450 /* XIM server might require some X events. */
2451 unsigned long fevent = NoEventMask;
2452 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2453 attributes.event_mask |= fevent;
2454 attribute_mask = CWEventMask;
2455 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2456 attribute_mask, &attributes);
2459 #endif /* HAVE_X_I18N */
2461 validate_x_resource_name ();
2463 class_hints.res_name = SSDATA (Vx_resource_name);
2464 class_hints.res_class = SSDATA (Vx_resource_class);
2465 XSetClassHint (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &class_hints);
2467 /* The menubar is part of the ordinary display;
2468 it does not count in addition to the height of the window. */
2469 f->output_data.x->menubar_height = 0;
2471 /* This indicates that we use the "Passive Input" input model.
2472 Unless we do this, we don't get the Focus{In,Out} events that we
2473 need to draw the cursor correctly. Accursed bureaucrats.
2474 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2476 f->output_data.x->wm_hints.input = True;
2477 f->output_data.x->wm_hints.flags |= InputHint;
2478 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2479 &f->output_data.x->wm_hints);
2480 f->output_data.x->wm_hints.icon_pixmap = None;
2482 /* Request "save yourself" and "delete window" commands from wm. */
2484 Atom protocols[2];
2485 protocols[0] = FRAME_DISPLAY_INFO (f)->Xatom_wm_delete_window;
2486 protocols[1] = FRAME_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
2487 XSetWMProtocols (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), protocols, 2);
2490 /* x_set_name normally ignores requests to set the name if the
2491 requested name is the same as the current name. This is the one
2492 place where that assumption isn't correct; f->name is set, but
2493 the X server hasn't been told. */
2495 Lisp_Object name;
2496 int explicit = f->explicit_name;
2498 f->explicit_name = 0;
2499 name = f->name;
2500 fset_name (f, Qnil);
2501 x_set_name (f, name, explicit);
2504 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2505 f->output_data.x->current_cursor
2506 = f->output_data.x->text_cursor);
2508 unblock_input ();
2510 if (FRAME_X_WINDOW (f) == 0)
2511 error ("Unable to create window");
2514 #endif /* not USE_GTK */
2515 #endif /* not USE_X_TOOLKIT */
2517 /* Verify that the icon position args for this window are valid. */
2519 static void
2520 x_icon_verify (struct frame *f, Lisp_Object parms)
2522 Lisp_Object icon_x, icon_y;
2524 /* Set the position of the icon. Note that twm groups all
2525 icons in an icon window. */
2526 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2527 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2528 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2530 CHECK_NUMBER (icon_x);
2531 CHECK_NUMBER (icon_y);
2533 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2534 error ("Both left and top icon corners of icon must be specified");
2537 /* Handle the icon stuff for this window. Perhaps later we might
2538 want an x_set_icon_position which can be called interactively as
2539 well. */
2541 static void
2542 x_icon (struct frame *f, Lisp_Object parms)
2544 Lisp_Object icon_x, icon_y;
2545 #if 0
2546 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2547 #endif
2549 /* Set the position of the icon. Note that twm groups all
2550 icons in an icon window. */
2551 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2552 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2553 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2555 CHECK_TYPE_RANGED_INTEGER (int, icon_x);
2556 CHECK_TYPE_RANGED_INTEGER (int, icon_y);
2558 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2559 error ("Both left and top icon corners of icon must be specified");
2561 block_input ();
2563 if (! EQ (icon_x, Qunbound))
2564 x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
2566 #if 0 /* x_get_arg removes the visibility parameter as a side effect,
2567 but x_create_frame still needs it. */
2568 /* Start up iconic or window? */
2569 x_wm_set_window_state
2570 (f, (EQ (x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL),
2571 Qicon)
2572 ? IconicState
2573 : NormalState));
2574 #endif
2576 x_text_icon (f, SSDATA ((!NILP (f->icon_name)
2577 ? f->icon_name
2578 : f->name)));
2580 unblock_input ();
2583 /* Make the GCs needed for this window, setting the
2584 background, border and mouse colors; also create the
2585 mouse cursor and the gray border tile. */
2587 static void
2588 x_make_gc (struct frame *f)
2590 XGCValues gc_values;
2592 block_input ();
2594 /* Create the GCs of this frame.
2595 Note that many default values are used. */
2597 gc_values.foreground = FRAME_FOREGROUND_PIXEL (f);
2598 gc_values.background = FRAME_BACKGROUND_PIXEL (f);
2599 gc_values.line_width = 0; /* Means 1 using fast algorithm. */
2600 f->output_data.x->normal_gc
2601 = XCreateGC (FRAME_X_DISPLAY (f),
2602 FRAME_X_WINDOW (f),
2603 GCLineWidth | GCForeground | GCBackground,
2604 &gc_values);
2606 /* Reverse video style. */
2607 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2608 gc_values.background = FRAME_FOREGROUND_PIXEL (f);
2609 f->output_data.x->reverse_gc
2610 = XCreateGC (FRAME_X_DISPLAY (f),
2611 FRAME_X_WINDOW (f),
2612 GCForeground | GCBackground | GCLineWidth,
2613 &gc_values);
2615 /* Cursor has cursor-color background, background-color foreground. */
2616 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2617 gc_values.background = f->output_data.x->cursor_pixel;
2618 gc_values.fill_style = FillOpaqueStippled;
2619 f->output_data.x->cursor_gc
2620 = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2621 (GCForeground | GCBackground
2622 | GCFillStyle | GCLineWidth),
2623 &gc_values);
2625 /* Create the gray border tile used when the pointer is not in
2626 the frame. Since this depends on the frame's pixel values,
2627 this must be done on a per-frame basis. */
2628 f->output_data.x->border_tile
2629 = (XCreatePixmapFromBitmapData
2630 (FRAME_X_DISPLAY (f), FRAME_DISPLAY_INFO (f)->root_window,
2631 gray_bits, gray_width, gray_height,
2632 FRAME_FOREGROUND_PIXEL (f),
2633 FRAME_BACKGROUND_PIXEL (f),
2634 DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
2636 unblock_input ();
2640 /* Free what was allocated in x_make_gc. */
2642 void
2643 x_free_gcs (struct frame *f)
2645 Display *dpy = FRAME_X_DISPLAY (f);
2647 block_input ();
2649 if (f->output_data.x->normal_gc)
2651 XFreeGC (dpy, f->output_data.x->normal_gc);
2652 f->output_data.x->normal_gc = 0;
2655 if (f->output_data.x->reverse_gc)
2657 XFreeGC (dpy, f->output_data.x->reverse_gc);
2658 f->output_data.x->reverse_gc = 0;
2661 if (f->output_data.x->cursor_gc)
2663 XFreeGC (dpy, f->output_data.x->cursor_gc);
2664 f->output_data.x->cursor_gc = 0;
2667 if (f->output_data.x->border_tile)
2669 XFreePixmap (dpy, f->output_data.x->border_tile);
2670 f->output_data.x->border_tile = 0;
2673 unblock_input ();
2677 /* Handler for signals raised during x_create_frame and
2678 x_create_tip_frame. FRAME is the frame which is partially
2679 constructed. */
2681 static Lisp_Object
2682 unwind_create_frame (Lisp_Object frame)
2684 struct frame *f = XFRAME (frame);
2686 /* If frame is already dead, nothing to do. This can happen if the
2687 display is disconnected after the frame has become official, but
2688 before x_create_frame removes the unwind protect. */
2689 if (!FRAME_LIVE_P (f))
2690 return Qnil;
2692 /* If frame is ``official'', nothing to do. */
2693 if (NILP (Fmemq (frame, Vframe_list)))
2695 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2696 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2697 #endif
2699 x_free_frame_resources (f);
2700 free_glyphs (f);
2702 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2703 /* Check that reference counts are indeed correct. */
2704 eassert (dpyinfo->reference_count == dpyinfo_refcount);
2705 eassert (dpyinfo->terminal->image_cache->refcount == image_cache_refcount);
2706 #endif
2707 return Qt;
2710 return Qnil;
2713 static void
2714 do_unwind_create_frame (Lisp_Object frame)
2716 unwind_create_frame (frame);
2719 static void
2720 unwind_create_frame_1 (Lisp_Object val)
2722 inhibit_lisp_code = val;
2725 static void
2726 x_default_font_parameter (struct frame *f, Lisp_Object parms)
2728 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2729 Lisp_Object font_param = x_get_arg (dpyinfo, parms, Qfont, NULL, NULL,
2730 RES_TYPE_STRING);
2731 Lisp_Object font = Qnil;
2732 if (EQ (font_param, Qunbound))
2733 font_param = Qnil;
2735 if (NILP (font_param))
2737 /* System font should take precedence over X resources. We suggest this
2738 regardless of font-use-system-font because .emacs may not have been
2739 read yet. */
2740 const char *system_font = xsettings_get_system_font ();
2741 if (system_font)
2742 font = font_open_by_name (f, build_unibyte_string (system_font));
2745 if (NILP (font))
2746 font = !NILP (font_param) ? font_param
2747 : x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
2749 if (! FONTP (font) && ! STRINGP (font))
2751 const char *names[]
2753 #ifdef HAVE_XFT
2754 /* This will find the normal Xft font. */
2755 "monospace-10",
2756 #endif
2757 "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
2758 "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
2759 "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
2760 /* This was formerly the first thing tried, but it finds
2761 too many fonts and takes too long. */
2762 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
2763 /* If those didn't work, look for something which will
2764 at least work. */
2765 "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
2766 "fixed",
2767 NULL };
2768 int i;
2770 for (i = 0; names[i]; i++)
2772 font = font_open_by_name (f, build_unibyte_string (names[i]));
2773 if (! NILP (font))
2774 break;
2776 if (NILP (font))
2777 error ("No suitable font was found");
2779 else if (!NILP (font_param))
2781 /* Remember the explicit font parameter, so we can re-apply it after
2782 we've applied the `default' face settings. */
2783 x_set_frame_parameters (f, list1 (Fcons (Qfont_param, font_param)));
2786 /* This call will make X resources override any system font setting. */
2787 x_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING);
2791 DEFUN ("x-wm-set-size-hint", Fx_wm_set_size_hint, Sx_wm_set_size_hint,
2792 0, 1, 0,
2793 doc: /* Send the size hints for frame FRAME to the window manager.
2794 If FRAME is omitted or nil, use the selected frame.
2795 Signal error if FRAME is not an X frame. */)
2796 (Lisp_Object frame)
2798 struct frame *f = decode_window_system_frame (frame);
2800 block_input ();
2801 x_wm_set_size_hint (f, 0, 0);
2802 unblock_input ();
2803 return Qnil;
2806 static void
2807 set_machine_and_pid_properties (struct frame *f)
2809 long pid = (long) getpid ();
2811 /* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME. */
2812 XSetWMProperties (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), NULL, NULL,
2813 NULL, 0, NULL, NULL, NULL);
2814 XChangeProperty (FRAME_X_DISPLAY (f),
2815 FRAME_OUTER_WINDOW (f),
2816 XInternAtom (FRAME_X_DISPLAY (f),
2817 "_NET_WM_PID",
2818 False),
2819 XA_CARDINAL, 32, PropModeReplace,
2820 (unsigned char *) &pid, 1);
2823 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
2824 1, 1, 0,
2825 doc: /* Make a new X window, which is called a "frame" in Emacs terms.
2826 Return an Emacs frame object.
2827 PARMS is an alist of frame parameters.
2828 If the parameters specify that the frame should not have a minibuffer,
2829 and do not specify a specific minibuffer window to use,
2830 then `default-minibuffer-frame' must be a frame whose minibuffer can
2831 be shared by the new frame.
2833 This function is an internal primitive--use `make-frame' instead. */)
2834 (Lisp_Object parms)
2836 struct frame *f;
2837 Lisp_Object frame, tem;
2838 Lisp_Object name;
2839 int minibuffer_only = 0;
2840 long window_prompting = 0;
2841 int width, height;
2842 ptrdiff_t count = SPECPDL_INDEX ();
2843 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
2844 Lisp_Object display;
2845 struct x_display_info *dpyinfo = NULL;
2846 Lisp_Object parent;
2847 struct kboard *kb;
2849 parms = Fcopy_alist (parms);
2851 /* Use this general default value to start with
2852 until we know if this frame has a specified name. */
2853 Vx_resource_name = Vinvocation_name;
2855 display = x_get_arg (dpyinfo, parms, Qterminal, 0, 0, RES_TYPE_NUMBER);
2856 if (EQ (display, Qunbound))
2857 display = x_get_arg (dpyinfo, parms, Qdisplay, 0, 0, RES_TYPE_STRING);
2858 if (EQ (display, Qunbound))
2859 display = Qnil;
2860 dpyinfo = check_x_display_info (display);
2861 kb = dpyinfo->terminal->kboard;
2863 if (!dpyinfo->terminal->name)
2864 error ("Terminal is not live, can't create new frames on it");
2866 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
2867 if (!STRINGP (name)
2868 && ! EQ (name, Qunbound)
2869 && ! NILP (name))
2870 error ("Invalid frame name--not a string or nil");
2872 if (STRINGP (name))
2873 Vx_resource_name = name;
2875 /* See if parent window is specified. */
2876 parent = x_get_arg (dpyinfo, parms, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
2877 if (EQ (parent, Qunbound))
2878 parent = Qnil;
2879 if (! NILP (parent))
2880 CHECK_NUMBER (parent);
2882 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
2883 /* No need to protect DISPLAY because that's not used after passing
2884 it to make_frame_without_minibuffer. */
2885 frame = Qnil;
2886 GCPRO4 (parms, parent, name, frame);
2887 tem = x_get_arg (dpyinfo, parms, Qminibuffer, "minibuffer", "Minibuffer",
2888 RES_TYPE_SYMBOL);
2889 if (EQ (tem, Qnone) || NILP (tem))
2890 f = make_frame_without_minibuffer (Qnil, kb, display);
2891 else if (EQ (tem, Qonly))
2893 f = make_minibuffer_frame ();
2894 minibuffer_only = 1;
2896 else if (WINDOWP (tem))
2897 f = make_frame_without_minibuffer (tem, kb, display);
2898 else
2899 f = make_frame (1);
2901 XSETFRAME (frame, f);
2903 f->terminal = dpyinfo->terminal;
2905 f->output_method = output_x_window;
2906 f->output_data.x = xzalloc (sizeof *f->output_data.x);
2907 f->output_data.x->icon_bitmap = -1;
2908 FRAME_FONTSET (f) = -1;
2909 f->output_data.x->scroll_bar_foreground_pixel = -1;
2910 f->output_data.x->scroll_bar_background_pixel = -1;
2911 #ifdef USE_TOOLKIT_SCROLL_BARS
2912 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
2913 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
2914 #endif /* USE_TOOLKIT_SCROLL_BARS */
2915 f->output_data.x->white_relief.pixel = -1;
2916 f->output_data.x->black_relief.pixel = -1;
2918 fset_icon_name (f,
2919 x_get_arg (dpyinfo, parms, Qicon_name, "iconName", "Title",
2920 RES_TYPE_STRING));
2921 if (! STRINGP (f->icon_name))
2922 fset_icon_name (f, Qnil);
2924 FRAME_DISPLAY_INFO (f) = dpyinfo;
2926 /* With FRAME_DISPLAY_INFO set up, this unwind-protect is safe. */
2927 record_unwind_protect (do_unwind_create_frame, frame);
2929 /* These colors will be set anyway later, but it's important
2930 to get the color reference counts right, so initialize them! */
2932 Lisp_Object black;
2933 struct gcpro gcpro1;
2935 /* Function x_decode_color can signal an error. Make
2936 sure to initialize color slots so that we won't try
2937 to free colors we haven't allocated. */
2938 FRAME_FOREGROUND_PIXEL (f) = -1;
2939 FRAME_BACKGROUND_PIXEL (f) = -1;
2940 f->output_data.x->cursor_pixel = -1;
2941 f->output_data.x->cursor_foreground_pixel = -1;
2942 f->output_data.x->border_pixel = -1;
2943 f->output_data.x->mouse_pixel = -1;
2945 black = build_string ("black");
2946 GCPRO1 (black);
2947 FRAME_FOREGROUND_PIXEL (f)
2948 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
2949 FRAME_BACKGROUND_PIXEL (f)
2950 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
2951 f->output_data.x->cursor_pixel
2952 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
2953 f->output_data.x->cursor_foreground_pixel
2954 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
2955 f->output_data.x->border_pixel
2956 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
2957 f->output_data.x->mouse_pixel
2958 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
2959 UNGCPRO;
2962 /* Specify the parent under which to make this X window. */
2964 if (!NILP (parent))
2966 f->output_data.x->parent_desc = (Window) XFASTINT (parent);
2967 f->output_data.x->explicit_parent = 1;
2969 else
2971 f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
2972 f->output_data.x->explicit_parent = 0;
2975 /* Set the name; the functions to which we pass f expect the name to
2976 be set. */
2977 if (EQ (name, Qunbound) || NILP (name))
2979 fset_name (f, build_string (dpyinfo->x_id_name));
2980 f->explicit_name = 0;
2982 else
2984 fset_name (f, name);
2985 f->explicit_name = 1;
2986 /* use the frame's title when getting resources for this frame. */
2987 specbind (Qx_resource_name, name);
2990 #ifdef HAVE_FREETYPE
2991 #ifdef HAVE_XFT
2992 register_font_driver (&xftfont_driver, f);
2993 #else /* not HAVE_XFT */
2994 register_font_driver (&ftxfont_driver, f);
2995 #endif /* not HAVE_XFT */
2996 #endif /* HAVE_FREETYPE */
2997 register_font_driver (&xfont_driver, f);
2999 x_default_parameter (f, parms, Qfont_backend, Qnil,
3000 "fontBackend", "FontBackend", RES_TYPE_STRING);
3002 /* Extract the window parameters from the supplied values
3003 that are needed to determine window geometry. */
3004 x_default_font_parameter (f, parms);
3005 if (!FRAME_FONT (f))
3007 delete_frame (frame, Qnoelisp);
3008 error ("Invalid frame font");
3011 /* Frame contents get displaced if an embedded X window has a border. */
3012 if (! FRAME_X_EMBEDDED_P (f))
3013 x_default_parameter (f, parms, Qborder_width, make_number (0),
3014 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
3016 /* This defaults to 1 in order to match xterm. We recognize either
3017 internalBorderWidth or internalBorder (which is what xterm calls
3018 it). */
3019 if (NILP (Fassq (Qinternal_border_width, parms)))
3021 Lisp_Object value;
3023 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
3024 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
3025 if (! EQ (value, Qunbound))
3026 parms = Fcons (Fcons (Qinternal_border_width, value),
3027 parms);
3029 x_default_parameter (f, parms, Qinternal_border_width,
3030 #ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */
3031 make_number (0),
3032 #else
3033 make_number (1),
3034 #endif
3035 "internalBorderWidth", "internalBorderWidth",
3036 RES_TYPE_NUMBER);
3037 x_default_parameter (f, parms, Qright_divider_width, make_number (0),
3038 NULL, NULL, RES_TYPE_NUMBER);
3039 x_default_parameter (f, parms, Qbottom_divider_width, make_number (0),
3040 NULL, NULL, RES_TYPE_NUMBER);
3041 x_default_parameter (f, parms, Qvertical_scroll_bars,
3042 #if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
3043 Qright,
3044 #else
3045 Qleft,
3046 #endif
3047 "verticalScrollBars", "ScrollBars",
3048 RES_TYPE_SYMBOL);
3050 /* Also do the stuff which must be set before the window exists. */
3051 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
3052 "foreground", "Foreground", RES_TYPE_STRING);
3053 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
3054 "background", "Background", RES_TYPE_STRING);
3055 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
3056 "pointerColor", "Foreground", RES_TYPE_STRING);
3057 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
3058 "borderColor", "BorderColor", RES_TYPE_STRING);
3059 x_default_parameter (f, parms, Qscreen_gamma, Qnil,
3060 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
3061 x_default_parameter (f, parms, Qline_spacing, Qnil,
3062 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
3063 x_default_parameter (f, parms, Qleft_fringe, Qnil,
3064 "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
3065 x_default_parameter (f, parms, Qright_fringe, Qnil,
3066 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
3068 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_foreground,
3069 "scrollBarForeground",
3070 "ScrollBarForeground", 1);
3071 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_background,
3072 "scrollBarBackground",
3073 "ScrollBarBackground", 0);
3075 #ifdef GLYPH_DEBUG
3076 image_cache_refcount =
3077 FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
3078 dpyinfo_refcount = dpyinfo->reference_count;
3079 #endif /* GLYPH_DEBUG */
3081 /* Init faces before x_default_parameter is called for scroll-bar
3082 parameters because that function calls x_set_scroll_bar_width,
3083 which calls change_frame_size, which calls Fset_window_buffer,
3084 which runs hooks, which call Fvertical_motion. At the end, we
3085 end up in init_iterator with a null face cache, which should not
3086 happen. */
3087 init_frame_faces (f);
3089 /* PXW: This is a duplicate from below. We have to do it here since
3090 otherwise x_set_tool_bar_lines will work with the character sizes
3091 installed by init_frame_faces while the frame's pixel size is still
3092 calculated from a character size of 1 and we subsequently hit the
3093 eassert (height >= 0) assertion in window_box_height. The
3094 non-pixelwise code apparently worked around this because it had one
3095 frame line vs one toolbar line which left us with a zero root
3096 window height which was obviously wrong as well ... */
3097 change_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
3098 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 1, 0, 0, 1);
3100 /* Set the menu-bar-lines and tool-bar-lines parameters. We don't
3101 look up the X resources controlling the menu-bar and tool-bar
3102 here; they are processed specially at startup, and reflected in
3103 the values of the mode variables.
3105 Avoid calling window-configuration-change-hook; otherwise we
3106 could get an infloop in next_frame since the frame is not yet in
3107 Vframe_list. */
3109 ptrdiff_t count2 = SPECPDL_INDEX ();
3110 record_unwind_protect (unwind_create_frame_1, inhibit_lisp_code);
3111 inhibit_lisp_code = Qt;
3113 x_default_parameter (f, parms, Qmenu_bar_lines,
3114 NILP (Vmenu_bar_mode)
3115 ? make_number (0) : make_number (1),
3116 NULL, NULL, RES_TYPE_NUMBER);
3117 x_default_parameter (f, parms, Qtool_bar_lines,
3118 NILP (Vtool_bar_mode)
3119 ? make_number (0) : make_number (1),
3120 NULL, NULL, RES_TYPE_NUMBER);
3122 unbind_to (count2, Qnil);
3125 x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
3126 "bufferPredicate", "BufferPredicate",
3127 RES_TYPE_SYMBOL);
3128 x_default_parameter (f, parms, Qtitle, Qnil,
3129 "title", "Title", RES_TYPE_STRING);
3130 x_default_parameter (f, parms, Qwait_for_wm, Qt,
3131 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
3132 x_default_parameter (f, parms, Qfullscreen, Qnil,
3133 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
3134 x_default_parameter (f, parms, Qtool_bar_position,
3135 f->tool_bar_position, 0, 0, RES_TYPE_SYMBOL);
3137 /* Compute the size of the X window. */
3138 window_prompting = x_figure_window_size (f, parms, 1);
3140 tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
3141 f->no_split = minibuffer_only || EQ (tem, Qt);
3143 x_icon_verify (f, parms);
3145 /* Create the X widget or window. */
3146 #ifdef USE_X_TOOLKIT
3147 x_window (f, window_prompting, minibuffer_only);
3148 #else
3149 x_window (f);
3150 #endif
3152 x_icon (f, parms);
3153 x_make_gc (f);
3155 /* Now consider the frame official. */
3156 f->terminal->reference_count++;
3157 FRAME_DISPLAY_INFO (f)->reference_count++;
3158 Vframe_list = Fcons (frame, Vframe_list);
3160 /* We need to do this after creating the X window, so that the
3161 icon-creation functions can say whose icon they're describing. */
3162 x_default_parameter (f, parms, Qicon_type, Qt,
3163 "bitmapIcon", "BitmapIcon", RES_TYPE_BOOLEAN);
3165 x_default_parameter (f, parms, Qauto_raise, Qnil,
3166 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3167 x_default_parameter (f, parms, Qauto_lower, Qnil,
3168 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3169 x_default_parameter (f, parms, Qcursor_type, Qbox,
3170 "cursorType", "CursorType", RES_TYPE_SYMBOL);
3171 x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
3172 "scrollBarWidth", "ScrollBarWidth",
3173 RES_TYPE_NUMBER);
3174 x_default_parameter (f, parms, Qalpha, Qnil,
3175 "alpha", "Alpha", RES_TYPE_NUMBER);
3177 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3178 Change will not be effected unless different from the current
3179 FRAME_LINES (f). */
3180 width = FRAME_TEXT_WIDTH (f);
3181 height = FRAME_TEXT_HEIGHT (f);
3182 FRAME_TEXT_HEIGHT (f) = 0;
3183 SET_FRAME_WIDTH (f, 0);
3184 change_frame_size (f, width, height, 1, 0, 0, 1);
3186 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3187 /* Create the menu bar. */
3188 if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
3190 /* If this signals an error, we haven't set size hints for the
3191 frame and we didn't make it visible. */
3192 initialize_frame_menubar (f);
3194 #ifndef USE_GTK
3195 /* This is a no-op, except under Motif where it arranges the
3196 main window for the widgets on it. */
3197 lw_set_main_areas (f->output_data.x->column_widget,
3198 f->output_data.x->menubar_widget,
3199 f->output_data.x->edit_widget);
3200 #endif /* not USE_GTK */
3202 #endif /* USE_X_TOOLKIT || USE_GTK */
3204 /* Tell the server what size and position, etc, we want, and how
3205 badly we want them. This should be done after we have the menu
3206 bar so that its size can be taken into account. */
3207 block_input ();
3208 x_wm_set_size_hint (f, window_prompting, 0);
3209 unblock_input ();
3211 /* Make the window appear on the frame and enable display, unless
3212 the caller says not to. However, with explicit parent, Emacs
3213 cannot control visibility, so don't try. */
3214 if (! f->output_data.x->explicit_parent)
3216 Lisp_Object visibility;
3218 visibility = x_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
3219 RES_TYPE_SYMBOL);
3220 if (EQ (visibility, Qunbound))
3221 visibility = Qt;
3223 if (EQ (visibility, Qicon))
3224 x_iconify_frame (f);
3225 else if (! NILP (visibility))
3226 x_make_frame_visible (f);
3227 else
3229 /* Must have been Qnil. */
3233 block_input ();
3235 /* Set machine name and pid for the purpose of window managers. */
3236 set_machine_and_pid_properties (f);
3238 /* Set the WM leader property. GTK does this itself, so this is not
3239 needed when using GTK. */
3240 if (dpyinfo->client_leader_window != 0)
3242 XChangeProperty (FRAME_X_DISPLAY (f),
3243 FRAME_OUTER_WINDOW (f),
3244 dpyinfo->Xatom_wm_client_leader,
3245 XA_WINDOW, 32, PropModeReplace,
3246 (unsigned char *) &dpyinfo->client_leader_window, 1);
3249 unblock_input ();
3251 /* Initialize `default-minibuffer-frame' in case this is the first
3252 frame on this terminal. */
3253 if (FRAME_HAS_MINIBUF_P (f)
3254 && (!FRAMEP (KVAR (kb, Vdefault_minibuffer_frame))
3255 || !FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame)))))
3256 kset_default_minibuffer_frame (kb, frame);
3258 /* All remaining specified parameters, which have not been "used"
3259 by x_get_arg and friends, now go in the misc. alist of the frame. */
3260 for (tem = parms; CONSP (tem); tem = XCDR (tem))
3261 if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
3262 fset_param_alist (f, Fcons (XCAR (tem), f->param_alist));
3264 UNGCPRO;
3266 /* Make sure windows on this frame appear in calls to next-window
3267 and similar functions. */
3268 Vwindow_list = Qnil;
3270 return unbind_to (count, frame);
3274 /* FRAME is used only to get a handle on the X display. We don't pass the
3275 display info directly because we're called from frame.c, which doesn't
3276 know about that structure. */
3278 Lisp_Object
3279 x_get_focus_frame (struct frame *frame)
3281 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (frame);
3282 Lisp_Object xfocus;
3283 if (! dpyinfo->x_focus_frame)
3284 return Qnil;
3286 XSETFRAME (xfocus, dpyinfo->x_focus_frame);
3287 return xfocus;
3291 /* In certain situations, when the window manager follows a
3292 click-to-focus policy, there seems to be no way around calling
3293 XSetInputFocus to give another frame the input focus .
3295 In an ideal world, XSetInputFocus should generally be avoided so
3296 that applications don't interfere with the window manager's focus
3297 policy. But I think it's okay to use when it's clearly done
3298 following a user-command. */
3300 void
3301 x_focus_frame (struct frame *f)
3303 Display *dpy = FRAME_X_DISPLAY (f);
3305 block_input ();
3306 x_catch_errors (dpy);
3308 if (FRAME_X_EMBEDDED_P (f))
3310 /* For Xembedded frames, normally the embedder forwards key
3311 events. See XEmbed Protocol Specification at
3312 http://freedesktop.org/wiki/Specifications/xembed-spec */
3313 xembed_request_focus (f);
3315 else
3317 XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3318 RevertToParent, CurrentTime);
3319 x_ewmh_activate_frame (f);
3322 x_uncatch_errors ();
3323 unblock_input ();
3327 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
3328 doc: /* Internal function called by `color-defined-p', which see
3329 .\(Note that the Nextstep version of this function ignores FRAME.) */)
3330 (Lisp_Object color, Lisp_Object frame)
3332 XColor foo;
3333 struct frame *f = decode_window_system_frame (frame);
3335 CHECK_STRING (color);
3337 if (x_defined_color (f, SSDATA (color), &foo, 0))
3338 return Qt;
3339 else
3340 return Qnil;
3343 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
3344 doc: /* Internal function called by `color-values', which see. */)
3345 (Lisp_Object color, Lisp_Object frame)
3347 XColor foo;
3348 struct frame *f = decode_window_system_frame (frame);
3350 CHECK_STRING (color);
3352 if (x_defined_color (f, SSDATA (color), &foo, 0))
3353 return list3i (foo.red, foo.green, foo.blue);
3354 else
3355 return Qnil;
3358 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
3359 doc: /* Internal function called by `display-color-p', which see. */)
3360 (Lisp_Object terminal)
3362 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3364 if (dpyinfo->n_planes <= 2)
3365 return Qnil;
3367 switch (dpyinfo->visual->class)
3369 case StaticColor:
3370 case PseudoColor:
3371 case TrueColor:
3372 case DirectColor:
3373 return Qt;
3375 default:
3376 return Qnil;
3380 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
3381 0, 1, 0,
3382 doc: /* Return t if the X display supports shades of gray.
3383 Note that color displays do support shades of gray.
3384 The optional argument TERMINAL specifies which display to ask about.
3385 TERMINAL should be a terminal object, a frame or a display name (a string).
3386 If omitted or nil, that stands for the selected frame's display. */)
3387 (Lisp_Object terminal)
3389 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3391 if (dpyinfo->n_planes <= 1)
3392 return Qnil;
3394 switch (dpyinfo->visual->class)
3396 case StaticColor:
3397 case PseudoColor:
3398 case TrueColor:
3399 case DirectColor:
3400 case StaticGray:
3401 case GrayScale:
3402 return Qt;
3404 default:
3405 return Qnil;
3409 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
3410 0, 1, 0,
3411 doc: /* Return the width in pixels of the X display TERMINAL.
3412 The optional argument TERMINAL specifies which display to ask about.
3413 TERMINAL should be a terminal object, a frame or a display name (a string).
3414 If omitted or nil, that stands for the selected frame's display.
3416 On \"multi-monitor\" setups this refers to the pixel width for all
3417 physical monitors associated with TERMINAL. To get information for
3418 each physical monitor, use `display-monitor-attributes-list'. */)
3419 (Lisp_Object terminal)
3421 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3423 return make_number (x_display_pixel_width (dpyinfo));
3426 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
3427 Sx_display_pixel_height, 0, 1, 0,
3428 doc: /* Return the height in pixels of the X display TERMINAL.
3429 The optional argument TERMINAL specifies which display to ask about.
3430 TERMINAL should be a terminal object, a frame or a display name (a string).
3431 If omitted or nil, that stands for the selected frame's display.
3433 On \"multi-monitor\" setups this refers to the pixel height for all
3434 physical monitors associated with TERMINAL. To get information for
3435 each physical monitor, use `display-monitor-attributes-list'. */)
3436 (Lisp_Object terminal)
3438 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3440 return make_number (x_display_pixel_height (dpyinfo));
3443 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
3444 0, 1, 0,
3445 doc: /* Return the number of bitplanes of the X display TERMINAL.
3446 The optional argument TERMINAL specifies which display to ask about.
3447 TERMINAL should be a terminal object, a frame or a display name (a string).
3448 If omitted or nil, that stands for the selected frame's display. */)
3449 (Lisp_Object terminal)
3451 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3453 return make_number (dpyinfo->n_planes);
3456 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
3457 0, 1, 0,
3458 doc: /* Return the number of color cells of the X display TERMINAL.
3459 The optional argument TERMINAL specifies which display to ask about.
3460 TERMINAL should be a terminal object, a frame or a display name (a string).
3461 If omitted or nil, that stands for the selected frame's display. */)
3462 (Lisp_Object terminal)
3464 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3466 int nr_planes = DisplayPlanes (dpyinfo->display,
3467 XScreenNumberOfScreen (dpyinfo->screen));
3469 /* Truncate nr_planes to 24 to avoid integer overflow.
3470 Some displays says 32, but only 24 bits are actually significant.
3471 There are only very few and rare video cards that have more than
3472 24 significant bits. Also 24 bits is more than 16 million colors,
3473 it "should be enough for everyone". */
3474 if (nr_planes > 24) nr_planes = 24;
3476 return make_number (1 << nr_planes);
3479 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
3480 Sx_server_max_request_size,
3481 0, 1, 0,
3482 doc: /* Return the maximum request size of the X server of display TERMINAL.
3483 The optional argument TERMINAL specifies which display to ask about.
3484 TERMINAL should be a terminal object, a frame or a display name (a string).
3485 If omitted or nil, that stands for the selected frame's display. */)
3486 (Lisp_Object terminal)
3488 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3490 return make_number (MAXREQUEST (dpyinfo->display));
3493 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
3494 doc: /* Return the "vendor ID" string of the X server of display TERMINAL.
3495 \(Labeling every distributor as a "vendor" embodies the false assumption
3496 that operating systems cannot be developed and distributed noncommercially.)
3497 The optional argument TERMINAL specifies which display to ask about.
3498 TERMINAL should be a terminal object, a frame or a display name (a string).
3499 If omitted or nil, that stands for the selected frame's display. */)
3500 (Lisp_Object terminal)
3502 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3503 const char *vendor = ServerVendor (dpyinfo->display);
3505 if (! vendor) vendor = "";
3506 return build_string (vendor);
3509 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
3510 doc: /* Return the version numbers of the X server of display TERMINAL.
3511 The value is a list of three integers: the major and minor
3512 version numbers of the X Protocol in use, and the distributor-specific release
3513 number. See also the function `x-server-vendor'.
3515 The optional argument TERMINAL specifies which display to ask about.
3516 TERMINAL should be a terminal object, a frame or a display name (a string).
3517 If omitted or nil, that stands for the selected frame's display. */)
3518 (Lisp_Object terminal)
3520 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3521 Display *dpy = dpyinfo->display;
3523 return list3i (ProtocolVersion (dpy), ProtocolRevision (dpy),
3524 VendorRelease (dpy));
3527 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
3528 doc: /* Return the number of screens on the X server of display TERMINAL.
3529 The optional argument TERMINAL specifies which display to ask about.
3530 TERMINAL should be a terminal object, a frame or a display name (a string).
3531 If omitted or nil, that stands for the selected frame's display. */)
3532 (Lisp_Object terminal)
3534 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3536 return make_number (ScreenCount (dpyinfo->display));
3539 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
3540 doc: /* Return the height in millimeters of the X display TERMINAL.
3541 The optional argument TERMINAL specifies which display to ask about.
3542 TERMINAL should be a terminal object, a frame or a display name (a string).
3543 If omitted or nil, that stands for the selected frame's display.
3545 On \"multi-monitor\" setups this refers to the height in millimeters for
3546 all physical monitors associated with TERMINAL. To get information
3547 for each physical monitor, use `display-monitor-attributes-list'. */)
3548 (Lisp_Object terminal)
3550 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3552 return make_number (HeightMMOfScreen (dpyinfo->screen));
3555 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
3556 doc: /* Return the width in millimeters of the X display TERMINAL.
3557 The optional argument TERMINAL specifies which display to ask about.
3558 TERMINAL should be a terminal object, a frame or a display name (a string).
3559 If omitted or nil, that stands for the selected frame's display.
3561 On \"multi-monitor\" setups this refers to the width in millimeters for
3562 all physical monitors associated with TERMINAL. To get information
3563 for each physical monitor, use `display-monitor-attributes-list'. */)
3564 (Lisp_Object terminal)
3566 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3568 return make_number (WidthMMOfScreen (dpyinfo->screen));
3571 DEFUN ("x-display-backing-store", Fx_display_backing_store,
3572 Sx_display_backing_store, 0, 1, 0,
3573 doc: /* Return an indication of whether X display TERMINAL does backing store.
3574 The value may be `always', `when-mapped', or `not-useful'.
3575 The optional argument TERMINAL specifies which display to ask about.
3576 TERMINAL should be a terminal object, a frame or a display name (a string).
3577 If omitted or nil, that stands for the selected frame's display. */)
3578 (Lisp_Object terminal)
3580 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3581 Lisp_Object result;
3583 switch (DoesBackingStore (dpyinfo->screen))
3585 case Always:
3586 result = intern ("always");
3587 break;
3589 case WhenMapped:
3590 result = intern ("when-mapped");
3591 break;
3593 case NotUseful:
3594 result = intern ("not-useful");
3595 break;
3597 default:
3598 error ("Strange value for BackingStore parameter of screen");
3601 return result;
3604 DEFUN ("x-display-visual-class", Fx_display_visual_class,
3605 Sx_display_visual_class, 0, 1, 0,
3606 doc: /* Return the visual class of the X display TERMINAL.
3607 The value is one of the symbols `static-gray', `gray-scale',
3608 `static-color', `pseudo-color', `true-color', or `direct-color'.
3610 The optional argument TERMINAL specifies which display to ask about.
3611 TERMINAL should a terminal object, a frame or a display name (a string).
3612 If omitted or nil, that stands for the selected frame's display. */)
3613 (Lisp_Object terminal)
3615 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3616 Lisp_Object result;
3618 switch (dpyinfo->visual->class)
3620 case StaticGray:
3621 result = intern ("static-gray");
3622 break;
3623 case GrayScale:
3624 result = intern ("gray-scale");
3625 break;
3626 case StaticColor:
3627 result = intern ("static-color");
3628 break;
3629 case PseudoColor:
3630 result = intern ("pseudo-color");
3631 break;
3632 case TrueColor:
3633 result = intern ("true-color");
3634 break;
3635 case DirectColor:
3636 result = intern ("direct-color");
3637 break;
3638 default:
3639 error ("Display has an unknown visual class");
3642 return result;
3645 DEFUN ("x-display-save-under", Fx_display_save_under,
3646 Sx_display_save_under, 0, 1, 0,
3647 doc: /* Return t if the X display TERMINAL supports the save-under feature.
3648 The optional argument TERMINAL specifies which display to ask about.
3649 TERMINAL should be a terminal object, a frame or a display name (a string).
3650 If omitted or nil, that stands for the selected frame's display. */)
3651 (Lisp_Object terminal)
3653 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3655 if (DoesSaveUnders (dpyinfo->screen) == True)
3656 return Qt;
3657 else
3658 return Qnil;
3661 /* Store the geometry of the workarea on display DPYINFO into *RECT.
3662 Return false if and only if the workarea information cannot be
3663 obtained via the _NET_WORKAREA root window property. */
3665 #if ! GTK_CHECK_VERSION (3, 4, 0)
3666 static bool
3667 x_get_net_workarea (struct x_display_info *dpyinfo, XRectangle *rect)
3669 Display *dpy = dpyinfo->display;
3670 long offset, max_len;
3671 Atom target_type, actual_type;
3672 unsigned long actual_size, bytes_remaining;
3673 int rc, actual_format;
3674 unsigned char *tmp_data = NULL;
3675 bool result = false;
3677 x_catch_errors (dpy);
3678 offset = 0;
3679 max_len = 1;
3680 target_type = XA_CARDINAL;
3681 rc = XGetWindowProperty (dpy, dpyinfo->root_window,
3682 dpyinfo->Xatom_net_current_desktop,
3683 offset, max_len, False, target_type,
3684 &actual_type, &actual_format, &actual_size,
3685 &bytes_remaining, &tmp_data);
3686 if (rc == Success && actual_type == target_type && !x_had_errors_p (dpy)
3687 && actual_format == 32 && actual_size == max_len)
3689 long current_desktop = ((long *) tmp_data)[0];
3691 XFree (tmp_data);
3692 tmp_data = NULL;
3694 offset = 4 * current_desktop;
3695 max_len = 4;
3696 rc = XGetWindowProperty (dpy, dpyinfo->root_window,
3697 dpyinfo->Xatom_net_workarea,
3698 offset, max_len, False, target_type,
3699 &actual_type, &actual_format, &actual_size,
3700 &bytes_remaining, &tmp_data);
3701 if (rc == Success && actual_type == target_type && !x_had_errors_p (dpy)
3702 && actual_format == 32 && actual_size == max_len)
3704 long *values = (long *) tmp_data;
3706 rect->x = values[0];
3707 rect->y = values[1];
3708 rect->width = values[2];
3709 rect->height = values[3];
3711 XFree (tmp_data);
3712 tmp_data = NULL;
3714 result = true;
3717 if (tmp_data)
3718 XFree (tmp_data);
3719 x_uncatch_errors ();
3721 return result;
3723 #endif
3725 #ifndef USE_GTK
3727 /* Return monitor number where F is "most" or closest to. */
3728 static int
3729 x_get_monitor_for_frame (struct frame *f,
3730 struct MonitorInfo *monitors,
3731 int n_monitors)
3733 XRectangle frect;
3734 int area = 0, dist = -1;
3735 int best_area = -1, best_dist = -1;
3736 int i;
3738 if (n_monitors == 1) return 0;
3739 frect.x = f->left_pos;
3740 frect.y = f->top_pos;
3741 frect.width = FRAME_PIXEL_WIDTH (f);
3742 frect.height = FRAME_PIXEL_HEIGHT (f);
3744 for (i = 0; i < n_monitors; ++i)
3746 struct MonitorInfo *mi = &monitors[i];
3747 XRectangle res;
3748 int a = 0;
3750 if (mi->geom.width == 0) continue;
3752 if (x_intersect_rectangles (&mi->geom, &frect, &res))
3754 a = res.width * res.height;
3755 if (a > area)
3757 area = a;
3758 best_area = i;
3762 if (a == 0 && area == 0)
3764 int dx, dy, d;
3765 if (frect.x + frect.width < mi->geom.x)
3766 dx = mi->geom.x - frect.x + frect.width;
3767 else if (frect.x > mi->geom.x + mi->geom.width)
3768 dx = frect.x - mi->geom.x + mi->geom.width;
3769 else
3770 dx = 0;
3771 if (frect.y + frect.height < mi->geom.y)
3772 dy = mi->geom.y - frect.y + frect.height;
3773 else if (frect.y > mi->geom.y + mi->geom.height)
3774 dy = frect.y - mi->geom.y + mi->geom.height;
3775 else
3776 dy = 0;
3778 d = dx*dx + dy*dy;
3779 if (dist == -1 || dist > d)
3781 dist = d;
3782 best_dist = i;
3787 return best_area != -1 ? best_area : (best_dist != -1 ? best_dist : 0);
3790 static Lisp_Object
3791 x_make_monitor_attribute_list (struct MonitorInfo *monitors,
3792 int n_monitors,
3793 int primary_monitor,
3794 struct x_display_info *dpyinfo,
3795 const char *source)
3797 Lisp_Object monitor_frames = Fmake_vector (make_number (n_monitors), Qnil);
3798 Lisp_Object frame, rest;
3800 FOR_EACH_FRAME (rest, frame)
3802 struct frame *f = XFRAME (frame);
3804 if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo
3805 && !EQ (frame, tip_frame))
3807 int i = x_get_monitor_for_frame (f, monitors, n_monitors);
3808 ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
3812 return make_monitor_attribute_list (monitors, n_monitors, primary_monitor,
3813 monitor_frames, source);
3816 static Lisp_Object
3817 x_get_monitor_attributes_fallback (struct x_display_info *dpyinfo)
3819 struct MonitorInfo monitor;
3820 XRectangle workarea_r;
3822 /* Fallback: treat (possibly) multiple physical monitors as if they
3823 formed a single monitor as a whole. This should provide a
3824 consistent result at least on single monitor environments. */
3825 monitor.geom.x = monitor.geom.y = 0;
3826 monitor.geom.width = x_display_pixel_width (dpyinfo);
3827 monitor.geom.height = x_display_pixel_height (dpyinfo);
3828 monitor.mm_width = WidthMMOfScreen (dpyinfo->screen);
3829 monitor.mm_height = HeightMMOfScreen (dpyinfo->screen);
3830 monitor.name = xstrdup ("combined screen");
3832 if (x_get_net_workarea (dpyinfo, &workarea_r))
3833 monitor.work = workarea_r;
3834 else
3835 monitor.work = monitor.geom;
3836 return x_make_monitor_attribute_list (&monitor, 1, 0, dpyinfo, "fallback");
3840 #ifdef HAVE_XINERAMA
3841 static Lisp_Object
3842 x_get_monitor_attributes_xinerama (struct x_display_info *dpyinfo)
3844 int n_monitors, i;
3845 Lisp_Object attributes_list = Qnil;
3846 Display *dpy = dpyinfo->display;
3847 XineramaScreenInfo *info = XineramaQueryScreens (dpy, &n_monitors);
3848 struct MonitorInfo *monitors;
3849 double mm_width_per_pixel, mm_height_per_pixel;
3851 if (! info || n_monitors == 0)
3853 if (info)
3854 XFree (info);
3855 return attributes_list;
3858 mm_width_per_pixel = ((double) WidthMMOfScreen (dpyinfo->screen)
3859 / x_display_pixel_width (dpyinfo));
3860 mm_height_per_pixel = ((double) HeightMMOfScreen (dpyinfo->screen)
3861 / x_display_pixel_height (dpyinfo));
3862 monitors = xzalloc (n_monitors * sizeof *monitors);
3863 for (i = 0; i < n_monitors; ++i)
3865 struct MonitorInfo *mi = &monitors[i];
3866 XRectangle workarea_r;
3868 mi->geom.x = info[i].x_org;
3869 mi->geom.y = info[i].y_org;
3870 mi->geom.width = info[i].width;
3871 mi->geom.height = info[i].height;
3872 mi->mm_width = mi->geom.width * mm_width_per_pixel + 0.5;
3873 mi->mm_height = mi->geom.height * mm_height_per_pixel + 0.5;
3874 mi->name = 0;
3876 /* Xinerama usually have primary monitor first, just use that. */
3877 if (i == 0 && x_get_net_workarea (dpyinfo, &workarea_r))
3879 mi->work = workarea_r;
3880 if (! x_intersect_rectangles (&mi->geom, &mi->work, &mi->work))
3881 mi->work = mi->geom;
3883 else
3884 mi->work = mi->geom;
3886 XFree (info);
3888 attributes_list = x_make_monitor_attribute_list (monitors,
3889 n_monitors,
3891 dpyinfo,
3892 "Xinerama");
3893 free_monitors (monitors, n_monitors);
3894 return attributes_list;
3896 #endif /* HAVE_XINERAMA */
3899 #ifdef HAVE_XRANDR
3900 static Lisp_Object
3901 x_get_monitor_attributes_xrandr (struct x_display_info *dpyinfo)
3903 Lisp_Object attributes_list = Qnil;
3904 XRRScreenResources *resources;
3905 Display *dpy = dpyinfo->display;
3906 int i, n_monitors, primary = -1;
3907 RROutput pxid = None;
3908 struct MonitorInfo *monitors;
3910 #ifdef HAVE_XRRGETSCREENRESOURCESCURRENT
3911 resources = XRRGetScreenResourcesCurrent (dpy, dpyinfo->root_window);
3912 #else
3913 resources = XRRGetScreenResources (dpy, dpyinfo->root_window);
3914 #endif
3915 if (! resources || resources->noutput == 0)
3917 if (resources)
3918 XRRFreeScreenResources (resources);
3919 return Qnil;
3921 n_monitors = resources->noutput;
3922 monitors = xzalloc (n_monitors * sizeof *monitors);
3924 #ifdef HAVE_XRRGETOUTPUTPRIMARY
3925 pxid = XRRGetOutputPrimary (dpy, dpyinfo->root_window);
3926 #endif
3928 for (i = 0; i < n_monitors; ++i)
3930 XRROutputInfo *info = XRRGetOutputInfo (dpy, resources,
3931 resources->outputs[i]);
3932 Connection conn = info ? info->connection : RR_Disconnected;
3933 RRCrtc id = info ? info->crtc : None;
3935 if (strcmp (info->name, "default") == 0)
3937 /* Non XRandr 1.2 driver, does not give useful data. */
3938 XRRFreeOutputInfo (info);
3939 XRRFreeScreenResources (resources);
3940 free_monitors (monitors, n_monitors);
3941 return Qnil;
3944 if (conn != RR_Disconnected && id != None)
3946 XRRCrtcInfo *crtc = XRRGetCrtcInfo (dpy, resources, id);
3947 struct MonitorInfo *mi = &monitors[i];
3948 XRectangle workarea_r;
3950 if (! crtc)
3952 XRRFreeOutputInfo (info);
3953 continue;
3956 mi->geom.x = crtc->x;
3957 mi->geom.y = crtc->y;
3958 mi->geom.width = crtc->width;
3959 mi->geom.height = crtc->height;
3960 mi->mm_width = info->mm_width;
3961 mi->mm_height = info->mm_height;
3962 mi->name = xstrdup (info->name);
3964 if (pxid != None && pxid == resources->outputs[i])
3965 primary = i;
3966 else if (primary == -1 && strcmp (info->name, "LVDS") == 0)
3967 primary = i;
3969 if (i == primary && x_get_net_workarea (dpyinfo, &workarea_r))
3971 mi->work= workarea_r;
3972 if (! x_intersect_rectangles (&mi->geom, &mi->work, &mi->work))
3973 mi->work = mi->geom;
3975 else
3976 mi->work = mi->geom;
3978 XRRFreeCrtcInfo (crtc);
3980 XRRFreeOutputInfo (info);
3982 XRRFreeScreenResources (resources);
3984 attributes_list = x_make_monitor_attribute_list (monitors,
3985 n_monitors,
3986 primary,
3987 dpyinfo,
3988 "XRandr");
3989 free_monitors (monitors, n_monitors);
3990 return attributes_list;
3992 #endif /* HAVE_XRANDR */
3994 static Lisp_Object
3995 x_get_monitor_attributes (struct x_display_info *dpyinfo)
3997 Lisp_Object attributes_list = Qnil;
3998 Display *dpy = dpyinfo->display;
4000 (void) dpy; /* Suppress unused variable warning. */
4002 #ifdef HAVE_XRANDR
4003 int xrr_event_base, xrr_error_base;
4004 bool xrr_ok = false;
4005 xrr_ok = XRRQueryExtension (dpy, &xrr_event_base, &xrr_error_base);
4006 if (xrr_ok)
4008 int xrr_major, xrr_minor;
4009 XRRQueryVersion (dpy, &xrr_major, &xrr_minor);
4010 xrr_ok = (xrr_major == 1 && xrr_minor >= 2) || xrr_major > 1;
4013 if (xrr_ok)
4014 attributes_list = x_get_monitor_attributes_xrandr (dpyinfo);
4015 #endif /* HAVE_XRANDR */
4017 #ifdef HAVE_XINERAMA
4018 if (NILP (attributes_list))
4020 int xin_event_base, xin_error_base;
4021 bool xin_ok = false;
4022 xin_ok = XineramaQueryExtension (dpy, &xin_event_base, &xin_error_base);
4023 if (xin_ok && XineramaIsActive (dpy))
4024 attributes_list = x_get_monitor_attributes_xinerama (dpyinfo);
4026 #endif /* HAVE_XINERAMA */
4028 if (NILP (attributes_list))
4029 attributes_list = x_get_monitor_attributes_fallback (dpyinfo);
4031 return attributes_list;
4034 #endif /* !USE_GTK */
4036 DEFUN ("x-display-monitor-attributes-list", Fx_display_monitor_attributes_list,
4037 Sx_display_monitor_attributes_list,
4038 0, 1, 0,
4039 doc: /* Return a list of physical monitor attributes on the X display TERMINAL.
4041 The optional argument TERMINAL specifies which display to ask about.
4042 TERMINAL should be a terminal object, a frame or a display name (a string).
4043 If omitted or nil, that stands for the selected frame's display.
4045 In addition to the standard attribute keys listed in
4046 `display-monitor-attributes-list', the following keys are contained in
4047 the attributes:
4049 source -- String describing the source from which multi-monitor
4050 information is obtained, one of \"Gdk\", \"XRandr\",
4051 \"Xinerama\", or \"fallback\"
4053 Internal use only, use `display-monitor-attributes-list' instead. */)
4054 (Lisp_Object terminal)
4056 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4057 Lisp_Object attributes_list = Qnil;
4059 #ifdef USE_GTK
4060 double mm_width_per_pixel, mm_height_per_pixel;
4061 GdkDisplay *gdpy;
4062 GdkScreen *gscreen;
4063 gint primary_monitor = 0, n_monitors, i;
4064 Lisp_Object monitor_frames, rest, frame;
4065 static const char *source = "Gdk";
4066 struct MonitorInfo *monitors;
4068 block_input ();
4069 mm_width_per_pixel = ((double) WidthMMOfScreen (dpyinfo->screen)
4070 / x_display_pixel_width (dpyinfo));
4071 mm_height_per_pixel = ((double) HeightMMOfScreen (dpyinfo->screen)
4072 / x_display_pixel_height (dpyinfo));
4073 gdpy = gdk_x11_lookup_xdisplay (dpyinfo->display);
4074 gscreen = gdk_display_get_default_screen (gdpy);
4075 #if GTK_CHECK_VERSION (2, 20, 0)
4076 primary_monitor = gdk_screen_get_primary_monitor (gscreen);
4077 #endif
4078 n_monitors = gdk_screen_get_n_monitors (gscreen);
4079 monitor_frames = Fmake_vector (make_number (n_monitors), Qnil);
4080 monitors = xzalloc (n_monitors * sizeof *monitors);
4082 FOR_EACH_FRAME (rest, frame)
4084 struct frame *f = XFRAME (frame);
4086 if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo
4087 && !EQ (frame, tip_frame))
4089 GdkWindow *gwin = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
4091 i = gdk_screen_get_monitor_at_window (gscreen, gwin);
4092 ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
4096 for (i = 0; i < n_monitors; ++i)
4098 gint width_mm = -1, height_mm = -1;
4099 GdkRectangle rec, work;
4100 struct MonitorInfo *mi = &monitors[i];
4102 gdk_screen_get_monitor_geometry (gscreen, i, &rec);
4104 #if GTK_CHECK_VERSION (2, 14, 0)
4105 width_mm = gdk_screen_get_monitor_width_mm (gscreen, i);
4106 height_mm = gdk_screen_get_monitor_height_mm (gscreen, i);
4107 #endif
4108 if (width_mm < 0)
4109 width_mm = rec.width * mm_width_per_pixel + 0.5;
4110 if (height_mm < 0)
4111 height_mm = rec.height * mm_height_per_pixel + 0.5;
4113 #if GTK_CHECK_VERSION (3, 4, 0)
4114 gdk_screen_get_monitor_workarea (gscreen, i, &work);
4115 #else
4116 /* Emulate the behavior of GTK+ 3.4. */
4118 XRectangle workarea_r;
4120 if (i == primary_monitor && x_get_net_workarea (dpyinfo, &workarea_r))
4122 work.x = workarea_r.x;
4123 work.y = workarea_r.y;
4124 work.width = workarea_r.width;
4125 work.height = workarea_r.height;
4126 if (! gdk_rectangle_intersect (&rec, &work, &work))
4127 work = rec;
4129 else
4130 work = rec;
4132 #endif
4135 mi->geom.x = rec.x;
4136 mi->geom.y = rec.y;
4137 mi->geom.width = rec.width;
4138 mi->geom.height = rec.height;
4139 mi->work.x = work.x;
4140 mi->work.y = work.y;
4141 mi->work.width = work.width;
4142 mi->work.height = work.height;
4143 mi->mm_width = width_mm;
4144 mi->mm_height = height_mm;
4146 #if GTK_CHECK_VERSION (2, 14, 0)
4147 mi->name = gdk_screen_get_monitor_plug_name (gscreen, i);
4148 #endif
4151 attributes_list = make_monitor_attribute_list (monitors,
4152 n_monitors,
4153 primary_monitor,
4154 monitor_frames,
4155 source);
4156 unblock_input ();
4157 #else /* not USE_GTK */
4159 block_input ();
4160 attributes_list = x_get_monitor_attributes (dpyinfo);
4161 unblock_input ();
4163 #endif /* not USE_GTK */
4165 return attributes_list;
4168 /************************************************************************
4169 X Displays
4170 ************************************************************************/
4173 /* Mapping visual names to visuals. */
4175 static struct visual_class
4177 const char *name;
4178 int class;
4180 visual_classes[] =
4182 {"StaticGray", StaticGray},
4183 {"GrayScale", GrayScale},
4184 {"StaticColor", StaticColor},
4185 {"PseudoColor", PseudoColor},
4186 {"TrueColor", TrueColor},
4187 {"DirectColor", DirectColor},
4188 {NULL, 0}
4192 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4194 /* Value is the screen number of screen SCR. This is a substitute for
4195 the X function with the same name when that doesn't exist. */
4198 XScreenNumberOfScreen (scr)
4199 register Screen *scr;
4201 Display *dpy = scr->display;
4202 int i;
4204 for (i = 0; i < dpy->nscreens; ++i)
4205 if (scr == dpy->screens + i)
4206 break;
4208 return i;
4211 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4214 /* Select the visual that should be used on display DPYINFO. Set
4215 members of DPYINFO appropriately. Called from x_term_init. */
4217 void
4218 select_visual (struct x_display_info *dpyinfo)
4220 Display *dpy = dpyinfo->display;
4221 Screen *screen = dpyinfo->screen;
4222 Lisp_Object value;
4224 /* See if a visual is specified. */
4225 value = display_x_get_resource (dpyinfo,
4226 build_string ("visualClass"),
4227 build_string ("VisualClass"),
4228 Qnil, Qnil);
4229 if (STRINGP (value))
4231 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
4232 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
4233 depth, a decimal number. NAME is compared with case ignored. */
4234 char *s = alloca (SBYTES (value) + 1);
4235 char *dash;
4236 int i, class = -1;
4237 XVisualInfo vinfo;
4239 strcpy (s, SSDATA (value));
4240 dash = strchr (s, '-');
4241 if (dash)
4243 dpyinfo->n_planes = atoi (dash + 1);
4244 *dash = '\0';
4246 else
4247 /* We won't find a matching visual with depth 0, so that
4248 an error will be printed below. */
4249 dpyinfo->n_planes = 0;
4251 /* Determine the visual class. */
4252 for (i = 0; visual_classes[i].name; ++i)
4253 if (xstrcasecmp (s, visual_classes[i].name) == 0)
4255 class = visual_classes[i].class;
4256 break;
4259 /* Look up a matching visual for the specified class. */
4260 if (class == -1
4261 || !XMatchVisualInfo (dpy, XScreenNumberOfScreen (screen),
4262 dpyinfo->n_planes, class, &vinfo))
4263 fatal ("Invalid visual specification `%s'", SDATA (value));
4265 dpyinfo->visual = vinfo.visual;
4267 else
4269 int n_visuals;
4270 XVisualInfo *vinfo, vinfo_template;
4272 dpyinfo->visual = DefaultVisualOfScreen (screen);
4274 vinfo_template.visualid = XVisualIDFromVisual (dpyinfo->visual);
4275 vinfo_template.screen = XScreenNumberOfScreen (screen);
4276 vinfo = XGetVisualInfo (dpy, VisualIDMask | VisualScreenMask,
4277 &vinfo_template, &n_visuals);
4278 if (n_visuals <= 0)
4279 fatal ("Can't get proper X visual info");
4281 dpyinfo->n_planes = vinfo->depth;
4282 XFree (vinfo);
4287 /* Return the X display structure for the display named NAME.
4288 Open a new connection if necessary. */
4290 static struct x_display_info *
4291 x_display_info_for_name (Lisp_Object name)
4293 struct x_display_info *dpyinfo;
4295 CHECK_STRING (name);
4297 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
4298 if (!NILP (Fstring_equal (XCAR (dpyinfo->name_list_element), name)))
4299 return dpyinfo;
4301 /* Use this general default value to start with. */
4302 Vx_resource_name = Vinvocation_name;
4304 validate_x_resource_name ();
4306 dpyinfo = x_term_init (name, 0, SSDATA (Vx_resource_name));
4308 if (dpyinfo == 0)
4309 error ("Cannot connect to X server %s", SDATA (name));
4311 XSETFASTINT (Vwindow_system_version, 11);
4313 return dpyinfo;
4317 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
4318 1, 3, 0,
4319 doc: /* Open a connection to a display server.
4320 DISPLAY is the name of the display to connect to.
4321 Optional second arg XRM-STRING is a string of resources in xrdb format.
4322 If the optional third arg MUST-SUCCEED is non-nil,
4323 terminate Emacs if we can't open the connection.
4324 \(In the Nextstep version, the last two arguments are currently ignored.) */)
4325 (Lisp_Object display, Lisp_Object xrm_string, Lisp_Object must_succeed)
4327 char *xrm_option;
4328 struct x_display_info *dpyinfo;
4330 CHECK_STRING (display);
4331 if (! NILP (xrm_string))
4332 CHECK_STRING (xrm_string);
4334 xrm_option = NILP (xrm_string) ? 0 : SSDATA (xrm_string);
4336 validate_x_resource_name ();
4338 /* This is what opens the connection and sets x_current_display.
4339 This also initializes many symbols, such as those used for input. */
4340 dpyinfo = x_term_init (display, xrm_option,
4341 SSDATA (Vx_resource_name));
4343 if (dpyinfo == 0)
4345 if (!NILP (must_succeed))
4346 fatal ("Cannot connect to X server %s.\n\
4347 Check the DISPLAY environment variable or use `-d'.\n\
4348 Also use the `xauth' program to verify that you have the proper\n\
4349 authorization information needed to connect the X server.\n\
4350 An insecure way to solve the problem may be to use `xhost'.\n",
4351 SDATA (display));
4352 else
4353 error ("Cannot connect to X server %s", SDATA (display));
4356 XSETFASTINT (Vwindow_system_version, 11);
4357 return Qnil;
4360 DEFUN ("x-close-connection", Fx_close_connection,
4361 Sx_close_connection, 1, 1, 0,
4362 doc: /* Close the connection to TERMINAL's X server.
4363 For TERMINAL, specify a terminal object, a frame or a display name (a
4364 string). If TERMINAL is nil, that stands for the selected frame's
4365 terminal. */)
4366 (Lisp_Object terminal)
4368 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4370 if (dpyinfo->reference_count > 0)
4371 error ("Display still has frames on it");
4373 x_delete_terminal (dpyinfo->terminal);
4375 return Qnil;
4378 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
4379 doc: /* Return the list of display names that Emacs has connections to. */)
4380 (void)
4382 Lisp_Object result = Qnil;
4383 struct x_display_info *xdi;
4385 for (xdi = x_display_list; xdi; xdi = xdi->next)
4386 result = Fcons (XCAR (xdi->name_list_element), result);
4388 return result;
4391 DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
4392 doc: /* If ON is non-nil, report X errors as soon as the erring request is made.
4393 This function only has an effect on X Windows. With MS Windows, it is
4394 defined but does nothing.
4396 If ON is nil, allow buffering of requests.
4397 Turning on synchronization prohibits the Xlib routines from buffering
4398 requests and seriously degrades performance, but makes debugging much
4399 easier.
4400 The optional second argument TERMINAL specifies which display to act on.
4401 TERMINAL should be a terminal object, a frame or a display name (a string).
4402 If TERMINAL is omitted or nil, that stands for the selected frame's display. */)
4403 (Lisp_Object on, Lisp_Object terminal)
4405 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4407 XSynchronize (dpyinfo->display, !EQ (on, Qnil));
4409 return Qnil;
4412 /* Wait for responses to all X commands issued so far for frame F. */
4414 void
4415 x_sync (struct frame *f)
4417 block_input ();
4418 XSync (FRAME_X_DISPLAY (f), False);
4419 unblock_input ();
4423 /***********************************************************************
4424 Window properties
4425 ***********************************************************************/
4427 DEFUN ("x-change-window-property", Fx_change_window_property,
4428 Sx_change_window_property, 2, 6, 0,
4429 doc: /* Change window property PROP to VALUE on the X window of FRAME.
4430 PROP must be a string. VALUE may be a string or a list of conses,
4431 numbers and/or strings. If an element in the list is a string, it is
4432 converted to an atom and the value of the atom is used. If an element
4433 is a cons, it is converted to a 32 bit number where the car is the 16
4434 top bits and the cdr is the lower 16 bits.
4436 FRAME nil or omitted means use the selected frame.
4437 If TYPE is given and non-nil, it is the name of the type of VALUE.
4438 If TYPE is not given or nil, the type is STRING.
4439 FORMAT gives the size in bits of each element if VALUE is a list.
4440 It must be one of 8, 16 or 32.
4441 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
4442 If OUTER-P is non-nil, the property is changed for the outer X window of
4443 FRAME. Default is to change on the edit X window. */)
4444 (Lisp_Object prop, Lisp_Object value, Lisp_Object frame,
4445 Lisp_Object type, Lisp_Object format, Lisp_Object outer_p)
4447 struct frame *f = decode_window_system_frame (frame);
4448 Atom prop_atom;
4449 Atom target_type = XA_STRING;
4450 int element_format = 8;
4451 unsigned char *data;
4452 int nelements;
4453 Window w;
4455 CHECK_STRING (prop);
4457 if (! NILP (format))
4459 CHECK_NUMBER (format);
4461 if (XINT (format) != 8 && XINT (format) != 16
4462 && XINT (format) != 32)
4463 error ("FORMAT must be one of 8, 16 or 32");
4464 element_format = XINT (format);
4467 if (CONSP (value))
4469 ptrdiff_t elsize;
4471 nelements = x_check_property_data (value);
4472 if (nelements == -1)
4473 error ("Bad data in VALUE, must be number, string or cons");
4475 /* The man page for XChangeProperty:
4476 "If the specified format is 32, the property data must be a
4477 long array."
4478 This applies even if long is more than 32 bits. The X library
4479 converts to 32 bits before sending to the X server. */
4480 elsize = element_format == 32 ? sizeof (long) : element_format >> 3;
4481 data = xnmalloc (nelements, elsize);
4483 x_fill_property_data (FRAME_X_DISPLAY (f), value, data, element_format);
4485 else
4487 CHECK_STRING (value);
4488 data = SDATA (value);
4489 if (INT_MAX < SBYTES (value))
4490 error ("VALUE too long");
4491 nelements = SBYTES (value);
4494 block_input ();
4495 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (prop), False);
4496 if (! NILP (type))
4498 CHECK_STRING (type);
4499 target_type = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (type), False);
4502 if (! NILP (outer_p)) w = FRAME_OUTER_WINDOW (f);
4503 else w = FRAME_X_WINDOW (f);
4505 XChangeProperty (FRAME_X_DISPLAY (f), w,
4506 prop_atom, target_type, element_format, PropModeReplace,
4507 data, nelements);
4509 if (CONSP (value)) xfree (data);
4511 /* Make sure the property is set when we return. */
4512 XFlush (FRAME_X_DISPLAY (f));
4513 unblock_input ();
4515 return value;
4519 DEFUN ("x-delete-window-property", Fx_delete_window_property,
4520 Sx_delete_window_property, 1, 2, 0,
4521 doc: /* Remove window property PROP from X window of FRAME.
4522 FRAME nil or omitted means use the selected frame. Value is PROP. */)
4523 (Lisp_Object prop, Lisp_Object frame)
4525 struct frame *f = decode_window_system_frame (frame);
4526 Atom prop_atom;
4528 CHECK_STRING (prop);
4529 block_input ();
4530 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (prop), False);
4531 XDeleteProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), prop_atom);
4533 /* Make sure the property is removed when we return. */
4534 XFlush (FRAME_X_DISPLAY (f));
4535 unblock_input ();
4537 return prop;
4541 DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
4542 1, 6, 0,
4543 doc: /* Value is the value of window property PROP on FRAME.
4544 If FRAME is nil or omitted, use the selected frame.
4546 On X Windows, the following optional arguments are also accepted:
4547 If TYPE is nil or omitted, get the property as a string.
4548 Otherwise TYPE is the name of the atom that denotes the type expected.
4549 If SOURCE is non-nil, get the property on that window instead of from
4550 FRAME. The number 0 denotes the root window.
4551 If DELETE-P is non-nil, delete the property after retrieving it.
4552 If VECTOR-RET-P is non-nil, don't return a string but a vector of values.
4554 On MS Windows, this function accepts but ignores those optional arguments.
4556 Value is nil if FRAME hasn't a property with name PROP or if PROP has
4557 no value of TYPE (always string in the MS Windows case). */)
4558 (Lisp_Object prop, Lisp_Object frame, Lisp_Object type,
4559 Lisp_Object source, Lisp_Object delete_p, Lisp_Object vector_ret_p)
4561 struct frame *f = decode_window_system_frame (frame);
4562 Atom prop_atom;
4563 int rc;
4564 Lisp_Object prop_value = Qnil;
4565 unsigned char *tmp_data = NULL;
4566 Atom actual_type;
4567 Atom target_type = XA_STRING;
4568 int actual_format;
4569 unsigned long actual_size, bytes_remaining;
4570 Window target_window = FRAME_X_WINDOW (f);
4571 struct gcpro gcpro1;
4573 GCPRO1 (prop_value);
4574 CHECK_STRING (prop);
4576 if (! NILP (source))
4578 CONS_TO_INTEGER (source, Window, target_window);
4579 if (! target_window)
4580 target_window = FRAME_DISPLAY_INFO (f)->root_window;
4583 block_input ();
4584 if (STRINGP (type))
4586 if (strcmp ("AnyPropertyType", SSDATA (type)) == 0)
4587 target_type = AnyPropertyType;
4588 else
4589 target_type = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (type), False);
4592 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (prop), False);
4593 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4594 prop_atom, 0, 0, False, target_type,
4595 &actual_type, &actual_format, &actual_size,
4596 &bytes_remaining, &tmp_data);
4597 if (rc == Success)
4599 int size = bytes_remaining;
4601 XFree (tmp_data);
4602 tmp_data = NULL;
4604 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4605 prop_atom, 0, bytes_remaining,
4606 ! NILP (delete_p), target_type,
4607 &actual_type, &actual_format,
4608 &actual_size, &bytes_remaining,
4609 &tmp_data);
4610 if (rc == Success && tmp_data)
4612 /* The man page for XGetWindowProperty says:
4613 "If the returned format is 32, the returned data is represented
4614 as a long array and should be cast to that type to obtain the
4615 elements."
4616 This applies even if long is more than 32 bits, the X library
4617 converts from 32 bit elements received from the X server to long
4618 and passes the long array to us. Thus, for that case memcpy can not
4619 be used. We convert to a 32 bit type here, because so much code
4620 assume on that.
4622 The bytes and offsets passed to XGetWindowProperty refers to the
4623 property and those are indeed in 32 bit quantities if format is
4624 32. */
4626 if (BITS_PER_LONG > 32 && actual_format == 32)
4628 unsigned long i;
4629 int *idata = (int *) tmp_data;
4630 long *ldata = (long *) tmp_data;
4632 for (i = 0; i < actual_size; ++i)
4633 idata[i] = (int) ldata[i];
4636 if (NILP (vector_ret_p))
4637 prop_value = make_string ((char *) tmp_data, size);
4638 else
4639 prop_value = x_property_data_to_lisp (f,
4640 tmp_data,
4641 actual_type,
4642 actual_format,
4643 actual_size);
4646 if (tmp_data) XFree (tmp_data);
4649 unblock_input ();
4650 UNGCPRO;
4651 return prop_value;
4656 /***********************************************************************
4657 Busy cursor
4658 ***********************************************************************/
4660 /* Timer function of hourglass_atimer. TIMER is equal to
4661 hourglass_atimer.
4663 Display an hourglass pointer on all frames by mapping the frames'
4664 hourglass_window. Set the hourglass_p flag in the frames'
4665 output_data.x structure to indicate that an hourglass cursor is
4666 shown on the frames. */
4668 void
4669 show_hourglass (struct atimer *timer)
4671 /* The timer implementation will cancel this timer automatically
4672 after this function has run. Set hourglass_atimer to null
4673 so that we know the timer doesn't have to be canceled. */
4674 hourglass_atimer = NULL;
4676 if (!hourglass_shown_p)
4678 Lisp_Object rest, frame;
4680 block_input ();
4682 FOR_EACH_FRAME (rest, frame)
4684 struct frame *f = XFRAME (frame);
4686 if (FRAME_LIVE_P (f) && FRAME_X_P (f) && FRAME_X_DISPLAY (f))
4688 Display *dpy = FRAME_X_DISPLAY (f);
4690 #ifdef USE_X_TOOLKIT
4691 if (f->output_data.x->widget)
4692 #else
4693 if (FRAME_OUTER_WINDOW (f))
4694 #endif
4696 f->output_data.x->hourglass_p = 1;
4698 if (!f->output_data.x->hourglass_window)
4700 unsigned long mask = CWCursor;
4701 XSetWindowAttributes attrs;
4702 #ifdef USE_GTK
4703 Window parent = FRAME_X_WINDOW (f);
4704 #else
4705 Window parent = FRAME_OUTER_WINDOW (f);
4706 #endif
4707 attrs.cursor = f->output_data.x->hourglass_cursor;
4709 f->output_data.x->hourglass_window
4710 = XCreateWindow (dpy, parent,
4711 0, 0, 32000, 32000, 0, 0,
4712 InputOnly,
4713 CopyFromParent,
4714 mask, &attrs);
4717 XMapRaised (dpy, f->output_data.x->hourglass_window);
4718 XFlush (dpy);
4723 hourglass_shown_p = 1;
4724 unblock_input ();
4729 /* Hide the hourglass pointer on all frames, if it is currently
4730 shown. */
4732 void
4733 hide_hourglass (void)
4735 if (hourglass_shown_p)
4737 Lisp_Object rest, frame;
4739 block_input ();
4740 FOR_EACH_FRAME (rest, frame)
4742 struct frame *f = XFRAME (frame);
4744 if (FRAME_X_P (f)
4745 /* Watch out for newly created frames. */
4746 && f->output_data.x->hourglass_window)
4748 XUnmapWindow (FRAME_X_DISPLAY (f),
4749 f->output_data.x->hourglass_window);
4750 /* Sync here because XTread_socket looks at the
4751 hourglass_p flag that is reset to zero below. */
4752 XSync (FRAME_X_DISPLAY (f), False);
4753 f->output_data.x->hourglass_p = 0;
4757 hourglass_shown_p = 0;
4758 unblock_input ();
4764 /***********************************************************************
4765 Tool tips
4766 ***********************************************************************/
4768 static Lisp_Object x_create_tip_frame (struct x_display_info *,
4769 Lisp_Object, Lisp_Object);
4770 static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
4771 Lisp_Object, int, int, int *, int *);
4773 /* The frame of a currently visible tooltip. */
4775 Lisp_Object tip_frame;
4777 /* If non-nil, a timer started that hides the last tooltip when it
4778 fires. */
4780 static Lisp_Object tip_timer;
4781 Window tip_window;
4783 /* If non-nil, a vector of 3 elements containing the last args
4784 with which x-show-tip was called. See there. */
4786 static Lisp_Object last_show_tip_args;
4789 static void
4790 unwind_create_tip_frame (Lisp_Object frame)
4792 Lisp_Object deleted;
4794 deleted = unwind_create_frame (frame);
4795 if (EQ (deleted, Qt))
4797 tip_window = None;
4798 tip_frame = Qnil;
4803 /* Create a frame for a tooltip on the display described by DPYINFO.
4804 PARMS is a list of frame parameters. TEXT is the string to
4805 display in the tip frame. Value is the frame.
4807 Note that functions called here, esp. x_default_parameter can
4808 signal errors, for instance when a specified color name is
4809 undefined. We have to make sure that we're in a consistent state
4810 when this happens. */
4812 static Lisp_Object
4813 x_create_tip_frame (struct x_display_info *dpyinfo,
4814 Lisp_Object parms,
4815 Lisp_Object text)
4817 struct frame *f;
4818 Lisp_Object frame;
4819 Lisp_Object name;
4820 int width, height;
4821 ptrdiff_t count = SPECPDL_INDEX ();
4822 struct gcpro gcpro1, gcpro2, gcpro3;
4823 int face_change_count_before = face_change_count;
4824 Lisp_Object buffer;
4825 struct buffer *old_buffer;
4827 if (!dpyinfo->terminal->name)
4828 error ("Terminal is not live, can't create new frames on it");
4830 parms = Fcopy_alist (parms);
4832 /* Get the name of the frame to use for resource lookup. */
4833 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
4834 if (!STRINGP (name)
4835 && !EQ (name, Qunbound)
4836 && !NILP (name))
4837 error ("Invalid frame name--not a string or nil");
4839 frame = Qnil;
4840 GCPRO3 (parms, name, frame);
4841 f = make_frame (1);
4842 XSETFRAME (frame, f);
4844 buffer = Fget_buffer_create (build_string (" *tip*"));
4845 /* Use set_window_buffer instead of Fset_window_buffer (see
4846 discussion of bug#11984, bug#12025, bug#12026). */
4847 set_window_buffer (FRAME_ROOT_WINDOW (f), buffer, 0, 0);
4848 old_buffer = current_buffer;
4849 set_buffer_internal_1 (XBUFFER (buffer));
4850 bset_truncate_lines (current_buffer, Qnil);
4851 specbind (Qinhibit_read_only, Qt);
4852 specbind (Qinhibit_modification_hooks, Qt);
4853 Ferase_buffer ();
4854 Finsert (1, &text);
4855 set_buffer_internal_1 (old_buffer);
4857 record_unwind_protect (unwind_create_tip_frame, frame);
4859 f->terminal = dpyinfo->terminal;
4861 /* By setting the output method, we're essentially saying that
4862 the frame is live, as per FRAME_LIVE_P. If we get a signal
4863 from this point on, x_destroy_window might screw up reference
4864 counts etc. */
4865 f->output_method = output_x_window;
4866 f->output_data.x = xzalloc (sizeof *f->output_data.x);
4867 f->output_data.x->icon_bitmap = -1;
4868 FRAME_FONTSET (f) = -1;
4869 f->output_data.x->scroll_bar_foreground_pixel = -1;
4870 f->output_data.x->scroll_bar_background_pixel = -1;
4871 #ifdef USE_TOOLKIT_SCROLL_BARS
4872 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
4873 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
4874 #endif /* USE_TOOLKIT_SCROLL_BARS */
4875 f->output_data.x->white_relief.pixel = -1;
4876 f->output_data.x->black_relief.pixel = -1;
4878 fset_icon_name (f, Qnil);
4879 FRAME_DISPLAY_INFO (f) = dpyinfo;
4880 f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
4881 f->output_data.x->explicit_parent = 0;
4883 /* These colors will be set anyway later, but it's important
4884 to get the color reference counts right, so initialize them! */
4886 Lisp_Object black;
4887 struct gcpro gcpro1;
4889 /* Function x_decode_color can signal an error. Make
4890 sure to initialize color slots so that we won't try
4891 to free colors we haven't allocated. */
4892 FRAME_FOREGROUND_PIXEL (f) = -1;
4893 FRAME_BACKGROUND_PIXEL (f) = -1;
4894 f->output_data.x->cursor_pixel = -1;
4895 f->output_data.x->cursor_foreground_pixel = -1;
4896 f->output_data.x->border_pixel = -1;
4897 f->output_data.x->mouse_pixel = -1;
4899 black = build_string ("black");
4900 GCPRO1 (black);
4901 FRAME_FOREGROUND_PIXEL (f)
4902 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4903 FRAME_BACKGROUND_PIXEL (f)
4904 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4905 f->output_data.x->cursor_pixel
4906 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4907 f->output_data.x->cursor_foreground_pixel
4908 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4909 f->output_data.x->border_pixel
4910 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4911 f->output_data.x->mouse_pixel
4912 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4913 UNGCPRO;
4916 /* Set the name; the functions to which we pass f expect the name to
4917 be set. */
4918 if (EQ (name, Qunbound) || NILP (name))
4920 fset_name (f, build_string (dpyinfo->x_id_name));
4921 f->explicit_name = 0;
4923 else
4925 fset_name (f, name);
4926 f->explicit_name = 1;
4927 /* use the frame's title when getting resources for this frame. */
4928 specbind (Qx_resource_name, name);
4931 register_font_driver (&xfont_driver, f);
4932 #ifdef HAVE_FREETYPE
4933 #ifdef HAVE_XFT
4934 register_font_driver (&xftfont_driver, f);
4935 #else /* not HAVE_XFT */
4936 register_font_driver (&ftxfont_driver, f);
4937 #endif /* not HAVE_XFT */
4938 #endif /* HAVE_FREETYPE */
4940 x_default_parameter (f, parms, Qfont_backend, Qnil,
4941 "fontBackend", "FontBackend", RES_TYPE_STRING);
4943 /* Extract the window parameters from the supplied values that are
4944 needed to determine window geometry. */
4945 x_default_font_parameter (f, parms);
4947 x_default_parameter (f, parms, Qborder_width, make_number (0),
4948 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
4950 /* This defaults to 2 in order to match xterm. We recognize either
4951 internalBorderWidth or internalBorder (which is what xterm calls
4952 it). */
4953 if (NILP (Fassq (Qinternal_border_width, parms)))
4955 Lisp_Object value;
4957 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
4958 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
4959 if (! EQ (value, Qunbound))
4960 parms = Fcons (Fcons (Qinternal_border_width, value),
4961 parms);
4964 x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
4965 "internalBorderWidth", "internalBorderWidth",
4966 RES_TYPE_NUMBER);
4967 x_default_parameter (f, parms, Qright_divider_width, make_number (0),
4968 NULL, NULL, RES_TYPE_NUMBER);
4969 x_default_parameter (f, parms, Qbottom_divider_width, make_number (0),
4970 NULL, NULL, RES_TYPE_NUMBER);
4972 /* Also do the stuff which must be set before the window exists. */
4973 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
4974 "foreground", "Foreground", RES_TYPE_STRING);
4975 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
4976 "background", "Background", RES_TYPE_STRING);
4977 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
4978 "pointerColor", "Foreground", RES_TYPE_STRING);
4979 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
4980 "cursorColor", "Foreground", RES_TYPE_STRING);
4981 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
4982 "borderColor", "BorderColor", RES_TYPE_STRING);
4984 #ifdef GLYPH_DEBUG
4985 image_cache_refcount =
4986 FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
4987 dpyinfo_refcount = dpyinfo->reference_count;
4988 #endif /* GLYPH_DEBUG */
4990 /* Init faces before x_default_parameter is called for scroll-bar
4991 parameters because that function calls x_set_scroll_bar_width,
4992 which calls change_frame_size, which calls Fset_window_buffer,
4993 which runs hooks, which call Fvertical_motion. At the end, we
4994 end up in init_iterator with a null face cache, which should not
4995 happen. */
4996 init_frame_faces (f);
4998 f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
5000 x_figure_window_size (f, parms, 0);
5003 XSetWindowAttributes attrs;
5004 unsigned long mask;
5005 Atom type = FRAME_DISPLAY_INFO (f)->Xatom_net_window_type_tooltip;
5007 block_input ();
5008 mask = CWBackPixel | CWOverrideRedirect | CWEventMask;
5009 if (DoesSaveUnders (dpyinfo->screen))
5010 mask |= CWSaveUnder;
5012 /* Window managers look at the override-redirect flag to determine
5013 whether or net to give windows a decoration (Xlib spec, chapter
5014 3.2.8). */
5015 attrs.override_redirect = True;
5016 attrs.save_under = True;
5017 attrs.background_pixel = FRAME_BACKGROUND_PIXEL (f);
5018 /* Arrange for getting MapNotify and UnmapNotify events. */
5019 attrs.event_mask = StructureNotifyMask;
5020 tip_window
5021 = FRAME_X_WINDOW (f)
5022 = XCreateWindow (FRAME_X_DISPLAY (f),
5023 FRAME_DISPLAY_INFO (f)->root_window,
5024 /* x, y, width, height */
5025 0, 0, 1, 1,
5026 /* Border. */
5027 f->border_width,
5028 CopyFromParent, InputOutput, CopyFromParent,
5029 mask, &attrs);
5030 XChangeProperty (FRAME_X_DISPLAY (f), tip_window,
5031 FRAME_DISPLAY_INFO (f)->Xatom_net_window_type,
5032 XA_ATOM, 32, PropModeReplace,
5033 (unsigned char *)&type, 1);
5034 unblock_input ();
5037 x_make_gc (f);
5039 x_default_parameter (f, parms, Qauto_raise, Qnil,
5040 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
5041 x_default_parameter (f, parms, Qauto_lower, Qnil,
5042 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
5043 x_default_parameter (f, parms, Qcursor_type, Qbox,
5044 "cursorType", "CursorType", RES_TYPE_SYMBOL);
5046 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
5047 Change will not be effected unless different from the current
5048 FRAME_LINES (f). */
5049 width = FRAME_COLS (f);
5050 height = FRAME_LINES (f);
5051 SET_FRAME_COLS (f, 0);
5052 FRAME_LINES (f) = 0;
5053 change_frame_size (f, width, height, 1, 0, 0, 0);
5055 /* Add `tooltip' frame parameter's default value. */
5056 if (NILP (Fframe_parameter (frame, Qtooltip)))
5057 Fmodify_frame_parameters (frame, list1 (Fcons (Qtooltip, Qt)));
5059 /* FIXME - can this be done in a similar way to normal frames?
5060 http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
5062 /* Set the `display-type' frame parameter before setting up faces. */
5064 Lisp_Object disptype;
5066 if (FRAME_DISPLAY_INFO (f)->n_planes == 1)
5067 disptype = intern ("mono");
5068 else if (FRAME_DISPLAY_INFO (f)->visual->class == GrayScale
5069 || FRAME_DISPLAY_INFO (f)->visual->class == StaticGray)
5070 disptype = intern ("grayscale");
5071 else
5072 disptype = intern ("color");
5074 if (NILP (Fframe_parameter (frame, Qdisplay_type)))
5075 Fmodify_frame_parameters (frame, list1 (Fcons (Qdisplay_type, disptype)));
5078 /* Set up faces after all frame parameters are known. This call
5079 also merges in face attributes specified for new frames.
5081 Frame parameters may be changed if .Xdefaults contains
5082 specifications for the default font. For example, if there is an
5083 `Emacs.default.attributeBackground: pink', the `background-color'
5084 attribute of the frame get's set, which let's the internal border
5085 of the tooltip frame appear in pink. Prevent this. */
5087 Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
5089 /* Set tip_frame here, so that */
5090 tip_frame = frame;
5091 call2 (Qface_set_after_frame_default, frame, Qnil);
5093 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
5094 Fmodify_frame_parameters (frame, list1 (Fcons (Qbackground_color, bg)));
5097 f->no_split = 1;
5099 UNGCPRO;
5101 /* Now that the frame will be official, it counts as a reference to
5102 its display and terminal. */
5103 FRAME_DISPLAY_INFO (f)->reference_count++;
5104 f->terminal->reference_count++;
5106 /* It is now ok to make the frame official even if we get an error
5107 below. And the frame needs to be on Vframe_list or making it
5108 visible won't work. */
5109 Vframe_list = Fcons (frame, Vframe_list);
5112 /* Setting attributes of faces of the tooltip frame from resources
5113 and similar will increment face_change_count, which leads to the
5114 clearing of all current matrices. Since this isn't necessary
5115 here, avoid it by resetting face_change_count to the value it
5116 had before we created the tip frame. */
5117 face_change_count = face_change_count_before;
5119 /* Discard the unwind_protect. */
5120 return unbind_to (count, frame);
5124 /* Compute where to display tip frame F. PARMS is the list of frame
5125 parameters for F. DX and DY are specified offsets from the current
5126 location of the mouse. WIDTH and HEIGHT are the width and height
5127 of the tooltip. Return coordinates relative to the root window of
5128 the display in *ROOT_X, and *ROOT_Y. */
5130 static void
5131 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)
5133 Lisp_Object left, top;
5134 int win_x, win_y;
5135 Window root, child;
5136 unsigned pmask;
5138 /* User-specified position? */
5139 left = Fcdr (Fassq (Qleft, parms));
5140 top = Fcdr (Fassq (Qtop, parms));
5142 /* Move the tooltip window where the mouse pointer is. Resize and
5143 show it. */
5144 if (!INTEGERP (left) || !INTEGERP (top))
5146 block_input ();
5147 XQueryPointer (FRAME_X_DISPLAY (f), FRAME_DISPLAY_INFO (f)->root_window,
5148 &root, &child, root_x, root_y, &win_x, &win_y, &pmask);
5149 unblock_input ();
5152 if (INTEGERP (top))
5153 *root_y = XINT (top);
5154 else if (*root_y + XINT (dy) <= 0)
5155 *root_y = 0; /* Can happen for negative dy */
5156 else if (*root_y + XINT (dy) + height
5157 <= x_display_pixel_height (FRAME_DISPLAY_INFO (f)))
5158 /* It fits below the pointer */
5159 *root_y += XINT (dy);
5160 else if (height + XINT (dy) <= *root_y)
5161 /* It fits above the pointer. */
5162 *root_y -= height + XINT (dy);
5163 else
5164 /* Put it on the top. */
5165 *root_y = 0;
5167 if (INTEGERP (left))
5168 *root_x = XINT (left);
5169 else if (*root_x + XINT (dx) <= 0)
5170 *root_x = 0; /* Can happen for negative dx */
5171 else if (*root_x + XINT (dx) + width
5172 <= x_display_pixel_width (FRAME_DISPLAY_INFO (f)))
5173 /* It fits to the right of the pointer. */
5174 *root_x += XINT (dx);
5175 else if (width + XINT (dx) <= *root_x)
5176 /* It fits to the left of the pointer. */
5177 *root_x -= width + XINT (dx);
5178 else
5179 /* Put it left-justified on the screen--it ought to fit that way. */
5180 *root_x = 0;
5184 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
5185 doc: /* Show STRING in a "tooltip" window on frame FRAME.
5186 A tooltip window is a small X window displaying a string.
5188 This is an internal function; Lisp code should call `tooltip-show'.
5190 FRAME nil or omitted means use the selected frame.
5192 PARMS is an optional list of frame parameters which can be used to
5193 change the tooltip's appearance.
5195 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
5196 means use the default timeout of 5 seconds.
5198 If the list of frame parameters PARMS contains a `left' parameters,
5199 the tooltip is displayed at that x-position. Otherwise it is
5200 displayed at the mouse position, with offset DX added (default is 5 if
5201 DX isn't specified). Likewise for the y-position; if a `top' frame
5202 parameter is specified, it determines the y-position of the tooltip
5203 window, otherwise it is displayed at the mouse position, with offset
5204 DY added (default is -10).
5206 A tooltip's maximum size is specified by `x-max-tooltip-size'.
5207 Text larger than the specified size is clipped. */)
5208 (Lisp_Object string, Lisp_Object frame, Lisp_Object parms, Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy)
5210 struct frame *f;
5211 struct window *w;
5212 int root_x, root_y;
5213 struct buffer *old_buffer;
5214 struct text_pos pos;
5215 int i, width, height, seen_reversed_p;
5216 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
5217 int old_windows_or_buffers_changed = windows_or_buffers_changed;
5218 ptrdiff_t count = SPECPDL_INDEX ();
5220 specbind (Qinhibit_redisplay, Qt);
5222 GCPRO4 (string, parms, frame, timeout);
5224 CHECK_STRING (string);
5225 if (SCHARS (string) == 0)
5226 string = make_unibyte_string (" ", 1);
5228 f = decode_window_system_frame (frame);
5229 if (NILP (timeout))
5230 timeout = make_number (5);
5231 else
5232 CHECK_NATNUM (timeout);
5234 if (NILP (dx))
5235 dx = make_number (5);
5236 else
5237 CHECK_NUMBER (dx);
5239 if (NILP (dy))
5240 dy = make_number (-10);
5241 else
5242 CHECK_NUMBER (dy);
5244 #ifdef USE_GTK
5245 if (x_gtk_use_system_tooltips)
5247 bool ok;
5249 /* Hide a previous tip, if any. */
5250 Fx_hide_tip ();
5252 block_input ();
5253 ok = xg_prepare_tooltip (f, string, &width, &height);
5254 if (ok)
5256 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
5257 xg_show_tooltip (f, root_x, root_y);
5258 /* This is used in Fx_hide_tip. */
5259 XSETFRAME (tip_frame, f);
5261 unblock_input ();
5262 if (ok) goto start_timer;
5264 #endif /* USE_GTK */
5266 if (NILP (last_show_tip_args))
5267 last_show_tip_args = Fmake_vector (make_number (3), Qnil);
5269 if (!NILP (tip_frame))
5271 Lisp_Object last_string = AREF (last_show_tip_args, 0);
5272 Lisp_Object last_frame = AREF (last_show_tip_args, 1);
5273 Lisp_Object last_parms = AREF (last_show_tip_args, 2);
5275 if (EQ (frame, last_frame)
5276 && !NILP (Fequal (last_string, string))
5277 && !NILP (Fequal (last_parms, parms)))
5279 struct frame *tip_f = XFRAME (tip_frame);
5281 /* Only DX and DY have changed. */
5282 if (!NILP (tip_timer))
5284 Lisp_Object timer = tip_timer;
5285 tip_timer = Qnil;
5286 call1 (Qcancel_timer, timer);
5289 block_input ();
5290 compute_tip_xy (tip_f, parms, dx, dy, FRAME_PIXEL_WIDTH (tip_f),
5291 FRAME_PIXEL_HEIGHT (tip_f), &root_x, &root_y);
5292 XMoveWindow (FRAME_X_DISPLAY (tip_f), FRAME_X_WINDOW (tip_f),
5293 root_x, root_y);
5294 unblock_input ();
5295 goto start_timer;
5299 /* Hide a previous tip, if any. */
5300 Fx_hide_tip ();
5302 ASET (last_show_tip_args, 0, string);
5303 ASET (last_show_tip_args, 1, frame);
5304 ASET (last_show_tip_args, 2, parms);
5306 /* Add default values to frame parameters. */
5307 if (NILP (Fassq (Qname, parms)))
5308 parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
5309 if (NILP (Fassq (Qinternal_border_width, parms)))
5310 parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
5311 if (NILP (Fassq (Qborder_width, parms)))
5312 parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
5313 if (NILP (Fassq (Qbottom_divider_width, parms)))
5314 parms = Fcons (Fcons (Qbottom_divider_width, make_number (0)), parms);
5315 if (NILP (Fassq (Qright_divider_width, parms)))
5316 parms = Fcons (Fcons (Qright_divider_width, make_number (0)), parms);
5317 if (NILP (Fassq (Qborder_color, parms)))
5318 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
5319 if (NILP (Fassq (Qbackground_color, parms)))
5320 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
5321 parms);
5323 /* Create a frame for the tooltip, and record it in the global
5324 variable tip_frame. */
5325 frame = x_create_tip_frame (FRAME_DISPLAY_INFO (f), parms, string);
5326 f = XFRAME (frame);
5328 /* Set up the frame's root window. */
5329 w = XWINDOW (FRAME_ROOT_WINDOW (f));
5330 w->left_col = 0;
5331 w->top_line = 0;
5332 w->pixel_left = 0;
5333 w->pixel_top = 0;
5335 if (CONSP (Vx_max_tooltip_size)
5336 && RANGED_INTEGERP (1, XCAR (Vx_max_tooltip_size), INT_MAX)
5337 && RANGED_INTEGERP (1, XCDR (Vx_max_tooltip_size), INT_MAX))
5339 w->total_cols = XFASTINT (XCAR (Vx_max_tooltip_size));
5340 w->total_lines = XFASTINT (XCDR (Vx_max_tooltip_size));
5342 else
5344 w->total_cols = 80;
5345 w->total_lines = 40;
5348 w->pixel_width = w->total_cols * FRAME_COLUMN_WIDTH (f);
5349 w->pixel_height = w->total_lines * FRAME_LINE_HEIGHT (f);
5351 FRAME_TOTAL_COLS (f) = w->total_cols;
5352 adjust_frame_glyphs (f);
5353 w->pseudo_window_p = 1;
5355 /* Display the tooltip text in a temporary buffer. */
5356 old_buffer = current_buffer;
5357 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->contents));
5358 bset_truncate_lines (current_buffer, Qnil);
5359 clear_glyph_matrix (w->desired_matrix);
5360 clear_glyph_matrix (w->current_matrix);
5361 SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
5362 try_window (FRAME_ROOT_WINDOW (f), pos, TRY_WINDOW_IGNORE_FONTS_CHANGE);
5364 /* Compute width and height of the tooltip. */
5365 width = height = seen_reversed_p = 0;
5366 for (i = 0; i < w->desired_matrix->nrows; ++i)
5368 struct glyph_row *row = &w->desired_matrix->rows[i];
5369 struct glyph *last;
5370 int row_width;
5372 /* Stop at the first empty row at the end. */
5373 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
5374 break;
5376 /* Let the row go over the full width of the frame. */
5377 row->full_width_p = 1;
5379 row_width = row->pixel_width;
5380 if (row->used[TEXT_AREA])
5382 /* There's a glyph at the end of rows that is used to place
5383 the cursor there. Don't include the width of this glyph. */
5384 if (!row->reversed_p)
5386 last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
5387 if (INTEGERP (last->object))
5388 row_width -= last->pixel_width;
5390 else
5392 /* There could be a stretch glyph at the beginning of R2L
5393 rows that is produced by extend_face_to_end_of_line.
5394 Don't count that glyph. */
5395 struct glyph *g = row->glyphs[TEXT_AREA];
5397 if (g->type == STRETCH_GLYPH && INTEGERP (g->object))
5399 row_width -= g->pixel_width;
5400 seen_reversed_p = 1;
5405 height += row->height;
5406 width = max (width, row_width);
5409 /* If we've seen partial-length R2L rows, we need to re-adjust the
5410 tool-tip frame width and redisplay it again, to avoid over-wide
5411 tips due to the stretch glyph that extends R2L lines to full
5412 width of the frame. */
5413 if (seen_reversed_p)
5415 /* w->total_cols and FRAME_TOTAL_COLS want the width in columns,
5416 not in pixels. */
5417 w->pixel_width = width;
5418 width /= WINDOW_FRAME_COLUMN_WIDTH (w);
5419 w->total_cols = width;
5420 FRAME_TOTAL_COLS (f) = width;
5421 SET_FRAME_WIDTH (f, width);
5422 adjust_frame_glyphs (f);
5423 clear_glyph_matrix (w->desired_matrix);
5424 clear_glyph_matrix (w->current_matrix);
5425 try_window (FRAME_ROOT_WINDOW (f), pos, 0);
5426 width = height = 0;
5427 /* Recompute width and height of the tooltip. */
5428 for (i = 0; i < w->desired_matrix->nrows; ++i)
5430 struct glyph_row *row = &w->desired_matrix->rows[i];
5431 struct glyph *last;
5432 int row_width;
5434 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
5435 break;
5436 row->full_width_p = 1;
5437 row_width = row->pixel_width;
5438 if (row->used[TEXT_AREA] && !row->reversed_p)
5440 last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
5441 if (INTEGERP (last->object))
5442 row_width -= last->pixel_width;
5445 height += row->height;
5446 width = max (width, row_width);
5450 /* Add the frame's internal border to the width and height the X
5451 window should have. */
5452 height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5453 width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5455 /* Move the tooltip window where the mouse pointer is. Resize and
5456 show it. */
5457 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
5459 block_input ();
5460 XMoveResizeWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5461 root_x, root_y, width, height);
5462 XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
5463 unblock_input ();
5465 /* Draw into the window. */
5466 w->must_be_updated_p = 1;
5467 update_single_window (w, 1);
5469 /* Restore original current buffer. */
5470 set_buffer_internal_1 (old_buffer);
5471 windows_or_buffers_changed = old_windows_or_buffers_changed;
5473 start_timer:
5474 /* Let the tip disappear after timeout seconds. */
5475 tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
5476 intern ("x-hide-tip"));
5478 UNGCPRO;
5479 return unbind_to (count, Qnil);
5483 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
5484 doc: /* Hide the current tooltip window, if there is any.
5485 Value is t if tooltip was open, nil otherwise. */)
5486 (void)
5488 ptrdiff_t count;
5489 Lisp_Object deleted, frame, timer;
5490 struct gcpro gcpro1, gcpro2;
5492 /* Return quickly if nothing to do. */
5493 if (NILP (tip_timer) && NILP (tip_frame))
5494 return Qnil;
5496 frame = tip_frame;
5497 timer = tip_timer;
5498 GCPRO2 (frame, timer);
5499 tip_frame = tip_timer = deleted = Qnil;
5501 count = SPECPDL_INDEX ();
5502 specbind (Qinhibit_redisplay, Qt);
5503 specbind (Qinhibit_quit, Qt);
5505 if (!NILP (timer))
5506 call1 (Qcancel_timer, timer);
5508 #ifdef USE_GTK
5510 /* When using system tooltip, tip_frame is the Emacs frame on which
5511 the tip is shown. */
5512 struct frame *f = XFRAME (frame);
5513 if (FRAME_LIVE_P (f) && xg_hide_tooltip (f))
5514 frame = Qnil;
5516 #endif
5518 if (FRAMEP (frame))
5520 delete_frame (frame, Qnil);
5521 deleted = Qt;
5523 #ifdef USE_LUCID
5524 /* Bloodcurdling hack alert: The Lucid menu bar widget's
5525 redisplay procedure is not called when a tip frame over menu
5526 items is unmapped. Redisplay the menu manually... */
5528 Widget w;
5529 struct frame *f = SELECTED_FRAME ();
5530 w = f->output_data.x->menubar_widget;
5532 if (!DoesSaveUnders (FRAME_DISPLAY_INFO (f)->screen)
5533 && w != NULL)
5535 block_input ();
5536 xlwmenu_redisplay (w);
5537 unblock_input ();
5540 #endif /* USE_LUCID */
5543 UNGCPRO;
5544 return unbind_to (count, deleted);
5549 /***********************************************************************
5550 File selection dialog
5551 ***********************************************************************/
5553 DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog,
5554 Sx_uses_old_gtk_dialog,
5555 0, 0, 0,
5556 doc: /* Return t if the old Gtk+ file selection dialog is used. */)
5557 (void)
5559 #ifdef USE_GTK
5560 if (use_dialog_box
5561 && use_file_dialog
5562 && window_system_available (SELECTED_FRAME ())
5563 && xg_uses_old_file_dialog ())
5564 return Qt;
5565 #endif
5566 return Qnil;
5570 #ifdef USE_MOTIF
5571 /* Callback for "OK" and "Cancel" on file selection dialog. */
5573 static void
5574 file_dialog_cb (Widget widget, XtPointer client_data, XtPointer call_data)
5576 int *result = client_data;
5577 XmAnyCallbackStruct *cb = call_data;
5578 *result = cb->reason;
5582 /* Callback for unmapping a file selection dialog. This is used to
5583 capture the case where a dialog is closed via a window manager's
5584 closer button, for example. Using a XmNdestroyCallback didn't work
5585 in this case. */
5587 static void
5588 file_dialog_unmap_cb (Widget widget, XtPointer client_data, XtPointer call_data)
5590 int *result = client_data;
5591 *result = XmCR_CANCEL;
5594 static void
5595 clean_up_file_dialog (void *arg)
5597 Widget dialog = arg;
5599 /* Clean up. */
5600 block_input ();
5601 XtUnmanageChild (dialog);
5602 XtDestroyWidget (dialog);
5603 x_menu_set_in_use (0);
5604 unblock_input ();
5608 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5609 doc: /* Read file name, prompting with PROMPT in directory DIR.
5610 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5611 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5612 or directory must exist.
5614 This function is only defined on NS, MS Windows, and X Windows with the
5615 Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
5616 Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */)
5617 (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename,
5618 Lisp_Object mustmatch, Lisp_Object only_dir_p)
5620 int result;
5621 struct frame *f = SELECTED_FRAME ();
5622 Lisp_Object file = Qnil;
5623 Lisp_Object decoded_file;
5624 Widget dialog, text, help;
5625 Arg al[10];
5626 int ac = 0;
5627 XmString dir_xmstring, pattern_xmstring;
5628 ptrdiff_t count = SPECPDL_INDEX ();
5629 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5631 check_window_system (f);
5633 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5635 if (popup_activated ())
5636 error ("Trying to use a menu from within a menu-entry");
5638 CHECK_STRING (prompt);
5639 CHECK_STRING (dir);
5641 /* Prevent redisplay. */
5642 specbind (Qinhibit_redisplay, Qt);
5644 block_input ();
5646 /* Create the dialog with PROMPT as title, using DIR as initial
5647 directory and using "*" as pattern. */
5648 dir = Fexpand_file_name (dir, Qnil);
5649 dir_xmstring = XmStringCreateLocalized (SSDATA (dir));
5650 pattern_xmstring = XmStringCreateLocalized ("*");
5652 XtSetArg (al[ac], XmNtitle, SDATA (prompt)); ++ac;
5653 XtSetArg (al[ac], XmNdirectory, dir_xmstring); ++ac;
5654 XtSetArg (al[ac], XmNpattern, pattern_xmstring); ++ac;
5655 XtSetArg (al[ac], XmNresizePolicy, XmRESIZE_GROW); ++ac;
5656 XtSetArg (al[ac], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); ++ac;
5657 dialog = XmCreateFileSelectionDialog (f->output_data.x->widget,
5658 "fsb", al, ac);
5659 XmStringFree (dir_xmstring);
5660 XmStringFree (pattern_xmstring);
5662 /* Add callbacks for OK and Cancel. */
5663 XtAddCallback (dialog, XmNokCallback, file_dialog_cb,
5664 (XtPointer) &result);
5665 XtAddCallback (dialog, XmNcancelCallback, file_dialog_cb,
5666 (XtPointer) &result);
5667 XtAddCallback (dialog, XmNunmapCallback, file_dialog_unmap_cb,
5668 (XtPointer) &result);
5670 /* Remove the help button since we can't display help. */
5671 help = XmFileSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON);
5672 XtUnmanageChild (help);
5674 /* Mark OK button as default. */
5675 XtVaSetValues (XmFileSelectionBoxGetChild (dialog, XmDIALOG_OK_BUTTON),
5676 XmNshowAsDefault, True, NULL);
5678 /* If MUSTMATCH is non-nil, disable the file entry field of the
5679 dialog, so that the user must select a file from the files list
5680 box. We can't remove it because we wouldn't have a way to get at
5681 the result file name, then. */
5682 text = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5683 if (!NILP (mustmatch))
5685 Widget label;
5686 label = XmFileSelectionBoxGetChild (dialog, XmDIALOG_SELECTION_LABEL);
5687 XtSetSensitive (text, False);
5688 XtSetSensitive (label, False);
5691 /* Manage the dialog, so that list boxes get filled. */
5692 XtManageChild (dialog);
5694 if (STRINGP (default_filename))
5696 XmString default_xmstring;
5697 Widget wtext = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5698 Widget list = XmFileSelectionBoxGetChild (dialog, XmDIALOG_LIST);
5700 XmTextPosition last_pos = XmTextFieldGetLastPosition (wtext);
5701 XmTextFieldReplace (wtext, 0, last_pos,
5702 (SSDATA (Ffile_name_nondirectory (default_filename))));
5704 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
5705 must include the path for this to work. */
5707 default_xmstring = XmStringCreateLocalized (SSDATA (default_filename));
5709 if (XmListItemExists (list, default_xmstring))
5711 int item_pos = XmListItemPos (list, default_xmstring);
5712 /* Select the item and scroll it into view. */
5713 XmListSelectPos (list, item_pos, True);
5714 XmListSetPos (list, item_pos);
5717 XmStringFree (default_xmstring);
5720 record_unwind_protect_ptr (clean_up_file_dialog, dialog);
5722 /* Process events until the user presses Cancel or OK. */
5723 x_menu_set_in_use (1);
5724 result = 0;
5725 while (result == 0)
5727 XEvent event;
5728 x_menu_wait_for_event (0);
5729 XtAppNextEvent (Xt_app_con, &event);
5730 if (event.type == KeyPress
5731 && FRAME_X_DISPLAY (f) == event.xkey.display)
5733 KeySym keysym = XLookupKeysym (&event.xkey, 0);
5735 /* Pop down on C-g. */
5736 if (keysym == XK_g && (event.xkey.state & ControlMask) != 0)
5737 XtUnmanageChild (dialog);
5740 (void) x_dispatch_event (&event, FRAME_X_DISPLAY (f));
5743 /* Get the result. */
5744 if (result == XmCR_OK)
5746 XmString text_string;
5747 String data;
5749 XtVaGetValues (dialog, XmNtextString, &text_string, NULL);
5750 XmStringGetLtoR (text_string, XmFONTLIST_DEFAULT_TAG, &data);
5751 XmStringFree (text_string);
5752 file = build_string (data);
5753 XtFree (data);
5755 else
5756 file = Qnil;
5758 unblock_input ();
5759 UNGCPRO;
5761 /* Make "Cancel" equivalent to C-g. */
5762 if (NILP (file))
5763 Fsignal (Qquit, Qnil);
5765 decoded_file = DECODE_FILE (file);
5767 return unbind_to (count, decoded_file);
5770 #endif /* USE_MOTIF */
5772 #ifdef USE_GTK
5774 static void
5775 clean_up_dialog (void)
5777 x_menu_set_in_use (0);
5780 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5781 doc: /* Read file name, prompting with PROMPT in directory DIR.
5782 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5783 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5784 or directory must exist.
5786 This function is only defined on NS, MS Windows, and X Windows with the
5787 Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
5788 Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */)
5789 (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p)
5791 struct frame *f = SELECTED_FRAME ();
5792 char *fn;
5793 Lisp_Object file = Qnil;
5794 Lisp_Object decoded_file;
5795 ptrdiff_t count = SPECPDL_INDEX ();
5796 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5797 char *cdef_file;
5799 check_window_system (f);
5801 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5803 if (popup_activated ())
5804 error ("Trying to use a menu from within a menu-entry");
5806 CHECK_STRING (prompt);
5807 CHECK_STRING (dir);
5809 /* Prevent redisplay. */
5810 specbind (Qinhibit_redisplay, Qt);
5811 record_unwind_protect_void (clean_up_dialog);
5813 block_input ();
5815 if (STRINGP (default_filename))
5816 cdef_file = SSDATA (default_filename);
5817 else
5818 cdef_file = SSDATA (dir);
5820 fn = xg_get_file_name (f, SSDATA (prompt), cdef_file,
5821 ! NILP (mustmatch),
5822 ! NILP (only_dir_p));
5824 if (fn)
5826 file = build_string (fn);
5827 xfree (fn);
5830 unblock_input ();
5831 UNGCPRO;
5833 /* Make "Cancel" equivalent to C-g. */
5834 if (NILP (file))
5835 Fsignal (Qquit, Qnil);
5837 decoded_file = DECODE_FILE (file);
5839 return unbind_to (count, decoded_file);
5843 #ifdef HAVE_FREETYPE
5845 DEFUN ("x-select-font", Fx_select_font, Sx_select_font, 0, 2, 0,
5846 doc: /* Read a font using a GTK dialog.
5847 Return either a font spec (for GTK versions >= 3.2) or a string
5848 containing a GTK-style font name.
5850 FRAME is the frame on which to pop up the font chooser. If omitted or
5851 nil, it defaults to the selected frame. */)
5852 (Lisp_Object frame, Lisp_Object ignored)
5854 struct frame *f = decode_window_system_frame (frame);
5855 Lisp_Object font;
5856 Lisp_Object font_param;
5857 char *default_name = NULL;
5858 struct gcpro gcpro1, gcpro2;
5859 ptrdiff_t count = SPECPDL_INDEX ();
5861 if (popup_activated ())
5862 error ("Trying to use a menu from within a menu-entry");
5864 /* Prevent redisplay. */
5865 specbind (Qinhibit_redisplay, Qt);
5866 record_unwind_protect_void (clean_up_dialog);
5868 block_input ();
5870 GCPRO2 (font_param, font);
5872 XSETFONT (font, FRAME_FONT (f));
5873 font_param = Ffont_get (font, intern (":name"));
5874 if (STRINGP (font_param))
5875 default_name = xstrdup (SSDATA (font_param));
5876 else
5878 font_param = Fframe_parameter (frame, Qfont_param);
5879 if (STRINGP (font_param))
5880 default_name = xstrdup (SSDATA (font_param));
5883 font = xg_get_font (f, default_name);
5884 xfree (default_name);
5886 unblock_input ();
5888 if (NILP (font))
5889 Fsignal (Qquit, Qnil);
5891 return unbind_to (count, font);
5893 #endif /* HAVE_FREETYPE */
5895 #endif /* USE_GTK */
5898 /***********************************************************************
5899 Keyboard
5900 ***********************************************************************/
5902 #ifdef HAVE_XKB
5903 #include <X11/XKBlib.h>
5904 #include <X11/keysym.h>
5905 #endif
5907 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p,
5908 Sx_backspace_delete_keys_p, 0, 1, 0,
5909 doc: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
5910 FRAME nil means use the selected frame.
5911 Value is t if we know that both keys are present, and are mapped to the
5912 usual X keysyms. Value is `lambda' if we cannot determine if both keys are
5913 present and mapped to the usual X keysyms. */)
5914 (Lisp_Object frame)
5916 #ifndef HAVE_XKB
5917 return Qlambda;
5918 #else
5919 XkbDescPtr kb;
5920 struct frame *f = decode_window_system_frame (frame);
5921 Display *dpy = FRAME_X_DISPLAY (f);
5922 Lisp_Object have_keys;
5923 int major, minor, op, event, error_code;
5925 block_input ();
5927 /* Check library version in case we're dynamically linked. */
5928 major = XkbMajorVersion;
5929 minor = XkbMinorVersion;
5930 if (!XkbLibraryVersion (&major, &minor))
5932 unblock_input ();
5933 return Qlambda;
5936 /* Check that the server supports XKB. */
5937 major = XkbMajorVersion;
5938 minor = XkbMinorVersion;
5939 if (!XkbQueryExtension (dpy, &op, &event, &error_code, &major, &minor))
5941 unblock_input ();
5942 return Qlambda;
5945 /* In this code we check that the keyboard has physical keys with names
5946 that start with BKSP (Backspace) and DELE (Delete), and that they
5947 generate keysym XK_BackSpace and XK_Delete respectively.
5948 This function is used to test if normal-erase-is-backspace should be
5949 turned on.
5950 An alternative approach would be to just check if XK_BackSpace and
5951 XK_Delete are mapped to any key. But if any of those are mapped to
5952 some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the
5953 user doesn't know about it, it is better to return false here.
5954 It is more obvious to the user what to do if she/he has two keys
5955 clearly marked with names/symbols and one key does something not
5956 expected (i.e. she/he then tries the other).
5957 The cases where Backspace/Delete is mapped to some other key combination
5958 are rare, and in those cases, normal-erase-is-backspace can be turned on
5959 manually. */
5961 have_keys = Qnil;
5962 kb = XkbGetMap (dpy, XkbAllMapComponentsMask, XkbUseCoreKbd);
5963 if (kb)
5965 int delete_keycode = 0, backspace_keycode = 0, i;
5967 if (XkbGetNames (dpy, XkbAllNamesMask, kb) == Success)
5969 for (i = kb->min_key_code;
5970 (i < kb->max_key_code
5971 && (delete_keycode == 0 || backspace_keycode == 0));
5972 ++i)
5974 /* The XKB symbolic key names can be seen most easily in
5975 the PS file generated by `xkbprint -label name
5976 $DISPLAY'. */
5977 if (memcmp ("DELE", kb->names->keys[i].name, 4) == 0)
5978 delete_keycode = i;
5979 else if (memcmp ("BKSP", kb->names->keys[i].name, 4) == 0)
5980 backspace_keycode = i;
5983 XkbFreeNames (kb, 0, True);
5986 XkbFreeClientMap (kb, 0, True);
5988 if (delete_keycode
5989 && backspace_keycode
5990 && XKeysymToKeycode (dpy, XK_Delete) == delete_keycode
5991 && XKeysymToKeycode (dpy, XK_BackSpace) == backspace_keycode)
5992 have_keys = Qt;
5994 unblock_input ();
5995 return have_keys;
5996 #endif
6001 /***********************************************************************
6002 Initialization
6003 ***********************************************************************/
6005 /* Keep this list in the same order as frame_parms in frame.c.
6006 Use 0 for unsupported frame parameters. */
6008 frame_parm_handler x_frame_parm_handlers[] =
6010 x_set_autoraise,
6011 x_set_autolower,
6012 x_set_background_color,
6013 x_set_border_color,
6014 x_set_border_width,
6015 x_set_cursor_color,
6016 x_set_cursor_type,
6017 x_set_font,
6018 x_set_foreground_color,
6019 x_set_icon_name,
6020 x_set_icon_type,
6021 x_set_internal_border_width,
6022 x_set_right_divider_width,
6023 x_set_bottom_divider_width,
6024 x_set_menu_bar_lines,
6025 x_set_mouse_color,
6026 x_explicitly_set_name,
6027 x_set_scroll_bar_width,
6028 x_set_title,
6029 x_set_unsplittable,
6030 x_set_vertical_scroll_bars,
6031 x_set_visibility,
6032 x_set_tool_bar_lines,
6033 x_set_scroll_bar_foreground,
6034 x_set_scroll_bar_background,
6035 x_set_screen_gamma,
6036 x_set_line_spacing,
6037 x_set_fringe_width,
6038 x_set_fringe_width,
6039 x_set_wait_for_wm,
6040 x_set_fullscreen,
6041 x_set_font_backend,
6042 x_set_alpha,
6043 x_set_sticky,
6044 x_set_tool_bar_position,
6047 void
6048 syms_of_xfns (void)
6050 /* The section below is built by the lisp expression at the top of the file,
6051 just above where these variables are declared. */
6052 /*&&& init symbols here &&&*/
6053 DEFSYM (Qsuppress_icon, "suppress-icon");
6054 DEFSYM (Qundefined_color, "undefined-color");
6055 DEFSYM (Qcompound_text, "compound-text");
6056 DEFSYM (Qcancel_timer, "cancel-timer");
6057 DEFSYM (Qfont_param, "font-parameter");
6058 /* This is the end of symbol initialization. */
6060 Fput (Qundefined_color, Qerror_conditions,
6061 listn (CONSTYPE_PURE, 2, Qundefined_color, Qerror));
6062 Fput (Qundefined_color, Qerror_message,
6063 build_pure_c_string ("Undefined color"));
6065 DEFVAR_LISP ("x-pointer-shape", Vx_pointer_shape,
6066 doc: /* The shape of the pointer when over text.
6067 Changing the value does not affect existing frames
6068 unless you set the mouse color. */);
6069 Vx_pointer_shape = Qnil;
6071 #if 0 /* This doesn't really do anything. */
6072 DEFVAR_LISP ("x-nontext-pointer-shape", Vx_nontext_pointer_shape,
6073 doc: /* The shape of the pointer when not over text.
6074 This variable takes effect when you create a new frame
6075 or when you set the mouse color. */);
6076 #endif
6077 Vx_nontext_pointer_shape = Qnil;
6079 DEFVAR_LISP ("x-hourglass-pointer-shape", Vx_hourglass_pointer_shape,
6080 doc: /* The shape of the pointer when Emacs is busy.
6081 This variable takes effect when you create a new frame
6082 or when you set the mouse color. */);
6083 Vx_hourglass_pointer_shape = Qnil;
6085 #if 0 /* This doesn't really do anything. */
6086 DEFVAR_LISP ("x-mode-pointer-shape", Vx_mode_pointer_shape,
6087 doc: /* The shape of the pointer when over the mode line.
6088 This variable takes effect when you create a new frame
6089 or when you set the mouse color. */);
6090 #endif
6091 Vx_mode_pointer_shape = Qnil;
6093 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
6094 Vx_sensitive_text_pointer_shape,
6095 doc: /* The shape of the pointer when over mouse-sensitive text.
6096 This variable takes effect when you create a new frame
6097 or when you set the mouse color. */);
6098 Vx_sensitive_text_pointer_shape = Qnil;
6100 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
6101 Vx_window_horizontal_drag_shape,
6102 doc: /* Pointer shape to use for indicating a window can be dragged horizontally.
6103 This variable takes effect when you create a new frame
6104 or when you set the mouse color. */);
6105 Vx_window_horizontal_drag_shape = Qnil;
6107 DEFVAR_LISP ("x-window-vertical-drag-cursor",
6108 Vx_window_vertical_drag_shape,
6109 doc: /* Pointer shape to use for indicating a window can be dragged vertically.
6110 This variable takes effect when you create a new frame
6111 or when you set the mouse color. */);
6112 Vx_window_vertical_drag_shape = Qnil;
6114 DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel,
6115 doc: /* A string indicating the foreground color of the cursor box. */);
6116 Vx_cursor_fore_pixel = Qnil;
6118 DEFVAR_LISP ("x-max-tooltip-size", Vx_max_tooltip_size,
6119 doc: /* Maximum size for tooltips.
6120 Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */);
6121 Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
6123 DEFVAR_LISP ("x-no-window-manager", Vx_no_window_manager,
6124 doc: /* Non-nil if no X window manager is in use.
6125 Emacs doesn't try to figure this out; this is always nil
6126 unless you set it to something else. */);
6127 /* We don't have any way to find this out, so set it to nil
6128 and maybe the user would like to set it to t. */
6129 Vx_no_window_manager = Qnil;
6131 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
6132 Vx_pixel_size_width_font_regexp,
6133 doc: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
6135 Since Emacs gets width of a font matching with this regexp from
6136 PIXEL_SIZE field of the name, font finding mechanism gets faster for
6137 such a font. This is especially effective for such large fonts as
6138 Chinese, Japanese, and Korean. */);
6139 Vx_pixel_size_width_font_regexp = Qnil;
6141 /* This is not ifdef:ed, so other builds than GTK can customize it. */
6142 DEFVAR_BOOL ("x-gtk-use-old-file-dialog", x_gtk_use_old_file_dialog,
6143 doc: /* Non-nil means prompt with the old GTK file selection dialog.
6144 If nil or if the file selection dialog is not available, the new GTK file
6145 chooser is used instead. To turn off all file dialogs set the
6146 variable `use-file-dialog'. */);
6147 x_gtk_use_old_file_dialog = 0;
6149 DEFVAR_BOOL ("x-gtk-show-hidden-files", x_gtk_show_hidden_files,
6150 doc: /* If non-nil, the GTK file chooser will by default show hidden files.
6151 Note that this is just the default, there is a toggle button on the file
6152 chooser to show or not show hidden files on a case by case basis. */);
6153 x_gtk_show_hidden_files = 0;
6155 DEFVAR_BOOL ("x-gtk-file-dialog-help-text", x_gtk_file_dialog_help_text,
6156 doc: /* If non-nil, the GTK file chooser will show additional help text.
6157 If more space for files in the file chooser dialog is wanted, set this to nil
6158 to turn the additional text off. */);
6159 x_gtk_file_dialog_help_text = 1;
6161 DEFVAR_BOOL ("x-gtk-whole-detached-tool-bar", x_gtk_whole_detached_tool_bar,
6162 doc: /* If non-nil, a detached tool bar is shown in full.
6163 The default is to just show an arrow and pressing on that arrow shows
6164 the tool bar buttons. */);
6165 x_gtk_whole_detached_tool_bar = 0;
6167 DEFVAR_BOOL ("x-gtk-use-system-tooltips", x_gtk_use_system_tooltips,
6168 doc: /* If non-nil with a Gtk+ built Emacs, the Gtk+ tooltip is used.
6169 Otherwise use Emacs own tooltip implementation.
6170 When using Gtk+ tooltips, the tooltip face is not used. */);
6171 x_gtk_use_system_tooltips = 1;
6173 /* Tell Emacs about this window system. */
6174 Fprovide (Qx, Qnil);
6176 #ifdef USE_X_TOOLKIT
6177 Fprovide (intern_c_string ("x-toolkit"), Qnil);
6178 #ifdef USE_MOTIF
6179 Fprovide (intern_c_string ("motif"), Qnil);
6181 DEFVAR_LISP ("motif-version-string", Vmotif_version_string,
6182 doc: /* Version info for LessTif/Motif. */);
6183 Vmotif_version_string = build_string (XmVERSION_STRING);
6184 #endif /* USE_MOTIF */
6185 #endif /* USE_X_TOOLKIT */
6187 #ifdef USE_GTK
6188 /* Provide x-toolkit also for GTK. Internally GTK does not use Xt so it
6189 is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
6190 But for a user it is a toolkit for X, and indeed, configure
6191 accepts --with-x-toolkit=gtk. */
6192 Fprovide (intern_c_string ("x-toolkit"), Qnil);
6193 Fprovide (intern_c_string ("gtk"), Qnil);
6194 Fprovide (intern_c_string ("move-toolbar"), Qnil);
6196 DEFVAR_LISP ("gtk-version-string", Vgtk_version_string,
6197 doc: /* Version info for GTK+. */);
6199 char gtk_version[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
6200 int len = sprintf (gtk_version, "%d.%d.%d",
6201 GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
6202 Vgtk_version_string = make_pure_string (gtk_version, len, len, 0);
6204 #endif /* USE_GTK */
6206 /* X window properties. */
6207 defsubr (&Sx_change_window_property);
6208 defsubr (&Sx_delete_window_property);
6209 defsubr (&Sx_window_property);
6211 defsubr (&Sxw_display_color_p);
6212 defsubr (&Sx_display_grayscale_p);
6213 defsubr (&Sxw_color_defined_p);
6214 defsubr (&Sxw_color_values);
6215 defsubr (&Sx_server_max_request_size);
6216 defsubr (&Sx_server_vendor);
6217 defsubr (&Sx_server_version);
6218 defsubr (&Sx_display_pixel_width);
6219 defsubr (&Sx_display_pixel_height);
6220 defsubr (&Sx_display_mm_width);
6221 defsubr (&Sx_display_mm_height);
6222 defsubr (&Sx_display_screens);
6223 defsubr (&Sx_display_planes);
6224 defsubr (&Sx_display_color_cells);
6225 defsubr (&Sx_display_visual_class);
6226 defsubr (&Sx_display_backing_store);
6227 defsubr (&Sx_display_save_under);
6228 defsubr (&Sx_display_monitor_attributes_list);
6229 defsubr (&Sx_wm_set_size_hint);
6230 defsubr (&Sx_create_frame);
6231 defsubr (&Sx_open_connection);
6232 defsubr (&Sx_close_connection);
6233 defsubr (&Sx_display_list);
6234 defsubr (&Sx_synchronize);
6235 defsubr (&Sx_backspace_delete_keys_p);
6237 defsubr (&Sx_show_tip);
6238 defsubr (&Sx_hide_tip);
6239 tip_timer = Qnil;
6240 staticpro (&tip_timer);
6241 tip_frame = Qnil;
6242 staticpro (&tip_frame);
6244 last_show_tip_args = Qnil;
6245 staticpro (&last_show_tip_args);
6247 defsubr (&Sx_uses_old_gtk_dialog);
6248 #if defined (USE_MOTIF) || defined (USE_GTK)
6249 defsubr (&Sx_file_dialog);
6250 #endif
6252 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
6253 defsubr (&Sx_select_font);
6254 #endif