src/w32heap.c (init_heap): Fix typos in comments (again).
[emacs.git] / src / xfns.c
blobdc3211e4d6b55df4e793ae0383cb9e9f3fb425ac
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 void
581 x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
583 struct x_output *x = f->output_data.x;
584 Display *dpy = FRAME_X_DISPLAY (f);
585 Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
586 Cursor hourglass_cursor, horizontal_drag_cursor, vertical_drag_cursor;
587 unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
588 unsigned long mask_color = FRAME_BACKGROUND_PIXEL (f);
590 /* Don't let pointers be invisible. */
591 if (mask_color == pixel)
593 x_free_colors (f, &pixel, 1);
594 pixel = x_copy_color (f, FRAME_FOREGROUND_PIXEL (f));
597 unload_color (f, x->mouse_pixel);
598 x->mouse_pixel = pixel;
600 block_input ();
602 /* It's not okay to crash if the user selects a screwy cursor. */
603 x_catch_errors (dpy);
605 if (!NILP (Vx_pointer_shape))
607 CHECK_NUMBER (Vx_pointer_shape);
608 cursor = XCreateFontCursor (dpy, XINT (Vx_pointer_shape));
610 else
611 cursor = XCreateFontCursor (dpy, XC_xterm);
612 x_check_errors (dpy, "bad text pointer cursor: %s");
614 if (!NILP (Vx_nontext_pointer_shape))
616 CHECK_NUMBER (Vx_nontext_pointer_shape);
617 nontext_cursor
618 = XCreateFontCursor (dpy, XINT (Vx_nontext_pointer_shape));
620 else
621 nontext_cursor = XCreateFontCursor (dpy, XC_left_ptr);
622 x_check_errors (dpy, "bad nontext pointer cursor: %s");
624 if (!NILP (Vx_hourglass_pointer_shape))
626 CHECK_NUMBER (Vx_hourglass_pointer_shape);
627 hourglass_cursor
628 = XCreateFontCursor (dpy, XINT (Vx_hourglass_pointer_shape));
630 else
631 hourglass_cursor = XCreateFontCursor (dpy, XC_watch);
632 x_check_errors (dpy, "bad hourglass pointer cursor: %s");
634 if (!NILP (Vx_mode_pointer_shape))
636 CHECK_NUMBER (Vx_mode_pointer_shape);
637 mode_cursor = XCreateFontCursor (dpy, XINT (Vx_mode_pointer_shape));
639 else
640 mode_cursor = XCreateFontCursor (dpy, XC_xterm);
641 x_check_errors (dpy, "bad modeline pointer cursor: %s");
643 if (!NILP (Vx_sensitive_text_pointer_shape))
645 CHECK_NUMBER (Vx_sensitive_text_pointer_shape);
646 hand_cursor
647 = XCreateFontCursor (dpy, XINT (Vx_sensitive_text_pointer_shape));
649 else
650 hand_cursor = XCreateFontCursor (dpy, XC_hand2);
652 if (!NILP (Vx_window_horizontal_drag_shape))
654 CHECK_TYPE_RANGED_INTEGER (unsigned, Vx_window_horizontal_drag_shape);
655 horizontal_drag_cursor
656 = XCreateFontCursor (dpy, XINT (Vx_window_horizontal_drag_shape));
658 else
659 horizontal_drag_cursor
660 = XCreateFontCursor (dpy, XC_sb_h_double_arrow);
662 if (!NILP (Vx_window_vertical_drag_shape))
664 CHECK_NUMBER (Vx_window_vertical_drag_shape);
665 vertical_drag_cursor
666 = XCreateFontCursor (dpy, XINT (Vx_window_vertical_drag_shape));
668 else
669 vertical_drag_cursor
670 = XCreateFontCursor (dpy, XC_sb_v_double_arrow);
672 /* Check and report errors with the above calls. */
673 x_check_errors (dpy, "can't set cursor shape: %s");
674 x_uncatch_errors ();
677 XColor fore_color, back_color;
679 fore_color.pixel = x->mouse_pixel;
680 x_query_color (f, &fore_color);
681 back_color.pixel = mask_color;
682 x_query_color (f, &back_color);
684 XRecolorCursor (dpy, cursor, &fore_color, &back_color);
685 XRecolorCursor (dpy, nontext_cursor, &fore_color, &back_color);
686 XRecolorCursor (dpy, mode_cursor, &fore_color, &back_color);
687 XRecolorCursor (dpy, hand_cursor, &fore_color, &back_color);
688 XRecolorCursor (dpy, hourglass_cursor, &fore_color, &back_color);
689 XRecolorCursor (dpy, horizontal_drag_cursor, &fore_color, &back_color);
690 XRecolorCursor (dpy, vertical_drag_cursor, &fore_color, &back_color);
693 if (FRAME_X_WINDOW (f) != 0)
694 XDefineCursor (dpy, FRAME_X_WINDOW (f),
695 f->output_data.x->current_cursor = cursor);
697 if (cursor != x->text_cursor
698 && x->text_cursor != 0)
699 XFreeCursor (dpy, x->text_cursor);
700 x->text_cursor = cursor;
702 if (nontext_cursor != x->nontext_cursor
703 && x->nontext_cursor != 0)
704 XFreeCursor (dpy, x->nontext_cursor);
705 x->nontext_cursor = nontext_cursor;
707 if (hourglass_cursor != x->hourglass_cursor
708 && x->hourglass_cursor != 0)
709 XFreeCursor (dpy, x->hourglass_cursor);
710 x->hourglass_cursor = hourglass_cursor;
712 if (mode_cursor != x->modeline_cursor
713 && x->modeline_cursor != 0)
714 XFreeCursor (dpy, f->output_data.x->modeline_cursor);
715 x->modeline_cursor = mode_cursor;
717 if (hand_cursor != x->hand_cursor
718 && x->hand_cursor != 0)
719 XFreeCursor (dpy, x->hand_cursor);
720 x->hand_cursor = hand_cursor;
722 if (horizontal_drag_cursor != x->horizontal_drag_cursor
723 && x->horizontal_drag_cursor != 0)
724 XFreeCursor (dpy, x->horizontal_drag_cursor);
725 x->horizontal_drag_cursor = horizontal_drag_cursor;
727 if (vertical_drag_cursor != x->vertical_drag_cursor
728 && x->vertical_drag_cursor != 0)
729 XFreeCursor (dpy, x->vertical_drag_cursor);
730 x->vertical_drag_cursor = vertical_drag_cursor;
732 XFlush (dpy);
733 unblock_input ();
735 update_face_from_frame_parameter (f, Qmouse_color, arg);
738 static void
739 x_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
741 unsigned long fore_pixel, pixel;
742 bool fore_pixel_allocated_p = 0, pixel_allocated_p = 0;
743 struct x_output *x = f->output_data.x;
745 if (!NILP (Vx_cursor_fore_pixel))
747 fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
748 WHITE_PIX_DEFAULT (f));
749 fore_pixel_allocated_p = 1;
751 else
752 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
754 pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
755 pixel_allocated_p = 1;
757 /* Make sure that the cursor color differs from the background color. */
758 if (pixel == FRAME_BACKGROUND_PIXEL (f))
760 if (pixel_allocated_p)
762 x_free_colors (f, &pixel, 1);
763 pixel_allocated_p = 0;
766 pixel = x->mouse_pixel;
767 if (pixel == fore_pixel)
769 if (fore_pixel_allocated_p)
771 x_free_colors (f, &fore_pixel, 1);
772 fore_pixel_allocated_p = 0;
774 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
778 unload_color (f, x->cursor_foreground_pixel);
779 if (!fore_pixel_allocated_p)
780 fore_pixel = x_copy_color (f, fore_pixel);
781 x->cursor_foreground_pixel = fore_pixel;
783 unload_color (f, x->cursor_pixel);
784 if (!pixel_allocated_p)
785 pixel = x_copy_color (f, pixel);
786 x->cursor_pixel = pixel;
788 if (FRAME_X_WINDOW (f) != 0)
790 block_input ();
791 XSetBackground (FRAME_X_DISPLAY (f), x->cursor_gc, x->cursor_pixel);
792 XSetForeground (FRAME_X_DISPLAY (f), x->cursor_gc, fore_pixel);
793 unblock_input ();
795 if (FRAME_VISIBLE_P (f))
797 x_update_cursor (f, 0);
798 x_update_cursor (f, 1);
802 update_face_from_frame_parameter (f, Qcursor_color, arg);
805 /* Set the border-color of frame F to pixel value PIX.
806 Note that this does not fully take effect if done before
807 F has an x-window. */
809 static void
810 x_set_border_pixel (struct frame *f, int pix)
812 unload_color (f, f->output_data.x->border_pixel);
813 f->output_data.x->border_pixel = pix;
815 if (FRAME_X_WINDOW (f) != 0 && f->border_width > 0)
817 block_input ();
818 XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), pix);
819 unblock_input ();
821 if (FRAME_VISIBLE_P (f))
822 redraw_frame (f);
826 /* Set the border-color of frame F to value described by ARG.
827 ARG can be a string naming a color.
828 The border-color is used for the border that is drawn by the X server.
829 Note that this does not fully take effect if done before
830 F has an x-window; it must be redone when the window is created.
832 Note: this is done in two routines because of the way X10 works.
834 Note: under X11, this is normally the province of the window manager,
835 and so emacs's border colors may be overridden. */
837 static void
838 x_set_border_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
840 int pix;
842 CHECK_STRING (arg);
843 pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
844 x_set_border_pixel (f, pix);
845 update_face_from_frame_parameter (f, Qborder_color, arg);
849 static void
850 x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
852 set_frame_cursor_types (f, arg);
855 static void
856 x_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
858 int result;
860 if (STRINGP (arg))
862 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
863 return;
865 else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
866 return;
868 block_input ();
869 if (NILP (arg))
870 result = x_text_icon (f,
871 SSDATA ((!NILP (f->icon_name)
872 ? f->icon_name
873 : f->name)));
874 else
875 result = x_bitmap_icon (f, arg);
877 if (result)
879 unblock_input ();
880 error ("No icon window available");
883 XFlush (FRAME_X_DISPLAY (f));
884 unblock_input ();
887 static void
888 x_set_icon_name (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 (!NILP (arg) || NILP (oldval))
898 return;
900 fset_icon_name (f, arg);
902 if (f->output_data.x->icon_bitmap != 0)
903 return;
905 block_input ();
907 result = x_text_icon (f,
908 SSDATA ((!NILP (f->icon_name)
909 ? f->icon_name
910 : !NILP (f->title)
911 ? f->title
912 : f->name)));
914 if (result)
916 unblock_input ();
917 error ("No icon window available");
920 XFlush (FRAME_X_DISPLAY (f));
921 unblock_input ();
925 void
926 x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
928 int nlines;
929 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
930 int olines = FRAME_MENU_BAR_LINES (f);
931 #endif
933 /* Right now, menu bars don't work properly in minibuf-only frames;
934 most of the commands try to apply themselves to the minibuffer
935 frame itself, and get an error because you can't switch buffers
936 in or split the minibuffer window. */
937 if (FRAME_MINIBUF_ONLY_P (f))
938 return;
940 if (TYPE_RANGED_INTEGERP (int, value))
941 nlines = XINT (value);
942 else
943 nlines = 0;
945 /* Make sure we redisplay all windows in this frame. */
946 windows_or_buffers_changed = 59;
948 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
949 FRAME_MENU_BAR_LINES (f) = 0;
950 FRAME_MENU_BAR_HEIGHT (f) = 0;
951 if (nlines)
953 FRAME_EXTERNAL_MENU_BAR (f) = 1;
954 if (FRAME_X_P (f) && f->output_data.x->menubar_widget == 0)
955 /* Make sure next redisplay shows the menu bar. */
956 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = 1;
958 else
960 if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
961 free_frame_menubar (f);
962 FRAME_EXTERNAL_MENU_BAR (f) = 0;
963 if (FRAME_X_P (f))
964 f->output_data.x->menubar_widget = 0;
966 #else /* not USE_X_TOOLKIT && not USE_GTK */
967 FRAME_MENU_BAR_LINES (f) = nlines;
968 FRAME_MENU_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
969 resize_frame_windows (f, FRAME_TEXT_HEIGHT (f), 0, 1);
970 if (FRAME_X_WINDOW (f))
971 x_clear_under_internal_border (f);
973 /* If the menu bar height gets changed, the internal border below
974 the top margin has to be cleared. Also, if the menu bar gets
975 larger, the area for the added lines has to be cleared except for
976 the first menu bar line that is to be drawn later. */
977 if (nlines != olines)
979 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
980 int width = FRAME_PIXEL_WIDTH (f);
981 int y;
983 /* height can be zero here. */
984 if (FRAME_X_WINDOW (f) && height > 0 && width > 0)
986 y = FRAME_TOP_MARGIN_HEIGHT (f);
988 block_input ();
989 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
990 0, y, width, height);
991 unblock_input ();
994 if (nlines > 1 && nlines > olines)
996 y = (olines == 0 ? 1 : olines) * FRAME_LINE_HEIGHT (f);
997 height = nlines * FRAME_LINE_HEIGHT (f) - y;
999 block_input ();
1000 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1001 0, y, width, height);
1002 unblock_input ();
1005 if (nlines == 0 && WINDOWP (f->menu_bar_window))
1006 clear_glyph_matrix (XWINDOW (f->menu_bar_window)->current_matrix);
1008 #endif /* not USE_X_TOOLKIT && not USE_GTK */
1009 adjust_frame_glyphs (f);
1010 run_window_configuration_change_hook (f);
1014 /* Set the number of lines used for the tool bar of frame F to VALUE.
1015 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1016 is the old number of tool bar lines. This function changes the
1017 height of all windows on frame F to match the new tool bar height.
1018 The frame's height doesn't change. */
1020 void
1021 x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1023 int nlines;
1024 #if ! defined (USE_GTK)
1025 int delta, root_height;
1026 int unit = FRAME_LINE_HEIGHT (f);
1027 #endif
1029 /* Treat tool bars like menu bars. */
1030 if (FRAME_MINIBUF_ONLY_P (f))
1031 return;
1033 /* Use VALUE only if an int >= 0. */
1034 if (RANGED_INTEGERP (0, value, INT_MAX))
1035 nlines = XFASTINT (value);
1036 else
1037 nlines = 0;
1039 #ifdef USE_GTK
1041 FRAME_TOOL_BAR_LINES (f) = 0;
1042 FRAME_TOOL_BAR_HEIGHT (f) = 0;
1043 if (nlines)
1045 FRAME_EXTERNAL_TOOL_BAR (f) = 1;
1046 if (FRAME_X_P (f) && f->output_data.x->toolbar_widget == 0)
1047 /* Make sure next redisplay shows the tool bar. */
1048 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = 1;
1049 update_frame_tool_bar (f);
1051 else
1053 if (FRAME_EXTERNAL_TOOL_BAR (f))
1054 free_frame_tool_bar (f);
1055 FRAME_EXTERNAL_TOOL_BAR (f) = 0;
1058 #else /* !USE_GTK */
1060 /* Make sure we redisplay all windows in this frame. */
1061 windows_or_buffers_changed = 60;
1063 /* DELTA is in pixels now. */
1064 delta = (nlines - FRAME_TOOL_BAR_LINES (f)) * unit;
1066 /* Don't resize the tool-bar to more than we have room for. Note: The
1067 calculations below and the subsequent call to resize_frame_windows
1068 are inherently flawed because they can make the toolbar higher than
1069 the containing frame. */
1070 if (delta > 0)
1072 root_height = WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_ROOT_WINDOW (f)));
1073 if (root_height - delta < unit)
1075 delta = root_height - unit;
1076 /* When creating a new frame and toolbar mode is enabled, we
1077 need at least one toolbar line. */
1078 nlines = max (FRAME_TOOL_BAR_LINES (f) + delta / unit, 1);
1082 FRAME_TOOL_BAR_LINES (f) = nlines;
1083 FRAME_TOOL_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
1084 resize_frame_windows (f, FRAME_TEXT_HEIGHT (f), 0, 1);
1085 #if !defined USE_X_TOOLKIT && !defined USE_GTK
1086 if (FRAME_X_WINDOW (f))
1087 x_clear_under_internal_border (f);
1088 #endif
1089 adjust_frame_glyphs (f);
1091 /* We also have to make sure that the internal border at the top of
1092 the frame, below the menu bar or tool bar, is redrawn when the
1093 tool bar disappears. This is so because the internal border is
1094 below the tool bar if one is displayed, but is below the menu bar
1095 if there isn't a tool bar. The tool bar draws into the area
1096 below the menu bar. */
1097 if (FRAME_X_WINDOW (f) && FRAME_TOOL_BAR_HEIGHT (f) == 0)
1099 clear_frame (f);
1100 clear_current_matrices (f);
1103 /* If the tool bar gets smaller, the internal border below it
1104 has to be cleared. It was formerly part of the display
1105 of the larger tool bar, and updating windows won't clear it. */
1106 if (delta < 0)
1108 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1109 int width = FRAME_PIXEL_WIDTH (f);
1110 int y = nlines * unit;
1112 /* height can be zero here. */
1113 if (height > 0 && width > 0)
1115 block_input ();
1116 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1117 0, y, width, height);
1118 unblock_input ();
1121 if (WINDOWP (f->tool_bar_window))
1122 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1125 run_window_configuration_change_hook (f);
1126 #endif /* USE_GTK */
1130 /* Set the foreground color for scroll bars on frame F to VALUE.
1131 VALUE should be a string, a color name. If it isn't a string or
1132 isn't a valid color name, do nothing. OLDVAL is the old value of
1133 the frame parameter. */
1135 static void
1136 x_set_scroll_bar_foreground (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1138 unsigned long pixel;
1140 if (STRINGP (value))
1141 pixel = x_decode_color (f, value, BLACK_PIX_DEFAULT (f));
1142 else
1143 pixel = -1;
1145 if (f->output_data.x->scroll_bar_foreground_pixel != -1)
1146 unload_color (f, f->output_data.x->scroll_bar_foreground_pixel);
1148 f->output_data.x->scroll_bar_foreground_pixel = pixel;
1149 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1151 /* Remove all scroll bars because they have wrong colors. */
1152 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1153 (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1154 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1155 (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1157 update_face_from_frame_parameter (f, Qscroll_bar_foreground, value);
1158 redraw_frame (f);
1163 /* Set the background color for scroll bars on frame F to VALUE VALUE
1164 should be a string, a color name. If it isn't a string or isn't a
1165 valid color name, do nothing. OLDVAL is the old value of the frame
1166 parameter. */
1168 static void
1169 x_set_scroll_bar_background (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1171 unsigned long pixel;
1173 if (STRINGP (value))
1174 pixel = x_decode_color (f, value, WHITE_PIX_DEFAULT (f));
1175 else
1176 pixel = -1;
1178 if (f->output_data.x->scroll_bar_background_pixel != -1)
1179 unload_color (f, f->output_data.x->scroll_bar_background_pixel);
1181 #ifdef USE_TOOLKIT_SCROLL_BARS
1182 /* Scrollbar shadow colors. */
1183 if (f->output_data.x->scroll_bar_top_shadow_pixel != -1)
1185 unload_color (f, f->output_data.x->scroll_bar_top_shadow_pixel);
1186 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
1188 if (f->output_data.x->scroll_bar_bottom_shadow_pixel != -1)
1190 unload_color (f, f->output_data.x->scroll_bar_bottom_shadow_pixel);
1191 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
1193 #endif /* USE_TOOLKIT_SCROLL_BARS */
1195 f->output_data.x->scroll_bar_background_pixel = pixel;
1196 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1198 /* Remove all scroll bars because they have wrong colors. */
1199 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1200 (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1201 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1202 (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1204 update_face_from_frame_parameter (f, Qscroll_bar_background, value);
1205 redraw_frame (f);
1210 /* Encode Lisp string STRING as a text in a format appropriate for
1211 XICCC (X Inter Client Communication Conventions).
1213 This can call Lisp code, so callers must GCPRO.
1215 If STRING contains only ASCII characters, do no conversion and
1216 return the string data of STRING. Otherwise, encode the text by
1217 CODING_SYSTEM, and return a newly allocated memory area which
1218 should be freed by `xfree' by a caller.
1220 SELECTIONP non-zero means the string is being encoded for an X
1221 selection, so it is safe to run pre-write conversions (which
1222 may run Lisp code).
1224 Store the byte length of resulting text in *TEXT_BYTES.
1226 If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
1227 which means that the `encoding' of the result can be `STRING'.
1228 Otherwise store 0 in *STRINGP, which means that the `encoding' of
1229 the result should be `COMPOUND_TEXT'. */
1231 static unsigned char *
1232 x_encode_text (Lisp_Object string, Lisp_Object coding_system, int selectionp,
1233 ptrdiff_t *text_bytes, int *stringp, int *freep)
1235 int result = string_xstring_p (string);
1236 struct coding_system coding;
1238 if (result == 0)
1240 /* No multibyte character in OBJ. We need not encode it. */
1241 *text_bytes = SBYTES (string);
1242 *stringp = 1;
1243 *freep = 0;
1244 return SDATA (string);
1247 setup_coding_system (coding_system, &coding);
1248 coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK);
1249 /* We suppress producing escape sequences for composition. */
1250 coding.common_flags &= ~CODING_ANNOTATION_MASK;
1251 coding.destination = xnmalloc (SCHARS (string), 2);
1252 coding.dst_bytes = SCHARS (string) * 2;
1253 encode_coding_object (&coding, string, 0, 0,
1254 SCHARS (string), SBYTES (string), Qnil);
1255 *text_bytes = coding.produced;
1256 *stringp = (result == 1 || !EQ (coding_system, Qcompound_text));
1257 *freep = 1;
1258 return coding.destination;
1262 /* Set the WM name to NAME for frame F. Also set the icon name.
1263 If the frame already has an icon name, use that, otherwise set the
1264 icon name to NAME. */
1266 static void
1267 x_set_name_internal (struct frame *f, Lisp_Object name)
1269 if (FRAME_X_WINDOW (f))
1271 block_input ();
1273 XTextProperty text, icon;
1274 ptrdiff_t bytes;
1275 int stringp;
1276 int do_free_icon_value = 0, do_free_text_value = 0;
1277 Lisp_Object coding_system;
1278 Lisp_Object encoded_name;
1279 Lisp_Object encoded_icon_name;
1280 struct gcpro gcpro1;
1282 /* As ENCODE_UTF_8 may cause GC and relocation of string data,
1283 we use it before x_encode_text that may return string data. */
1284 GCPRO1 (name);
1285 encoded_name = ENCODE_UTF_8 (name);
1286 UNGCPRO;
1288 coding_system = Qcompound_text;
1289 /* Note: Encoding strategy
1291 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1292 text.encoding. But, there are non-internationalized window
1293 managers which don't support that encoding. So, if NAME
1294 contains only ASCII and 8859-1 characters, encode it by
1295 iso-latin-1, and use "STRING" in text.encoding hoping that
1296 such window managers at least analyze this format correctly,
1297 i.e. treat 8-bit bytes as 8859-1 characters.
1299 We may also be able to use "UTF8_STRING" in text.encoding
1300 in the future which can encode all Unicode characters.
1301 But, for the moment, there's no way to know that the
1302 current window manager supports it or not.
1304 Either way, we also set the _NET_WM_NAME and _NET_WM_ICON_NAME
1305 properties. Per the EWMH specification, those two properties
1306 are always UTF8_STRING. This matches what gtk_window_set_title()
1307 does in the USE_GTK case. */
1308 text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp,
1309 &do_free_text_value);
1310 text.encoding = (stringp ? XA_STRING
1311 : FRAME_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1312 text.format = 8;
1313 text.nitems = bytes;
1314 if (text.nitems != bytes)
1315 error ("Window name too large");
1317 if (!STRINGP (f->icon_name))
1319 icon = text;
1320 encoded_icon_name = encoded_name;
1322 else
1324 /* See the above comment "Note: Encoding strategy". */
1325 icon.value = x_encode_text (f->icon_name, coding_system, 0,
1326 &bytes, &stringp, &do_free_icon_value);
1327 icon.encoding = (stringp ? XA_STRING
1328 : FRAME_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1329 icon.format = 8;
1330 icon.nitems = bytes;
1331 if (icon.nitems != bytes)
1332 error ("Icon name too large");
1334 encoded_icon_name = ENCODE_UTF_8 (f->icon_name);
1337 #ifdef USE_GTK
1338 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
1339 SSDATA (encoded_name));
1340 #else /* not USE_GTK */
1341 XSetWMName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &text);
1342 XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
1343 FRAME_DISPLAY_INFO (f)->Xatom_net_wm_name,
1344 FRAME_DISPLAY_INFO (f)->Xatom_UTF8_STRING,
1345 8, PropModeReplace,
1346 SDATA (encoded_name),
1347 SBYTES (encoded_name));
1348 #endif /* not USE_GTK */
1350 XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &icon);
1351 XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
1352 FRAME_DISPLAY_INFO (f)->Xatom_net_wm_icon_name,
1353 FRAME_DISPLAY_INFO (f)->Xatom_UTF8_STRING,
1354 8, PropModeReplace,
1355 SDATA (encoded_icon_name),
1356 SBYTES (encoded_icon_name));
1358 if (do_free_icon_value)
1359 xfree (icon.value);
1360 if (do_free_text_value)
1361 xfree (text.value);
1363 unblock_input ();
1367 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1368 x_id_name.
1370 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1371 name; if NAME is a string, set F's name to NAME and set
1372 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1374 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1375 suggesting a new name, which lisp code should override; if
1376 F->explicit_name is set, ignore the new name; otherwise, set it. */
1378 static void
1379 x_set_name (struct frame *f, Lisp_Object name, int explicit)
1381 /* Make sure that requests from lisp code override requests from
1382 Emacs redisplay code. */
1383 if (explicit)
1385 /* If we're switching from explicit to implicit, we had better
1386 update the mode lines and thereby update the title. */
1387 if (f->explicit_name && NILP (name))
1388 update_mode_lines = 37;
1390 f->explicit_name = ! NILP (name);
1392 else if (f->explicit_name)
1393 return;
1395 /* If NAME is nil, set the name to the x_id_name. */
1396 if (NILP (name))
1398 /* Check for no change needed in this very common case
1399 before we do any consing. */
1400 if (!strcmp (FRAME_DISPLAY_INFO (f)->x_id_name,
1401 SSDATA (f->name)))
1402 return;
1403 name = build_string (FRAME_DISPLAY_INFO (f)->x_id_name);
1405 else
1406 CHECK_STRING (name);
1408 /* Don't change the name if it's already NAME. */
1409 if (! NILP (Fstring_equal (name, f->name)))
1410 return;
1412 fset_name (f, name);
1414 /* For setting the frame title, the title parameter should override
1415 the name parameter. */
1416 if (! NILP (f->title))
1417 name = f->title;
1419 x_set_name_internal (f, name);
1422 /* This function should be called when the user's lisp code has
1423 specified a name for the frame; the name will override any set by the
1424 redisplay code. */
1425 static void
1426 x_explicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1428 x_set_name (f, arg, 1);
1431 /* This function should be called by Emacs redisplay code to set the
1432 name; names set this way will never override names set by the user's
1433 lisp code. */
1434 void
1435 x_implicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1437 x_set_name (f, arg, 0);
1440 /* Change the title of frame F to NAME.
1441 If NAME is nil, use the frame name as the title. */
1443 static void
1444 x_set_title (struct frame *f, Lisp_Object name, Lisp_Object old_name)
1446 /* Don't change the title if it's already NAME. */
1447 if (EQ (name, f->title))
1448 return;
1450 update_mode_lines = 38;
1452 fset_title (f, name);
1454 if (NILP (name))
1455 name = f->name;
1456 else
1457 CHECK_STRING (name);
1459 x_set_name_internal (f, name);
1462 void
1463 x_set_scroll_bar_default_width (struct frame *f)
1465 int unit = FRAME_COLUMN_WIDTH (f);
1466 #ifdef USE_TOOLKIT_SCROLL_BARS
1467 #ifdef USE_GTK
1468 int minw = xg_get_default_scrollbar_width ();
1469 #else
1470 int minw = 16;
1471 #endif
1472 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
1473 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (minw + unit - 1) / unit;
1474 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = minw;
1475 #else
1476 /* The width of a non-toolkit scrollbar is at least 14 pixels and a
1477 multiple of the frame's character width. */
1478 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + unit - 1) / unit;
1479 FRAME_CONFIG_SCROLL_BAR_WIDTH (f)
1480 = FRAME_CONFIG_SCROLL_BAR_COLS (f) * unit;
1481 #endif
1485 /* Record in frame F the specified or default value according to ALIST
1486 of the parameter named PROP (a Lisp symbol). If no value is
1487 specified for PROP, look for an X default for XPROP on the frame
1488 named NAME. If that is not found either, use the value DEFLT. */
1490 static Lisp_Object
1491 x_default_scroll_bar_color_parameter (struct frame *f,
1492 Lisp_Object alist, Lisp_Object prop,
1493 const char *xprop, const char *xclass,
1494 int foreground_p)
1496 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
1497 Lisp_Object tem;
1499 tem = x_get_arg (dpyinfo, alist, prop, xprop, xclass, RES_TYPE_STRING);
1500 if (EQ (tem, Qunbound))
1502 #ifdef USE_TOOLKIT_SCROLL_BARS
1504 /* See if an X resource for the scroll bar color has been
1505 specified. */
1506 tem = display_x_get_resource (dpyinfo,
1507 build_string (foreground_p
1508 ? "foreground"
1509 : "background"),
1510 empty_unibyte_string,
1511 build_string ("verticalScrollBar"),
1512 empty_unibyte_string);
1513 if (!STRINGP (tem))
1515 /* If nothing has been specified, scroll bars will use a
1516 toolkit-dependent default. Because these defaults are
1517 difficult to get at without actually creating a scroll
1518 bar, use nil to indicate that no color has been
1519 specified. */
1520 tem = Qnil;
1523 #else /* not USE_TOOLKIT_SCROLL_BARS */
1525 tem = Qnil;
1527 #endif /* not USE_TOOLKIT_SCROLL_BARS */
1530 x_set_frame_parameters (f, list1 (Fcons (prop, tem)));
1531 return tem;
1537 #ifdef USE_X_TOOLKIT
1539 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
1540 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
1541 already be present because of the toolkit (Motif adds some of them,
1542 for example, but Xt doesn't). */
1544 static void
1545 hack_wm_protocols (struct frame *f, Widget widget)
1547 Display *dpy = XtDisplay (widget);
1548 Window w = XtWindow (widget);
1549 int need_delete = 1;
1550 int need_focus = 1;
1551 int need_save = 1;
1553 block_input ();
1555 Atom type;
1556 unsigned char *catoms;
1557 int format = 0;
1558 unsigned long nitems = 0;
1559 unsigned long bytes_after;
1561 if ((XGetWindowProperty (dpy, w,
1562 FRAME_DISPLAY_INFO (f)->Xatom_wm_protocols,
1563 (long)0, (long)100, False, XA_ATOM,
1564 &type, &format, &nitems, &bytes_after,
1565 &catoms)
1566 == Success)
1567 && format == 32 && type == XA_ATOM)
1569 Atom *atoms = (Atom *) catoms;
1570 while (nitems > 0)
1572 nitems--;
1573 if (atoms[nitems]
1574 == FRAME_DISPLAY_INFO (f)->Xatom_wm_delete_window)
1575 need_delete = 0;
1576 else if (atoms[nitems]
1577 == FRAME_DISPLAY_INFO (f)->Xatom_wm_take_focus)
1578 need_focus = 0;
1579 else if (atoms[nitems]
1580 == FRAME_DISPLAY_INFO (f)->Xatom_wm_save_yourself)
1581 need_save = 0;
1584 if (catoms)
1585 XFree (catoms);
1588 Atom props [10];
1589 int count = 0;
1590 if (need_delete)
1591 props[count++] = FRAME_DISPLAY_INFO (f)->Xatom_wm_delete_window;
1592 if (need_focus)
1593 props[count++] = FRAME_DISPLAY_INFO (f)->Xatom_wm_take_focus;
1594 if (need_save)
1595 props[count++] = FRAME_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
1596 if (count)
1597 XChangeProperty (dpy, w, FRAME_DISPLAY_INFO (f)->Xatom_wm_protocols,
1598 XA_ATOM, 32, PropModeAppend,
1599 (unsigned char *) props, count);
1601 unblock_input ();
1603 #endif
1607 /* Support routines for XIC (X Input Context). */
1609 #ifdef HAVE_X_I18N
1611 static XFontSet xic_create_xfontset (struct frame *);
1612 static XIMStyle best_xim_style (XIMStyles *);
1615 /* Supported XIM styles, ordered by preference. */
1617 static const XIMStyle supported_xim_styles[] =
1619 XIMPreeditPosition | XIMStatusArea,
1620 XIMPreeditPosition | XIMStatusNothing,
1621 XIMPreeditPosition | XIMStatusNone,
1622 XIMPreeditNothing | XIMStatusArea,
1623 XIMPreeditNothing | XIMStatusNothing,
1624 XIMPreeditNothing | XIMStatusNone,
1625 XIMPreeditNone | XIMStatusArea,
1626 XIMPreeditNone | XIMStatusNothing,
1627 XIMPreeditNone | XIMStatusNone,
1632 #if defined HAVE_X_WINDOWS && defined USE_X_TOOLKIT
1633 /* Create an X fontset on frame F with base font name BASE_FONTNAME. */
1635 static const char xic_default_fontset[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
1637 /* Create an Xt fontset spec from the name of a base font.
1638 If `motif' is True use the Motif syntax. */
1639 char *
1640 xic_create_fontsetname (const char *base_fontname, int motif)
1642 const char *sep = motif ? ";" : ",";
1643 char *fontsetname;
1645 /* Make a fontset name from the base font name. */
1646 if (xic_default_fontset == base_fontname)
1648 /* There is no base font name, use the default. */
1649 fontsetname = xmalloc (strlen (base_fontname) + 2);
1650 strcpy (fontsetname, base_fontname);
1652 else
1654 /* Make a fontset name from the base font name.
1655 The font set will be made of the following elements:
1656 - the base font.
1657 - the base font where the charset spec is replaced by -*-*.
1658 - the same but with the family also replaced with -*-*-. */
1659 const char *p = base_fontname;
1660 ptrdiff_t i;
1662 for (i = 0; *p; p++)
1663 if (*p == '-') i++;
1664 if (i != 14)
1666 /* As the font name doesn't conform to XLFD, we can't
1667 modify it to generalize it to allcs and allfamilies.
1668 Use the specified font plus the default. */
1669 fontsetname = xmalloc (strlen (base_fontname)
1670 + strlen (xic_default_fontset) + 3);
1671 strcpy (fontsetname, base_fontname);
1672 strcat (fontsetname, sep);
1673 strcat (fontsetname, xic_default_fontset);
1675 else
1677 ptrdiff_t len;
1678 const char *p1 = NULL, *p2 = NULL, *p3 = NULL;
1679 char *font_allcs = NULL;
1680 char *font_allfamilies = NULL;
1681 char *font_all = NULL;
1682 const char *allcs = "*-*-*-*-*-*-*";
1683 const char *allfamilies = "-*-*-";
1684 const char *all = "*-*-*-*-";
1685 char *base;
1687 for (i = 0, p = base_fontname; i < 8; p++)
1689 if (*p == '-')
1691 i++;
1692 if (i == 3)
1693 p1 = p + 1;
1694 else if (i == 7)
1695 p2 = p + 1;
1696 else if (i == 6)
1697 p3 = p + 1;
1700 /* If base_fontname specifies ADSTYLE, make it a
1701 wildcard. */
1702 if (*p3 != '*')
1704 ptrdiff_t diff = (p2 - p3) - 2;
1706 base = alloca (strlen (base_fontname) + 1);
1707 memcpy (base, base_fontname, p3 - base_fontname);
1708 base[p3 - base_fontname] = '*';
1709 base[(p3 - base_fontname) + 1] = '-';
1710 strcpy (base + (p3 - base_fontname) + 2, p2);
1711 p = base + (p - base_fontname) - diff;
1712 p1 = base + (p1 - base_fontname);
1713 p2 = base + (p2 - base_fontname) - diff;
1714 base_fontname = base;
1717 /* Build the font spec that matches all charsets. */
1718 len = p - base_fontname + strlen (allcs) + 1;
1719 font_allcs = alloca (len);
1720 memcpy (font_allcs, base_fontname, p - base_fontname);
1721 strcat (font_allcs, allcs);
1723 /* Build the font spec that matches all families and
1724 add-styles. */
1725 len = p - p1 + strlen (allcs) + strlen (allfamilies) + 1;
1726 font_allfamilies = alloca (len);
1727 strcpy (font_allfamilies, allfamilies);
1728 memcpy (font_allfamilies + strlen (allfamilies), p1, p - p1);
1729 strcat (font_allfamilies, allcs);
1731 /* Build the font spec that matches all. */
1732 len = p - p2 + strlen (allcs) + strlen (all) + strlen (allfamilies) + 1;
1733 font_all = alloca (len);
1734 strcpy (font_all, allfamilies);
1735 strcat (font_all, all);
1736 memcpy (font_all + strlen (all) + strlen (allfamilies), p2, p - p2);
1737 strcat (font_all, allcs);
1739 /* Build the actual font set name. */
1740 len = strlen (base_fontname) + strlen (font_allcs)
1741 + strlen (font_allfamilies) + strlen (font_all) + 5;
1742 fontsetname = xmalloc (len);
1743 strcpy (fontsetname, base_fontname);
1744 strcat (fontsetname, sep);
1745 strcat (fontsetname, font_allcs);
1746 strcat (fontsetname, sep);
1747 strcat (fontsetname, font_allfamilies);
1748 strcat (fontsetname, sep);
1749 strcat (fontsetname, font_all);
1752 if (motif)
1753 return strcat (fontsetname, ":");
1754 return fontsetname;
1756 #endif /* HAVE_X_WINDOWS && USE_X_TOOLKIT */
1758 #ifdef DEBUG_XIC_FONTSET
1759 static void
1760 print_fontset_result (XFontSet xfs, char *name, char **missing_list,
1761 int missing_count)
1763 if (xfs)
1764 fprintf (stderr, "XIC Fontset created: %s\n", name);
1765 else
1767 fprintf (stderr, "XIC Fontset failed: %s\n", name);
1768 while (missing_count-- > 0)
1770 fprintf (stderr, " missing: %s\n", *missing_list);
1771 missing_list++;
1776 #endif
1778 static XFontSet
1779 xic_create_xfontset (struct frame *f)
1781 XFontSet xfs = NULL;
1782 struct font *font = FRAME_FONT (f);
1783 int pixel_size = font->pixel_size;
1784 Lisp_Object rest, frame;
1786 /* See if there is another frame already using same fontset. */
1787 FOR_EACH_FRAME (rest, frame)
1789 struct frame *cf = XFRAME (frame);
1791 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
1792 && FRAME_DISPLAY_INFO (cf) == FRAME_DISPLAY_INFO (f)
1793 && FRAME_FONT (f)
1794 && FRAME_FONT (f)->pixel_size == pixel_size)
1796 xfs = FRAME_XIC_FONTSET (cf);
1797 break;
1801 if (! xfs)
1803 char buf[256];
1804 char **missing_list;
1805 int missing_count;
1806 char *def_string;
1807 const char *xlfd_format = "-*-*-medium-r-normal--%d-*-*-*-*-*";
1809 sprintf (buf, xlfd_format, pixel_size);
1810 missing_list = NULL;
1811 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
1812 &missing_list, &missing_count, &def_string);
1813 #ifdef DEBUG_XIC_FONTSET
1814 print_fontset_result (xfs, buf, missing_list, missing_count);
1815 #endif
1816 if (missing_list)
1817 XFreeStringList (missing_list);
1818 if (! xfs)
1820 /* List of pixel sizes most likely available. Find one that
1821 is closest to pixel_size. */
1822 int sizes[] = {0, 8, 10, 11, 12, 14, 17, 18, 20, 24, 26, 34, 0};
1823 int *smaller, *larger;
1825 for (smaller = sizes; smaller[1]; smaller++)
1826 if (smaller[1] >= pixel_size)
1827 break;
1828 larger = smaller + 1;
1829 if (*larger == pixel_size)
1830 larger++;
1831 while (*smaller || *larger)
1833 int this_size;
1835 if (! *larger)
1836 this_size = *smaller--;
1837 else if (! *smaller)
1838 this_size = *larger++;
1839 else if (pixel_size - *smaller < *larger - pixel_size)
1840 this_size = *smaller--;
1841 else
1842 this_size = *larger++;
1843 sprintf (buf, xlfd_format, this_size);
1844 missing_list = NULL;
1845 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
1846 &missing_list, &missing_count, &def_string);
1847 #ifdef DEBUG_XIC_FONTSET
1848 print_fontset_result (xfs, buf, missing_list, missing_count);
1849 #endif
1850 if (missing_list)
1851 XFreeStringList (missing_list);
1852 if (xfs)
1853 break;
1856 if (! xfs)
1858 const char *last_resort = "-*-*-*-r-normal--*-*-*-*-*-*";
1860 missing_list = NULL;
1861 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), last_resort,
1862 &missing_list, &missing_count, &def_string);
1863 #ifdef DEBUG_XIC_FONTSET
1864 print_fontset_result (xfs, last_resort, missing_list, missing_count);
1865 #endif
1866 if (missing_list)
1867 XFreeStringList (missing_list);
1872 return xfs;
1875 /* Free the X fontset of frame F if it is the last frame using it. */
1877 void
1878 xic_free_xfontset (struct frame *f)
1880 Lisp_Object rest, frame;
1881 bool shared_p = 0;
1883 if (!FRAME_XIC_FONTSET (f))
1884 return;
1886 /* See if there is another frame sharing the same fontset. */
1887 FOR_EACH_FRAME (rest, frame)
1889 struct frame *cf = XFRAME (frame);
1890 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
1891 && FRAME_DISPLAY_INFO (cf) == FRAME_DISPLAY_INFO (f)
1892 && FRAME_XIC_FONTSET (cf) == FRAME_XIC_FONTSET (f))
1894 shared_p = 1;
1895 break;
1899 if (!shared_p)
1900 /* The fontset is not used anymore. It is safe to free it. */
1901 XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f));
1903 FRAME_XIC_FONTSET (f) = NULL;
1907 /* Value is the best input style, given user preferences USER (already
1908 checked to be supported by Emacs), and styles supported by the
1909 input method XIM. */
1911 static XIMStyle
1912 best_xim_style (XIMStyles *xim)
1914 int i, j;
1915 int nr_supported = ARRAYELTS (supported_xim_styles);
1917 for (i = 0; i < nr_supported; ++i)
1918 for (j = 0; j < xim->count_styles; ++j)
1919 if (supported_xim_styles[i] == xim->supported_styles[j])
1920 return supported_xim_styles[i];
1922 /* Return the default style. */
1923 return XIMPreeditNothing | XIMStatusNothing;
1926 /* Create XIC for frame F. */
1928 void
1929 create_frame_xic (struct frame *f)
1931 XIM xim;
1932 XIC xic = NULL;
1933 XFontSet xfs = NULL;
1934 XVaNestedList status_attr = NULL;
1935 XVaNestedList preedit_attr = NULL;
1936 XRectangle s_area;
1937 XPoint spot;
1938 XIMStyle xic_style;
1940 if (FRAME_XIC (f))
1941 goto out;
1943 xim = FRAME_X_XIM (f);
1944 if (!xim)
1945 goto out;
1947 /* Determine XIC style. */
1948 xic_style = best_xim_style (FRAME_X_XIM_STYLES (f));
1950 /* Create X fontset. */
1951 if (xic_style & (XIMPreeditPosition | XIMStatusArea))
1953 xfs = xic_create_xfontset (f);
1954 if (!xfs)
1955 goto out;
1957 FRAME_XIC_FONTSET (f) = xfs;
1960 if (xic_style & XIMPreeditPosition)
1962 spot.x = 0; spot.y = 1;
1963 preedit_attr = XVaCreateNestedList (0,
1964 XNFontSet, xfs,
1965 XNForeground,
1966 FRAME_FOREGROUND_PIXEL (f),
1967 XNBackground,
1968 FRAME_BACKGROUND_PIXEL (f),
1969 (xic_style & XIMPreeditPosition
1970 ? XNSpotLocation
1971 : NULL),
1972 &spot,
1973 NULL);
1975 if (!preedit_attr)
1976 goto out;
1979 if (xic_style & XIMStatusArea)
1981 s_area.x = 0; s_area.y = 0; s_area.width = 1; s_area.height = 1;
1982 status_attr = XVaCreateNestedList (0,
1983 XNArea,
1984 &s_area,
1985 XNFontSet,
1986 xfs,
1987 XNForeground,
1988 FRAME_FOREGROUND_PIXEL (f),
1989 XNBackground,
1990 FRAME_BACKGROUND_PIXEL (f),
1991 NULL);
1993 if (!status_attr)
1994 goto out;
1997 if (preedit_attr && status_attr)
1998 xic = XCreateIC (xim,
1999 XNInputStyle, xic_style,
2000 XNClientWindow, FRAME_X_WINDOW (f),
2001 XNFocusWindow, FRAME_X_WINDOW (f),
2002 XNStatusAttributes, status_attr,
2003 XNPreeditAttributes, preedit_attr,
2004 NULL);
2005 else if (preedit_attr)
2006 xic = XCreateIC (xim,
2007 XNInputStyle, xic_style,
2008 XNClientWindow, FRAME_X_WINDOW (f),
2009 XNFocusWindow, FRAME_X_WINDOW (f),
2010 XNPreeditAttributes, preedit_attr,
2011 NULL);
2012 else if (status_attr)
2013 xic = XCreateIC (xim,
2014 XNInputStyle, xic_style,
2015 XNClientWindow, FRAME_X_WINDOW (f),
2016 XNFocusWindow, FRAME_X_WINDOW (f),
2017 XNStatusAttributes, status_attr,
2018 NULL);
2019 else
2020 xic = XCreateIC (xim,
2021 XNInputStyle, xic_style,
2022 XNClientWindow, FRAME_X_WINDOW (f),
2023 XNFocusWindow, FRAME_X_WINDOW (f),
2024 NULL);
2026 if (!xic)
2027 goto out;
2029 FRAME_XIC (f) = xic;
2030 FRAME_XIC_STYLE (f) = xic_style;
2031 xfs = NULL; /* Don't free below. */
2033 out:
2035 if (xfs)
2036 free_frame_xic (f);
2038 if (preedit_attr)
2039 XFree (preedit_attr);
2041 if (status_attr)
2042 XFree (status_attr);
2046 /* Destroy XIC and free XIC fontset of frame F, if any. */
2048 void
2049 free_frame_xic (struct frame *f)
2051 if (FRAME_XIC (f) == NULL)
2052 return;
2054 XDestroyIC (FRAME_XIC (f));
2055 xic_free_xfontset (f);
2057 FRAME_XIC (f) = NULL;
2061 /* Place preedit area for XIC of window W's frame to specified
2062 pixel position X/Y. X and Y are relative to window W. */
2064 void
2065 xic_set_preeditarea (struct window *w, int x, int y)
2067 struct frame *f = XFRAME (w->frame);
2068 XVaNestedList attr;
2069 XPoint spot;
2071 spot.x = WINDOW_TO_FRAME_PIXEL_X (w, x) + WINDOW_LEFT_FRINGE_WIDTH (w);
2072 spot.y = WINDOW_TO_FRAME_PIXEL_Y (w, y) + FONT_BASE (FRAME_FONT (f));
2073 attr = XVaCreateNestedList (0, XNSpotLocation, &spot, NULL);
2074 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2075 XFree (attr);
2079 /* Place status area for XIC in bottom right corner of frame F.. */
2081 void
2082 xic_set_statusarea (struct frame *f)
2084 XIC xic = FRAME_XIC (f);
2085 XVaNestedList attr;
2086 XRectangle area;
2087 XRectangle *needed;
2089 /* Negotiate geometry of status area. If input method has existing
2090 status area, use its current size. */
2091 area.x = area.y = area.width = area.height = 0;
2092 attr = XVaCreateNestedList (0, XNAreaNeeded, &area, NULL);
2093 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2094 XFree (attr);
2096 attr = XVaCreateNestedList (0, XNAreaNeeded, &needed, NULL);
2097 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2098 XFree (attr);
2100 if (needed->width == 0) /* Use XNArea instead of XNAreaNeeded */
2102 attr = XVaCreateNestedList (0, XNArea, &needed, NULL);
2103 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2104 XFree (attr);
2107 area.width = needed->width;
2108 area.height = needed->height;
2109 area.x = FRAME_PIXEL_WIDTH (f) - area.width - FRAME_INTERNAL_BORDER_WIDTH (f);
2110 area.y = (FRAME_PIXEL_HEIGHT (f) - area.height
2111 - FRAME_MENUBAR_HEIGHT (f)
2112 - FRAME_TOOLBAR_TOP_HEIGHT (f)
2113 - FRAME_INTERNAL_BORDER_WIDTH (f));
2114 XFree (needed);
2116 attr = XVaCreateNestedList (0, XNArea, &area, NULL);
2117 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2118 XFree (attr);
2122 /* Set X fontset for XIC of frame F, using base font name
2123 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2125 void
2126 xic_set_xfontset (struct frame *f, const char *base_fontname)
2128 XVaNestedList attr;
2129 XFontSet xfs;
2131 xic_free_xfontset (f);
2133 xfs = xic_create_xfontset (f);
2135 attr = XVaCreateNestedList (0, XNFontSet, xfs, NULL);
2136 if (FRAME_XIC_STYLE (f) & XIMPreeditPosition)
2137 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2138 if (FRAME_XIC_STYLE (f) & XIMStatusArea)
2139 XSetICValues (FRAME_XIC (f), XNStatusAttributes, attr, NULL);
2140 XFree (attr);
2142 FRAME_XIC_FONTSET (f) = xfs;
2145 #endif /* HAVE_X_I18N */
2149 #ifdef USE_X_TOOLKIT
2151 /* Create and set up the X widget for frame F. */
2153 static void
2154 x_window (struct frame *f, long window_prompting, int minibuffer_only)
2156 XClassHint class_hints;
2157 XSetWindowAttributes attributes;
2158 unsigned long attribute_mask;
2159 Widget shell_widget;
2160 Widget pane_widget;
2161 Widget frame_widget;
2162 Arg al [25];
2163 int ac;
2165 block_input ();
2167 /* Use the resource name as the top-level widget name
2168 for looking up resources. Make a non-Lisp copy
2169 for the window manager, so GC relocation won't bother it.
2171 Elsewhere we specify the window name for the window manager. */
2172 f->namebuf = xstrdup (SSDATA (Vx_resource_name));
2174 ac = 0;
2175 XtSetArg (al[ac], XtNallowShellResize, 1); ac++;
2176 XtSetArg (al[ac], XtNinput, 1); ac++;
2177 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2178 XtSetArg (al[ac], XtNborderWidth, f->border_width); ac++;
2179 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2180 XtSetArg (al[ac], XtNdepth, FRAME_DISPLAY_INFO (f)->n_planes); ac++;
2181 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2182 shell_widget = XtAppCreateShell (f->namebuf, EMACS_CLASS,
2183 applicationShellWidgetClass,
2184 FRAME_X_DISPLAY (f), al, ac);
2186 f->output_data.x->widget = shell_widget;
2187 /* maybe_set_screen_title_format (shell_widget); */
2189 pane_widget = lw_create_widget ("main", "pane", widget_id_tick++,
2190 NULL, shell_widget, False,
2191 NULL, NULL, NULL, NULL);
2193 ac = 0;
2194 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2195 XtSetArg (al[ac], XtNdepth, FRAME_DISPLAY_INFO (f)->n_planes); ac++;
2196 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2197 XtSetArg (al[ac], XtNborderWidth, 0); ac++;
2198 XtSetValues (pane_widget, al, ac);
2199 f->output_data.x->column_widget = pane_widget;
2201 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2202 the emacs screen when changing menubar. This reduces flickering. */
2204 ac = 0;
2205 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2206 XtSetArg (al[ac], XtNshowGrip, 0); ac++;
2207 XtSetArg (al[ac], XtNallowResize, 1); ac++;
2208 XtSetArg (al[ac], XtNresizeToPreferred, 1); ac++;
2209 XtSetArg (al[ac], XtNemacsFrame, f); ac++;
2210 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2211 XtSetArg (al[ac], XtNdepth, FRAME_DISPLAY_INFO (f)->n_planes); ac++;
2212 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2213 XtSetArg (al[ac], XtNborderWidth, 0); ac++;
2214 frame_widget = XtCreateWidget (f->namebuf, emacsFrameClass, pane_widget,
2215 al, ac);
2217 f->output_data.x->edit_widget = frame_widget;
2219 XtManageChild (frame_widget);
2221 /* Do some needed geometry management. */
2223 char *tem, shell_position[sizeof "=x++" + 4 * INT_STRLEN_BOUND (int)];
2224 Arg gal[10];
2225 int gac = 0;
2226 int extra_borders = 0;
2227 int menubar_size
2228 = (f->output_data.x->menubar_widget
2229 ? (f->output_data.x->menubar_widget->core.height
2230 + f->output_data.x->menubar_widget->core.border_width)
2231 : 0);
2233 #if 0 /* Experimentally, we now get the right results
2234 for -geometry -0-0 without this. 24 Aug 96, rms. */
2235 if (FRAME_EXTERNAL_MENU_BAR (f))
2237 Dimension ibw = 0;
2238 XtVaGetValues (pane_widget, XtNinternalBorderWidth, &ibw, NULL);
2239 menubar_size += ibw;
2241 #endif
2243 f->output_data.x->menubar_height = menubar_size;
2245 #ifndef USE_LUCID
2246 /* Motif seems to need this amount added to the sizes
2247 specified for the shell widget. The Athena/Lucid widgets don't.
2248 Both conclusions reached experimentally. -- rms. */
2249 XtVaGetValues (f->output_data.x->edit_widget, XtNinternalBorderWidth,
2250 &extra_borders, NULL);
2251 extra_borders *= 2;
2252 #endif
2254 /* Convert our geometry parameters into a geometry string
2255 and specify it.
2256 Note that we do not specify here whether the position
2257 is a user-specified or program-specified one.
2258 We pass that information later, in x_wm_set_size_hints. */
2260 int left = f->left_pos;
2261 int xneg = window_prompting & XNegative;
2262 int top = f->top_pos;
2263 int yneg = window_prompting & YNegative;
2264 if (xneg)
2265 left = -left;
2266 if (yneg)
2267 top = -top;
2269 if (window_prompting & USPosition)
2270 sprintf (shell_position, "=%dx%d%c%d%c%d",
2271 FRAME_PIXEL_WIDTH (f) + extra_borders,
2272 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders,
2273 (xneg ? '-' : '+'), left,
2274 (yneg ? '-' : '+'), top);
2275 else
2277 sprintf (shell_position, "=%dx%d",
2278 FRAME_PIXEL_WIDTH (f) + extra_borders,
2279 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders);
2281 /* Setting x and y when the position is not specified in
2282 the geometry string will set program position in the WM hints.
2283 If Emacs had just one program position, we could set it in
2284 fallback resources, but since each make-frame call can specify
2285 different program positions, this is easier. */
2286 XtSetArg (gal[gac], XtNx, left); gac++;
2287 XtSetArg (gal[gac], XtNy, top); gac++;
2291 /* We don't free this because we don't know whether
2292 it is safe to free it while the frame exists.
2293 It isn't worth the trouble of arranging to free it
2294 when the frame is deleted. */
2295 tem = xstrdup (shell_position);
2296 XtSetArg (gal[gac], XtNgeometry, tem); gac++;
2297 XtSetValues (shell_widget, gal, gac);
2300 XtManageChild (pane_widget);
2301 XtRealizeWidget (shell_widget);
2303 if (FRAME_X_EMBEDDED_P (f))
2304 XReparentWindow (FRAME_X_DISPLAY (f), XtWindow (shell_widget),
2305 f->output_data.x->parent_desc, 0, 0);
2307 FRAME_X_WINDOW (f) = XtWindow (frame_widget);
2309 validate_x_resource_name ();
2311 class_hints.res_name = SSDATA (Vx_resource_name);
2312 class_hints.res_class = SSDATA (Vx_resource_class);
2313 XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints);
2315 #ifdef HAVE_X_I18N
2316 FRAME_XIC (f) = NULL;
2317 if (use_xim)
2318 create_frame_xic (f);
2319 #endif
2321 f->output_data.x->wm_hints.input = True;
2322 f->output_data.x->wm_hints.flags |= InputHint;
2323 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2324 &f->output_data.x->wm_hints);
2326 hack_wm_protocols (f, shell_widget);
2328 #ifdef HACK_EDITRES
2329 XtAddEventHandler (shell_widget, 0, True, _XEditResCheckMessages, 0);
2330 #endif
2332 /* Do a stupid property change to force the server to generate a
2333 PropertyNotify event so that the event_stream server timestamp will
2334 be initialized to something relevant to the time we created the window.
2336 XChangeProperty (XtDisplay (frame_widget), XtWindow (frame_widget),
2337 FRAME_DISPLAY_INFO (f)->Xatom_wm_protocols,
2338 XA_ATOM, 32, PropModeAppend, NULL, 0);
2340 /* Make all the standard events reach the Emacs frame. */
2341 attributes.event_mask = STANDARD_EVENT_SET;
2343 #ifdef HAVE_X_I18N
2344 if (FRAME_XIC (f))
2346 /* XIM server might require some X events. */
2347 unsigned long fevent = NoEventMask;
2348 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2349 attributes.event_mask |= fevent;
2351 #endif /* HAVE_X_I18N */
2353 attribute_mask = CWEventMask;
2354 XChangeWindowAttributes (XtDisplay (shell_widget), XtWindow (shell_widget),
2355 attribute_mask, &attributes);
2357 XtMapWidget (frame_widget);
2359 /* x_set_name normally ignores requests to set the name if the
2360 requested name is the same as the current name. This is the one
2361 place where that assumption isn't correct; f->name is set, but
2362 the X server hasn't been told. */
2364 Lisp_Object name;
2365 int explicit = f->explicit_name;
2367 f->explicit_name = 0;
2368 name = f->name;
2369 fset_name (f, Qnil);
2370 x_set_name (f, name, explicit);
2373 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2374 f->output_data.x->current_cursor
2375 = f->output_data.x->text_cursor);
2377 unblock_input ();
2379 /* This is a no-op, except under Motif. Make sure main areas are
2380 set to something reasonable, in case we get an error later. */
2381 lw_set_main_areas (pane_widget, 0, frame_widget);
2384 #else /* not USE_X_TOOLKIT */
2385 #ifdef USE_GTK
2386 static void
2387 x_window (struct frame *f)
2389 if (! xg_create_frame_widgets (f))
2390 error ("Unable to create window");
2392 #ifdef HAVE_X_I18N
2393 FRAME_XIC (f) = NULL;
2394 if (use_xim)
2396 block_input ();
2397 create_frame_xic (f);
2398 if (FRAME_XIC (f))
2400 /* XIM server might require some X events. */
2401 unsigned long fevent = NoEventMask;
2402 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2404 if (fevent != NoEventMask)
2406 XSetWindowAttributes attributes;
2407 XWindowAttributes wattr;
2408 unsigned long attribute_mask;
2410 XGetWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2411 &wattr);
2412 attributes.event_mask = wattr.your_event_mask | fevent;
2413 attribute_mask = CWEventMask;
2414 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2415 attribute_mask, &attributes);
2418 unblock_input ();
2420 #endif
2423 #else /*! USE_GTK */
2424 /* Create and set up the X window for frame F. */
2426 static void
2427 x_window (struct frame *f)
2429 XClassHint class_hints;
2430 XSetWindowAttributes attributes;
2431 unsigned long attribute_mask;
2433 attributes.background_pixel = FRAME_BACKGROUND_PIXEL (f);
2434 attributes.border_pixel = f->output_data.x->border_pixel;
2435 attributes.bit_gravity = StaticGravity;
2436 attributes.backing_store = NotUseful;
2437 attributes.save_under = True;
2438 attributes.event_mask = STANDARD_EVENT_SET;
2439 attributes.colormap = FRAME_X_COLORMAP (f);
2440 attribute_mask = (CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask
2441 | CWColormap);
2443 block_input ();
2444 FRAME_X_WINDOW (f)
2445 = XCreateWindow (FRAME_X_DISPLAY (f),
2446 f->output_data.x->parent_desc,
2447 f->left_pos,
2448 f->top_pos,
2449 FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
2450 f->border_width,
2451 CopyFromParent, /* depth */
2452 InputOutput, /* class */
2453 FRAME_X_VISUAL (f),
2454 attribute_mask, &attributes);
2456 #ifdef HAVE_X_I18N
2457 if (use_xim)
2459 create_frame_xic (f);
2460 if (FRAME_XIC (f))
2462 /* XIM server might require some X events. */
2463 unsigned long fevent = NoEventMask;
2464 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2465 attributes.event_mask |= fevent;
2466 attribute_mask = CWEventMask;
2467 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2468 attribute_mask, &attributes);
2471 #endif /* HAVE_X_I18N */
2473 validate_x_resource_name ();
2475 class_hints.res_name = SSDATA (Vx_resource_name);
2476 class_hints.res_class = SSDATA (Vx_resource_class);
2477 XSetClassHint (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &class_hints);
2479 /* The menubar is part of the ordinary display;
2480 it does not count in addition to the height of the window. */
2481 f->output_data.x->menubar_height = 0;
2483 /* This indicates that we use the "Passive Input" input model.
2484 Unless we do this, we don't get the Focus{In,Out} events that we
2485 need to draw the cursor correctly. Accursed bureaucrats.
2486 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2488 f->output_data.x->wm_hints.input = True;
2489 f->output_data.x->wm_hints.flags |= InputHint;
2490 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2491 &f->output_data.x->wm_hints);
2492 f->output_data.x->wm_hints.icon_pixmap = None;
2494 /* Request "save yourself" and "delete window" commands from wm. */
2496 Atom protocols[2];
2497 protocols[0] = FRAME_DISPLAY_INFO (f)->Xatom_wm_delete_window;
2498 protocols[1] = FRAME_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
2499 XSetWMProtocols (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), protocols, 2);
2502 /* x_set_name normally ignores requests to set the name if the
2503 requested name is the same as the current name. This is the one
2504 place where that assumption isn't correct; f->name is set, but
2505 the X server hasn't been told. */
2507 Lisp_Object name;
2508 int explicit = f->explicit_name;
2510 f->explicit_name = 0;
2511 name = f->name;
2512 fset_name (f, Qnil);
2513 x_set_name (f, name, explicit);
2516 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2517 f->output_data.x->current_cursor
2518 = f->output_data.x->text_cursor);
2520 unblock_input ();
2522 if (FRAME_X_WINDOW (f) == 0)
2523 error ("Unable to create window");
2526 #endif /* not USE_GTK */
2527 #endif /* not USE_X_TOOLKIT */
2529 /* Verify that the icon position args for this window are valid. */
2531 static void
2532 x_icon_verify (struct frame *f, Lisp_Object parms)
2534 Lisp_Object icon_x, icon_y;
2536 /* Set the position of the icon. Note that twm groups all
2537 icons in an icon window. */
2538 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2539 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2540 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2542 CHECK_NUMBER (icon_x);
2543 CHECK_NUMBER (icon_y);
2545 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2546 error ("Both left and top icon corners of icon must be specified");
2549 /* Handle the icon stuff for this window. Perhaps later we might
2550 want an x_set_icon_position which can be called interactively as
2551 well. */
2553 static void
2554 x_icon (struct frame *f, Lisp_Object parms)
2556 Lisp_Object icon_x, icon_y;
2557 #if 0
2558 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2559 #endif
2561 /* Set the position of the icon. Note that twm groups all
2562 icons in an icon window. */
2563 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2564 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2565 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2567 CHECK_TYPE_RANGED_INTEGER (int, icon_x);
2568 CHECK_TYPE_RANGED_INTEGER (int, icon_y);
2570 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2571 error ("Both left and top icon corners of icon must be specified");
2573 block_input ();
2575 if (! EQ (icon_x, Qunbound))
2576 x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
2578 #if 0 /* x_get_arg removes the visibility parameter as a side effect,
2579 but x_create_frame still needs it. */
2580 /* Start up iconic or window? */
2581 x_wm_set_window_state
2582 (f, (EQ (x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL),
2583 Qicon)
2584 ? IconicState
2585 : NormalState));
2586 #endif
2588 x_text_icon (f, SSDATA ((!NILP (f->icon_name)
2589 ? f->icon_name
2590 : f->name)));
2592 unblock_input ();
2595 /* Make the GCs needed for this window, setting the
2596 background, border and mouse colors; also create the
2597 mouse cursor and the gray border tile. */
2599 static void
2600 x_make_gc (struct frame *f)
2602 XGCValues gc_values;
2604 block_input ();
2606 /* Create the GCs of this frame.
2607 Note that many default values are used. */
2609 gc_values.foreground = FRAME_FOREGROUND_PIXEL (f);
2610 gc_values.background = FRAME_BACKGROUND_PIXEL (f);
2611 gc_values.line_width = 0; /* Means 1 using fast algorithm. */
2612 f->output_data.x->normal_gc
2613 = XCreateGC (FRAME_X_DISPLAY (f),
2614 FRAME_X_WINDOW (f),
2615 GCLineWidth | GCForeground | GCBackground,
2616 &gc_values);
2618 /* Reverse video style. */
2619 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2620 gc_values.background = FRAME_FOREGROUND_PIXEL (f);
2621 f->output_data.x->reverse_gc
2622 = XCreateGC (FRAME_X_DISPLAY (f),
2623 FRAME_X_WINDOW (f),
2624 GCForeground | GCBackground | GCLineWidth,
2625 &gc_values);
2627 /* Cursor has cursor-color background, background-color foreground. */
2628 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2629 gc_values.background = f->output_data.x->cursor_pixel;
2630 gc_values.fill_style = FillOpaqueStippled;
2631 f->output_data.x->cursor_gc
2632 = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2633 (GCForeground | GCBackground
2634 | GCFillStyle | GCLineWidth),
2635 &gc_values);
2637 /* Create the gray border tile used when the pointer is not in
2638 the frame. Since this depends on the frame's pixel values,
2639 this must be done on a per-frame basis. */
2640 f->output_data.x->border_tile
2641 = (XCreatePixmapFromBitmapData
2642 (FRAME_X_DISPLAY (f), FRAME_DISPLAY_INFO (f)->root_window,
2643 gray_bits, gray_width, gray_height,
2644 FRAME_FOREGROUND_PIXEL (f),
2645 FRAME_BACKGROUND_PIXEL (f),
2646 DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
2648 unblock_input ();
2652 /* Free what was allocated in x_make_gc. */
2654 void
2655 x_free_gcs (struct frame *f)
2657 Display *dpy = FRAME_X_DISPLAY (f);
2659 block_input ();
2661 if (f->output_data.x->normal_gc)
2663 XFreeGC (dpy, f->output_data.x->normal_gc);
2664 f->output_data.x->normal_gc = 0;
2667 if (f->output_data.x->reverse_gc)
2669 XFreeGC (dpy, f->output_data.x->reverse_gc);
2670 f->output_data.x->reverse_gc = 0;
2673 if (f->output_data.x->cursor_gc)
2675 XFreeGC (dpy, f->output_data.x->cursor_gc);
2676 f->output_data.x->cursor_gc = 0;
2679 if (f->output_data.x->border_tile)
2681 XFreePixmap (dpy, f->output_data.x->border_tile);
2682 f->output_data.x->border_tile = 0;
2685 unblock_input ();
2689 /* Handler for signals raised during x_create_frame and
2690 x_create_tip_frame. FRAME is the frame which is partially
2691 constructed. */
2693 static Lisp_Object
2694 unwind_create_frame (Lisp_Object frame)
2696 struct frame *f = XFRAME (frame);
2698 /* If frame is already dead, nothing to do. This can happen if the
2699 display is disconnected after the frame has become official, but
2700 before x_create_frame removes the unwind protect. */
2701 if (!FRAME_LIVE_P (f))
2702 return Qnil;
2704 /* If frame is ``official'', nothing to do. */
2705 if (NILP (Fmemq (frame, Vframe_list)))
2707 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2708 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2709 #endif
2711 x_free_frame_resources (f);
2712 free_glyphs (f);
2714 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2715 /* Check that reference counts are indeed correct. */
2716 eassert (dpyinfo->reference_count == dpyinfo_refcount);
2717 eassert (dpyinfo->terminal->image_cache->refcount == image_cache_refcount);
2718 #endif
2719 return Qt;
2722 return Qnil;
2725 static void
2726 do_unwind_create_frame (Lisp_Object frame)
2728 unwind_create_frame (frame);
2731 static void
2732 unwind_create_frame_1 (Lisp_Object val)
2734 inhibit_lisp_code = val;
2737 static void
2738 x_default_font_parameter (struct frame *f, Lisp_Object parms)
2740 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2741 Lisp_Object font_param = x_get_arg (dpyinfo, parms, Qfont, NULL, NULL,
2742 RES_TYPE_STRING);
2743 Lisp_Object font = Qnil;
2744 if (EQ (font_param, Qunbound))
2745 font_param = Qnil;
2747 if (NILP (font_param))
2749 /* System font should take precedence over X resources. We suggest this
2750 regardless of font-use-system-font because .emacs may not have been
2751 read yet. */
2752 const char *system_font = xsettings_get_system_font ();
2753 if (system_font)
2754 font = font_open_by_name (f, build_unibyte_string (system_font));
2757 if (NILP (font))
2758 font = !NILP (font_param) ? font_param
2759 : x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
2761 if (! FONTP (font) && ! STRINGP (font))
2763 const char *names[]
2765 #ifdef HAVE_XFT
2766 /* This will find the normal Xft font. */
2767 "monospace-10",
2768 #endif
2769 "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
2770 "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
2771 "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
2772 /* This was formerly the first thing tried, but it finds
2773 too many fonts and takes too long. */
2774 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
2775 /* If those didn't work, look for something which will
2776 at least work. */
2777 "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
2778 "fixed",
2779 NULL };
2780 int i;
2782 for (i = 0; names[i]; i++)
2784 font = font_open_by_name (f, build_unibyte_string (names[i]));
2785 if (! NILP (font))
2786 break;
2788 if (NILP (font))
2789 error ("No suitable font was found");
2791 else if (!NILP (font_param))
2793 /* Remember the explicit font parameter, so we can re-apply it after
2794 we've applied the `default' face settings. */
2795 x_set_frame_parameters (f, list1 (Fcons (Qfont_param, font_param)));
2798 /* This call will make X resources override any system font setting. */
2799 x_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING);
2803 DEFUN ("x-wm-set-size-hint", Fx_wm_set_size_hint, Sx_wm_set_size_hint,
2804 0, 1, 0,
2805 doc: /* Send the size hints for frame FRAME to the window manager.
2806 If FRAME is omitted or nil, use the selected frame.
2807 Signal error if FRAME is not an X frame. */)
2808 (Lisp_Object frame)
2810 struct frame *f = decode_window_system_frame (frame);
2812 block_input ();
2813 x_wm_set_size_hint (f, 0, 0);
2814 unblock_input ();
2815 return Qnil;
2818 static void
2819 set_machine_and_pid_properties (struct frame *f)
2821 long pid = (long) getpid ();
2823 /* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME. */
2824 XSetWMProperties (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), NULL, NULL,
2825 NULL, 0, NULL, NULL, NULL);
2826 XChangeProperty (FRAME_X_DISPLAY (f),
2827 FRAME_OUTER_WINDOW (f),
2828 XInternAtom (FRAME_X_DISPLAY (f),
2829 "_NET_WM_PID",
2830 False),
2831 XA_CARDINAL, 32, PropModeReplace,
2832 (unsigned char *) &pid, 1);
2835 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
2836 1, 1, 0,
2837 doc: /* Make a new X window, which is called a "frame" in Emacs terms.
2838 Return an Emacs frame object.
2839 PARMS is an alist of frame parameters.
2840 If the parameters specify that the frame should not have a minibuffer,
2841 and do not specify a specific minibuffer window to use,
2842 then `default-minibuffer-frame' must be a frame whose minibuffer can
2843 be shared by the new frame.
2845 This function is an internal primitive--use `make-frame' instead. */)
2846 (Lisp_Object parms)
2848 struct frame *f;
2849 Lisp_Object frame, tem;
2850 Lisp_Object name;
2851 int minibuffer_only = 0;
2852 long window_prompting = 0;
2853 int width, height;
2854 ptrdiff_t count = SPECPDL_INDEX ();
2855 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
2856 Lisp_Object display;
2857 struct x_display_info *dpyinfo = NULL;
2858 Lisp_Object parent;
2859 struct kboard *kb;
2861 parms = Fcopy_alist (parms);
2863 /* Use this general default value to start with
2864 until we know if this frame has a specified name. */
2865 Vx_resource_name = Vinvocation_name;
2867 display = x_get_arg (dpyinfo, parms, Qterminal, 0, 0, RES_TYPE_NUMBER);
2868 if (EQ (display, Qunbound))
2869 display = x_get_arg (dpyinfo, parms, Qdisplay, 0, 0, RES_TYPE_STRING);
2870 if (EQ (display, Qunbound))
2871 display = Qnil;
2872 dpyinfo = check_x_display_info (display);
2873 kb = dpyinfo->terminal->kboard;
2875 if (!dpyinfo->terminal->name)
2876 error ("Terminal is not live, can't create new frames on it");
2878 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
2879 if (!STRINGP (name)
2880 && ! EQ (name, Qunbound)
2881 && ! NILP (name))
2882 error ("Invalid frame name--not a string or nil");
2884 if (STRINGP (name))
2885 Vx_resource_name = name;
2887 /* See if parent window is specified. */
2888 parent = x_get_arg (dpyinfo, parms, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
2889 if (EQ (parent, Qunbound))
2890 parent = Qnil;
2891 if (! NILP (parent))
2892 CHECK_NUMBER (parent);
2894 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
2895 /* No need to protect DISPLAY because that's not used after passing
2896 it to make_frame_without_minibuffer. */
2897 frame = Qnil;
2898 GCPRO4 (parms, parent, name, frame);
2899 tem = x_get_arg (dpyinfo, parms, Qminibuffer, "minibuffer", "Minibuffer",
2900 RES_TYPE_SYMBOL);
2901 if (EQ (tem, Qnone) || NILP (tem))
2902 f = make_frame_without_minibuffer (Qnil, kb, display);
2903 else if (EQ (tem, Qonly))
2905 f = make_minibuffer_frame ();
2906 minibuffer_only = 1;
2908 else if (WINDOWP (tem))
2909 f = make_frame_without_minibuffer (tem, kb, display);
2910 else
2911 f = make_frame (1);
2913 XSETFRAME (frame, f);
2915 f->terminal = dpyinfo->terminal;
2917 f->output_method = output_x_window;
2918 f->output_data.x = xzalloc (sizeof *f->output_data.x);
2919 f->output_data.x->icon_bitmap = -1;
2920 FRAME_FONTSET (f) = -1;
2921 f->output_data.x->scroll_bar_foreground_pixel = -1;
2922 f->output_data.x->scroll_bar_background_pixel = -1;
2923 #ifdef USE_TOOLKIT_SCROLL_BARS
2924 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
2925 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
2926 #endif /* USE_TOOLKIT_SCROLL_BARS */
2927 f->output_data.x->white_relief.pixel = -1;
2928 f->output_data.x->black_relief.pixel = -1;
2930 fset_icon_name (f,
2931 x_get_arg (dpyinfo, parms, Qicon_name, "iconName", "Title",
2932 RES_TYPE_STRING));
2933 if (! STRINGP (f->icon_name))
2934 fset_icon_name (f, Qnil);
2936 FRAME_DISPLAY_INFO (f) = dpyinfo;
2938 /* With FRAME_DISPLAY_INFO set up, this unwind-protect is safe. */
2939 record_unwind_protect (do_unwind_create_frame, frame);
2941 /* These colors will be set anyway later, but it's important
2942 to get the color reference counts right, so initialize them! */
2944 Lisp_Object black;
2945 struct gcpro gcpro1;
2947 /* Function x_decode_color can signal an error. Make
2948 sure to initialize color slots so that we won't try
2949 to free colors we haven't allocated. */
2950 FRAME_FOREGROUND_PIXEL (f) = -1;
2951 FRAME_BACKGROUND_PIXEL (f) = -1;
2952 f->output_data.x->cursor_pixel = -1;
2953 f->output_data.x->cursor_foreground_pixel = -1;
2954 f->output_data.x->border_pixel = -1;
2955 f->output_data.x->mouse_pixel = -1;
2957 black = build_string ("black");
2958 GCPRO1 (black);
2959 FRAME_FOREGROUND_PIXEL (f)
2960 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
2961 FRAME_BACKGROUND_PIXEL (f)
2962 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
2963 f->output_data.x->cursor_pixel
2964 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
2965 f->output_data.x->cursor_foreground_pixel
2966 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
2967 f->output_data.x->border_pixel
2968 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
2969 f->output_data.x->mouse_pixel
2970 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
2971 UNGCPRO;
2974 /* Specify the parent under which to make this X window. */
2976 if (!NILP (parent))
2978 f->output_data.x->parent_desc = (Window) XFASTINT (parent);
2979 f->output_data.x->explicit_parent = 1;
2981 else
2983 f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
2984 f->output_data.x->explicit_parent = 0;
2987 /* Set the name; the functions to which we pass f expect the name to
2988 be set. */
2989 if (EQ (name, Qunbound) || NILP (name))
2991 fset_name (f, build_string (dpyinfo->x_id_name));
2992 f->explicit_name = 0;
2994 else
2996 fset_name (f, name);
2997 f->explicit_name = 1;
2998 /* use the frame's title when getting resources for this frame. */
2999 specbind (Qx_resource_name, name);
3002 #ifdef HAVE_FREETYPE
3003 #ifdef HAVE_XFT
3004 register_font_driver (&xftfont_driver, f);
3005 #else /* not HAVE_XFT */
3006 register_font_driver (&ftxfont_driver, f);
3007 #endif /* not HAVE_XFT */
3008 #endif /* HAVE_FREETYPE */
3009 register_font_driver (&xfont_driver, f);
3011 x_default_parameter (f, parms, Qfont_backend, Qnil,
3012 "fontBackend", "FontBackend", RES_TYPE_STRING);
3014 /* Extract the window parameters from the supplied values
3015 that are needed to determine window geometry. */
3016 x_default_font_parameter (f, parms);
3017 if (!FRAME_FONT (f))
3019 delete_frame (frame, Qnoelisp);
3020 error ("Invalid frame font");
3023 /* Frame contents get displaced if an embedded X window has a border. */
3024 if (! FRAME_X_EMBEDDED_P (f))
3025 x_default_parameter (f, parms, Qborder_width, make_number (0),
3026 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
3028 /* This defaults to 1 in order to match xterm. We recognize either
3029 internalBorderWidth or internalBorder (which is what xterm calls
3030 it). */
3031 if (NILP (Fassq (Qinternal_border_width, parms)))
3033 Lisp_Object value;
3035 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
3036 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
3037 if (! EQ (value, Qunbound))
3038 parms = Fcons (Fcons (Qinternal_border_width, value),
3039 parms);
3041 x_default_parameter (f, parms, Qinternal_border_width,
3042 #ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */
3043 make_number (0),
3044 #else
3045 make_number (1),
3046 #endif
3047 "internalBorderWidth", "internalBorderWidth",
3048 RES_TYPE_NUMBER);
3049 x_default_parameter (f, parms, Qright_divider_width, make_number (0),
3050 NULL, NULL, RES_TYPE_NUMBER);
3051 x_default_parameter (f, parms, Qbottom_divider_width, make_number (0),
3052 NULL, NULL, RES_TYPE_NUMBER);
3053 x_default_parameter (f, parms, Qvertical_scroll_bars,
3054 #if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
3055 Qright,
3056 #else
3057 Qleft,
3058 #endif
3059 "verticalScrollBars", "ScrollBars",
3060 RES_TYPE_SYMBOL);
3062 /* Also do the stuff which must be set before the window exists. */
3063 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
3064 "foreground", "Foreground", RES_TYPE_STRING);
3065 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
3066 "background", "Background", RES_TYPE_STRING);
3067 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
3068 "pointerColor", "Foreground", RES_TYPE_STRING);
3069 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
3070 "borderColor", "BorderColor", RES_TYPE_STRING);
3071 x_default_parameter (f, parms, Qscreen_gamma, Qnil,
3072 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
3073 x_default_parameter (f, parms, Qline_spacing, Qnil,
3074 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
3075 x_default_parameter (f, parms, Qleft_fringe, Qnil,
3076 "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
3077 x_default_parameter (f, parms, Qright_fringe, Qnil,
3078 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
3080 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_foreground,
3081 "scrollBarForeground",
3082 "ScrollBarForeground", 1);
3083 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_background,
3084 "scrollBarBackground",
3085 "ScrollBarBackground", 0);
3087 #ifdef GLYPH_DEBUG
3088 image_cache_refcount =
3089 FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
3090 dpyinfo_refcount = dpyinfo->reference_count;
3091 #endif /* GLYPH_DEBUG */
3093 /* Init faces before x_default_parameter is called for scroll-bar
3094 parameters because that function calls x_set_scroll_bar_width,
3095 which calls change_frame_size, which calls Fset_window_buffer,
3096 which runs hooks, which call Fvertical_motion. At the end, we
3097 end up in init_iterator with a null face cache, which should not
3098 happen. */
3099 init_frame_faces (f);
3101 /* PXW: This is a duplicate from below. We have to do it here since
3102 otherwise x_set_tool_bar_lines will work with the character sizes
3103 installed by init_frame_faces while the frame's pixel size is still
3104 calculated from a character size of 1 and we subsequently hit the
3105 eassert (height >= 0) assertion in window_box_height. The
3106 non-pixelwise code apparently worked around this because it had one
3107 frame line vs one toolbar line which left us with a zero root
3108 window height which was obviously wrong as well ... */
3109 change_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
3110 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 1, 0, 0, 1);
3112 /* Set the menu-bar-lines and tool-bar-lines parameters. We don't
3113 look up the X resources controlling the menu-bar and tool-bar
3114 here; they are processed specially at startup, and reflected in
3115 the values of the mode variables.
3117 Avoid calling window-configuration-change-hook; otherwise we
3118 could get an infloop in next_frame since the frame is not yet in
3119 Vframe_list. */
3121 ptrdiff_t count2 = SPECPDL_INDEX ();
3122 record_unwind_protect (unwind_create_frame_1, inhibit_lisp_code);
3123 inhibit_lisp_code = Qt;
3125 x_default_parameter (f, parms, Qmenu_bar_lines,
3126 NILP (Vmenu_bar_mode)
3127 ? make_number (0) : make_number (1),
3128 NULL, NULL, RES_TYPE_NUMBER);
3129 x_default_parameter (f, parms, Qtool_bar_lines,
3130 NILP (Vtool_bar_mode)
3131 ? make_number (0) : make_number (1),
3132 NULL, NULL, RES_TYPE_NUMBER);
3134 unbind_to (count2, Qnil);
3137 x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
3138 "bufferPredicate", "BufferPredicate",
3139 RES_TYPE_SYMBOL);
3140 x_default_parameter (f, parms, Qtitle, Qnil,
3141 "title", "Title", RES_TYPE_STRING);
3142 x_default_parameter (f, parms, Qwait_for_wm, Qt,
3143 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
3144 x_default_parameter (f, parms, Qfullscreen, Qnil,
3145 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
3146 x_default_parameter (f, parms, Qtool_bar_position,
3147 f->tool_bar_position, 0, 0, RES_TYPE_SYMBOL);
3149 /* Compute the size of the X window. */
3150 window_prompting = x_figure_window_size (f, parms, 1);
3152 tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
3153 f->no_split = minibuffer_only || EQ (tem, Qt);
3155 x_icon_verify (f, parms);
3157 /* Create the X widget or window. */
3158 #ifdef USE_X_TOOLKIT
3159 x_window (f, window_prompting, minibuffer_only);
3160 #else
3161 x_window (f);
3162 #endif
3164 x_icon (f, parms);
3165 x_make_gc (f);
3167 /* Now consider the frame official. */
3168 f->terminal->reference_count++;
3169 FRAME_DISPLAY_INFO (f)->reference_count++;
3170 Vframe_list = Fcons (frame, Vframe_list);
3172 /* We need to do this after creating the X window, so that the
3173 icon-creation functions can say whose icon they're describing. */
3174 x_default_parameter (f, parms, Qicon_type, Qt,
3175 "bitmapIcon", "BitmapIcon", RES_TYPE_BOOLEAN);
3177 x_default_parameter (f, parms, Qauto_raise, Qnil,
3178 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3179 x_default_parameter (f, parms, Qauto_lower, Qnil,
3180 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3181 x_default_parameter (f, parms, Qcursor_type, Qbox,
3182 "cursorType", "CursorType", RES_TYPE_SYMBOL);
3183 x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
3184 "scrollBarWidth", "ScrollBarWidth",
3185 RES_TYPE_NUMBER);
3186 x_default_parameter (f, parms, Qalpha, Qnil,
3187 "alpha", "Alpha", RES_TYPE_NUMBER);
3189 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3190 Change will not be effected unless different from the current
3191 FRAME_LINES (f). */
3192 width = FRAME_TEXT_WIDTH (f);
3193 height = FRAME_TEXT_HEIGHT (f);
3194 FRAME_TEXT_HEIGHT (f) = 0;
3195 SET_FRAME_WIDTH (f, 0);
3196 change_frame_size (f, width, height, 1, 0, 0, 1);
3198 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3199 /* Create the menu bar. */
3200 if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
3202 /* If this signals an error, we haven't set size hints for the
3203 frame and we didn't make it visible. */
3204 initialize_frame_menubar (f);
3206 #ifndef USE_GTK
3207 /* This is a no-op, except under Motif where it arranges the
3208 main window for the widgets on it. */
3209 lw_set_main_areas (f->output_data.x->column_widget,
3210 f->output_data.x->menubar_widget,
3211 f->output_data.x->edit_widget);
3212 #endif /* not USE_GTK */
3214 #endif /* USE_X_TOOLKIT || USE_GTK */
3216 /* Tell the server what size and position, etc, we want, and how
3217 badly we want them. This should be done after we have the menu
3218 bar so that its size can be taken into account. */
3219 block_input ();
3220 x_wm_set_size_hint (f, window_prompting, 0);
3221 unblock_input ();
3223 /* Make the window appear on the frame and enable display, unless
3224 the caller says not to. However, with explicit parent, Emacs
3225 cannot control visibility, so don't try. */
3226 if (! f->output_data.x->explicit_parent)
3228 Lisp_Object visibility;
3230 visibility = x_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
3231 RES_TYPE_SYMBOL);
3232 if (EQ (visibility, Qunbound))
3233 visibility = Qt;
3235 if (EQ (visibility, Qicon))
3236 x_iconify_frame (f);
3237 else if (! NILP (visibility))
3238 x_make_frame_visible (f);
3239 else
3241 /* Must have been Qnil. */
3245 block_input ();
3247 /* Set machine name and pid for the purpose of window managers. */
3248 set_machine_and_pid_properties (f);
3250 /* Set the WM leader property. GTK does this itself, so this is not
3251 needed when using GTK. */
3252 if (dpyinfo->client_leader_window != 0)
3254 XChangeProperty (FRAME_X_DISPLAY (f),
3255 FRAME_OUTER_WINDOW (f),
3256 dpyinfo->Xatom_wm_client_leader,
3257 XA_WINDOW, 32, PropModeReplace,
3258 (unsigned char *) &dpyinfo->client_leader_window, 1);
3261 unblock_input ();
3263 /* Initialize `default-minibuffer-frame' in case this is the first
3264 frame on this terminal. */
3265 if (FRAME_HAS_MINIBUF_P (f)
3266 && (!FRAMEP (KVAR (kb, Vdefault_minibuffer_frame))
3267 || !FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame)))))
3268 kset_default_minibuffer_frame (kb, frame);
3270 /* All remaining specified parameters, which have not been "used"
3271 by x_get_arg and friends, now go in the misc. alist of the frame. */
3272 for (tem = parms; CONSP (tem); tem = XCDR (tem))
3273 if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
3274 fset_param_alist (f, Fcons (XCAR (tem), f->param_alist));
3276 UNGCPRO;
3278 /* Make sure windows on this frame appear in calls to next-window
3279 and similar functions. */
3280 Vwindow_list = Qnil;
3282 return unbind_to (count, frame);
3286 /* FRAME is used only to get a handle on the X display. We don't pass the
3287 display info directly because we're called from frame.c, which doesn't
3288 know about that structure. */
3290 Lisp_Object
3291 x_get_focus_frame (struct frame *frame)
3293 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (frame);
3294 Lisp_Object xfocus;
3295 if (! dpyinfo->x_focus_frame)
3296 return Qnil;
3298 XSETFRAME (xfocus, dpyinfo->x_focus_frame);
3299 return xfocus;
3303 /* In certain situations, when the window manager follows a
3304 click-to-focus policy, there seems to be no way around calling
3305 XSetInputFocus to give another frame the input focus .
3307 In an ideal world, XSetInputFocus should generally be avoided so
3308 that applications don't interfere with the window manager's focus
3309 policy. But I think it's okay to use when it's clearly done
3310 following a user-command. */
3312 void
3313 x_focus_frame (struct frame *f)
3315 Display *dpy = FRAME_X_DISPLAY (f);
3317 block_input ();
3318 x_catch_errors (dpy);
3320 if (FRAME_X_EMBEDDED_P (f))
3322 /* For Xembedded frames, normally the embedder forwards key
3323 events. See XEmbed Protocol Specification at
3324 http://freedesktop.org/wiki/Specifications/xembed-spec */
3325 xembed_request_focus (f);
3327 else
3329 XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3330 RevertToParent, CurrentTime);
3331 x_ewmh_activate_frame (f);
3334 x_uncatch_errors ();
3335 unblock_input ();
3339 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
3340 doc: /* Internal function called by `color-defined-p', which see
3341 .\(Note that the Nextstep version of this function ignores FRAME.) */)
3342 (Lisp_Object color, Lisp_Object frame)
3344 XColor foo;
3345 struct frame *f = decode_window_system_frame (frame);
3347 CHECK_STRING (color);
3349 if (x_defined_color (f, SSDATA (color), &foo, 0))
3350 return Qt;
3351 else
3352 return Qnil;
3355 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
3356 doc: /* Internal function called by `color-values', which see. */)
3357 (Lisp_Object color, Lisp_Object frame)
3359 XColor foo;
3360 struct frame *f = decode_window_system_frame (frame);
3362 CHECK_STRING (color);
3364 if (x_defined_color (f, SSDATA (color), &foo, 0))
3365 return list3i (foo.red, foo.green, foo.blue);
3366 else
3367 return Qnil;
3370 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
3371 doc: /* Internal function called by `display-color-p', which see. */)
3372 (Lisp_Object terminal)
3374 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3376 if (dpyinfo->n_planes <= 2)
3377 return Qnil;
3379 switch (dpyinfo->visual->class)
3381 case StaticColor:
3382 case PseudoColor:
3383 case TrueColor:
3384 case DirectColor:
3385 return Qt;
3387 default:
3388 return Qnil;
3392 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
3393 0, 1, 0,
3394 doc: /* Return t if the X display supports shades of gray.
3395 Note that color displays do support shades of gray.
3396 The optional argument TERMINAL specifies which display to ask about.
3397 TERMINAL should be a terminal object, a frame or a display name (a string).
3398 If omitted or nil, that stands for the selected frame's display. */)
3399 (Lisp_Object terminal)
3401 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3403 if (dpyinfo->n_planes <= 1)
3404 return Qnil;
3406 switch (dpyinfo->visual->class)
3408 case StaticColor:
3409 case PseudoColor:
3410 case TrueColor:
3411 case DirectColor:
3412 case StaticGray:
3413 case GrayScale:
3414 return Qt;
3416 default:
3417 return Qnil;
3421 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
3422 0, 1, 0,
3423 doc: /* Return the width in pixels of the X display TERMINAL.
3424 The optional argument TERMINAL specifies which display to ask about.
3425 TERMINAL should be a terminal object, a frame or a display name (a string).
3426 If omitted or nil, that stands for the selected frame's display.
3428 On \"multi-monitor\" setups this refers to the pixel width for all
3429 physical monitors associated with TERMINAL. To get information for
3430 each physical monitor, use `display-monitor-attributes-list'. */)
3431 (Lisp_Object terminal)
3433 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3435 return make_number (x_display_pixel_width (dpyinfo));
3438 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
3439 Sx_display_pixel_height, 0, 1, 0,
3440 doc: /* Return the height in pixels of the X display TERMINAL.
3441 The optional argument TERMINAL specifies which display to ask about.
3442 TERMINAL should be a terminal object, a frame or a display name (a string).
3443 If omitted or nil, that stands for the selected frame's display.
3445 On \"multi-monitor\" setups this refers to the pixel height for all
3446 physical monitors associated with TERMINAL. To get information for
3447 each physical monitor, use `display-monitor-attributes-list'. */)
3448 (Lisp_Object terminal)
3450 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3452 return make_number (x_display_pixel_height (dpyinfo));
3455 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
3456 0, 1, 0,
3457 doc: /* Return the number of bitplanes of the X display TERMINAL.
3458 The optional argument TERMINAL specifies which display to ask about.
3459 TERMINAL should be a terminal object, a frame or a display name (a string).
3460 If omitted or nil, that stands for the selected frame's display. */)
3461 (Lisp_Object terminal)
3463 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3465 return make_number (dpyinfo->n_planes);
3468 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
3469 0, 1, 0,
3470 doc: /* Return the number of color cells of the X display TERMINAL.
3471 The optional argument TERMINAL specifies which display to ask about.
3472 TERMINAL should be a terminal object, a frame or a display name (a string).
3473 If omitted or nil, that stands for the selected frame's display. */)
3474 (Lisp_Object terminal)
3476 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3478 int nr_planes = DisplayPlanes (dpyinfo->display,
3479 XScreenNumberOfScreen (dpyinfo->screen));
3481 /* Truncate nr_planes to 24 to avoid integer overflow.
3482 Some displays says 32, but only 24 bits are actually significant.
3483 There are only very few and rare video cards that have more than
3484 24 significant bits. Also 24 bits is more than 16 million colors,
3485 it "should be enough for everyone". */
3486 if (nr_planes > 24) nr_planes = 24;
3488 return make_number (1 << nr_planes);
3491 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
3492 Sx_server_max_request_size,
3493 0, 1, 0,
3494 doc: /* Return the maximum request size of the X server of display TERMINAL.
3495 The optional argument TERMINAL specifies which display to ask about.
3496 TERMINAL should be a terminal object, a frame or a display name (a string).
3497 If omitted or nil, that stands for the selected frame's display. */)
3498 (Lisp_Object terminal)
3500 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3502 return make_number (MAXREQUEST (dpyinfo->display));
3505 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
3506 doc: /* Return the "vendor ID" string of the X server of display TERMINAL.
3507 \(Labeling every distributor as a "vendor" embodies the false assumption
3508 that operating systems cannot be developed and distributed noncommercially.)
3509 The optional argument TERMINAL specifies which display to ask about.
3510 TERMINAL should be a terminal object, a frame or a display name (a string).
3511 If omitted or nil, that stands for the selected frame's display. */)
3512 (Lisp_Object terminal)
3514 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3515 const char *vendor = ServerVendor (dpyinfo->display);
3517 if (! vendor) vendor = "";
3518 return build_string (vendor);
3521 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
3522 doc: /* Return the version numbers of the X server of display TERMINAL.
3523 The value is a list of three integers: the major and minor
3524 version numbers of the X Protocol in use, and the distributor-specific release
3525 number. See also the function `x-server-vendor'.
3527 The optional argument TERMINAL specifies which display to ask about.
3528 TERMINAL should be a terminal object, a frame or a display name (a string).
3529 If omitted or nil, that stands for the selected frame's display. */)
3530 (Lisp_Object terminal)
3532 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3533 Display *dpy = dpyinfo->display;
3535 return list3i (ProtocolVersion (dpy), ProtocolRevision (dpy),
3536 VendorRelease (dpy));
3539 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
3540 doc: /* Return the number of screens on the X server of 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. */)
3544 (Lisp_Object terminal)
3546 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3548 return make_number (ScreenCount (dpyinfo->display));
3551 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
3552 doc: /* Return the height in millimeters of the X display TERMINAL.
3553 The optional argument TERMINAL specifies which display to ask about.
3554 TERMINAL should be a terminal object, a frame or a display name (a string).
3555 If omitted or nil, that stands for the selected frame's display.
3557 On \"multi-monitor\" setups this refers to the height in millimeters for
3558 all physical monitors associated with TERMINAL. To get information
3559 for each physical monitor, use `display-monitor-attributes-list'. */)
3560 (Lisp_Object terminal)
3562 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3564 return make_number (HeightMMOfScreen (dpyinfo->screen));
3567 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
3568 doc: /* Return the width in millimeters of the X display TERMINAL.
3569 The optional argument TERMINAL specifies which display to ask about.
3570 TERMINAL should be a terminal object, a frame or a display name (a string).
3571 If omitted or nil, that stands for the selected frame's display.
3573 On \"multi-monitor\" setups this refers to the width in millimeters for
3574 all physical monitors associated with TERMINAL. To get information
3575 for each physical monitor, use `display-monitor-attributes-list'. */)
3576 (Lisp_Object terminal)
3578 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3580 return make_number (WidthMMOfScreen (dpyinfo->screen));
3583 DEFUN ("x-display-backing-store", Fx_display_backing_store,
3584 Sx_display_backing_store, 0, 1, 0,
3585 doc: /* Return an indication of whether X display TERMINAL does backing store.
3586 The value may be `always', `when-mapped', or `not-useful'.
3587 The optional argument TERMINAL specifies which display to ask about.
3588 TERMINAL should be a terminal object, a frame or a display name (a string).
3589 If omitted or nil, that stands for the selected frame's display. */)
3590 (Lisp_Object terminal)
3592 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3593 Lisp_Object result;
3595 switch (DoesBackingStore (dpyinfo->screen))
3597 case Always:
3598 result = intern ("always");
3599 break;
3601 case WhenMapped:
3602 result = intern ("when-mapped");
3603 break;
3605 case NotUseful:
3606 result = intern ("not-useful");
3607 break;
3609 default:
3610 error ("Strange value for BackingStore parameter of screen");
3613 return result;
3616 DEFUN ("x-display-visual-class", Fx_display_visual_class,
3617 Sx_display_visual_class, 0, 1, 0,
3618 doc: /* Return the visual class of the X display TERMINAL.
3619 The value is one of the symbols `static-gray', `gray-scale',
3620 `static-color', `pseudo-color', `true-color', or `direct-color'.
3622 The optional argument TERMINAL specifies which display to ask about.
3623 TERMINAL should a terminal object, a frame or a display name (a string).
3624 If omitted or nil, that stands for the selected frame's display. */)
3625 (Lisp_Object terminal)
3627 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3628 Lisp_Object result;
3630 switch (dpyinfo->visual->class)
3632 case StaticGray:
3633 result = intern ("static-gray");
3634 break;
3635 case GrayScale:
3636 result = intern ("gray-scale");
3637 break;
3638 case StaticColor:
3639 result = intern ("static-color");
3640 break;
3641 case PseudoColor:
3642 result = intern ("pseudo-color");
3643 break;
3644 case TrueColor:
3645 result = intern ("true-color");
3646 break;
3647 case DirectColor:
3648 result = intern ("direct-color");
3649 break;
3650 default:
3651 error ("Display has an unknown visual class");
3654 return result;
3657 DEFUN ("x-display-save-under", Fx_display_save_under,
3658 Sx_display_save_under, 0, 1, 0,
3659 doc: /* Return t if the X display TERMINAL supports the save-under feature.
3660 The optional argument TERMINAL specifies which display to ask about.
3661 TERMINAL should be a terminal object, a frame or a display name (a string).
3662 If omitted or nil, that stands for the selected frame's display. */)
3663 (Lisp_Object terminal)
3665 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3667 if (DoesSaveUnders (dpyinfo->screen) == True)
3668 return Qt;
3669 else
3670 return Qnil;
3673 /* Store the geometry of the workarea on display DPYINFO into *RECT.
3674 Return false if and only if the workarea information cannot be
3675 obtained via the _NET_WORKAREA root window property. */
3677 #if ! GTK_CHECK_VERSION (3, 4, 0)
3678 static bool
3679 x_get_net_workarea (struct x_display_info *dpyinfo, XRectangle *rect)
3681 Display *dpy = dpyinfo->display;
3682 long offset, max_len;
3683 Atom target_type, actual_type;
3684 unsigned long actual_size, bytes_remaining;
3685 int rc, actual_format;
3686 unsigned char *tmp_data = NULL;
3687 bool result = false;
3689 x_catch_errors (dpy);
3690 offset = 0;
3691 max_len = 1;
3692 target_type = XA_CARDINAL;
3693 rc = XGetWindowProperty (dpy, dpyinfo->root_window,
3694 dpyinfo->Xatom_net_current_desktop,
3695 offset, max_len, False, target_type,
3696 &actual_type, &actual_format, &actual_size,
3697 &bytes_remaining, &tmp_data);
3698 if (rc == Success && actual_type == target_type && !x_had_errors_p (dpy)
3699 && actual_format == 32 && actual_size == max_len)
3701 long current_desktop = ((long *) tmp_data)[0];
3703 XFree (tmp_data);
3704 tmp_data = NULL;
3706 offset = 4 * current_desktop;
3707 max_len = 4;
3708 rc = XGetWindowProperty (dpy, dpyinfo->root_window,
3709 dpyinfo->Xatom_net_workarea,
3710 offset, max_len, False, target_type,
3711 &actual_type, &actual_format, &actual_size,
3712 &bytes_remaining, &tmp_data);
3713 if (rc == Success && actual_type == target_type && !x_had_errors_p (dpy)
3714 && actual_format == 32 && actual_size == max_len)
3716 long *values = (long *) tmp_data;
3718 rect->x = values[0];
3719 rect->y = values[1];
3720 rect->width = values[2];
3721 rect->height = values[3];
3723 XFree (tmp_data);
3724 tmp_data = NULL;
3726 result = true;
3729 if (tmp_data)
3730 XFree (tmp_data);
3731 x_uncatch_errors ();
3733 return result;
3735 #endif
3737 #ifndef USE_GTK
3739 /* Return monitor number where F is "most" or closest to. */
3740 static int
3741 x_get_monitor_for_frame (struct frame *f,
3742 struct MonitorInfo *monitors,
3743 int n_monitors)
3745 XRectangle frect;
3746 int area = 0, dist = -1;
3747 int best_area = -1, best_dist = -1;
3748 int i;
3750 if (n_monitors == 1) return 0;
3751 frect.x = f->left_pos;
3752 frect.y = f->top_pos;
3753 frect.width = FRAME_PIXEL_WIDTH (f);
3754 frect.height = FRAME_PIXEL_HEIGHT (f);
3756 for (i = 0; i < n_monitors; ++i)
3758 struct MonitorInfo *mi = &monitors[i];
3759 XRectangle res;
3760 int a = 0;
3762 if (mi->geom.width == 0) continue;
3764 if (x_intersect_rectangles (&mi->geom, &frect, &res))
3766 a = res.width * res.height;
3767 if (a > area)
3769 area = a;
3770 best_area = i;
3774 if (a == 0 && area == 0)
3776 int dx, dy, d;
3777 if (frect.x + frect.width < mi->geom.x)
3778 dx = mi->geom.x - frect.x + frect.width;
3779 else if (frect.x > mi->geom.x + mi->geom.width)
3780 dx = frect.x - mi->geom.x + mi->geom.width;
3781 else
3782 dx = 0;
3783 if (frect.y + frect.height < mi->geom.y)
3784 dy = mi->geom.y - frect.y + frect.height;
3785 else if (frect.y > mi->geom.y + mi->geom.height)
3786 dy = frect.y - mi->geom.y + mi->geom.height;
3787 else
3788 dy = 0;
3790 d = dx*dx + dy*dy;
3791 if (dist == -1 || dist > d)
3793 dist = d;
3794 best_dist = i;
3799 return best_area != -1 ? best_area : (best_dist != -1 ? best_dist : 0);
3802 static Lisp_Object
3803 x_make_monitor_attribute_list (struct MonitorInfo *monitors,
3804 int n_monitors,
3805 int primary_monitor,
3806 struct x_display_info *dpyinfo,
3807 const char *source)
3809 Lisp_Object monitor_frames = Fmake_vector (make_number (n_monitors), Qnil);
3810 Lisp_Object frame, rest;
3812 FOR_EACH_FRAME (rest, frame)
3814 struct frame *f = XFRAME (frame);
3816 if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo
3817 && !EQ (frame, tip_frame))
3819 int i = x_get_monitor_for_frame (f, monitors, n_monitors);
3820 ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
3824 return make_monitor_attribute_list (monitors, n_monitors, primary_monitor,
3825 monitor_frames, source);
3828 static Lisp_Object
3829 x_get_monitor_attributes_fallback (struct x_display_info *dpyinfo)
3831 struct MonitorInfo monitor;
3832 XRectangle workarea_r;
3834 /* Fallback: treat (possibly) multiple physical monitors as if they
3835 formed a single monitor as a whole. This should provide a
3836 consistent result at least on single monitor environments. */
3837 monitor.geom.x = monitor.geom.y = 0;
3838 monitor.geom.width = x_display_pixel_width (dpyinfo);
3839 monitor.geom.height = x_display_pixel_height (dpyinfo);
3840 monitor.mm_width = WidthMMOfScreen (dpyinfo->screen);
3841 monitor.mm_height = HeightMMOfScreen (dpyinfo->screen);
3842 monitor.name = xstrdup ("combined screen");
3844 if (x_get_net_workarea (dpyinfo, &workarea_r))
3845 monitor.work = workarea_r;
3846 else
3847 monitor.work = monitor.geom;
3848 return x_make_monitor_attribute_list (&monitor, 1, 0, dpyinfo, "fallback");
3852 #ifdef HAVE_XINERAMA
3853 static Lisp_Object
3854 x_get_monitor_attributes_xinerama (struct x_display_info *dpyinfo)
3856 int n_monitors, i;
3857 Lisp_Object attributes_list = Qnil;
3858 Display *dpy = dpyinfo->display;
3859 XineramaScreenInfo *info = XineramaQueryScreens (dpy, &n_monitors);
3860 struct MonitorInfo *monitors;
3861 double mm_width_per_pixel, mm_height_per_pixel;
3863 if (! info || n_monitors == 0)
3865 if (info)
3866 XFree (info);
3867 return attributes_list;
3870 mm_width_per_pixel = ((double) WidthMMOfScreen (dpyinfo->screen)
3871 / x_display_pixel_width (dpyinfo));
3872 mm_height_per_pixel = ((double) HeightMMOfScreen (dpyinfo->screen)
3873 / x_display_pixel_height (dpyinfo));
3874 monitors = xzalloc (n_monitors * sizeof *monitors);
3875 for (i = 0; i < n_monitors; ++i)
3877 struct MonitorInfo *mi = &monitors[i];
3878 XRectangle workarea_r;
3880 mi->geom.x = info[i].x_org;
3881 mi->geom.y = info[i].y_org;
3882 mi->geom.width = info[i].width;
3883 mi->geom.height = info[i].height;
3884 mi->mm_width = mi->geom.width * mm_width_per_pixel + 0.5;
3885 mi->mm_height = mi->geom.height * mm_height_per_pixel + 0.5;
3886 mi->name = 0;
3888 /* Xinerama usually have primary monitor first, just use that. */
3889 if (i == 0 && x_get_net_workarea (dpyinfo, &workarea_r))
3891 mi->work = workarea_r;
3892 if (! x_intersect_rectangles (&mi->geom, &mi->work, &mi->work))
3893 mi->work = mi->geom;
3895 else
3896 mi->work = mi->geom;
3898 XFree (info);
3900 attributes_list = x_make_monitor_attribute_list (monitors,
3901 n_monitors,
3903 dpyinfo,
3904 "Xinerama");
3905 free_monitors (monitors, n_monitors);
3906 return attributes_list;
3908 #endif /* HAVE_XINERAMA */
3911 #ifdef HAVE_XRANDR
3912 static Lisp_Object
3913 x_get_monitor_attributes_xrandr (struct x_display_info *dpyinfo)
3915 Lisp_Object attributes_list = Qnil;
3916 XRRScreenResources *resources;
3917 Display *dpy = dpyinfo->display;
3918 int i, n_monitors, primary = -1;
3919 RROutput pxid = None;
3920 struct MonitorInfo *monitors;
3922 #ifdef HAVE_XRRGETSCREENRESOURCESCURRENT
3923 resources = XRRGetScreenResourcesCurrent (dpy, dpyinfo->root_window);
3924 #else
3925 resources = XRRGetScreenResources (dpy, dpyinfo->root_window);
3926 #endif
3927 if (! resources || resources->noutput == 0)
3929 if (resources)
3930 XRRFreeScreenResources (resources);
3931 return Qnil;
3933 n_monitors = resources->noutput;
3934 monitors = xzalloc (n_monitors * sizeof *monitors);
3936 #ifdef HAVE_XRRGETOUTPUTPRIMARY
3937 pxid = XRRGetOutputPrimary (dpy, dpyinfo->root_window);
3938 #endif
3940 for (i = 0; i < n_monitors; ++i)
3942 XRROutputInfo *info = XRRGetOutputInfo (dpy, resources,
3943 resources->outputs[i]);
3944 Connection conn = info ? info->connection : RR_Disconnected;
3945 RRCrtc id = info ? info->crtc : None;
3947 if (strcmp (info->name, "default") == 0)
3949 /* Non XRandr 1.2 driver, does not give useful data. */
3950 XRRFreeOutputInfo (info);
3951 XRRFreeScreenResources (resources);
3952 free_monitors (monitors, n_monitors);
3953 return Qnil;
3956 if (conn != RR_Disconnected && id != None)
3958 XRRCrtcInfo *crtc = XRRGetCrtcInfo (dpy, resources, id);
3959 struct MonitorInfo *mi = &monitors[i];
3960 XRectangle workarea_r;
3962 if (! crtc)
3964 XRRFreeOutputInfo (info);
3965 continue;
3968 mi->geom.x = crtc->x;
3969 mi->geom.y = crtc->y;
3970 mi->geom.width = crtc->width;
3971 mi->geom.height = crtc->height;
3972 mi->mm_width = info->mm_width;
3973 mi->mm_height = info->mm_height;
3974 mi->name = xstrdup (info->name);
3976 if (pxid != None && pxid == resources->outputs[i])
3977 primary = i;
3978 else if (primary == -1 && strcmp (info->name, "LVDS") == 0)
3979 primary = i;
3981 if (i == primary && x_get_net_workarea (dpyinfo, &workarea_r))
3983 mi->work= workarea_r;
3984 if (! x_intersect_rectangles (&mi->geom, &mi->work, &mi->work))
3985 mi->work = mi->geom;
3987 else
3988 mi->work = mi->geom;
3990 XRRFreeCrtcInfo (crtc);
3992 XRRFreeOutputInfo (info);
3994 XRRFreeScreenResources (resources);
3996 attributes_list = x_make_monitor_attribute_list (monitors,
3997 n_monitors,
3998 primary,
3999 dpyinfo,
4000 "XRandr");
4001 free_monitors (monitors, n_monitors);
4002 return attributes_list;
4004 #endif /* HAVE_XRANDR */
4006 static Lisp_Object
4007 x_get_monitor_attributes (struct x_display_info *dpyinfo)
4009 Lisp_Object attributes_list = Qnil;
4010 Display *dpy = dpyinfo->display;
4012 (void) dpy; /* Suppress unused variable warning. */
4014 #ifdef HAVE_XRANDR
4015 int xrr_event_base, xrr_error_base;
4016 bool xrr_ok = false;
4017 xrr_ok = XRRQueryExtension (dpy, &xrr_event_base, &xrr_error_base);
4018 if (xrr_ok)
4020 int xrr_major, xrr_minor;
4021 XRRQueryVersion (dpy, &xrr_major, &xrr_minor);
4022 xrr_ok = (xrr_major == 1 && xrr_minor >= 2) || xrr_major > 1;
4025 if (xrr_ok)
4026 attributes_list = x_get_monitor_attributes_xrandr (dpyinfo);
4027 #endif /* HAVE_XRANDR */
4029 #ifdef HAVE_XINERAMA
4030 if (NILP (attributes_list))
4032 int xin_event_base, xin_error_base;
4033 bool xin_ok = false;
4034 xin_ok = XineramaQueryExtension (dpy, &xin_event_base, &xin_error_base);
4035 if (xin_ok && XineramaIsActive (dpy))
4036 attributes_list = x_get_monitor_attributes_xinerama (dpyinfo);
4038 #endif /* HAVE_XINERAMA */
4040 if (NILP (attributes_list))
4041 attributes_list = x_get_monitor_attributes_fallback (dpyinfo);
4043 return attributes_list;
4046 #endif /* !USE_GTK */
4048 DEFUN ("x-display-monitor-attributes-list", Fx_display_monitor_attributes_list,
4049 Sx_display_monitor_attributes_list,
4050 0, 1, 0,
4051 doc: /* Return a list of physical monitor attributes on the X display TERMINAL.
4053 The optional argument TERMINAL specifies which display to ask about.
4054 TERMINAL should be a terminal object, a frame or a display name (a string).
4055 If omitted or nil, that stands for the selected frame's display.
4057 In addition to the standard attribute keys listed in
4058 `display-monitor-attributes-list', the following keys are contained in
4059 the attributes:
4061 source -- String describing the source from which multi-monitor
4062 information is obtained, one of \"Gdk\", \"XRandr\",
4063 \"Xinerama\", or \"fallback\"
4065 Internal use only, use `display-monitor-attributes-list' instead. */)
4066 (Lisp_Object terminal)
4068 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4069 Lisp_Object attributes_list = Qnil;
4071 #ifdef USE_GTK
4072 double mm_width_per_pixel, mm_height_per_pixel;
4073 GdkDisplay *gdpy;
4074 GdkScreen *gscreen;
4075 gint primary_monitor = 0, n_monitors, i;
4076 Lisp_Object monitor_frames, rest, frame;
4077 static const char *source = "Gdk";
4078 struct MonitorInfo *monitors;
4080 block_input ();
4081 mm_width_per_pixel = ((double) WidthMMOfScreen (dpyinfo->screen)
4082 / x_display_pixel_width (dpyinfo));
4083 mm_height_per_pixel = ((double) HeightMMOfScreen (dpyinfo->screen)
4084 / x_display_pixel_height (dpyinfo));
4085 gdpy = gdk_x11_lookup_xdisplay (dpyinfo->display);
4086 gscreen = gdk_display_get_default_screen (gdpy);
4087 #if GTK_CHECK_VERSION (2, 20, 0)
4088 primary_monitor = gdk_screen_get_primary_monitor (gscreen);
4089 #endif
4090 n_monitors = gdk_screen_get_n_monitors (gscreen);
4091 monitor_frames = Fmake_vector (make_number (n_monitors), Qnil);
4092 monitors = xzalloc (n_monitors * sizeof *monitors);
4094 FOR_EACH_FRAME (rest, frame)
4096 struct frame *f = XFRAME (frame);
4098 if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo
4099 && !EQ (frame, tip_frame))
4101 GdkWindow *gwin = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
4103 i = gdk_screen_get_monitor_at_window (gscreen, gwin);
4104 ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
4108 for (i = 0; i < n_monitors; ++i)
4110 gint width_mm = -1, height_mm = -1;
4111 GdkRectangle rec, work;
4112 struct MonitorInfo *mi = &monitors[i];
4114 gdk_screen_get_monitor_geometry (gscreen, i, &rec);
4116 #if GTK_CHECK_VERSION (2, 14, 0)
4117 width_mm = gdk_screen_get_monitor_width_mm (gscreen, i);
4118 height_mm = gdk_screen_get_monitor_height_mm (gscreen, i);
4119 #endif
4120 if (width_mm < 0)
4121 width_mm = rec.width * mm_width_per_pixel + 0.5;
4122 if (height_mm < 0)
4123 height_mm = rec.height * mm_height_per_pixel + 0.5;
4125 #if GTK_CHECK_VERSION (3, 4, 0)
4126 gdk_screen_get_monitor_workarea (gscreen, i, &work);
4127 #else
4128 /* Emulate the behavior of GTK+ 3.4. */
4130 XRectangle workarea_r;
4132 if (i == primary_monitor && x_get_net_workarea (dpyinfo, &workarea_r))
4134 work.x = workarea_r.x;
4135 work.y = workarea_r.y;
4136 work.width = workarea_r.width;
4137 work.height = workarea_r.height;
4138 if (! gdk_rectangle_intersect (&rec, &work, &work))
4139 work = rec;
4141 else
4142 work = rec;
4144 #endif
4147 mi->geom.x = rec.x;
4148 mi->geom.y = rec.y;
4149 mi->geom.width = rec.width;
4150 mi->geom.height = rec.height;
4151 mi->work.x = work.x;
4152 mi->work.y = work.y;
4153 mi->work.width = work.width;
4154 mi->work.height = work.height;
4155 mi->mm_width = width_mm;
4156 mi->mm_height = height_mm;
4158 #if GTK_CHECK_VERSION (2, 14, 0)
4159 mi->name = gdk_screen_get_monitor_plug_name (gscreen, i);
4160 #endif
4163 attributes_list = make_monitor_attribute_list (monitors,
4164 n_monitors,
4165 primary_monitor,
4166 monitor_frames,
4167 source);
4168 unblock_input ();
4169 #else /* not USE_GTK */
4171 block_input ();
4172 attributes_list = x_get_monitor_attributes (dpyinfo);
4173 unblock_input ();
4175 #endif /* not USE_GTK */
4177 return attributes_list;
4180 /************************************************************************
4181 X Displays
4182 ************************************************************************/
4185 /* Mapping visual names to visuals. */
4187 static struct visual_class
4189 const char *name;
4190 int class;
4192 visual_classes[] =
4194 {"StaticGray", StaticGray},
4195 {"GrayScale", GrayScale},
4196 {"StaticColor", StaticColor},
4197 {"PseudoColor", PseudoColor},
4198 {"TrueColor", TrueColor},
4199 {"DirectColor", DirectColor},
4200 {NULL, 0}
4204 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4206 /* Value is the screen number of screen SCR. This is a substitute for
4207 the X function with the same name when that doesn't exist. */
4210 XScreenNumberOfScreen (scr)
4211 register Screen *scr;
4213 Display *dpy = scr->display;
4214 int i;
4216 for (i = 0; i < dpy->nscreens; ++i)
4217 if (scr == dpy->screens + i)
4218 break;
4220 return i;
4223 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4226 /* Select the visual that should be used on display DPYINFO. Set
4227 members of DPYINFO appropriately. Called from x_term_init. */
4229 void
4230 select_visual (struct x_display_info *dpyinfo)
4232 Display *dpy = dpyinfo->display;
4233 Screen *screen = dpyinfo->screen;
4234 Lisp_Object value;
4236 /* See if a visual is specified. */
4237 value = display_x_get_resource (dpyinfo,
4238 build_string ("visualClass"),
4239 build_string ("VisualClass"),
4240 Qnil, Qnil);
4241 if (STRINGP (value))
4243 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
4244 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
4245 depth, a decimal number. NAME is compared with case ignored. */
4246 char *s = alloca (SBYTES (value) + 1);
4247 char *dash;
4248 int i, class = -1;
4249 XVisualInfo vinfo;
4251 strcpy (s, SSDATA (value));
4252 dash = strchr (s, '-');
4253 if (dash)
4255 dpyinfo->n_planes = atoi (dash + 1);
4256 *dash = '\0';
4258 else
4259 /* We won't find a matching visual with depth 0, so that
4260 an error will be printed below. */
4261 dpyinfo->n_planes = 0;
4263 /* Determine the visual class. */
4264 for (i = 0; visual_classes[i].name; ++i)
4265 if (xstrcasecmp (s, visual_classes[i].name) == 0)
4267 class = visual_classes[i].class;
4268 break;
4271 /* Look up a matching visual for the specified class. */
4272 if (class == -1
4273 || !XMatchVisualInfo (dpy, XScreenNumberOfScreen (screen),
4274 dpyinfo->n_planes, class, &vinfo))
4275 fatal ("Invalid visual specification `%s'", SDATA (value));
4277 dpyinfo->visual = vinfo.visual;
4279 else
4281 int n_visuals;
4282 XVisualInfo *vinfo, vinfo_template;
4284 dpyinfo->visual = DefaultVisualOfScreen (screen);
4286 vinfo_template.visualid = XVisualIDFromVisual (dpyinfo->visual);
4287 vinfo_template.screen = XScreenNumberOfScreen (screen);
4288 vinfo = XGetVisualInfo (dpy, VisualIDMask | VisualScreenMask,
4289 &vinfo_template, &n_visuals);
4290 if (n_visuals <= 0)
4291 fatal ("Can't get proper X visual info");
4293 dpyinfo->n_planes = vinfo->depth;
4294 XFree (vinfo);
4299 /* Return the X display structure for the display named NAME.
4300 Open a new connection if necessary. */
4302 static struct x_display_info *
4303 x_display_info_for_name (Lisp_Object name)
4305 struct x_display_info *dpyinfo;
4307 CHECK_STRING (name);
4309 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
4310 if (!NILP (Fstring_equal (XCAR (dpyinfo->name_list_element), name)))
4311 return dpyinfo;
4313 /* Use this general default value to start with. */
4314 Vx_resource_name = Vinvocation_name;
4316 validate_x_resource_name ();
4318 dpyinfo = x_term_init (name, 0, SSDATA (Vx_resource_name));
4320 if (dpyinfo == 0)
4321 error ("Cannot connect to X server %s", SDATA (name));
4323 XSETFASTINT (Vwindow_system_version, 11);
4325 return dpyinfo;
4329 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
4330 1, 3, 0,
4331 doc: /* Open a connection to a display server.
4332 DISPLAY is the name of the display to connect to.
4333 Optional second arg XRM-STRING is a string of resources in xrdb format.
4334 If the optional third arg MUST-SUCCEED is non-nil,
4335 terminate Emacs if we can't open the connection.
4336 \(In the Nextstep version, the last two arguments are currently ignored.) */)
4337 (Lisp_Object display, Lisp_Object xrm_string, Lisp_Object must_succeed)
4339 char *xrm_option;
4340 struct x_display_info *dpyinfo;
4342 CHECK_STRING (display);
4343 if (! NILP (xrm_string))
4344 CHECK_STRING (xrm_string);
4346 xrm_option = NILP (xrm_string) ? 0 : SSDATA (xrm_string);
4348 validate_x_resource_name ();
4350 /* This is what opens the connection and sets x_current_display.
4351 This also initializes many symbols, such as those used for input. */
4352 dpyinfo = x_term_init (display, xrm_option,
4353 SSDATA (Vx_resource_name));
4355 if (dpyinfo == 0)
4357 if (!NILP (must_succeed))
4358 fatal ("Cannot connect to X server %s.\n\
4359 Check the DISPLAY environment variable or use `-d'.\n\
4360 Also use the `xauth' program to verify that you have the proper\n\
4361 authorization information needed to connect the X server.\n\
4362 An insecure way to solve the problem may be to use `xhost'.\n",
4363 SDATA (display));
4364 else
4365 error ("Cannot connect to X server %s", SDATA (display));
4368 XSETFASTINT (Vwindow_system_version, 11);
4369 return Qnil;
4372 DEFUN ("x-close-connection", Fx_close_connection,
4373 Sx_close_connection, 1, 1, 0,
4374 doc: /* Close the connection to TERMINAL's X server.
4375 For TERMINAL, specify a terminal object, a frame or a display name (a
4376 string). If TERMINAL is nil, that stands for the selected frame's
4377 terminal. */)
4378 (Lisp_Object terminal)
4380 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4382 if (dpyinfo->reference_count > 0)
4383 error ("Display still has frames on it");
4385 x_delete_terminal (dpyinfo->terminal);
4387 return Qnil;
4390 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
4391 doc: /* Return the list of display names that Emacs has connections to. */)
4392 (void)
4394 Lisp_Object result = Qnil;
4395 struct x_display_info *xdi;
4397 for (xdi = x_display_list; xdi; xdi = xdi->next)
4398 result = Fcons (XCAR (xdi->name_list_element), result);
4400 return result;
4403 DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
4404 doc: /* If ON is non-nil, report X errors as soon as the erring request is made.
4405 This function only has an effect on X Windows. With MS Windows, it is
4406 defined but does nothing.
4408 If ON is nil, allow buffering of requests.
4409 Turning on synchronization prohibits the Xlib routines from buffering
4410 requests and seriously degrades performance, but makes debugging much
4411 easier.
4412 The optional second argument TERMINAL specifies which display to act on.
4413 TERMINAL should be a terminal object, a frame or a display name (a string).
4414 If TERMINAL is omitted or nil, that stands for the selected frame's display. */)
4415 (Lisp_Object on, Lisp_Object terminal)
4417 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4419 XSynchronize (dpyinfo->display, !EQ (on, Qnil));
4421 return Qnil;
4424 /* Wait for responses to all X commands issued so far for frame F. */
4426 void
4427 x_sync (struct frame *f)
4429 block_input ();
4430 XSync (FRAME_X_DISPLAY (f), False);
4431 unblock_input ();
4435 /***********************************************************************
4436 Window properties
4437 ***********************************************************************/
4439 DEFUN ("x-change-window-property", Fx_change_window_property,
4440 Sx_change_window_property, 2, 6, 0,
4441 doc: /* Change window property PROP to VALUE on the X window of FRAME.
4442 PROP must be a string. VALUE may be a string or a list of conses,
4443 numbers and/or strings. If an element in the list is a string, it is
4444 converted to an atom and the value of the atom is used. If an element
4445 is a cons, it is converted to a 32 bit number where the car is the 16
4446 top bits and the cdr is the lower 16 bits.
4448 FRAME nil or omitted means use the selected frame.
4449 If TYPE is given and non-nil, it is the name of the type of VALUE.
4450 If TYPE is not given or nil, the type is STRING.
4451 FORMAT gives the size in bits of each element if VALUE is a list.
4452 It must be one of 8, 16 or 32.
4453 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
4454 If OUTER-P is non-nil, the property is changed for the outer X window of
4455 FRAME. Default is to change on the edit X window. */)
4456 (Lisp_Object prop, Lisp_Object value, Lisp_Object frame,
4457 Lisp_Object type, Lisp_Object format, Lisp_Object outer_p)
4459 struct frame *f = decode_window_system_frame (frame);
4460 Atom prop_atom;
4461 Atom target_type = XA_STRING;
4462 int element_format = 8;
4463 unsigned char *data;
4464 int nelements;
4465 Window w;
4467 CHECK_STRING (prop);
4469 if (! NILP (format))
4471 CHECK_NUMBER (format);
4473 if (XINT (format) != 8 && XINT (format) != 16
4474 && XINT (format) != 32)
4475 error ("FORMAT must be one of 8, 16 or 32");
4476 element_format = XINT (format);
4479 if (CONSP (value))
4481 ptrdiff_t elsize;
4483 nelements = x_check_property_data (value);
4484 if (nelements == -1)
4485 error ("Bad data in VALUE, must be number, string or cons");
4487 /* The man page for XChangeProperty:
4488 "If the specified format is 32, the property data must be a
4489 long array."
4490 This applies even if long is more than 32 bits. The X library
4491 converts to 32 bits before sending to the X server. */
4492 elsize = element_format == 32 ? sizeof (long) : element_format >> 3;
4493 data = xnmalloc (nelements, elsize);
4495 x_fill_property_data (FRAME_X_DISPLAY (f), value, data, element_format);
4497 else
4499 CHECK_STRING (value);
4500 data = SDATA (value);
4501 if (INT_MAX < SBYTES (value))
4502 error ("VALUE too long");
4503 nelements = SBYTES (value);
4506 block_input ();
4507 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (prop), False);
4508 if (! NILP (type))
4510 CHECK_STRING (type);
4511 target_type = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (type), False);
4514 if (! NILP (outer_p)) w = FRAME_OUTER_WINDOW (f);
4515 else w = FRAME_X_WINDOW (f);
4517 XChangeProperty (FRAME_X_DISPLAY (f), w,
4518 prop_atom, target_type, element_format, PropModeReplace,
4519 data, nelements);
4521 if (CONSP (value)) xfree (data);
4523 /* Make sure the property is set when we return. */
4524 XFlush (FRAME_X_DISPLAY (f));
4525 unblock_input ();
4527 return value;
4531 DEFUN ("x-delete-window-property", Fx_delete_window_property,
4532 Sx_delete_window_property, 1, 2, 0,
4533 doc: /* Remove window property PROP from X window of FRAME.
4534 FRAME nil or omitted means use the selected frame. Value is PROP. */)
4535 (Lisp_Object prop, Lisp_Object frame)
4537 struct frame *f = decode_window_system_frame (frame);
4538 Atom prop_atom;
4540 CHECK_STRING (prop);
4541 block_input ();
4542 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (prop), False);
4543 XDeleteProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), prop_atom);
4545 /* Make sure the property is removed when we return. */
4546 XFlush (FRAME_X_DISPLAY (f));
4547 unblock_input ();
4549 return prop;
4553 static Lisp_Object
4554 x_window_property_intern (struct frame *f,
4555 Window target_window,
4556 Atom prop_atom,
4557 Atom target_type,
4558 Lisp_Object delete_p,
4559 Lisp_Object vector_ret_p,
4560 bool *found)
4562 unsigned char *tmp_data = NULL;
4563 Lisp_Object prop_value = Qnil;
4564 Atom actual_type;
4565 int actual_format;
4566 unsigned long actual_size, bytes_remaining;
4567 int rc;
4568 struct gcpro gcpro1;
4570 GCPRO1 (prop_value);
4572 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4573 prop_atom, 0, 0, False, target_type,
4574 &actual_type, &actual_format, &actual_size,
4575 &bytes_remaining, &tmp_data);
4577 *found = actual_format != 0;
4579 if (rc == Success && *found)
4581 XFree (tmp_data);
4582 tmp_data = NULL;
4584 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4585 prop_atom, 0, bytes_remaining,
4586 ! NILP (delete_p), target_type,
4587 &actual_type, &actual_format,
4588 &actual_size, &bytes_remaining,
4589 &tmp_data);
4590 if (rc == Success && tmp_data)
4592 /* The man page for XGetWindowProperty says:
4593 "If the returned format is 32, the returned data is represented
4594 as a long array and should be cast to that type to obtain the
4595 elements."
4596 This applies even if long is more than 32 bits, the X library
4597 converts from 32 bit elements received from the X server to long
4598 and passes the long array to us. Thus, for that case memcpy can not
4599 be used. We convert to a 32 bit type here, because so much code
4600 assume on that.
4602 The bytes and offsets passed to XGetWindowProperty refers to the
4603 property and those are indeed in 32 bit quantities if format is
4604 32. */
4606 if (BITS_PER_LONG > 32 && actual_format == 32)
4608 unsigned long i;
4609 int *idata = (int *) tmp_data;
4610 long *ldata = (long *) tmp_data;
4612 for (i = 0; i < actual_size; ++i)
4613 idata[i] = (int) ldata[i];
4616 if (NILP (vector_ret_p))
4617 prop_value = make_string ((char *) tmp_data, actual_size);
4618 else
4619 prop_value = x_property_data_to_lisp (f,
4620 tmp_data,
4621 actual_type,
4622 actual_format,
4623 actual_size);
4626 if (tmp_data) XFree (tmp_data);
4629 UNGCPRO;
4630 return prop_value;
4633 DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
4634 1, 6, 0,
4635 doc: /* Value is the value of window property PROP on FRAME.
4636 If FRAME is nil or omitted, use the selected frame.
4638 On X Windows, the following optional arguments are also accepted:
4639 If TYPE is nil or omitted, get the property as a string.
4640 Otherwise TYPE is the name of the atom that denotes the type expected.
4641 If SOURCE is non-nil, get the property on that window instead of from
4642 FRAME. The number 0 denotes the root window.
4643 If DELETE-P is non-nil, delete the property after retrieving it.
4644 If VECTOR-RET-P is non-nil, don't return a string but a vector of values.
4646 On MS Windows, this function accepts but ignores those optional arguments.
4648 Value is nil if FRAME hasn't a property with name PROP or if PROP has
4649 no value of TYPE (always string in the MS Windows case). */)
4650 (Lisp_Object prop, Lisp_Object frame, Lisp_Object type,
4651 Lisp_Object source, Lisp_Object delete_p, Lisp_Object vector_ret_p)
4653 struct frame *f = decode_window_system_frame (frame);
4654 Atom prop_atom;
4655 Lisp_Object prop_value = Qnil;
4656 Atom target_type = XA_STRING;
4657 Window target_window = FRAME_X_WINDOW (f);
4658 struct gcpro gcpro1;
4659 bool found;
4661 GCPRO1 (prop_value);
4662 CHECK_STRING (prop);
4664 if (! NILP (source))
4666 CONS_TO_INTEGER (source, Window, target_window);
4667 if (! target_window)
4668 target_window = FRAME_DISPLAY_INFO (f)->root_window;
4671 block_input ();
4672 if (STRINGP (type))
4674 if (strcmp ("AnyPropertyType", SSDATA (type)) == 0)
4675 target_type = AnyPropertyType;
4676 else
4677 target_type = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (type), False);
4680 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (prop), False);
4681 prop_value = x_window_property_intern (f,
4682 target_window,
4683 prop_atom,
4684 target_type,
4685 delete_p,
4686 vector_ret_p,
4687 &found);
4688 if (NILP (prop_value)
4689 && ! found
4690 && NILP (source)
4691 && target_window != FRAME_OUTER_WINDOW (f))
4693 prop_value = x_window_property_intern (f,
4694 FRAME_OUTER_WINDOW (f),
4695 prop_atom,
4696 target_type,
4697 delete_p,
4698 vector_ret_p,
4699 &found);
4703 unblock_input ();
4704 UNGCPRO;
4705 return prop_value;
4710 /***********************************************************************
4711 Busy cursor
4712 ***********************************************************************/
4714 /* Timer function of hourglass_atimer. TIMER is equal to
4715 hourglass_atimer.
4717 Display an hourglass pointer on all frames by mapping the frames'
4718 hourglass_window. Set the hourglass_p flag in the frames'
4719 output_data.x structure to indicate that an hourglass cursor is
4720 shown on the frames. */
4722 void
4723 show_hourglass (struct atimer *timer)
4725 /* The timer implementation will cancel this timer automatically
4726 after this function has run. Set hourglass_atimer to null
4727 so that we know the timer doesn't have to be canceled. */
4728 hourglass_atimer = NULL;
4730 if (!hourglass_shown_p)
4732 Lisp_Object rest, frame;
4734 block_input ();
4736 FOR_EACH_FRAME (rest, frame)
4738 struct frame *f = XFRAME (frame);
4740 if (FRAME_LIVE_P (f) && FRAME_X_P (f) && FRAME_X_DISPLAY (f))
4742 Display *dpy = FRAME_X_DISPLAY (f);
4744 #ifdef USE_X_TOOLKIT
4745 if (f->output_data.x->widget)
4746 #else
4747 if (FRAME_OUTER_WINDOW (f))
4748 #endif
4750 f->output_data.x->hourglass_p = 1;
4752 if (!f->output_data.x->hourglass_window)
4754 unsigned long mask = CWCursor;
4755 XSetWindowAttributes attrs;
4756 #ifdef USE_GTK
4757 Window parent = FRAME_X_WINDOW (f);
4758 #else
4759 Window parent = FRAME_OUTER_WINDOW (f);
4760 #endif
4761 attrs.cursor = f->output_data.x->hourglass_cursor;
4763 f->output_data.x->hourglass_window
4764 = XCreateWindow (dpy, parent,
4765 0, 0, 32000, 32000, 0, 0,
4766 InputOnly,
4767 CopyFromParent,
4768 mask, &attrs);
4771 XMapRaised (dpy, f->output_data.x->hourglass_window);
4772 XFlush (dpy);
4777 hourglass_shown_p = 1;
4778 unblock_input ();
4783 /* Hide the hourglass pointer on all frames, if it is currently
4784 shown. */
4786 void
4787 hide_hourglass (void)
4789 if (hourglass_shown_p)
4791 Lisp_Object rest, frame;
4793 block_input ();
4794 FOR_EACH_FRAME (rest, frame)
4796 struct frame *f = XFRAME (frame);
4798 if (FRAME_X_P (f)
4799 /* Watch out for newly created frames. */
4800 && f->output_data.x->hourglass_window)
4802 XUnmapWindow (FRAME_X_DISPLAY (f),
4803 f->output_data.x->hourglass_window);
4804 /* Sync here because XTread_socket looks at the
4805 hourglass_p flag that is reset to zero below. */
4806 XSync (FRAME_X_DISPLAY (f), False);
4807 f->output_data.x->hourglass_p = 0;
4811 hourglass_shown_p = 0;
4812 unblock_input ();
4818 /***********************************************************************
4819 Tool tips
4820 ***********************************************************************/
4822 static Lisp_Object x_create_tip_frame (struct x_display_info *,
4823 Lisp_Object, Lisp_Object);
4824 static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
4825 Lisp_Object, int, int, int *, int *);
4827 /* The frame of a currently visible tooltip. */
4829 Lisp_Object tip_frame;
4831 /* If non-nil, a timer started that hides the last tooltip when it
4832 fires. */
4834 static Lisp_Object tip_timer;
4835 Window tip_window;
4837 /* If non-nil, a vector of 3 elements containing the last args
4838 with which x-show-tip was called. See there. */
4840 static Lisp_Object last_show_tip_args;
4843 static void
4844 unwind_create_tip_frame (Lisp_Object frame)
4846 Lisp_Object deleted;
4848 deleted = unwind_create_frame (frame);
4849 if (EQ (deleted, Qt))
4851 tip_window = None;
4852 tip_frame = Qnil;
4857 /* Create a frame for a tooltip on the display described by DPYINFO.
4858 PARMS is a list of frame parameters. TEXT is the string to
4859 display in the tip frame. Value is the frame.
4861 Note that functions called here, esp. x_default_parameter can
4862 signal errors, for instance when a specified color name is
4863 undefined. We have to make sure that we're in a consistent state
4864 when this happens. */
4866 static Lisp_Object
4867 x_create_tip_frame (struct x_display_info *dpyinfo,
4868 Lisp_Object parms,
4869 Lisp_Object text)
4871 struct frame *f;
4872 Lisp_Object frame;
4873 Lisp_Object name;
4874 int width, height;
4875 ptrdiff_t count = SPECPDL_INDEX ();
4876 struct gcpro gcpro1, gcpro2, gcpro3;
4877 int face_change_count_before = face_change_count;
4878 Lisp_Object buffer;
4879 struct buffer *old_buffer;
4881 if (!dpyinfo->terminal->name)
4882 error ("Terminal is not live, can't create new frames on it");
4884 parms = Fcopy_alist (parms);
4886 /* Get the name of the frame to use for resource lookup. */
4887 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
4888 if (!STRINGP (name)
4889 && !EQ (name, Qunbound)
4890 && !NILP (name))
4891 error ("Invalid frame name--not a string or nil");
4893 frame = Qnil;
4894 GCPRO3 (parms, name, frame);
4895 f = make_frame (1);
4896 XSETFRAME (frame, f);
4898 buffer = Fget_buffer_create (build_string (" *tip*"));
4899 /* Use set_window_buffer instead of Fset_window_buffer (see
4900 discussion of bug#11984, bug#12025, bug#12026). */
4901 set_window_buffer (FRAME_ROOT_WINDOW (f), buffer, 0, 0);
4902 old_buffer = current_buffer;
4903 set_buffer_internal_1 (XBUFFER (buffer));
4904 bset_truncate_lines (current_buffer, Qnil);
4905 specbind (Qinhibit_read_only, Qt);
4906 specbind (Qinhibit_modification_hooks, Qt);
4907 Ferase_buffer ();
4908 Finsert (1, &text);
4909 set_buffer_internal_1 (old_buffer);
4911 record_unwind_protect (unwind_create_tip_frame, frame);
4913 f->terminal = dpyinfo->terminal;
4915 /* By setting the output method, we're essentially saying that
4916 the frame is live, as per FRAME_LIVE_P. If we get a signal
4917 from this point on, x_destroy_window might screw up reference
4918 counts etc. */
4919 f->output_method = output_x_window;
4920 f->output_data.x = xzalloc (sizeof *f->output_data.x);
4921 f->output_data.x->icon_bitmap = -1;
4922 FRAME_FONTSET (f) = -1;
4923 f->output_data.x->scroll_bar_foreground_pixel = -1;
4924 f->output_data.x->scroll_bar_background_pixel = -1;
4925 #ifdef USE_TOOLKIT_SCROLL_BARS
4926 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
4927 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
4928 #endif /* USE_TOOLKIT_SCROLL_BARS */
4929 f->output_data.x->white_relief.pixel = -1;
4930 f->output_data.x->black_relief.pixel = -1;
4932 fset_icon_name (f, Qnil);
4933 FRAME_DISPLAY_INFO (f) = dpyinfo;
4934 f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
4935 f->output_data.x->explicit_parent = 0;
4937 /* These colors will be set anyway later, but it's important
4938 to get the color reference counts right, so initialize them! */
4940 Lisp_Object black;
4941 struct gcpro gcpro1;
4943 /* Function x_decode_color can signal an error. Make
4944 sure to initialize color slots so that we won't try
4945 to free colors we haven't allocated. */
4946 FRAME_FOREGROUND_PIXEL (f) = -1;
4947 FRAME_BACKGROUND_PIXEL (f) = -1;
4948 f->output_data.x->cursor_pixel = -1;
4949 f->output_data.x->cursor_foreground_pixel = -1;
4950 f->output_data.x->border_pixel = -1;
4951 f->output_data.x->mouse_pixel = -1;
4953 black = build_string ("black");
4954 GCPRO1 (black);
4955 FRAME_FOREGROUND_PIXEL (f)
4956 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4957 FRAME_BACKGROUND_PIXEL (f)
4958 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4959 f->output_data.x->cursor_pixel
4960 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4961 f->output_data.x->cursor_foreground_pixel
4962 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4963 f->output_data.x->border_pixel
4964 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4965 f->output_data.x->mouse_pixel
4966 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4967 UNGCPRO;
4970 /* Set the name; the functions to which we pass f expect the name to
4971 be set. */
4972 if (EQ (name, Qunbound) || NILP (name))
4974 fset_name (f, build_string (dpyinfo->x_id_name));
4975 f->explicit_name = 0;
4977 else
4979 fset_name (f, name);
4980 f->explicit_name = 1;
4981 /* use the frame's title when getting resources for this frame. */
4982 specbind (Qx_resource_name, name);
4985 register_font_driver (&xfont_driver, f);
4986 #ifdef HAVE_FREETYPE
4987 #ifdef HAVE_XFT
4988 register_font_driver (&xftfont_driver, f);
4989 #else /* not HAVE_XFT */
4990 register_font_driver (&ftxfont_driver, f);
4991 #endif /* not HAVE_XFT */
4992 #endif /* HAVE_FREETYPE */
4994 x_default_parameter (f, parms, Qfont_backend, Qnil,
4995 "fontBackend", "FontBackend", RES_TYPE_STRING);
4997 /* Extract the window parameters from the supplied values that are
4998 needed to determine window geometry. */
4999 x_default_font_parameter (f, parms);
5001 x_default_parameter (f, parms, Qborder_width, make_number (0),
5002 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
5004 /* This defaults to 2 in order to match xterm. We recognize either
5005 internalBorderWidth or internalBorder (which is what xterm calls
5006 it). */
5007 if (NILP (Fassq (Qinternal_border_width, parms)))
5009 Lisp_Object value;
5011 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
5012 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
5013 if (! EQ (value, Qunbound))
5014 parms = Fcons (Fcons (Qinternal_border_width, value),
5015 parms);
5018 x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
5019 "internalBorderWidth", "internalBorderWidth",
5020 RES_TYPE_NUMBER);
5021 x_default_parameter (f, parms, Qright_divider_width, make_number (0),
5022 NULL, NULL, RES_TYPE_NUMBER);
5023 x_default_parameter (f, parms, Qbottom_divider_width, make_number (0),
5024 NULL, NULL, RES_TYPE_NUMBER);
5026 /* Also do the stuff which must be set before the window exists. */
5027 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
5028 "foreground", "Foreground", RES_TYPE_STRING);
5029 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
5030 "background", "Background", RES_TYPE_STRING);
5031 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
5032 "pointerColor", "Foreground", RES_TYPE_STRING);
5033 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
5034 "cursorColor", "Foreground", RES_TYPE_STRING);
5035 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
5036 "borderColor", "BorderColor", RES_TYPE_STRING);
5038 #ifdef GLYPH_DEBUG
5039 image_cache_refcount =
5040 FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
5041 dpyinfo_refcount = dpyinfo->reference_count;
5042 #endif /* GLYPH_DEBUG */
5044 /* Init faces before x_default_parameter is called for scroll-bar
5045 parameters because that function calls x_set_scroll_bar_width,
5046 which calls change_frame_size, which calls Fset_window_buffer,
5047 which runs hooks, which call Fvertical_motion. At the end, we
5048 end up in init_iterator with a null face cache, which should not
5049 happen. */
5050 init_frame_faces (f);
5052 f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
5054 x_figure_window_size (f, parms, 0);
5057 XSetWindowAttributes attrs;
5058 unsigned long mask;
5059 Atom type = FRAME_DISPLAY_INFO (f)->Xatom_net_window_type_tooltip;
5061 block_input ();
5062 mask = CWBackPixel | CWOverrideRedirect | CWEventMask;
5063 if (DoesSaveUnders (dpyinfo->screen))
5064 mask |= CWSaveUnder;
5066 /* Window managers look at the override-redirect flag to determine
5067 whether or net to give windows a decoration (Xlib spec, chapter
5068 3.2.8). */
5069 attrs.override_redirect = True;
5070 attrs.save_under = True;
5071 attrs.background_pixel = FRAME_BACKGROUND_PIXEL (f);
5072 /* Arrange for getting MapNotify and UnmapNotify events. */
5073 attrs.event_mask = StructureNotifyMask;
5074 tip_window
5075 = FRAME_X_WINDOW (f)
5076 = XCreateWindow (FRAME_X_DISPLAY (f),
5077 FRAME_DISPLAY_INFO (f)->root_window,
5078 /* x, y, width, height */
5079 0, 0, 1, 1,
5080 /* Border. */
5081 f->border_width,
5082 CopyFromParent, InputOutput, CopyFromParent,
5083 mask, &attrs);
5084 XChangeProperty (FRAME_X_DISPLAY (f), tip_window,
5085 FRAME_DISPLAY_INFO (f)->Xatom_net_window_type,
5086 XA_ATOM, 32, PropModeReplace,
5087 (unsigned char *)&type, 1);
5088 unblock_input ();
5091 x_make_gc (f);
5093 x_default_parameter (f, parms, Qauto_raise, Qnil,
5094 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
5095 x_default_parameter (f, parms, Qauto_lower, Qnil,
5096 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
5097 x_default_parameter (f, parms, Qcursor_type, Qbox,
5098 "cursorType", "CursorType", RES_TYPE_SYMBOL);
5100 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
5101 Change will not be effected unless different from the current
5102 FRAME_LINES (f). */
5103 width = FRAME_COLS (f);
5104 height = FRAME_LINES (f);
5105 SET_FRAME_COLS (f, 0);
5106 FRAME_LINES (f) = 0;
5107 change_frame_size (f, width, height, 1, 0, 0, 0);
5109 /* Add `tooltip' frame parameter's default value. */
5110 if (NILP (Fframe_parameter (frame, Qtooltip)))
5111 Fmodify_frame_parameters (frame, list1 (Fcons (Qtooltip, Qt)));
5113 /* FIXME - can this be done in a similar way to normal frames?
5114 http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
5116 /* Set the `display-type' frame parameter before setting up faces. */
5118 Lisp_Object disptype;
5120 if (FRAME_DISPLAY_INFO (f)->n_planes == 1)
5121 disptype = intern ("mono");
5122 else if (FRAME_DISPLAY_INFO (f)->visual->class == GrayScale
5123 || FRAME_DISPLAY_INFO (f)->visual->class == StaticGray)
5124 disptype = intern ("grayscale");
5125 else
5126 disptype = intern ("color");
5128 if (NILP (Fframe_parameter (frame, Qdisplay_type)))
5129 Fmodify_frame_parameters (frame, list1 (Fcons (Qdisplay_type, disptype)));
5132 /* Set up faces after all frame parameters are known. This call
5133 also merges in face attributes specified for new frames.
5135 Frame parameters may be changed if .Xdefaults contains
5136 specifications for the default font. For example, if there is an
5137 `Emacs.default.attributeBackground: pink', the `background-color'
5138 attribute of the frame get's set, which let's the internal border
5139 of the tooltip frame appear in pink. Prevent this. */
5141 Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
5143 /* Set tip_frame here, so that */
5144 tip_frame = frame;
5145 call2 (Qface_set_after_frame_default, frame, Qnil);
5147 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
5148 Fmodify_frame_parameters (frame, list1 (Fcons (Qbackground_color, bg)));
5151 f->no_split = 1;
5153 UNGCPRO;
5155 /* Now that the frame will be official, it counts as a reference to
5156 its display and terminal. */
5157 FRAME_DISPLAY_INFO (f)->reference_count++;
5158 f->terminal->reference_count++;
5160 /* It is now ok to make the frame official even if we get an error
5161 below. And the frame needs to be on Vframe_list or making it
5162 visible won't work. */
5163 Vframe_list = Fcons (frame, Vframe_list);
5166 /* Setting attributes of faces of the tooltip frame from resources
5167 and similar will increment face_change_count, which leads to the
5168 clearing of all current matrices. Since this isn't necessary
5169 here, avoid it by resetting face_change_count to the value it
5170 had before we created the tip frame. */
5171 face_change_count = face_change_count_before;
5173 /* Discard the unwind_protect. */
5174 return unbind_to (count, frame);
5178 /* Compute where to display tip frame F. PARMS is the list of frame
5179 parameters for F. DX and DY are specified offsets from the current
5180 location of the mouse. WIDTH and HEIGHT are the width and height
5181 of the tooltip. Return coordinates relative to the root window of
5182 the display in *ROOT_X, and *ROOT_Y. */
5184 static void
5185 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)
5187 Lisp_Object left, top;
5188 int win_x, win_y;
5189 Window root, child;
5190 unsigned pmask;
5192 /* User-specified position? */
5193 left = Fcdr (Fassq (Qleft, parms));
5194 top = Fcdr (Fassq (Qtop, parms));
5196 /* Move the tooltip window where the mouse pointer is. Resize and
5197 show it. */
5198 if (!INTEGERP (left) || !INTEGERP (top))
5200 block_input ();
5201 XQueryPointer (FRAME_X_DISPLAY (f), FRAME_DISPLAY_INFO (f)->root_window,
5202 &root, &child, root_x, root_y, &win_x, &win_y, &pmask);
5203 unblock_input ();
5206 if (INTEGERP (top))
5207 *root_y = XINT (top);
5208 else if (*root_y + XINT (dy) <= 0)
5209 *root_y = 0; /* Can happen for negative dy */
5210 else if (*root_y + XINT (dy) + height
5211 <= x_display_pixel_height (FRAME_DISPLAY_INFO (f)))
5212 /* It fits below the pointer */
5213 *root_y += XINT (dy);
5214 else if (height + XINT (dy) <= *root_y)
5215 /* It fits above the pointer. */
5216 *root_y -= height + XINT (dy);
5217 else
5218 /* Put it on the top. */
5219 *root_y = 0;
5221 if (INTEGERP (left))
5222 *root_x = XINT (left);
5223 else if (*root_x + XINT (dx) <= 0)
5224 *root_x = 0; /* Can happen for negative dx */
5225 else if (*root_x + XINT (dx) + width
5226 <= x_display_pixel_width (FRAME_DISPLAY_INFO (f)))
5227 /* It fits to the right of the pointer. */
5228 *root_x += XINT (dx);
5229 else if (width + XINT (dx) <= *root_x)
5230 /* It fits to the left of the pointer. */
5231 *root_x -= width + XINT (dx);
5232 else
5233 /* Put it left-justified on the screen--it ought to fit that way. */
5234 *root_x = 0;
5238 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
5239 doc: /* Show STRING in a "tooltip" window on frame FRAME.
5240 A tooltip window is a small X window displaying a string.
5242 This is an internal function; Lisp code should call `tooltip-show'.
5244 FRAME nil or omitted means use the selected frame.
5246 PARMS is an optional list of frame parameters which can be used to
5247 change the tooltip's appearance.
5249 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
5250 means use the default timeout of 5 seconds.
5252 If the list of frame parameters PARMS contains a `left' parameters,
5253 the tooltip is displayed at that x-position. Otherwise it is
5254 displayed at the mouse position, with offset DX added (default is 5 if
5255 DX isn't specified). Likewise for the y-position; if a `top' frame
5256 parameter is specified, it determines the y-position of the tooltip
5257 window, otherwise it is displayed at the mouse position, with offset
5258 DY added (default is -10).
5260 A tooltip's maximum size is specified by `x-max-tooltip-size'.
5261 Text larger than the specified size is clipped. */)
5262 (Lisp_Object string, Lisp_Object frame, Lisp_Object parms, Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy)
5264 struct frame *f;
5265 struct window *w;
5266 int root_x, root_y;
5267 struct buffer *old_buffer;
5268 struct text_pos pos;
5269 int i, width, height, seen_reversed_p;
5270 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
5271 int old_windows_or_buffers_changed = windows_or_buffers_changed;
5272 ptrdiff_t count = SPECPDL_INDEX ();
5274 specbind (Qinhibit_redisplay, Qt);
5276 GCPRO4 (string, parms, frame, timeout);
5278 CHECK_STRING (string);
5279 if (SCHARS (string) == 0)
5280 string = make_unibyte_string (" ", 1);
5282 f = decode_window_system_frame (frame);
5283 if (NILP (timeout))
5284 timeout = make_number (5);
5285 else
5286 CHECK_NATNUM (timeout);
5288 if (NILP (dx))
5289 dx = make_number (5);
5290 else
5291 CHECK_NUMBER (dx);
5293 if (NILP (dy))
5294 dy = make_number (-10);
5295 else
5296 CHECK_NUMBER (dy);
5298 #ifdef USE_GTK
5299 if (x_gtk_use_system_tooltips)
5301 bool ok;
5303 /* Hide a previous tip, if any. */
5304 Fx_hide_tip ();
5306 block_input ();
5307 ok = xg_prepare_tooltip (f, string, &width, &height);
5308 if (ok)
5310 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
5311 xg_show_tooltip (f, root_x, root_y);
5312 /* This is used in Fx_hide_tip. */
5313 XSETFRAME (tip_frame, f);
5315 unblock_input ();
5316 if (ok) goto start_timer;
5318 #endif /* USE_GTK */
5320 if (NILP (last_show_tip_args))
5321 last_show_tip_args = Fmake_vector (make_number (3), Qnil);
5323 if (!NILP (tip_frame))
5325 Lisp_Object last_string = AREF (last_show_tip_args, 0);
5326 Lisp_Object last_frame = AREF (last_show_tip_args, 1);
5327 Lisp_Object last_parms = AREF (last_show_tip_args, 2);
5329 if (EQ (frame, last_frame)
5330 && !NILP (Fequal (last_string, string))
5331 && !NILP (Fequal (last_parms, parms)))
5333 struct frame *tip_f = XFRAME (tip_frame);
5335 /* Only DX and DY have changed. */
5336 if (!NILP (tip_timer))
5338 Lisp_Object timer = tip_timer;
5339 tip_timer = Qnil;
5340 call1 (Qcancel_timer, timer);
5343 block_input ();
5344 compute_tip_xy (tip_f, parms, dx, dy, FRAME_PIXEL_WIDTH (tip_f),
5345 FRAME_PIXEL_HEIGHT (tip_f), &root_x, &root_y);
5346 XMoveWindow (FRAME_X_DISPLAY (tip_f), FRAME_X_WINDOW (tip_f),
5347 root_x, root_y);
5348 unblock_input ();
5349 goto start_timer;
5353 /* Hide a previous tip, if any. */
5354 Fx_hide_tip ();
5356 ASET (last_show_tip_args, 0, string);
5357 ASET (last_show_tip_args, 1, frame);
5358 ASET (last_show_tip_args, 2, parms);
5360 /* Add default values to frame parameters. */
5361 if (NILP (Fassq (Qname, parms)))
5362 parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
5363 if (NILP (Fassq (Qinternal_border_width, parms)))
5364 parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
5365 if (NILP (Fassq (Qborder_width, parms)))
5366 parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
5367 if (NILP (Fassq (Qbottom_divider_width, parms)))
5368 parms = Fcons (Fcons (Qbottom_divider_width, make_number (0)), parms);
5369 if (NILP (Fassq (Qright_divider_width, parms)))
5370 parms = Fcons (Fcons (Qright_divider_width, make_number (0)), parms);
5371 if (NILP (Fassq (Qborder_color, parms)))
5372 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
5373 if (NILP (Fassq (Qbackground_color, parms)))
5374 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
5375 parms);
5377 /* Create a frame for the tooltip, and record it in the global
5378 variable tip_frame. */
5379 frame = x_create_tip_frame (FRAME_DISPLAY_INFO (f), parms, string);
5380 f = XFRAME (frame);
5382 /* Set up the frame's root window. */
5383 w = XWINDOW (FRAME_ROOT_WINDOW (f));
5384 w->left_col = 0;
5385 w->top_line = 0;
5386 w->pixel_left = 0;
5387 w->pixel_top = 0;
5389 if (CONSP (Vx_max_tooltip_size)
5390 && RANGED_INTEGERP (1, XCAR (Vx_max_tooltip_size), INT_MAX)
5391 && RANGED_INTEGERP (1, XCDR (Vx_max_tooltip_size), INT_MAX))
5393 w->total_cols = XFASTINT (XCAR (Vx_max_tooltip_size));
5394 w->total_lines = XFASTINT (XCDR (Vx_max_tooltip_size));
5396 else
5398 w->total_cols = 80;
5399 w->total_lines = 40;
5402 w->pixel_width = w->total_cols * FRAME_COLUMN_WIDTH (f);
5403 w->pixel_height = w->total_lines * FRAME_LINE_HEIGHT (f);
5405 FRAME_TOTAL_COLS (f) = w->total_cols;
5406 adjust_frame_glyphs (f);
5407 w->pseudo_window_p = 1;
5409 /* Display the tooltip text in a temporary buffer. */
5410 old_buffer = current_buffer;
5411 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->contents));
5412 bset_truncate_lines (current_buffer, Qnil);
5413 clear_glyph_matrix (w->desired_matrix);
5414 clear_glyph_matrix (w->current_matrix);
5415 SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
5416 try_window (FRAME_ROOT_WINDOW (f), pos, TRY_WINDOW_IGNORE_FONTS_CHANGE);
5418 /* Compute width and height of the tooltip. */
5419 width = height = seen_reversed_p = 0;
5420 for (i = 0; i < w->desired_matrix->nrows; ++i)
5422 struct glyph_row *row = &w->desired_matrix->rows[i];
5423 struct glyph *last;
5424 int row_width;
5426 /* Stop at the first empty row at the end. */
5427 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
5428 break;
5430 /* Let the row go over the full width of the frame. */
5431 row->full_width_p = 1;
5433 row_width = row->pixel_width;
5434 if (row->used[TEXT_AREA])
5436 /* There's a glyph at the end of rows that is used to place
5437 the cursor there. Don't include the width of this glyph. */
5438 if (!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;
5444 else
5446 /* There could be a stretch glyph at the beginning of R2L
5447 rows that is produced by extend_face_to_end_of_line.
5448 Don't count that glyph. */
5449 struct glyph *g = row->glyphs[TEXT_AREA];
5451 if (g->type == STRETCH_GLYPH && INTEGERP (g->object))
5453 row_width -= g->pixel_width;
5454 seen_reversed_p = 1;
5459 height += row->height;
5460 width = max (width, row_width);
5463 /* If we've seen partial-length R2L rows, we need to re-adjust the
5464 tool-tip frame width and redisplay it again, to avoid over-wide
5465 tips due to the stretch glyph that extends R2L lines to full
5466 width of the frame. */
5467 if (seen_reversed_p)
5469 /* w->total_cols and FRAME_TOTAL_COLS want the width in columns,
5470 not in pixels. */
5471 w->pixel_width = width;
5472 width /= WINDOW_FRAME_COLUMN_WIDTH (w);
5473 w->total_cols = width;
5474 FRAME_TOTAL_COLS (f) = width;
5475 SET_FRAME_WIDTH (f, width);
5476 adjust_frame_glyphs (f);
5477 clear_glyph_matrix (w->desired_matrix);
5478 clear_glyph_matrix (w->current_matrix);
5479 try_window (FRAME_ROOT_WINDOW (f), pos, 0);
5480 width = height = 0;
5481 /* Recompute width and height of the tooltip. */
5482 for (i = 0; i < w->desired_matrix->nrows; ++i)
5484 struct glyph_row *row = &w->desired_matrix->rows[i];
5485 struct glyph *last;
5486 int row_width;
5488 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
5489 break;
5490 row->full_width_p = 1;
5491 row_width = row->pixel_width;
5492 if (row->used[TEXT_AREA] && !row->reversed_p)
5494 last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
5495 if (INTEGERP (last->object))
5496 row_width -= last->pixel_width;
5499 height += row->height;
5500 width = max (width, row_width);
5504 /* Add the frame's internal border to the width and height the X
5505 window should have. */
5506 height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5507 width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5509 /* Move the tooltip window where the mouse pointer is. Resize and
5510 show it. */
5511 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
5513 block_input ();
5514 XMoveResizeWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5515 root_x, root_y, width, height);
5516 XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
5517 unblock_input ();
5519 /* Draw into the window. */
5520 w->must_be_updated_p = 1;
5521 update_single_window (w, 1);
5523 /* Restore original current buffer. */
5524 set_buffer_internal_1 (old_buffer);
5525 windows_or_buffers_changed = old_windows_or_buffers_changed;
5527 start_timer:
5528 /* Let the tip disappear after timeout seconds. */
5529 tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
5530 intern ("x-hide-tip"));
5532 UNGCPRO;
5533 return unbind_to (count, Qnil);
5537 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
5538 doc: /* Hide the current tooltip window, if there is any.
5539 Value is t if tooltip was open, nil otherwise. */)
5540 (void)
5542 ptrdiff_t count;
5543 Lisp_Object deleted, frame, timer;
5544 struct gcpro gcpro1, gcpro2;
5546 /* Return quickly if nothing to do. */
5547 if (NILP (tip_timer) && NILP (tip_frame))
5548 return Qnil;
5550 frame = tip_frame;
5551 timer = tip_timer;
5552 GCPRO2 (frame, timer);
5553 tip_frame = tip_timer = deleted = Qnil;
5555 count = SPECPDL_INDEX ();
5556 specbind (Qinhibit_redisplay, Qt);
5557 specbind (Qinhibit_quit, Qt);
5559 if (!NILP (timer))
5560 call1 (Qcancel_timer, timer);
5562 #ifdef USE_GTK
5564 /* When using system tooltip, tip_frame is the Emacs frame on which
5565 the tip is shown. */
5566 struct frame *f = XFRAME (frame);
5567 if (FRAME_LIVE_P (f) && xg_hide_tooltip (f))
5568 frame = Qnil;
5570 #endif
5572 if (FRAMEP (frame))
5574 delete_frame (frame, Qnil);
5575 deleted = Qt;
5577 #ifdef USE_LUCID
5578 /* Bloodcurdling hack alert: The Lucid menu bar widget's
5579 redisplay procedure is not called when a tip frame over menu
5580 items is unmapped. Redisplay the menu manually... */
5582 Widget w;
5583 struct frame *f = SELECTED_FRAME ();
5584 w = f->output_data.x->menubar_widget;
5586 if (!DoesSaveUnders (FRAME_DISPLAY_INFO (f)->screen)
5587 && w != NULL)
5589 block_input ();
5590 xlwmenu_redisplay (w);
5591 unblock_input ();
5594 #endif /* USE_LUCID */
5597 UNGCPRO;
5598 return unbind_to (count, deleted);
5603 /***********************************************************************
5604 File selection dialog
5605 ***********************************************************************/
5607 DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog,
5608 Sx_uses_old_gtk_dialog,
5609 0, 0, 0,
5610 doc: /* Return t if the old Gtk+ file selection dialog is used. */)
5611 (void)
5613 #ifdef USE_GTK
5614 if (use_dialog_box
5615 && use_file_dialog
5616 && window_system_available (SELECTED_FRAME ())
5617 && xg_uses_old_file_dialog ())
5618 return Qt;
5619 #endif
5620 return Qnil;
5624 #ifdef USE_MOTIF
5625 /* Callback for "OK" and "Cancel" on file selection dialog. */
5627 static void
5628 file_dialog_cb (Widget widget, XtPointer client_data, XtPointer call_data)
5630 int *result = client_data;
5631 XmAnyCallbackStruct *cb = call_data;
5632 *result = cb->reason;
5636 /* Callback for unmapping a file selection dialog. This is used to
5637 capture the case where a dialog is closed via a window manager's
5638 closer button, for example. Using a XmNdestroyCallback didn't work
5639 in this case. */
5641 static void
5642 file_dialog_unmap_cb (Widget widget, XtPointer client_data, XtPointer call_data)
5644 int *result = client_data;
5645 *result = XmCR_CANCEL;
5648 static void
5649 clean_up_file_dialog (void *arg)
5651 Widget dialog = arg;
5653 /* Clean up. */
5654 block_input ();
5655 XtUnmanageChild (dialog);
5656 XtDestroyWidget (dialog);
5657 x_menu_set_in_use (0);
5658 unblock_input ();
5662 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5663 doc: /* Read file name, prompting with PROMPT in directory DIR.
5664 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5665 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5666 or directory must exist.
5668 This function is only defined on NS, MS Windows, and X Windows with the
5669 Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
5670 Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */)
5671 (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename,
5672 Lisp_Object mustmatch, Lisp_Object only_dir_p)
5674 int result;
5675 struct frame *f = SELECTED_FRAME ();
5676 Lisp_Object file = Qnil;
5677 Lisp_Object decoded_file;
5678 Widget dialog, text, help;
5679 Arg al[10];
5680 int ac = 0;
5681 XmString dir_xmstring, pattern_xmstring;
5682 ptrdiff_t count = SPECPDL_INDEX ();
5683 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5685 check_window_system (f);
5687 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5689 if (popup_activated ())
5690 error ("Trying to use a menu from within a menu-entry");
5692 CHECK_STRING (prompt);
5693 CHECK_STRING (dir);
5695 /* Prevent redisplay. */
5696 specbind (Qinhibit_redisplay, Qt);
5698 block_input ();
5700 /* Create the dialog with PROMPT as title, using DIR as initial
5701 directory and using "*" as pattern. */
5702 dir = Fexpand_file_name (dir, Qnil);
5703 dir_xmstring = XmStringCreateLocalized (SSDATA (dir));
5704 pattern_xmstring = XmStringCreateLocalized ("*");
5706 XtSetArg (al[ac], XmNtitle, SDATA (prompt)); ++ac;
5707 XtSetArg (al[ac], XmNdirectory, dir_xmstring); ++ac;
5708 XtSetArg (al[ac], XmNpattern, pattern_xmstring); ++ac;
5709 XtSetArg (al[ac], XmNresizePolicy, XmRESIZE_GROW); ++ac;
5710 XtSetArg (al[ac], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); ++ac;
5711 dialog = XmCreateFileSelectionDialog (f->output_data.x->widget,
5712 "fsb", al, ac);
5713 XmStringFree (dir_xmstring);
5714 XmStringFree (pattern_xmstring);
5716 /* Add callbacks for OK and Cancel. */
5717 XtAddCallback (dialog, XmNokCallback, file_dialog_cb,
5718 (XtPointer) &result);
5719 XtAddCallback (dialog, XmNcancelCallback, file_dialog_cb,
5720 (XtPointer) &result);
5721 XtAddCallback (dialog, XmNunmapCallback, file_dialog_unmap_cb,
5722 (XtPointer) &result);
5724 /* Remove the help button since we can't display help. */
5725 help = XmFileSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON);
5726 XtUnmanageChild (help);
5728 /* Mark OK button as default. */
5729 XtVaSetValues (XmFileSelectionBoxGetChild (dialog, XmDIALOG_OK_BUTTON),
5730 XmNshowAsDefault, True, NULL);
5732 /* If MUSTMATCH is non-nil, disable the file entry field of the
5733 dialog, so that the user must select a file from the files list
5734 box. We can't remove it because we wouldn't have a way to get at
5735 the result file name, then. */
5736 text = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5737 if (!NILP (mustmatch))
5739 Widget label;
5740 label = XmFileSelectionBoxGetChild (dialog, XmDIALOG_SELECTION_LABEL);
5741 XtSetSensitive (text, False);
5742 XtSetSensitive (label, False);
5745 /* Manage the dialog, so that list boxes get filled. */
5746 XtManageChild (dialog);
5748 if (STRINGP (default_filename))
5750 XmString default_xmstring;
5751 Widget wtext = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5752 Widget list = XmFileSelectionBoxGetChild (dialog, XmDIALOG_LIST);
5754 XmTextPosition last_pos = XmTextFieldGetLastPosition (wtext);
5755 XmTextFieldReplace (wtext, 0, last_pos,
5756 (SSDATA (Ffile_name_nondirectory (default_filename))));
5758 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
5759 must include the path for this to work. */
5761 default_xmstring = XmStringCreateLocalized (SSDATA (default_filename));
5763 if (XmListItemExists (list, default_xmstring))
5765 int item_pos = XmListItemPos (list, default_xmstring);
5766 /* Select the item and scroll it into view. */
5767 XmListSelectPos (list, item_pos, True);
5768 XmListSetPos (list, item_pos);
5771 XmStringFree (default_xmstring);
5774 record_unwind_protect_ptr (clean_up_file_dialog, dialog);
5776 /* Process events until the user presses Cancel or OK. */
5777 x_menu_set_in_use (1);
5778 result = 0;
5779 while (result == 0)
5781 XEvent event;
5782 x_menu_wait_for_event (0);
5783 XtAppNextEvent (Xt_app_con, &event);
5784 if (event.type == KeyPress
5785 && FRAME_X_DISPLAY (f) == event.xkey.display)
5787 KeySym keysym = XLookupKeysym (&event.xkey, 0);
5789 /* Pop down on C-g. */
5790 if (keysym == XK_g && (event.xkey.state & ControlMask) != 0)
5791 XtUnmanageChild (dialog);
5794 (void) x_dispatch_event (&event, FRAME_X_DISPLAY (f));
5797 /* Get the result. */
5798 if (result == XmCR_OK)
5800 XmString text_string;
5801 String data;
5803 XtVaGetValues (dialog, XmNtextString, &text_string, NULL);
5804 XmStringGetLtoR (text_string, XmFONTLIST_DEFAULT_TAG, &data);
5805 XmStringFree (text_string);
5806 file = build_string (data);
5807 XtFree (data);
5809 else
5810 file = Qnil;
5812 unblock_input ();
5813 UNGCPRO;
5815 /* Make "Cancel" equivalent to C-g. */
5816 if (NILP (file))
5817 Fsignal (Qquit, Qnil);
5819 decoded_file = DECODE_FILE (file);
5821 return unbind_to (count, decoded_file);
5824 #endif /* USE_MOTIF */
5826 #ifdef USE_GTK
5828 static void
5829 clean_up_dialog (void)
5831 x_menu_set_in_use (0);
5834 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5835 doc: /* Read file name, prompting with PROMPT in directory DIR.
5836 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5837 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5838 or directory must exist.
5840 This function is only defined on NS, MS Windows, and X Windows with the
5841 Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
5842 Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */)
5843 (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p)
5845 struct frame *f = SELECTED_FRAME ();
5846 char *fn;
5847 Lisp_Object file = Qnil;
5848 Lisp_Object decoded_file;
5849 ptrdiff_t count = SPECPDL_INDEX ();
5850 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5851 char *cdef_file;
5853 check_window_system (f);
5855 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5857 if (popup_activated ())
5858 error ("Trying to use a menu from within a menu-entry");
5860 CHECK_STRING (prompt);
5861 CHECK_STRING (dir);
5863 /* Prevent redisplay. */
5864 specbind (Qinhibit_redisplay, Qt);
5865 record_unwind_protect_void (clean_up_dialog);
5867 block_input ();
5869 if (STRINGP (default_filename))
5870 cdef_file = SSDATA (default_filename);
5871 else
5872 cdef_file = SSDATA (dir);
5874 fn = xg_get_file_name (f, SSDATA (prompt), cdef_file,
5875 ! NILP (mustmatch),
5876 ! NILP (only_dir_p));
5878 if (fn)
5880 file = build_string (fn);
5881 xfree (fn);
5884 unblock_input ();
5885 UNGCPRO;
5887 /* Make "Cancel" equivalent to C-g. */
5888 if (NILP (file))
5889 Fsignal (Qquit, Qnil);
5891 decoded_file = DECODE_FILE (file);
5893 return unbind_to (count, decoded_file);
5897 #ifdef HAVE_FREETYPE
5899 DEFUN ("x-select-font", Fx_select_font, Sx_select_font, 0, 2, 0,
5900 doc: /* Read a font using a GTK dialog.
5901 Return either a font spec (for GTK versions >= 3.2) or a string
5902 containing a GTK-style font name.
5904 FRAME is the frame on which to pop up the font chooser. If omitted or
5905 nil, it defaults to the selected frame. */)
5906 (Lisp_Object frame, Lisp_Object ignored)
5908 struct frame *f = decode_window_system_frame (frame);
5909 Lisp_Object font;
5910 Lisp_Object font_param;
5911 char *default_name = NULL;
5912 struct gcpro gcpro1, gcpro2;
5913 ptrdiff_t count = SPECPDL_INDEX ();
5915 if (popup_activated ())
5916 error ("Trying to use a menu from within a menu-entry");
5918 /* Prevent redisplay. */
5919 specbind (Qinhibit_redisplay, Qt);
5920 record_unwind_protect_void (clean_up_dialog);
5922 block_input ();
5924 GCPRO2 (font_param, font);
5926 XSETFONT (font, FRAME_FONT (f));
5927 font_param = Ffont_get (font, intern (":name"));
5928 if (STRINGP (font_param))
5929 default_name = xstrdup (SSDATA (font_param));
5930 else
5932 font_param = Fframe_parameter (frame, Qfont_param);
5933 if (STRINGP (font_param))
5934 default_name = xstrdup (SSDATA (font_param));
5937 font = xg_get_font (f, default_name);
5938 xfree (default_name);
5940 unblock_input ();
5942 if (NILP (font))
5943 Fsignal (Qquit, Qnil);
5945 return unbind_to (count, font);
5947 #endif /* HAVE_FREETYPE */
5949 #endif /* USE_GTK */
5952 /***********************************************************************
5953 Keyboard
5954 ***********************************************************************/
5956 #ifdef HAVE_XKB
5957 #include <X11/XKBlib.h>
5958 #include <X11/keysym.h>
5959 #endif
5961 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p,
5962 Sx_backspace_delete_keys_p, 0, 1, 0,
5963 doc: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
5964 FRAME nil means use the selected frame.
5965 Value is t if we know that both keys are present, and are mapped to the
5966 usual X keysyms. Value is `lambda' if we cannot determine if both keys are
5967 present and mapped to the usual X keysyms. */)
5968 (Lisp_Object frame)
5970 #ifndef HAVE_XKB
5971 return Qlambda;
5972 #else
5973 XkbDescPtr kb;
5974 struct frame *f = decode_window_system_frame (frame);
5975 Display *dpy = FRAME_X_DISPLAY (f);
5976 Lisp_Object have_keys;
5977 int major, minor, op, event, error_code;
5979 block_input ();
5981 /* Check library version in case we're dynamically linked. */
5982 major = XkbMajorVersion;
5983 minor = XkbMinorVersion;
5984 if (!XkbLibraryVersion (&major, &minor))
5986 unblock_input ();
5987 return Qlambda;
5990 /* Check that the server supports XKB. */
5991 major = XkbMajorVersion;
5992 minor = XkbMinorVersion;
5993 if (!XkbQueryExtension (dpy, &op, &event, &error_code, &major, &minor))
5995 unblock_input ();
5996 return Qlambda;
5999 /* In this code we check that the keyboard has physical keys with names
6000 that start with BKSP (Backspace) and DELE (Delete), and that they
6001 generate keysym XK_BackSpace and XK_Delete respectively.
6002 This function is used to test if normal-erase-is-backspace should be
6003 turned on.
6004 An alternative approach would be to just check if XK_BackSpace and
6005 XK_Delete are mapped to any key. But if any of those are mapped to
6006 some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the
6007 user doesn't know about it, it is better to return false here.
6008 It is more obvious to the user what to do if she/he has two keys
6009 clearly marked with names/symbols and one key does something not
6010 expected (i.e. she/he then tries the other).
6011 The cases where Backspace/Delete is mapped to some other key combination
6012 are rare, and in those cases, normal-erase-is-backspace can be turned on
6013 manually. */
6015 have_keys = Qnil;
6016 kb = XkbGetMap (dpy, XkbAllMapComponentsMask, XkbUseCoreKbd);
6017 if (kb)
6019 int delete_keycode = 0, backspace_keycode = 0, i;
6021 if (XkbGetNames (dpy, XkbAllNamesMask, kb) == Success)
6023 for (i = kb->min_key_code;
6024 (i < kb->max_key_code
6025 && (delete_keycode == 0 || backspace_keycode == 0));
6026 ++i)
6028 /* The XKB symbolic key names can be seen most easily in
6029 the PS file generated by `xkbprint -label name
6030 $DISPLAY'. */
6031 if (memcmp ("DELE", kb->names->keys[i].name, 4) == 0)
6032 delete_keycode = i;
6033 else if (memcmp ("BKSP", kb->names->keys[i].name, 4) == 0)
6034 backspace_keycode = i;
6037 XkbFreeNames (kb, 0, True);
6040 XkbFreeClientMap (kb, 0, True);
6042 if (delete_keycode
6043 && backspace_keycode
6044 && XKeysymToKeycode (dpy, XK_Delete) == delete_keycode
6045 && XKeysymToKeycode (dpy, XK_BackSpace) == backspace_keycode)
6046 have_keys = Qt;
6048 unblock_input ();
6049 return have_keys;
6050 #endif
6055 /***********************************************************************
6056 Initialization
6057 ***********************************************************************/
6059 /* Keep this list in the same order as frame_parms in frame.c.
6060 Use 0 for unsupported frame parameters. */
6062 frame_parm_handler x_frame_parm_handlers[] =
6064 x_set_autoraise,
6065 x_set_autolower,
6066 x_set_background_color,
6067 x_set_border_color,
6068 x_set_border_width,
6069 x_set_cursor_color,
6070 x_set_cursor_type,
6071 x_set_font,
6072 x_set_foreground_color,
6073 x_set_icon_name,
6074 x_set_icon_type,
6075 x_set_internal_border_width,
6076 x_set_right_divider_width,
6077 x_set_bottom_divider_width,
6078 x_set_menu_bar_lines,
6079 x_set_mouse_color,
6080 x_explicitly_set_name,
6081 x_set_scroll_bar_width,
6082 x_set_title,
6083 x_set_unsplittable,
6084 x_set_vertical_scroll_bars,
6085 x_set_visibility,
6086 x_set_tool_bar_lines,
6087 x_set_scroll_bar_foreground,
6088 x_set_scroll_bar_background,
6089 x_set_screen_gamma,
6090 x_set_line_spacing,
6091 x_set_fringe_width,
6092 x_set_fringe_width,
6093 x_set_wait_for_wm,
6094 x_set_fullscreen,
6095 x_set_font_backend,
6096 x_set_alpha,
6097 x_set_sticky,
6098 x_set_tool_bar_position,
6101 void
6102 syms_of_xfns (void)
6104 /* The section below is built by the lisp expression at the top of the file,
6105 just above where these variables are declared. */
6106 /*&&& init symbols here &&&*/
6107 DEFSYM (Qsuppress_icon, "suppress-icon");
6108 DEFSYM (Qundefined_color, "undefined-color");
6109 DEFSYM (Qcompound_text, "compound-text");
6110 DEFSYM (Qcancel_timer, "cancel-timer");
6111 DEFSYM (Qfont_param, "font-parameter");
6112 /* This is the end of symbol initialization. */
6114 Fput (Qundefined_color, Qerror_conditions,
6115 listn (CONSTYPE_PURE, 2, Qundefined_color, Qerror));
6116 Fput (Qundefined_color, Qerror_message,
6117 build_pure_c_string ("Undefined color"));
6119 DEFVAR_LISP ("x-pointer-shape", Vx_pointer_shape,
6120 doc: /* The shape of the pointer when over text.
6121 Changing the value does not affect existing frames
6122 unless you set the mouse color. */);
6123 Vx_pointer_shape = Qnil;
6125 #if 0 /* This doesn't really do anything. */
6126 DEFVAR_LISP ("x-nontext-pointer-shape", Vx_nontext_pointer_shape,
6127 doc: /* The shape of the pointer when not over text.
6128 This variable takes effect when you create a new frame
6129 or when you set the mouse color. */);
6130 #endif
6131 Vx_nontext_pointer_shape = Qnil;
6133 DEFVAR_LISP ("x-hourglass-pointer-shape", Vx_hourglass_pointer_shape,
6134 doc: /* The shape of the pointer when Emacs is busy.
6135 This variable takes effect when you create a new frame
6136 or when you set the mouse color. */);
6137 Vx_hourglass_pointer_shape = Qnil;
6139 #if 0 /* This doesn't really do anything. */
6140 DEFVAR_LISP ("x-mode-pointer-shape", Vx_mode_pointer_shape,
6141 doc: /* The shape of the pointer when over the mode line.
6142 This variable takes effect when you create a new frame
6143 or when you set the mouse color. */);
6144 #endif
6145 Vx_mode_pointer_shape = Qnil;
6147 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
6148 Vx_sensitive_text_pointer_shape,
6149 doc: /* The shape of the pointer when over mouse-sensitive text.
6150 This variable takes effect when you create a new frame
6151 or when you set the mouse color. */);
6152 Vx_sensitive_text_pointer_shape = Qnil;
6154 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
6155 Vx_window_horizontal_drag_shape,
6156 doc: /* Pointer shape to use for indicating a window can be dragged horizontally.
6157 This variable takes effect when you create a new frame
6158 or when you set the mouse color. */);
6159 Vx_window_horizontal_drag_shape = Qnil;
6161 DEFVAR_LISP ("x-window-vertical-drag-cursor",
6162 Vx_window_vertical_drag_shape,
6163 doc: /* Pointer shape to use for indicating a window can be dragged vertically.
6164 This variable takes effect when you create a new frame
6165 or when you set the mouse color. */);
6166 Vx_window_vertical_drag_shape = Qnil;
6168 DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel,
6169 doc: /* A string indicating the foreground color of the cursor box. */);
6170 Vx_cursor_fore_pixel = Qnil;
6172 DEFVAR_LISP ("x-max-tooltip-size", Vx_max_tooltip_size,
6173 doc: /* Maximum size for tooltips.
6174 Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */);
6175 Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
6177 DEFVAR_LISP ("x-no-window-manager", Vx_no_window_manager,
6178 doc: /* Non-nil if no X window manager is in use.
6179 Emacs doesn't try to figure this out; this is always nil
6180 unless you set it to something else. */);
6181 /* We don't have any way to find this out, so set it to nil
6182 and maybe the user would like to set it to t. */
6183 Vx_no_window_manager = Qnil;
6185 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
6186 Vx_pixel_size_width_font_regexp,
6187 doc: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
6189 Since Emacs gets width of a font matching with this regexp from
6190 PIXEL_SIZE field of the name, font finding mechanism gets faster for
6191 such a font. This is especially effective for such large fonts as
6192 Chinese, Japanese, and Korean. */);
6193 Vx_pixel_size_width_font_regexp = Qnil;
6195 /* This is not ifdef:ed, so other builds than GTK can customize it. */
6196 DEFVAR_BOOL ("x-gtk-use-old-file-dialog", x_gtk_use_old_file_dialog,
6197 doc: /* Non-nil means prompt with the old GTK file selection dialog.
6198 If nil or if the file selection dialog is not available, the new GTK file
6199 chooser is used instead. To turn off all file dialogs set the
6200 variable `use-file-dialog'. */);
6201 x_gtk_use_old_file_dialog = 0;
6203 DEFVAR_BOOL ("x-gtk-show-hidden-files", x_gtk_show_hidden_files,
6204 doc: /* If non-nil, the GTK file chooser will by default show hidden files.
6205 Note that this is just the default, there is a toggle button on the file
6206 chooser to show or not show hidden files on a case by case basis. */);
6207 x_gtk_show_hidden_files = 0;
6209 DEFVAR_BOOL ("x-gtk-file-dialog-help-text", x_gtk_file_dialog_help_text,
6210 doc: /* If non-nil, the GTK file chooser will show additional help text.
6211 If more space for files in the file chooser dialog is wanted, set this to nil
6212 to turn the additional text off. */);
6213 x_gtk_file_dialog_help_text = 1;
6215 DEFVAR_BOOL ("x-gtk-whole-detached-tool-bar", x_gtk_whole_detached_tool_bar,
6216 doc: /* If non-nil, a detached tool bar is shown in full.
6217 The default is to just show an arrow and pressing on that arrow shows
6218 the tool bar buttons. */);
6219 x_gtk_whole_detached_tool_bar = 0;
6221 DEFVAR_BOOL ("x-gtk-use-system-tooltips", x_gtk_use_system_tooltips,
6222 doc: /* If non-nil with a Gtk+ built Emacs, the Gtk+ tooltip is used.
6223 Otherwise use Emacs own tooltip implementation.
6224 When using Gtk+ tooltips, the tooltip face is not used. */);
6225 x_gtk_use_system_tooltips = 1;
6227 /* Tell Emacs about this window system. */
6228 Fprovide (Qx, Qnil);
6230 #ifdef USE_X_TOOLKIT
6231 Fprovide (intern_c_string ("x-toolkit"), Qnil);
6232 #ifdef USE_MOTIF
6233 Fprovide (intern_c_string ("motif"), Qnil);
6235 DEFVAR_LISP ("motif-version-string", Vmotif_version_string,
6236 doc: /* Version info for LessTif/Motif. */);
6237 Vmotif_version_string = build_string (XmVERSION_STRING);
6238 #endif /* USE_MOTIF */
6239 #endif /* USE_X_TOOLKIT */
6241 #ifdef USE_GTK
6242 /* Provide x-toolkit also for GTK. Internally GTK does not use Xt so it
6243 is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
6244 But for a user it is a toolkit for X, and indeed, configure
6245 accepts --with-x-toolkit=gtk. */
6246 Fprovide (intern_c_string ("x-toolkit"), Qnil);
6247 Fprovide (intern_c_string ("gtk"), Qnil);
6248 Fprovide (intern_c_string ("move-toolbar"), Qnil);
6250 DEFVAR_LISP ("gtk-version-string", Vgtk_version_string,
6251 doc: /* Version info for GTK+. */);
6253 char gtk_version[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
6254 int len = sprintf (gtk_version, "%d.%d.%d",
6255 GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
6256 Vgtk_version_string = make_pure_string (gtk_version, len, len, 0);
6258 #endif /* USE_GTK */
6260 /* X window properties. */
6261 defsubr (&Sx_change_window_property);
6262 defsubr (&Sx_delete_window_property);
6263 defsubr (&Sx_window_property);
6265 defsubr (&Sxw_display_color_p);
6266 defsubr (&Sx_display_grayscale_p);
6267 defsubr (&Sxw_color_defined_p);
6268 defsubr (&Sxw_color_values);
6269 defsubr (&Sx_server_max_request_size);
6270 defsubr (&Sx_server_vendor);
6271 defsubr (&Sx_server_version);
6272 defsubr (&Sx_display_pixel_width);
6273 defsubr (&Sx_display_pixel_height);
6274 defsubr (&Sx_display_mm_width);
6275 defsubr (&Sx_display_mm_height);
6276 defsubr (&Sx_display_screens);
6277 defsubr (&Sx_display_planes);
6278 defsubr (&Sx_display_color_cells);
6279 defsubr (&Sx_display_visual_class);
6280 defsubr (&Sx_display_backing_store);
6281 defsubr (&Sx_display_save_under);
6282 defsubr (&Sx_display_monitor_attributes_list);
6283 defsubr (&Sx_wm_set_size_hint);
6284 defsubr (&Sx_create_frame);
6285 defsubr (&Sx_open_connection);
6286 defsubr (&Sx_close_connection);
6287 defsubr (&Sx_display_list);
6288 defsubr (&Sx_synchronize);
6289 defsubr (&Sx_backspace_delete_keys_p);
6291 defsubr (&Sx_show_tip);
6292 defsubr (&Sx_hide_tip);
6293 tip_timer = Qnil;
6294 staticpro (&tip_timer);
6295 tip_frame = Qnil;
6296 staticpro (&tip_frame);
6298 last_show_tip_args = Qnil;
6299 staticpro (&last_show_tip_args);
6301 defsubr (&Sx_uses_old_gtk_dialog);
6302 #if defined (USE_MOTIF) || defined (USE_GTK)
6303 defsubr (&Sx_file_dialog);
6304 #endif
6306 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
6307 defsubr (&Sx_select_font);
6308 #endif