Spelling fixes.
[emacs.git] / src / xfns.c
blobaaa75f285fdbd9a9dd1770504857bd23b3556089
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 "menu.h"
28 #include "frame.h"
29 #include "window.h"
30 #include "character.h"
31 #include "buffer.h"
32 #include "intervals.h"
33 #include "dispextern.h"
34 #include "keyboard.h"
35 #include "blockinput.h"
36 #include <epaths.h>
37 #include "charset.h"
38 #include "coding.h"
39 #include "fontset.h"
40 #include "systime.h"
41 #include "termhooks.h"
42 #include "atimer.h"
43 #include "termchar.h"
44 #include "font.h"
46 #include <sys/types.h>
47 #include <sys/stat.h>
49 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */
50 #include "bitmaps/gray.xbm"
51 #else
52 #include <X11/bitmaps/gray>
53 #endif
55 #include "xsettings.h"
57 #ifdef HAVE_XRANDR
58 #include <X11/extensions/Xrandr.h>
59 #endif
60 #ifdef HAVE_XINERAMA
61 #include <X11/extensions/Xinerama.h>
62 #endif
64 #ifdef USE_GTK
65 #include "gtkutil.h"
66 #endif
68 #ifdef USE_X_TOOLKIT
69 #include <X11/Shell.h>
71 #ifndef USE_MOTIF
72 #ifdef HAVE_XAW3D
73 #include <X11/Xaw3d/Paned.h>
74 #include <X11/Xaw3d/Label.h>
75 #else /* !HAVE_XAW3D */
76 #include <X11/Xaw/Paned.h>
77 #include <X11/Xaw/Label.h>
78 #endif /* HAVE_XAW3D */
79 #endif /* USE_MOTIF */
81 #ifdef USG
82 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
83 #include <X11/Xos.h>
84 #define USG
85 #ifdef USG /* Pacify gcc -Wunused-macros. */
86 #endif
87 #else
88 #include <X11/Xos.h>
89 #endif
91 #include "widget.h"
93 #include "../lwlib/lwlib.h"
95 #ifdef USE_MOTIF
96 #include <Xm/Xm.h>
97 #include <Xm/DialogS.h>
98 #include <Xm/FileSB.h>
99 #include <Xm/List.h>
100 #include <Xm/TextF.h>
101 #endif
103 #ifdef USE_LUCID
104 #include "../lwlib/xlwmenu.h"
105 #endif
107 #if !defined (NO_EDITRES)
108 #define HACK_EDITRES
109 extern void _XEditResCheckMessages (Widget, XtPointer, XEvent *, Boolean *);
110 #endif /* not defined NO_EDITRES */
112 /* Unique id counter for widgets created by the Lucid Widget Library. */
114 extern LWLIB_ID widget_id_tick;
116 #ifdef USE_MOTIF
118 #endif /* USE_MOTIF */
120 #endif /* USE_X_TOOLKIT */
122 #ifdef USE_GTK
124 #endif /* USE_GTK */
126 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
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 = decode_live_terminal (object);
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;
332 /* Get the mouse position in frame relative coordinates. */
334 void
335 x_relative_mouse_position (struct frame *f, int *x, int *y)
337 Window root, dummy_window;
338 int dummy;
340 eassert (FRAME_X_P (f));
342 block_input ();
344 XQueryPointer (FRAME_X_DISPLAY (f),
345 DefaultRootWindow (FRAME_X_DISPLAY (f)),
347 /* The root window which contains the pointer. */
348 &root,
350 /* Window pointer is on, not used */
351 &dummy_window,
353 /* The position on that root window. */
354 x, y,
356 /* x/y in dummy_window coordinates, not used. */
357 &dummy, &dummy,
359 /* Modifier keys and pointer buttons, about which
360 we don't care. */
361 (unsigned int *) &dummy);
363 unblock_input ();
365 /* Translate root window coordinates to window coordinates. */
366 *x -= f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
367 *y -= f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
370 /* Gamma-correct COLOR on frame F. */
372 void
373 gamma_correct (struct frame *f, XColor *color)
375 if (f->gamma)
377 color->red = pow (color->red / 65535.0, f->gamma) * 65535.0 + 0.5;
378 color->green = pow (color->green / 65535.0, f->gamma) * 65535.0 + 0.5;
379 color->blue = pow (color->blue / 65535.0, f->gamma) * 65535.0 + 0.5;
384 /* Decide if color named COLOR_NAME is valid for use on frame F. If
385 so, return the RGB values in COLOR. If ALLOC_P,
386 allocate the color. Value is false if COLOR_NAME is invalid, or
387 no color could be allocated. */
389 bool
390 x_defined_color (struct frame *f, const char *color_name,
391 XColor *color, bool alloc_p)
393 bool success_p = 0;
394 Display *dpy = FRAME_X_DISPLAY (f);
395 Colormap cmap = FRAME_X_COLORMAP (f);
397 block_input ();
398 #ifdef USE_GTK
399 success_p = xg_check_special_colors (f, color_name, color);
400 #endif
401 if (!success_p)
402 success_p = XParseColor (dpy, cmap, color_name, color) != 0;
403 if (success_p && alloc_p)
404 success_p = x_alloc_nearest_color (f, cmap, color);
405 unblock_input ();
407 return success_p;
411 /* Return the pixel color value for color COLOR_NAME on frame F. If F
412 is a monochrome frame, return MONO_COLOR regardless of what ARG says.
413 Signal an error if color can't be allocated. */
415 static int
416 x_decode_color (struct frame *f, Lisp_Object color_name, int mono_color)
418 XColor cdef;
420 CHECK_STRING (color_name);
422 #if 0 /* Don't do this. It's wrong when we're not using the default
423 colormap, it makes freeing difficult, and it's probably not
424 an important optimization. */
425 if (strcmp (SDATA (color_name), "black") == 0)
426 return BLACK_PIX_DEFAULT (f);
427 else if (strcmp (SDATA (color_name), "white") == 0)
428 return WHITE_PIX_DEFAULT (f);
429 #endif
431 /* Return MONO_COLOR for monochrome frames. */
432 if (FRAME_DISPLAY_INFO (f)->n_planes == 1)
433 return mono_color;
435 /* x_defined_color is responsible for coping with failures
436 by looking for a near-miss. */
437 if (x_defined_color (f, SSDATA (color_name), &cdef, 1))
438 return cdef.pixel;
440 signal_error ("Undefined color", color_name);
445 /* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
446 the previous value of that parameter, NEW_VALUE is the new value.
447 See also the comment of wait_for_wm in struct x_output. */
449 static void
450 x_set_wait_for_wm (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
452 f->output_data.x->wait_for_wm = !NILP (new_value);
455 static void
456 x_set_tool_bar_position (struct frame *f,
457 Lisp_Object new_value,
458 Lisp_Object old_value)
460 Lisp_Object choice = list4 (Qleft, Qright, Qtop, Qbottom);
462 if (!NILP (Fmemq (new_value, choice)))
464 #ifdef USE_GTK
465 if (!EQ (new_value, old_value))
467 xg_change_toolbar_position (f, new_value);
468 fset_tool_bar_position (f, new_value);
470 #else
471 if (!EQ (new_value, Qtop))
472 error ("The only supported tool bar position is top");
473 #endif
475 else
476 wrong_choice (choice, new_value);
479 #ifdef USE_GTK
481 /* Set icon from FILE for frame F. By using GTK functions the icon
482 may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
485 xg_set_icon (struct frame *f, Lisp_Object file)
487 int result = 0;
488 Lisp_Object found;
490 found = x_find_image_file (file);
492 if (! NILP (found))
494 GdkPixbuf *pixbuf;
495 GError *err = NULL;
496 char *filename = SSDATA (found);
497 block_input ();
499 pixbuf = gdk_pixbuf_new_from_file (filename, &err);
501 if (pixbuf)
503 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
504 pixbuf);
505 g_object_unref (pixbuf);
507 result = 1;
509 else
510 g_error_free (err);
512 unblock_input ();
515 return result;
519 xg_set_icon_from_xpm_data (struct frame *f, const char **data)
521 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data (data);
523 if (!pixbuf)
524 return 0;
526 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), pixbuf);
527 g_object_unref (pixbuf);
528 return 1;
530 #endif /* USE_GTK */
533 /* Functions called only from `x_set_frame_param'
534 to set individual parameters.
536 If FRAME_X_WINDOW (f) is 0,
537 the frame is being created and its X-window does not exist yet.
538 In that case, just record the parameter's new value
539 in the standard place; do not attempt to change the window. */
541 static void
542 x_set_foreground_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
544 struct x_output *x = f->output_data.x;
545 unsigned long fg, old_fg;
547 fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
548 old_fg = FRAME_FOREGROUND_PIXEL (f);
549 FRAME_FOREGROUND_PIXEL (f) = fg;
551 if (FRAME_X_WINDOW (f) != 0)
553 Display *dpy = FRAME_X_DISPLAY (f);
555 block_input ();
556 XSetForeground (dpy, x->normal_gc, fg);
557 XSetBackground (dpy, x->reverse_gc, fg);
559 if (x->cursor_pixel == old_fg)
561 unload_color (f, x->cursor_pixel);
562 x->cursor_pixel = x_copy_color (f, fg);
563 XSetBackground (dpy, x->cursor_gc, x->cursor_pixel);
566 unblock_input ();
568 update_face_from_frame_parameter (f, Qforeground_color, arg);
570 if (FRAME_VISIBLE_P (f))
571 redraw_frame (f);
574 unload_color (f, old_fg);
577 static void
578 x_set_background_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
580 struct x_output *x = f->output_data.x;
581 unsigned long bg;
583 bg = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
584 unload_color (f, FRAME_BACKGROUND_PIXEL (f));
585 FRAME_BACKGROUND_PIXEL (f) = bg;
587 if (FRAME_X_WINDOW (f) != 0)
589 Display *dpy = FRAME_X_DISPLAY (f);
591 block_input ();
592 XSetBackground (dpy, x->normal_gc, bg);
593 XSetForeground (dpy, x->reverse_gc, bg);
594 XSetWindowBackground (dpy, FRAME_X_WINDOW (f), bg);
595 XSetForeground (dpy, x->cursor_gc, bg);
597 #ifdef USE_GTK
598 xg_set_background_color (f, bg);
599 #endif
601 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
602 toolkit scroll bars. */
604 Lisp_Object bar;
605 for (bar = FRAME_SCROLL_BARS (f);
606 !NILP (bar);
607 bar = XSCROLL_BAR (bar)->next)
609 Window window = XSCROLL_BAR (bar)->x_window;
610 XSetWindowBackground (dpy, window, bg);
613 #endif /* USE_TOOLKIT_SCROLL_BARS */
615 unblock_input ();
616 update_face_from_frame_parameter (f, Qbackground_color, arg);
618 if (FRAME_VISIBLE_P (f))
619 redraw_frame (f);
623 static void
624 x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
626 struct x_output *x = f->output_data.x;
627 Display *dpy = FRAME_X_DISPLAY (f);
628 Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
629 Cursor hourglass_cursor, horizontal_drag_cursor, vertical_drag_cursor;
630 unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
631 unsigned long mask_color = FRAME_BACKGROUND_PIXEL (f);
633 /* Don't let pointers be invisible. */
634 if (mask_color == pixel)
636 x_free_colors (f, &pixel, 1);
637 pixel = x_copy_color (f, FRAME_FOREGROUND_PIXEL (f));
640 unload_color (f, x->mouse_pixel);
641 x->mouse_pixel = pixel;
643 block_input ();
645 /* It's not okay to crash if the user selects a screwy cursor. */
646 x_catch_errors (dpy);
648 if (!NILP (Vx_pointer_shape))
650 CHECK_NUMBER (Vx_pointer_shape);
651 cursor = XCreateFontCursor (dpy, XINT (Vx_pointer_shape));
653 else
654 cursor = XCreateFontCursor (dpy, XC_xterm);
655 x_check_errors (dpy, "bad text pointer cursor: %s");
657 if (!NILP (Vx_nontext_pointer_shape))
659 CHECK_NUMBER (Vx_nontext_pointer_shape);
660 nontext_cursor
661 = XCreateFontCursor (dpy, XINT (Vx_nontext_pointer_shape));
663 else
664 nontext_cursor = XCreateFontCursor (dpy, XC_left_ptr);
665 x_check_errors (dpy, "bad nontext pointer cursor: %s");
667 if (!NILP (Vx_hourglass_pointer_shape))
669 CHECK_NUMBER (Vx_hourglass_pointer_shape);
670 hourglass_cursor
671 = XCreateFontCursor (dpy, XINT (Vx_hourglass_pointer_shape));
673 else
674 hourglass_cursor = XCreateFontCursor (dpy, XC_watch);
675 x_check_errors (dpy, "bad hourglass pointer cursor: %s");
677 if (!NILP (Vx_mode_pointer_shape))
679 CHECK_NUMBER (Vx_mode_pointer_shape);
680 mode_cursor = XCreateFontCursor (dpy, XINT (Vx_mode_pointer_shape));
682 else
683 mode_cursor = XCreateFontCursor (dpy, XC_xterm);
684 x_check_errors (dpy, "bad modeline pointer cursor: %s");
686 if (!NILP (Vx_sensitive_text_pointer_shape))
688 CHECK_NUMBER (Vx_sensitive_text_pointer_shape);
689 hand_cursor
690 = XCreateFontCursor (dpy, XINT (Vx_sensitive_text_pointer_shape));
692 else
693 hand_cursor = XCreateFontCursor (dpy, XC_hand2);
695 if (!NILP (Vx_window_horizontal_drag_shape))
697 CHECK_TYPE_RANGED_INTEGER (unsigned, Vx_window_horizontal_drag_shape);
698 horizontal_drag_cursor
699 = XCreateFontCursor (dpy, XINT (Vx_window_horizontal_drag_shape));
701 else
702 horizontal_drag_cursor
703 = XCreateFontCursor (dpy, XC_sb_h_double_arrow);
705 if (!NILP (Vx_window_vertical_drag_shape))
707 CHECK_NUMBER (Vx_window_vertical_drag_shape);
708 vertical_drag_cursor
709 = XCreateFontCursor (dpy, XINT (Vx_window_vertical_drag_shape));
711 else
712 vertical_drag_cursor
713 = XCreateFontCursor (dpy, XC_sb_v_double_arrow);
715 /* Check and report errors with the above calls. */
716 x_check_errors (dpy, "can't set cursor shape: %s");
717 x_uncatch_errors ();
720 XColor fore_color, back_color;
722 fore_color.pixel = x->mouse_pixel;
723 x_query_color (f, &fore_color);
724 back_color.pixel = mask_color;
725 x_query_color (f, &back_color);
727 XRecolorCursor (dpy, cursor, &fore_color, &back_color);
728 XRecolorCursor (dpy, nontext_cursor, &fore_color, &back_color);
729 XRecolorCursor (dpy, mode_cursor, &fore_color, &back_color);
730 XRecolorCursor (dpy, hand_cursor, &fore_color, &back_color);
731 XRecolorCursor (dpy, hourglass_cursor, &fore_color, &back_color);
732 XRecolorCursor (dpy, horizontal_drag_cursor, &fore_color, &back_color);
733 XRecolorCursor (dpy, vertical_drag_cursor, &fore_color, &back_color);
736 if (FRAME_X_WINDOW (f) != 0)
737 XDefineCursor (dpy, FRAME_X_WINDOW (f),
738 f->output_data.x->current_cursor = cursor);
740 if (cursor != x->text_cursor
741 && x->text_cursor != 0)
742 XFreeCursor (dpy, x->text_cursor);
743 x->text_cursor = cursor;
745 if (nontext_cursor != x->nontext_cursor
746 && x->nontext_cursor != 0)
747 XFreeCursor (dpy, x->nontext_cursor);
748 x->nontext_cursor = nontext_cursor;
750 if (hourglass_cursor != x->hourglass_cursor
751 && x->hourglass_cursor != 0)
752 XFreeCursor (dpy, x->hourglass_cursor);
753 x->hourglass_cursor = hourglass_cursor;
755 if (mode_cursor != x->modeline_cursor
756 && x->modeline_cursor != 0)
757 XFreeCursor (dpy, f->output_data.x->modeline_cursor);
758 x->modeline_cursor = mode_cursor;
760 if (hand_cursor != x->hand_cursor
761 && x->hand_cursor != 0)
762 XFreeCursor (dpy, x->hand_cursor);
763 x->hand_cursor = hand_cursor;
765 if (horizontal_drag_cursor != x->horizontal_drag_cursor
766 && x->horizontal_drag_cursor != 0)
767 XFreeCursor (dpy, x->horizontal_drag_cursor);
768 x->horizontal_drag_cursor = horizontal_drag_cursor;
770 if (vertical_drag_cursor != x->vertical_drag_cursor
771 && x->vertical_drag_cursor != 0)
772 XFreeCursor (dpy, x->vertical_drag_cursor);
773 x->vertical_drag_cursor = vertical_drag_cursor;
775 XFlush (dpy);
776 unblock_input ();
778 update_face_from_frame_parameter (f, Qmouse_color, arg);
781 static void
782 x_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
784 unsigned long fore_pixel, pixel;
785 bool fore_pixel_allocated_p = 0, pixel_allocated_p = 0;
786 struct x_output *x = f->output_data.x;
788 if (!NILP (Vx_cursor_fore_pixel))
790 fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
791 WHITE_PIX_DEFAULT (f));
792 fore_pixel_allocated_p = 1;
794 else
795 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
797 pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
798 pixel_allocated_p = 1;
800 /* Make sure that the cursor color differs from the background color. */
801 if (pixel == FRAME_BACKGROUND_PIXEL (f))
803 if (pixel_allocated_p)
805 x_free_colors (f, &pixel, 1);
806 pixel_allocated_p = 0;
809 pixel = x->mouse_pixel;
810 if (pixel == fore_pixel)
812 if (fore_pixel_allocated_p)
814 x_free_colors (f, &fore_pixel, 1);
815 fore_pixel_allocated_p = 0;
817 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
821 unload_color (f, x->cursor_foreground_pixel);
822 if (!fore_pixel_allocated_p)
823 fore_pixel = x_copy_color (f, fore_pixel);
824 x->cursor_foreground_pixel = fore_pixel;
826 unload_color (f, x->cursor_pixel);
827 if (!pixel_allocated_p)
828 pixel = x_copy_color (f, pixel);
829 x->cursor_pixel = pixel;
831 if (FRAME_X_WINDOW (f) != 0)
833 block_input ();
834 XSetBackground (FRAME_X_DISPLAY (f), x->cursor_gc, x->cursor_pixel);
835 XSetForeground (FRAME_X_DISPLAY (f), x->cursor_gc, fore_pixel);
836 unblock_input ();
838 if (FRAME_VISIBLE_P (f))
840 x_update_cursor (f, 0);
841 x_update_cursor (f, 1);
845 update_face_from_frame_parameter (f, Qcursor_color, arg);
848 /* Set the border-color of frame F to pixel value PIX.
849 Note that this does not fully take effect if done before
850 F has an x-window. */
852 static void
853 x_set_border_pixel (struct frame *f, int pix)
855 unload_color (f, f->output_data.x->border_pixel);
856 f->output_data.x->border_pixel = pix;
858 if (FRAME_X_WINDOW (f) != 0 && f->border_width > 0)
860 block_input ();
861 XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), pix);
862 unblock_input ();
864 if (FRAME_VISIBLE_P (f))
865 redraw_frame (f);
869 /* Set the border-color of frame F to value described by ARG.
870 ARG can be a string naming a color.
871 The border-color is used for the border that is drawn by the X server.
872 Note that this does not fully take effect if done before
873 F has an x-window; it must be redone when the window is created.
875 Note: this is done in two routines because of the way X10 works.
877 Note: under X11, this is normally the province of the window manager,
878 and so emacs's border colors may be overridden. */
880 static void
881 x_set_border_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
883 int pix;
885 CHECK_STRING (arg);
886 pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
887 x_set_border_pixel (f, pix);
888 update_face_from_frame_parameter (f, Qborder_color, arg);
892 static void
893 x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
895 set_frame_cursor_types (f, arg);
898 static void
899 x_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
901 int result;
903 if (STRINGP (arg))
905 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
906 return;
908 else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
909 return;
911 block_input ();
912 if (NILP (arg))
913 result = x_text_icon (f,
914 SSDATA ((!NILP (f->icon_name)
915 ? f->icon_name
916 : f->name)));
917 else
918 result = x_bitmap_icon (f, arg);
920 if (result)
922 unblock_input ();
923 error ("No icon window available");
926 XFlush (FRAME_X_DISPLAY (f));
927 unblock_input ();
930 static void
931 x_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
933 int result;
935 if (STRINGP (arg))
937 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
938 return;
940 else if (!NILP (arg) || NILP (oldval))
941 return;
943 fset_icon_name (f, arg);
945 if (f->output_data.x->icon_bitmap != 0)
946 return;
948 block_input ();
950 result = x_text_icon (f,
951 SSDATA ((!NILP (f->icon_name)
952 ? f->icon_name
953 : !NILP (f->title)
954 ? f->title
955 : f->name)));
957 if (result)
959 unblock_input ();
960 error ("No icon window available");
963 XFlush (FRAME_X_DISPLAY (f));
964 unblock_input ();
968 static void
969 x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
971 int nlines;
972 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
973 int olines = FRAME_MENU_BAR_LINES (f);
974 #endif
976 /* Right now, menu bars don't work properly in minibuf-only frames;
977 most of the commands try to apply themselves to the minibuffer
978 frame itself, and get an error because you can't switch buffers
979 in or split the minibuffer window. */
980 if (FRAME_MINIBUF_ONLY_P (f))
981 return;
983 if (TYPE_RANGED_INTEGERP (int, value))
984 nlines = XINT (value);
985 else
986 nlines = 0;
988 /* Make sure we redisplay all windows in this frame. */
989 windows_or_buffers_changed = 59;
991 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
992 FRAME_MENU_BAR_LINES (f) = 0;
993 FRAME_MENU_BAR_HEIGHT (f) = 0;
994 if (nlines)
996 FRAME_EXTERNAL_MENU_BAR (f) = 1;
997 if (FRAME_X_P (f) && f->output_data.x->menubar_widget == 0)
998 /* Make sure next redisplay shows the menu bar. */
999 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = 1;
1001 else
1003 if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
1004 free_frame_menubar (f);
1005 FRAME_EXTERNAL_MENU_BAR (f) = 0;
1006 if (FRAME_X_P (f))
1007 f->output_data.x->menubar_widget = 0;
1009 #else /* not USE_X_TOOLKIT && not USE_GTK */
1010 FRAME_MENU_BAR_LINES (f) = nlines;
1011 FRAME_MENU_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
1012 adjust_frame_size (f, -1, -1, 2, 1, Qmenu_bar_lines);
1013 if (FRAME_X_WINDOW (f))
1014 x_clear_under_internal_border (f);
1016 /* If the menu bar height gets changed, the internal border below
1017 the top margin has to be cleared. Also, if the menu bar gets
1018 larger, the area for the added lines has to be cleared except for
1019 the first menu bar line that is to be drawn later. */
1020 if (nlines != olines)
1022 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1023 int width = FRAME_PIXEL_WIDTH (f);
1024 int y;
1026 /* height can be zero here. */
1027 if (FRAME_X_WINDOW (f) && height > 0 && width > 0)
1029 y = FRAME_TOP_MARGIN_HEIGHT (f);
1031 block_input ();
1032 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1033 0, y, width, height);
1034 unblock_input ();
1037 if (nlines > 1 && nlines > olines)
1039 y = (olines == 0 ? 1 : olines) * FRAME_LINE_HEIGHT (f);
1040 height = nlines * FRAME_LINE_HEIGHT (f) - y;
1042 block_input ();
1043 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1044 0, y, width, height);
1045 unblock_input ();
1048 if (nlines == 0 && WINDOWP (f->menu_bar_window))
1049 clear_glyph_matrix (XWINDOW (f->menu_bar_window)->current_matrix);
1051 #endif /* not USE_X_TOOLKIT && not USE_GTK */
1052 adjust_frame_glyphs (f);
1053 run_window_configuration_change_hook (f);
1057 /* Set the number of lines used for the tool bar of frame F to VALUE.
1058 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1059 is the old number of tool bar lines. This function changes the
1060 height of all windows on frame F to match the new tool bar height.
1061 The frame's height doesn't change. */
1063 static void
1064 x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1066 int nlines;
1068 /* Treat tool bars like menu bars. */
1069 if (FRAME_MINIBUF_ONLY_P (f))
1070 return;
1072 /* Use VALUE only if an int >= 0. */
1073 if (RANGED_INTEGERP (0, value, INT_MAX))
1074 nlines = XFASTINT (value);
1075 else
1076 nlines = 0;
1078 #ifdef USE_GTK
1079 x_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
1080 #else /* !USE_GTK */
1081 if (nlines == 0)
1082 x_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
1083 else
1085 f->n_tool_bar_rows = 0;
1086 FRAME_TOOL_BAR_LINES (f) = nlines;
1087 adjust_frame_glyphs (f);
1088 SET_FRAME_GARBAGED (f);
1090 #endif /* USE_GTK */
1094 /* Set the pixel height of the tool bar of frame F to HEIGHT. */
1095 void
1096 x_change_tool_bar_height (struct frame *f, int height)
1098 #ifdef USE_GTK
1099 FRAME_TOOL_BAR_LINES (f) = 0;
1100 FRAME_TOOL_BAR_HEIGHT (f) = 0;
1101 if (height)
1103 FRAME_EXTERNAL_TOOL_BAR (f) = 1;
1104 if (FRAME_X_P (f) && f->output_data.x->toolbar_widget == 0)
1105 /* Make sure next redisplay shows the tool bar. */
1106 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = 1;
1107 update_frame_tool_bar (f);
1109 else
1111 if (FRAME_EXTERNAL_TOOL_BAR (f))
1112 free_frame_tool_bar (f);
1113 FRAME_EXTERNAL_TOOL_BAR (f) = 0;
1115 #else /* !USE_GTK */
1116 int unit = FRAME_LINE_HEIGHT (f);
1117 int old_height = FRAME_TOOL_BAR_HEIGHT (f);
1118 int lines = (height + unit - 1) / unit;
1120 /* Make sure we redisplay all windows in this frame. */
1121 windows_or_buffers_changed = 60;
1124 /* Recalculate tool bar and frame text sizes. */
1125 FRAME_TOOL_BAR_HEIGHT (f) = height;
1126 FRAME_TOOL_BAR_LINES (f) = lines;
1127 /** FRAME_TEXT_HEIGHT (f) **/
1128 /** = FRAME_PIXEL_TO_TEXT_HEIGHT (f, FRAME_PIXEL_HEIGHT (f)); **/
1129 /** FRAME_LINES (f) **/
1130 /** = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, FRAME_PIXEL_HEIGHT (f)); **/
1131 /* Store the `tool-bar-lines' and `height' frame parameters. */
1132 store_frame_param (f, Qtool_bar_lines, make_number (lines));
1133 store_frame_param (f, Qheight, make_number (FRAME_LINES (f)));
1135 /* We also have to make sure that the internal border at the top of
1136 the frame, below the menu bar or tool bar, is redrawn when the
1137 tool bar disappears. This is so because the internal border is
1138 below the tool bar if one is displayed, but is below the menu bar
1139 if there isn't a tool bar. The tool bar draws into the area
1140 below the menu bar. */
1141 if (FRAME_X_WINDOW (f) && FRAME_TOOL_BAR_HEIGHT (f) == 0)
1143 clear_frame (f);
1144 clear_current_matrices (f);
1147 if ((height < old_height) && WINDOWP (f->tool_bar_window))
1148 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1150 /* Recalculate toolbar height. */
1151 f->n_tool_bar_rows = 0;
1153 adjust_frame_size (f, -1, -1, (old_height == 0 || height == 0) ? 2 : 4, 0,
1154 Qtool_bar_lines);
1156 if (FRAME_X_WINDOW (f))
1157 x_clear_under_internal_border (f);
1159 #endif /* USE_GTK */
1163 static void
1164 x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1166 int border;
1168 CHECK_TYPE_RANGED_INTEGER (int, arg);
1169 border = max (XINT (arg), 0);
1171 if (border != FRAME_INTERNAL_BORDER_WIDTH (f))
1173 FRAME_INTERNAL_BORDER_WIDTH (f) = border;
1175 #ifdef USE_X_TOOLKIT
1176 if (FRAME_X_OUTPUT (f)->edit_widget)
1177 widget_store_internal_border (FRAME_X_OUTPUT (f)->edit_widget);
1178 #endif
1180 if (FRAME_X_WINDOW (f) != 0)
1182 adjust_frame_size (f, -1, -1, 3, 0, Qinternal_border_width);
1184 #ifdef USE_GTK
1185 xg_clear_under_internal_border (f);
1186 #else
1187 x_clear_under_internal_border (f);
1188 #endif
1195 /* Set the foreground color for scroll bars on frame F to VALUE.
1196 VALUE should be a string, a color name. If it isn't a string or
1197 isn't a valid color name, do nothing. OLDVAL is the old value of
1198 the frame parameter. */
1200 static void
1201 x_set_scroll_bar_foreground (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1203 unsigned long pixel;
1205 if (STRINGP (value))
1206 pixel = x_decode_color (f, value, BLACK_PIX_DEFAULT (f));
1207 else
1208 pixel = -1;
1210 if (f->output_data.x->scroll_bar_foreground_pixel != -1)
1211 unload_color (f, f->output_data.x->scroll_bar_foreground_pixel);
1213 f->output_data.x->scroll_bar_foreground_pixel = pixel;
1214 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1216 /* Remove all scroll bars because they have wrong colors. */
1217 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1218 (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1219 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1220 (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1222 update_face_from_frame_parameter (f, Qscroll_bar_foreground, value);
1223 redraw_frame (f);
1228 /* Set the background color for scroll bars on frame F to VALUE VALUE
1229 should be a string, a color name. If it isn't a string or isn't a
1230 valid color name, do nothing. OLDVAL is the old value of the frame
1231 parameter. */
1233 static void
1234 x_set_scroll_bar_background (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1236 unsigned long pixel;
1238 if (STRINGP (value))
1239 pixel = x_decode_color (f, value, WHITE_PIX_DEFAULT (f));
1240 else
1241 pixel = -1;
1243 if (f->output_data.x->scroll_bar_background_pixel != -1)
1244 unload_color (f, f->output_data.x->scroll_bar_background_pixel);
1246 #if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
1247 /* Scrollbar shadow colors. */
1248 if (f->output_data.x->scroll_bar_top_shadow_pixel != -1)
1250 unload_color (f, f->output_data.x->scroll_bar_top_shadow_pixel);
1251 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
1253 if (f->output_data.x->scroll_bar_bottom_shadow_pixel != -1)
1255 unload_color (f, f->output_data.x->scroll_bar_bottom_shadow_pixel);
1256 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
1258 #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
1260 f->output_data.x->scroll_bar_background_pixel = pixel;
1261 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1263 /* Remove all scroll bars because they have wrong colors. */
1264 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1265 (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1266 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1267 (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1269 update_face_from_frame_parameter (f, Qscroll_bar_background, value);
1270 redraw_frame (f);
1275 /* Encode Lisp string STRING as a text in a format appropriate for
1276 XICCC (X Inter Client Communication Conventions).
1278 This can call Lisp code, so callers must GCPRO.
1280 If STRING contains only ASCII characters, do no conversion and
1281 return the string data of STRING. Otherwise, encode the text by
1282 CODING_SYSTEM, and return a newly allocated memory area which
1283 should be freed by `xfree' by a caller.
1285 Store the byte length of resulting text in *TEXT_BYTES.
1287 If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
1288 which means that the `encoding' of the result can be `STRING'.
1289 Otherwise store 0 in *STRINGP, which means that the `encoding' of
1290 the result should be `COMPOUND_TEXT'. */
1292 static unsigned char *
1293 x_encode_text (Lisp_Object string, Lisp_Object coding_system,
1294 ptrdiff_t *text_bytes, int *stringp, bool *freep)
1296 int result = string_xstring_p (string);
1297 struct coding_system coding;
1299 if (result == 0)
1301 /* No multibyte character in OBJ. We need not encode it. */
1302 *text_bytes = SBYTES (string);
1303 *stringp = 1;
1304 *freep = 0;
1305 return SDATA (string);
1308 setup_coding_system (coding_system, &coding);
1309 coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK);
1310 /* We suppress producing escape sequences for composition. */
1311 coding.common_flags &= ~CODING_ANNOTATION_MASK;
1312 coding.destination = xnmalloc (SCHARS (string), 2);
1313 coding.dst_bytes = SCHARS (string) * 2;
1314 encode_coding_object (&coding, string, 0, 0,
1315 SCHARS (string), SBYTES (string), Qnil);
1316 *text_bytes = coding.produced;
1317 *stringp = (result == 1 || !EQ (coding_system, Qcompound_text));
1318 *freep = 1;
1319 return coding.destination;
1323 /* Set the WM name to NAME for frame F. Also set the icon name.
1324 If the frame already has an icon name, use that, otherwise set the
1325 icon name to NAME. */
1327 static void
1328 x_set_name_internal (struct frame *f, Lisp_Object name)
1330 if (FRAME_X_WINDOW (f))
1332 block_input ();
1334 XTextProperty text, icon;
1335 ptrdiff_t bytes;
1336 int stringp;
1337 bool do_free_icon_value = 0, do_free_text_value = 0;
1338 Lisp_Object coding_system;
1339 Lisp_Object encoded_name;
1340 Lisp_Object encoded_icon_name;
1341 struct gcpro gcpro1;
1343 /* As ENCODE_UTF_8 may cause GC and relocation of string data,
1344 we use it before x_encode_text that may return string data. */
1345 GCPRO1 (name);
1346 encoded_name = ENCODE_UTF_8 (name);
1347 UNGCPRO;
1349 coding_system = Qcompound_text;
1350 /* Note: Encoding strategy
1352 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1353 text.encoding. But, there are non-internationalized window
1354 managers which don't support that encoding. So, if NAME
1355 contains only ASCII and 8859-1 characters, encode it by
1356 iso-latin-1, and use "STRING" in text.encoding hoping that
1357 such window managers at least analyze this format correctly,
1358 i.e. treat 8-bit bytes as 8859-1 characters.
1360 We may also be able to use "UTF8_STRING" in text.encoding
1361 in the future which can encode all Unicode characters.
1362 But, for the moment, there's no way to know that the
1363 current window manager supports it or not.
1365 Either way, we also set the _NET_WM_NAME and _NET_WM_ICON_NAME
1366 properties. Per the EWMH specification, those two properties
1367 are always UTF8_STRING. This matches what gtk_window_set_title()
1368 does in the USE_GTK case. */
1369 text.value = x_encode_text (name, coding_system, &bytes,
1370 &stringp, &do_free_text_value);
1371 text.encoding = (stringp ? XA_STRING
1372 : FRAME_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1373 text.format = 8;
1374 text.nitems = bytes;
1376 if (!STRINGP (f->icon_name))
1378 icon = text;
1379 encoded_icon_name = encoded_name;
1381 else
1383 /* See the above comment "Note: Encoding strategy". */
1384 icon.value = x_encode_text (f->icon_name, coding_system, &bytes,
1385 &stringp, &do_free_icon_value);
1386 icon.encoding = (stringp ? XA_STRING
1387 : FRAME_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1388 icon.format = 8;
1389 icon.nitems = bytes;
1391 encoded_icon_name = ENCODE_UTF_8 (f->icon_name);
1394 #ifdef USE_GTK
1395 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
1396 SSDATA (encoded_name));
1397 #else /* not USE_GTK */
1398 XSetWMName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &text);
1399 XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
1400 FRAME_DISPLAY_INFO (f)->Xatom_net_wm_name,
1401 FRAME_DISPLAY_INFO (f)->Xatom_UTF8_STRING,
1402 8, PropModeReplace,
1403 SDATA (encoded_name),
1404 SBYTES (encoded_name));
1405 #endif /* not USE_GTK */
1407 XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &icon);
1408 XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
1409 FRAME_DISPLAY_INFO (f)->Xatom_net_wm_icon_name,
1410 FRAME_DISPLAY_INFO (f)->Xatom_UTF8_STRING,
1411 8, PropModeReplace,
1412 SDATA (encoded_icon_name),
1413 SBYTES (encoded_icon_name));
1415 if (do_free_icon_value)
1416 xfree (icon.value);
1417 if (do_free_text_value)
1418 xfree (text.value);
1420 unblock_input ();
1424 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1425 x_id_name.
1427 If EXPLICIT is true, that indicates that lisp code is setting the
1428 name; if NAME is a string, set F's name to NAME and set
1429 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1431 If EXPLICIT is false, that indicates that Emacs redisplay code is
1432 suggesting a new name, which lisp code should override; if
1433 F->explicit_name is set, ignore the new name; otherwise, set it. */
1435 static void
1436 x_set_name (struct frame *f, Lisp_Object name, bool explicit)
1438 /* Make sure that requests from lisp code override requests from
1439 Emacs redisplay code. */
1440 if (explicit)
1442 /* If we're switching from explicit to implicit, we had better
1443 update the mode lines and thereby update the title. */
1444 if (f->explicit_name && NILP (name))
1445 update_mode_lines = 37;
1447 f->explicit_name = ! NILP (name);
1449 else if (f->explicit_name)
1450 return;
1452 /* If NAME is nil, set the name to the x_id_name. */
1453 if (NILP (name))
1455 /* Check for no change needed in this very common case
1456 before we do any consing. */
1457 if (!strcmp (FRAME_DISPLAY_INFO (f)->x_id_name,
1458 SSDATA (f->name)))
1459 return;
1460 name = build_string (FRAME_DISPLAY_INFO (f)->x_id_name);
1462 else
1463 CHECK_STRING (name);
1465 /* Don't change the name if it's already NAME. */
1466 if (! NILP (Fstring_equal (name, f->name)))
1467 return;
1469 fset_name (f, name);
1471 /* For setting the frame title, the title parameter should override
1472 the name parameter. */
1473 if (! NILP (f->title))
1474 name = f->title;
1476 x_set_name_internal (f, name);
1479 /* This function should be called when the user's lisp code has
1480 specified a name for the frame; the name will override any set by the
1481 redisplay code. */
1482 static void
1483 x_explicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1485 x_set_name (f, arg, 1);
1488 /* This function should be called by Emacs redisplay code to set the
1489 name; names set this way will never override names set by the user's
1490 lisp code. */
1491 void
1492 x_implicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1494 x_set_name (f, arg, 0);
1497 /* Change the title of frame F to NAME.
1498 If NAME is nil, use the frame name as the title. */
1500 static void
1501 x_set_title (struct frame *f, Lisp_Object name, Lisp_Object old_name)
1503 /* Don't change the title if it's already NAME. */
1504 if (EQ (name, f->title))
1505 return;
1507 update_mode_lines = 38;
1509 fset_title (f, name);
1511 if (NILP (name))
1512 name = f->name;
1513 else
1514 CHECK_STRING (name);
1516 x_set_name_internal (f, name);
1519 void
1520 x_set_scroll_bar_default_width (struct frame *f)
1522 int unit = FRAME_COLUMN_WIDTH (f);
1523 #ifdef USE_TOOLKIT_SCROLL_BARS
1524 #ifdef USE_GTK
1525 int minw = xg_get_default_scrollbar_width ();
1526 #else
1527 int minw = 16;
1528 #endif
1529 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
1530 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (minw + unit - 1) / unit;
1531 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = minw;
1532 #else
1533 /* The width of a non-toolkit scrollbar is 14 pixels. */
1534 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + unit - 1) / unit;
1535 FRAME_CONFIG_SCROLL_BAR_WIDTH (f)
1536 = FRAME_CONFIG_SCROLL_BAR_COLS (f) * unit;
1537 #endif
1540 void
1541 x_set_scroll_bar_default_height (struct frame *f)
1543 int height = FRAME_LINE_HEIGHT (f);
1544 #ifdef USE_TOOLKIT_SCROLL_BARS
1545 #ifdef USE_GTK
1546 int min_height = xg_get_default_scrollbar_height ();
1547 #else
1548 int min_height = 16;
1549 #endif
1550 /* A minimum height of 14 doesn't look good for toolkit scroll bars. */
1551 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = min_height;
1552 FRAME_CONFIG_SCROLL_BAR_LINES (f) = (min_height + height - 1) / height;
1553 #else
1554 /* The height of a non-toolkit scrollbar is 14 pixels. */
1555 FRAME_CONFIG_SCROLL_BAR_LINES (f) = (14 + height - 1) / height;
1557 /* Use all of that space (aside from required margins) for the
1558 scroll bar. */
1559 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = 14;
1560 #endif
1564 /* Record in frame F the specified or default value according to ALIST
1565 of the parameter named PROP (a Lisp symbol). If no value is
1566 specified for PROP, look for an X default for XPROP on the frame
1567 named NAME. If that is not found either, use the value DEFLT. */
1569 static Lisp_Object
1570 x_default_scroll_bar_color_parameter (struct frame *f,
1571 Lisp_Object alist, Lisp_Object prop,
1572 const char *xprop, const char *xclass,
1573 int foreground_p)
1575 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
1576 Lisp_Object tem;
1578 tem = x_get_arg (dpyinfo, alist, prop, xprop, xclass, RES_TYPE_STRING);
1579 if (EQ (tem, Qunbound))
1581 #ifdef USE_TOOLKIT_SCROLL_BARS
1583 /* See if an X resource for the scroll bar color has been
1584 specified. */
1585 AUTO_STRING (foreground, "foreground");
1586 AUTO_STRING (background, "foreground");
1587 AUTO_STRING (verticalScrollBar, "verticalScrollBar");
1588 tem = (display_x_get_resource
1589 (dpyinfo, foreground_p ? foreground : background,
1590 empty_unibyte_string,
1591 verticalScrollBar,
1592 empty_unibyte_string));
1593 if (!STRINGP (tem))
1595 /* If nothing has been specified, scroll bars will use a
1596 toolkit-dependent default. Because these defaults are
1597 difficult to get at without actually creating a scroll
1598 bar, use nil to indicate that no color has been
1599 specified. */
1600 tem = Qnil;
1603 #else /* not USE_TOOLKIT_SCROLL_BARS */
1605 tem = Qnil;
1607 #endif /* not USE_TOOLKIT_SCROLL_BARS */
1610 AUTO_FRAME_ARG (arg, prop, tem);
1611 x_set_frame_parameters (f, arg);
1612 return tem;
1618 #ifdef USE_X_TOOLKIT
1620 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
1621 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
1622 already be present because of the toolkit (Motif adds some of them,
1623 for example, but Xt doesn't). */
1625 static void
1626 hack_wm_protocols (struct frame *f, Widget widget)
1628 Display *dpy = XtDisplay (widget);
1629 Window w = XtWindow (widget);
1630 int need_delete = 1;
1631 int need_focus = 1;
1632 int need_save = 1;
1634 block_input ();
1636 Atom type;
1637 unsigned char *catoms;
1638 int format = 0;
1639 unsigned long nitems = 0;
1640 unsigned long bytes_after;
1642 if ((XGetWindowProperty (dpy, w,
1643 FRAME_DISPLAY_INFO (f)->Xatom_wm_protocols,
1644 0, 100, False, XA_ATOM,
1645 &type, &format, &nitems, &bytes_after,
1646 &catoms)
1647 == Success)
1648 && format == 32 && type == XA_ATOM)
1650 Atom *atoms = (Atom *) catoms;
1651 while (nitems > 0)
1653 nitems--;
1654 if (atoms[nitems]
1655 == FRAME_DISPLAY_INFO (f)->Xatom_wm_delete_window)
1656 need_delete = 0;
1657 else if (atoms[nitems]
1658 == FRAME_DISPLAY_INFO (f)->Xatom_wm_take_focus)
1659 need_focus = 0;
1660 else if (atoms[nitems]
1661 == FRAME_DISPLAY_INFO (f)->Xatom_wm_save_yourself)
1662 need_save = 0;
1665 if (catoms)
1666 XFree (catoms);
1669 Atom props [10];
1670 int count = 0;
1671 if (need_delete)
1672 props[count++] = FRAME_DISPLAY_INFO (f)->Xatom_wm_delete_window;
1673 if (need_focus)
1674 props[count++] = FRAME_DISPLAY_INFO (f)->Xatom_wm_take_focus;
1675 if (need_save)
1676 props[count++] = FRAME_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
1677 if (count)
1678 XChangeProperty (dpy, w, FRAME_DISPLAY_INFO (f)->Xatom_wm_protocols,
1679 XA_ATOM, 32, PropModeAppend,
1680 (unsigned char *) props, count);
1682 unblock_input ();
1684 #endif
1688 /* Support routines for XIC (X Input Context). */
1690 #ifdef HAVE_X_I18N
1692 static XFontSet xic_create_xfontset (struct frame *);
1693 static XIMStyle best_xim_style (XIMStyles *);
1696 /* Supported XIM styles, ordered by preference. */
1698 static const XIMStyle supported_xim_styles[] =
1700 XIMPreeditPosition | XIMStatusArea,
1701 XIMPreeditPosition | XIMStatusNothing,
1702 XIMPreeditPosition | XIMStatusNone,
1703 XIMPreeditNothing | XIMStatusArea,
1704 XIMPreeditNothing | XIMStatusNothing,
1705 XIMPreeditNothing | XIMStatusNone,
1706 XIMPreeditNone | XIMStatusArea,
1707 XIMPreeditNone | XIMStatusNothing,
1708 XIMPreeditNone | XIMStatusNone,
1713 #if defined HAVE_X_WINDOWS && defined USE_X_TOOLKIT
1714 /* Create an X fontset on frame F with base font name BASE_FONTNAME. */
1716 static const char xic_default_fontset[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
1718 /* Create an Xt fontset spec from the name of a base font.
1719 If `motif' is True use the Motif syntax. */
1720 char *
1721 xic_create_fontsetname (const char *base_fontname, int motif)
1723 const char *sep = motif ? ";" : ",";
1724 char *fontsetname;
1726 /* Make a fontset name from the base font name. */
1727 if (xic_default_fontset == base_fontname)
1729 /* There is no base font name, use the default. */
1730 fontsetname = xmalloc (strlen (base_fontname) + 2);
1731 strcpy (fontsetname, base_fontname);
1733 else
1735 /* Make a fontset name from the base font name.
1736 The font set will be made of the following elements:
1737 - the base font.
1738 - the base font where the charset spec is replaced by -*-*.
1739 - the same but with the family also replaced with -*-*-. */
1740 const char *p = base_fontname;
1741 ptrdiff_t i;
1743 for (i = 0; *p; p++)
1744 if (*p == '-') i++;
1745 if (i != 14)
1747 /* As the font name doesn't conform to XLFD, we can't
1748 modify it to generalize it to allcs and allfamilies.
1749 Use the specified font plus the default. */
1750 fontsetname = xmalloc (strlen (base_fontname)
1751 + strlen (xic_default_fontset) + 3);
1752 strcpy (fontsetname, base_fontname);
1753 strcat (fontsetname, sep);
1754 strcat (fontsetname, xic_default_fontset);
1756 else
1758 ptrdiff_t len;
1759 const char *p1 = NULL, *p2 = NULL, *p3 = NULL;
1760 char *font_allcs = NULL;
1761 char *font_allfamilies = NULL;
1762 char *font_all = NULL;
1763 const char *allcs = "*-*-*-*-*-*-*";
1764 const char *allfamilies = "-*-*-";
1765 const char *all = "*-*-*-*-";
1766 char *base;
1768 for (i = 0, p = base_fontname; i < 8; p++)
1770 if (*p == '-')
1772 i++;
1773 if (i == 3)
1774 p1 = p + 1;
1775 else if (i == 7)
1776 p2 = p + 1;
1777 else if (i == 6)
1778 p3 = p + 1;
1781 /* If base_fontname specifies ADSTYLE, make it a
1782 wildcard. */
1783 if (*p3 != '*')
1785 ptrdiff_t diff = (p2 - p3) - 2;
1787 base = alloca (strlen (base_fontname) + 1);
1788 memcpy (base, base_fontname, p3 - base_fontname);
1789 base[p3 - base_fontname] = '*';
1790 base[(p3 - base_fontname) + 1] = '-';
1791 strcpy (base + (p3 - base_fontname) + 2, p2);
1792 p = base + (p - base_fontname) - diff;
1793 p1 = base + (p1 - base_fontname);
1794 p2 = base + (p2 - base_fontname) - diff;
1795 base_fontname = base;
1798 /* Build the font spec that matches all charsets. */
1799 len = p - base_fontname + strlen (allcs) + 1;
1800 font_allcs = alloca (len);
1801 memcpy (font_allcs, base_fontname, p - base_fontname);
1802 strcpy (font_allcs + (p - base_fontname), allcs);
1804 /* Build the font spec that matches all families and
1805 add-styles. */
1806 len = p - p1 + strlen (allcs) + strlen (allfamilies) + 1;
1807 font_allfamilies = alloca (len);
1808 strcpy (font_allfamilies, allfamilies);
1809 memcpy (font_allfamilies + strlen (allfamilies), p1, p - p1);
1810 strcpy (font_allfamilies + strlen (allfamilies) + (p - p1), allcs);
1812 /* Build the font spec that matches all. */
1813 len = p - p2 + strlen (allcs) + strlen (all) + strlen (allfamilies) + 1;
1814 font_all = alloca (len);
1815 strcpy (font_all, allfamilies);
1816 strcat (font_all, all);
1817 memcpy (font_all + strlen (all) + strlen (allfamilies), p2, p - p2);
1818 strcpy (font_all + strlen (all) + strlen (allfamilies) + (p - p2),
1819 allcs);
1821 /* Build the actual font set name. */
1822 len = strlen (base_fontname) + strlen (font_allcs)
1823 + strlen (font_allfamilies) + strlen (font_all) + 5;
1824 fontsetname = xmalloc (len);
1825 strcpy (fontsetname, base_fontname);
1826 strcat (fontsetname, sep);
1827 strcat (fontsetname, font_allcs);
1828 strcat (fontsetname, sep);
1829 strcat (fontsetname, font_allfamilies);
1830 strcat (fontsetname, sep);
1831 strcat (fontsetname, font_all);
1834 if (motif)
1835 return strcat (fontsetname, ":");
1836 return fontsetname;
1838 #endif /* HAVE_X_WINDOWS && USE_X_TOOLKIT */
1840 #ifdef DEBUG_XIC_FONTSET
1841 static void
1842 print_fontset_result (XFontSet xfs, char *name, char **missing_list,
1843 int missing_count)
1845 if (xfs)
1846 fprintf (stderr, "XIC Fontset created: %s\n", name);
1847 else
1849 fprintf (stderr, "XIC Fontset failed: %s\n", name);
1850 while (missing_count-- > 0)
1852 fprintf (stderr, " missing: %s\n", *missing_list);
1853 missing_list++;
1858 #endif
1860 static XFontSet
1861 xic_create_xfontset (struct frame *f)
1863 XFontSet xfs = NULL;
1864 struct font *font = FRAME_FONT (f);
1865 int pixel_size = font->pixel_size;
1866 Lisp_Object rest, frame;
1868 /* See if there is another frame already using same fontset. */
1869 FOR_EACH_FRAME (rest, frame)
1871 struct frame *cf = XFRAME (frame);
1873 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
1874 && FRAME_DISPLAY_INFO (cf) == FRAME_DISPLAY_INFO (f)
1875 && FRAME_FONT (f)
1876 && FRAME_FONT (f)->pixel_size == pixel_size)
1878 xfs = FRAME_XIC_FONTSET (cf);
1879 break;
1883 if (! xfs)
1885 char buf[256];
1886 char **missing_list;
1887 int missing_count;
1888 char *def_string;
1889 const char *xlfd_format = "-*-*-medium-r-normal--%d-*-*-*-*-*";
1891 sprintf (buf, xlfd_format, pixel_size);
1892 missing_list = NULL;
1893 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
1894 &missing_list, &missing_count, &def_string);
1895 #ifdef DEBUG_XIC_FONTSET
1896 print_fontset_result (xfs, buf, missing_list, missing_count);
1897 #endif
1898 if (missing_list)
1899 XFreeStringList (missing_list);
1900 if (! xfs)
1902 /* List of pixel sizes most likely available. Find one that
1903 is closest to pixel_size. */
1904 int sizes[] = {0, 8, 10, 11, 12, 14, 17, 18, 20, 24, 26, 34, 0};
1905 int *smaller, *larger;
1907 for (smaller = sizes; smaller[1]; smaller++)
1908 if (smaller[1] >= pixel_size)
1909 break;
1910 larger = smaller + 1;
1911 if (*larger == pixel_size)
1912 larger++;
1913 while (*smaller || *larger)
1915 int this_size;
1917 if (! *larger)
1918 this_size = *smaller--;
1919 else if (! *smaller)
1920 this_size = *larger++;
1921 else if (pixel_size - *smaller < *larger - pixel_size)
1922 this_size = *smaller--;
1923 else
1924 this_size = *larger++;
1925 sprintf (buf, xlfd_format, this_size);
1926 missing_list = NULL;
1927 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
1928 &missing_list, &missing_count, &def_string);
1929 #ifdef DEBUG_XIC_FONTSET
1930 print_fontset_result (xfs, buf, missing_list, missing_count);
1931 #endif
1932 if (missing_list)
1933 XFreeStringList (missing_list);
1934 if (xfs)
1935 break;
1938 if (! xfs)
1940 const char *last_resort = "-*-*-*-r-normal--*-*-*-*-*-*";
1942 missing_list = NULL;
1943 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), last_resort,
1944 &missing_list, &missing_count, &def_string);
1945 #ifdef DEBUG_XIC_FONTSET
1946 print_fontset_result (xfs, last_resort, missing_list, missing_count);
1947 #endif
1948 if (missing_list)
1949 XFreeStringList (missing_list);
1954 return xfs;
1957 /* Free the X fontset of frame F if it is the last frame using it. */
1959 void
1960 xic_free_xfontset (struct frame *f)
1962 Lisp_Object rest, frame;
1963 bool shared_p = 0;
1965 if (!FRAME_XIC_FONTSET (f))
1966 return;
1968 /* See if there is another frame sharing the same fontset. */
1969 FOR_EACH_FRAME (rest, frame)
1971 struct frame *cf = XFRAME (frame);
1972 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
1973 && FRAME_DISPLAY_INFO (cf) == FRAME_DISPLAY_INFO (f)
1974 && FRAME_XIC_FONTSET (cf) == FRAME_XIC_FONTSET (f))
1976 shared_p = 1;
1977 break;
1981 if (!shared_p)
1982 /* The fontset is not used anymore. It is safe to free it. */
1983 XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f));
1985 FRAME_XIC_FONTSET (f) = NULL;
1989 /* Value is the best input style, given user preferences USER (already
1990 checked to be supported by Emacs), and styles supported by the
1991 input method XIM. */
1993 static XIMStyle
1994 best_xim_style (XIMStyles *xim)
1996 int i, j;
1997 int nr_supported = ARRAYELTS (supported_xim_styles);
1999 for (i = 0; i < nr_supported; ++i)
2000 for (j = 0; j < xim->count_styles; ++j)
2001 if (supported_xim_styles[i] == xim->supported_styles[j])
2002 return supported_xim_styles[i];
2004 /* Return the default style. */
2005 return XIMPreeditNothing | XIMStatusNothing;
2008 /* Create XIC for frame F. */
2010 void
2011 create_frame_xic (struct frame *f)
2013 XIM xim;
2014 XIC xic = NULL;
2015 XFontSet xfs = NULL;
2016 XVaNestedList status_attr = NULL;
2017 XVaNestedList preedit_attr = NULL;
2018 XRectangle s_area;
2019 XPoint spot;
2020 XIMStyle xic_style;
2022 if (FRAME_XIC (f))
2023 goto out;
2025 xim = FRAME_X_XIM (f);
2026 if (!xim)
2027 goto out;
2029 /* Determine XIC style. */
2030 xic_style = best_xim_style (FRAME_X_XIM_STYLES (f));
2032 /* Create X fontset. */
2033 if (xic_style & (XIMPreeditPosition | XIMStatusArea))
2035 xfs = xic_create_xfontset (f);
2036 if (!xfs)
2037 goto out;
2039 FRAME_XIC_FONTSET (f) = xfs;
2042 if (xic_style & XIMPreeditPosition)
2044 spot.x = 0; spot.y = 1;
2045 preedit_attr = XVaCreateNestedList (0,
2046 XNFontSet, xfs,
2047 XNForeground,
2048 FRAME_FOREGROUND_PIXEL (f),
2049 XNBackground,
2050 FRAME_BACKGROUND_PIXEL (f),
2051 (xic_style & XIMPreeditPosition
2052 ? XNSpotLocation
2053 : NULL),
2054 &spot,
2055 NULL);
2057 if (!preedit_attr)
2058 goto out;
2061 if (xic_style & XIMStatusArea)
2063 s_area.x = 0; s_area.y = 0; s_area.width = 1; s_area.height = 1;
2064 status_attr = XVaCreateNestedList (0,
2065 XNArea,
2066 &s_area,
2067 XNFontSet,
2068 xfs,
2069 XNForeground,
2070 FRAME_FOREGROUND_PIXEL (f),
2071 XNBackground,
2072 FRAME_BACKGROUND_PIXEL (f),
2073 NULL);
2075 if (!status_attr)
2076 goto out;
2079 if (preedit_attr && status_attr)
2080 xic = XCreateIC (xim,
2081 XNInputStyle, xic_style,
2082 XNClientWindow, FRAME_X_WINDOW (f),
2083 XNFocusWindow, FRAME_X_WINDOW (f),
2084 XNStatusAttributes, status_attr,
2085 XNPreeditAttributes, preedit_attr,
2086 NULL);
2087 else if (preedit_attr)
2088 xic = XCreateIC (xim,
2089 XNInputStyle, xic_style,
2090 XNClientWindow, FRAME_X_WINDOW (f),
2091 XNFocusWindow, FRAME_X_WINDOW (f),
2092 XNPreeditAttributes, preedit_attr,
2093 NULL);
2094 else if (status_attr)
2095 xic = XCreateIC (xim,
2096 XNInputStyle, xic_style,
2097 XNClientWindow, FRAME_X_WINDOW (f),
2098 XNFocusWindow, FRAME_X_WINDOW (f),
2099 XNStatusAttributes, status_attr,
2100 NULL);
2101 else
2102 xic = XCreateIC (xim,
2103 XNInputStyle, xic_style,
2104 XNClientWindow, FRAME_X_WINDOW (f),
2105 XNFocusWindow, FRAME_X_WINDOW (f),
2106 NULL);
2108 if (!xic)
2109 goto out;
2111 FRAME_XIC (f) = xic;
2112 FRAME_XIC_STYLE (f) = xic_style;
2113 xfs = NULL; /* Don't free below. */
2115 out:
2117 if (xfs)
2118 free_frame_xic (f);
2120 if (preedit_attr)
2121 XFree (preedit_attr);
2123 if (status_attr)
2124 XFree (status_attr);
2128 /* Destroy XIC and free XIC fontset of frame F, if any. */
2130 void
2131 free_frame_xic (struct frame *f)
2133 if (FRAME_XIC (f) == NULL)
2134 return;
2136 XDestroyIC (FRAME_XIC (f));
2137 xic_free_xfontset (f);
2139 FRAME_XIC (f) = NULL;
2143 /* Place preedit area for XIC of window W's frame to specified
2144 pixel position X/Y. X and Y are relative to window W. */
2146 void
2147 xic_set_preeditarea (struct window *w, int x, int y)
2149 struct frame *f = XFRAME (w->frame);
2150 XVaNestedList attr;
2151 XPoint spot;
2153 spot.x = WINDOW_TO_FRAME_PIXEL_X (w, x) + WINDOW_LEFT_FRINGE_WIDTH (w);
2154 spot.y = WINDOW_TO_FRAME_PIXEL_Y (w, y) + FONT_BASE (FRAME_FONT (f));
2155 attr = XVaCreateNestedList (0, XNSpotLocation, &spot, NULL);
2156 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2157 XFree (attr);
2161 /* Place status area for XIC in bottom right corner of frame F.. */
2163 void
2164 xic_set_statusarea (struct frame *f)
2166 XIC xic = FRAME_XIC (f);
2167 XVaNestedList attr;
2168 XRectangle area;
2169 XRectangle *needed;
2171 /* Negotiate geometry of status area. If input method has existing
2172 status area, use its current size. */
2173 area.x = area.y = area.width = area.height = 0;
2174 attr = XVaCreateNestedList (0, XNAreaNeeded, &area, NULL);
2175 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2176 XFree (attr);
2178 attr = XVaCreateNestedList (0, XNAreaNeeded, &needed, NULL);
2179 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2180 XFree (attr);
2182 if (needed->width == 0) /* Use XNArea instead of XNAreaNeeded */
2184 attr = XVaCreateNestedList (0, XNArea, &needed, NULL);
2185 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2186 XFree (attr);
2189 area.width = needed->width;
2190 area.height = needed->height;
2191 area.x = FRAME_PIXEL_WIDTH (f) - area.width - FRAME_INTERNAL_BORDER_WIDTH (f);
2192 area.y = (FRAME_PIXEL_HEIGHT (f) - area.height
2193 - FRAME_MENUBAR_HEIGHT (f)
2194 - FRAME_TOOLBAR_TOP_HEIGHT (f)
2195 - FRAME_INTERNAL_BORDER_WIDTH (f));
2196 XFree (needed);
2198 attr = XVaCreateNestedList (0, XNArea, &area, NULL);
2199 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2200 XFree (attr);
2204 /* Set X fontset for XIC of frame F, using base font name
2205 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2207 void
2208 xic_set_xfontset (struct frame *f, const char *base_fontname)
2210 XVaNestedList attr;
2211 XFontSet xfs;
2213 xic_free_xfontset (f);
2215 xfs = xic_create_xfontset (f);
2217 attr = XVaCreateNestedList (0, XNFontSet, xfs, NULL);
2218 if (FRAME_XIC_STYLE (f) & XIMPreeditPosition)
2219 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2220 if (FRAME_XIC_STYLE (f) & XIMStatusArea)
2221 XSetICValues (FRAME_XIC (f), XNStatusAttributes, attr, NULL);
2222 XFree (attr);
2224 FRAME_XIC_FONTSET (f) = xfs;
2227 #endif /* HAVE_X_I18N */
2231 #ifdef USE_X_TOOLKIT
2233 /* Create and set up the X widget for frame F. */
2235 static void
2236 x_window (struct frame *f, long window_prompting, int minibuffer_only)
2238 XClassHint class_hints;
2239 XSetWindowAttributes attributes;
2240 unsigned long attribute_mask;
2241 Widget shell_widget;
2242 Widget pane_widget;
2243 Widget frame_widget;
2244 Arg al [25];
2245 int ac;
2247 block_input ();
2249 /* Use the resource name as the top-level widget name
2250 for looking up resources. Make a non-Lisp copy
2251 for the window manager, so GC relocation won't bother it.
2253 Elsewhere we specify the window name for the window manager. */
2254 f->namebuf = xstrdup (SSDATA (Vx_resource_name));
2256 ac = 0;
2257 XtSetArg (al[ac], XtNallowShellResize, 1); ac++;
2258 XtSetArg (al[ac], XtNinput, 1); ac++;
2259 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2260 XtSetArg (al[ac], XtNborderWidth, f->border_width); ac++;
2261 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2262 XtSetArg (al[ac], XtNdepth, FRAME_DISPLAY_INFO (f)->n_planes); ac++;
2263 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2264 shell_widget = XtAppCreateShell (f->namebuf, EMACS_CLASS,
2265 applicationShellWidgetClass,
2266 FRAME_X_DISPLAY (f), al, ac);
2268 f->output_data.x->widget = shell_widget;
2269 /* maybe_set_screen_title_format (shell_widget); */
2271 pane_widget = lw_create_widget ("main", "pane", widget_id_tick++,
2272 NULL, shell_widget, False,
2273 NULL, NULL, NULL, NULL);
2275 ac = 0;
2276 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2277 XtSetArg (al[ac], XtNdepth, FRAME_DISPLAY_INFO (f)->n_planes); ac++;
2278 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2279 XtSetArg (al[ac], XtNborderWidth, 0); ac++;
2280 XtSetValues (pane_widget, al, ac);
2281 f->output_data.x->column_widget = pane_widget;
2283 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2284 the emacs screen when changing menubar. This reduces flickering. */
2286 ac = 0;
2287 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2288 XtSetArg (al[ac], XtNshowGrip, 0); ac++;
2289 XtSetArg (al[ac], XtNallowResize, 1); ac++;
2290 XtSetArg (al[ac], XtNresizeToPreferred, 1); ac++;
2291 XtSetArg (al[ac], XtNemacsFrame, f); ac++;
2292 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2293 XtSetArg (al[ac], XtNdepth, FRAME_DISPLAY_INFO (f)->n_planes); ac++;
2294 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2295 XtSetArg (al[ac], XtNborderWidth, 0); ac++;
2296 frame_widget = XtCreateWidget (f->namebuf, emacsFrameClass, pane_widget,
2297 al, ac);
2299 f->output_data.x->edit_widget = frame_widget;
2301 XtManageChild (frame_widget);
2303 /* Do some needed geometry management. */
2305 Arg gal[3];
2306 int gac = 0;
2307 int extra_borders = 0;
2308 int menubar_size
2309 = (f->output_data.x->menubar_widget
2310 ? (f->output_data.x->menubar_widget->core.height
2311 + f->output_data.x->menubar_widget->core.border_width)
2312 : 0);
2314 #if 0 /* Experimentally, we now get the right results
2315 for -geometry -0-0 without this. 24 Aug 96, rms. */
2316 if (FRAME_EXTERNAL_MENU_BAR (f))
2318 Dimension ibw = 0;
2319 XtVaGetValues (pane_widget, XtNinternalBorderWidth, &ibw, NULL);
2320 menubar_size += ibw;
2322 #endif
2324 FRAME_MENUBAR_HEIGHT (f) = menubar_size;
2326 #ifndef USE_LUCID
2327 /* Motif seems to need this amount added to the sizes
2328 specified for the shell widget. The Athena/Lucid widgets don't.
2329 Both conclusions reached experimentally. -- rms. */
2330 XtVaGetValues (f->output_data.x->edit_widget, XtNinternalBorderWidth,
2331 &extra_borders, NULL);
2332 extra_borders *= 2;
2333 #endif
2335 f->shell_position = xmalloc (sizeof "=x++" + 4 * INT_STRLEN_BOUND (int));
2337 /* Convert our geometry parameters into a geometry string
2338 and specify it.
2339 Note that we do not specify here whether the position
2340 is a user-specified or program-specified one.
2341 We pass that information later, in x_wm_set_size_hints. */
2343 int left = f->left_pos;
2344 int xneg = window_prompting & XNegative;
2345 int top = f->top_pos;
2346 int yneg = window_prompting & YNegative;
2347 if (xneg)
2348 left = -left;
2349 if (yneg)
2350 top = -top;
2352 if (window_prompting & USPosition)
2353 sprintf (f->shell_position, "=%dx%d%c%d%c%d",
2354 FRAME_PIXEL_WIDTH (f) + extra_borders,
2355 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders,
2356 (xneg ? '-' : '+'), left,
2357 (yneg ? '-' : '+'), top);
2358 else
2360 sprintf (f->shell_position, "=%dx%d",
2361 FRAME_PIXEL_WIDTH (f) + extra_borders,
2362 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders);
2364 /* Setting x and y when the position is not specified in
2365 the geometry string will set program position in the WM hints.
2366 If Emacs had just one program position, we could set it in
2367 fallback resources, but since each make-frame call can specify
2368 different program positions, this is easier. */
2369 XtSetArg (gal[gac], XtNx, left); gac++;
2370 XtSetArg (gal[gac], XtNy, top); gac++;
2374 XtSetArg (gal[gac], XtNgeometry, f->shell_position); gac++;
2375 XtSetValues (shell_widget, gal, gac);
2378 XtManageChild (pane_widget);
2379 XtRealizeWidget (shell_widget);
2381 if (FRAME_X_EMBEDDED_P (f))
2382 XReparentWindow (FRAME_X_DISPLAY (f), XtWindow (shell_widget),
2383 f->output_data.x->parent_desc, 0, 0);
2385 FRAME_X_WINDOW (f) = XtWindow (frame_widget);
2387 validate_x_resource_name ();
2389 class_hints.res_name = SSDATA (Vx_resource_name);
2390 class_hints.res_class = SSDATA (Vx_resource_class);
2391 XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints);
2393 #ifdef HAVE_X_I18N
2394 FRAME_XIC (f) = NULL;
2395 if (use_xim)
2396 create_frame_xic (f);
2397 #endif
2399 f->output_data.x->wm_hints.input = True;
2400 f->output_data.x->wm_hints.flags |= InputHint;
2401 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2402 &f->output_data.x->wm_hints);
2404 hack_wm_protocols (f, shell_widget);
2406 #ifdef HACK_EDITRES
2407 XtAddEventHandler (shell_widget, 0, True, _XEditResCheckMessages, 0);
2408 #endif
2410 /* Do a stupid property change to force the server to generate a
2411 PropertyNotify event so that the event_stream server timestamp will
2412 be initialized to something relevant to the time we created the window.
2414 XChangeProperty (XtDisplay (frame_widget), XtWindow (frame_widget),
2415 FRAME_DISPLAY_INFO (f)->Xatom_wm_protocols,
2416 XA_ATOM, 32, PropModeAppend, NULL, 0);
2418 /* Make all the standard events reach the Emacs frame. */
2419 attributes.event_mask = STANDARD_EVENT_SET;
2421 #ifdef HAVE_X_I18N
2422 if (FRAME_XIC (f))
2424 /* XIM server might require some X events. */
2425 unsigned long fevent = NoEventMask;
2426 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2427 attributes.event_mask |= fevent;
2429 #endif /* HAVE_X_I18N */
2431 attribute_mask = CWEventMask;
2432 XChangeWindowAttributes (XtDisplay (shell_widget), XtWindow (shell_widget),
2433 attribute_mask, &attributes);
2435 XtMapWidget (frame_widget);
2437 /* x_set_name normally ignores requests to set the name if the
2438 requested name is the same as the current name. This is the one
2439 place where that assumption isn't correct; f->name is set, but
2440 the X server hasn't been told. */
2442 Lisp_Object name;
2443 bool explicit = f->explicit_name;
2445 f->explicit_name = 0;
2446 name = f->name;
2447 fset_name (f, Qnil);
2448 x_set_name (f, name, explicit);
2451 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2452 f->output_data.x->current_cursor
2453 = f->output_data.x->text_cursor);
2455 unblock_input ();
2457 /* This is a no-op, except under Motif. Make sure main areas are
2458 set to something reasonable, in case we get an error later. */
2459 lw_set_main_areas (pane_widget, 0, frame_widget);
2462 #else /* not USE_X_TOOLKIT */
2463 #ifdef USE_GTK
2464 static void
2465 x_window (struct frame *f)
2467 if (! xg_create_frame_widgets (f))
2468 error ("Unable to create window");
2470 #ifdef HAVE_X_I18N
2471 FRAME_XIC (f) = NULL;
2472 if (use_xim)
2474 block_input ();
2475 create_frame_xic (f);
2476 if (FRAME_XIC (f))
2478 /* XIM server might require some X events. */
2479 unsigned long fevent = NoEventMask;
2480 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2482 if (fevent != NoEventMask)
2484 XSetWindowAttributes attributes;
2485 XWindowAttributes wattr;
2486 unsigned long attribute_mask;
2488 XGetWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2489 &wattr);
2490 attributes.event_mask = wattr.your_event_mask | fevent;
2491 attribute_mask = CWEventMask;
2492 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2493 attribute_mask, &attributes);
2496 unblock_input ();
2498 #endif
2501 #else /*! USE_GTK */
2502 /* Create and set up the X window for frame F. */
2504 static void
2505 x_window (struct frame *f)
2507 XClassHint class_hints;
2508 XSetWindowAttributes attributes;
2509 unsigned long attribute_mask;
2511 attributes.background_pixel = FRAME_BACKGROUND_PIXEL (f);
2512 attributes.border_pixel = f->output_data.x->border_pixel;
2513 attributes.bit_gravity = StaticGravity;
2514 attributes.backing_store = NotUseful;
2515 attributes.save_under = True;
2516 attributes.event_mask = STANDARD_EVENT_SET;
2517 attributes.colormap = FRAME_X_COLORMAP (f);
2518 attribute_mask = (CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask
2519 | CWColormap);
2521 block_input ();
2522 FRAME_X_WINDOW (f)
2523 = XCreateWindow (FRAME_X_DISPLAY (f),
2524 f->output_data.x->parent_desc,
2525 f->left_pos,
2526 f->top_pos,
2527 FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
2528 f->border_width,
2529 CopyFromParent, /* depth */
2530 InputOutput, /* class */
2531 FRAME_X_VISUAL (f),
2532 attribute_mask, &attributes);
2534 #ifdef HAVE_X_I18N
2535 if (use_xim)
2537 create_frame_xic (f);
2538 if (FRAME_XIC (f))
2540 /* XIM server might require some X events. */
2541 unsigned long fevent = NoEventMask;
2542 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2543 attributes.event_mask |= fevent;
2544 attribute_mask = CWEventMask;
2545 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2546 attribute_mask, &attributes);
2549 #endif /* HAVE_X_I18N */
2551 validate_x_resource_name ();
2553 class_hints.res_name = SSDATA (Vx_resource_name);
2554 class_hints.res_class = SSDATA (Vx_resource_class);
2555 XSetClassHint (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &class_hints);
2557 /* This indicates that we use the "Passive Input" input model.
2558 Unless we do this, we don't get the Focus{In,Out} events that we
2559 need to draw the cursor correctly. Accursed bureaucrats.
2560 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2562 f->output_data.x->wm_hints.input = True;
2563 f->output_data.x->wm_hints.flags |= InputHint;
2564 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2565 &f->output_data.x->wm_hints);
2566 f->output_data.x->wm_hints.icon_pixmap = None;
2568 /* Request "save yourself" and "delete window" commands from wm. */
2570 Atom protocols[2];
2571 protocols[0] = FRAME_DISPLAY_INFO (f)->Xatom_wm_delete_window;
2572 protocols[1] = FRAME_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
2573 XSetWMProtocols (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), protocols, 2);
2576 /* x_set_name normally ignores requests to set the name if the
2577 requested name is the same as the current name. This is the one
2578 place where that assumption isn't correct; f->name is set, but
2579 the X server hasn't been told. */
2581 Lisp_Object name;
2582 bool explicit = f->explicit_name;
2584 f->explicit_name = 0;
2585 name = f->name;
2586 fset_name (f, Qnil);
2587 x_set_name (f, name, explicit);
2590 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2591 f->output_data.x->current_cursor
2592 = f->output_data.x->text_cursor);
2594 unblock_input ();
2596 if (FRAME_X_WINDOW (f) == 0)
2597 error ("Unable to create window");
2600 #endif /* not USE_GTK */
2601 #endif /* not USE_X_TOOLKIT */
2603 /* Verify that the icon position args for this window are valid. */
2605 static void
2606 x_icon_verify (struct frame *f, Lisp_Object parms)
2608 Lisp_Object icon_x, icon_y;
2610 /* Set the position of the icon. Note that twm groups all
2611 icons in an icon window. */
2612 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2613 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2614 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2616 CHECK_NUMBER (icon_x);
2617 CHECK_NUMBER (icon_y);
2619 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2620 error ("Both left and top icon corners of icon must be specified");
2623 /* Handle the icon stuff for this window. Perhaps later we might
2624 want an x_set_icon_position which can be called interactively as
2625 well. */
2627 static void
2628 x_icon (struct frame *f, Lisp_Object parms)
2630 Lisp_Object icon_x, icon_y;
2631 #if 0
2632 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2633 #endif
2635 /* Set the position of the icon. Note that twm groups all
2636 icons in an icon window. */
2637 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2638 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2639 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2641 CHECK_TYPE_RANGED_INTEGER (int, icon_x);
2642 CHECK_TYPE_RANGED_INTEGER (int, icon_y);
2644 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2645 error ("Both left and top icon corners of icon must be specified");
2647 block_input ();
2649 if (! EQ (icon_x, Qunbound))
2650 x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
2652 #if 0 /* x_get_arg removes the visibility parameter as a side effect,
2653 but x_create_frame still needs it. */
2654 /* Start up iconic or window? */
2655 x_wm_set_window_state
2656 (f, (EQ (x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL),
2657 Qicon)
2658 ? IconicState
2659 : NormalState));
2660 #endif
2662 x_text_icon (f, SSDATA ((!NILP (f->icon_name)
2663 ? f->icon_name
2664 : f->name)));
2666 unblock_input ();
2669 /* Make the GCs needed for this window, setting the
2670 background, border and mouse colors; also create the
2671 mouse cursor and the gray border tile. */
2673 static void
2674 x_make_gc (struct frame *f)
2676 XGCValues gc_values;
2678 block_input ();
2680 /* Create the GCs of this frame.
2681 Note that many default values are used. */
2683 gc_values.foreground = FRAME_FOREGROUND_PIXEL (f);
2684 gc_values.background = FRAME_BACKGROUND_PIXEL (f);
2685 gc_values.line_width = 0; /* Means 1 using fast algorithm. */
2686 f->output_data.x->normal_gc
2687 = XCreateGC (FRAME_X_DISPLAY (f),
2688 FRAME_X_WINDOW (f),
2689 GCLineWidth | GCForeground | GCBackground,
2690 &gc_values);
2692 /* Reverse video style. */
2693 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2694 gc_values.background = FRAME_FOREGROUND_PIXEL (f);
2695 f->output_data.x->reverse_gc
2696 = XCreateGC (FRAME_X_DISPLAY (f),
2697 FRAME_X_WINDOW (f),
2698 GCForeground | GCBackground | GCLineWidth,
2699 &gc_values);
2701 /* Cursor has cursor-color background, background-color foreground. */
2702 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2703 gc_values.background = f->output_data.x->cursor_pixel;
2704 gc_values.fill_style = FillOpaqueStippled;
2705 f->output_data.x->cursor_gc
2706 = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2707 (GCForeground | GCBackground
2708 | GCFillStyle | GCLineWidth),
2709 &gc_values);
2711 /* Create the gray border tile used when the pointer is not in
2712 the frame. Since this depends on the frame's pixel values,
2713 this must be done on a per-frame basis. */
2714 f->output_data.x->border_tile
2715 = (XCreatePixmapFromBitmapData
2716 (FRAME_X_DISPLAY (f), FRAME_DISPLAY_INFO (f)->root_window,
2717 gray_bits, gray_width, gray_height,
2718 FRAME_FOREGROUND_PIXEL (f),
2719 FRAME_BACKGROUND_PIXEL (f),
2720 DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
2722 unblock_input ();
2726 /* Free what was allocated in x_make_gc. */
2728 void
2729 x_free_gcs (struct frame *f)
2731 Display *dpy = FRAME_X_DISPLAY (f);
2733 block_input ();
2735 if (f->output_data.x->normal_gc)
2737 XFreeGC (dpy, f->output_data.x->normal_gc);
2738 f->output_data.x->normal_gc = 0;
2741 if (f->output_data.x->reverse_gc)
2743 XFreeGC (dpy, f->output_data.x->reverse_gc);
2744 f->output_data.x->reverse_gc = 0;
2747 if (f->output_data.x->cursor_gc)
2749 XFreeGC (dpy, f->output_data.x->cursor_gc);
2750 f->output_data.x->cursor_gc = 0;
2753 if (f->output_data.x->border_tile)
2755 XFreePixmap (dpy, f->output_data.x->border_tile);
2756 f->output_data.x->border_tile = 0;
2759 unblock_input ();
2763 /* Handler for signals raised during x_create_frame and
2764 x_create_tip_frame. FRAME is the frame which is partially
2765 constructed. */
2767 static Lisp_Object
2768 unwind_create_frame (Lisp_Object frame)
2770 struct frame *f = XFRAME (frame);
2772 /* If frame is already dead, nothing to do. This can happen if the
2773 display is disconnected after the frame has become official, but
2774 before x_create_frame removes the unwind protect. */
2775 if (!FRAME_LIVE_P (f))
2776 return Qnil;
2778 /* If frame is ``official'', nothing to do. */
2779 if (NILP (Fmemq (frame, Vframe_list)))
2781 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2782 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2783 #endif
2785 x_free_frame_resources (f);
2786 free_glyphs (f);
2788 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2789 /* Check that reference counts are indeed correct. */
2790 eassert (dpyinfo->reference_count == dpyinfo_refcount);
2791 eassert (dpyinfo->terminal->image_cache->refcount == image_cache_refcount);
2792 #endif
2793 return Qt;
2796 return Qnil;
2799 static void
2800 do_unwind_create_frame (Lisp_Object frame)
2802 unwind_create_frame (frame);
2805 static void
2806 x_default_font_parameter (struct frame *f, Lisp_Object parms)
2808 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2809 Lisp_Object font_param = x_get_arg (dpyinfo, parms, Qfont, NULL, NULL,
2810 RES_TYPE_STRING);
2811 Lisp_Object font = Qnil;
2812 if (EQ (font_param, Qunbound))
2813 font_param = Qnil;
2815 if (NILP (font_param))
2817 /* System font should take precedence over X resources. We suggest this
2818 regardless of font-use-system-font because .emacs may not have been
2819 read yet. */
2820 const char *system_font = xsettings_get_system_font ();
2821 if (system_font)
2822 font = font_open_by_name (f, build_unibyte_string (system_font));
2825 if (NILP (font))
2826 font = !NILP (font_param) ? font_param
2827 : x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
2829 if (! FONTP (font) && ! STRINGP (font))
2831 const char *names[]
2833 #ifdef HAVE_XFT
2834 /* This will find the normal Xft font. */
2835 "monospace-10",
2836 #endif
2837 "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
2838 "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
2839 "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
2840 /* This was formerly the first thing tried, but it finds
2841 too many fonts and takes too long. */
2842 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
2843 /* If those didn't work, look for something which will
2844 at least work. */
2845 "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
2846 "fixed",
2847 NULL };
2848 int i;
2850 for (i = 0; names[i]; i++)
2852 font = font_open_by_name (f, build_unibyte_string (names[i]));
2853 if (! NILP (font))
2854 break;
2856 if (NILP (font))
2857 error ("No suitable font was found");
2859 else if (!NILP (font_param))
2861 /* Remember the explicit font parameter, so we can re-apply it after
2862 we've applied the `default' face settings. */
2863 AUTO_FRAME_ARG (arg, Qfont_param, font_param);
2864 x_set_frame_parameters (f, arg);
2867 /* This call will make X resources override any system font setting. */
2868 x_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING);
2872 DEFUN ("x-wm-set-size-hint", Fx_wm_set_size_hint, Sx_wm_set_size_hint,
2873 0, 1, 0,
2874 doc: /* Send the size hints for frame FRAME to the window manager.
2875 If FRAME is omitted or nil, use the selected frame.
2876 Signal error if FRAME is not an X frame. */)
2877 (Lisp_Object frame)
2879 struct frame *f = decode_window_system_frame (frame);
2881 block_input ();
2882 x_wm_set_size_hint (f, 0, 0);
2883 unblock_input ();
2884 return Qnil;
2887 static void
2888 set_machine_and_pid_properties (struct frame *f)
2890 /* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME. */
2891 XSetWMProperties (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), NULL, NULL,
2892 NULL, 0, NULL, NULL, NULL);
2893 pid_t pid = getpid ();
2894 if (pid <= 0xffffffffu)
2896 unsigned long xpid = pid;
2897 XChangeProperty (FRAME_X_DISPLAY (f),
2898 FRAME_OUTER_WINDOW (f),
2899 XInternAtom (FRAME_X_DISPLAY (f),
2900 "_NET_WM_PID",
2901 False),
2902 XA_CARDINAL, 32, PropModeReplace,
2903 (unsigned char *) &xpid, 1);
2907 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
2908 1, 1, 0,
2909 doc: /* Make a new X window, which is called a "frame" in Emacs terms.
2910 Return an Emacs frame object. PARMS is an alist of frame parameters.
2911 If the parameters specify that the frame should not have a minibuffer,
2912 and do not specify a specific minibuffer window to use, then
2913 `default-minibuffer-frame' must be a frame whose minibuffer can be
2914 shared by the new frame.
2916 This function is an internal primitive--use `make-frame' instead. */)
2917 (Lisp_Object parms)
2919 struct frame *f;
2920 Lisp_Object frame, tem;
2921 Lisp_Object name;
2922 int minibuffer_only = 0;
2923 long window_prompting = 0;
2924 ptrdiff_t count = SPECPDL_INDEX ();
2925 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
2926 Lisp_Object display;
2927 struct x_display_info *dpyinfo = NULL;
2928 Lisp_Object parent;
2929 struct kboard *kb;
2931 parms = Fcopy_alist (parms);
2933 /* Use this general default value to start with
2934 until we know if this frame has a specified name. */
2935 Vx_resource_name = Vinvocation_name;
2937 display = x_get_arg (dpyinfo, parms, Qterminal, 0, 0, RES_TYPE_NUMBER);
2938 if (EQ (display, Qunbound))
2939 display = x_get_arg (dpyinfo, parms, Qdisplay, 0, 0, RES_TYPE_STRING);
2940 if (EQ (display, Qunbound))
2941 display = Qnil;
2942 dpyinfo = check_x_display_info (display);
2943 kb = dpyinfo->terminal->kboard;
2945 if (!dpyinfo->terminal->name)
2946 error ("Terminal is not live, can't create new frames on it");
2948 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
2949 if (!STRINGP (name)
2950 && ! EQ (name, Qunbound)
2951 && ! NILP (name))
2952 error ("Invalid frame name--not a string or nil");
2954 if (STRINGP (name))
2955 Vx_resource_name = name;
2957 /* See if parent window is specified. */
2958 parent = x_get_arg (dpyinfo, parms, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
2959 if (EQ (parent, Qunbound))
2960 parent = Qnil;
2961 if (! NILP (parent))
2962 CHECK_NUMBER (parent);
2964 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
2965 /* No need to protect DISPLAY because that's not used after passing
2966 it to make_frame_without_minibuffer. */
2967 frame = Qnil;
2968 GCPRO4 (parms, parent, name, frame);
2969 tem = x_get_arg (dpyinfo, parms, Qminibuffer, "minibuffer", "Minibuffer",
2970 RES_TYPE_SYMBOL);
2971 if (EQ (tem, Qnone) || NILP (tem))
2972 f = make_frame_without_minibuffer (Qnil, kb, display);
2973 else if (EQ (tem, Qonly))
2975 f = make_minibuffer_frame ();
2976 minibuffer_only = 1;
2978 else if (WINDOWP (tem))
2979 f = make_frame_without_minibuffer (tem, kb, display);
2980 else
2981 f = make_frame (1);
2983 XSETFRAME (frame, f);
2985 f->terminal = dpyinfo->terminal;
2987 f->output_method = output_x_window;
2988 f->output_data.x = xzalloc (sizeof *f->output_data.x);
2989 f->output_data.x->icon_bitmap = -1;
2990 FRAME_FONTSET (f) = -1;
2991 f->output_data.x->scroll_bar_foreground_pixel = -1;
2992 f->output_data.x->scroll_bar_background_pixel = -1;
2993 #if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
2994 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
2995 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
2996 #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
2997 f->output_data.x->white_relief.pixel = -1;
2998 f->output_data.x->black_relief.pixel = -1;
3000 fset_icon_name (f,
3001 x_get_arg (dpyinfo, parms, Qicon_name, "iconName", "Title",
3002 RES_TYPE_STRING));
3003 if (! STRINGP (f->icon_name))
3004 fset_icon_name (f, Qnil);
3006 FRAME_DISPLAY_INFO (f) = dpyinfo;
3008 /* With FRAME_DISPLAY_INFO set up, this unwind-protect is safe. */
3009 record_unwind_protect (do_unwind_create_frame, frame);
3011 /* These colors will be set anyway later, but it's important
3012 to get the color reference counts right, so initialize them! */
3014 Lisp_Object black;
3015 struct gcpro gcpro1;
3017 /* Function x_decode_color can signal an error. Make
3018 sure to initialize color slots so that we won't try
3019 to free colors we haven't allocated. */
3020 FRAME_FOREGROUND_PIXEL (f) = -1;
3021 FRAME_BACKGROUND_PIXEL (f) = -1;
3022 f->output_data.x->cursor_pixel = -1;
3023 f->output_data.x->cursor_foreground_pixel = -1;
3024 f->output_data.x->border_pixel = -1;
3025 f->output_data.x->mouse_pixel = -1;
3027 black = build_string ("black");
3028 GCPRO1 (black);
3029 FRAME_FOREGROUND_PIXEL (f)
3030 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3031 FRAME_BACKGROUND_PIXEL (f)
3032 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3033 f->output_data.x->cursor_pixel
3034 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3035 f->output_data.x->cursor_foreground_pixel
3036 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3037 f->output_data.x->border_pixel
3038 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3039 f->output_data.x->mouse_pixel
3040 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3041 UNGCPRO;
3044 /* Specify the parent under which to make this X window. */
3045 if (!NILP (parent))
3047 f->output_data.x->parent_desc = (Window) XFASTINT (parent);
3048 f->output_data.x->explicit_parent = 1;
3050 else
3052 f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
3053 f->output_data.x->explicit_parent = 0;
3056 /* Set the name; the functions to which we pass f expect the name to
3057 be set. */
3058 if (EQ (name, Qunbound) || NILP (name))
3060 fset_name (f, build_string (dpyinfo->x_id_name));
3061 f->explicit_name = 0;
3063 else
3065 fset_name (f, name);
3066 f->explicit_name = 1;
3067 /* Use the frame's title when getting resources for this frame. */
3068 specbind (Qx_resource_name, name);
3071 #ifdef HAVE_FREETYPE
3072 #ifdef HAVE_XFT
3073 register_font_driver (&xftfont_driver, f);
3074 #else /* not HAVE_XFT */
3075 register_font_driver (&ftxfont_driver, f);
3076 #endif /* not HAVE_XFT */
3077 #endif /* HAVE_FREETYPE */
3078 register_font_driver (&xfont_driver, f);
3080 x_default_parameter (f, parms, Qfont_backend, Qnil,
3081 "fontBackend", "FontBackend", RES_TYPE_STRING);
3083 /* Extract the window parameters from the supplied values
3084 that are needed to determine window geometry. */
3085 x_default_font_parameter (f, parms);
3086 if (!FRAME_FONT (f))
3088 delete_frame (frame, Qnoelisp);
3089 error ("Invalid frame font");
3092 /* Frame contents get displaced if an embedded X window has a border. */
3093 if (! FRAME_X_EMBEDDED_P (f))
3094 x_default_parameter (f, parms, Qborder_width, make_number (0),
3095 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
3097 /* This defaults to 1 in order to match xterm. We recognize either
3098 internalBorderWidth or internalBorder (which is what xterm calls
3099 it). */
3100 if (NILP (Fassq (Qinternal_border_width, parms)))
3102 Lisp_Object value;
3104 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
3105 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
3106 if (! EQ (value, Qunbound))
3107 parms = Fcons (Fcons (Qinternal_border_width, value),
3108 parms);
3110 x_default_parameter (f, parms, Qinternal_border_width,
3111 #ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */
3112 make_number (0),
3113 #else
3114 make_number (1),
3115 #endif
3116 "internalBorderWidth", "internalBorderWidth",
3117 RES_TYPE_NUMBER);
3118 x_default_parameter (f, parms, Qright_divider_width, make_number (0),
3119 NULL, NULL, RES_TYPE_NUMBER);
3120 x_default_parameter (f, parms, Qbottom_divider_width, make_number (0),
3121 NULL, NULL, RES_TYPE_NUMBER);
3122 x_default_parameter (f, parms, Qvertical_scroll_bars,
3123 #if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
3124 Qright,
3125 #else
3126 Qleft,
3127 #endif
3128 "verticalScrollBars", "ScrollBars",
3129 RES_TYPE_SYMBOL);
3130 x_default_parameter (f, parms, Qhorizontal_scroll_bars, Qnil,
3131 "horizontalScrollBars", "ScrollBars",
3132 RES_TYPE_SYMBOL);
3133 /* Also do the stuff which must be set before the window exists. */
3134 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
3135 "foreground", "Foreground", RES_TYPE_STRING);
3136 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
3137 "background", "Background", RES_TYPE_STRING);
3138 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
3139 "pointerColor", "Foreground", RES_TYPE_STRING);
3140 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
3141 "borderColor", "BorderColor", RES_TYPE_STRING);
3142 x_default_parameter (f, parms, Qscreen_gamma, Qnil,
3143 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
3144 x_default_parameter (f, parms, Qline_spacing, Qnil,
3145 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
3146 x_default_parameter (f, parms, Qleft_fringe, Qnil,
3147 "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
3148 x_default_parameter (f, parms, Qright_fringe, Qnil,
3149 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
3151 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_foreground,
3152 "scrollBarForeground",
3153 "ScrollBarForeground", 1);
3154 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_background,
3155 "scrollBarBackground",
3156 "ScrollBarBackground", 0);
3158 #ifdef GLYPH_DEBUG
3159 image_cache_refcount =
3160 FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
3161 dpyinfo_refcount = dpyinfo->reference_count;
3162 #endif /* GLYPH_DEBUG */
3164 /* Init faces before x_default_parameter is called for the
3165 scroll-bar-width parameter because otherwise we end up in
3166 init_iterator with a null face cache, which should not happen. */
3167 init_frame_faces (f);
3169 /* The following call of change_frame_size is needed since otherwise
3170 x_set_tool_bar_lines will already work with the character sizes
3171 installed by init_frame_faces while the frame's pixel size is
3172 still calculated from a character size of 1 and we subsequently
3173 hit the (height >= 0) assertion in window_box_height.
3175 The non-pixelwise code apparently worked around this because it
3176 had one frame line vs one toolbar line which left us with a zero
3177 root window height which was obviously wrong as well ... */
3178 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
3179 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1, Qnil);
3181 /* Set the menu-bar-lines and tool-bar-lines parameters. We don't
3182 look up the X resources controlling the menu-bar and tool-bar
3183 here; they are processed specially at startup, and reflected in
3184 the values of the mode variables. */
3186 x_default_parameter (f, parms, Qmenu_bar_lines,
3187 NILP (Vmenu_bar_mode)
3188 ? make_number (0) : make_number (1),
3189 NULL, NULL, RES_TYPE_NUMBER);
3190 x_default_parameter (f, parms, Qtool_bar_lines,
3191 NILP (Vtool_bar_mode)
3192 ? make_number (0) : make_number (1),
3193 NULL, NULL, RES_TYPE_NUMBER);
3195 x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
3196 "bufferPredicate", "BufferPredicate",
3197 RES_TYPE_SYMBOL);
3198 x_default_parameter (f, parms, Qtitle, Qnil,
3199 "title", "Title", RES_TYPE_STRING);
3200 x_default_parameter (f, parms, Qwait_for_wm, Qt,
3201 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
3202 x_default_parameter (f, parms, Qfullscreen, Qnil,
3203 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
3204 x_default_parameter (f, parms, Qtool_bar_position,
3205 FRAME_TOOL_BAR_POSITION (f), 0, 0, RES_TYPE_SYMBOL);
3207 /* Compute the size of the X window. */
3208 window_prompting = x_figure_window_size (f, parms, 1);
3210 tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
3211 f->no_split = minibuffer_only || EQ (tem, Qt);
3213 x_icon_verify (f, parms);
3215 /* Create the X widget or window. */
3216 #ifdef USE_X_TOOLKIT
3217 x_window (f, window_prompting, minibuffer_only);
3218 #else
3219 x_window (f);
3220 #endif
3222 x_icon (f, parms);
3223 x_make_gc (f);
3225 /* Now consider the frame official. */
3226 f->terminal->reference_count++;
3227 FRAME_DISPLAY_INFO (f)->reference_count++;
3228 Vframe_list = Fcons (frame, Vframe_list);
3230 /* We need to do this after creating the X window, so that the
3231 icon-creation functions can say whose icon they're describing. */
3232 x_default_parameter (f, parms, Qicon_type, Qt,
3233 "bitmapIcon", "BitmapIcon", RES_TYPE_BOOLEAN);
3235 x_default_parameter (f, parms, Qauto_raise, Qnil,
3236 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3237 x_default_parameter (f, parms, Qauto_lower, Qnil,
3238 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3239 x_default_parameter (f, parms, Qcursor_type, Qbox,
3240 "cursorType", "CursorType", RES_TYPE_SYMBOL);
3241 x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
3242 "scrollBarWidth", "ScrollBarWidth",
3243 RES_TYPE_NUMBER);
3244 x_default_parameter (f, parms, Qscroll_bar_height, Qnil,
3245 "scrollBarHeight", "ScrollBarHeight",
3246 RES_TYPE_NUMBER);
3247 x_default_parameter (f, parms, Qalpha, Qnil,
3248 "alpha", "Alpha", RES_TYPE_NUMBER);
3250 /* Consider frame official, now. */
3251 f->can_x_set_window_size = true;
3253 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, 1, Qnil);
3255 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3256 /* Create the menu bar. */
3257 if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
3259 /* If this signals an error, we haven't set size hints for the
3260 frame and we didn't make it visible. */
3261 initialize_frame_menubar (f);
3263 #ifndef USE_GTK
3264 /* This is a no-op, except under Motif where it arranges the
3265 main window for the widgets on it. */
3266 lw_set_main_areas (f->output_data.x->column_widget,
3267 f->output_data.x->menubar_widget,
3268 f->output_data.x->edit_widget);
3269 #endif /* not USE_GTK */
3271 #endif /* USE_X_TOOLKIT || USE_GTK */
3273 /* Tell the server what size and position, etc, we want, and how
3274 badly we want them. This should be done after we have the menu
3275 bar so that its size can be taken into account. */
3276 block_input ();
3277 x_wm_set_size_hint (f, window_prompting, 0);
3278 unblock_input ();
3280 /* Make the window appear on the frame and enable display, unless
3281 the caller says not to. However, with explicit parent, Emacs
3282 cannot control visibility, so don't try. */
3283 if (! f->output_data.x->explicit_parent)
3285 Lisp_Object visibility;
3287 visibility = x_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
3288 RES_TYPE_SYMBOL);
3289 if (EQ (visibility, Qunbound))
3290 visibility = Qt;
3292 if (EQ (visibility, Qicon))
3293 x_iconify_frame (f);
3294 else if (! NILP (visibility))
3295 x_make_frame_visible (f);
3296 else
3298 /* Must have been Qnil. */
3302 block_input ();
3304 /* Set machine name and pid for the purpose of window managers. */
3305 set_machine_and_pid_properties (f);
3307 /* Set the WM leader property. GTK does this itself, so this is not
3308 needed when using GTK. */
3309 if (dpyinfo->client_leader_window != 0)
3311 XChangeProperty (FRAME_X_DISPLAY (f),
3312 FRAME_OUTER_WINDOW (f),
3313 dpyinfo->Xatom_wm_client_leader,
3314 XA_WINDOW, 32, PropModeReplace,
3315 (unsigned char *) &dpyinfo->client_leader_window, 1);
3318 unblock_input ();
3320 /* Initialize `default-minibuffer-frame' in case this is the first
3321 frame on this terminal. */
3322 if (FRAME_HAS_MINIBUF_P (f)
3323 && (!FRAMEP (KVAR (kb, Vdefault_minibuffer_frame))
3324 || !FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame)))))
3325 kset_default_minibuffer_frame (kb, frame);
3327 /* All remaining specified parameters, which have not been "used"
3328 by x_get_arg and friends, now go in the misc. alist of the frame. */
3329 for (tem = parms; CONSP (tem); tem = XCDR (tem))
3330 if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
3331 fset_param_alist (f, Fcons (XCAR (tem), f->param_alist));
3333 UNGCPRO;
3335 /* Make sure windows on this frame appear in calls to next-window
3336 and similar functions. */
3337 Vwindow_list = Qnil;
3339 return unbind_to (count, frame);
3343 /* FRAME is used only to get a handle on the X display. We don't pass the
3344 display info directly because we're called from frame.c, which doesn't
3345 know about that structure. */
3347 Lisp_Object
3348 x_get_focus_frame (struct frame *frame)
3350 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (frame);
3351 Lisp_Object xfocus;
3352 if (! dpyinfo->x_focus_frame)
3353 return Qnil;
3355 XSETFRAME (xfocus, dpyinfo->x_focus_frame);
3356 return xfocus;
3360 /* In certain situations, when the window manager follows a
3361 click-to-focus policy, there seems to be no way around calling
3362 XSetInputFocus to give another frame the input focus .
3364 In an ideal world, XSetInputFocus should generally be avoided so
3365 that applications don't interfere with the window manager's focus
3366 policy. But I think it's okay to use when it's clearly done
3367 following a user-command. */
3369 void
3370 x_focus_frame (struct frame *f)
3372 Display *dpy = FRAME_X_DISPLAY (f);
3374 block_input ();
3375 x_catch_errors (dpy);
3377 if (FRAME_X_EMBEDDED_P (f))
3379 /* For Xembedded frames, normally the embedder forwards key
3380 events. See XEmbed Protocol Specification at
3381 http://freedesktop.org/wiki/Specifications/xembed-spec */
3382 xembed_request_focus (f);
3384 else
3386 XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3387 RevertToParent, CurrentTime);
3388 x_ewmh_activate_frame (f);
3391 x_uncatch_errors ();
3392 unblock_input ();
3396 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
3397 doc: /* Internal function called by `color-defined-p', which see
3398 .\(Note that the Nextstep version of this function ignores FRAME.) */)
3399 (Lisp_Object color, Lisp_Object frame)
3401 XColor foo;
3402 struct frame *f = decode_window_system_frame (frame);
3404 CHECK_STRING (color);
3406 if (x_defined_color (f, SSDATA (color), &foo, 0))
3407 return Qt;
3408 else
3409 return Qnil;
3412 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
3413 doc: /* Internal function called by `color-values', which see. */)
3414 (Lisp_Object color, Lisp_Object frame)
3416 XColor foo;
3417 struct frame *f = decode_window_system_frame (frame);
3419 CHECK_STRING (color);
3421 if (x_defined_color (f, SSDATA (color), &foo, 0))
3422 return list3i (foo.red, foo.green, foo.blue);
3423 else
3424 return Qnil;
3427 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
3428 doc: /* Internal function called by `display-color-p', which see. */)
3429 (Lisp_Object terminal)
3431 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3433 if (dpyinfo->n_planes <= 2)
3434 return Qnil;
3436 switch (dpyinfo->visual->class)
3438 case StaticColor:
3439 case PseudoColor:
3440 case TrueColor:
3441 case DirectColor:
3442 return Qt;
3444 default:
3445 return Qnil;
3449 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
3450 0, 1, 0,
3451 doc: /* Return t if the X display supports shades of gray.
3452 Note that color displays do support shades of gray.
3453 The optional argument TERMINAL specifies which display to ask about.
3454 TERMINAL should be a terminal object, a frame or a display name (a string).
3455 If omitted or nil, that stands for the selected frame's display. */)
3456 (Lisp_Object terminal)
3458 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3460 if (dpyinfo->n_planes <= 1)
3461 return Qnil;
3463 switch (dpyinfo->visual->class)
3465 case StaticColor:
3466 case PseudoColor:
3467 case TrueColor:
3468 case DirectColor:
3469 case StaticGray:
3470 case GrayScale:
3471 return Qt;
3473 default:
3474 return Qnil;
3478 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
3479 0, 1, 0,
3480 doc: /* Return the width in pixels of the X display TERMINAL.
3481 The optional argument TERMINAL specifies which display to ask about.
3482 TERMINAL should be a terminal object, a frame or a display name (a string).
3483 If omitted or nil, that stands for the selected frame's display.
3485 On \"multi-monitor\" setups this refers to the pixel width for all
3486 physical monitors associated with TERMINAL. To get information for
3487 each physical monitor, use `display-monitor-attributes-list'. */)
3488 (Lisp_Object terminal)
3490 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3492 return make_number (x_display_pixel_width (dpyinfo));
3495 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
3496 Sx_display_pixel_height, 0, 1, 0,
3497 doc: /* Return the height in pixels of the X display TERMINAL.
3498 The optional argument TERMINAL specifies which display to ask about.
3499 TERMINAL should be a terminal object, a frame or a display name (a string).
3500 If omitted or nil, that stands for the selected frame's display.
3502 On \"multi-monitor\" setups this refers to the pixel height for all
3503 physical monitors associated with TERMINAL. To get information for
3504 each physical monitor, use `display-monitor-attributes-list'. */)
3505 (Lisp_Object terminal)
3507 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3509 return make_number (x_display_pixel_height (dpyinfo));
3512 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
3513 0, 1, 0,
3514 doc: /* Return the number of bitplanes of the X display TERMINAL.
3515 The optional argument TERMINAL specifies which display to ask about.
3516 TERMINAL should be a terminal object, a frame or a display name (a string).
3517 If omitted or nil, that stands for the selected frame's display. */)
3518 (Lisp_Object terminal)
3520 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3522 return make_number (dpyinfo->n_planes);
3525 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
3526 0, 1, 0,
3527 doc: /* Return the number of color cells of the X display TERMINAL.
3528 The optional argument TERMINAL specifies which display to ask about.
3529 TERMINAL should be a terminal object, a frame or a display name (a string).
3530 If omitted or nil, that stands for the selected frame's display. */)
3531 (Lisp_Object terminal)
3533 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3535 int nr_planes = DisplayPlanes (dpyinfo->display,
3536 XScreenNumberOfScreen (dpyinfo->screen));
3538 /* Truncate nr_planes to 24 to avoid integer overflow.
3539 Some displays says 32, but only 24 bits are actually significant.
3540 There are only very few and rare video cards that have more than
3541 24 significant bits. Also 24 bits is more than 16 million colors,
3542 it "should be enough for everyone". */
3543 if (nr_planes > 24) nr_planes = 24;
3545 return make_number (1 << nr_planes);
3548 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
3549 Sx_server_max_request_size,
3550 0, 1, 0,
3551 doc: /* Return the maximum request size of the X server of display TERMINAL.
3552 The optional argument TERMINAL specifies which display to ask about.
3553 TERMINAL should be a terminal object, a frame or a display name (a string).
3554 If omitted or nil, that stands for the selected frame's display. */)
3555 (Lisp_Object terminal)
3557 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3559 return make_number (MAXREQUEST (dpyinfo->display));
3562 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
3563 doc: /* Return the "vendor ID" string of the X server of display TERMINAL.
3564 \(Labeling every distributor as a "vendor" embodies the false assumption
3565 that operating systems cannot be developed and distributed noncommercially.)
3566 The optional argument TERMINAL specifies which display to ask about.
3567 TERMINAL should be a terminal object, a frame or a display name (a string).
3568 If omitted or nil, that stands for the selected frame's display. */)
3569 (Lisp_Object terminal)
3571 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3572 const char *vendor = ServerVendor (dpyinfo->display);
3574 if (! vendor) vendor = "";
3575 return build_string (vendor);
3578 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
3579 doc: /* Return the version numbers of the X server of display TERMINAL.
3580 The value is a list of three integers: the major and minor
3581 version numbers of the X Protocol in use, and the distributor-specific release
3582 number. See also the function `x-server-vendor'.
3584 The optional argument TERMINAL specifies which display to ask about.
3585 TERMINAL should be a terminal object, a frame or a display name (a string).
3586 If omitted or nil, that stands for the selected frame's display. */)
3587 (Lisp_Object terminal)
3589 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3590 Display *dpy = dpyinfo->display;
3592 return list3i (ProtocolVersion (dpy), ProtocolRevision (dpy),
3593 VendorRelease (dpy));
3596 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
3597 doc: /* Return the number of screens on the X server of display TERMINAL.
3598 The optional argument TERMINAL specifies which display to ask about.
3599 TERMINAL should be a terminal object, a frame or a display name (a string).
3600 If omitted or nil, that stands for the selected frame's display. */)
3601 (Lisp_Object terminal)
3603 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3605 return make_number (ScreenCount (dpyinfo->display));
3608 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
3609 doc: /* Return the height in millimeters of the X display TERMINAL.
3610 The optional argument TERMINAL specifies which display to ask about.
3611 TERMINAL should be a terminal object, a frame or a display name (a string).
3612 If omitted or nil, that stands for the selected frame's display.
3614 On \"multi-monitor\" setups this refers to the height in millimeters for
3615 all physical monitors associated with TERMINAL. To get information
3616 for each physical monitor, use `display-monitor-attributes-list'. */)
3617 (Lisp_Object terminal)
3619 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3621 return make_number (HeightMMOfScreen (dpyinfo->screen));
3624 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
3625 doc: /* Return the width in millimeters of the X display TERMINAL.
3626 The optional argument TERMINAL specifies which display to ask about.
3627 TERMINAL should be a terminal object, a frame or a display name (a string).
3628 If omitted or nil, that stands for the selected frame's display.
3630 On \"multi-monitor\" setups this refers to the width in millimeters for
3631 all physical monitors associated with TERMINAL. To get information
3632 for each physical monitor, use `display-monitor-attributes-list'. */)
3633 (Lisp_Object terminal)
3635 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3637 return make_number (WidthMMOfScreen (dpyinfo->screen));
3640 DEFUN ("x-display-backing-store", Fx_display_backing_store,
3641 Sx_display_backing_store, 0, 1, 0,
3642 doc: /* Return an indication of whether X display TERMINAL does backing store.
3643 The value may be `always', `when-mapped', or `not-useful'.
3644 The optional argument TERMINAL specifies which display to ask about.
3645 TERMINAL should be a terminal object, a frame or a display name (a string).
3646 If omitted or nil, that stands for the selected frame's display. */)
3647 (Lisp_Object terminal)
3649 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3650 Lisp_Object result;
3652 switch (DoesBackingStore (dpyinfo->screen))
3654 case Always:
3655 result = intern ("always");
3656 break;
3658 case WhenMapped:
3659 result = intern ("when-mapped");
3660 break;
3662 case NotUseful:
3663 result = intern ("not-useful");
3664 break;
3666 default:
3667 error ("Strange value for BackingStore parameter of screen");
3670 return result;
3673 DEFUN ("x-display-visual-class", Fx_display_visual_class,
3674 Sx_display_visual_class, 0, 1, 0,
3675 doc: /* Return the visual class of the X display TERMINAL.
3676 The value is one of the symbols `static-gray', `gray-scale',
3677 `static-color', `pseudo-color', `true-color', or `direct-color'.
3679 The optional argument TERMINAL specifies which display to ask about.
3680 TERMINAL should a terminal object, a frame or a display name (a string).
3681 If omitted or nil, that stands for the selected frame's display. */)
3682 (Lisp_Object terminal)
3684 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3685 Lisp_Object result;
3687 switch (dpyinfo->visual->class)
3689 case StaticGray:
3690 result = intern ("static-gray");
3691 break;
3692 case GrayScale:
3693 result = intern ("gray-scale");
3694 break;
3695 case StaticColor:
3696 result = intern ("static-color");
3697 break;
3698 case PseudoColor:
3699 result = intern ("pseudo-color");
3700 break;
3701 case TrueColor:
3702 result = intern ("true-color");
3703 break;
3704 case DirectColor:
3705 result = intern ("direct-color");
3706 break;
3707 default:
3708 error ("Display has an unknown visual class");
3711 return result;
3714 DEFUN ("x-display-save-under", Fx_display_save_under,
3715 Sx_display_save_under, 0, 1, 0,
3716 doc: /* Return t if the X display TERMINAL supports the save-under feature.
3717 The optional argument TERMINAL specifies which display to ask about.
3718 TERMINAL should be a terminal object, a frame or a display name (a string).
3719 If omitted or nil, that stands for the selected frame's display. */)
3720 (Lisp_Object terminal)
3722 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3724 if (DoesSaveUnders (dpyinfo->screen) == True)
3725 return Qt;
3726 else
3727 return Qnil;
3730 /* Store the geometry of the workarea on display DPYINFO into *RECT.
3731 Return false if and only if the workarea information cannot be
3732 obtained via the _NET_WORKAREA root window property. */
3734 #if ! GTK_CHECK_VERSION (3, 4, 0)
3735 static bool
3736 x_get_net_workarea (struct x_display_info *dpyinfo, XRectangle *rect)
3738 Display *dpy = dpyinfo->display;
3739 long offset, max_len;
3740 Atom target_type, actual_type;
3741 unsigned long actual_size, bytes_remaining;
3742 int rc, actual_format;
3743 unsigned char *tmp_data = NULL;
3744 bool result = false;
3746 x_catch_errors (dpy);
3747 offset = 0;
3748 max_len = 1;
3749 target_type = XA_CARDINAL;
3750 rc = XGetWindowProperty (dpy, dpyinfo->root_window,
3751 dpyinfo->Xatom_net_current_desktop,
3752 offset, max_len, False, target_type,
3753 &actual_type, &actual_format, &actual_size,
3754 &bytes_remaining, &tmp_data);
3755 if (rc == Success && actual_type == target_type && !x_had_errors_p (dpy)
3756 && actual_format == 32 && actual_size == max_len)
3758 long current_desktop = ((long *) tmp_data)[0];
3760 XFree (tmp_data);
3761 tmp_data = NULL;
3763 offset = 4 * current_desktop;
3764 max_len = 4;
3765 rc = XGetWindowProperty (dpy, dpyinfo->root_window,
3766 dpyinfo->Xatom_net_workarea,
3767 offset, max_len, False, target_type,
3768 &actual_type, &actual_format, &actual_size,
3769 &bytes_remaining, &tmp_data);
3770 if (rc == Success && actual_type == target_type && !x_had_errors_p (dpy)
3771 && actual_format == 32 && actual_size == max_len)
3773 long *values = (long *) tmp_data;
3775 rect->x = values[0];
3776 rect->y = values[1];
3777 rect->width = values[2];
3778 rect->height = values[3];
3780 XFree (tmp_data);
3781 tmp_data = NULL;
3783 result = true;
3786 if (tmp_data)
3787 XFree (tmp_data);
3788 x_uncatch_errors ();
3790 return result;
3792 #endif
3794 #ifndef USE_GTK
3796 /* Return monitor number where F is "most" or closest to. */
3797 static int
3798 x_get_monitor_for_frame (struct frame *f,
3799 struct MonitorInfo *monitors,
3800 int n_monitors)
3802 XRectangle frect;
3803 int area = 0, dist = -1;
3804 int best_area = -1, best_dist = -1;
3805 int i;
3807 if (n_monitors == 1) return 0;
3808 frect.x = f->left_pos;
3809 frect.y = f->top_pos;
3810 frect.width = FRAME_PIXEL_WIDTH (f);
3811 frect.height = FRAME_PIXEL_HEIGHT (f);
3813 for (i = 0; i < n_monitors; ++i)
3815 struct MonitorInfo *mi = &monitors[i];
3816 XRectangle res;
3817 int a = 0;
3819 if (mi->geom.width == 0) continue;
3821 if (x_intersect_rectangles (&mi->geom, &frect, &res))
3823 a = res.width * res.height;
3824 if (a > area)
3826 area = a;
3827 best_area = i;
3831 if (a == 0 && area == 0)
3833 int dx, dy, d;
3834 if (frect.x + frect.width < mi->geom.x)
3835 dx = mi->geom.x - frect.x + frect.width;
3836 else if (frect.x > mi->geom.x + mi->geom.width)
3837 dx = frect.x - mi->geom.x + mi->geom.width;
3838 else
3839 dx = 0;
3840 if (frect.y + frect.height < mi->geom.y)
3841 dy = mi->geom.y - frect.y + frect.height;
3842 else if (frect.y > mi->geom.y + mi->geom.height)
3843 dy = frect.y - mi->geom.y + mi->geom.height;
3844 else
3845 dy = 0;
3847 d = dx*dx + dy*dy;
3848 if (dist == -1 || dist > d)
3850 dist = d;
3851 best_dist = i;
3856 return best_area != -1 ? best_area : (best_dist != -1 ? best_dist : 0);
3859 static Lisp_Object
3860 x_make_monitor_attribute_list (struct MonitorInfo *monitors,
3861 int n_monitors,
3862 int primary_monitor,
3863 struct x_display_info *dpyinfo,
3864 const char *source)
3866 Lisp_Object monitor_frames = Fmake_vector (make_number (n_monitors), Qnil);
3867 Lisp_Object frame, rest;
3869 FOR_EACH_FRAME (rest, frame)
3871 struct frame *f = XFRAME (frame);
3873 if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo
3874 && !EQ (frame, tip_frame))
3876 int i = x_get_monitor_for_frame (f, monitors, n_monitors);
3877 ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
3881 return make_monitor_attribute_list (monitors, n_monitors, primary_monitor,
3882 monitor_frames, source);
3885 static Lisp_Object
3886 x_get_monitor_attributes_fallback (struct x_display_info *dpyinfo)
3888 struct MonitorInfo monitor;
3889 XRectangle workarea_r;
3891 /* Fallback: treat (possibly) multiple physical monitors as if they
3892 formed a single monitor as a whole. This should provide a
3893 consistent result at least on single monitor environments. */
3894 monitor.geom.x = monitor.geom.y = 0;
3895 monitor.geom.width = x_display_pixel_width (dpyinfo);
3896 monitor.geom.height = x_display_pixel_height (dpyinfo);
3897 monitor.mm_width = WidthMMOfScreen (dpyinfo->screen);
3898 monitor.mm_height = HeightMMOfScreen (dpyinfo->screen);
3899 monitor.name = xstrdup ("combined screen");
3901 if (x_get_net_workarea (dpyinfo, &workarea_r))
3902 monitor.work = workarea_r;
3903 else
3904 monitor.work = monitor.geom;
3905 return x_make_monitor_attribute_list (&monitor, 1, 0, dpyinfo, "fallback");
3909 #ifdef HAVE_XINERAMA
3910 static Lisp_Object
3911 x_get_monitor_attributes_xinerama (struct x_display_info *dpyinfo)
3913 int n_monitors, i;
3914 Lisp_Object attributes_list = Qnil;
3915 Display *dpy = dpyinfo->display;
3916 XineramaScreenInfo *info = XineramaQueryScreens (dpy, &n_monitors);
3917 struct MonitorInfo *monitors;
3918 double mm_width_per_pixel, mm_height_per_pixel;
3920 if (! info || n_monitors == 0)
3922 if (info)
3923 XFree (info);
3924 return attributes_list;
3927 mm_width_per_pixel = ((double) WidthMMOfScreen (dpyinfo->screen)
3928 / x_display_pixel_width (dpyinfo));
3929 mm_height_per_pixel = ((double) HeightMMOfScreen (dpyinfo->screen)
3930 / x_display_pixel_height (dpyinfo));
3931 monitors = xzalloc (n_monitors * sizeof *monitors);
3932 for (i = 0; i < n_monitors; ++i)
3934 struct MonitorInfo *mi = &monitors[i];
3935 XRectangle workarea_r;
3937 mi->geom.x = info[i].x_org;
3938 mi->geom.y = info[i].y_org;
3939 mi->geom.width = info[i].width;
3940 mi->geom.height = info[i].height;
3941 mi->mm_width = mi->geom.width * mm_width_per_pixel + 0.5;
3942 mi->mm_height = mi->geom.height * mm_height_per_pixel + 0.5;
3943 mi->name = 0;
3945 /* Xinerama usually have primary monitor first, just use that. */
3946 if (i == 0 && x_get_net_workarea (dpyinfo, &workarea_r))
3948 mi->work = workarea_r;
3949 if (! x_intersect_rectangles (&mi->geom, &mi->work, &mi->work))
3950 mi->work = mi->geom;
3952 else
3953 mi->work = mi->geom;
3955 XFree (info);
3957 attributes_list = x_make_monitor_attribute_list (monitors,
3958 n_monitors,
3960 dpyinfo,
3961 "Xinerama");
3962 free_monitors (monitors, n_monitors);
3963 return attributes_list;
3965 #endif /* HAVE_XINERAMA */
3968 #ifdef HAVE_XRANDR
3969 static Lisp_Object
3970 x_get_monitor_attributes_xrandr (struct x_display_info *dpyinfo)
3972 Lisp_Object attributes_list = Qnil;
3973 XRRScreenResources *resources;
3974 Display *dpy = dpyinfo->display;
3975 int i, n_monitors, primary = -1;
3976 RROutput pxid = None;
3977 struct MonitorInfo *monitors;
3979 #ifdef HAVE_XRRGETSCREENRESOURCESCURRENT
3980 resources = XRRGetScreenResourcesCurrent (dpy, dpyinfo->root_window);
3981 #else
3982 resources = XRRGetScreenResources (dpy, dpyinfo->root_window);
3983 #endif
3984 if (! resources || resources->noutput == 0)
3986 if (resources)
3987 XRRFreeScreenResources (resources);
3988 return Qnil;
3990 n_monitors = resources->noutput;
3991 monitors = xzalloc (n_monitors * sizeof *monitors);
3993 #ifdef HAVE_XRRGETOUTPUTPRIMARY
3994 pxid = XRRGetOutputPrimary (dpy, dpyinfo->root_window);
3995 #endif
3997 for (i = 0; i < n_monitors; ++i)
3999 XRROutputInfo *info = XRRGetOutputInfo (dpy, resources,
4000 resources->outputs[i]);
4001 Connection conn = info ? info->connection : RR_Disconnected;
4002 RRCrtc id = info ? info->crtc : None;
4004 if (strcmp (info->name, "default") == 0)
4006 /* Non XRandr 1.2 driver, does not give useful data. */
4007 XRRFreeOutputInfo (info);
4008 XRRFreeScreenResources (resources);
4009 free_monitors (monitors, n_monitors);
4010 return Qnil;
4013 if (conn != RR_Disconnected && id != None)
4015 XRRCrtcInfo *crtc = XRRGetCrtcInfo (dpy, resources, id);
4016 struct MonitorInfo *mi = &monitors[i];
4017 XRectangle workarea_r;
4019 if (! crtc)
4021 XRRFreeOutputInfo (info);
4022 continue;
4025 mi->geom.x = crtc->x;
4026 mi->geom.y = crtc->y;
4027 mi->geom.width = crtc->width;
4028 mi->geom.height = crtc->height;
4029 mi->mm_width = info->mm_width;
4030 mi->mm_height = info->mm_height;
4031 mi->name = xstrdup (info->name);
4033 if (pxid != None && pxid == resources->outputs[i])
4034 primary = i;
4035 else if (primary == -1 && strcmp (info->name, "LVDS") == 0)
4036 primary = i;
4038 if (i == primary && x_get_net_workarea (dpyinfo, &workarea_r))
4040 mi->work= workarea_r;
4041 if (! x_intersect_rectangles (&mi->geom, &mi->work, &mi->work))
4042 mi->work = mi->geom;
4044 else
4045 mi->work = mi->geom;
4047 XRRFreeCrtcInfo (crtc);
4049 XRRFreeOutputInfo (info);
4051 XRRFreeScreenResources (resources);
4053 attributes_list = x_make_monitor_attribute_list (monitors,
4054 n_monitors,
4055 primary,
4056 dpyinfo,
4057 "XRandr");
4058 free_monitors (monitors, n_monitors);
4059 return attributes_list;
4061 #endif /* HAVE_XRANDR */
4063 static Lisp_Object
4064 x_get_monitor_attributes (struct x_display_info *dpyinfo)
4066 Lisp_Object attributes_list = Qnil;
4067 Display *dpy = dpyinfo->display;
4069 (void) dpy; /* Suppress unused variable warning. */
4071 #ifdef HAVE_XRANDR
4072 int xrr_event_base, xrr_error_base;
4073 bool xrr_ok = false;
4074 xrr_ok = XRRQueryExtension (dpy, &xrr_event_base, &xrr_error_base);
4075 if (xrr_ok)
4077 int xrr_major, xrr_minor;
4078 XRRQueryVersion (dpy, &xrr_major, &xrr_minor);
4079 xrr_ok = (xrr_major == 1 && xrr_minor >= 2) || xrr_major > 1;
4082 if (xrr_ok)
4083 attributes_list = x_get_monitor_attributes_xrandr (dpyinfo);
4084 #endif /* HAVE_XRANDR */
4086 #ifdef HAVE_XINERAMA
4087 if (NILP (attributes_list))
4089 int xin_event_base, xin_error_base;
4090 bool xin_ok = false;
4091 xin_ok = XineramaQueryExtension (dpy, &xin_event_base, &xin_error_base);
4092 if (xin_ok && XineramaIsActive (dpy))
4093 attributes_list = x_get_monitor_attributes_xinerama (dpyinfo);
4095 #endif /* HAVE_XINERAMA */
4097 if (NILP (attributes_list))
4098 attributes_list = x_get_monitor_attributes_fallback (dpyinfo);
4100 return attributes_list;
4103 #endif /* !USE_GTK */
4105 DEFUN ("x-display-monitor-attributes-list", Fx_display_monitor_attributes_list,
4106 Sx_display_monitor_attributes_list,
4107 0, 1, 0,
4108 doc: /* Return a list of physical monitor attributes on the X display TERMINAL.
4110 The optional argument TERMINAL specifies which display to ask about.
4111 TERMINAL should be a terminal object, a frame or a display name (a string).
4112 If omitted or nil, that stands for the selected frame's display.
4114 In addition to the standard attribute keys listed in
4115 `display-monitor-attributes-list', the following keys are contained in
4116 the attributes:
4118 source -- String describing the source from which multi-monitor
4119 information is obtained, one of \"Gdk\", \"XRandr\",
4120 \"Xinerama\", or \"fallback\"
4122 Internal use only, use `display-monitor-attributes-list' instead. */)
4123 (Lisp_Object terminal)
4125 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4126 Lisp_Object attributes_list = Qnil;
4128 #ifdef USE_GTK
4129 double mm_width_per_pixel, mm_height_per_pixel;
4130 GdkDisplay *gdpy;
4131 GdkScreen *gscreen;
4132 gint primary_monitor = 0, n_monitors, i;
4133 Lisp_Object monitor_frames, rest, frame;
4134 static const char *source = "Gdk";
4135 struct MonitorInfo *monitors;
4137 block_input ();
4138 mm_width_per_pixel = ((double) WidthMMOfScreen (dpyinfo->screen)
4139 / x_display_pixel_width (dpyinfo));
4140 mm_height_per_pixel = ((double) HeightMMOfScreen (dpyinfo->screen)
4141 / x_display_pixel_height (dpyinfo));
4142 gdpy = gdk_x11_lookup_xdisplay (dpyinfo->display);
4143 gscreen = gdk_display_get_default_screen (gdpy);
4144 #if GTK_CHECK_VERSION (2, 20, 0)
4145 primary_monitor = gdk_screen_get_primary_monitor (gscreen);
4146 #endif
4147 n_monitors = gdk_screen_get_n_monitors (gscreen);
4148 monitor_frames = Fmake_vector (make_number (n_monitors), Qnil);
4149 monitors = xzalloc (n_monitors * sizeof *monitors);
4151 FOR_EACH_FRAME (rest, frame)
4153 struct frame *f = XFRAME (frame);
4155 if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo
4156 && !EQ (frame, tip_frame))
4158 GdkWindow *gwin = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
4160 i = gdk_screen_get_monitor_at_window (gscreen, gwin);
4161 ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
4165 for (i = 0; i < n_monitors; ++i)
4167 gint width_mm = -1, height_mm = -1;
4168 GdkRectangle rec, work;
4169 struct MonitorInfo *mi = &monitors[i];
4171 gdk_screen_get_monitor_geometry (gscreen, i, &rec);
4173 #if GTK_CHECK_VERSION (2, 14, 0)
4174 width_mm = gdk_screen_get_monitor_width_mm (gscreen, i);
4175 height_mm = gdk_screen_get_monitor_height_mm (gscreen, i);
4176 #endif
4177 if (width_mm < 0)
4178 width_mm = rec.width * mm_width_per_pixel + 0.5;
4179 if (height_mm < 0)
4180 height_mm = rec.height * mm_height_per_pixel + 0.5;
4182 #if GTK_CHECK_VERSION (3, 4, 0)
4183 gdk_screen_get_monitor_workarea (gscreen, i, &work);
4184 #else
4185 /* Emulate the behavior of GTK+ 3.4. */
4187 XRectangle workarea_r;
4189 if (i == primary_monitor && x_get_net_workarea (dpyinfo, &workarea_r))
4191 work.x = workarea_r.x;
4192 work.y = workarea_r.y;
4193 work.width = workarea_r.width;
4194 work.height = workarea_r.height;
4195 if (! gdk_rectangle_intersect (&rec, &work, &work))
4196 work = rec;
4198 else
4199 work = rec;
4201 #endif
4204 mi->geom.x = rec.x;
4205 mi->geom.y = rec.y;
4206 mi->geom.width = rec.width;
4207 mi->geom.height = rec.height;
4208 mi->work.x = work.x;
4209 mi->work.y = work.y;
4210 mi->work.width = work.width;
4211 mi->work.height = work.height;
4212 mi->mm_width = width_mm;
4213 mi->mm_height = height_mm;
4215 #if GTK_CHECK_VERSION (2, 14, 0)
4216 mi->name = gdk_screen_get_monitor_plug_name (gscreen, i);
4217 #endif
4220 attributes_list = make_monitor_attribute_list (monitors,
4221 n_monitors,
4222 primary_monitor,
4223 monitor_frames,
4224 source);
4225 unblock_input ();
4226 #else /* not USE_GTK */
4228 block_input ();
4229 attributes_list = x_get_monitor_attributes (dpyinfo);
4230 unblock_input ();
4232 #endif /* not USE_GTK */
4234 return attributes_list;
4237 DEFUN ("x-frame-geometry", Fx_frame_geometry, Sx_frame_geometry, 0, 1, 0,
4238 doc: /* Return geometric attributes of frame FRAME.
4240 FRAME must be a live frame and defaults to the selected one.
4242 The return value is an association list containing the following
4243 elements (all size values are in pixels).
4245 - `frame-outer-size' is a cons of the outer width and height of FRAME.
4246 The outer size include the title bar and the external borders as well
4247 as any menu and/or tool bar of frame.
4249 - `border' is a cons of the horizontal and vertical width of FRAME's
4250 external borders.
4252 - `title-bar-height' is the height of the title bar of FRAME.
4254 - `menu-bar-external' if `t' means the menu bar is external (not
4255 included in the inner edges of FRAME).
4257 - `menu-bar-size' is a cons of the width and height of the menu bar of
4258 FRAME.
4260 - `tool-bar-external' if `t' means the tool bar is external (not
4261 included in the inner edges of FRAME).
4263 - `tool-bar-side' tells tells on which side the tool bar on FRAME is and
4264 can be one of `left', `top', `right' or `bottom'.
4266 - `tool-bar-size' is a cons of the width and height of the tool bar of
4267 FRAME.
4269 - `frame-inner-size' is a cons of the inner width and height of FRAME.
4270 This excludes FRAME's title bar and external border as well as any
4271 external menu and/or tool bar. */)
4272 (Lisp_Object frame)
4274 struct frame *f = decode_live_frame (frame);
4275 int inner_width = FRAME_PIXEL_WIDTH (f);
4276 int inner_height = FRAME_PIXEL_HEIGHT (f);
4277 int outer_width, outer_height, border, title;
4278 Lisp_Object fullscreen = Fframe_parameter (frame, Qfullscreen);
4279 int menu_bar_height, menu_bar_width, tool_bar_height, tool_bar_width;
4281 border = FRAME_OUTER_TO_INNER_DIFF_X (f);
4282 title = FRAME_X_OUTPUT (f)->y_pixels_outer_diff - border;
4284 outer_width = FRAME_PIXEL_WIDTH (f) + 2 * border;
4285 outer_height = (FRAME_PIXEL_HEIGHT (f)
4286 + FRAME_OUTER_TO_INNER_DIFF_Y (f)
4287 + FRAME_OUTER_TO_INNER_DIFF_X (f));
4289 #if defined (USE_GTK)
4291 bool tool_bar_left_right = (EQ (FRAME_TOOL_BAR_POSITION (f), Qleft)
4292 || EQ (FRAME_TOOL_BAR_POSITION (f), Qright));
4294 tool_bar_width = (tool_bar_left_right
4295 ? FRAME_TOOLBAR_WIDTH (f)
4296 : FRAME_PIXEL_WIDTH (f));
4297 tool_bar_height = (tool_bar_left_right
4298 ? FRAME_PIXEL_HEIGHT (f)
4299 : FRAME_TOOLBAR_HEIGHT (f));
4300 if (tool_bar_left_right)
4301 /* For some reason FRAME_OUTER_TO_INNER_DIFF_X does not count the
4302 width of a tool bar. */
4303 outer_width += FRAME_TOOLBAR_WIDTH (f);
4305 #else
4306 tool_bar_height = FRAME_TOOL_BAR_HEIGHT (f);
4307 tool_bar_width = ((tool_bar_height > 0)
4308 ? outer_width - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)
4309 : 0);
4310 #endif
4312 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
4313 menu_bar_height = FRAME_MENUBAR_HEIGHT (f);
4314 #else
4315 menu_bar_height = FRAME_MENU_BAR_HEIGHT (f);
4316 #endif
4318 menu_bar_width = ((menu_bar_height > 0)
4319 ? outer_width - 2 * border
4320 : 0);
4322 if (!FRAME_EXTERNAL_MENU_BAR (f))
4323 inner_height -= menu_bar_height;
4324 if (!FRAME_EXTERNAL_TOOL_BAR (f))
4325 inner_height -= tool_bar_height;
4327 return
4328 listn (CONSTYPE_PURE, 10,
4329 Fcons (Qframe_position,
4330 Fcons (make_number (f->left_pos), make_number (f->top_pos))),
4331 Fcons (Qframe_outer_size,
4332 Fcons (make_number (outer_width), make_number (outer_height))),
4333 Fcons (Qexternal_border_size,
4334 ((EQ (fullscreen, Qfullboth) || EQ (fullscreen, Qfullscreen))
4335 ? Fcons (make_number (0), make_number (0))
4336 : Fcons (make_number (border), make_number (border)))),
4337 Fcons (Qtitle_height,
4338 ((EQ (fullscreen, Qfullboth) || EQ (fullscreen, Qfullscreen))
4339 ? make_number (0)
4340 : make_number (title))),
4341 Fcons (Qmenu_bar_external, FRAME_EXTERNAL_MENU_BAR (f) ? Qt : Qnil),
4342 Fcons (Qmenu_bar_size,
4343 Fcons (make_number (menu_bar_width),
4344 make_number (menu_bar_height))),
4345 Fcons (Qtool_bar_external, FRAME_EXTERNAL_TOOL_BAR (f) ? Qt : Qnil),
4346 Fcons (Qtool_bar_position, FRAME_TOOL_BAR_POSITION (f)),
4347 Fcons (Qtool_bar_size,
4348 Fcons (make_number (tool_bar_width),
4349 make_number (tool_bar_height))),
4350 Fcons (Qframe_inner_size,
4351 Fcons (make_number (inner_width),
4352 make_number (inner_height))));
4355 /************************************************************************
4356 X Displays
4357 ************************************************************************/
4360 /* Mapping visual names to visuals. */
4362 static struct visual_class
4364 const char *name;
4365 int class;
4367 visual_classes[] =
4369 {"StaticGray", StaticGray},
4370 {"GrayScale", GrayScale},
4371 {"StaticColor", StaticColor},
4372 {"PseudoColor", PseudoColor},
4373 {"TrueColor", TrueColor},
4374 {"DirectColor", DirectColor},
4375 {NULL, 0}
4379 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4381 /* Value is the screen number of screen SCR. This is a substitute for
4382 the X function with the same name when that doesn't exist. */
4385 XScreenNumberOfScreen (scr)
4386 register Screen *scr;
4388 Display *dpy = scr->display;
4389 int i;
4391 for (i = 0; i < dpy->nscreens; ++i)
4392 if (scr == dpy->screens + i)
4393 break;
4395 return i;
4398 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4401 /* Select the visual that should be used on display DPYINFO. Set
4402 members of DPYINFO appropriately. Called from x_term_init. */
4404 void
4405 select_visual (struct x_display_info *dpyinfo)
4407 Display *dpy = dpyinfo->display;
4408 Screen *screen = dpyinfo->screen;
4410 /* See if a visual is specified. */
4411 AUTO_STRING (visualClass, "visualClass");
4412 AUTO_STRING (VisualClass, "VisualClass");
4413 Lisp_Object value = display_x_get_resource (dpyinfo, visualClass,
4414 VisualClass, Qnil, Qnil);
4416 if (STRINGP (value))
4418 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
4419 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
4420 depth, a decimal number. NAME is compared with case ignored. */
4421 char *s = alloca (SBYTES (value) + 1);
4422 char *dash;
4423 int i, class = -1;
4424 XVisualInfo vinfo;
4426 lispstpcpy (s, value);
4427 dash = strchr (s, '-');
4428 if (dash)
4430 dpyinfo->n_planes = atoi (dash + 1);
4431 *dash = '\0';
4433 else
4434 /* We won't find a matching visual with depth 0, so that
4435 an error will be printed below. */
4436 dpyinfo->n_planes = 0;
4438 /* Determine the visual class. */
4439 for (i = 0; visual_classes[i].name; ++i)
4440 if (xstrcasecmp (s, visual_classes[i].name) == 0)
4442 class = visual_classes[i].class;
4443 break;
4446 /* Look up a matching visual for the specified class. */
4447 if (class == -1
4448 || !XMatchVisualInfo (dpy, XScreenNumberOfScreen (screen),
4449 dpyinfo->n_planes, class, &vinfo))
4450 fatal ("Invalid visual specification `%s'", SDATA (value));
4452 dpyinfo->visual = vinfo.visual;
4454 else
4456 int n_visuals;
4457 XVisualInfo *vinfo, vinfo_template;
4459 dpyinfo->visual = DefaultVisualOfScreen (screen);
4461 vinfo_template.visualid = XVisualIDFromVisual (dpyinfo->visual);
4462 vinfo_template.screen = XScreenNumberOfScreen (screen);
4463 vinfo = XGetVisualInfo (dpy, VisualIDMask | VisualScreenMask,
4464 &vinfo_template, &n_visuals);
4465 if (n_visuals <= 0)
4466 fatal ("Can't get proper X visual info");
4468 dpyinfo->n_planes = vinfo->depth;
4469 XFree (vinfo);
4474 /* Return the X display structure for the display named NAME.
4475 Open a new connection if necessary. */
4477 static struct x_display_info *
4478 x_display_info_for_name (Lisp_Object name)
4480 struct x_display_info *dpyinfo;
4482 CHECK_STRING (name);
4484 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
4485 if (!NILP (Fstring_equal (XCAR (dpyinfo->name_list_element), name)))
4486 return dpyinfo;
4488 /* Use this general default value to start with. */
4489 Vx_resource_name = Vinvocation_name;
4491 validate_x_resource_name ();
4493 dpyinfo = x_term_init (name, 0, SSDATA (Vx_resource_name));
4495 if (dpyinfo == 0)
4496 error ("Cannot connect to X server %s", SDATA (name));
4498 XSETFASTINT (Vwindow_system_version, 11);
4500 return dpyinfo;
4504 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
4505 1, 3, 0,
4506 doc: /* Open a connection to a display server.
4507 DISPLAY is the name of the display to connect to.
4508 Optional second arg XRM-STRING is a string of resources in xrdb format.
4509 If the optional third arg MUST-SUCCEED is non-nil,
4510 terminate Emacs if we can't open the connection.
4511 \(In the Nextstep version, the last two arguments are currently ignored.) */)
4512 (Lisp_Object display, Lisp_Object xrm_string, Lisp_Object must_succeed)
4514 char *xrm_option;
4515 struct x_display_info *dpyinfo;
4517 CHECK_STRING (display);
4518 if (! NILP (xrm_string))
4519 CHECK_STRING (xrm_string);
4521 xrm_option = NILP (xrm_string) ? 0 : SSDATA (xrm_string);
4523 validate_x_resource_name ();
4525 /* This is what opens the connection and sets x_current_display.
4526 This also initializes many symbols, such as those used for input. */
4527 dpyinfo = x_term_init (display, xrm_option,
4528 SSDATA (Vx_resource_name));
4530 if (dpyinfo == 0)
4532 if (!NILP (must_succeed))
4533 fatal ("Cannot connect to X server %s.\n\
4534 Check the DISPLAY environment variable or use `-d'.\n\
4535 Also use the `xauth' program to verify that you have the proper\n\
4536 authorization information needed to connect the X server.\n\
4537 An insecure way to solve the problem may be to use `xhost'.\n",
4538 SDATA (display));
4539 else
4540 error ("Cannot connect to X server %s", SDATA (display));
4543 XSETFASTINT (Vwindow_system_version, 11);
4544 return Qnil;
4547 DEFUN ("x-close-connection", Fx_close_connection,
4548 Sx_close_connection, 1, 1, 0,
4549 doc: /* Close the connection to TERMINAL's X server.
4550 For TERMINAL, specify a terminal object, a frame or a display name (a
4551 string). If TERMINAL is nil, that stands for the selected frame's
4552 terminal. */)
4553 (Lisp_Object terminal)
4555 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4557 if (dpyinfo->reference_count > 0)
4558 error ("Display still has frames on it");
4560 x_delete_terminal (dpyinfo->terminal);
4562 return Qnil;
4565 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
4566 doc: /* Return the list of display names that Emacs has connections to. */)
4567 (void)
4569 Lisp_Object result = Qnil;
4570 struct x_display_info *xdi;
4572 for (xdi = x_display_list; xdi; xdi = xdi->next)
4573 result = Fcons (XCAR (xdi->name_list_element), result);
4575 return result;
4578 DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
4579 doc: /* If ON is non-nil, report X errors as soon as the erring request is made.
4580 This function only has an effect on X Windows. With MS Windows, it is
4581 defined but does nothing.
4583 If ON is nil, allow buffering of requests.
4584 Turning on synchronization prohibits the Xlib routines from buffering
4585 requests and seriously degrades performance, but makes debugging much
4586 easier.
4587 The optional second argument TERMINAL specifies which display to act on.
4588 TERMINAL should be a terminal object, a frame or a display name (a string).
4589 If TERMINAL is omitted or nil, that stands for the selected frame's display. */)
4590 (Lisp_Object on, Lisp_Object terminal)
4592 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4594 XSynchronize (dpyinfo->display, !EQ (on, Qnil));
4596 return Qnil;
4599 /* Wait for responses to all X commands issued so far for frame F. */
4601 void
4602 x_sync (struct frame *f)
4604 block_input ();
4605 XSync (FRAME_X_DISPLAY (f), False);
4606 unblock_input ();
4610 /***********************************************************************
4611 Window properties
4612 ***********************************************************************/
4614 DEFUN ("x-change-window-property", Fx_change_window_property,
4615 Sx_change_window_property, 2, 6, 0,
4616 doc: /* Change window property PROP to VALUE on the X window of FRAME.
4617 PROP must be a string. VALUE may be a string or a list of conses,
4618 numbers and/or strings. If an element in the list is a string, it is
4619 converted to an atom and the value of the atom is used. If an element
4620 is a cons, it is converted to a 32 bit number where the car is the 16
4621 top bits and the cdr is the lower 16 bits.
4623 FRAME nil or omitted means use the selected frame.
4624 If TYPE is given and non-nil, it is the name of the type of VALUE.
4625 If TYPE is not given or nil, the type is STRING.
4626 FORMAT gives the size in bits of each element if VALUE is a list.
4627 It must be one of 8, 16 or 32.
4628 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
4629 If OUTER-P is non-nil, the property is changed for the outer X window of
4630 FRAME. Default is to change on the edit X window. */)
4631 (Lisp_Object prop, Lisp_Object value, Lisp_Object frame,
4632 Lisp_Object type, Lisp_Object format, Lisp_Object outer_p)
4634 struct frame *f = decode_window_system_frame (frame);
4635 Atom prop_atom;
4636 Atom target_type = XA_STRING;
4637 int element_format = 8;
4638 unsigned char *data;
4639 int nelements;
4640 Window w;
4642 CHECK_STRING (prop);
4644 if (! NILP (format))
4646 CHECK_NUMBER (format);
4648 if (XINT (format) != 8 && XINT (format) != 16
4649 && XINT (format) != 32)
4650 error ("FORMAT must be one of 8, 16 or 32");
4651 element_format = XINT (format);
4654 if (CONSP (value))
4656 ptrdiff_t elsize;
4658 nelements = x_check_property_data (value);
4659 if (nelements == -1)
4660 error ("Bad data in VALUE, must be number, string or cons");
4662 /* The man page for XChangeProperty:
4663 "If the specified format is 32, the property data must be a
4664 long array."
4665 This applies even if long is more than 32 bits. The X library
4666 converts to 32 bits before sending to the X server. */
4667 elsize = element_format == 32 ? sizeof (long) : element_format >> 3;
4668 data = xnmalloc (nelements, elsize);
4670 x_fill_property_data (FRAME_X_DISPLAY (f), value, data, element_format);
4672 else
4674 CHECK_STRING (value);
4675 data = SDATA (value);
4676 if (INT_MAX < SBYTES (value))
4677 error ("VALUE too long");
4678 nelements = SBYTES (value);
4681 block_input ();
4682 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (prop), False);
4683 if (! NILP (type))
4685 CHECK_STRING (type);
4686 target_type = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (type), False);
4689 if (! NILP (outer_p)) w = FRAME_OUTER_WINDOW (f);
4690 else w = FRAME_X_WINDOW (f);
4692 XChangeProperty (FRAME_X_DISPLAY (f), w,
4693 prop_atom, target_type, element_format, PropModeReplace,
4694 data, nelements);
4696 if (CONSP (value)) xfree (data);
4698 /* Make sure the property is set when we return. */
4699 XFlush (FRAME_X_DISPLAY (f));
4700 unblock_input ();
4702 return value;
4706 DEFUN ("x-delete-window-property", Fx_delete_window_property,
4707 Sx_delete_window_property, 1, 2, 0,
4708 doc: /* Remove window property PROP from X window of FRAME.
4709 FRAME nil or omitted means use the selected frame. Value is PROP. */)
4710 (Lisp_Object prop, Lisp_Object frame)
4712 struct frame *f = decode_window_system_frame (frame);
4713 Atom prop_atom;
4715 CHECK_STRING (prop);
4716 block_input ();
4717 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (prop), False);
4718 XDeleteProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), prop_atom);
4720 /* Make sure the property is removed when we return. */
4721 XFlush (FRAME_X_DISPLAY (f));
4722 unblock_input ();
4724 return prop;
4728 static Lisp_Object
4729 x_window_property_intern (struct frame *f,
4730 Window target_window,
4731 Atom prop_atom,
4732 Atom target_type,
4733 Lisp_Object delete_p,
4734 Lisp_Object vector_ret_p,
4735 bool *found)
4737 unsigned char *tmp_data = NULL;
4738 Lisp_Object prop_value = Qnil;
4739 Atom actual_type;
4740 int actual_format;
4741 unsigned long actual_size, bytes_remaining;
4742 int rc;
4743 struct gcpro gcpro1;
4745 GCPRO1 (prop_value);
4747 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4748 prop_atom, 0, 0, False, target_type,
4749 &actual_type, &actual_format, &actual_size,
4750 &bytes_remaining, &tmp_data);
4752 *found = actual_format != 0;
4754 if (rc == Success && *found)
4756 XFree (tmp_data);
4757 tmp_data = NULL;
4759 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4760 prop_atom, 0, bytes_remaining,
4761 ! NILP (delete_p), target_type,
4762 &actual_type, &actual_format,
4763 &actual_size, &bytes_remaining,
4764 &tmp_data);
4765 if (rc == Success && tmp_data)
4767 /* The man page for XGetWindowProperty says:
4768 "If the returned format is 32, the returned data is represented
4769 as a long array and should be cast to that type to obtain the
4770 elements."
4771 This applies even if long is more than 32 bits, the X library
4772 converts from 32 bit elements received from the X server to long
4773 and passes the long array to us. Thus, for that case memcpy can not
4774 be used. We convert to a 32 bit type here, because so much code
4775 assume on that.
4777 The bytes and offsets passed to XGetWindowProperty refers to the
4778 property and those are indeed in 32 bit quantities if format is
4779 32. */
4781 if (BITS_PER_LONG > 32 && actual_format == 32)
4783 unsigned long i;
4784 int *idata = (int *) tmp_data;
4785 long *ldata = (long *) tmp_data;
4787 for (i = 0; i < actual_size; ++i)
4788 idata[i] = (int) ldata[i];
4791 if (NILP (vector_ret_p))
4792 prop_value = make_string ((char *) tmp_data, actual_size);
4793 else
4794 prop_value = x_property_data_to_lisp (f,
4795 tmp_data,
4796 actual_type,
4797 actual_format,
4798 actual_size);
4801 if (tmp_data) XFree (tmp_data);
4804 UNGCPRO;
4805 return prop_value;
4808 DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
4809 1, 6, 0,
4810 doc: /* Value is the value of window property PROP on FRAME.
4811 If FRAME is nil or omitted, use the selected frame.
4813 On X Windows, the following optional arguments are also accepted:
4814 If TYPE is nil or omitted, get the property as a string.
4815 Otherwise TYPE is the name of the atom that denotes the type expected.
4816 If SOURCE is non-nil, get the property on that window instead of from
4817 FRAME. The number 0 denotes the root window.
4818 If DELETE-P is non-nil, delete the property after retrieving it.
4819 If VECTOR-RET-P is non-nil, don't return a string but a vector of values.
4821 On MS Windows, this function accepts but ignores those optional arguments.
4823 Value is nil if FRAME hasn't a property with name PROP or if PROP has
4824 no value of TYPE (always string in the MS Windows case). */)
4825 (Lisp_Object prop, Lisp_Object frame, Lisp_Object type,
4826 Lisp_Object source, Lisp_Object delete_p, Lisp_Object vector_ret_p)
4828 struct frame *f = decode_window_system_frame (frame);
4829 Atom prop_atom;
4830 Lisp_Object prop_value = Qnil;
4831 Atom target_type = XA_STRING;
4832 Window target_window = FRAME_X_WINDOW (f);
4833 struct gcpro gcpro1;
4834 bool found;
4836 GCPRO1 (prop_value);
4837 CHECK_STRING (prop);
4839 if (! NILP (source))
4841 CONS_TO_INTEGER (source, Window, target_window);
4842 if (! target_window)
4843 target_window = FRAME_DISPLAY_INFO (f)->root_window;
4846 block_input ();
4847 if (STRINGP (type))
4849 if (strcmp ("AnyPropertyType", SSDATA (type)) == 0)
4850 target_type = AnyPropertyType;
4851 else
4852 target_type = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (type), False);
4855 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (prop), False);
4856 prop_value = x_window_property_intern (f,
4857 target_window,
4858 prop_atom,
4859 target_type,
4860 delete_p,
4861 vector_ret_p,
4862 &found);
4863 if (NILP (prop_value)
4864 && ! found
4865 && NILP (source)
4866 && target_window != FRAME_OUTER_WINDOW (f))
4868 prop_value = x_window_property_intern (f,
4869 FRAME_OUTER_WINDOW (f),
4870 prop_atom,
4871 target_type,
4872 delete_p,
4873 vector_ret_p,
4874 &found);
4878 unblock_input ();
4879 UNGCPRO;
4880 return prop_value;
4883 /***********************************************************************
4884 Tool tips
4885 ***********************************************************************/
4887 static Lisp_Object x_create_tip_frame (struct x_display_info *,
4888 Lisp_Object, Lisp_Object);
4889 static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
4890 Lisp_Object, int, int, int *, int *);
4892 /* The frame of a currently visible tooltip. */
4894 Lisp_Object tip_frame;
4896 /* If non-nil, a timer started that hides the last tooltip when it
4897 fires. */
4899 static Lisp_Object tip_timer;
4900 Window tip_window;
4902 /* If non-nil, a vector of 3 elements containing the last args
4903 with which x-show-tip was called. See there. */
4905 static Lisp_Object last_show_tip_args;
4908 static void
4909 unwind_create_tip_frame (Lisp_Object frame)
4911 Lisp_Object deleted;
4913 deleted = unwind_create_frame (frame);
4914 if (EQ (deleted, Qt))
4916 tip_window = None;
4917 tip_frame = Qnil;
4922 /* Create a frame for a tooltip on the display described by DPYINFO.
4923 PARMS is a list of frame parameters. TEXT is the string to
4924 display in the tip frame. Value is the frame.
4926 Note that functions called here, esp. x_default_parameter can
4927 signal errors, for instance when a specified color name is
4928 undefined. We have to make sure that we're in a consistent state
4929 when this happens. */
4931 static Lisp_Object
4932 x_create_tip_frame (struct x_display_info *dpyinfo,
4933 Lisp_Object parms,
4934 Lisp_Object text)
4936 struct frame *f;
4937 Lisp_Object frame;
4938 Lisp_Object name;
4939 int width, height;
4940 ptrdiff_t count = SPECPDL_INDEX ();
4941 struct gcpro gcpro1, gcpro2, gcpro3;
4942 int face_change_count_before = face_change_count;
4943 Lisp_Object buffer;
4944 struct buffer *old_buffer;
4946 if (!dpyinfo->terminal->name)
4947 error ("Terminal is not live, can't create new frames on it");
4949 parms = Fcopy_alist (parms);
4951 /* Get the name of the frame to use for resource lookup. */
4952 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
4953 if (!STRINGP (name)
4954 && !EQ (name, Qunbound)
4955 && !NILP (name))
4956 error ("Invalid frame name--not a string or nil");
4958 frame = Qnil;
4959 GCPRO3 (parms, name, frame);
4960 f = make_frame (1);
4961 XSETFRAME (frame, f);
4963 AUTO_STRING (tip, " *tip*");
4964 buffer = Fget_buffer_create (tip);
4965 /* Use set_window_buffer instead of Fset_window_buffer (see
4966 discussion of bug#11984, bug#12025, bug#12026). */
4967 set_window_buffer (FRAME_ROOT_WINDOW (f), buffer, 0, 0);
4968 old_buffer = current_buffer;
4969 set_buffer_internal_1 (XBUFFER (buffer));
4970 bset_truncate_lines (current_buffer, Qnil);
4971 specbind (Qinhibit_read_only, Qt);
4972 specbind (Qinhibit_modification_hooks, Qt);
4973 Ferase_buffer ();
4974 Finsert (1, &text);
4975 set_buffer_internal_1 (old_buffer);
4977 record_unwind_protect (unwind_create_tip_frame, frame);
4979 f->terminal = dpyinfo->terminal;
4981 /* By setting the output method, we're essentially saying that
4982 the frame is live, as per FRAME_LIVE_P. If we get a signal
4983 from this point on, x_destroy_window might screw up reference
4984 counts etc. */
4985 f->output_method = output_x_window;
4986 f->output_data.x = xzalloc (sizeof *f->output_data.x);
4987 f->output_data.x->icon_bitmap = -1;
4988 FRAME_FONTSET (f) = -1;
4989 f->output_data.x->scroll_bar_foreground_pixel = -1;
4990 f->output_data.x->scroll_bar_background_pixel = -1;
4991 #if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
4992 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
4993 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
4994 #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
4995 f->output_data.x->white_relief.pixel = -1;
4996 f->output_data.x->black_relief.pixel = -1;
4998 fset_icon_name (f, Qnil);
4999 FRAME_DISPLAY_INFO (f) = dpyinfo;
5000 f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
5001 f->output_data.x->explicit_parent = 0;
5003 /* These colors will be set anyway later, but it's important
5004 to get the color reference counts right, so initialize them! */
5006 Lisp_Object black;
5007 struct gcpro gcpro1;
5009 /* Function x_decode_color can signal an error. Make
5010 sure to initialize color slots so that we won't try
5011 to free colors we haven't allocated. */
5012 FRAME_FOREGROUND_PIXEL (f) = -1;
5013 FRAME_BACKGROUND_PIXEL (f) = -1;
5014 f->output_data.x->cursor_pixel = -1;
5015 f->output_data.x->cursor_foreground_pixel = -1;
5016 f->output_data.x->border_pixel = -1;
5017 f->output_data.x->mouse_pixel = -1;
5019 black = build_string ("black");
5020 GCPRO1 (black);
5021 FRAME_FOREGROUND_PIXEL (f)
5022 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
5023 FRAME_BACKGROUND_PIXEL (f)
5024 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
5025 f->output_data.x->cursor_pixel
5026 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
5027 f->output_data.x->cursor_foreground_pixel
5028 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
5029 f->output_data.x->border_pixel
5030 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
5031 f->output_data.x->mouse_pixel
5032 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
5033 UNGCPRO;
5036 /* Set the name; the functions to which we pass f expect the name to
5037 be set. */
5038 if (EQ (name, Qunbound) || NILP (name))
5040 fset_name (f, build_string (dpyinfo->x_id_name));
5041 f->explicit_name = 0;
5043 else
5045 fset_name (f, name);
5046 f->explicit_name = 1;
5047 /* use the frame's title when getting resources for this frame. */
5048 specbind (Qx_resource_name, name);
5051 register_font_driver (&xfont_driver, f);
5052 #ifdef HAVE_FREETYPE
5053 #ifdef HAVE_XFT
5054 register_font_driver (&xftfont_driver, f);
5055 #else /* not HAVE_XFT */
5056 register_font_driver (&ftxfont_driver, f);
5057 #endif /* not HAVE_XFT */
5058 #endif /* HAVE_FREETYPE */
5060 x_default_parameter (f, parms, Qfont_backend, Qnil,
5061 "fontBackend", "FontBackend", RES_TYPE_STRING);
5063 /* Extract the window parameters from the supplied values that are
5064 needed to determine window geometry. */
5065 x_default_font_parameter (f, parms);
5067 x_default_parameter (f, parms, Qborder_width, make_number (0),
5068 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
5070 /* This defaults to 2 in order to match xterm. We recognize either
5071 internalBorderWidth or internalBorder (which is what xterm calls
5072 it). */
5073 if (NILP (Fassq (Qinternal_border_width, parms)))
5075 Lisp_Object value;
5077 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
5078 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
5079 if (! EQ (value, Qunbound))
5080 parms = Fcons (Fcons (Qinternal_border_width, value),
5081 parms);
5084 x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
5085 "internalBorderWidth", "internalBorderWidth",
5086 RES_TYPE_NUMBER);
5087 x_default_parameter (f, parms, Qright_divider_width, make_number (0),
5088 NULL, NULL, RES_TYPE_NUMBER);
5089 x_default_parameter (f, parms, Qbottom_divider_width, make_number (0),
5090 NULL, NULL, RES_TYPE_NUMBER);
5092 /* Also do the stuff which must be set before the window exists. */
5093 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
5094 "foreground", "Foreground", RES_TYPE_STRING);
5095 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
5096 "background", "Background", RES_TYPE_STRING);
5097 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
5098 "pointerColor", "Foreground", RES_TYPE_STRING);
5099 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
5100 "cursorColor", "Foreground", RES_TYPE_STRING);
5101 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
5102 "borderColor", "BorderColor", RES_TYPE_STRING);
5104 #ifdef GLYPH_DEBUG
5105 image_cache_refcount =
5106 FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
5107 dpyinfo_refcount = dpyinfo->reference_count;
5108 #endif /* GLYPH_DEBUG */
5110 /* Init faces before x_default_parameter is called for the
5111 scroll-bar-width parameter because otherwise we end up in
5112 init_iterator with a null face cache, which should not happen. */
5113 init_frame_faces (f);
5115 f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
5117 x_figure_window_size (f, parms, 0);
5120 XSetWindowAttributes attrs;
5121 unsigned long mask;
5122 Atom type = FRAME_DISPLAY_INFO (f)->Xatom_net_window_type_tooltip;
5124 block_input ();
5125 mask = CWBackPixel | CWOverrideRedirect | CWEventMask;
5126 if (DoesSaveUnders (dpyinfo->screen))
5127 mask |= CWSaveUnder;
5129 /* Window managers look at the override-redirect flag to determine
5130 whether or net to give windows a decoration (Xlib spec, chapter
5131 3.2.8). */
5132 attrs.override_redirect = True;
5133 attrs.save_under = True;
5134 attrs.background_pixel = FRAME_BACKGROUND_PIXEL (f);
5135 /* Arrange for getting MapNotify and UnmapNotify events. */
5136 attrs.event_mask = StructureNotifyMask;
5137 tip_window
5138 = FRAME_X_WINDOW (f)
5139 = XCreateWindow (FRAME_X_DISPLAY (f),
5140 FRAME_DISPLAY_INFO (f)->root_window,
5141 /* x, y, width, height */
5142 0, 0, 1, 1,
5143 /* Border. */
5144 f->border_width,
5145 CopyFromParent, InputOutput, CopyFromParent,
5146 mask, &attrs);
5147 XChangeProperty (FRAME_X_DISPLAY (f), tip_window,
5148 FRAME_DISPLAY_INFO (f)->Xatom_net_window_type,
5149 XA_ATOM, 32, PropModeReplace,
5150 (unsigned char *)&type, 1);
5151 unblock_input ();
5154 x_make_gc (f);
5156 x_default_parameter (f, parms, Qauto_raise, Qnil,
5157 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
5158 x_default_parameter (f, parms, Qauto_lower, Qnil,
5159 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
5160 x_default_parameter (f, parms, Qcursor_type, Qbox,
5161 "cursorType", "CursorType", RES_TYPE_SYMBOL);
5163 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
5164 Change will not be effected unless different from the current
5165 FRAME_LINES (f). */
5166 width = FRAME_COLS (f);
5167 height = FRAME_LINES (f);
5168 SET_FRAME_COLS (f, 0);
5169 SET_FRAME_LINES (f, 0);
5170 change_frame_size (f, width, height, 1, 0, 0, 0);
5172 /* Add `tooltip' frame parameter's default value. */
5173 if (NILP (Fframe_parameter (frame, Qtooltip)))
5175 AUTO_FRAME_ARG (arg, Qtooltip, Qt);
5176 Fmodify_frame_parameters (frame, arg);
5179 /* FIXME - can this be done in a similar way to normal frames?
5180 http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
5182 /* Set the `display-type' frame parameter before setting up faces. */
5184 Lisp_Object disptype;
5186 if (FRAME_DISPLAY_INFO (f)->n_planes == 1)
5187 disptype = intern ("mono");
5188 else if (FRAME_DISPLAY_INFO (f)->visual->class == GrayScale
5189 || FRAME_DISPLAY_INFO (f)->visual->class == StaticGray)
5190 disptype = intern ("grayscale");
5191 else
5192 disptype = intern ("color");
5194 if (NILP (Fframe_parameter (frame, Qdisplay_type)))
5196 AUTO_FRAME_ARG (arg, Qdisplay_type, disptype);
5197 Fmodify_frame_parameters (frame, arg);
5201 /* Set up faces after all frame parameters are known. This call
5202 also merges in face attributes specified for new frames.
5204 Frame parameters may be changed if .Xdefaults contains
5205 specifications for the default font. For example, if there is an
5206 `Emacs.default.attributeBackground: pink', the `background-color'
5207 attribute of the frame get's set, which let's the internal border
5208 of the tooltip frame appear in pink. Prevent this. */
5210 Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
5212 /* Set tip_frame here, so that */
5213 tip_frame = frame;
5214 call2 (Qface_set_after_frame_default, frame, Qnil);
5216 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
5218 AUTO_FRAME_ARG (arg, Qbackground_color, bg);
5219 Fmodify_frame_parameters (frame, arg);
5223 f->no_split = 1;
5225 UNGCPRO;
5227 /* Now that the frame will be official, it counts as a reference to
5228 its display and terminal. */
5229 FRAME_DISPLAY_INFO (f)->reference_count++;
5230 f->terminal->reference_count++;
5232 /* It is now ok to make the frame official even if we get an error
5233 below. And the frame needs to be on Vframe_list or making it
5234 visible won't work. */
5235 Vframe_list = Fcons (frame, Vframe_list);
5236 f->can_x_set_window_size = true;
5238 /* Setting attributes of faces of the tooltip frame from resources
5239 and similar will increment face_change_count, which leads to the
5240 clearing of all current matrices. Since this isn't necessary
5241 here, avoid it by resetting face_change_count to the value it
5242 had before we created the tip frame. */
5243 face_change_count = face_change_count_before;
5245 /* Discard the unwind_protect. */
5246 return unbind_to (count, frame);
5250 /* Compute where to display tip frame F. PARMS is the list of frame
5251 parameters for F. DX and DY are specified offsets from the current
5252 location of the mouse. WIDTH and HEIGHT are the width and height
5253 of the tooltip. Return coordinates relative to the root window of
5254 the display in *ROOT_X, and *ROOT_Y. */
5256 static void
5257 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)
5259 Lisp_Object left, top;
5260 int win_x, win_y;
5261 Window root, child;
5262 unsigned pmask;
5264 /* User-specified position? */
5265 left = Fcdr (Fassq (Qleft, parms));
5266 top = Fcdr (Fassq (Qtop, parms));
5268 /* Move the tooltip window where the mouse pointer is. Resize and
5269 show it. */
5270 if (!INTEGERP (left) || !INTEGERP (top))
5272 block_input ();
5273 XQueryPointer (FRAME_X_DISPLAY (f), FRAME_DISPLAY_INFO (f)->root_window,
5274 &root, &child, root_x, root_y, &win_x, &win_y, &pmask);
5275 unblock_input ();
5278 if (INTEGERP (top))
5279 *root_y = XINT (top);
5280 else if (*root_y + XINT (dy) <= 0)
5281 *root_y = 0; /* Can happen for negative dy */
5282 else if (*root_y + XINT (dy) + height
5283 <= x_display_pixel_height (FRAME_DISPLAY_INFO (f)))
5284 /* It fits below the pointer */
5285 *root_y += XINT (dy);
5286 else if (height + XINT (dy) <= *root_y)
5287 /* It fits above the pointer. */
5288 *root_y -= height + XINT (dy);
5289 else
5290 /* Put it on the top. */
5291 *root_y = 0;
5293 if (INTEGERP (left))
5294 *root_x = XINT (left);
5295 else if (*root_x + XINT (dx) <= 0)
5296 *root_x = 0; /* Can happen for negative dx */
5297 else if (*root_x + XINT (dx) + width
5298 <= x_display_pixel_width (FRAME_DISPLAY_INFO (f)))
5299 /* It fits to the right of the pointer. */
5300 *root_x += XINT (dx);
5301 else if (width + XINT (dx) <= *root_x)
5302 /* It fits to the left of the pointer. */
5303 *root_x -= width + XINT (dx);
5304 else
5305 /* Put it left-justified on the screen--it ought to fit that way. */
5306 *root_x = 0;
5310 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
5311 doc: /* Show STRING in a "tooltip" window on frame FRAME.
5312 A tooltip window is a small X window displaying a string.
5314 This is an internal function; Lisp code should call `tooltip-show'.
5316 FRAME nil or omitted means use the selected frame.
5318 PARMS is an optional list of frame parameters which can be used to
5319 change the tooltip's appearance.
5321 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
5322 means use the default timeout of 5 seconds.
5324 If the list of frame parameters PARMS contains a `left' parameters,
5325 the tooltip is displayed at that x-position. Otherwise it is
5326 displayed at the mouse position, with offset DX added (default is 5 if
5327 DX isn't specified). Likewise for the y-position; if a `top' frame
5328 parameter is specified, it determines the y-position of the tooltip
5329 window, otherwise it is displayed at the mouse position, with offset
5330 DY added (default is -10).
5332 A tooltip's maximum size is specified by `x-max-tooltip-size'.
5333 Text larger than the specified size is clipped. */)
5334 (Lisp_Object string, Lisp_Object frame, Lisp_Object parms, Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy)
5336 struct frame *f;
5337 struct window *w;
5338 int root_x, root_y;
5339 struct buffer *old_buffer;
5340 struct text_pos pos;
5341 int i, width, height, seen_reversed_p;
5342 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
5343 int old_windows_or_buffers_changed = windows_or_buffers_changed;
5344 ptrdiff_t count = SPECPDL_INDEX ();
5346 specbind (Qinhibit_redisplay, Qt);
5348 GCPRO4 (string, parms, frame, timeout);
5350 CHECK_STRING (string);
5351 if (SCHARS (string) == 0)
5352 string = make_unibyte_string (" ", 1);
5354 f = decode_window_system_frame (frame);
5355 if (NILP (timeout))
5356 timeout = make_number (5);
5357 else
5358 CHECK_NATNUM (timeout);
5360 if (NILP (dx))
5361 dx = make_number (5);
5362 else
5363 CHECK_NUMBER (dx);
5365 if (NILP (dy))
5366 dy = make_number (-10);
5367 else
5368 CHECK_NUMBER (dy);
5370 #ifdef USE_GTK
5371 if (x_gtk_use_system_tooltips)
5373 bool ok;
5375 /* Hide a previous tip, if any. */
5376 Fx_hide_tip ();
5378 block_input ();
5379 ok = xg_prepare_tooltip (f, string, &width, &height);
5380 if (ok)
5382 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
5383 xg_show_tooltip (f, root_x, root_y);
5384 /* This is used in Fx_hide_tip. */
5385 XSETFRAME (tip_frame, f);
5387 unblock_input ();
5388 if (ok) goto start_timer;
5390 #endif /* USE_GTK */
5392 if (NILP (last_show_tip_args))
5393 last_show_tip_args = Fmake_vector (make_number (3), Qnil);
5395 if (!NILP (tip_frame))
5397 Lisp_Object last_string = AREF (last_show_tip_args, 0);
5398 Lisp_Object last_frame = AREF (last_show_tip_args, 1);
5399 Lisp_Object last_parms = AREF (last_show_tip_args, 2);
5401 if (EQ (frame, last_frame)
5402 && !NILP (Fequal (last_string, string))
5403 && !NILP (Fequal (last_parms, parms)))
5405 struct frame *tip_f = XFRAME (tip_frame);
5407 /* Only DX and DY have changed. */
5408 if (!NILP (tip_timer))
5410 Lisp_Object timer = tip_timer;
5411 tip_timer = Qnil;
5412 call1 (Qcancel_timer, timer);
5415 block_input ();
5416 compute_tip_xy (tip_f, parms, dx, dy, FRAME_PIXEL_WIDTH (tip_f),
5417 FRAME_PIXEL_HEIGHT (tip_f), &root_x, &root_y);
5418 XMoveWindow (FRAME_X_DISPLAY (tip_f), FRAME_X_WINDOW (tip_f),
5419 root_x, root_y);
5420 unblock_input ();
5421 goto start_timer;
5425 /* Hide a previous tip, if any. */
5426 Fx_hide_tip ();
5428 ASET (last_show_tip_args, 0, string);
5429 ASET (last_show_tip_args, 1, frame);
5430 ASET (last_show_tip_args, 2, parms);
5432 /* Add default values to frame parameters. */
5433 if (NILP (Fassq (Qname, parms)))
5434 parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
5435 if (NILP (Fassq (Qinternal_border_width, parms)))
5436 parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
5437 if (NILP (Fassq (Qborder_width, parms)))
5438 parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
5439 if (NILP (Fassq (Qbottom_divider_width, parms)))
5440 parms = Fcons (Fcons (Qbottom_divider_width, make_number (0)), parms);
5441 if (NILP (Fassq (Qright_divider_width, parms)))
5442 parms = Fcons (Fcons (Qright_divider_width, make_number (0)), parms);
5443 if (NILP (Fassq (Qborder_color, parms)))
5444 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
5445 if (NILP (Fassq (Qbackground_color, parms)))
5446 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
5447 parms);
5449 /* Create a frame for the tooltip, and record it in the global
5450 variable tip_frame. */
5451 frame = x_create_tip_frame (FRAME_DISPLAY_INFO (f), parms, string);
5452 f = XFRAME (frame);
5454 /* Set up the frame's root window. */
5455 w = XWINDOW (FRAME_ROOT_WINDOW (f));
5456 w->left_col = 0;
5457 w->top_line = 0;
5458 w->pixel_left = 0;
5459 w->pixel_top = 0;
5461 if (CONSP (Vx_max_tooltip_size)
5462 && RANGED_INTEGERP (1, XCAR (Vx_max_tooltip_size), INT_MAX)
5463 && RANGED_INTEGERP (1, XCDR (Vx_max_tooltip_size), INT_MAX))
5465 w->total_cols = XFASTINT (XCAR (Vx_max_tooltip_size));
5466 w->total_lines = XFASTINT (XCDR (Vx_max_tooltip_size));
5468 else
5470 w->total_cols = 80;
5471 w->total_lines = 40;
5474 w->pixel_width = w->total_cols * FRAME_COLUMN_WIDTH (f);
5475 w->pixel_height = w->total_lines * FRAME_LINE_HEIGHT (f);
5477 FRAME_TOTAL_COLS (f) = w->total_cols;
5478 adjust_frame_glyphs (f);
5479 w->pseudo_window_p = 1;
5481 /* Display the tooltip text in a temporary buffer. */
5482 old_buffer = current_buffer;
5483 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->contents));
5484 bset_truncate_lines (current_buffer, Qnil);
5485 clear_glyph_matrix (w->desired_matrix);
5486 clear_glyph_matrix (w->current_matrix);
5487 SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
5488 try_window (FRAME_ROOT_WINDOW (f), pos, TRY_WINDOW_IGNORE_FONTS_CHANGE);
5490 /* Compute width and height of the tooltip. */
5491 width = height = seen_reversed_p = 0;
5492 for (i = 0; i < w->desired_matrix->nrows; ++i)
5494 struct glyph_row *row = &w->desired_matrix->rows[i];
5495 struct glyph *last;
5496 int row_width;
5498 /* Stop at the first empty row at the end. */
5499 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
5500 break;
5502 /* Let the row go over the full width of the frame. */
5503 row->full_width_p = 1;
5505 row_width = row->pixel_width;
5506 if (row->used[TEXT_AREA])
5508 /* There's a glyph at the end of rows that is used to place
5509 the cursor there. Don't include the width of this glyph. */
5510 if (!row->reversed_p)
5512 last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
5513 if (INTEGERP (last->object))
5514 row_width -= last->pixel_width;
5516 else
5518 /* There could be a stretch glyph at the beginning of R2L
5519 rows that is produced by extend_face_to_end_of_line.
5520 Don't count that glyph. */
5521 struct glyph *g = row->glyphs[TEXT_AREA];
5523 if (g->type == STRETCH_GLYPH && INTEGERP (g->object))
5525 row_width -= g->pixel_width;
5526 seen_reversed_p = 1;
5531 height += row->height;
5532 width = max (width, row_width);
5535 /* If we've seen partial-length R2L rows, we need to re-adjust the
5536 tool-tip frame width and redisplay it again, to avoid over-wide
5537 tips due to the stretch glyph that extends R2L lines to full
5538 width of the frame. */
5539 if (seen_reversed_p)
5541 /* w->total_cols and FRAME_TOTAL_COLS want the width in columns,
5542 not in pixels. */
5543 w->pixel_width = width;
5544 width /= WINDOW_FRAME_COLUMN_WIDTH (w);
5545 w->total_cols = width;
5546 FRAME_TOTAL_COLS (f) = width;
5547 SET_FRAME_WIDTH (f, width);
5548 adjust_frame_glyphs (f);
5549 clear_glyph_matrix (w->desired_matrix);
5550 clear_glyph_matrix (w->current_matrix);
5551 try_window (FRAME_ROOT_WINDOW (f), pos, 0);
5552 width = height = 0;
5553 /* Recompute width and height of the tooltip. */
5554 for (i = 0; i < w->desired_matrix->nrows; ++i)
5556 struct glyph_row *row = &w->desired_matrix->rows[i];
5557 struct glyph *last;
5558 int row_width;
5560 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
5561 break;
5562 row->full_width_p = 1;
5563 row_width = row->pixel_width;
5564 if (row->used[TEXT_AREA] && !row->reversed_p)
5566 last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
5567 if (INTEGERP (last->object))
5568 row_width -= last->pixel_width;
5571 height += row->height;
5572 width = max (width, row_width);
5576 /* Add the frame's internal border to the width and height the X
5577 window should have. */
5578 height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5579 width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5581 /* Move the tooltip window where the mouse pointer is. Resize and
5582 show it. */
5583 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
5585 block_input ();
5586 XMoveResizeWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5587 root_x, root_y, width, height);
5588 XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
5589 unblock_input ();
5591 /* Draw into the window. */
5592 w->must_be_updated_p = 1;
5593 update_single_window (w, 1);
5595 /* Restore original current buffer. */
5596 set_buffer_internal_1 (old_buffer);
5597 windows_or_buffers_changed = old_windows_or_buffers_changed;
5599 start_timer:
5600 /* Let the tip disappear after timeout seconds. */
5601 tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
5602 intern ("x-hide-tip"));
5604 UNGCPRO;
5605 return unbind_to (count, Qnil);
5609 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
5610 doc: /* Hide the current tooltip window, if there is any.
5611 Value is t if tooltip was open, nil otherwise. */)
5612 (void)
5614 ptrdiff_t count;
5615 Lisp_Object deleted, frame, timer;
5616 struct gcpro gcpro1, gcpro2;
5618 /* Return quickly if nothing to do. */
5619 if (NILP (tip_timer) && NILP (tip_frame))
5620 return Qnil;
5622 frame = tip_frame;
5623 timer = tip_timer;
5624 GCPRO2 (frame, timer);
5625 tip_frame = tip_timer = deleted = Qnil;
5627 count = SPECPDL_INDEX ();
5628 specbind (Qinhibit_redisplay, Qt);
5629 specbind (Qinhibit_quit, Qt);
5631 if (!NILP (timer))
5632 call1 (Qcancel_timer, timer);
5634 #ifdef USE_GTK
5636 /* When using system tooltip, tip_frame is the Emacs frame on which
5637 the tip is shown. */
5638 struct frame *f = XFRAME (frame);
5639 if (FRAME_LIVE_P (f) && xg_hide_tooltip (f))
5640 frame = Qnil;
5642 #endif
5644 if (FRAMEP (frame))
5646 delete_frame (frame, Qnil);
5647 deleted = Qt;
5649 #ifdef USE_LUCID
5650 /* Bloodcurdling hack alert: The Lucid menu bar widget's
5651 redisplay procedure is not called when a tip frame over menu
5652 items is unmapped. Redisplay the menu manually... */
5654 Widget w;
5655 struct frame *f = SELECTED_FRAME ();
5656 w = f->output_data.x->menubar_widget;
5658 if (!DoesSaveUnders (FRAME_DISPLAY_INFO (f)->screen)
5659 && w != NULL)
5661 block_input ();
5662 xlwmenu_redisplay (w);
5663 unblock_input ();
5666 #endif /* USE_LUCID */
5669 UNGCPRO;
5670 return unbind_to (count, deleted);
5675 /***********************************************************************
5676 File selection dialog
5677 ***********************************************************************/
5679 DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog,
5680 Sx_uses_old_gtk_dialog,
5681 0, 0, 0,
5682 doc: /* Return t if the old Gtk+ file selection dialog is used. */)
5683 (void)
5685 #ifdef USE_GTK
5686 if (use_dialog_box
5687 && use_file_dialog
5688 && window_system_available (SELECTED_FRAME ())
5689 && xg_uses_old_file_dialog ())
5690 return Qt;
5691 #endif
5692 return Qnil;
5696 #ifdef USE_MOTIF
5697 /* Callback for "OK" and "Cancel" on file selection dialog. */
5699 static void
5700 file_dialog_cb (Widget widget, XtPointer client_data, XtPointer call_data)
5702 int *result = client_data;
5703 XmAnyCallbackStruct *cb = call_data;
5704 *result = cb->reason;
5708 /* Callback for unmapping a file selection dialog. This is used to
5709 capture the case where a dialog is closed via a window manager's
5710 closer button, for example. Using a XmNdestroyCallback didn't work
5711 in this case. */
5713 static void
5714 file_dialog_unmap_cb (Widget widget, XtPointer client_data, XtPointer call_data)
5716 int *result = client_data;
5717 *result = XmCR_CANCEL;
5720 static void
5721 clean_up_file_dialog (void *arg)
5723 Widget dialog = arg;
5725 /* Clean up. */
5726 block_input ();
5727 XtUnmanageChild (dialog);
5728 XtDestroyWidget (dialog);
5729 x_menu_set_in_use (0);
5730 unblock_input ();
5734 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5735 doc: /* Read file name, prompting with PROMPT in directory DIR.
5736 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5737 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5738 or directory must exist.
5740 This function is only defined on NS, MS Windows, and X Windows with the
5741 Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
5742 Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.
5743 On Windows 7 and later, the file selection dialog "remembers" the last
5744 directory where the user selected a file, and will open that directory
5745 instead of DIR on subsequent invocations of this function with the same
5746 value of DIR as in previous invocations; this is standard Windows behavior. */)
5747 (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename,
5748 Lisp_Object mustmatch, Lisp_Object only_dir_p)
5750 int result;
5751 struct frame *f = SELECTED_FRAME ();
5752 Lisp_Object file = Qnil;
5753 Lisp_Object decoded_file;
5754 Widget dialog, text, help;
5755 Arg al[10];
5756 int ac = 0;
5757 XmString dir_xmstring, pattern_xmstring;
5758 ptrdiff_t count = SPECPDL_INDEX ();
5759 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5761 check_window_system (f);
5763 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5765 if (popup_activated ())
5766 error ("Trying to use a menu from within a menu-entry");
5768 CHECK_STRING (prompt);
5769 CHECK_STRING (dir);
5771 /* Prevent redisplay. */
5772 specbind (Qinhibit_redisplay, Qt);
5774 block_input ();
5776 /* Create the dialog with PROMPT as title, using DIR as initial
5777 directory and using "*" as pattern. */
5778 dir = Fexpand_file_name (dir, Qnil);
5779 dir_xmstring = XmStringCreateLocalized (SSDATA (dir));
5780 pattern_xmstring = XmStringCreateLocalized ("*");
5782 XtSetArg (al[ac], XmNtitle, SDATA (prompt)); ++ac;
5783 XtSetArg (al[ac], XmNdirectory, dir_xmstring); ++ac;
5784 XtSetArg (al[ac], XmNpattern, pattern_xmstring); ++ac;
5785 XtSetArg (al[ac], XmNresizePolicy, XmRESIZE_GROW); ++ac;
5786 XtSetArg (al[ac], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); ++ac;
5787 dialog = XmCreateFileSelectionDialog (f->output_data.x->widget,
5788 "fsb", al, ac);
5789 XmStringFree (dir_xmstring);
5790 XmStringFree (pattern_xmstring);
5792 /* Add callbacks for OK and Cancel. */
5793 XtAddCallback (dialog, XmNokCallback, file_dialog_cb,
5794 (XtPointer) &result);
5795 XtAddCallback (dialog, XmNcancelCallback, file_dialog_cb,
5796 (XtPointer) &result);
5797 XtAddCallback (dialog, XmNunmapCallback, file_dialog_unmap_cb,
5798 (XtPointer) &result);
5800 /* Remove the help button since we can't display help. */
5801 help = XmFileSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON);
5802 XtUnmanageChild (help);
5804 /* Mark OK button as default. */
5805 XtVaSetValues (XmFileSelectionBoxGetChild (dialog, XmDIALOG_OK_BUTTON),
5806 XmNshowAsDefault, True, NULL);
5808 /* If MUSTMATCH is non-nil, disable the file entry field of the
5809 dialog, so that the user must select a file from the files list
5810 box. We can't remove it because we wouldn't have a way to get at
5811 the result file name, then. */
5812 text = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5813 if (!NILP (mustmatch))
5815 Widget label;
5816 label = XmFileSelectionBoxGetChild (dialog, XmDIALOG_SELECTION_LABEL);
5817 XtSetSensitive (text, False);
5818 XtSetSensitive (label, False);
5821 /* Manage the dialog, so that list boxes get filled. */
5822 XtManageChild (dialog);
5824 if (STRINGP (default_filename))
5826 XmString default_xmstring;
5827 Widget wtext = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5828 Widget list = XmFileSelectionBoxGetChild (dialog, XmDIALOG_LIST);
5830 XmTextPosition last_pos = XmTextFieldGetLastPosition (wtext);
5831 XmTextFieldReplace (wtext, 0, last_pos,
5832 (SSDATA (Ffile_name_nondirectory (default_filename))));
5834 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
5835 must include the path for this to work. */
5837 default_xmstring = XmStringCreateLocalized (SSDATA (default_filename));
5839 if (XmListItemExists (list, default_xmstring))
5841 int item_pos = XmListItemPos (list, default_xmstring);
5842 /* Select the item and scroll it into view. */
5843 XmListSelectPos (list, item_pos, True);
5844 XmListSetPos (list, item_pos);
5847 XmStringFree (default_xmstring);
5850 record_unwind_protect_ptr (clean_up_file_dialog, dialog);
5852 /* Process events until the user presses Cancel or OK. */
5853 x_menu_set_in_use (1);
5854 result = 0;
5855 while (result == 0)
5857 XEvent event;
5858 x_menu_wait_for_event (0);
5859 XtAppNextEvent (Xt_app_con, &event);
5860 if (event.type == KeyPress
5861 && FRAME_X_DISPLAY (f) == event.xkey.display)
5863 KeySym keysym = XLookupKeysym (&event.xkey, 0);
5865 /* Pop down on C-g. */
5866 if (keysym == XK_g && (event.xkey.state & ControlMask) != 0)
5867 XtUnmanageChild (dialog);
5870 (void) x_dispatch_event (&event, FRAME_X_DISPLAY (f));
5873 /* Get the result. */
5874 if (result == XmCR_OK)
5876 XmString text_string;
5877 String data;
5879 XtVaGetValues (dialog, XmNtextString, &text_string, NULL);
5880 XmStringGetLtoR (text_string, XmFONTLIST_DEFAULT_TAG, &data);
5881 XmStringFree (text_string);
5882 file = build_string (data);
5883 XtFree (data);
5885 else
5886 file = Qnil;
5888 unblock_input ();
5889 UNGCPRO;
5891 /* Make "Cancel" equivalent to C-g. */
5892 if (NILP (file))
5893 Fsignal (Qquit, Qnil);
5895 decoded_file = DECODE_FILE (file);
5897 return unbind_to (count, decoded_file);
5900 #endif /* USE_MOTIF */
5902 #ifdef USE_GTK
5904 static void
5905 clean_up_dialog (void)
5907 x_menu_set_in_use (0);
5910 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5911 doc: /* Read file name, prompting with PROMPT in directory DIR.
5912 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5913 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5914 or directory must exist.
5916 This function is only defined on NS, MS Windows, and X Windows with the
5917 Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
5918 Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.
5919 On Windows 7 and later, the file selection dialog "remembers" the last
5920 directory where the user selected a file, and will open that directory
5921 instead of DIR on subsequent invocations of this function with the same
5922 value of DIR as in previous invocations; this is standard Windows behavior. */)
5923 (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p)
5925 struct frame *f = SELECTED_FRAME ();
5926 char *fn;
5927 Lisp_Object file = Qnil;
5928 Lisp_Object decoded_file;
5929 ptrdiff_t count = SPECPDL_INDEX ();
5930 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5931 char *cdef_file;
5933 check_window_system (f);
5935 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5937 if (popup_activated ())
5938 error ("Trying to use a menu from within a menu-entry");
5940 CHECK_STRING (prompt);
5941 CHECK_STRING (dir);
5943 /* Prevent redisplay. */
5944 specbind (Qinhibit_redisplay, Qt);
5945 record_unwind_protect_void (clean_up_dialog);
5947 block_input ();
5949 if (STRINGP (default_filename))
5950 cdef_file = SSDATA (default_filename);
5951 else
5952 cdef_file = SSDATA (dir);
5954 fn = xg_get_file_name (f, SSDATA (prompt), cdef_file,
5955 ! NILP (mustmatch),
5956 ! NILP (only_dir_p));
5958 if (fn)
5960 file = build_string (fn);
5961 xfree (fn);
5964 unblock_input ();
5965 UNGCPRO;
5967 /* Make "Cancel" equivalent to C-g. */
5968 if (NILP (file))
5969 Fsignal (Qquit, Qnil);
5971 decoded_file = DECODE_FILE (file);
5973 return unbind_to (count, decoded_file);
5977 #ifdef HAVE_FREETYPE
5979 DEFUN ("x-select-font", Fx_select_font, Sx_select_font, 0, 2, 0,
5980 doc: /* Read a font using a GTK dialog.
5981 Return either a font spec (for GTK versions >= 3.2) or a string
5982 containing a GTK-style font name.
5984 FRAME is the frame on which to pop up the font chooser. If omitted or
5985 nil, it defaults to the selected frame. */)
5986 (Lisp_Object frame, Lisp_Object ignored)
5988 struct frame *f = decode_window_system_frame (frame);
5989 Lisp_Object font;
5990 Lisp_Object font_param;
5991 char *default_name = NULL;
5992 struct gcpro gcpro1, gcpro2;
5993 ptrdiff_t count = SPECPDL_INDEX ();
5995 if (popup_activated ())
5996 error ("Trying to use a menu from within a menu-entry");
5998 /* Prevent redisplay. */
5999 specbind (Qinhibit_redisplay, Qt);
6000 record_unwind_protect_void (clean_up_dialog);
6002 block_input ();
6004 GCPRO2 (font_param, font);
6006 XSETFONT (font, FRAME_FONT (f));
6007 font_param = Ffont_get (font, intern (":name"));
6008 if (STRINGP (font_param))
6009 default_name = xstrdup (SSDATA (font_param));
6010 else
6012 font_param = Fframe_parameter (frame, Qfont_param);
6013 if (STRINGP (font_param))
6014 default_name = xstrdup (SSDATA (font_param));
6017 font = xg_get_font (f, default_name);
6018 xfree (default_name);
6020 unblock_input ();
6022 if (NILP (font))
6023 Fsignal (Qquit, Qnil);
6025 return unbind_to (count, font);
6027 #endif /* HAVE_FREETYPE */
6029 #endif /* USE_GTK */
6032 /***********************************************************************
6033 Keyboard
6034 ***********************************************************************/
6036 #ifdef HAVE_XKB
6037 #include <X11/XKBlib.h>
6038 #include <X11/keysym.h>
6039 #endif
6041 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p,
6042 Sx_backspace_delete_keys_p, 0, 1, 0,
6043 doc: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
6044 FRAME nil means use the selected frame.
6045 Value is t if we know that both keys are present, and are mapped to the
6046 usual X keysyms. Value is `lambda' if we cannot determine if both keys are
6047 present and mapped to the usual X keysyms. */)
6048 (Lisp_Object frame)
6050 #ifndef HAVE_XKB
6051 return Qlambda;
6052 #else
6053 XkbDescPtr kb;
6054 struct frame *f = decode_window_system_frame (frame);
6055 Display *dpy = FRAME_X_DISPLAY (f);
6056 Lisp_Object have_keys;
6057 int major, minor, op, event, error_code;
6059 block_input ();
6061 /* Check library version in case we're dynamically linked. */
6062 major = XkbMajorVersion;
6063 minor = XkbMinorVersion;
6064 if (!XkbLibraryVersion (&major, &minor))
6066 unblock_input ();
6067 return Qlambda;
6070 /* Check that the server supports XKB. */
6071 major = XkbMajorVersion;
6072 minor = XkbMinorVersion;
6073 if (!XkbQueryExtension (dpy, &op, &event, &error_code, &major, &minor))
6075 unblock_input ();
6076 return Qlambda;
6079 /* In this code we check that the keyboard has physical keys with names
6080 that start with BKSP (Backspace) and DELE (Delete), and that they
6081 generate keysym XK_BackSpace and XK_Delete respectively.
6082 This function is used to test if normal-erase-is-backspace should be
6083 turned on.
6084 An alternative approach would be to just check if XK_BackSpace and
6085 XK_Delete are mapped to any key. But if any of those are mapped to
6086 some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the
6087 user doesn't know about it, it is better to return false here.
6088 It is more obvious to the user what to do if she/he has two keys
6089 clearly marked with names/symbols and one key does something not
6090 expected (i.e. she/he then tries the other).
6091 The cases where Backspace/Delete is mapped to some other key combination
6092 are rare, and in those cases, normal-erase-is-backspace can be turned on
6093 manually. */
6095 have_keys = Qnil;
6096 kb = XkbGetMap (dpy, XkbAllMapComponentsMask, XkbUseCoreKbd);
6097 if (kb)
6099 int delete_keycode = 0, backspace_keycode = 0, i;
6101 if (XkbGetNames (dpy, XkbAllNamesMask, kb) == Success)
6103 for (i = kb->min_key_code;
6104 (i < kb->max_key_code
6105 && (delete_keycode == 0 || backspace_keycode == 0));
6106 ++i)
6108 /* The XKB symbolic key names can be seen most easily in
6109 the PS file generated by `xkbprint -label name
6110 $DISPLAY'. */
6111 if (memcmp ("DELE", kb->names->keys[i].name, 4) == 0)
6112 delete_keycode = i;
6113 else if (memcmp ("BKSP", kb->names->keys[i].name, 4) == 0)
6114 backspace_keycode = i;
6117 XkbFreeNames (kb, 0, True);
6120 /* As of libX11-1.6.2, XkbGetMap manual says that you should use
6121 XkbFreeClientMap to free the data returned by XkbGetMap. But
6122 this function just frees the data referenced from KB and not
6123 KB itself. To free KB as well, call XkbFreeKeyboard. */
6124 XkbFreeKeyboard (kb, XkbAllMapComponentsMask, True);
6126 if (delete_keycode
6127 && backspace_keycode
6128 && XKeysymToKeycode (dpy, XK_Delete) == delete_keycode
6129 && XKeysymToKeycode (dpy, XK_BackSpace) == backspace_keycode)
6130 have_keys = Qt;
6132 unblock_input ();
6133 return have_keys;
6134 #endif
6139 /***********************************************************************
6140 Initialization
6141 ***********************************************************************/
6143 /* Keep this list in the same order as frame_parms in frame.c.
6144 Use 0 for unsupported frame parameters. */
6146 frame_parm_handler x_frame_parm_handlers[] =
6148 x_set_autoraise,
6149 x_set_autolower,
6150 x_set_background_color,
6151 x_set_border_color,
6152 x_set_border_width,
6153 x_set_cursor_color,
6154 x_set_cursor_type,
6155 x_set_font,
6156 x_set_foreground_color,
6157 x_set_icon_name,
6158 x_set_icon_type,
6159 x_set_internal_border_width,
6160 x_set_right_divider_width,
6161 x_set_bottom_divider_width,
6162 x_set_menu_bar_lines,
6163 x_set_mouse_color,
6164 x_explicitly_set_name,
6165 x_set_scroll_bar_width,
6166 x_set_scroll_bar_height,
6167 x_set_title,
6168 x_set_unsplittable,
6169 x_set_vertical_scroll_bars,
6170 x_set_horizontal_scroll_bars,
6171 x_set_visibility,
6172 x_set_tool_bar_lines,
6173 x_set_scroll_bar_foreground,
6174 x_set_scroll_bar_background,
6175 x_set_screen_gamma,
6176 x_set_line_spacing,
6177 x_set_left_fringe,
6178 x_set_right_fringe,
6179 x_set_wait_for_wm,
6180 x_set_fullscreen,
6181 x_set_font_backend,
6182 x_set_alpha,
6183 x_set_sticky,
6184 x_set_tool_bar_position,
6187 void
6188 syms_of_xfns (void)
6190 DEFSYM (Qundefined_color, "undefined-color");
6191 DEFSYM (Qcompound_text, "compound-text");
6192 DEFSYM (Qcancel_timer, "cancel-timer");
6193 DEFSYM (Qfont_param, "font-parameter");
6195 Fput (Qundefined_color, Qerror_conditions,
6196 listn (CONSTYPE_PURE, 2, Qundefined_color, Qerror));
6197 Fput (Qundefined_color, Qerror_message,
6198 build_pure_c_string ("Undefined color"));
6200 DEFVAR_LISP ("x-pointer-shape", Vx_pointer_shape,
6201 doc: /* The shape of the pointer when over text.
6202 Changing the value does not affect existing frames
6203 unless you set the mouse color. */);
6204 Vx_pointer_shape = Qnil;
6206 #if 0 /* This doesn't really do anything. */
6207 DEFVAR_LISP ("x-nontext-pointer-shape", Vx_nontext_pointer_shape,
6208 doc: /* The shape of the pointer when not over text.
6209 This variable takes effect when you create a new frame
6210 or when you set the mouse color. */);
6211 #endif
6212 Vx_nontext_pointer_shape = Qnil;
6214 DEFVAR_LISP ("x-hourglass-pointer-shape", Vx_hourglass_pointer_shape,
6215 doc: /* The shape of the pointer when Emacs is busy.
6216 This variable takes effect when you create a new frame
6217 or when you set the mouse color. */);
6218 Vx_hourglass_pointer_shape = Qnil;
6220 #if 0 /* This doesn't really do anything. */
6221 DEFVAR_LISP ("x-mode-pointer-shape", Vx_mode_pointer_shape,
6222 doc: /* The shape of the pointer when over the mode line.
6223 This variable takes effect when you create a new frame
6224 or when you set the mouse color. */);
6225 #endif
6226 Vx_mode_pointer_shape = Qnil;
6228 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
6229 Vx_sensitive_text_pointer_shape,
6230 doc: /* The shape of the pointer when over mouse-sensitive text.
6231 This variable takes effect when you create a new frame
6232 or when you set the mouse color. */);
6233 Vx_sensitive_text_pointer_shape = Qnil;
6235 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
6236 Vx_window_horizontal_drag_shape,
6237 doc: /* Pointer shape to use for indicating a window can be dragged horizontally.
6238 This variable takes effect when you create a new frame
6239 or when you set the mouse color. */);
6240 Vx_window_horizontal_drag_shape = Qnil;
6242 DEFVAR_LISP ("x-window-vertical-drag-cursor",
6243 Vx_window_vertical_drag_shape,
6244 doc: /* Pointer shape to use for indicating a window can be dragged vertically.
6245 This variable takes effect when you create a new frame
6246 or when you set the mouse color. */);
6247 Vx_window_vertical_drag_shape = Qnil;
6249 DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel,
6250 doc: /* A string indicating the foreground color of the cursor box. */);
6251 Vx_cursor_fore_pixel = Qnil;
6253 DEFVAR_LISP ("x-max-tooltip-size", Vx_max_tooltip_size,
6254 doc: /* Maximum size for tooltips.
6255 Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */);
6256 Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
6258 DEFVAR_LISP ("x-no-window-manager", Vx_no_window_manager,
6259 doc: /* Non-nil if no X window manager is in use.
6260 Emacs doesn't try to figure this out; this is always nil
6261 unless you set it to something else. */);
6262 /* We don't have any way to find this out, so set it to nil
6263 and maybe the user would like to set it to t. */
6264 Vx_no_window_manager = Qnil;
6266 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
6267 Vx_pixel_size_width_font_regexp,
6268 doc: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
6270 Since Emacs gets width of a font matching with this regexp from
6271 PIXEL_SIZE field of the name, font finding mechanism gets faster for
6272 such a font. This is especially effective for such large fonts as
6273 Chinese, Japanese, and Korean. */);
6274 Vx_pixel_size_width_font_regexp = Qnil;
6276 /* This is not ifdef:ed, so other builds than GTK can customize it. */
6277 DEFVAR_BOOL ("x-gtk-use-old-file-dialog", x_gtk_use_old_file_dialog,
6278 doc: /* Non-nil means prompt with the old GTK file selection dialog.
6279 If nil or if the file selection dialog is not available, the new GTK file
6280 chooser is used instead. To turn off all file dialogs set the
6281 variable `use-file-dialog'. */);
6282 x_gtk_use_old_file_dialog = 0;
6284 DEFVAR_BOOL ("x-gtk-show-hidden-files", x_gtk_show_hidden_files,
6285 doc: /* If non-nil, the GTK file chooser will by default show hidden files.
6286 Note that this is just the default, there is a toggle button on the file
6287 chooser to show or not show hidden files on a case by case basis. */);
6288 x_gtk_show_hidden_files = 0;
6290 DEFVAR_BOOL ("x-gtk-file-dialog-help-text", x_gtk_file_dialog_help_text,
6291 doc: /* If non-nil, the GTK file chooser will show additional help text.
6292 If more space for files in the file chooser dialog is wanted, set this to nil
6293 to turn the additional text off. */);
6294 x_gtk_file_dialog_help_text = 1;
6296 DEFVAR_BOOL ("x-gtk-use-system-tooltips", x_gtk_use_system_tooltips,
6297 doc: /* If non-nil with a Gtk+ built Emacs, the Gtk+ tooltip is used.
6298 Otherwise use Emacs own tooltip implementation.
6299 When using Gtk+ tooltips, the tooltip face is not used. */);
6300 x_gtk_use_system_tooltips = 1;
6302 /* Tell Emacs about this window system. */
6303 Fprovide (Qx, Qnil);
6305 #ifdef USE_X_TOOLKIT
6306 Fprovide (intern_c_string ("x-toolkit"), Qnil);
6307 #ifdef USE_MOTIF
6308 Fprovide (intern_c_string ("motif"), Qnil);
6310 DEFVAR_LISP ("motif-version-string", Vmotif_version_string,
6311 doc: /* Version info for LessTif/Motif. */);
6312 Vmotif_version_string = build_string (XmVERSION_STRING);
6313 #endif /* USE_MOTIF */
6314 #endif /* USE_X_TOOLKIT */
6316 #ifdef USE_GTK
6317 /* Provide x-toolkit also for GTK. Internally GTK does not use Xt so it
6318 is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
6319 But for a user it is a toolkit for X, and indeed, configure
6320 accepts --with-x-toolkit=gtk. */
6321 Fprovide (intern_c_string ("x-toolkit"), Qnil);
6322 Fprovide (intern_c_string ("gtk"), Qnil);
6323 Fprovide (intern_c_string ("move-toolbar"), Qnil);
6325 DEFVAR_LISP ("gtk-version-string", Vgtk_version_string,
6326 doc: /* Version info for GTK+. */);
6328 char gtk_version[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
6329 int len = sprintf (gtk_version, "%d.%d.%d",
6330 GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
6331 Vgtk_version_string = make_pure_string (gtk_version, len, len, 0);
6333 #endif /* USE_GTK */
6335 /* X window properties. */
6336 defsubr (&Sx_change_window_property);
6337 defsubr (&Sx_delete_window_property);
6338 defsubr (&Sx_window_property);
6340 defsubr (&Sxw_display_color_p);
6341 defsubr (&Sx_display_grayscale_p);
6342 defsubr (&Sxw_color_defined_p);
6343 defsubr (&Sxw_color_values);
6344 defsubr (&Sx_server_max_request_size);
6345 defsubr (&Sx_server_vendor);
6346 defsubr (&Sx_server_version);
6347 defsubr (&Sx_display_pixel_width);
6348 defsubr (&Sx_display_pixel_height);
6349 defsubr (&Sx_display_mm_width);
6350 defsubr (&Sx_display_mm_height);
6351 defsubr (&Sx_display_screens);
6352 defsubr (&Sx_display_planes);
6353 defsubr (&Sx_display_color_cells);
6354 defsubr (&Sx_display_visual_class);
6355 defsubr (&Sx_display_backing_store);
6356 defsubr (&Sx_display_save_under);
6357 defsubr (&Sx_display_monitor_attributes_list);
6358 defsubr (&Sx_frame_geometry);
6359 defsubr (&Sx_wm_set_size_hint);
6360 defsubr (&Sx_create_frame);
6361 defsubr (&Sx_open_connection);
6362 defsubr (&Sx_close_connection);
6363 defsubr (&Sx_display_list);
6364 defsubr (&Sx_synchronize);
6365 defsubr (&Sx_backspace_delete_keys_p);
6367 defsubr (&Sx_show_tip);
6368 defsubr (&Sx_hide_tip);
6369 tip_timer = Qnil;
6370 staticpro (&tip_timer);
6371 tip_frame = Qnil;
6372 staticpro (&tip_frame);
6374 last_show_tip_args = Qnil;
6375 staticpro (&last_show_tip_args);
6377 defsubr (&Sx_uses_old_gtk_dialog);
6378 #if defined (USE_MOTIF) || defined (USE_GTK)
6379 defsubr (&Sx_file_dialog);
6380 #endif
6382 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
6383 defsubr (&Sx_select_font);
6384 #endif