]> code.delx.au - gnu-emacs/blob - src/xfns.c
Merge from emacs-24; up to 2014-08-07T11:49:36Z!rrt@sc3d.org
[gnu-emacs] / src / xfns.c
1 /* Functions for the X window system.
2
3 Copyright (C) 1989, 1992-2014 Free Software Foundation, Inc.
4
5 This file is part of GNU Emacs.
6
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.
11
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.
16
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/>. */
19
20 #include <config.h>
21 #include <stdio.h>
22 #include <math.h>
23 #include <unistd.h>
24
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"
45
46 #include <sys/types.h>
47 #include <sys/stat.h>
48
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
54
55 #include "xsettings.h"
56
57 #ifdef HAVE_XRANDR
58 #include <X11/extensions/Xrandr.h>
59 #endif
60 #ifdef HAVE_XINERAMA
61 #include <X11/extensions/Xinerama.h>
62 #endif
63
64 #ifdef USE_GTK
65 #include "gtkutil.h"
66 #endif
67
68 #ifdef USE_X_TOOLKIT
69 #include <X11/Shell.h>
70
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 */
80
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
90
91 #include "widget.h"
92
93 #include "../lwlib/lwlib.h"
94
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
102
103 #ifdef USE_LUCID
104 #include "../lwlib/xlwmenu.h"
105 #endif
106
107 #if !defined (NO_EDITRES)
108 #define HACK_EDITRES
109 extern void _XEditResCheckMessages (Widget, XtPointer, XEvent *, Boolean *);
110 #endif /* not defined NO_EDITRES */
111
112 /* Unique id counter for widgets created by the Lucid Widget Library. */
113
114 extern LWLIB_ID widget_id_tick;
115
116 #ifdef USE_MOTIF
117
118 #endif /* USE_MOTIF */
119
120 #endif /* USE_X_TOOLKIT */
121
122 #ifdef USE_GTK
123
124 #endif /* USE_GTK */
125
126 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
127
128 static Lisp_Object Qundefined_color;
129 static Lisp_Object Qcompound_text, Qcancel_timer;
130 Lisp_Object Qfont_param;
131
132 #ifdef GLYPH_DEBUG
133 static ptrdiff_t image_cache_refcount;
134 static int dpyinfo_refcount;
135 #endif
136
137 static struct x_display_info *x_display_info_for_name (Lisp_Object);
138
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. */
143
144 struct x_display_info *
145 check_x_display_info (Lisp_Object object)
146 {
147 struct x_display_info *dpyinfo = NULL;
148
149 if (NILP (object))
150 {
151 struct frame *sf = XFRAME (selected_frame);
152
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");
159 }
160 else if (TERMINALP (object))
161 {
162 struct terminal *t = decode_live_terminal (object);
163
164 if (t->type != output_x_window)
165 error ("Terminal %d is not an X display", t->id);
166
167 dpyinfo = t->display_info.x;
168 }
169 else if (STRINGP (object))
170 dpyinfo = x_display_info_for_name (object);
171 else
172 {
173 struct frame *f = decode_window_system_frame (object);
174 dpyinfo = FRAME_DISPLAY_INFO (f);
175 }
176
177 return dpyinfo;
178 }
179
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. */
183
184 void
185 x_real_positions (struct frame *f, int *xptr, int *yptr)
186 {
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;
199
200 block_input ();
201
202 x_catch_errors (dpy);
203
204 if (win == dpyinfo->root_window)
205 win = FRAME_OUTER_WINDOW (f);
206
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 (;;)
212 {
213 Window wm_window, rootw;
214 Window *tmp_children;
215 unsigned int tmp_nchildren;
216 int success;
217
218 success = XQueryTree (FRAME_X_DISPLAY (f), win, &rootw,
219 &wm_window, &tmp_children, &tmp_nchildren);
220
221 had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
222
223 /* Don't free tmp_children if XQueryTree failed. */
224 if (! success)
225 break;
226
227 XFree (tmp_children);
228
229 if (wm_window == rootw || had_errors)
230 break;
231
232 win = wm_window;
233 }
234
235 if (! had_errors)
236 {
237 unsigned int ign;
238 Window child, rootw;
239
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);
243
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:
248
249 ------------------ ---> x
250 | title |
251 | ----------------- v y
252 | | our window
253 */
254 XTranslateCoordinates (FRAME_X_DISPLAY (f),
255
256 /* From-window, to-window. */
257 FRAME_DISPLAY_INFO (f)->root_window,
258 FRAME_X_WINDOW (f),
259
260 /* From-position, to-position. */
261 real_x, real_y, &win_x, &win_y,
262
263 /* Child of win. */
264 &child);
265
266 if (FRAME_X_WINDOW (f) == FRAME_OUTER_WINDOW (f))
267 {
268 outer_x = win_x;
269 outer_y = win_y;
270 }
271 else
272 {
273 XTranslateCoordinates (FRAME_X_DISPLAY (f),
274
275 /* From-window, to-window. */
276 FRAME_DISPLAY_INFO (f)->root_window,
277 FRAME_OUTER_WINDOW (f),
278
279 /* From-position, to-position. */
280 real_x, real_y, &outer_x, &outer_y,
281
282 /* Child of win. */
283 &child);
284 }
285
286 had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
287 }
288
289
290 if (dpyinfo->root_window == f->output_data.x->parent_desc)
291 {
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);
297
298 if (rc == Success && actual_type == target_type && !x_had_errors_p (dpy)
299 && actual_size == 4 && actual_format == 32)
300 {
301 unsigned int ign;
302 Window rootw;
303 long *fe = (long *)tmp_data;
304
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];
311 }
312 }
313
314 if (tmp_data) XFree (tmp_data);
315
316 x_uncatch_errors ();
317
318 unblock_input ();
319
320 if (had_errors) return;
321
322 f->x_pixels_diff = -win_x;
323 f->y_pixels_diff = -win_y;
324
325 FRAME_X_OUTPUT (f)->x_pixels_outer_diff = -outer_x;
326 FRAME_X_OUTPUT (f)->y_pixels_outer_diff = -outer_y;
327
328 *xptr = real_x;
329 *yptr = real_y;
330 }
331
332 /* Get the mouse position in frame relative coordinates. */
333
334 void
335 x_relative_mouse_position (struct frame *f, int *x, int *y)
336 {
337 Window root, dummy_window;
338 int dummy;
339
340 eassert (FRAME_X_P (f));
341
342 block_input ();
343
344 XQueryPointer (FRAME_X_DISPLAY (f),
345 DefaultRootWindow (FRAME_X_DISPLAY (f)),
346
347 /* The root window which contains the pointer. */
348 &root,
349
350 /* Window pointer is on, not used */
351 &dummy_window,
352
353 /* The position on that root window. */
354 x, y,
355
356 /* x/y in dummy_window coordinates, not used. */
357 &dummy, &dummy,
358
359 /* Modifier keys and pointer buttons, about which
360 we don't care. */
361 (unsigned int *) &dummy);
362
363 unblock_input ();
364
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);
368 }
369
370 /* Gamma-correct COLOR on frame F. */
371
372 void
373 gamma_correct (struct frame *f, XColor *color)
374 {
375 if (f->gamma)
376 {
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;
380 }
381 }
382
383
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. */
388
389 bool
390 x_defined_color (struct frame *f, const char *color_name,
391 XColor *color, bool alloc_p)
392 {
393 bool success_p = 0;
394 Display *dpy = FRAME_X_DISPLAY (f);
395 Colormap cmap = FRAME_X_COLORMAP (f);
396
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 ();
406
407 return success_p;
408 }
409
410
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. */
414
415 static int
416 x_decode_color (struct frame *f, Lisp_Object color_name, int mono_color)
417 {
418 XColor cdef;
419
420 CHECK_STRING (color_name);
421
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
430
431 /* Return MONO_COLOR for monochrome frames. */
432 if (FRAME_DISPLAY_INFO (f)->n_planes == 1)
433 return mono_color;
434
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;
439
440 signal_error ("Undefined color", color_name);
441 }
442
443
444 \f
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. */
448
449 static void
450 x_set_wait_for_wm (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
451 {
452 f->output_data.x->wait_for_wm = !NILP (new_value);
453 }
454
455 static void
456 x_set_tool_bar_position (struct frame *f,
457 Lisp_Object new_value,
458 Lisp_Object old_value)
459 {
460 Lisp_Object choice = list4 (Qleft, Qright, Qtop, Qbottom);
461
462 if (!NILP (Fmemq (new_value, choice)))
463 {
464 #ifdef USE_GTK
465 if (!EQ (new_value, old_value))
466 {
467 xg_change_toolbar_position (f, new_value);
468 fset_tool_bar_position (f, new_value);
469 }
470 #else
471 if (!EQ (new_value, Qtop))
472 error ("The only supported tool bar position is top");
473 #endif
474 }
475 else
476 wrong_choice (choice, new_value);
477 }
478
479 #ifdef USE_GTK
480
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. */
483
484 int
485 xg_set_icon (struct frame *f, Lisp_Object file)
486 {
487 int result = 0;
488 Lisp_Object found;
489
490 found = x_find_image_file (file);
491
492 if (! NILP (found))
493 {
494 GdkPixbuf *pixbuf;
495 GError *err = NULL;
496 char *filename = SSDATA (found);
497 block_input ();
498
499 pixbuf = gdk_pixbuf_new_from_file (filename, &err);
500
501 if (pixbuf)
502 {
503 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
504 pixbuf);
505 g_object_unref (pixbuf);
506
507 result = 1;
508 }
509 else
510 g_error_free (err);
511
512 unblock_input ();
513 }
514
515 return result;
516 }
517
518 int
519 xg_set_icon_from_xpm_data (struct frame *f, const char **data)
520 {
521 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data (data);
522
523 if (!pixbuf)
524 return 0;
525
526 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), pixbuf);
527 g_object_unref (pixbuf);
528 return 1;
529 }
530 #endif /* USE_GTK */
531
532
533 /* Functions called only from `x_set_frame_param'
534 to set individual parameters.
535
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. */
540
541 static void
542 x_set_foreground_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
543 {
544 struct x_output *x = f->output_data.x;
545 unsigned long fg, old_fg;
546
547 fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
548 old_fg = FRAME_FOREGROUND_PIXEL (f);
549 FRAME_FOREGROUND_PIXEL (f) = fg;
550
551 if (FRAME_X_WINDOW (f) != 0)
552 {
553 Display *dpy = FRAME_X_DISPLAY (f);
554
555 block_input ();
556 XSetForeground (dpy, x->normal_gc, fg);
557 XSetBackground (dpy, x->reverse_gc, fg);
558
559 if (x->cursor_pixel == old_fg)
560 {
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);
564 }
565
566 unblock_input ();
567
568 update_face_from_frame_parameter (f, Qforeground_color, arg);
569
570 if (FRAME_VISIBLE_P (f))
571 redraw_frame (f);
572 }
573
574 unload_color (f, old_fg);
575 }
576
577 static void
578 x_set_background_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
579 {
580 struct x_output *x = f->output_data.x;
581 unsigned long bg;
582
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;
586
587 if (FRAME_X_WINDOW (f) != 0)
588 {
589 Display *dpy = FRAME_X_DISPLAY (f);
590
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);
596
597 #ifdef USE_GTK
598 xg_set_background_color (f, bg);
599 #endif
600
601 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
602 toolkit scroll bars. */
603 {
604 Lisp_Object bar;
605 for (bar = FRAME_SCROLL_BARS (f);
606 !NILP (bar);
607 bar = XSCROLL_BAR (bar)->next)
608 {
609 Window window = XSCROLL_BAR (bar)->x_window;
610 XSetWindowBackground (dpy, window, bg);
611 }
612 }
613 #endif /* USE_TOOLKIT_SCROLL_BARS */
614
615 unblock_input ();
616 update_face_from_frame_parameter (f, Qbackground_color, arg);
617
618 if (FRAME_VISIBLE_P (f))
619 redraw_frame (f);
620 }
621 }
622
623 static void
624 x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
625 {
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);
632
633 /* Don't let pointers be invisible. */
634 if (mask_color == pixel)
635 {
636 x_free_colors (f, &pixel, 1);
637 pixel = x_copy_color (f, FRAME_FOREGROUND_PIXEL (f));
638 }
639
640 unload_color (f, x->mouse_pixel);
641 x->mouse_pixel = pixel;
642
643 block_input ();
644
645 /* It's not okay to crash if the user selects a screwy cursor. */
646 x_catch_errors (dpy);
647
648 if (!NILP (Vx_pointer_shape))
649 {
650 CHECK_NUMBER (Vx_pointer_shape);
651 cursor = XCreateFontCursor (dpy, XINT (Vx_pointer_shape));
652 }
653 else
654 cursor = XCreateFontCursor (dpy, XC_xterm);
655 x_check_errors (dpy, "bad text pointer cursor: %s");
656
657 if (!NILP (Vx_nontext_pointer_shape))
658 {
659 CHECK_NUMBER (Vx_nontext_pointer_shape);
660 nontext_cursor
661 = XCreateFontCursor (dpy, XINT (Vx_nontext_pointer_shape));
662 }
663 else
664 nontext_cursor = XCreateFontCursor (dpy, XC_left_ptr);
665 x_check_errors (dpy, "bad nontext pointer cursor: %s");
666
667 if (!NILP (Vx_hourglass_pointer_shape))
668 {
669 CHECK_NUMBER (Vx_hourglass_pointer_shape);
670 hourglass_cursor
671 = XCreateFontCursor (dpy, XINT (Vx_hourglass_pointer_shape));
672 }
673 else
674 hourglass_cursor = XCreateFontCursor (dpy, XC_watch);
675 x_check_errors (dpy, "bad hourglass pointer cursor: %s");
676
677 if (!NILP (Vx_mode_pointer_shape))
678 {
679 CHECK_NUMBER (Vx_mode_pointer_shape);
680 mode_cursor = XCreateFontCursor (dpy, XINT (Vx_mode_pointer_shape));
681 }
682 else
683 mode_cursor = XCreateFontCursor (dpy, XC_xterm);
684 x_check_errors (dpy, "bad modeline pointer cursor: %s");
685
686 if (!NILP (Vx_sensitive_text_pointer_shape))
687 {
688 CHECK_NUMBER (Vx_sensitive_text_pointer_shape);
689 hand_cursor
690 = XCreateFontCursor (dpy, XINT (Vx_sensitive_text_pointer_shape));
691 }
692 else
693 hand_cursor = XCreateFontCursor (dpy, XC_hand2);
694
695 if (!NILP (Vx_window_horizontal_drag_shape))
696 {
697 CHECK_TYPE_RANGED_INTEGER (unsigned, Vx_window_horizontal_drag_shape);
698 horizontal_drag_cursor
699 = XCreateFontCursor (dpy, XINT (Vx_window_horizontal_drag_shape));
700 }
701 else
702 horizontal_drag_cursor
703 = XCreateFontCursor (dpy, XC_sb_h_double_arrow);
704
705 if (!NILP (Vx_window_vertical_drag_shape))
706 {
707 CHECK_NUMBER (Vx_window_vertical_drag_shape);
708 vertical_drag_cursor
709 = XCreateFontCursor (dpy, XINT (Vx_window_vertical_drag_shape));
710 }
711 else
712 vertical_drag_cursor
713 = XCreateFontCursor (dpy, XC_sb_v_double_arrow);
714
715 /* Check and report errors with the above calls. */
716 x_check_errors (dpy, "can't set cursor shape: %s");
717 x_uncatch_errors ();
718
719 {
720 XColor fore_color, back_color;
721
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);
726
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);
734 }
735
736 if (FRAME_X_WINDOW (f) != 0)
737 XDefineCursor (dpy, FRAME_X_WINDOW (f),
738 f->output_data.x->current_cursor = cursor);
739
740 if (cursor != x->text_cursor
741 && x->text_cursor != 0)
742 XFreeCursor (dpy, x->text_cursor);
743 x->text_cursor = cursor;
744
745 if (nontext_cursor != x->nontext_cursor
746 && x->nontext_cursor != 0)
747 XFreeCursor (dpy, x->nontext_cursor);
748 x->nontext_cursor = nontext_cursor;
749
750 if (hourglass_cursor != x->hourglass_cursor
751 && x->hourglass_cursor != 0)
752 XFreeCursor (dpy, x->hourglass_cursor);
753 x->hourglass_cursor = hourglass_cursor;
754
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;
759
760 if (hand_cursor != x->hand_cursor
761 && x->hand_cursor != 0)
762 XFreeCursor (dpy, x->hand_cursor);
763 x->hand_cursor = hand_cursor;
764
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;
769
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;
774
775 XFlush (dpy);
776 unblock_input ();
777
778 update_face_from_frame_parameter (f, Qmouse_color, arg);
779 }
780
781 static void
782 x_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
783 {
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;
787
788 if (!NILP (Vx_cursor_fore_pixel))
789 {
790 fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
791 WHITE_PIX_DEFAULT (f));
792 fore_pixel_allocated_p = 1;
793 }
794 else
795 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
796
797 pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
798 pixel_allocated_p = 1;
799
800 /* Make sure that the cursor color differs from the background color. */
801 if (pixel == FRAME_BACKGROUND_PIXEL (f))
802 {
803 if (pixel_allocated_p)
804 {
805 x_free_colors (f, &pixel, 1);
806 pixel_allocated_p = 0;
807 }
808
809 pixel = x->mouse_pixel;
810 if (pixel == fore_pixel)
811 {
812 if (fore_pixel_allocated_p)
813 {
814 x_free_colors (f, &fore_pixel, 1);
815 fore_pixel_allocated_p = 0;
816 }
817 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
818 }
819 }
820
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;
825
826 unload_color (f, x->cursor_pixel);
827 if (!pixel_allocated_p)
828 pixel = x_copy_color (f, pixel);
829 x->cursor_pixel = pixel;
830
831 if (FRAME_X_WINDOW (f) != 0)
832 {
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 ();
837
838 if (FRAME_VISIBLE_P (f))
839 {
840 x_update_cursor (f, 0);
841 x_update_cursor (f, 1);
842 }
843 }
844
845 update_face_from_frame_parameter (f, Qcursor_color, arg);
846 }
847 \f
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. */
851
852 static void
853 x_set_border_pixel (struct frame *f, int pix)
854 {
855 unload_color (f, f->output_data.x->border_pixel);
856 f->output_data.x->border_pixel = pix;
857
858 if (FRAME_X_WINDOW (f) != 0 && f->border_width > 0)
859 {
860 block_input ();
861 XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), pix);
862 unblock_input ();
863
864 if (FRAME_VISIBLE_P (f))
865 redraw_frame (f);
866 }
867 }
868
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.
874
875 Note: this is done in two routines because of the way X10 works.
876
877 Note: under X11, this is normally the province of the window manager,
878 and so emacs's border colors may be overridden. */
879
880 static void
881 x_set_border_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
882 {
883 int pix;
884
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);
889 }
890
891
892 static void
893 x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
894 {
895 set_frame_cursor_types (f, arg);
896 }
897
898 static void
899 x_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
900 {
901 int result;
902
903 if (STRINGP (arg))
904 {
905 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
906 return;
907 }
908 else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
909 return;
910
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);
919
920 if (result)
921 {
922 unblock_input ();
923 error ("No icon window available");
924 }
925
926 XFlush (FRAME_X_DISPLAY (f));
927 unblock_input ();
928 }
929
930 static void
931 x_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
932 {
933 int result;
934
935 if (STRINGP (arg))
936 {
937 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
938 return;
939 }
940 else if (!NILP (arg) || NILP (oldval))
941 return;
942
943 fset_icon_name (f, arg);
944
945 if (f->output_data.x->icon_bitmap != 0)
946 return;
947
948 block_input ();
949
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)));
956
957 if (result)
958 {
959 unblock_input ();
960 error ("No icon window available");
961 }
962
963 XFlush (FRAME_X_DISPLAY (f));
964 unblock_input ();
965 }
966
967 \f
968 static void
969 x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
970 {
971 int nlines;
972 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
973 int olines = FRAME_MENU_BAR_LINES (f);
974 #endif
975
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;
982
983 if (TYPE_RANGED_INTEGERP (int, value))
984 nlines = XINT (value);
985 else
986 nlines = 0;
987
988 /* Make sure we redisplay all windows in this frame. */
989 windows_or_buffers_changed = 59;
990
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)
995 {
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;
1000 }
1001 else
1002 {
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;
1008 }
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);
1013 if (FRAME_X_WINDOW (f))
1014 x_clear_under_internal_border (f);
1015
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)
1021 {
1022 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1023 int width = FRAME_PIXEL_WIDTH (f);
1024 int y;
1025
1026 /* height can be zero here. */
1027 if (FRAME_X_WINDOW (f) && height > 0 && width > 0)
1028 {
1029 y = FRAME_TOP_MARGIN_HEIGHT (f);
1030
1031 block_input ();
1032 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1033 0, y, width, height);
1034 unblock_input ();
1035 }
1036
1037 if (nlines > 1 && nlines > olines)
1038 {
1039 y = (olines == 0 ? 1 : olines) * FRAME_LINE_HEIGHT (f);
1040 height = nlines * FRAME_LINE_HEIGHT (f) - y;
1041
1042 block_input ();
1043 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1044 0, y, width, height);
1045 unblock_input ();
1046 }
1047
1048 if (nlines == 0 && WINDOWP (f->menu_bar_window))
1049 clear_glyph_matrix (XWINDOW (f->menu_bar_window)->current_matrix);
1050 }
1051 #endif /* not USE_X_TOOLKIT && not USE_GTK */
1052 adjust_frame_glyphs (f);
1053 run_window_configuration_change_hook (f);
1054 }
1055
1056
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. */
1062
1063 static void
1064 x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1065 {
1066 int nlines;
1067
1068 /* Treat tool bars like menu bars. */
1069 if (FRAME_MINIBUF_ONLY_P (f))
1070 return;
1071
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;
1077
1078 x_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
1079 }
1080
1081
1082 /* Set the pixel height of the tool bar of frame F to HEIGHT. */
1083 void
1084 x_change_tool_bar_height (struct frame *f, int height)
1085 {
1086 #ifdef USE_GTK
1087 FRAME_TOOL_BAR_LINES (f) = 0;
1088 FRAME_TOOL_BAR_HEIGHT (f) = 0;
1089 if (height)
1090 {
1091 FRAME_EXTERNAL_TOOL_BAR (f) = 1;
1092 if (FRAME_X_P (f) && f->output_data.x->toolbar_widget == 0)
1093 /* Make sure next redisplay shows the tool bar. */
1094 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = 1;
1095 update_frame_tool_bar (f);
1096 }
1097 else
1098 {
1099 if (FRAME_EXTERNAL_TOOL_BAR (f))
1100 free_frame_tool_bar (f);
1101 FRAME_EXTERNAL_TOOL_BAR (f) = 0;
1102 }
1103 #else /* !USE_GTK */
1104 int unit = FRAME_LINE_HEIGHT (f);
1105 int old_height = FRAME_TOOL_BAR_HEIGHT (f);
1106 int lines = (height + unit - 1) / unit;
1107
1108 /* Make sure we redisplay all windows in this frame. */
1109 windows_or_buffers_changed = 60;
1110
1111
1112 /* Recalculate tool bar and frame text sizes. */
1113 FRAME_TOOL_BAR_HEIGHT (f) = height;
1114 FRAME_TOOL_BAR_LINES (f) = lines;
1115 FRAME_TEXT_HEIGHT (f)
1116 = FRAME_PIXEL_TO_TEXT_HEIGHT (f, FRAME_PIXEL_HEIGHT (f));
1117 FRAME_LINES (f)
1118 = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, FRAME_PIXEL_HEIGHT (f));
1119 /* Store the `tool-bar-lines' and `height' frame parameters. */
1120 store_frame_param (f, Qtool_bar_lines, make_number (lines));
1121 store_frame_param (f, Qheight, make_number (FRAME_LINES (f)));
1122
1123 /* We also have to make sure that the internal border at the top of
1124 the frame, below the menu bar or tool bar, is redrawn when the
1125 tool bar disappears. This is so because the internal border is
1126 below the tool bar if one is displayed, but is below the menu bar
1127 if there isn't a tool bar. The tool bar draws into the area
1128 below the menu bar. */
1129 if (FRAME_X_WINDOW (f) && FRAME_TOOL_BAR_HEIGHT (f) == 0)
1130 {
1131 clear_frame (f);
1132 clear_current_matrices (f);
1133 }
1134
1135 if ((height < old_height) && WINDOWP (f->tool_bar_window))
1136 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1137
1138 /* Recalculate toolbar height. */
1139 f->n_tool_bar_rows = 0;
1140
1141 adjust_frame_size (f, -1, -1, 4, 0);
1142
1143 if (FRAME_X_WINDOW (f))
1144 x_clear_under_internal_border (f);
1145
1146 #endif /* USE_GTK */
1147 }
1148
1149
1150 static void
1151 x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1152 {
1153 int border;
1154
1155 CHECK_TYPE_RANGED_INTEGER (int, arg);
1156 border = max (XINT (arg), 0);
1157
1158 if (border != FRAME_INTERNAL_BORDER_WIDTH (f))
1159 {
1160 FRAME_INTERNAL_BORDER_WIDTH (f) = border;
1161
1162 #ifdef USE_X_TOOLKIT
1163 if (FRAME_X_OUTPUT (f)->edit_widget)
1164 widget_store_internal_border (FRAME_X_OUTPUT (f)->edit_widget);
1165 #endif
1166
1167 if (FRAME_X_WINDOW (f) != 0)
1168 {
1169 adjust_frame_size (f, -1, -1, 3, 0);
1170
1171 #ifdef USE_GTK
1172 xg_clear_under_internal_border (f);
1173 #else
1174 x_clear_under_internal_border (f);
1175 #endif
1176 }
1177 }
1178
1179 }
1180
1181
1182 /* Set the foreground color for scroll bars on frame F to VALUE.
1183 VALUE should be a string, a color name. If it isn't a string or
1184 isn't a valid color name, do nothing. OLDVAL is the old value of
1185 the frame parameter. */
1186
1187 static void
1188 x_set_scroll_bar_foreground (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1189 {
1190 unsigned long pixel;
1191
1192 if (STRINGP (value))
1193 pixel = x_decode_color (f, value, BLACK_PIX_DEFAULT (f));
1194 else
1195 pixel = -1;
1196
1197 if (f->output_data.x->scroll_bar_foreground_pixel != -1)
1198 unload_color (f, f->output_data.x->scroll_bar_foreground_pixel);
1199
1200 f->output_data.x->scroll_bar_foreground_pixel = pixel;
1201 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1202 {
1203 /* Remove all scroll bars because they have wrong colors. */
1204 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1205 (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1206 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1207 (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1208
1209 update_face_from_frame_parameter (f, Qscroll_bar_foreground, value);
1210 redraw_frame (f);
1211 }
1212 }
1213
1214
1215 /* Set the background color for scroll bars on frame F to VALUE VALUE
1216 should be a string, a color name. If it isn't a string or isn't a
1217 valid color name, do nothing. OLDVAL is the old value of the frame
1218 parameter. */
1219
1220 static void
1221 x_set_scroll_bar_background (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1222 {
1223 unsigned long pixel;
1224
1225 if (STRINGP (value))
1226 pixel = x_decode_color (f, value, WHITE_PIX_DEFAULT (f));
1227 else
1228 pixel = -1;
1229
1230 if (f->output_data.x->scroll_bar_background_pixel != -1)
1231 unload_color (f, f->output_data.x->scroll_bar_background_pixel);
1232
1233 #if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
1234 /* Scrollbar shadow colors. */
1235 if (f->output_data.x->scroll_bar_top_shadow_pixel != -1)
1236 {
1237 unload_color (f, f->output_data.x->scroll_bar_top_shadow_pixel);
1238 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
1239 }
1240 if (f->output_data.x->scroll_bar_bottom_shadow_pixel != -1)
1241 {
1242 unload_color (f, f->output_data.x->scroll_bar_bottom_shadow_pixel);
1243 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
1244 }
1245 #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
1246
1247 f->output_data.x->scroll_bar_background_pixel = pixel;
1248 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1249 {
1250 /* Remove all scroll bars because they have wrong colors. */
1251 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1252 (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1253 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1254 (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1255
1256 update_face_from_frame_parameter (f, Qscroll_bar_background, value);
1257 redraw_frame (f);
1258 }
1259 }
1260
1261 \f
1262 /* Encode Lisp string STRING as a text in a format appropriate for
1263 XICCC (X Inter Client Communication Conventions).
1264
1265 This can call Lisp code, so callers must GCPRO.
1266
1267 If STRING contains only ASCII characters, do no conversion and
1268 return the string data of STRING. Otherwise, encode the text by
1269 CODING_SYSTEM, and return a newly allocated memory area which
1270 should be freed by `xfree' by a caller.
1271
1272 Store the byte length of resulting text in *TEXT_BYTES.
1273
1274 If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
1275 which means that the `encoding' of the result can be `STRING'.
1276 Otherwise store 0 in *STRINGP, which means that the `encoding' of
1277 the result should be `COMPOUND_TEXT'. */
1278
1279 static unsigned char *
1280 x_encode_text (Lisp_Object string, Lisp_Object coding_system,
1281 ptrdiff_t *text_bytes, int *stringp, bool *freep)
1282 {
1283 int result = string_xstring_p (string);
1284 struct coding_system coding;
1285
1286 if (result == 0)
1287 {
1288 /* No multibyte character in OBJ. We need not encode it. */
1289 *text_bytes = SBYTES (string);
1290 *stringp = 1;
1291 *freep = 0;
1292 return SDATA (string);
1293 }
1294
1295 setup_coding_system (coding_system, &coding);
1296 coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK);
1297 /* We suppress producing escape sequences for composition. */
1298 coding.common_flags &= ~CODING_ANNOTATION_MASK;
1299 coding.destination = xnmalloc (SCHARS (string), 2);
1300 coding.dst_bytes = SCHARS (string) * 2;
1301 encode_coding_object (&coding, string, 0, 0,
1302 SCHARS (string), SBYTES (string), Qnil);
1303 *text_bytes = coding.produced;
1304 *stringp = (result == 1 || !EQ (coding_system, Qcompound_text));
1305 *freep = 1;
1306 return coding.destination;
1307 }
1308
1309 \f
1310 /* Set the WM name to NAME for frame F. Also set the icon name.
1311 If the frame already has an icon name, use that, otherwise set the
1312 icon name to NAME. */
1313
1314 static void
1315 x_set_name_internal (struct frame *f, Lisp_Object name)
1316 {
1317 if (FRAME_X_WINDOW (f))
1318 {
1319 block_input ();
1320 {
1321 XTextProperty text, icon;
1322 ptrdiff_t bytes;
1323 int stringp;
1324 bool do_free_icon_value = 0, do_free_text_value = 0;
1325 Lisp_Object coding_system;
1326 Lisp_Object encoded_name;
1327 Lisp_Object encoded_icon_name;
1328 struct gcpro gcpro1;
1329
1330 /* As ENCODE_UTF_8 may cause GC and relocation of string data,
1331 we use it before x_encode_text that may return string data. */
1332 GCPRO1 (name);
1333 encoded_name = ENCODE_UTF_8 (name);
1334 UNGCPRO;
1335
1336 coding_system = Qcompound_text;
1337 /* Note: Encoding strategy
1338
1339 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1340 text.encoding. But, there are non-internationalized window
1341 managers which don't support that encoding. So, if NAME
1342 contains only ASCII and 8859-1 characters, encode it by
1343 iso-latin-1, and use "STRING" in text.encoding hoping that
1344 such window managers at least analyze this format correctly,
1345 i.e. treat 8-bit bytes as 8859-1 characters.
1346
1347 We may also be able to use "UTF8_STRING" in text.encoding
1348 in the future which can encode all Unicode characters.
1349 But, for the moment, there's no way to know that the
1350 current window manager supports it or not.
1351
1352 Either way, we also set the _NET_WM_NAME and _NET_WM_ICON_NAME
1353 properties. Per the EWMH specification, those two properties
1354 are always UTF8_STRING. This matches what gtk_window_set_title()
1355 does in the USE_GTK case. */
1356 text.value = x_encode_text (name, coding_system, &bytes,
1357 &stringp, &do_free_text_value);
1358 text.encoding = (stringp ? XA_STRING
1359 : FRAME_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1360 text.format = 8;
1361 text.nitems = bytes;
1362
1363 if (!STRINGP (f->icon_name))
1364 {
1365 icon = text;
1366 encoded_icon_name = encoded_name;
1367 }
1368 else
1369 {
1370 /* See the above comment "Note: Encoding strategy". */
1371 icon.value = x_encode_text (f->icon_name, coding_system, &bytes,
1372 &stringp, &do_free_icon_value);
1373 icon.encoding = (stringp ? XA_STRING
1374 : FRAME_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1375 icon.format = 8;
1376 icon.nitems = bytes;
1377
1378 encoded_icon_name = ENCODE_UTF_8 (f->icon_name);
1379 }
1380
1381 #ifdef USE_GTK
1382 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
1383 SSDATA (encoded_name));
1384 #else /* not USE_GTK */
1385 XSetWMName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &text);
1386 XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
1387 FRAME_DISPLAY_INFO (f)->Xatom_net_wm_name,
1388 FRAME_DISPLAY_INFO (f)->Xatom_UTF8_STRING,
1389 8, PropModeReplace,
1390 SDATA (encoded_name),
1391 SBYTES (encoded_name));
1392 #endif /* not USE_GTK */
1393
1394 XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &icon);
1395 XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
1396 FRAME_DISPLAY_INFO (f)->Xatom_net_wm_icon_name,
1397 FRAME_DISPLAY_INFO (f)->Xatom_UTF8_STRING,
1398 8, PropModeReplace,
1399 SDATA (encoded_icon_name),
1400 SBYTES (encoded_icon_name));
1401
1402 if (do_free_icon_value)
1403 xfree (icon.value);
1404 if (do_free_text_value)
1405 xfree (text.value);
1406 }
1407 unblock_input ();
1408 }
1409 }
1410
1411 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1412 x_id_name.
1413
1414 If EXPLICIT is true, that indicates that lisp code is setting the
1415 name; if NAME is a string, set F's name to NAME and set
1416 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1417
1418 If EXPLICIT is false, that indicates that Emacs redisplay code is
1419 suggesting a new name, which lisp code should override; if
1420 F->explicit_name is set, ignore the new name; otherwise, set it. */
1421
1422 static void
1423 x_set_name (struct frame *f, Lisp_Object name, bool explicit)
1424 {
1425 /* Make sure that requests from lisp code override requests from
1426 Emacs redisplay code. */
1427 if (explicit)
1428 {
1429 /* If we're switching from explicit to implicit, we had better
1430 update the mode lines and thereby update the title. */
1431 if (f->explicit_name && NILP (name))
1432 update_mode_lines = 37;
1433
1434 f->explicit_name = ! NILP (name);
1435 }
1436 else if (f->explicit_name)
1437 return;
1438
1439 /* If NAME is nil, set the name to the x_id_name. */
1440 if (NILP (name))
1441 {
1442 /* Check for no change needed in this very common case
1443 before we do any consing. */
1444 if (!strcmp (FRAME_DISPLAY_INFO (f)->x_id_name,
1445 SSDATA (f->name)))
1446 return;
1447 name = build_string (FRAME_DISPLAY_INFO (f)->x_id_name);
1448 }
1449 else
1450 CHECK_STRING (name);
1451
1452 /* Don't change the name if it's already NAME. */
1453 if (! NILP (Fstring_equal (name, f->name)))
1454 return;
1455
1456 fset_name (f, name);
1457
1458 /* For setting the frame title, the title parameter should override
1459 the name parameter. */
1460 if (! NILP (f->title))
1461 name = f->title;
1462
1463 x_set_name_internal (f, name);
1464 }
1465
1466 /* This function should be called when the user's lisp code has
1467 specified a name for the frame; the name will override any set by the
1468 redisplay code. */
1469 static void
1470 x_explicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1471 {
1472 x_set_name (f, arg, 1);
1473 }
1474
1475 /* This function should be called by Emacs redisplay code to set the
1476 name; names set this way will never override names set by the user's
1477 lisp code. */
1478 void
1479 x_implicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1480 {
1481 x_set_name (f, arg, 0);
1482 }
1483 \f
1484 /* Change the title of frame F to NAME.
1485 If NAME is nil, use the frame name as the title. */
1486
1487 static void
1488 x_set_title (struct frame *f, Lisp_Object name, Lisp_Object old_name)
1489 {
1490 /* Don't change the title if it's already NAME. */
1491 if (EQ (name, f->title))
1492 return;
1493
1494 update_mode_lines = 38;
1495
1496 fset_title (f, name);
1497
1498 if (NILP (name))
1499 name = f->name;
1500 else
1501 CHECK_STRING (name);
1502
1503 x_set_name_internal (f, name);
1504 }
1505
1506 void
1507 x_set_scroll_bar_default_width (struct frame *f)
1508 {
1509 int unit = FRAME_COLUMN_WIDTH (f);
1510 #ifdef USE_TOOLKIT_SCROLL_BARS
1511 #ifdef USE_GTK
1512 int minw = xg_get_default_scrollbar_width ();
1513 #else
1514 int minw = 16;
1515 #endif
1516 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
1517 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (minw + unit - 1) / unit;
1518 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = minw;
1519 #else
1520 /* The width of a non-toolkit scrollbar is 14 pixels. */
1521 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + unit - 1) / unit;
1522 FRAME_CONFIG_SCROLL_BAR_WIDTH (f)
1523 = FRAME_CONFIG_SCROLL_BAR_COLS (f) * unit;
1524 #endif
1525 }
1526
1527 void
1528 x_set_scroll_bar_default_height (struct frame *f)
1529 {
1530 int height = FRAME_LINE_HEIGHT (f);
1531 #ifdef USE_TOOLKIT_SCROLL_BARS
1532 #ifdef USE_GTK
1533 int min_height = xg_get_default_scrollbar_height ();
1534 #else
1535 int min_height = 16;
1536 #endif
1537 /* A minimum height of 14 doesn't look good for toolkit scroll bars. */
1538 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = min_height;
1539 FRAME_CONFIG_SCROLL_BAR_LINES (f) = (min_height + height - 1) / height;
1540 #else
1541 /* The height of a non-toolkit scrollbar is 14 pixels. */
1542 FRAME_CONFIG_SCROLL_BAR_LINES (f) = (14 + height - 1) / height;
1543
1544 /* Use all of that space (aside from required margins) for the
1545 scroll bar. */
1546 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = 14;
1547 #endif
1548 }
1549
1550 \f
1551 /* Record in frame F the specified or default value according to ALIST
1552 of the parameter named PROP (a Lisp symbol). If no value is
1553 specified for PROP, look for an X default for XPROP on the frame
1554 named NAME. If that is not found either, use the value DEFLT. */
1555
1556 static Lisp_Object
1557 x_default_scroll_bar_color_parameter (struct frame *f,
1558 Lisp_Object alist, Lisp_Object prop,
1559 const char *xprop, const char *xclass,
1560 int foreground_p)
1561 {
1562 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
1563 Lisp_Object tem;
1564
1565 tem = x_get_arg (dpyinfo, alist, prop, xprop, xclass, RES_TYPE_STRING);
1566 if (EQ (tem, Qunbound))
1567 {
1568 #ifdef USE_TOOLKIT_SCROLL_BARS
1569
1570 /* See if an X resource for the scroll bar color has been
1571 specified. */
1572 AUTO_STRING (foreground, "foreground");
1573 AUTO_STRING (background, "foreground");
1574 AUTO_STRING (verticalScrollBar, "verticalScrollBar");
1575 tem = (display_x_get_resource
1576 (dpyinfo, foreground_p ? foreground : background,
1577 empty_unibyte_string,
1578 verticalScrollBar,
1579 empty_unibyte_string));
1580 if (!STRINGP (tem))
1581 {
1582 /* If nothing has been specified, scroll bars will use a
1583 toolkit-dependent default. Because these defaults are
1584 difficult to get at without actually creating a scroll
1585 bar, use nil to indicate that no color has been
1586 specified. */
1587 tem = Qnil;
1588 }
1589
1590 #else /* not USE_TOOLKIT_SCROLL_BARS */
1591
1592 tem = Qnil;
1593
1594 #endif /* not USE_TOOLKIT_SCROLL_BARS */
1595 }
1596
1597 AUTO_FRAME_ARG (arg, prop, tem);
1598 x_set_frame_parameters (f, arg);
1599 return tem;
1600 }
1601
1602
1603
1604 \f
1605 #ifdef USE_X_TOOLKIT
1606
1607 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
1608 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
1609 already be present because of the toolkit (Motif adds some of them,
1610 for example, but Xt doesn't). */
1611
1612 static void
1613 hack_wm_protocols (struct frame *f, Widget widget)
1614 {
1615 Display *dpy = XtDisplay (widget);
1616 Window w = XtWindow (widget);
1617 int need_delete = 1;
1618 int need_focus = 1;
1619 int need_save = 1;
1620
1621 block_input ();
1622 {
1623 Atom type;
1624 unsigned char *catoms;
1625 int format = 0;
1626 unsigned long nitems = 0;
1627 unsigned long bytes_after;
1628
1629 if ((XGetWindowProperty (dpy, w,
1630 FRAME_DISPLAY_INFO (f)->Xatom_wm_protocols,
1631 0, 100, False, XA_ATOM,
1632 &type, &format, &nitems, &bytes_after,
1633 &catoms)
1634 == Success)
1635 && format == 32 && type == XA_ATOM)
1636 {
1637 Atom *atoms = (Atom *) catoms;
1638 while (nitems > 0)
1639 {
1640 nitems--;
1641 if (atoms[nitems]
1642 == FRAME_DISPLAY_INFO (f)->Xatom_wm_delete_window)
1643 need_delete = 0;
1644 else if (atoms[nitems]
1645 == FRAME_DISPLAY_INFO (f)->Xatom_wm_take_focus)
1646 need_focus = 0;
1647 else if (atoms[nitems]
1648 == FRAME_DISPLAY_INFO (f)->Xatom_wm_save_yourself)
1649 need_save = 0;
1650 }
1651 }
1652 if (catoms)
1653 XFree (catoms);
1654 }
1655 {
1656 Atom props [10];
1657 int count = 0;
1658 if (need_delete)
1659 props[count++] = FRAME_DISPLAY_INFO (f)->Xatom_wm_delete_window;
1660 if (need_focus)
1661 props[count++] = FRAME_DISPLAY_INFO (f)->Xatom_wm_take_focus;
1662 if (need_save)
1663 props[count++] = FRAME_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
1664 if (count)
1665 XChangeProperty (dpy, w, FRAME_DISPLAY_INFO (f)->Xatom_wm_protocols,
1666 XA_ATOM, 32, PropModeAppend,
1667 (unsigned char *) props, count);
1668 }
1669 unblock_input ();
1670 }
1671 #endif
1672
1673
1674 \f
1675 /* Support routines for XIC (X Input Context). */
1676
1677 #ifdef HAVE_X_I18N
1678
1679 static XFontSet xic_create_xfontset (struct frame *);
1680 static XIMStyle best_xim_style (XIMStyles *);
1681
1682
1683 /* Supported XIM styles, ordered by preference. */
1684
1685 static const XIMStyle supported_xim_styles[] =
1686 {
1687 XIMPreeditPosition | XIMStatusArea,
1688 XIMPreeditPosition | XIMStatusNothing,
1689 XIMPreeditPosition | XIMStatusNone,
1690 XIMPreeditNothing | XIMStatusArea,
1691 XIMPreeditNothing | XIMStatusNothing,
1692 XIMPreeditNothing | XIMStatusNone,
1693 XIMPreeditNone | XIMStatusArea,
1694 XIMPreeditNone | XIMStatusNothing,
1695 XIMPreeditNone | XIMStatusNone,
1696 0,
1697 };
1698
1699
1700 #if defined HAVE_X_WINDOWS && defined USE_X_TOOLKIT
1701 /* Create an X fontset on frame F with base font name BASE_FONTNAME. */
1702
1703 static const char xic_default_fontset[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
1704
1705 /* Create an Xt fontset spec from the name of a base font.
1706 If `motif' is True use the Motif syntax. */
1707 char *
1708 xic_create_fontsetname (const char *base_fontname, int motif)
1709 {
1710 const char *sep = motif ? ";" : ",";
1711 char *fontsetname;
1712
1713 /* Make a fontset name from the base font name. */
1714 if (xic_default_fontset == base_fontname)
1715 {
1716 /* There is no base font name, use the default. */
1717 fontsetname = xmalloc (strlen (base_fontname) + 2);
1718 strcpy (fontsetname, base_fontname);
1719 }
1720 else
1721 {
1722 /* Make a fontset name from the base font name.
1723 The font set will be made of the following elements:
1724 - the base font.
1725 - the base font where the charset spec is replaced by -*-*.
1726 - the same but with the family also replaced with -*-*-. */
1727 const char *p = base_fontname;
1728 ptrdiff_t i;
1729
1730 for (i = 0; *p; p++)
1731 if (*p == '-') i++;
1732 if (i != 14)
1733 {
1734 /* As the font name doesn't conform to XLFD, we can't
1735 modify it to generalize it to allcs and allfamilies.
1736 Use the specified font plus the default. */
1737 fontsetname = xmalloc (strlen (base_fontname)
1738 + strlen (xic_default_fontset) + 3);
1739 strcpy (fontsetname, base_fontname);
1740 strcat (fontsetname, sep);
1741 strcat (fontsetname, xic_default_fontset);
1742 }
1743 else
1744 {
1745 ptrdiff_t len;
1746 const char *p1 = NULL, *p2 = NULL, *p3 = NULL;
1747 char *font_allcs = NULL;
1748 char *font_allfamilies = NULL;
1749 char *font_all = NULL;
1750 const char *allcs = "*-*-*-*-*-*-*";
1751 const char *allfamilies = "-*-*-";
1752 const char *all = "*-*-*-*-";
1753 char *base;
1754
1755 for (i = 0, p = base_fontname; i < 8; p++)
1756 {
1757 if (*p == '-')
1758 {
1759 i++;
1760 if (i == 3)
1761 p1 = p + 1;
1762 else if (i == 7)
1763 p2 = p + 1;
1764 else if (i == 6)
1765 p3 = p + 1;
1766 }
1767 }
1768 /* If base_fontname specifies ADSTYLE, make it a
1769 wildcard. */
1770 if (*p3 != '*')
1771 {
1772 ptrdiff_t diff = (p2 - p3) - 2;
1773
1774 base = alloca (strlen (base_fontname) + 1);
1775 memcpy (base, base_fontname, p3 - base_fontname);
1776 base[p3 - base_fontname] = '*';
1777 base[(p3 - base_fontname) + 1] = '-';
1778 strcpy (base + (p3 - base_fontname) + 2, p2);
1779 p = base + (p - base_fontname) - diff;
1780 p1 = base + (p1 - base_fontname);
1781 p2 = base + (p2 - base_fontname) - diff;
1782 base_fontname = base;
1783 }
1784
1785 /* Build the font spec that matches all charsets. */
1786 len = p - base_fontname + strlen (allcs) + 1;
1787 font_allcs = alloca (len);
1788 memcpy (font_allcs, base_fontname, p - base_fontname);
1789 strcpy (font_allcs + (p - base_fontname), allcs);
1790
1791 /* Build the font spec that matches all families and
1792 add-styles. */
1793 len = p - p1 + strlen (allcs) + strlen (allfamilies) + 1;
1794 font_allfamilies = alloca (len);
1795 strcpy (font_allfamilies, allfamilies);
1796 memcpy (font_allfamilies + strlen (allfamilies), p1, p - p1);
1797 strcpy (font_allfamilies + strlen (allfamilies) + (p - p1), allcs);
1798
1799 /* Build the font spec that matches all. */
1800 len = p - p2 + strlen (allcs) + strlen (all) + strlen (allfamilies) + 1;
1801 font_all = alloca (len);
1802 strcpy (font_all, allfamilies);
1803 strcat (font_all, all);
1804 memcpy (font_all + strlen (all) + strlen (allfamilies), p2, p - p2);
1805 strcpy (font_all + strlen (all) + strlen (allfamilies) + (p - p2),
1806 allcs);
1807
1808 /* Build the actual font set name. */
1809 len = strlen (base_fontname) + strlen (font_allcs)
1810 + strlen (font_allfamilies) + strlen (font_all) + 5;
1811 fontsetname = xmalloc (len);
1812 strcpy (fontsetname, base_fontname);
1813 strcat (fontsetname, sep);
1814 strcat (fontsetname, font_allcs);
1815 strcat (fontsetname, sep);
1816 strcat (fontsetname, font_allfamilies);
1817 strcat (fontsetname, sep);
1818 strcat (fontsetname, font_all);
1819 }
1820 }
1821 if (motif)
1822 return strcat (fontsetname, ":");
1823 return fontsetname;
1824 }
1825 #endif /* HAVE_X_WINDOWS && USE_X_TOOLKIT */
1826
1827 #ifdef DEBUG_XIC_FONTSET
1828 static void
1829 print_fontset_result (XFontSet xfs, char *name, char **missing_list,
1830 int missing_count)
1831 {
1832 if (xfs)
1833 fprintf (stderr, "XIC Fontset created: %s\n", name);
1834 else
1835 {
1836 fprintf (stderr, "XIC Fontset failed: %s\n", name);
1837 while (missing_count-- > 0)
1838 {
1839 fprintf (stderr, " missing: %s\n", *missing_list);
1840 missing_list++;
1841 }
1842 }
1843
1844 }
1845 #endif
1846
1847 static XFontSet
1848 xic_create_xfontset (struct frame *f)
1849 {
1850 XFontSet xfs = NULL;
1851 struct font *font = FRAME_FONT (f);
1852 int pixel_size = font->pixel_size;
1853 Lisp_Object rest, frame;
1854
1855 /* See if there is another frame already using same fontset. */
1856 FOR_EACH_FRAME (rest, frame)
1857 {
1858 struct frame *cf = XFRAME (frame);
1859
1860 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
1861 && FRAME_DISPLAY_INFO (cf) == FRAME_DISPLAY_INFO (f)
1862 && FRAME_FONT (f)
1863 && FRAME_FONT (f)->pixel_size == pixel_size)
1864 {
1865 xfs = FRAME_XIC_FONTSET (cf);
1866 break;
1867 }
1868 }
1869
1870 if (! xfs)
1871 {
1872 char buf[256];
1873 char **missing_list;
1874 int missing_count;
1875 char *def_string;
1876 const char *xlfd_format = "-*-*-medium-r-normal--%d-*-*-*-*-*";
1877
1878 sprintf (buf, xlfd_format, pixel_size);
1879 missing_list = NULL;
1880 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
1881 &missing_list, &missing_count, &def_string);
1882 #ifdef DEBUG_XIC_FONTSET
1883 print_fontset_result (xfs, buf, missing_list, missing_count);
1884 #endif
1885 if (missing_list)
1886 XFreeStringList (missing_list);
1887 if (! xfs)
1888 {
1889 /* List of pixel sizes most likely available. Find one that
1890 is closest to pixel_size. */
1891 int sizes[] = {0, 8, 10, 11, 12, 14, 17, 18, 20, 24, 26, 34, 0};
1892 int *smaller, *larger;
1893
1894 for (smaller = sizes; smaller[1]; smaller++)
1895 if (smaller[1] >= pixel_size)
1896 break;
1897 larger = smaller + 1;
1898 if (*larger == pixel_size)
1899 larger++;
1900 while (*smaller || *larger)
1901 {
1902 int this_size;
1903
1904 if (! *larger)
1905 this_size = *smaller--;
1906 else if (! *smaller)
1907 this_size = *larger++;
1908 else if (pixel_size - *smaller < *larger - pixel_size)
1909 this_size = *smaller--;
1910 else
1911 this_size = *larger++;
1912 sprintf (buf, xlfd_format, this_size);
1913 missing_list = NULL;
1914 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
1915 &missing_list, &missing_count, &def_string);
1916 #ifdef DEBUG_XIC_FONTSET
1917 print_fontset_result (xfs, buf, missing_list, missing_count);
1918 #endif
1919 if (missing_list)
1920 XFreeStringList (missing_list);
1921 if (xfs)
1922 break;
1923 }
1924 }
1925 if (! xfs)
1926 {
1927 const char *last_resort = "-*-*-*-r-normal--*-*-*-*-*-*";
1928
1929 missing_list = NULL;
1930 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), last_resort,
1931 &missing_list, &missing_count, &def_string);
1932 #ifdef DEBUG_XIC_FONTSET
1933 print_fontset_result (xfs, last_resort, missing_list, missing_count);
1934 #endif
1935 if (missing_list)
1936 XFreeStringList (missing_list);
1937 }
1938
1939 }
1940
1941 return xfs;
1942 }
1943
1944 /* Free the X fontset of frame F if it is the last frame using it. */
1945
1946 void
1947 xic_free_xfontset (struct frame *f)
1948 {
1949 Lisp_Object rest, frame;
1950 bool shared_p = 0;
1951
1952 if (!FRAME_XIC_FONTSET (f))
1953 return;
1954
1955 /* See if there is another frame sharing the same fontset. */
1956 FOR_EACH_FRAME (rest, frame)
1957 {
1958 struct frame *cf = XFRAME (frame);
1959 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
1960 && FRAME_DISPLAY_INFO (cf) == FRAME_DISPLAY_INFO (f)
1961 && FRAME_XIC_FONTSET (cf) == FRAME_XIC_FONTSET (f))
1962 {
1963 shared_p = 1;
1964 break;
1965 }
1966 }
1967
1968 if (!shared_p)
1969 /* The fontset is not used anymore. It is safe to free it. */
1970 XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f));
1971
1972 FRAME_XIC_FONTSET (f) = NULL;
1973 }
1974
1975
1976 /* Value is the best input style, given user preferences USER (already
1977 checked to be supported by Emacs), and styles supported by the
1978 input method XIM. */
1979
1980 static XIMStyle
1981 best_xim_style (XIMStyles *xim)
1982 {
1983 int i, j;
1984 int nr_supported = ARRAYELTS (supported_xim_styles);
1985
1986 for (i = 0; i < nr_supported; ++i)
1987 for (j = 0; j < xim->count_styles; ++j)
1988 if (supported_xim_styles[i] == xim->supported_styles[j])
1989 return supported_xim_styles[i];
1990
1991 /* Return the default style. */
1992 return XIMPreeditNothing | XIMStatusNothing;
1993 }
1994
1995 /* Create XIC for frame F. */
1996
1997 void
1998 create_frame_xic (struct frame *f)
1999 {
2000 XIM xim;
2001 XIC xic = NULL;
2002 XFontSet xfs = NULL;
2003 XVaNestedList status_attr = NULL;
2004 XVaNestedList preedit_attr = NULL;
2005 XRectangle s_area;
2006 XPoint spot;
2007 XIMStyle xic_style;
2008
2009 if (FRAME_XIC (f))
2010 goto out;
2011
2012 xim = FRAME_X_XIM (f);
2013 if (!xim)
2014 goto out;
2015
2016 /* Determine XIC style. */
2017 xic_style = best_xim_style (FRAME_X_XIM_STYLES (f));
2018
2019 /* Create X fontset. */
2020 if (xic_style & (XIMPreeditPosition | XIMStatusArea))
2021 {
2022 xfs = xic_create_xfontset (f);
2023 if (!xfs)
2024 goto out;
2025
2026 FRAME_XIC_FONTSET (f) = xfs;
2027 }
2028
2029 if (xic_style & XIMPreeditPosition)
2030 {
2031 spot.x = 0; spot.y = 1;
2032 preedit_attr = XVaCreateNestedList (0,
2033 XNFontSet, xfs,
2034 XNForeground,
2035 FRAME_FOREGROUND_PIXEL (f),
2036 XNBackground,
2037 FRAME_BACKGROUND_PIXEL (f),
2038 (xic_style & XIMPreeditPosition
2039 ? XNSpotLocation
2040 : NULL),
2041 &spot,
2042 NULL);
2043
2044 if (!preedit_attr)
2045 goto out;
2046 }
2047
2048 if (xic_style & XIMStatusArea)
2049 {
2050 s_area.x = 0; s_area.y = 0; s_area.width = 1; s_area.height = 1;
2051 status_attr = XVaCreateNestedList (0,
2052 XNArea,
2053 &s_area,
2054 XNFontSet,
2055 xfs,
2056 XNForeground,
2057 FRAME_FOREGROUND_PIXEL (f),
2058 XNBackground,
2059 FRAME_BACKGROUND_PIXEL (f),
2060 NULL);
2061
2062 if (!status_attr)
2063 goto out;
2064 }
2065
2066 if (preedit_attr && status_attr)
2067 xic = XCreateIC (xim,
2068 XNInputStyle, xic_style,
2069 XNClientWindow, FRAME_X_WINDOW (f),
2070 XNFocusWindow, FRAME_X_WINDOW (f),
2071 XNStatusAttributes, status_attr,
2072 XNPreeditAttributes, preedit_attr,
2073 NULL);
2074 else if (preedit_attr)
2075 xic = XCreateIC (xim,
2076 XNInputStyle, xic_style,
2077 XNClientWindow, FRAME_X_WINDOW (f),
2078 XNFocusWindow, FRAME_X_WINDOW (f),
2079 XNPreeditAttributes, preedit_attr,
2080 NULL);
2081 else if (status_attr)
2082 xic = XCreateIC (xim,
2083 XNInputStyle, xic_style,
2084 XNClientWindow, FRAME_X_WINDOW (f),
2085 XNFocusWindow, FRAME_X_WINDOW (f),
2086 XNStatusAttributes, status_attr,
2087 NULL);
2088 else
2089 xic = XCreateIC (xim,
2090 XNInputStyle, xic_style,
2091 XNClientWindow, FRAME_X_WINDOW (f),
2092 XNFocusWindow, FRAME_X_WINDOW (f),
2093 NULL);
2094
2095 if (!xic)
2096 goto out;
2097
2098 FRAME_XIC (f) = xic;
2099 FRAME_XIC_STYLE (f) = xic_style;
2100 xfs = NULL; /* Don't free below. */
2101
2102 out:
2103
2104 if (xfs)
2105 free_frame_xic (f);
2106
2107 if (preedit_attr)
2108 XFree (preedit_attr);
2109
2110 if (status_attr)
2111 XFree (status_attr);
2112 }
2113
2114
2115 /* Destroy XIC and free XIC fontset of frame F, if any. */
2116
2117 void
2118 free_frame_xic (struct frame *f)
2119 {
2120 if (FRAME_XIC (f) == NULL)
2121 return;
2122
2123 XDestroyIC (FRAME_XIC (f));
2124 xic_free_xfontset (f);
2125
2126 FRAME_XIC (f) = NULL;
2127 }
2128
2129
2130 /* Place preedit area for XIC of window W's frame to specified
2131 pixel position X/Y. X and Y are relative to window W. */
2132
2133 void
2134 xic_set_preeditarea (struct window *w, int x, int y)
2135 {
2136 struct frame *f = XFRAME (w->frame);
2137 XVaNestedList attr;
2138 XPoint spot;
2139
2140 spot.x = WINDOW_TO_FRAME_PIXEL_X (w, x) + WINDOW_LEFT_FRINGE_WIDTH (w);
2141 spot.y = WINDOW_TO_FRAME_PIXEL_Y (w, y) + FONT_BASE (FRAME_FONT (f));
2142 attr = XVaCreateNestedList (0, XNSpotLocation, &spot, NULL);
2143 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2144 XFree (attr);
2145 }
2146
2147
2148 /* Place status area for XIC in bottom right corner of frame F.. */
2149
2150 void
2151 xic_set_statusarea (struct frame *f)
2152 {
2153 XIC xic = FRAME_XIC (f);
2154 XVaNestedList attr;
2155 XRectangle area;
2156 XRectangle *needed;
2157
2158 /* Negotiate geometry of status area. If input method has existing
2159 status area, use its current size. */
2160 area.x = area.y = area.width = area.height = 0;
2161 attr = XVaCreateNestedList (0, XNAreaNeeded, &area, NULL);
2162 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2163 XFree (attr);
2164
2165 attr = XVaCreateNestedList (0, XNAreaNeeded, &needed, NULL);
2166 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2167 XFree (attr);
2168
2169 if (needed->width == 0) /* Use XNArea instead of XNAreaNeeded */
2170 {
2171 attr = XVaCreateNestedList (0, XNArea, &needed, NULL);
2172 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2173 XFree (attr);
2174 }
2175
2176 area.width = needed->width;
2177 area.height = needed->height;
2178 area.x = FRAME_PIXEL_WIDTH (f) - area.width - FRAME_INTERNAL_BORDER_WIDTH (f);
2179 area.y = (FRAME_PIXEL_HEIGHT (f) - area.height
2180 - FRAME_MENUBAR_HEIGHT (f)
2181 - FRAME_TOOLBAR_TOP_HEIGHT (f)
2182 - FRAME_INTERNAL_BORDER_WIDTH (f));
2183 XFree (needed);
2184
2185 attr = XVaCreateNestedList (0, XNArea, &area, NULL);
2186 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2187 XFree (attr);
2188 }
2189
2190
2191 /* Set X fontset for XIC of frame F, using base font name
2192 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2193
2194 void
2195 xic_set_xfontset (struct frame *f, const char *base_fontname)
2196 {
2197 XVaNestedList attr;
2198 XFontSet xfs;
2199
2200 xic_free_xfontset (f);
2201
2202 xfs = xic_create_xfontset (f);
2203
2204 attr = XVaCreateNestedList (0, XNFontSet, xfs, NULL);
2205 if (FRAME_XIC_STYLE (f) & XIMPreeditPosition)
2206 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2207 if (FRAME_XIC_STYLE (f) & XIMStatusArea)
2208 XSetICValues (FRAME_XIC (f), XNStatusAttributes, attr, NULL);
2209 XFree (attr);
2210
2211 FRAME_XIC_FONTSET (f) = xfs;
2212 }
2213
2214 #endif /* HAVE_X_I18N */
2215
2216
2217 \f
2218 #ifdef USE_X_TOOLKIT
2219
2220 /* Create and set up the X widget for frame F. */
2221
2222 static void
2223 x_window (struct frame *f, long window_prompting, int minibuffer_only)
2224 {
2225 XClassHint class_hints;
2226 XSetWindowAttributes attributes;
2227 unsigned long attribute_mask;
2228 Widget shell_widget;
2229 Widget pane_widget;
2230 Widget frame_widget;
2231 Arg al [25];
2232 int ac;
2233
2234 block_input ();
2235
2236 /* Use the resource name as the top-level widget name
2237 for looking up resources. Make a non-Lisp copy
2238 for the window manager, so GC relocation won't bother it.
2239
2240 Elsewhere we specify the window name for the window manager. */
2241 f->namebuf = xstrdup (SSDATA (Vx_resource_name));
2242
2243 ac = 0;
2244 XtSetArg (al[ac], XtNallowShellResize, 1); ac++;
2245 XtSetArg (al[ac], XtNinput, 1); ac++;
2246 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2247 XtSetArg (al[ac], XtNborderWidth, f->border_width); ac++;
2248 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2249 XtSetArg (al[ac], XtNdepth, FRAME_DISPLAY_INFO (f)->n_planes); ac++;
2250 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2251 shell_widget = XtAppCreateShell (f->namebuf, EMACS_CLASS,
2252 applicationShellWidgetClass,
2253 FRAME_X_DISPLAY (f), al, ac);
2254
2255 f->output_data.x->widget = shell_widget;
2256 /* maybe_set_screen_title_format (shell_widget); */
2257
2258 pane_widget = lw_create_widget ("main", "pane", widget_id_tick++,
2259 NULL, shell_widget, False,
2260 NULL, NULL, NULL, NULL);
2261
2262 ac = 0;
2263 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2264 XtSetArg (al[ac], XtNdepth, FRAME_DISPLAY_INFO (f)->n_planes); ac++;
2265 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2266 XtSetArg (al[ac], XtNborderWidth, 0); ac++;
2267 XtSetValues (pane_widget, al, ac);
2268 f->output_data.x->column_widget = pane_widget;
2269
2270 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2271 the emacs screen when changing menubar. This reduces flickering. */
2272
2273 ac = 0;
2274 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2275 XtSetArg (al[ac], XtNshowGrip, 0); ac++;
2276 XtSetArg (al[ac], XtNallowResize, 1); ac++;
2277 XtSetArg (al[ac], XtNresizeToPreferred, 1); ac++;
2278 XtSetArg (al[ac], XtNemacsFrame, f); ac++;
2279 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2280 XtSetArg (al[ac], XtNdepth, FRAME_DISPLAY_INFO (f)->n_planes); ac++;
2281 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2282 XtSetArg (al[ac], XtNborderWidth, 0); ac++;
2283 frame_widget = XtCreateWidget (f->namebuf, emacsFrameClass, pane_widget,
2284 al, ac);
2285
2286 f->output_data.x->edit_widget = frame_widget;
2287
2288 XtManageChild (frame_widget);
2289
2290 /* Do some needed geometry management. */
2291 {
2292 Arg gal[3];
2293 int gac = 0;
2294 int extra_borders = 0;
2295 int menubar_size
2296 = (f->output_data.x->menubar_widget
2297 ? (f->output_data.x->menubar_widget->core.height
2298 + f->output_data.x->menubar_widget->core.border_width)
2299 : 0);
2300
2301 #if 0 /* Experimentally, we now get the right results
2302 for -geometry -0-0 without this. 24 Aug 96, rms. */
2303 if (FRAME_EXTERNAL_MENU_BAR (f))
2304 {
2305 Dimension ibw = 0;
2306 XtVaGetValues (pane_widget, XtNinternalBorderWidth, &ibw, NULL);
2307 menubar_size += ibw;
2308 }
2309 #endif
2310
2311 FRAME_MENUBAR_HEIGHT (f) = menubar_size;
2312
2313 #ifndef USE_LUCID
2314 /* Motif seems to need this amount added to the sizes
2315 specified for the shell widget. The Athena/Lucid widgets don't.
2316 Both conclusions reached experimentally. -- rms. */
2317 XtVaGetValues (f->output_data.x->edit_widget, XtNinternalBorderWidth,
2318 &extra_borders, NULL);
2319 extra_borders *= 2;
2320 #endif
2321
2322 f->shell_position = xmalloc (sizeof "=x++" + 4 * INT_STRLEN_BOUND (int));
2323
2324 /* Convert our geometry parameters into a geometry string
2325 and specify it.
2326 Note that we do not specify here whether the position
2327 is a user-specified or program-specified one.
2328 We pass that information later, in x_wm_set_size_hints. */
2329 {
2330 int left = f->left_pos;
2331 int xneg = window_prompting & XNegative;
2332 int top = f->top_pos;
2333 int yneg = window_prompting & YNegative;
2334 if (xneg)
2335 left = -left;
2336 if (yneg)
2337 top = -top;
2338
2339 if (window_prompting & USPosition)
2340 sprintf (f->shell_position, "=%dx%d%c%d%c%d",
2341 FRAME_PIXEL_WIDTH (f) + extra_borders,
2342 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders,
2343 (xneg ? '-' : '+'), left,
2344 (yneg ? '-' : '+'), top);
2345 else
2346 {
2347 sprintf (f->shell_position, "=%dx%d",
2348 FRAME_PIXEL_WIDTH (f) + extra_borders,
2349 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders);
2350
2351 /* Setting x and y when the position is not specified in
2352 the geometry string will set program position in the WM hints.
2353 If Emacs had just one program position, we could set it in
2354 fallback resources, but since each make-frame call can specify
2355 different program positions, this is easier. */
2356 XtSetArg (gal[gac], XtNx, left); gac++;
2357 XtSetArg (gal[gac], XtNy, top); gac++;
2358 }
2359 }
2360
2361 XtSetArg (gal[gac], XtNgeometry, f->shell_position); gac++;
2362 XtSetValues (shell_widget, gal, gac);
2363 }
2364
2365 XtManageChild (pane_widget);
2366 XtRealizeWidget (shell_widget);
2367
2368 if (FRAME_X_EMBEDDED_P (f))
2369 XReparentWindow (FRAME_X_DISPLAY (f), XtWindow (shell_widget),
2370 f->output_data.x->parent_desc, 0, 0);
2371
2372 FRAME_X_WINDOW (f) = XtWindow (frame_widget);
2373
2374 validate_x_resource_name ();
2375
2376 class_hints.res_name = SSDATA (Vx_resource_name);
2377 class_hints.res_class = SSDATA (Vx_resource_class);
2378 XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints);
2379
2380 #ifdef HAVE_X_I18N
2381 FRAME_XIC (f) = NULL;
2382 if (use_xim)
2383 create_frame_xic (f);
2384 #endif
2385
2386 f->output_data.x->wm_hints.input = True;
2387 f->output_data.x->wm_hints.flags |= InputHint;
2388 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2389 &f->output_data.x->wm_hints);
2390
2391 hack_wm_protocols (f, shell_widget);
2392
2393 #ifdef HACK_EDITRES
2394 XtAddEventHandler (shell_widget, 0, True, _XEditResCheckMessages, 0);
2395 #endif
2396
2397 /* Do a stupid property change to force the server to generate a
2398 PropertyNotify event so that the event_stream server timestamp will
2399 be initialized to something relevant to the time we created the window.
2400 */
2401 XChangeProperty (XtDisplay (frame_widget), XtWindow (frame_widget),
2402 FRAME_DISPLAY_INFO (f)->Xatom_wm_protocols,
2403 XA_ATOM, 32, PropModeAppend, NULL, 0);
2404
2405 /* Make all the standard events reach the Emacs frame. */
2406 attributes.event_mask = STANDARD_EVENT_SET;
2407
2408 #ifdef HAVE_X_I18N
2409 if (FRAME_XIC (f))
2410 {
2411 /* XIM server might require some X events. */
2412 unsigned long fevent = NoEventMask;
2413 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2414 attributes.event_mask |= fevent;
2415 }
2416 #endif /* HAVE_X_I18N */
2417
2418 attribute_mask = CWEventMask;
2419 XChangeWindowAttributes (XtDisplay (shell_widget), XtWindow (shell_widget),
2420 attribute_mask, &attributes);
2421
2422 XtMapWidget (frame_widget);
2423
2424 /* x_set_name normally ignores requests to set the name if the
2425 requested name is the same as the current name. This is the one
2426 place where that assumption isn't correct; f->name is set, but
2427 the X server hasn't been told. */
2428 {
2429 Lisp_Object name;
2430 bool explicit = f->explicit_name;
2431
2432 f->explicit_name = 0;
2433 name = f->name;
2434 fset_name (f, Qnil);
2435 x_set_name (f, name, explicit);
2436 }
2437
2438 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2439 f->output_data.x->current_cursor
2440 = f->output_data.x->text_cursor);
2441
2442 unblock_input ();
2443
2444 /* This is a no-op, except under Motif. Make sure main areas are
2445 set to something reasonable, in case we get an error later. */
2446 lw_set_main_areas (pane_widget, 0, frame_widget);
2447 }
2448
2449 #else /* not USE_X_TOOLKIT */
2450 #ifdef USE_GTK
2451 static void
2452 x_window (struct frame *f)
2453 {
2454 if (! xg_create_frame_widgets (f))
2455 error ("Unable to create window");
2456
2457 #ifdef HAVE_X_I18N
2458 FRAME_XIC (f) = NULL;
2459 if (use_xim)
2460 {
2461 block_input ();
2462 create_frame_xic (f);
2463 if (FRAME_XIC (f))
2464 {
2465 /* XIM server might require some X events. */
2466 unsigned long fevent = NoEventMask;
2467 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2468
2469 if (fevent != NoEventMask)
2470 {
2471 XSetWindowAttributes attributes;
2472 XWindowAttributes wattr;
2473 unsigned long attribute_mask;
2474
2475 XGetWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2476 &wattr);
2477 attributes.event_mask = wattr.your_event_mask | fevent;
2478 attribute_mask = CWEventMask;
2479 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2480 attribute_mask, &attributes);
2481 }
2482 }
2483 unblock_input ();
2484 }
2485 #endif
2486 }
2487
2488 #else /*! USE_GTK */
2489 /* Create and set up the X window for frame F. */
2490
2491 static void
2492 x_window (struct frame *f)
2493 {
2494 XClassHint class_hints;
2495 XSetWindowAttributes attributes;
2496 unsigned long attribute_mask;
2497
2498 attributes.background_pixel = FRAME_BACKGROUND_PIXEL (f);
2499 attributes.border_pixel = f->output_data.x->border_pixel;
2500 attributes.bit_gravity = StaticGravity;
2501 attributes.backing_store = NotUseful;
2502 attributes.save_under = True;
2503 attributes.event_mask = STANDARD_EVENT_SET;
2504 attributes.colormap = FRAME_X_COLORMAP (f);
2505 attribute_mask = (CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask
2506 | CWColormap);
2507
2508 block_input ();
2509 FRAME_X_WINDOW (f)
2510 = XCreateWindow (FRAME_X_DISPLAY (f),
2511 f->output_data.x->parent_desc,
2512 f->left_pos,
2513 f->top_pos,
2514 FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
2515 f->border_width,
2516 CopyFromParent, /* depth */
2517 InputOutput, /* class */
2518 FRAME_X_VISUAL (f),
2519 attribute_mask, &attributes);
2520
2521 #ifdef HAVE_X_I18N
2522 if (use_xim)
2523 {
2524 create_frame_xic (f);
2525 if (FRAME_XIC (f))
2526 {
2527 /* XIM server might require some X events. */
2528 unsigned long fevent = NoEventMask;
2529 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2530 attributes.event_mask |= fevent;
2531 attribute_mask = CWEventMask;
2532 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2533 attribute_mask, &attributes);
2534 }
2535 }
2536 #endif /* HAVE_X_I18N */
2537
2538 validate_x_resource_name ();
2539
2540 class_hints.res_name = SSDATA (Vx_resource_name);
2541 class_hints.res_class = SSDATA (Vx_resource_class);
2542 XSetClassHint (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &class_hints);
2543
2544 /* This indicates that we use the "Passive Input" input model.
2545 Unless we do this, we don't get the Focus{In,Out} events that we
2546 need to draw the cursor correctly. Accursed bureaucrats.
2547 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2548
2549 f->output_data.x->wm_hints.input = True;
2550 f->output_data.x->wm_hints.flags |= InputHint;
2551 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2552 &f->output_data.x->wm_hints);
2553 f->output_data.x->wm_hints.icon_pixmap = None;
2554
2555 /* Request "save yourself" and "delete window" commands from wm. */
2556 {
2557 Atom protocols[2];
2558 protocols[0] = FRAME_DISPLAY_INFO (f)->Xatom_wm_delete_window;
2559 protocols[1] = FRAME_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
2560 XSetWMProtocols (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), protocols, 2);
2561 }
2562
2563 /* x_set_name normally ignores requests to set the name if the
2564 requested name is the same as the current name. This is the one
2565 place where that assumption isn't correct; f->name is set, but
2566 the X server hasn't been told. */
2567 {
2568 Lisp_Object name;
2569 bool explicit = f->explicit_name;
2570
2571 f->explicit_name = 0;
2572 name = f->name;
2573 fset_name (f, Qnil);
2574 x_set_name (f, name, explicit);
2575 }
2576
2577 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2578 f->output_data.x->current_cursor
2579 = f->output_data.x->text_cursor);
2580
2581 unblock_input ();
2582
2583 if (FRAME_X_WINDOW (f) == 0)
2584 error ("Unable to create window");
2585 }
2586
2587 #endif /* not USE_GTK */
2588 #endif /* not USE_X_TOOLKIT */
2589
2590 /* Verify that the icon position args for this window are valid. */
2591
2592 static void
2593 x_icon_verify (struct frame *f, Lisp_Object parms)
2594 {
2595 Lisp_Object icon_x, icon_y;
2596
2597 /* Set the position of the icon. Note that twm groups all
2598 icons in an icon window. */
2599 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2600 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2601 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2602 {
2603 CHECK_NUMBER (icon_x);
2604 CHECK_NUMBER (icon_y);
2605 }
2606 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2607 error ("Both left and top icon corners of icon must be specified");
2608 }
2609
2610 /* Handle the icon stuff for this window. Perhaps later we might
2611 want an x_set_icon_position which can be called interactively as
2612 well. */
2613
2614 static void
2615 x_icon (struct frame *f, Lisp_Object parms)
2616 {
2617 Lisp_Object icon_x, icon_y;
2618 #if 0
2619 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2620 #endif
2621
2622 /* Set the position of the icon. Note that twm groups all
2623 icons in an icon window. */
2624 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2625 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2626 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2627 {
2628 CHECK_TYPE_RANGED_INTEGER (int, icon_x);
2629 CHECK_TYPE_RANGED_INTEGER (int, icon_y);
2630 }
2631 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2632 error ("Both left and top icon corners of icon must be specified");
2633
2634 block_input ();
2635
2636 if (! EQ (icon_x, Qunbound))
2637 x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
2638
2639 #if 0 /* x_get_arg removes the visibility parameter as a side effect,
2640 but x_create_frame still needs it. */
2641 /* Start up iconic or window? */
2642 x_wm_set_window_state
2643 (f, (EQ (x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL),
2644 Qicon)
2645 ? IconicState
2646 : NormalState));
2647 #endif
2648
2649 x_text_icon (f, SSDATA ((!NILP (f->icon_name)
2650 ? f->icon_name
2651 : f->name)));
2652
2653 unblock_input ();
2654 }
2655
2656 /* Make the GCs needed for this window, setting the
2657 background, border and mouse colors; also create the
2658 mouse cursor and the gray border tile. */
2659
2660 static void
2661 x_make_gc (struct frame *f)
2662 {
2663 XGCValues gc_values;
2664
2665 block_input ();
2666
2667 /* Create the GCs of this frame.
2668 Note that many default values are used. */
2669
2670 gc_values.foreground = FRAME_FOREGROUND_PIXEL (f);
2671 gc_values.background = FRAME_BACKGROUND_PIXEL (f);
2672 gc_values.line_width = 0; /* Means 1 using fast algorithm. */
2673 f->output_data.x->normal_gc
2674 = XCreateGC (FRAME_X_DISPLAY (f),
2675 FRAME_X_WINDOW (f),
2676 GCLineWidth | GCForeground | GCBackground,
2677 &gc_values);
2678
2679 /* Reverse video style. */
2680 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2681 gc_values.background = FRAME_FOREGROUND_PIXEL (f);
2682 f->output_data.x->reverse_gc
2683 = XCreateGC (FRAME_X_DISPLAY (f),
2684 FRAME_X_WINDOW (f),
2685 GCForeground | GCBackground | GCLineWidth,
2686 &gc_values);
2687
2688 /* Cursor has cursor-color background, background-color foreground. */
2689 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2690 gc_values.background = f->output_data.x->cursor_pixel;
2691 gc_values.fill_style = FillOpaqueStippled;
2692 f->output_data.x->cursor_gc
2693 = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2694 (GCForeground | GCBackground
2695 | GCFillStyle | GCLineWidth),
2696 &gc_values);
2697
2698 /* Create the gray border tile used when the pointer is not in
2699 the frame. Since this depends on the frame's pixel values,
2700 this must be done on a per-frame basis. */
2701 f->output_data.x->border_tile
2702 = (XCreatePixmapFromBitmapData
2703 (FRAME_X_DISPLAY (f), FRAME_DISPLAY_INFO (f)->root_window,
2704 gray_bits, gray_width, gray_height,
2705 FRAME_FOREGROUND_PIXEL (f),
2706 FRAME_BACKGROUND_PIXEL (f),
2707 DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
2708
2709 unblock_input ();
2710 }
2711
2712
2713 /* Free what was allocated in x_make_gc. */
2714
2715 void
2716 x_free_gcs (struct frame *f)
2717 {
2718 Display *dpy = FRAME_X_DISPLAY (f);
2719
2720 block_input ();
2721
2722 if (f->output_data.x->normal_gc)
2723 {
2724 XFreeGC (dpy, f->output_data.x->normal_gc);
2725 f->output_data.x->normal_gc = 0;
2726 }
2727
2728 if (f->output_data.x->reverse_gc)
2729 {
2730 XFreeGC (dpy, f->output_data.x->reverse_gc);
2731 f->output_data.x->reverse_gc = 0;
2732 }
2733
2734 if (f->output_data.x->cursor_gc)
2735 {
2736 XFreeGC (dpy, f->output_data.x->cursor_gc);
2737 f->output_data.x->cursor_gc = 0;
2738 }
2739
2740 if (f->output_data.x->border_tile)
2741 {
2742 XFreePixmap (dpy, f->output_data.x->border_tile);
2743 f->output_data.x->border_tile = 0;
2744 }
2745
2746 unblock_input ();
2747 }
2748
2749
2750 /* Handler for signals raised during x_create_frame and
2751 x_create_tip_frame. FRAME is the frame which is partially
2752 constructed. */
2753
2754 static Lisp_Object
2755 unwind_create_frame (Lisp_Object frame)
2756 {
2757 struct frame *f = XFRAME (frame);
2758
2759 /* If frame is already dead, nothing to do. This can happen if the
2760 display is disconnected after the frame has become official, but
2761 before x_create_frame removes the unwind protect. */
2762 if (!FRAME_LIVE_P (f))
2763 return Qnil;
2764
2765 /* If frame is ``official'', nothing to do. */
2766 if (NILP (Fmemq (frame, Vframe_list)))
2767 {
2768 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2769 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2770 #endif
2771
2772 x_free_frame_resources (f);
2773 free_glyphs (f);
2774
2775 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2776 /* Check that reference counts are indeed correct. */
2777 eassert (dpyinfo->reference_count == dpyinfo_refcount);
2778 eassert (dpyinfo->terminal->image_cache->refcount == image_cache_refcount);
2779 #endif
2780 return Qt;
2781 }
2782
2783 return Qnil;
2784 }
2785
2786 static void
2787 do_unwind_create_frame (Lisp_Object frame)
2788 {
2789 unwind_create_frame (frame);
2790 }
2791
2792 static void
2793 x_default_font_parameter (struct frame *f, Lisp_Object parms)
2794 {
2795 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2796 Lisp_Object font_param = x_get_arg (dpyinfo, parms, Qfont, NULL, NULL,
2797 RES_TYPE_STRING);
2798 Lisp_Object font = Qnil;
2799 if (EQ (font_param, Qunbound))
2800 font_param = Qnil;
2801
2802 if (NILP (font_param))
2803 {
2804 /* System font should take precedence over X resources. We suggest this
2805 regardless of font-use-system-font because .emacs may not have been
2806 read yet. */
2807 const char *system_font = xsettings_get_system_font ();
2808 if (system_font)
2809 font = font_open_by_name (f, build_unibyte_string (system_font));
2810 }
2811
2812 if (NILP (font))
2813 font = !NILP (font_param) ? font_param
2814 : x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
2815
2816 if (! FONTP (font) && ! STRINGP (font))
2817 {
2818 const char *names[]
2819 = {
2820 #ifdef HAVE_XFT
2821 /* This will find the normal Xft font. */
2822 "monospace-10",
2823 #endif
2824 "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
2825 "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
2826 "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
2827 /* This was formerly the first thing tried, but it finds
2828 too many fonts and takes too long. */
2829 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
2830 /* If those didn't work, look for something which will
2831 at least work. */
2832 "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
2833 "fixed",
2834 NULL };
2835 int i;
2836
2837 for (i = 0; names[i]; i++)
2838 {
2839 font = font_open_by_name (f, build_unibyte_string (names[i]));
2840 if (! NILP (font))
2841 break;
2842 }
2843 if (NILP (font))
2844 error ("No suitable font was found");
2845 }
2846 else if (!NILP (font_param))
2847 {
2848 /* Remember the explicit font parameter, so we can re-apply it after
2849 we've applied the `default' face settings. */
2850 AUTO_FRAME_ARG (arg, Qfont_param, font_param);
2851 x_set_frame_parameters (f, arg);
2852 }
2853
2854 /* This call will make X resources override any system font setting. */
2855 x_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING);
2856 }
2857
2858
2859 DEFUN ("x-wm-set-size-hint", Fx_wm_set_size_hint, Sx_wm_set_size_hint,
2860 0, 1, 0,
2861 doc: /* Send the size hints for frame FRAME to the window manager.
2862 If FRAME is omitted or nil, use the selected frame.
2863 Signal error if FRAME is not an X frame. */)
2864 (Lisp_Object frame)
2865 {
2866 struct frame *f = decode_window_system_frame (frame);
2867
2868 block_input ();
2869 x_wm_set_size_hint (f, 0, 0);
2870 unblock_input ();
2871 return Qnil;
2872 }
2873
2874 static void
2875 set_machine_and_pid_properties (struct frame *f)
2876 {
2877 /* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME. */
2878 XSetWMProperties (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), NULL, NULL,
2879 NULL, 0, NULL, NULL, NULL);
2880 pid_t pid = getpid ();
2881 if (pid <= 0xffffffffu)
2882 {
2883 unsigned long xpid = pid;
2884 XChangeProperty (FRAME_X_DISPLAY (f),
2885 FRAME_OUTER_WINDOW (f),
2886 XInternAtom (FRAME_X_DISPLAY (f),
2887 "_NET_WM_PID",
2888 False),
2889 XA_CARDINAL, 32, PropModeReplace,
2890 (unsigned char *) &xpid, 1);
2891 }
2892 }
2893
2894 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
2895 1, 1, 0,
2896 doc: /* Make a new X window, which is called a "frame" in Emacs terms.
2897 Return an Emacs frame object. PARMS is an alist of frame parameters.
2898 If the parameters specify that the frame should not have a minibuffer,
2899 and do not specify a specific minibuffer window to use, then
2900 `default-minibuffer-frame' must be a frame whose minibuffer can be
2901 shared by the new frame.
2902
2903 This function is an internal primitive--use `make-frame' instead. */)
2904 (Lisp_Object parms)
2905 {
2906 struct frame *f;
2907 Lisp_Object frame, tem;
2908 Lisp_Object name;
2909 int minibuffer_only = 0;
2910 long window_prompting = 0;
2911 ptrdiff_t count = SPECPDL_INDEX ();
2912 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
2913 Lisp_Object display;
2914 struct x_display_info *dpyinfo = NULL;
2915 Lisp_Object parent;
2916 struct kboard *kb;
2917
2918 parms = Fcopy_alist (parms);
2919
2920 /* Use this general default value to start with
2921 until we know if this frame has a specified name. */
2922 Vx_resource_name = Vinvocation_name;
2923
2924 display = x_get_arg (dpyinfo, parms, Qterminal, 0, 0, RES_TYPE_NUMBER);
2925 if (EQ (display, Qunbound))
2926 display = x_get_arg (dpyinfo, parms, Qdisplay, 0, 0, RES_TYPE_STRING);
2927 if (EQ (display, Qunbound))
2928 display = Qnil;
2929 dpyinfo = check_x_display_info (display);
2930 kb = dpyinfo->terminal->kboard;
2931
2932 if (!dpyinfo->terminal->name)
2933 error ("Terminal is not live, can't create new frames on it");
2934
2935 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
2936 if (!STRINGP (name)
2937 && ! EQ (name, Qunbound)
2938 && ! NILP (name))
2939 error ("Invalid frame name--not a string or nil");
2940
2941 if (STRINGP (name))
2942 Vx_resource_name = name;
2943
2944 /* See if parent window is specified. */
2945 parent = x_get_arg (dpyinfo, parms, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
2946 if (EQ (parent, Qunbound))
2947 parent = Qnil;
2948 if (! NILP (parent))
2949 CHECK_NUMBER (parent);
2950
2951 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
2952 /* No need to protect DISPLAY because that's not used after passing
2953 it to make_frame_without_minibuffer. */
2954 frame = Qnil;
2955 GCPRO4 (parms, parent, name, frame);
2956 tem = x_get_arg (dpyinfo, parms, Qminibuffer, "minibuffer", "Minibuffer",
2957 RES_TYPE_SYMBOL);
2958 if (EQ (tem, Qnone) || NILP (tem))
2959 f = make_frame_without_minibuffer (Qnil, kb, display);
2960 else if (EQ (tem, Qonly))
2961 {
2962 f = make_minibuffer_frame ();
2963 minibuffer_only = 1;
2964 }
2965 else if (WINDOWP (tem))
2966 f = make_frame_without_minibuffer (tem, kb, display);
2967 else
2968 f = make_frame (1);
2969
2970 XSETFRAME (frame, f);
2971
2972 f->terminal = dpyinfo->terminal;
2973
2974 f->output_method = output_x_window;
2975 f->output_data.x = xzalloc (sizeof *f->output_data.x);
2976 f->output_data.x->icon_bitmap = -1;
2977 FRAME_FONTSET (f) = -1;
2978 f->output_data.x->scroll_bar_foreground_pixel = -1;
2979 f->output_data.x->scroll_bar_background_pixel = -1;
2980 #if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
2981 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
2982 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
2983 #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
2984 f->output_data.x->white_relief.pixel = -1;
2985 f->output_data.x->black_relief.pixel = -1;
2986
2987 fset_icon_name (f,
2988 x_get_arg (dpyinfo, parms, Qicon_name, "iconName", "Title",
2989 RES_TYPE_STRING));
2990 if (! STRINGP (f->icon_name))
2991 fset_icon_name (f, Qnil);
2992
2993 FRAME_DISPLAY_INFO (f) = dpyinfo;
2994
2995 /* With FRAME_DISPLAY_INFO set up, this unwind-protect is safe. */
2996 record_unwind_protect (do_unwind_create_frame, frame);
2997
2998 /* These colors will be set anyway later, but it's important
2999 to get the color reference counts right, so initialize them! */
3000 {
3001 Lisp_Object black;
3002 struct gcpro gcpro1;
3003
3004 /* Function x_decode_color can signal an error. Make
3005 sure to initialize color slots so that we won't try
3006 to free colors we haven't allocated. */
3007 FRAME_FOREGROUND_PIXEL (f) = -1;
3008 FRAME_BACKGROUND_PIXEL (f) = -1;
3009 f->output_data.x->cursor_pixel = -1;
3010 f->output_data.x->cursor_foreground_pixel = -1;
3011 f->output_data.x->border_pixel = -1;
3012 f->output_data.x->mouse_pixel = -1;
3013
3014 black = build_string ("black");
3015 GCPRO1 (black);
3016 FRAME_FOREGROUND_PIXEL (f)
3017 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3018 FRAME_BACKGROUND_PIXEL (f)
3019 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3020 f->output_data.x->cursor_pixel
3021 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3022 f->output_data.x->cursor_foreground_pixel
3023 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3024 f->output_data.x->border_pixel
3025 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3026 f->output_data.x->mouse_pixel
3027 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3028 UNGCPRO;
3029 }
3030
3031 /* Specify the parent under which to make this X window. */
3032 if (!NILP (parent))
3033 {
3034 f->output_data.x->parent_desc = (Window) XFASTINT (parent);
3035 f->output_data.x->explicit_parent = 1;
3036 }
3037 else
3038 {
3039 f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
3040 f->output_data.x->explicit_parent = 0;
3041 }
3042
3043 /* Set the name; the functions to which we pass f expect the name to
3044 be set. */
3045 if (EQ (name, Qunbound) || NILP (name))
3046 {
3047 fset_name (f, build_string (dpyinfo->x_id_name));
3048 f->explicit_name = 0;
3049 }
3050 else
3051 {
3052 fset_name (f, name);
3053 f->explicit_name = 1;
3054 /* Use the frame's title when getting resources for this frame. */
3055 specbind (Qx_resource_name, name);
3056 }
3057
3058 #ifdef HAVE_FREETYPE
3059 #ifdef HAVE_XFT
3060 register_font_driver (&xftfont_driver, f);
3061 #else /* not HAVE_XFT */
3062 register_font_driver (&ftxfont_driver, f);
3063 #endif /* not HAVE_XFT */
3064 #endif /* HAVE_FREETYPE */
3065 register_font_driver (&xfont_driver, f);
3066
3067 x_default_parameter (f, parms, Qfont_backend, Qnil,
3068 "fontBackend", "FontBackend", RES_TYPE_STRING);
3069
3070 /* Extract the window parameters from the supplied values
3071 that are needed to determine window geometry. */
3072 x_default_font_parameter (f, parms);
3073 if (!FRAME_FONT (f))
3074 {
3075 delete_frame (frame, Qnoelisp);
3076 error ("Invalid frame font");
3077 }
3078
3079 /* Frame contents get displaced if an embedded X window has a border. */
3080 if (! FRAME_X_EMBEDDED_P (f))
3081 x_default_parameter (f, parms, Qborder_width, make_number (0),
3082 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
3083
3084 /* This defaults to 1 in order to match xterm. We recognize either
3085 internalBorderWidth or internalBorder (which is what xterm calls
3086 it). */
3087 if (NILP (Fassq (Qinternal_border_width, parms)))
3088 {
3089 Lisp_Object value;
3090
3091 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
3092 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
3093 if (! EQ (value, Qunbound))
3094 parms = Fcons (Fcons (Qinternal_border_width, value),
3095 parms);
3096 }
3097 x_default_parameter (f, parms, Qinternal_border_width,
3098 #ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */
3099 make_number (0),
3100 #else
3101 make_number (1),
3102 #endif
3103 "internalBorderWidth", "internalBorderWidth",
3104 RES_TYPE_NUMBER);
3105 x_default_parameter (f, parms, Qright_divider_width, make_number (0),
3106 NULL, NULL, RES_TYPE_NUMBER);
3107 x_default_parameter (f, parms, Qbottom_divider_width, make_number (0),
3108 NULL, NULL, RES_TYPE_NUMBER);
3109 x_default_parameter (f, parms, Qvertical_scroll_bars,
3110 #if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
3111 Qright,
3112 #else
3113 Qleft,
3114 #endif
3115 "verticalScrollBars", "ScrollBars",
3116 RES_TYPE_SYMBOL);
3117 x_default_parameter (f, parms, Qhorizontal_scroll_bars, Qnil,
3118 "horizontalScrollBars", "ScrollBars",
3119 RES_TYPE_SYMBOL);
3120 /* Also do the stuff which must be set before the window exists. */
3121 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
3122 "foreground", "Foreground", RES_TYPE_STRING);
3123 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
3124 "background", "Background", RES_TYPE_STRING);
3125 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
3126 "pointerColor", "Foreground", RES_TYPE_STRING);
3127 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
3128 "borderColor", "BorderColor", RES_TYPE_STRING);
3129 x_default_parameter (f, parms, Qscreen_gamma, Qnil,
3130 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
3131 x_default_parameter (f, parms, Qline_spacing, Qnil,
3132 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
3133 x_default_parameter (f, parms, Qleft_fringe, Qnil,
3134 "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
3135 x_default_parameter (f, parms, Qright_fringe, Qnil,
3136 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
3137
3138 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_foreground,
3139 "scrollBarForeground",
3140 "ScrollBarForeground", 1);
3141 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_background,
3142 "scrollBarBackground",
3143 "ScrollBarBackground", 0);
3144
3145 #ifdef GLYPH_DEBUG
3146 image_cache_refcount =
3147 FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
3148 dpyinfo_refcount = dpyinfo->reference_count;
3149 #endif /* GLYPH_DEBUG */
3150
3151 /* Init faces before x_default_parameter is called for the
3152 scroll-bar-width parameter because otherwise we end up in
3153 init_iterator with a null face cache, which should not happen. */
3154 init_frame_faces (f);
3155
3156 /* The following call of change_frame_size is needed since otherwise
3157 x_set_tool_bar_lines will already work with the character sizes
3158 installed by init_frame_faces while the frame's pixel size is
3159 still calculated from a character size of 1 and we subsequently
3160 hit the (height >= 0) assertion in window_box_height.
3161
3162 The non-pixelwise code apparently worked around this because it
3163 had one frame line vs one toolbar line which left us with a zero
3164 root window height which was obviously wrong as well ... */
3165 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
3166 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1);
3167
3168 /* Set the menu-bar-lines and tool-bar-lines parameters. We don't
3169 look up the X resources controlling the menu-bar and tool-bar
3170 here; they are processed specially at startup, and reflected in
3171 the values of the mode variables. */
3172
3173 x_default_parameter (f, parms, Qmenu_bar_lines,
3174 NILP (Vmenu_bar_mode)
3175 ? make_number (0) : make_number (1),
3176 NULL, NULL, RES_TYPE_NUMBER);
3177 x_default_parameter (f, parms, Qtool_bar_lines,
3178 NILP (Vtool_bar_mode)
3179 ? make_number (0) : make_number (1),
3180 NULL, NULL, RES_TYPE_NUMBER);
3181
3182 x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
3183 "bufferPredicate", "BufferPredicate",
3184 RES_TYPE_SYMBOL);
3185 x_default_parameter (f, parms, Qtitle, Qnil,
3186 "title", "Title", RES_TYPE_STRING);
3187 x_default_parameter (f, parms, Qwait_for_wm, Qt,
3188 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
3189 x_default_parameter (f, parms, Qfullscreen, Qnil,
3190 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
3191 x_default_parameter (f, parms, Qtool_bar_position,
3192 FRAME_TOOL_BAR_POSITION (f), 0, 0, RES_TYPE_SYMBOL);
3193
3194 /* Compute the size of the X window. */
3195 window_prompting = x_figure_window_size (f, parms, 1);
3196
3197 tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
3198 f->no_split = minibuffer_only || EQ (tem, Qt);
3199
3200 x_icon_verify (f, parms);
3201
3202 /* Create the X widget or window. */
3203 #ifdef USE_X_TOOLKIT
3204 x_window (f, window_prompting, minibuffer_only);
3205 #else
3206 x_window (f);
3207 #endif
3208
3209 x_icon (f, parms);
3210 x_make_gc (f);
3211
3212 /* Now consider the frame official. */
3213 f->terminal->reference_count++;
3214 FRAME_DISPLAY_INFO (f)->reference_count++;
3215 Vframe_list = Fcons (frame, Vframe_list);
3216
3217 /* We need to do this after creating the X window, so that the
3218 icon-creation functions can say whose icon they're describing. */
3219 x_default_parameter (f, parms, Qicon_type, Qt,
3220 "bitmapIcon", "BitmapIcon", RES_TYPE_BOOLEAN);
3221
3222 x_default_parameter (f, parms, Qauto_raise, Qnil,
3223 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3224 x_default_parameter (f, parms, Qauto_lower, Qnil,
3225 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3226 x_default_parameter (f, parms, Qcursor_type, Qbox,
3227 "cursorType", "CursorType", RES_TYPE_SYMBOL);
3228 x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
3229 "scrollBarWidth", "ScrollBarWidth",
3230 RES_TYPE_NUMBER);
3231 x_default_parameter (f, parms, Qscroll_bar_height, Qnil,
3232 "scrollBarHeight", "ScrollBarHeight",
3233 RES_TYPE_NUMBER);
3234 x_default_parameter (f, parms, Qalpha, Qnil,
3235 "alpha", "Alpha", RES_TYPE_NUMBER);
3236
3237 /* Consider frame official, now. */
3238 f->official = true;
3239
3240 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, 1);
3241
3242 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3243 /* Create the menu bar. */
3244 if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
3245 {
3246 /* If this signals an error, we haven't set size hints for the
3247 frame and we didn't make it visible. */
3248 initialize_frame_menubar (f);
3249
3250 #ifndef USE_GTK
3251 /* This is a no-op, except under Motif where it arranges the
3252 main window for the widgets on it. */
3253 lw_set_main_areas (f->output_data.x->column_widget,
3254 f->output_data.x->menubar_widget,
3255 f->output_data.x->edit_widget);
3256 #endif /* not USE_GTK */
3257 }
3258 #endif /* USE_X_TOOLKIT || USE_GTK */
3259
3260 /* Tell the server what size and position, etc, we want, and how
3261 badly we want them. This should be done after we have the menu
3262 bar so that its size can be taken into account. */
3263 block_input ();
3264 x_wm_set_size_hint (f, window_prompting, 0);
3265 unblock_input ();
3266
3267 /* Make the window appear on the frame and enable display, unless
3268 the caller says not to. However, with explicit parent, Emacs
3269 cannot control visibility, so don't try. */
3270 if (! f->output_data.x->explicit_parent)
3271 {
3272 Lisp_Object visibility;
3273
3274 visibility = x_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
3275 RES_TYPE_SYMBOL);
3276 if (EQ (visibility, Qunbound))
3277 visibility = Qt;
3278
3279 if (EQ (visibility, Qicon))
3280 x_iconify_frame (f);
3281 else if (! NILP (visibility))
3282 x_make_frame_visible (f);
3283 else
3284 {
3285 /* Must have been Qnil. */
3286 }
3287 }
3288
3289 block_input ();
3290
3291 /* Set machine name and pid for the purpose of window managers. */
3292 set_machine_and_pid_properties (f);
3293
3294 /* Set the WM leader property. GTK does this itself, so this is not
3295 needed when using GTK. */
3296 if (dpyinfo->client_leader_window != 0)
3297 {
3298 XChangeProperty (FRAME_X_DISPLAY (f),
3299 FRAME_OUTER_WINDOW (f),
3300 dpyinfo->Xatom_wm_client_leader,
3301 XA_WINDOW, 32, PropModeReplace,
3302 (unsigned char *) &dpyinfo->client_leader_window, 1);
3303 }
3304
3305 unblock_input ();
3306
3307 /* Initialize `default-minibuffer-frame' in case this is the first
3308 frame on this terminal. */
3309 if (FRAME_HAS_MINIBUF_P (f)
3310 && (!FRAMEP (KVAR (kb, Vdefault_minibuffer_frame))
3311 || !FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame)))))
3312 kset_default_minibuffer_frame (kb, frame);
3313
3314 /* All remaining specified parameters, which have not been "used"
3315 by x_get_arg and friends, now go in the misc. alist of the frame. */
3316 for (tem = parms; CONSP (tem); tem = XCDR (tem))
3317 if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
3318 fset_param_alist (f, Fcons (XCAR (tem), f->param_alist));
3319
3320 UNGCPRO;
3321
3322 /* Make sure windows on this frame appear in calls to next-window
3323 and similar functions. */
3324 Vwindow_list = Qnil;
3325
3326 return unbind_to (count, frame);
3327 }
3328
3329
3330 /* FRAME is used only to get a handle on the X display. We don't pass the
3331 display info directly because we're called from frame.c, which doesn't
3332 know about that structure. */
3333
3334 Lisp_Object
3335 x_get_focus_frame (struct frame *frame)
3336 {
3337 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (frame);
3338 Lisp_Object xfocus;
3339 if (! dpyinfo->x_focus_frame)
3340 return Qnil;
3341
3342 XSETFRAME (xfocus, dpyinfo->x_focus_frame);
3343 return xfocus;
3344 }
3345
3346
3347 /* In certain situations, when the window manager follows a
3348 click-to-focus policy, there seems to be no way around calling
3349 XSetInputFocus to give another frame the input focus .
3350
3351 In an ideal world, XSetInputFocus should generally be avoided so
3352 that applications don't interfere with the window manager's focus
3353 policy. But I think it's okay to use when it's clearly done
3354 following a user-command. */
3355
3356 void
3357 x_focus_frame (struct frame *f)
3358 {
3359 Display *dpy = FRAME_X_DISPLAY (f);
3360
3361 block_input ();
3362 x_catch_errors (dpy);
3363
3364 if (FRAME_X_EMBEDDED_P (f))
3365 {
3366 /* For Xembedded frames, normally the embedder forwards key
3367 events. See XEmbed Protocol Specification at
3368 http://freedesktop.org/wiki/Specifications/xembed-spec */
3369 xembed_request_focus (f);
3370 }
3371 else
3372 {
3373 XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3374 RevertToParent, CurrentTime);
3375 x_ewmh_activate_frame (f);
3376 }
3377
3378 x_uncatch_errors ();
3379 unblock_input ();
3380 }
3381
3382 \f
3383 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
3384 doc: /* Internal function called by `color-defined-p', which see
3385 .\(Note that the Nextstep version of this function ignores FRAME.) */)
3386 (Lisp_Object color, Lisp_Object frame)
3387 {
3388 XColor foo;
3389 struct frame *f = decode_window_system_frame (frame);
3390
3391 CHECK_STRING (color);
3392
3393 if (x_defined_color (f, SSDATA (color), &foo, 0))
3394 return Qt;
3395 else
3396 return Qnil;
3397 }
3398
3399 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
3400 doc: /* Internal function called by `color-values', which see. */)
3401 (Lisp_Object color, Lisp_Object frame)
3402 {
3403 XColor foo;
3404 struct frame *f = decode_window_system_frame (frame);
3405
3406 CHECK_STRING (color);
3407
3408 if (x_defined_color (f, SSDATA (color), &foo, 0))
3409 return list3i (foo.red, foo.green, foo.blue);
3410 else
3411 return Qnil;
3412 }
3413
3414 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
3415 doc: /* Internal function called by `display-color-p', which see. */)
3416 (Lisp_Object terminal)
3417 {
3418 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3419
3420 if (dpyinfo->n_planes <= 2)
3421 return Qnil;
3422
3423 switch (dpyinfo->visual->class)
3424 {
3425 case StaticColor:
3426 case PseudoColor:
3427 case TrueColor:
3428 case DirectColor:
3429 return Qt;
3430
3431 default:
3432 return Qnil;
3433 }
3434 }
3435
3436 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
3437 0, 1, 0,
3438 doc: /* Return t if the X display supports shades of gray.
3439 Note that color displays do support shades of gray.
3440 The optional argument TERMINAL specifies which display to ask about.
3441 TERMINAL should be a terminal object, a frame or a display name (a string).
3442 If omitted or nil, that stands for the selected frame's display. */)
3443 (Lisp_Object terminal)
3444 {
3445 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3446
3447 if (dpyinfo->n_planes <= 1)
3448 return Qnil;
3449
3450 switch (dpyinfo->visual->class)
3451 {
3452 case StaticColor:
3453 case PseudoColor:
3454 case TrueColor:
3455 case DirectColor:
3456 case StaticGray:
3457 case GrayScale:
3458 return Qt;
3459
3460 default:
3461 return Qnil;
3462 }
3463 }
3464
3465 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
3466 0, 1, 0,
3467 doc: /* Return the width in pixels of the X display TERMINAL.
3468 The optional argument TERMINAL specifies which display to ask about.
3469 TERMINAL should be a terminal object, a frame or a display name (a string).
3470 If omitted or nil, that stands for the selected frame's display.
3471
3472 On \"multi-monitor\" setups this refers to the pixel width for all
3473 physical monitors associated with TERMINAL. To get information for
3474 each physical monitor, use `display-monitor-attributes-list'. */)
3475 (Lisp_Object terminal)
3476 {
3477 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3478
3479 return make_number (x_display_pixel_width (dpyinfo));
3480 }
3481
3482 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
3483 Sx_display_pixel_height, 0, 1, 0,
3484 doc: /* Return the height in pixels of the X display TERMINAL.
3485 The optional argument TERMINAL specifies which display to ask about.
3486 TERMINAL should be a terminal object, a frame or a display name (a string).
3487 If omitted or nil, that stands for the selected frame's display.
3488
3489 On \"multi-monitor\" setups this refers to the pixel height for all
3490 physical monitors associated with TERMINAL. To get information for
3491 each physical monitor, use `display-monitor-attributes-list'. */)
3492 (Lisp_Object terminal)
3493 {
3494 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3495
3496 return make_number (x_display_pixel_height (dpyinfo));
3497 }
3498
3499 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
3500 0, 1, 0,
3501 doc: /* Return the number of bitplanes of the X display TERMINAL.
3502 The optional argument TERMINAL specifies which display to ask about.
3503 TERMINAL should be a terminal object, a frame or a display name (a string).
3504 If omitted or nil, that stands for the selected frame's display. */)
3505 (Lisp_Object terminal)
3506 {
3507 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3508
3509 return make_number (dpyinfo->n_planes);
3510 }
3511
3512 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
3513 0, 1, 0,
3514 doc: /* Return the number of color cells 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)
3519 {
3520 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3521
3522 int nr_planes = DisplayPlanes (dpyinfo->display,
3523 XScreenNumberOfScreen (dpyinfo->screen));
3524
3525 /* Truncate nr_planes to 24 to avoid integer overflow.
3526 Some displays says 32, but only 24 bits are actually significant.
3527 There are only very few and rare video cards that have more than
3528 24 significant bits. Also 24 bits is more than 16 million colors,
3529 it "should be enough for everyone". */
3530 if (nr_planes > 24) nr_planes = 24;
3531
3532 return make_number (1 << nr_planes);
3533 }
3534
3535 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
3536 Sx_server_max_request_size,
3537 0, 1, 0,
3538 doc: /* Return the maximum request size of the X server of display TERMINAL.
3539 The optional argument TERMINAL specifies which display to ask about.
3540 TERMINAL should be a terminal object, a frame or a display name (a string).
3541 If omitted or nil, that stands for the selected frame's display. */)
3542 (Lisp_Object terminal)
3543 {
3544 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3545
3546 return make_number (MAXREQUEST (dpyinfo->display));
3547 }
3548
3549 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
3550 doc: /* Return the "vendor ID" string of the X server of display TERMINAL.
3551 \(Labeling every distributor as a "vendor" embodies the false assumption
3552 that operating systems cannot be developed and distributed noncommercially.)
3553 The optional argument TERMINAL specifies which display to ask about.
3554 TERMINAL should be a terminal object, a frame or a display name (a string).
3555 If omitted or nil, that stands for the selected frame's display. */)
3556 (Lisp_Object terminal)
3557 {
3558 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3559 const char *vendor = ServerVendor (dpyinfo->display);
3560
3561 if (! vendor) vendor = "";
3562 return build_string (vendor);
3563 }
3564
3565 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
3566 doc: /* Return the version numbers of the X server of display TERMINAL.
3567 The value is a list of three integers: the major and minor
3568 version numbers of the X Protocol in use, and the distributor-specific release
3569 number. See also the function `x-server-vendor'.
3570
3571 The optional argument TERMINAL specifies which display to ask about.
3572 TERMINAL should be a terminal object, a frame or a display name (a string).
3573 If omitted or nil, that stands for the selected frame's display. */)
3574 (Lisp_Object terminal)
3575 {
3576 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3577 Display *dpy = dpyinfo->display;
3578
3579 return list3i (ProtocolVersion (dpy), ProtocolRevision (dpy),
3580 VendorRelease (dpy));
3581 }
3582
3583 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
3584 doc: /* Return the number of screens on the X server of display TERMINAL.
3585 The optional argument TERMINAL specifies which display to ask about.
3586 TERMINAL should be a terminal object, a frame or a display name (a string).
3587 If omitted or nil, that stands for the selected frame's display. */)
3588 (Lisp_Object terminal)
3589 {
3590 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3591
3592 return make_number (ScreenCount (dpyinfo->display));
3593 }
3594
3595 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
3596 doc: /* Return the height in millimeters of the X display TERMINAL.
3597 The optional argument TERMINAL specifies which display to ask about.
3598 TERMINAL should be a terminal object, a frame or a display name (a string).
3599 If omitted or nil, that stands for the selected frame's display.
3600
3601 On \"multi-monitor\" setups this refers to the height in millimeters for
3602 all physical monitors associated with TERMINAL. To get information
3603 for each physical monitor, use `display-monitor-attributes-list'. */)
3604 (Lisp_Object terminal)
3605 {
3606 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3607
3608 return make_number (HeightMMOfScreen (dpyinfo->screen));
3609 }
3610
3611 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
3612 doc: /* Return the width in millimeters of the X display TERMINAL.
3613 The optional argument TERMINAL specifies which display to ask about.
3614 TERMINAL should be a terminal object, a frame or a display name (a string).
3615 If omitted or nil, that stands for the selected frame's display.
3616
3617 On \"multi-monitor\" setups this refers to the width in millimeters for
3618 all physical monitors associated with TERMINAL. To get information
3619 for each physical monitor, use `display-monitor-attributes-list'. */)
3620 (Lisp_Object terminal)
3621 {
3622 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3623
3624 return make_number (WidthMMOfScreen (dpyinfo->screen));
3625 }
3626
3627 DEFUN ("x-display-backing-store", Fx_display_backing_store,
3628 Sx_display_backing_store, 0, 1, 0,
3629 doc: /* Return an indication of whether X display TERMINAL does backing store.
3630 The value may be `always', `when-mapped', or `not-useful'.
3631 The optional argument TERMINAL specifies which display to ask about.
3632 TERMINAL should be a terminal object, a frame or a display name (a string).
3633 If omitted or nil, that stands for the selected frame's display. */)
3634 (Lisp_Object terminal)
3635 {
3636 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3637 Lisp_Object result;
3638
3639 switch (DoesBackingStore (dpyinfo->screen))
3640 {
3641 case Always:
3642 result = intern ("always");
3643 break;
3644
3645 case WhenMapped:
3646 result = intern ("when-mapped");
3647 break;
3648
3649 case NotUseful:
3650 result = intern ("not-useful");
3651 break;
3652
3653 default:
3654 error ("Strange value for BackingStore parameter of screen");
3655 }
3656
3657 return result;
3658 }
3659
3660 DEFUN ("x-display-visual-class", Fx_display_visual_class,
3661 Sx_display_visual_class, 0, 1, 0,
3662 doc: /* Return the visual class of the X display TERMINAL.
3663 The value is one of the symbols `static-gray', `gray-scale',
3664 `static-color', `pseudo-color', `true-color', or `direct-color'.
3665
3666 The optional argument TERMINAL specifies which display to ask about.
3667 TERMINAL should a terminal object, a frame or a display name (a string).
3668 If omitted or nil, that stands for the selected frame's display. */)
3669 (Lisp_Object terminal)
3670 {
3671 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3672 Lisp_Object result;
3673
3674 switch (dpyinfo->visual->class)
3675 {
3676 case StaticGray:
3677 result = intern ("static-gray");
3678 break;
3679 case GrayScale:
3680 result = intern ("gray-scale");
3681 break;
3682 case StaticColor:
3683 result = intern ("static-color");
3684 break;
3685 case PseudoColor:
3686 result = intern ("pseudo-color");
3687 break;
3688 case TrueColor:
3689 result = intern ("true-color");
3690 break;
3691 case DirectColor:
3692 result = intern ("direct-color");
3693 break;
3694 default:
3695 error ("Display has an unknown visual class");
3696 }
3697
3698 return result;
3699 }
3700
3701 DEFUN ("x-display-save-under", Fx_display_save_under,
3702 Sx_display_save_under, 0, 1, 0,
3703 doc: /* Return t if the X display TERMINAL supports the save-under feature.
3704 The optional argument TERMINAL specifies which display to ask about.
3705 TERMINAL should be a terminal object, a frame or a display name (a string).
3706 If omitted or nil, that stands for the selected frame's display. */)
3707 (Lisp_Object terminal)
3708 {
3709 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3710
3711 if (DoesSaveUnders (dpyinfo->screen) == True)
3712 return Qt;
3713 else
3714 return Qnil;
3715 }
3716
3717 /* Store the geometry of the workarea on display DPYINFO into *RECT.
3718 Return false if and only if the workarea information cannot be
3719 obtained via the _NET_WORKAREA root window property. */
3720
3721 #if ! GTK_CHECK_VERSION (3, 4, 0)
3722 static bool
3723 x_get_net_workarea (struct x_display_info *dpyinfo, XRectangle *rect)
3724 {
3725 Display *dpy = dpyinfo->display;
3726 long offset, max_len;
3727 Atom target_type, actual_type;
3728 unsigned long actual_size, bytes_remaining;
3729 int rc, actual_format;
3730 unsigned char *tmp_data = NULL;
3731 bool result = false;
3732
3733 x_catch_errors (dpy);
3734 offset = 0;
3735 max_len = 1;
3736 target_type = XA_CARDINAL;
3737 rc = XGetWindowProperty (dpy, dpyinfo->root_window,
3738 dpyinfo->Xatom_net_current_desktop,
3739 offset, max_len, False, target_type,
3740 &actual_type, &actual_format, &actual_size,
3741 &bytes_remaining, &tmp_data);
3742 if (rc == Success && actual_type == target_type && !x_had_errors_p (dpy)
3743 && actual_format == 32 && actual_size == max_len)
3744 {
3745 long current_desktop = ((long *) tmp_data)[0];
3746
3747 XFree (tmp_data);
3748 tmp_data = NULL;
3749
3750 offset = 4 * current_desktop;
3751 max_len = 4;
3752 rc = XGetWindowProperty (dpy, dpyinfo->root_window,
3753 dpyinfo->Xatom_net_workarea,
3754 offset, max_len, False, target_type,
3755 &actual_type, &actual_format, &actual_size,
3756 &bytes_remaining, &tmp_data);
3757 if (rc == Success && actual_type == target_type && !x_had_errors_p (dpy)
3758 && actual_format == 32 && actual_size == max_len)
3759 {
3760 long *values = (long *) tmp_data;
3761
3762 rect->x = values[0];
3763 rect->y = values[1];
3764 rect->width = values[2];
3765 rect->height = values[3];
3766
3767 XFree (tmp_data);
3768 tmp_data = NULL;
3769
3770 result = true;
3771 }
3772 }
3773 if (tmp_data)
3774 XFree (tmp_data);
3775 x_uncatch_errors ();
3776
3777 return result;
3778 }
3779 #endif
3780
3781 #ifndef USE_GTK
3782
3783 /* Return monitor number where F is "most" or closest to. */
3784 static int
3785 x_get_monitor_for_frame (struct frame *f,
3786 struct MonitorInfo *monitors,
3787 int n_monitors)
3788 {
3789 XRectangle frect;
3790 int area = 0, dist = -1;
3791 int best_area = -1, best_dist = -1;
3792 int i;
3793
3794 if (n_monitors == 1) return 0;
3795 frect.x = f->left_pos;
3796 frect.y = f->top_pos;
3797 frect.width = FRAME_PIXEL_WIDTH (f);
3798 frect.height = FRAME_PIXEL_HEIGHT (f);
3799
3800 for (i = 0; i < n_monitors; ++i)
3801 {
3802 struct MonitorInfo *mi = &monitors[i];
3803 XRectangle res;
3804 int a = 0;
3805
3806 if (mi->geom.width == 0) continue;
3807
3808 if (x_intersect_rectangles (&mi->geom, &frect, &res))
3809 {
3810 a = res.width * res.height;
3811 if (a > area)
3812 {
3813 area = a;
3814 best_area = i;
3815 }
3816 }
3817
3818 if (a == 0 && area == 0)
3819 {
3820 int dx, dy, d;
3821 if (frect.x + frect.width < mi->geom.x)
3822 dx = mi->geom.x - frect.x + frect.width;
3823 else if (frect.x > mi->geom.x + mi->geom.width)
3824 dx = frect.x - mi->geom.x + mi->geom.width;
3825 else
3826 dx = 0;
3827 if (frect.y + frect.height < mi->geom.y)
3828 dy = mi->geom.y - frect.y + frect.height;
3829 else if (frect.y > mi->geom.y + mi->geom.height)
3830 dy = frect.y - mi->geom.y + mi->geom.height;
3831 else
3832 dy = 0;
3833
3834 d = dx*dx + dy*dy;
3835 if (dist == -1 || dist > d)
3836 {
3837 dist = d;
3838 best_dist = i;
3839 }
3840 }
3841 }
3842
3843 return best_area != -1 ? best_area : (best_dist != -1 ? best_dist : 0);
3844 }
3845
3846 static Lisp_Object
3847 x_make_monitor_attribute_list (struct MonitorInfo *monitors,
3848 int n_monitors,
3849 int primary_monitor,
3850 struct x_display_info *dpyinfo,
3851 const char *source)
3852 {
3853 Lisp_Object monitor_frames = Fmake_vector (make_number (n_monitors), Qnil);
3854 Lisp_Object frame, rest;
3855
3856 FOR_EACH_FRAME (rest, frame)
3857 {
3858 struct frame *f = XFRAME (frame);
3859
3860 if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo
3861 && !EQ (frame, tip_frame))
3862 {
3863 int i = x_get_monitor_for_frame (f, monitors, n_monitors);
3864 ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
3865 }
3866 }
3867
3868 return make_monitor_attribute_list (monitors, n_monitors, primary_monitor,
3869 monitor_frames, source);
3870 }
3871
3872 static Lisp_Object
3873 x_get_monitor_attributes_fallback (struct x_display_info *dpyinfo)
3874 {
3875 struct MonitorInfo monitor;
3876 XRectangle workarea_r;
3877
3878 /* Fallback: treat (possibly) multiple physical monitors as if they
3879 formed a single monitor as a whole. This should provide a
3880 consistent result at least on single monitor environments. */
3881 monitor.geom.x = monitor.geom.y = 0;
3882 monitor.geom.width = x_display_pixel_width (dpyinfo);
3883 monitor.geom.height = x_display_pixel_height (dpyinfo);
3884 monitor.mm_width = WidthMMOfScreen (dpyinfo->screen);
3885 monitor.mm_height = HeightMMOfScreen (dpyinfo->screen);
3886 monitor.name = xstrdup ("combined screen");
3887
3888 if (x_get_net_workarea (dpyinfo, &workarea_r))
3889 monitor.work = workarea_r;
3890 else
3891 monitor.work = monitor.geom;
3892 return x_make_monitor_attribute_list (&monitor, 1, 0, dpyinfo, "fallback");
3893 }
3894
3895
3896 #ifdef HAVE_XINERAMA
3897 static Lisp_Object
3898 x_get_monitor_attributes_xinerama (struct x_display_info *dpyinfo)
3899 {
3900 int n_monitors, i;
3901 Lisp_Object attributes_list = Qnil;
3902 Display *dpy = dpyinfo->display;
3903 XineramaScreenInfo *info = XineramaQueryScreens (dpy, &n_monitors);
3904 struct MonitorInfo *monitors;
3905 double mm_width_per_pixel, mm_height_per_pixel;
3906
3907 if (! info || n_monitors == 0)
3908 {
3909 if (info)
3910 XFree (info);
3911 return attributes_list;
3912 }
3913
3914 mm_width_per_pixel = ((double) WidthMMOfScreen (dpyinfo->screen)
3915 / x_display_pixel_width (dpyinfo));
3916 mm_height_per_pixel = ((double) HeightMMOfScreen (dpyinfo->screen)
3917 / x_display_pixel_height (dpyinfo));
3918 monitors = xzalloc (n_monitors * sizeof *monitors);
3919 for (i = 0; i < n_monitors; ++i)
3920 {
3921 struct MonitorInfo *mi = &monitors[i];
3922 XRectangle workarea_r;
3923
3924 mi->geom.x = info[i].x_org;
3925 mi->geom.y = info[i].y_org;
3926 mi->geom.width = info[i].width;
3927 mi->geom.height = info[i].height;
3928 mi->mm_width = mi->geom.width * mm_width_per_pixel + 0.5;
3929 mi->mm_height = mi->geom.height * mm_height_per_pixel + 0.5;
3930 mi->name = 0;
3931
3932 /* Xinerama usually have primary monitor first, just use that. */
3933 if (i == 0 && x_get_net_workarea (dpyinfo, &workarea_r))
3934 {
3935 mi->work = workarea_r;
3936 if (! x_intersect_rectangles (&mi->geom, &mi->work, &mi->work))
3937 mi->work = mi->geom;
3938 }
3939 else
3940 mi->work = mi->geom;
3941 }
3942 XFree (info);
3943
3944 attributes_list = x_make_monitor_attribute_list (monitors,
3945 n_monitors,
3946 0,
3947 dpyinfo,
3948 "Xinerama");
3949 free_monitors (monitors, n_monitors);
3950 return attributes_list;
3951 }
3952 #endif /* HAVE_XINERAMA */
3953
3954
3955 #ifdef HAVE_XRANDR
3956 static Lisp_Object
3957 x_get_monitor_attributes_xrandr (struct x_display_info *dpyinfo)
3958 {
3959 Lisp_Object attributes_list = Qnil;
3960 XRRScreenResources *resources;
3961 Display *dpy = dpyinfo->display;
3962 int i, n_monitors, primary = -1;
3963 RROutput pxid = None;
3964 struct MonitorInfo *monitors;
3965
3966 #ifdef HAVE_XRRGETSCREENRESOURCESCURRENT
3967 resources = XRRGetScreenResourcesCurrent (dpy, dpyinfo->root_window);
3968 #else
3969 resources = XRRGetScreenResources (dpy, dpyinfo->root_window);
3970 #endif
3971 if (! resources || resources->noutput == 0)
3972 {
3973 if (resources)
3974 XRRFreeScreenResources (resources);
3975 return Qnil;
3976 }
3977 n_monitors = resources->noutput;
3978 monitors = xzalloc (n_monitors * sizeof *monitors);
3979
3980 #ifdef HAVE_XRRGETOUTPUTPRIMARY
3981 pxid = XRRGetOutputPrimary (dpy, dpyinfo->root_window);
3982 #endif
3983
3984 for (i = 0; i < n_monitors; ++i)
3985 {
3986 XRROutputInfo *info = XRRGetOutputInfo (dpy, resources,
3987 resources->outputs[i]);
3988 Connection conn = info ? info->connection : RR_Disconnected;
3989 RRCrtc id = info ? info->crtc : None;
3990
3991 if (strcmp (info->name, "default") == 0)
3992 {
3993 /* Non XRandr 1.2 driver, does not give useful data. */
3994 XRRFreeOutputInfo (info);
3995 XRRFreeScreenResources (resources);
3996 free_monitors (monitors, n_monitors);
3997 return Qnil;
3998 }
3999
4000 if (conn != RR_Disconnected && id != None)
4001 {
4002 XRRCrtcInfo *crtc = XRRGetCrtcInfo (dpy, resources, id);
4003 struct MonitorInfo *mi = &monitors[i];
4004 XRectangle workarea_r;
4005
4006 if (! crtc)
4007 {
4008 XRRFreeOutputInfo (info);
4009 continue;
4010 }
4011
4012 mi->geom.x = crtc->x;
4013 mi->geom.y = crtc->y;
4014 mi->geom.width = crtc->width;
4015 mi->geom.height = crtc->height;
4016 mi->mm_width = info->mm_width;
4017 mi->mm_height = info->mm_height;
4018 mi->name = xstrdup (info->name);
4019
4020 if (pxid != None && pxid == resources->outputs[i])
4021 primary = i;
4022 else if (primary == -1 && strcmp (info->name, "LVDS") == 0)
4023 primary = i;
4024
4025 if (i == primary && x_get_net_workarea (dpyinfo, &workarea_r))
4026 {
4027 mi->work= workarea_r;
4028 if (! x_intersect_rectangles (&mi->geom, &mi->work, &mi->work))
4029 mi->work = mi->geom;
4030 }
4031 else
4032 mi->work = mi->geom;
4033
4034 XRRFreeCrtcInfo (crtc);
4035 }
4036 XRRFreeOutputInfo (info);
4037 }
4038 XRRFreeScreenResources (resources);
4039
4040 attributes_list = x_make_monitor_attribute_list (monitors,
4041 n_monitors,
4042 primary,
4043 dpyinfo,
4044 "XRandr");
4045 free_monitors (monitors, n_monitors);
4046 return attributes_list;
4047 }
4048 #endif /* HAVE_XRANDR */
4049
4050 static Lisp_Object
4051 x_get_monitor_attributes (struct x_display_info *dpyinfo)
4052 {
4053 Lisp_Object attributes_list = Qnil;
4054 Display *dpy = dpyinfo->display;
4055
4056 (void) dpy; /* Suppress unused variable warning. */
4057
4058 #ifdef HAVE_XRANDR
4059 int xrr_event_base, xrr_error_base;
4060 bool xrr_ok = false;
4061 xrr_ok = XRRQueryExtension (dpy, &xrr_event_base, &xrr_error_base);
4062 if (xrr_ok)
4063 {
4064 int xrr_major, xrr_minor;
4065 XRRQueryVersion (dpy, &xrr_major, &xrr_minor);
4066 xrr_ok = (xrr_major == 1 && xrr_minor >= 2) || xrr_major > 1;
4067 }
4068
4069 if (xrr_ok)
4070 attributes_list = x_get_monitor_attributes_xrandr (dpyinfo);
4071 #endif /* HAVE_XRANDR */
4072
4073 #ifdef HAVE_XINERAMA
4074 if (NILP (attributes_list))
4075 {
4076 int xin_event_base, xin_error_base;
4077 bool xin_ok = false;
4078 xin_ok = XineramaQueryExtension (dpy, &xin_event_base, &xin_error_base);
4079 if (xin_ok && XineramaIsActive (dpy))
4080 attributes_list = x_get_monitor_attributes_xinerama (dpyinfo);
4081 }
4082 #endif /* HAVE_XINERAMA */
4083
4084 if (NILP (attributes_list))
4085 attributes_list = x_get_monitor_attributes_fallback (dpyinfo);
4086
4087 return attributes_list;
4088 }
4089
4090 #endif /* !USE_GTK */
4091
4092 DEFUN ("x-display-monitor-attributes-list", Fx_display_monitor_attributes_list,
4093 Sx_display_monitor_attributes_list,
4094 0, 1, 0,
4095 doc: /* Return a list of physical monitor attributes on the X display TERMINAL.
4096
4097 The optional argument TERMINAL specifies which display to ask about.
4098 TERMINAL should be a terminal object, a frame or a display name (a string).
4099 If omitted or nil, that stands for the selected frame's display.
4100
4101 In addition to the standard attribute keys listed in
4102 `display-monitor-attributes-list', the following keys are contained in
4103 the attributes:
4104
4105 source -- String describing the source from which multi-monitor
4106 information is obtained, one of \"Gdk\", \"XRandr\",
4107 \"Xinerama\", or \"fallback\"
4108
4109 Internal use only, use `display-monitor-attributes-list' instead. */)
4110 (Lisp_Object terminal)
4111 {
4112 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4113 Lisp_Object attributes_list = Qnil;
4114
4115 #ifdef USE_GTK
4116 double mm_width_per_pixel, mm_height_per_pixel;
4117 GdkDisplay *gdpy;
4118 GdkScreen *gscreen;
4119 gint primary_monitor = 0, n_monitors, i;
4120 Lisp_Object monitor_frames, rest, frame;
4121 static const char *source = "Gdk";
4122 struct MonitorInfo *monitors;
4123
4124 block_input ();
4125 mm_width_per_pixel = ((double) WidthMMOfScreen (dpyinfo->screen)
4126 / x_display_pixel_width (dpyinfo));
4127 mm_height_per_pixel = ((double) HeightMMOfScreen (dpyinfo->screen)
4128 / x_display_pixel_height (dpyinfo));
4129 gdpy = gdk_x11_lookup_xdisplay (dpyinfo->display);
4130 gscreen = gdk_display_get_default_screen (gdpy);
4131 #if GTK_CHECK_VERSION (2, 20, 0)
4132 primary_monitor = gdk_screen_get_primary_monitor (gscreen);
4133 #endif
4134 n_monitors = gdk_screen_get_n_monitors (gscreen);
4135 monitor_frames = Fmake_vector (make_number (n_monitors), Qnil);
4136 monitors = xzalloc (n_monitors * sizeof *monitors);
4137
4138 FOR_EACH_FRAME (rest, frame)
4139 {
4140 struct frame *f = XFRAME (frame);
4141
4142 if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo
4143 && !EQ (frame, tip_frame))
4144 {
4145 GdkWindow *gwin = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
4146
4147 i = gdk_screen_get_monitor_at_window (gscreen, gwin);
4148 ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
4149 }
4150 }
4151
4152 for (i = 0; i < n_monitors; ++i)
4153 {
4154 gint width_mm = -1, height_mm = -1;
4155 GdkRectangle rec, work;
4156 struct MonitorInfo *mi = &monitors[i];
4157
4158 gdk_screen_get_monitor_geometry (gscreen, i, &rec);
4159
4160 #if GTK_CHECK_VERSION (2, 14, 0)
4161 width_mm = gdk_screen_get_monitor_width_mm (gscreen, i);
4162 height_mm = gdk_screen_get_monitor_height_mm (gscreen, i);
4163 #endif
4164 if (width_mm < 0)
4165 width_mm = rec.width * mm_width_per_pixel + 0.5;
4166 if (height_mm < 0)
4167 height_mm = rec.height * mm_height_per_pixel + 0.5;
4168
4169 #if GTK_CHECK_VERSION (3, 4, 0)
4170 gdk_screen_get_monitor_workarea (gscreen, i, &work);
4171 #else
4172 /* Emulate the behavior of GTK+ 3.4. */
4173 {
4174 XRectangle workarea_r;
4175
4176 if (i == primary_monitor && x_get_net_workarea (dpyinfo, &workarea_r))
4177 {
4178 work.x = workarea_r.x;
4179 work.y = workarea_r.y;
4180 work.width = workarea_r.width;
4181 work.height = workarea_r.height;
4182 if (! gdk_rectangle_intersect (&rec, &work, &work))
4183 work = rec;
4184 }
4185 else
4186 work = rec;
4187 }
4188 #endif
4189
4190
4191 mi->geom.x = rec.x;
4192 mi->geom.y = rec.y;
4193 mi->geom.width = rec.width;
4194 mi->geom.height = rec.height;
4195 mi->work.x = work.x;
4196 mi->work.y = work.y;
4197 mi->work.width = work.width;
4198 mi->work.height = work.height;
4199 mi->mm_width = width_mm;
4200 mi->mm_height = height_mm;
4201
4202 #if GTK_CHECK_VERSION (2, 14, 0)
4203 mi->name = gdk_screen_get_monitor_plug_name (gscreen, i);
4204 #endif
4205 }
4206
4207 attributes_list = make_monitor_attribute_list (monitors,
4208 n_monitors,
4209 primary_monitor,
4210 monitor_frames,
4211 source);
4212 unblock_input ();
4213 #else /* not USE_GTK */
4214
4215 block_input ();
4216 attributes_list = x_get_monitor_attributes (dpyinfo);
4217 unblock_input ();
4218
4219 #endif /* not USE_GTK */
4220
4221 return attributes_list;
4222 }
4223
4224 /************************************************************************
4225 X Displays
4226 ************************************************************************/
4227
4228 \f
4229 /* Mapping visual names to visuals. */
4230
4231 static struct visual_class
4232 {
4233 const char *name;
4234 int class;
4235 }
4236 visual_classes[] =
4237 {
4238 {"StaticGray", StaticGray},
4239 {"GrayScale", GrayScale},
4240 {"StaticColor", StaticColor},
4241 {"PseudoColor", PseudoColor},
4242 {"TrueColor", TrueColor},
4243 {"DirectColor", DirectColor},
4244 {NULL, 0}
4245 };
4246
4247
4248 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4249
4250 /* Value is the screen number of screen SCR. This is a substitute for
4251 the X function with the same name when that doesn't exist. */
4252
4253 int
4254 XScreenNumberOfScreen (scr)
4255 register Screen *scr;
4256 {
4257 Display *dpy = scr->display;
4258 int i;
4259
4260 for (i = 0; i < dpy->nscreens; ++i)
4261 if (scr == dpy->screens + i)
4262 break;
4263
4264 return i;
4265 }
4266
4267 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4268
4269
4270 /* Select the visual that should be used on display DPYINFO. Set
4271 members of DPYINFO appropriately. Called from x_term_init. */
4272
4273 void
4274 select_visual (struct x_display_info *dpyinfo)
4275 {
4276 Display *dpy = dpyinfo->display;
4277 Screen *screen = dpyinfo->screen;
4278
4279 /* See if a visual is specified. */
4280 AUTO_STRING (visualClass, "visualClass");
4281 AUTO_STRING (VisualClass, "VisualClass");
4282 Lisp_Object value = display_x_get_resource (dpyinfo, visualClass,
4283 VisualClass, Qnil, Qnil);
4284
4285 if (STRINGP (value))
4286 {
4287 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
4288 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
4289 depth, a decimal number. NAME is compared with case ignored. */
4290 char *s = alloca (SBYTES (value) + 1);
4291 char *dash;
4292 int i, class = -1;
4293 XVisualInfo vinfo;
4294
4295 lispstpcpy (s, value);
4296 dash = strchr (s, '-');
4297 if (dash)
4298 {
4299 dpyinfo->n_planes = atoi (dash + 1);
4300 *dash = '\0';
4301 }
4302 else
4303 /* We won't find a matching visual with depth 0, so that
4304 an error will be printed below. */
4305 dpyinfo->n_planes = 0;
4306
4307 /* Determine the visual class. */
4308 for (i = 0; visual_classes[i].name; ++i)
4309 if (xstrcasecmp (s, visual_classes[i].name) == 0)
4310 {
4311 class = visual_classes[i].class;
4312 break;
4313 }
4314
4315 /* Look up a matching visual for the specified class. */
4316 if (class == -1
4317 || !XMatchVisualInfo (dpy, XScreenNumberOfScreen (screen),
4318 dpyinfo->n_planes, class, &vinfo))
4319 fatal ("Invalid visual specification `%s'", SDATA (value));
4320
4321 dpyinfo->visual = vinfo.visual;
4322 }
4323 else
4324 {
4325 int n_visuals;
4326 XVisualInfo *vinfo, vinfo_template;
4327
4328 dpyinfo->visual = DefaultVisualOfScreen (screen);
4329
4330 vinfo_template.visualid = XVisualIDFromVisual (dpyinfo->visual);
4331 vinfo_template.screen = XScreenNumberOfScreen (screen);
4332 vinfo = XGetVisualInfo (dpy, VisualIDMask | VisualScreenMask,
4333 &vinfo_template, &n_visuals);
4334 if (n_visuals <= 0)
4335 fatal ("Can't get proper X visual info");
4336
4337 dpyinfo->n_planes = vinfo->depth;
4338 XFree (vinfo);
4339 }
4340 }
4341
4342
4343 /* Return the X display structure for the display named NAME.
4344 Open a new connection if necessary. */
4345
4346 static struct x_display_info *
4347 x_display_info_for_name (Lisp_Object name)
4348 {
4349 struct x_display_info *dpyinfo;
4350
4351 CHECK_STRING (name);
4352
4353 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
4354 if (!NILP (Fstring_equal (XCAR (dpyinfo->name_list_element), name)))
4355 return dpyinfo;
4356
4357 /* Use this general default value to start with. */
4358 Vx_resource_name = Vinvocation_name;
4359
4360 validate_x_resource_name ();
4361
4362 dpyinfo = x_term_init (name, 0, SSDATA (Vx_resource_name));
4363
4364 if (dpyinfo == 0)
4365 error ("Cannot connect to X server %s", SDATA (name));
4366
4367 XSETFASTINT (Vwindow_system_version, 11);
4368
4369 return dpyinfo;
4370 }
4371
4372
4373 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
4374 1, 3, 0,
4375 doc: /* Open a connection to a display server.
4376 DISPLAY is the name of the display to connect to.
4377 Optional second arg XRM-STRING is a string of resources in xrdb format.
4378 If the optional third arg MUST-SUCCEED is non-nil,
4379 terminate Emacs if we can't open the connection.
4380 \(In the Nextstep version, the last two arguments are currently ignored.) */)
4381 (Lisp_Object display, Lisp_Object xrm_string, Lisp_Object must_succeed)
4382 {
4383 char *xrm_option;
4384 struct x_display_info *dpyinfo;
4385
4386 CHECK_STRING (display);
4387 if (! NILP (xrm_string))
4388 CHECK_STRING (xrm_string);
4389
4390 xrm_option = NILP (xrm_string) ? 0 : SSDATA (xrm_string);
4391
4392 validate_x_resource_name ();
4393
4394 /* This is what opens the connection and sets x_current_display.
4395 This also initializes many symbols, such as those used for input. */
4396 dpyinfo = x_term_init (display, xrm_option,
4397 SSDATA (Vx_resource_name));
4398
4399 if (dpyinfo == 0)
4400 {
4401 if (!NILP (must_succeed))
4402 fatal ("Cannot connect to X server %s.\n\
4403 Check the DISPLAY environment variable or use `-d'.\n\
4404 Also use the `xauth' program to verify that you have the proper\n\
4405 authorization information needed to connect the X server.\n\
4406 An insecure way to solve the problem may be to use `xhost'.\n",
4407 SDATA (display));
4408 else
4409 error ("Cannot connect to X server %s", SDATA (display));
4410 }
4411
4412 XSETFASTINT (Vwindow_system_version, 11);
4413 return Qnil;
4414 }
4415
4416 DEFUN ("x-close-connection", Fx_close_connection,
4417 Sx_close_connection, 1, 1, 0,
4418 doc: /* Close the connection to TERMINAL's X server.
4419 For TERMINAL, specify a terminal object, a frame or a display name (a
4420 string). If TERMINAL is nil, that stands for the selected frame's
4421 terminal. */)
4422 (Lisp_Object terminal)
4423 {
4424 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4425
4426 if (dpyinfo->reference_count > 0)
4427 error ("Display still has frames on it");
4428
4429 x_delete_terminal (dpyinfo->terminal);
4430
4431 return Qnil;
4432 }
4433
4434 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
4435 doc: /* Return the list of display names that Emacs has connections to. */)
4436 (void)
4437 {
4438 Lisp_Object result = Qnil;
4439 struct x_display_info *xdi;
4440
4441 for (xdi = x_display_list; xdi; xdi = xdi->next)
4442 result = Fcons (XCAR (xdi->name_list_element), result);
4443
4444 return result;
4445 }
4446
4447 DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
4448 doc: /* If ON is non-nil, report X errors as soon as the erring request is made.
4449 This function only has an effect on X Windows. With MS Windows, it is
4450 defined but does nothing.
4451
4452 If ON is nil, allow buffering of requests.
4453 Turning on synchronization prohibits the Xlib routines from buffering
4454 requests and seriously degrades performance, but makes debugging much
4455 easier.
4456 The optional second argument TERMINAL specifies which display to act on.
4457 TERMINAL should be a terminal object, a frame or a display name (a string).
4458 If TERMINAL is omitted or nil, that stands for the selected frame's display. */)
4459 (Lisp_Object on, Lisp_Object terminal)
4460 {
4461 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4462
4463 XSynchronize (dpyinfo->display, !EQ (on, Qnil));
4464
4465 return Qnil;
4466 }
4467
4468 /* Wait for responses to all X commands issued so far for frame F. */
4469
4470 void
4471 x_sync (struct frame *f)
4472 {
4473 block_input ();
4474 XSync (FRAME_X_DISPLAY (f), False);
4475 unblock_input ();
4476 }
4477
4478 \f
4479 /***********************************************************************
4480 Window properties
4481 ***********************************************************************/
4482
4483 DEFUN ("x-change-window-property", Fx_change_window_property,
4484 Sx_change_window_property, 2, 6, 0,
4485 doc: /* Change window property PROP to VALUE on the X window of FRAME.
4486 PROP must be a string. VALUE may be a string or a list of conses,
4487 numbers and/or strings. If an element in the list is a string, it is
4488 converted to an atom and the value of the atom is used. If an element
4489 is a cons, it is converted to a 32 bit number where the car is the 16
4490 top bits and the cdr is the lower 16 bits.
4491
4492 FRAME nil or omitted means use the selected frame.
4493 If TYPE is given and non-nil, it is the name of the type of VALUE.
4494 If TYPE is not given or nil, the type is STRING.
4495 FORMAT gives the size in bits of each element if VALUE is a list.
4496 It must be one of 8, 16 or 32.
4497 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
4498 If OUTER-P is non-nil, the property is changed for the outer X window of
4499 FRAME. Default is to change on the edit X window. */)
4500 (Lisp_Object prop, Lisp_Object value, Lisp_Object frame,
4501 Lisp_Object type, Lisp_Object format, Lisp_Object outer_p)
4502 {
4503 struct frame *f = decode_window_system_frame (frame);
4504 Atom prop_atom;
4505 Atom target_type = XA_STRING;
4506 int element_format = 8;
4507 unsigned char *data;
4508 int nelements;
4509 Window w;
4510
4511 CHECK_STRING (prop);
4512
4513 if (! NILP (format))
4514 {
4515 CHECK_NUMBER (format);
4516
4517 if (XINT (format) != 8 && XINT (format) != 16
4518 && XINT (format) != 32)
4519 error ("FORMAT must be one of 8, 16 or 32");
4520 element_format = XINT (format);
4521 }
4522
4523 if (CONSP (value))
4524 {
4525 ptrdiff_t elsize;
4526
4527 nelements = x_check_property_data (value);
4528 if (nelements == -1)
4529 error ("Bad data in VALUE, must be number, string or cons");
4530
4531 /* The man page for XChangeProperty:
4532 "If the specified format is 32, the property data must be a
4533 long array."
4534 This applies even if long is more than 32 bits. The X library
4535 converts to 32 bits before sending to the X server. */
4536 elsize = element_format == 32 ? sizeof (long) : element_format >> 3;
4537 data = xnmalloc (nelements, elsize);
4538
4539 x_fill_property_data (FRAME_X_DISPLAY (f), value, data, element_format);
4540 }
4541 else
4542 {
4543 CHECK_STRING (value);
4544 data = SDATA (value);
4545 if (INT_MAX < SBYTES (value))
4546 error ("VALUE too long");
4547 nelements = SBYTES (value);
4548 }
4549
4550 block_input ();
4551 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (prop), False);
4552 if (! NILP (type))
4553 {
4554 CHECK_STRING (type);
4555 target_type = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (type), False);
4556 }
4557
4558 if (! NILP (outer_p)) w = FRAME_OUTER_WINDOW (f);
4559 else w = FRAME_X_WINDOW (f);
4560
4561 XChangeProperty (FRAME_X_DISPLAY (f), w,
4562 prop_atom, target_type, element_format, PropModeReplace,
4563 data, nelements);
4564
4565 if (CONSP (value)) xfree (data);
4566
4567 /* Make sure the property is set when we return. */
4568 XFlush (FRAME_X_DISPLAY (f));
4569 unblock_input ();
4570
4571 return value;
4572 }
4573
4574
4575 DEFUN ("x-delete-window-property", Fx_delete_window_property,
4576 Sx_delete_window_property, 1, 2, 0,
4577 doc: /* Remove window property PROP from X window of FRAME.
4578 FRAME nil or omitted means use the selected frame. Value is PROP. */)
4579 (Lisp_Object prop, Lisp_Object frame)
4580 {
4581 struct frame *f = decode_window_system_frame (frame);
4582 Atom prop_atom;
4583
4584 CHECK_STRING (prop);
4585 block_input ();
4586 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (prop), False);
4587 XDeleteProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), prop_atom);
4588
4589 /* Make sure the property is removed when we return. */
4590 XFlush (FRAME_X_DISPLAY (f));
4591 unblock_input ();
4592
4593 return prop;
4594 }
4595
4596
4597 static Lisp_Object
4598 x_window_property_intern (struct frame *f,
4599 Window target_window,
4600 Atom prop_atom,
4601 Atom target_type,
4602 Lisp_Object delete_p,
4603 Lisp_Object vector_ret_p,
4604 bool *found)
4605 {
4606 unsigned char *tmp_data = NULL;
4607 Lisp_Object prop_value = Qnil;
4608 Atom actual_type;
4609 int actual_format;
4610 unsigned long actual_size, bytes_remaining;
4611 int rc;
4612 struct gcpro gcpro1;
4613
4614 GCPRO1 (prop_value);
4615
4616 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4617 prop_atom, 0, 0, False, target_type,
4618 &actual_type, &actual_format, &actual_size,
4619 &bytes_remaining, &tmp_data);
4620
4621 *found = actual_format != 0;
4622
4623 if (rc == Success && *found)
4624 {
4625 XFree (tmp_data);
4626 tmp_data = NULL;
4627
4628 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4629 prop_atom, 0, bytes_remaining,
4630 ! NILP (delete_p), target_type,
4631 &actual_type, &actual_format,
4632 &actual_size, &bytes_remaining,
4633 &tmp_data);
4634 if (rc == Success && tmp_data)
4635 {
4636 /* The man page for XGetWindowProperty says:
4637 "If the returned format is 32, the returned data is represented
4638 as a long array and should be cast to that type to obtain the
4639 elements."
4640 This applies even if long is more than 32 bits, the X library
4641 converts from 32 bit elements received from the X server to long
4642 and passes the long array to us. Thus, for that case memcpy can not
4643 be used. We convert to a 32 bit type here, because so much code
4644 assume on that.
4645
4646 The bytes and offsets passed to XGetWindowProperty refers to the
4647 property and those are indeed in 32 bit quantities if format is
4648 32. */
4649
4650 if (BITS_PER_LONG > 32 && actual_format == 32)
4651 {
4652 unsigned long i;
4653 int *idata = (int *) tmp_data;
4654 long *ldata = (long *) tmp_data;
4655
4656 for (i = 0; i < actual_size; ++i)
4657 idata[i] = (int) ldata[i];
4658 }
4659
4660 if (NILP (vector_ret_p))
4661 prop_value = make_string ((char *) tmp_data, actual_size);
4662 else
4663 prop_value = x_property_data_to_lisp (f,
4664 tmp_data,
4665 actual_type,
4666 actual_format,
4667 actual_size);
4668 }
4669
4670 if (tmp_data) XFree (tmp_data);
4671 }
4672
4673 UNGCPRO;
4674 return prop_value;
4675 }
4676
4677 DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
4678 1, 6, 0,
4679 doc: /* Value is the value of window property PROP on FRAME.
4680 If FRAME is nil or omitted, use the selected frame.
4681
4682 On X Windows, the following optional arguments are also accepted:
4683 If TYPE is nil or omitted, get the property as a string.
4684 Otherwise TYPE is the name of the atom that denotes the type expected.
4685 If SOURCE is non-nil, get the property on that window instead of from
4686 FRAME. The number 0 denotes the root window.
4687 If DELETE-P is non-nil, delete the property after retrieving it.
4688 If VECTOR-RET-P is non-nil, don't return a string but a vector of values.
4689
4690 On MS Windows, this function accepts but ignores those optional arguments.
4691
4692 Value is nil if FRAME hasn't a property with name PROP or if PROP has
4693 no value of TYPE (always string in the MS Windows case). */)
4694 (Lisp_Object prop, Lisp_Object frame, Lisp_Object type,
4695 Lisp_Object source, Lisp_Object delete_p, Lisp_Object vector_ret_p)
4696 {
4697 struct frame *f = decode_window_system_frame (frame);
4698 Atom prop_atom;
4699 Lisp_Object prop_value = Qnil;
4700 Atom target_type = XA_STRING;
4701 Window target_window = FRAME_X_WINDOW (f);
4702 struct gcpro gcpro1;
4703 bool found;
4704
4705 GCPRO1 (prop_value);
4706 CHECK_STRING (prop);
4707
4708 if (! NILP (source))
4709 {
4710 CONS_TO_INTEGER (source, Window, target_window);
4711 if (! target_window)
4712 target_window = FRAME_DISPLAY_INFO (f)->root_window;
4713 }
4714
4715 block_input ();
4716 if (STRINGP (type))
4717 {
4718 if (strcmp ("AnyPropertyType", SSDATA (type)) == 0)
4719 target_type = AnyPropertyType;
4720 else
4721 target_type = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (type), False);
4722 }
4723
4724 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (prop), False);
4725 prop_value = x_window_property_intern (f,
4726 target_window,
4727 prop_atom,
4728 target_type,
4729 delete_p,
4730 vector_ret_p,
4731 &found);
4732 if (NILP (prop_value)
4733 && ! found
4734 && NILP (source)
4735 && target_window != FRAME_OUTER_WINDOW (f))
4736 {
4737 prop_value = x_window_property_intern (f,
4738 FRAME_OUTER_WINDOW (f),
4739 prop_atom,
4740 target_type,
4741 delete_p,
4742 vector_ret_p,
4743 &found);
4744 }
4745
4746
4747 unblock_input ();
4748 UNGCPRO;
4749 return prop_value;
4750 }
4751
4752 /***********************************************************************
4753 Tool tips
4754 ***********************************************************************/
4755
4756 static Lisp_Object x_create_tip_frame (struct x_display_info *,
4757 Lisp_Object, Lisp_Object);
4758 static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
4759 Lisp_Object, int, int, int *, int *);
4760
4761 /* The frame of a currently visible tooltip. */
4762
4763 Lisp_Object tip_frame;
4764
4765 /* If non-nil, a timer started that hides the last tooltip when it
4766 fires. */
4767
4768 static Lisp_Object tip_timer;
4769 Window tip_window;
4770
4771 /* If non-nil, a vector of 3 elements containing the last args
4772 with which x-show-tip was called. See there. */
4773
4774 static Lisp_Object last_show_tip_args;
4775
4776
4777 static void
4778 unwind_create_tip_frame (Lisp_Object frame)
4779 {
4780 Lisp_Object deleted;
4781
4782 deleted = unwind_create_frame (frame);
4783 if (EQ (deleted, Qt))
4784 {
4785 tip_window = None;
4786 tip_frame = Qnil;
4787 }
4788 }
4789
4790
4791 /* Create a frame for a tooltip on the display described by DPYINFO.
4792 PARMS is a list of frame parameters. TEXT is the string to
4793 display in the tip frame. Value is the frame.
4794
4795 Note that functions called here, esp. x_default_parameter can
4796 signal errors, for instance when a specified color name is
4797 undefined. We have to make sure that we're in a consistent state
4798 when this happens. */
4799
4800 static Lisp_Object
4801 x_create_tip_frame (struct x_display_info *dpyinfo,
4802 Lisp_Object parms,
4803 Lisp_Object text)
4804 {
4805 struct frame *f;
4806 Lisp_Object frame;
4807 Lisp_Object name;
4808 int width, height;
4809 ptrdiff_t count = SPECPDL_INDEX ();
4810 struct gcpro gcpro1, gcpro2, gcpro3;
4811 int face_change_count_before = face_change_count;
4812 Lisp_Object buffer;
4813 struct buffer *old_buffer;
4814
4815 if (!dpyinfo->terminal->name)
4816 error ("Terminal is not live, can't create new frames on it");
4817
4818 parms = Fcopy_alist (parms);
4819
4820 /* Get the name of the frame to use for resource lookup. */
4821 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
4822 if (!STRINGP (name)
4823 && !EQ (name, Qunbound)
4824 && !NILP (name))
4825 error ("Invalid frame name--not a string or nil");
4826
4827 frame = Qnil;
4828 GCPRO3 (parms, name, frame);
4829 f = make_frame (1);
4830 XSETFRAME (frame, f);
4831
4832 AUTO_STRING (tip, " *tip*");
4833 buffer = Fget_buffer_create (tip);
4834 /* Use set_window_buffer instead of Fset_window_buffer (see
4835 discussion of bug#11984, bug#12025, bug#12026). */
4836 set_window_buffer (FRAME_ROOT_WINDOW (f), buffer, 0, 0);
4837 old_buffer = current_buffer;
4838 set_buffer_internal_1 (XBUFFER (buffer));
4839 bset_truncate_lines (current_buffer, Qnil);
4840 specbind (Qinhibit_read_only, Qt);
4841 specbind (Qinhibit_modification_hooks, Qt);
4842 Ferase_buffer ();
4843 Finsert (1, &text);
4844 set_buffer_internal_1 (old_buffer);
4845
4846 record_unwind_protect (unwind_create_tip_frame, frame);
4847
4848 f->terminal = dpyinfo->terminal;
4849
4850 /* By setting the output method, we're essentially saying that
4851 the frame is live, as per FRAME_LIVE_P. If we get a signal
4852 from this point on, x_destroy_window might screw up reference
4853 counts etc. */
4854 f->output_method = output_x_window;
4855 f->output_data.x = xzalloc (sizeof *f->output_data.x);
4856 f->output_data.x->icon_bitmap = -1;
4857 FRAME_FONTSET (f) = -1;
4858 f->output_data.x->scroll_bar_foreground_pixel = -1;
4859 f->output_data.x->scroll_bar_background_pixel = -1;
4860 #if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
4861 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
4862 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
4863 #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
4864 f->output_data.x->white_relief.pixel = -1;
4865 f->output_data.x->black_relief.pixel = -1;
4866
4867 fset_icon_name (f, Qnil);
4868 FRAME_DISPLAY_INFO (f) = dpyinfo;
4869 f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
4870 f->output_data.x->explicit_parent = 0;
4871
4872 /* These colors will be set anyway later, but it's important
4873 to get the color reference counts right, so initialize them! */
4874 {
4875 Lisp_Object black;
4876 struct gcpro gcpro1;
4877
4878 /* Function x_decode_color can signal an error. Make
4879 sure to initialize color slots so that we won't try
4880 to free colors we haven't allocated. */
4881 FRAME_FOREGROUND_PIXEL (f) = -1;
4882 FRAME_BACKGROUND_PIXEL (f) = -1;
4883 f->output_data.x->cursor_pixel = -1;
4884 f->output_data.x->cursor_foreground_pixel = -1;
4885 f->output_data.x->border_pixel = -1;
4886 f->output_data.x->mouse_pixel = -1;
4887
4888 black = build_string ("black");
4889 GCPRO1 (black);
4890 FRAME_FOREGROUND_PIXEL (f)
4891 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4892 FRAME_BACKGROUND_PIXEL (f)
4893 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4894 f->output_data.x->cursor_pixel
4895 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4896 f->output_data.x->cursor_foreground_pixel
4897 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4898 f->output_data.x->border_pixel
4899 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4900 f->output_data.x->mouse_pixel
4901 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4902 UNGCPRO;
4903 }
4904
4905 /* Set the name; the functions to which we pass f expect the name to
4906 be set. */
4907 if (EQ (name, Qunbound) || NILP (name))
4908 {
4909 fset_name (f, build_string (dpyinfo->x_id_name));
4910 f->explicit_name = 0;
4911 }
4912 else
4913 {
4914 fset_name (f, name);
4915 f->explicit_name = 1;
4916 /* use the frame's title when getting resources for this frame. */
4917 specbind (Qx_resource_name, name);
4918 }
4919
4920 register_font_driver (&xfont_driver, f);
4921 #ifdef HAVE_FREETYPE
4922 #ifdef HAVE_XFT
4923 register_font_driver (&xftfont_driver, f);
4924 #else /* not HAVE_XFT */
4925 register_font_driver (&ftxfont_driver, f);
4926 #endif /* not HAVE_XFT */
4927 #endif /* HAVE_FREETYPE */
4928
4929 x_default_parameter (f, parms, Qfont_backend, Qnil,
4930 "fontBackend", "FontBackend", RES_TYPE_STRING);
4931
4932 /* Extract the window parameters from the supplied values that are
4933 needed to determine window geometry. */
4934 x_default_font_parameter (f, parms);
4935
4936 x_default_parameter (f, parms, Qborder_width, make_number (0),
4937 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
4938
4939 /* This defaults to 2 in order to match xterm. We recognize either
4940 internalBorderWidth or internalBorder (which is what xterm calls
4941 it). */
4942 if (NILP (Fassq (Qinternal_border_width, parms)))
4943 {
4944 Lisp_Object value;
4945
4946 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
4947 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
4948 if (! EQ (value, Qunbound))
4949 parms = Fcons (Fcons (Qinternal_border_width, value),
4950 parms);
4951 }
4952
4953 x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
4954 "internalBorderWidth", "internalBorderWidth",
4955 RES_TYPE_NUMBER);
4956 x_default_parameter (f, parms, Qright_divider_width, make_number (0),
4957 NULL, NULL, RES_TYPE_NUMBER);
4958 x_default_parameter (f, parms, Qbottom_divider_width, make_number (0),
4959 NULL, NULL, RES_TYPE_NUMBER);
4960
4961 /* Also do the stuff which must be set before the window exists. */
4962 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
4963 "foreground", "Foreground", RES_TYPE_STRING);
4964 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
4965 "background", "Background", RES_TYPE_STRING);
4966 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
4967 "pointerColor", "Foreground", RES_TYPE_STRING);
4968 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
4969 "cursorColor", "Foreground", RES_TYPE_STRING);
4970 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
4971 "borderColor", "BorderColor", RES_TYPE_STRING);
4972
4973 #ifdef GLYPH_DEBUG
4974 image_cache_refcount =
4975 FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
4976 dpyinfo_refcount = dpyinfo->reference_count;
4977 #endif /* GLYPH_DEBUG */
4978
4979 /* Init faces before x_default_parameter is called for the
4980 scroll-bar-width parameter because otherwise we end up in
4981 init_iterator with a null face cache, which should not happen. */
4982 init_frame_faces (f);
4983
4984 f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
4985
4986 x_figure_window_size (f, parms, 0);
4987
4988 {
4989 XSetWindowAttributes attrs;
4990 unsigned long mask;
4991 Atom type = FRAME_DISPLAY_INFO (f)->Xatom_net_window_type_tooltip;
4992
4993 block_input ();
4994 mask = CWBackPixel | CWOverrideRedirect | CWEventMask;
4995 if (DoesSaveUnders (dpyinfo->screen))
4996 mask |= CWSaveUnder;
4997
4998 /* Window managers look at the override-redirect flag to determine
4999 whether or net to give windows a decoration (Xlib spec, chapter
5000 3.2.8). */
5001 attrs.override_redirect = True;
5002 attrs.save_under = True;
5003 attrs.background_pixel = FRAME_BACKGROUND_PIXEL (f);
5004 /* Arrange for getting MapNotify and UnmapNotify events. */
5005 attrs.event_mask = StructureNotifyMask;
5006 tip_window
5007 = FRAME_X_WINDOW (f)
5008 = XCreateWindow (FRAME_X_DISPLAY (f),
5009 FRAME_DISPLAY_INFO (f)->root_window,
5010 /* x, y, width, height */
5011 0, 0, 1, 1,
5012 /* Border. */
5013 f->border_width,
5014 CopyFromParent, InputOutput, CopyFromParent,
5015 mask, &attrs);
5016 XChangeProperty (FRAME_X_DISPLAY (f), tip_window,
5017 FRAME_DISPLAY_INFO (f)->Xatom_net_window_type,
5018 XA_ATOM, 32, PropModeReplace,
5019 (unsigned char *)&type, 1);
5020 unblock_input ();
5021 }
5022
5023 x_make_gc (f);
5024
5025 x_default_parameter (f, parms, Qauto_raise, Qnil,
5026 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
5027 x_default_parameter (f, parms, Qauto_lower, Qnil,
5028 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
5029 x_default_parameter (f, parms, Qcursor_type, Qbox,
5030 "cursorType", "CursorType", RES_TYPE_SYMBOL);
5031
5032 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
5033 Change will not be effected unless different from the current
5034 FRAME_LINES (f). */
5035 width = FRAME_COLS (f);
5036 height = FRAME_LINES (f);
5037 SET_FRAME_COLS (f, 0);
5038 SET_FRAME_LINES (f, 0);
5039 change_frame_size (f, width, height, 1, 0, 0, 0);
5040
5041 /* Add `tooltip' frame parameter's default value. */
5042 if (NILP (Fframe_parameter (frame, Qtooltip)))
5043 {
5044 AUTO_FRAME_ARG (arg, Qtooltip, Qt);
5045 Fmodify_frame_parameters (frame, arg);
5046 }
5047
5048 /* FIXME - can this be done in a similar way to normal frames?
5049 http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
5050
5051 /* Set the `display-type' frame parameter before setting up faces. */
5052 {
5053 Lisp_Object disptype;
5054
5055 if (FRAME_DISPLAY_INFO (f)->n_planes == 1)
5056 disptype = intern ("mono");
5057 else if (FRAME_DISPLAY_INFO (f)->visual->class == GrayScale
5058 || FRAME_DISPLAY_INFO (f)->visual->class == StaticGray)
5059 disptype = intern ("grayscale");
5060 else
5061 disptype = intern ("color");
5062
5063 if (NILP (Fframe_parameter (frame, Qdisplay_type)))
5064 {
5065 AUTO_FRAME_ARG (arg, Qdisplay_type, disptype);
5066 Fmodify_frame_parameters (frame, arg);
5067 }
5068 }
5069
5070 /* Set up faces after all frame parameters are known. This call
5071 also merges in face attributes specified for new frames.
5072
5073 Frame parameters may be changed if .Xdefaults contains
5074 specifications for the default font. For example, if there is an
5075 `Emacs.default.attributeBackground: pink', the `background-color'
5076 attribute of the frame get's set, which let's the internal border
5077 of the tooltip frame appear in pink. Prevent this. */
5078 {
5079 Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
5080
5081 /* Set tip_frame here, so that */
5082 tip_frame = frame;
5083 call2 (Qface_set_after_frame_default, frame, Qnil);
5084
5085 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
5086 {
5087 AUTO_FRAME_ARG (arg, Qbackground_color, bg);
5088 Fmodify_frame_parameters (frame, arg);
5089 }
5090 }
5091
5092 f->no_split = 1;
5093
5094 UNGCPRO;
5095
5096 /* Now that the frame will be official, it counts as a reference to
5097 its display and terminal. */
5098 FRAME_DISPLAY_INFO (f)->reference_count++;
5099 f->terminal->reference_count++;
5100
5101 /* It is now ok to make the frame official even if we get an error
5102 below. And the frame needs to be on Vframe_list or making it
5103 visible won't work. */
5104 Vframe_list = Fcons (frame, Vframe_list);
5105 f->official = true;
5106
5107 /* Setting attributes of faces of the tooltip frame from resources
5108 and similar will increment face_change_count, which leads to the
5109 clearing of all current matrices. Since this isn't necessary
5110 here, avoid it by resetting face_change_count to the value it
5111 had before we created the tip frame. */
5112 face_change_count = face_change_count_before;
5113
5114 /* Discard the unwind_protect. */
5115 return unbind_to (count, frame);
5116 }
5117
5118
5119 /* Compute where to display tip frame F. PARMS is the list of frame
5120 parameters for F. DX and DY are specified offsets from the current
5121 location of the mouse. WIDTH and HEIGHT are the width and height
5122 of the tooltip. Return coordinates relative to the root window of
5123 the display in *ROOT_X, and *ROOT_Y. */
5124
5125 static void
5126 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)
5127 {
5128 Lisp_Object left, top;
5129 int win_x, win_y;
5130 Window root, child;
5131 unsigned pmask;
5132
5133 /* User-specified position? */
5134 left = Fcdr (Fassq (Qleft, parms));
5135 top = Fcdr (Fassq (Qtop, parms));
5136
5137 /* Move the tooltip window where the mouse pointer is. Resize and
5138 show it. */
5139 if (!INTEGERP (left) || !INTEGERP (top))
5140 {
5141 block_input ();
5142 XQueryPointer (FRAME_X_DISPLAY (f), FRAME_DISPLAY_INFO (f)->root_window,
5143 &root, &child, root_x, root_y, &win_x, &win_y, &pmask);
5144 unblock_input ();
5145 }
5146
5147 if (INTEGERP (top))
5148 *root_y = XINT (top);
5149 else if (*root_y + XINT (dy) <= 0)
5150 *root_y = 0; /* Can happen for negative dy */
5151 else if (*root_y + XINT (dy) + height
5152 <= x_display_pixel_height (FRAME_DISPLAY_INFO (f)))
5153 /* It fits below the pointer */
5154 *root_y += XINT (dy);
5155 else if (height + XINT (dy) <= *root_y)
5156 /* It fits above the pointer. */
5157 *root_y -= height + XINT (dy);
5158 else
5159 /* Put it on the top. */
5160 *root_y = 0;
5161
5162 if (INTEGERP (left))
5163 *root_x = XINT (left);
5164 else if (*root_x + XINT (dx) <= 0)
5165 *root_x = 0; /* Can happen for negative dx */
5166 else if (*root_x + XINT (dx) + width
5167 <= x_display_pixel_width (FRAME_DISPLAY_INFO (f)))
5168 /* It fits to the right of the pointer. */
5169 *root_x += XINT (dx);
5170 else if (width + XINT (dx) <= *root_x)
5171 /* It fits to the left of the pointer. */
5172 *root_x -= width + XINT (dx);
5173 else
5174 /* Put it left-justified on the screen--it ought to fit that way. */
5175 *root_x = 0;
5176 }
5177
5178
5179 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
5180 doc: /* Show STRING in a "tooltip" window on frame FRAME.
5181 A tooltip window is a small X window displaying a string.
5182
5183 This is an internal function; Lisp code should call `tooltip-show'.
5184
5185 FRAME nil or omitted means use the selected frame.
5186
5187 PARMS is an optional list of frame parameters which can be used to
5188 change the tooltip's appearance.
5189
5190 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
5191 means use the default timeout of 5 seconds.
5192
5193 If the list of frame parameters PARMS contains a `left' parameters,
5194 the tooltip is displayed at that x-position. Otherwise it is
5195 displayed at the mouse position, with offset DX added (default is 5 if
5196 DX isn't specified). Likewise for the y-position; if a `top' frame
5197 parameter is specified, it determines the y-position of the tooltip
5198 window, otherwise it is displayed at the mouse position, with offset
5199 DY added (default is -10).
5200
5201 A tooltip's maximum size is specified by `x-max-tooltip-size'.
5202 Text larger than the specified size is clipped. */)
5203 (Lisp_Object string, Lisp_Object frame, Lisp_Object parms, Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy)
5204 {
5205 struct frame *f;
5206 struct window *w;
5207 int root_x, root_y;
5208 struct buffer *old_buffer;
5209 struct text_pos pos;
5210 int i, width, height, seen_reversed_p;
5211 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
5212 int old_windows_or_buffers_changed = windows_or_buffers_changed;
5213 ptrdiff_t count = SPECPDL_INDEX ();
5214
5215 specbind (Qinhibit_redisplay, Qt);
5216
5217 GCPRO4 (string, parms, frame, timeout);
5218
5219 CHECK_STRING (string);
5220 if (SCHARS (string) == 0)
5221 string = make_unibyte_string (" ", 1);
5222
5223 f = decode_window_system_frame (frame);
5224 if (NILP (timeout))
5225 timeout = make_number (5);
5226 else
5227 CHECK_NATNUM (timeout);
5228
5229 if (NILP (dx))
5230 dx = make_number (5);
5231 else
5232 CHECK_NUMBER (dx);
5233
5234 if (NILP (dy))
5235 dy = make_number (-10);
5236 else
5237 CHECK_NUMBER (dy);
5238
5239 #ifdef USE_GTK
5240 if (x_gtk_use_system_tooltips)
5241 {
5242 bool ok;
5243
5244 /* Hide a previous tip, if any. */
5245 Fx_hide_tip ();
5246
5247 block_input ();
5248 ok = xg_prepare_tooltip (f, string, &width, &height);
5249 if (ok)
5250 {
5251 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
5252 xg_show_tooltip (f, root_x, root_y);
5253 /* This is used in Fx_hide_tip. */
5254 XSETFRAME (tip_frame, f);
5255 }
5256 unblock_input ();
5257 if (ok) goto start_timer;
5258 }
5259 #endif /* USE_GTK */
5260
5261 if (NILP (last_show_tip_args))
5262 last_show_tip_args = Fmake_vector (make_number (3), Qnil);
5263
5264 if (!NILP (tip_frame))
5265 {
5266 Lisp_Object last_string = AREF (last_show_tip_args, 0);
5267 Lisp_Object last_frame = AREF (last_show_tip_args, 1);
5268 Lisp_Object last_parms = AREF (last_show_tip_args, 2);
5269
5270 if (EQ (frame, last_frame)
5271 && !NILP (Fequal (last_string, string))
5272 && !NILP (Fequal (last_parms, parms)))
5273 {
5274 struct frame *tip_f = XFRAME (tip_frame);
5275
5276 /* Only DX and DY have changed. */
5277 if (!NILP (tip_timer))
5278 {
5279 Lisp_Object timer = tip_timer;
5280 tip_timer = Qnil;
5281 call1 (Qcancel_timer, timer);
5282 }
5283
5284 block_input ();
5285 compute_tip_xy (tip_f, parms, dx, dy, FRAME_PIXEL_WIDTH (tip_f),
5286 FRAME_PIXEL_HEIGHT (tip_f), &root_x, &root_y);
5287 XMoveWindow (FRAME_X_DISPLAY (tip_f), FRAME_X_WINDOW (tip_f),
5288 root_x, root_y);
5289 unblock_input ();
5290 goto start_timer;
5291 }
5292 }
5293
5294 /* Hide a previous tip, if any. */
5295 Fx_hide_tip ();
5296
5297 ASET (last_show_tip_args, 0, string);
5298 ASET (last_show_tip_args, 1, frame);
5299 ASET (last_show_tip_args, 2, parms);
5300
5301 /* Add default values to frame parameters. */
5302 if (NILP (Fassq (Qname, parms)))
5303 parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
5304 if (NILP (Fassq (Qinternal_border_width, parms)))
5305 parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
5306 if (NILP (Fassq (Qborder_width, parms)))
5307 parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
5308 if (NILP (Fassq (Qbottom_divider_width, parms)))
5309 parms = Fcons (Fcons (Qbottom_divider_width, make_number (0)), parms);
5310 if (NILP (Fassq (Qright_divider_width, parms)))
5311 parms = Fcons (Fcons (Qright_divider_width, make_number (0)), parms);
5312 if (NILP (Fassq (Qborder_color, parms)))
5313 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
5314 if (NILP (Fassq (Qbackground_color, parms)))
5315 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
5316 parms);
5317
5318 /* Create a frame for the tooltip, and record it in the global
5319 variable tip_frame. */
5320 frame = x_create_tip_frame (FRAME_DISPLAY_INFO (f), parms, string);
5321 f = XFRAME (frame);
5322
5323 /* Set up the frame's root window. */
5324 w = XWINDOW (FRAME_ROOT_WINDOW (f));
5325 w->left_col = 0;
5326 w->top_line = 0;
5327 w->pixel_left = 0;
5328 w->pixel_top = 0;
5329
5330 if (CONSP (Vx_max_tooltip_size)
5331 && RANGED_INTEGERP (1, XCAR (Vx_max_tooltip_size), INT_MAX)
5332 && RANGED_INTEGERP (1, XCDR (Vx_max_tooltip_size), INT_MAX))
5333 {
5334 w->total_cols = XFASTINT (XCAR (Vx_max_tooltip_size));
5335 w->total_lines = XFASTINT (XCDR (Vx_max_tooltip_size));
5336 }
5337 else
5338 {
5339 w->total_cols = 80;
5340 w->total_lines = 40;
5341 }
5342
5343 w->pixel_width = w->total_cols * FRAME_COLUMN_WIDTH (f);
5344 w->pixel_height = w->total_lines * FRAME_LINE_HEIGHT (f);
5345
5346 FRAME_TOTAL_COLS (f) = w->total_cols;
5347 adjust_frame_glyphs (f);
5348 w->pseudo_window_p = 1;
5349
5350 /* Display the tooltip text in a temporary buffer. */
5351 old_buffer = current_buffer;
5352 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->contents));
5353 bset_truncate_lines (current_buffer, Qnil);
5354 clear_glyph_matrix (w->desired_matrix);
5355 clear_glyph_matrix (w->current_matrix);
5356 SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
5357 try_window (FRAME_ROOT_WINDOW (f), pos, TRY_WINDOW_IGNORE_FONTS_CHANGE);
5358
5359 /* Compute width and height of the tooltip. */
5360 width = height = seen_reversed_p = 0;
5361 for (i = 0; i < w->desired_matrix->nrows; ++i)
5362 {
5363 struct glyph_row *row = &w->desired_matrix->rows[i];
5364 struct glyph *last;
5365 int row_width;
5366
5367 /* Stop at the first empty row at the end. */
5368 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
5369 break;
5370
5371 /* Let the row go over the full width of the frame. */
5372 row->full_width_p = 1;
5373
5374 row_width = row->pixel_width;
5375 if (row->used[TEXT_AREA])
5376 {
5377 /* There's a glyph at the end of rows that is used to place
5378 the cursor there. Don't include the width of this glyph. */
5379 if (!row->reversed_p)
5380 {
5381 last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
5382 if (INTEGERP (last->object))
5383 row_width -= last->pixel_width;
5384 }
5385 else
5386 {
5387 /* There could be a stretch glyph at the beginning of R2L
5388 rows that is produced by extend_face_to_end_of_line.
5389 Don't count that glyph. */
5390 struct glyph *g = row->glyphs[TEXT_AREA];
5391
5392 if (g->type == STRETCH_GLYPH && INTEGERP (g->object))
5393 {
5394 row_width -= g->pixel_width;
5395 seen_reversed_p = 1;
5396 }
5397 }
5398 }
5399
5400 height += row->height;
5401 width = max (width, row_width);
5402 }
5403
5404 /* If we've seen partial-length R2L rows, we need to re-adjust the
5405 tool-tip frame width and redisplay it again, to avoid over-wide
5406 tips due to the stretch glyph that extends R2L lines to full
5407 width of the frame. */
5408 if (seen_reversed_p)
5409 {
5410 /* w->total_cols and FRAME_TOTAL_COLS want the width in columns,
5411 not in pixels. */
5412 w->pixel_width = width;
5413 width /= WINDOW_FRAME_COLUMN_WIDTH (w);
5414 w->total_cols = width;
5415 FRAME_TOTAL_COLS (f) = width;
5416 SET_FRAME_WIDTH (f, width);
5417 adjust_frame_glyphs (f);
5418 clear_glyph_matrix (w->desired_matrix);
5419 clear_glyph_matrix (w->current_matrix);
5420 try_window (FRAME_ROOT_WINDOW (f), pos, 0);
5421 width = height = 0;
5422 /* Recompute width and height of the tooltip. */
5423 for (i = 0; i < w->desired_matrix->nrows; ++i)
5424 {
5425 struct glyph_row *row = &w->desired_matrix->rows[i];
5426 struct glyph *last;
5427 int row_width;
5428
5429 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
5430 break;
5431 row->full_width_p = 1;
5432 row_width = row->pixel_width;
5433 if (row->used[TEXT_AREA] && !row->reversed_p)
5434 {
5435 last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
5436 if (INTEGERP (last->object))
5437 row_width -= last->pixel_width;
5438 }
5439
5440 height += row->height;
5441 width = max (width, row_width);
5442 }
5443 }
5444
5445 /* Add the frame's internal border to the width and height the X
5446 window should have. */
5447 height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5448 width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5449
5450 /* Move the tooltip window where the mouse pointer is. Resize and
5451 show it. */
5452 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
5453
5454 block_input ();
5455 XMoveResizeWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5456 root_x, root_y, width, height);
5457 XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
5458 unblock_input ();
5459
5460 /* Draw into the window. */
5461 w->must_be_updated_p = 1;
5462 update_single_window (w, 1);
5463
5464 /* Restore original current buffer. */
5465 set_buffer_internal_1 (old_buffer);
5466 windows_or_buffers_changed = old_windows_or_buffers_changed;
5467
5468 start_timer:
5469 /* Let the tip disappear after timeout seconds. */
5470 tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
5471 intern ("x-hide-tip"));
5472
5473 UNGCPRO;
5474 return unbind_to (count, Qnil);
5475 }
5476
5477
5478 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
5479 doc: /* Hide the current tooltip window, if there is any.
5480 Value is t if tooltip was open, nil otherwise. */)
5481 (void)
5482 {
5483 ptrdiff_t count;
5484 Lisp_Object deleted, frame, timer;
5485 struct gcpro gcpro1, gcpro2;
5486
5487 /* Return quickly if nothing to do. */
5488 if (NILP (tip_timer) && NILP (tip_frame))
5489 return Qnil;
5490
5491 frame = tip_frame;
5492 timer = tip_timer;
5493 GCPRO2 (frame, timer);
5494 tip_frame = tip_timer = deleted = Qnil;
5495
5496 count = SPECPDL_INDEX ();
5497 specbind (Qinhibit_redisplay, Qt);
5498 specbind (Qinhibit_quit, Qt);
5499
5500 if (!NILP (timer))
5501 call1 (Qcancel_timer, timer);
5502
5503 #ifdef USE_GTK
5504 {
5505 /* When using system tooltip, tip_frame is the Emacs frame on which
5506 the tip is shown. */
5507 struct frame *f = XFRAME (frame);
5508 if (FRAME_LIVE_P (f) && xg_hide_tooltip (f))
5509 frame = Qnil;
5510 }
5511 #endif
5512
5513 if (FRAMEP (frame))
5514 {
5515 delete_frame (frame, Qnil);
5516 deleted = Qt;
5517
5518 #ifdef USE_LUCID
5519 /* Bloodcurdling hack alert: The Lucid menu bar widget's
5520 redisplay procedure is not called when a tip frame over menu
5521 items is unmapped. Redisplay the menu manually... */
5522 {
5523 Widget w;
5524 struct frame *f = SELECTED_FRAME ();
5525 w = f->output_data.x->menubar_widget;
5526
5527 if (!DoesSaveUnders (FRAME_DISPLAY_INFO (f)->screen)
5528 && w != NULL)
5529 {
5530 block_input ();
5531 xlwmenu_redisplay (w);
5532 unblock_input ();
5533 }
5534 }
5535 #endif /* USE_LUCID */
5536 }
5537
5538 UNGCPRO;
5539 return unbind_to (count, deleted);
5540 }
5541
5542
5543 \f
5544 /***********************************************************************
5545 File selection dialog
5546 ***********************************************************************/
5547
5548 DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog,
5549 Sx_uses_old_gtk_dialog,
5550 0, 0, 0,
5551 doc: /* Return t if the old Gtk+ file selection dialog is used. */)
5552 (void)
5553 {
5554 #ifdef USE_GTK
5555 if (use_dialog_box
5556 && use_file_dialog
5557 && window_system_available (SELECTED_FRAME ())
5558 && xg_uses_old_file_dialog ())
5559 return Qt;
5560 #endif
5561 return Qnil;
5562 }
5563
5564
5565 #ifdef USE_MOTIF
5566 /* Callback for "OK" and "Cancel" on file selection dialog. */
5567
5568 static void
5569 file_dialog_cb (Widget widget, XtPointer client_data, XtPointer call_data)
5570 {
5571 int *result = client_data;
5572 XmAnyCallbackStruct *cb = call_data;
5573 *result = cb->reason;
5574 }
5575
5576
5577 /* Callback for unmapping a file selection dialog. This is used to
5578 capture the case where a dialog is closed via a window manager's
5579 closer button, for example. Using a XmNdestroyCallback didn't work
5580 in this case. */
5581
5582 static void
5583 file_dialog_unmap_cb (Widget widget, XtPointer client_data, XtPointer call_data)
5584 {
5585 int *result = client_data;
5586 *result = XmCR_CANCEL;
5587 }
5588
5589 static void
5590 clean_up_file_dialog (void *arg)
5591 {
5592 Widget dialog = arg;
5593
5594 /* Clean up. */
5595 block_input ();
5596 XtUnmanageChild (dialog);
5597 XtDestroyWidget (dialog);
5598 x_menu_set_in_use (0);
5599 unblock_input ();
5600 }
5601
5602
5603 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5604 doc: /* Read file name, prompting with PROMPT in directory DIR.
5605 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5606 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5607 or directory must exist.
5608
5609 This function is only defined on NS, MS Windows, and X Windows with the
5610 Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
5611 Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.
5612 On Windows 7 and later, the file selection dialog "remembers" the last
5613 directory where the user selected a file, and will open that directory
5614 instead of DIR on subsequent invocations of this function with the same
5615 value of DIR as in previous invocations; this is standard Windows behavior. */)
5616 (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename,
5617 Lisp_Object mustmatch, Lisp_Object only_dir_p)
5618 {
5619 int result;
5620 struct frame *f = SELECTED_FRAME ();
5621 Lisp_Object file = Qnil;
5622 Lisp_Object decoded_file;
5623 Widget dialog, text, help;
5624 Arg al[10];
5625 int ac = 0;
5626 XmString dir_xmstring, pattern_xmstring;
5627 ptrdiff_t count = SPECPDL_INDEX ();
5628 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5629
5630 check_window_system (f);
5631
5632 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5633
5634 if (popup_activated ())
5635 error ("Trying to use a menu from within a menu-entry");
5636
5637 CHECK_STRING (prompt);
5638 CHECK_STRING (dir);
5639
5640 /* Prevent redisplay. */
5641 specbind (Qinhibit_redisplay, Qt);
5642
5643 block_input ();
5644
5645 /* Create the dialog with PROMPT as title, using DIR as initial
5646 directory and using "*" as pattern. */
5647 dir = Fexpand_file_name (dir, Qnil);
5648 dir_xmstring = XmStringCreateLocalized (SSDATA (dir));
5649 pattern_xmstring = XmStringCreateLocalized ("*");
5650
5651 XtSetArg (al[ac], XmNtitle, SDATA (prompt)); ++ac;
5652 XtSetArg (al[ac], XmNdirectory, dir_xmstring); ++ac;
5653 XtSetArg (al[ac], XmNpattern, pattern_xmstring); ++ac;
5654 XtSetArg (al[ac], XmNresizePolicy, XmRESIZE_GROW); ++ac;
5655 XtSetArg (al[ac], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); ++ac;
5656 dialog = XmCreateFileSelectionDialog (f->output_data.x->widget,
5657 "fsb", al, ac);
5658 XmStringFree (dir_xmstring);
5659 XmStringFree (pattern_xmstring);
5660
5661 /* Add callbacks for OK and Cancel. */
5662 XtAddCallback (dialog, XmNokCallback, file_dialog_cb,
5663 (XtPointer) &result);
5664 XtAddCallback (dialog, XmNcancelCallback, file_dialog_cb,
5665 (XtPointer) &result);
5666 XtAddCallback (dialog, XmNunmapCallback, file_dialog_unmap_cb,
5667 (XtPointer) &result);
5668
5669 /* Remove the help button since we can't display help. */
5670 help = XmFileSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON);
5671 XtUnmanageChild (help);
5672
5673 /* Mark OK button as default. */
5674 XtVaSetValues (XmFileSelectionBoxGetChild (dialog, XmDIALOG_OK_BUTTON),
5675 XmNshowAsDefault, True, NULL);
5676
5677 /* If MUSTMATCH is non-nil, disable the file entry field of the
5678 dialog, so that the user must select a file from the files list
5679 box. We can't remove it because we wouldn't have a way to get at
5680 the result file name, then. */
5681 text = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5682 if (!NILP (mustmatch))
5683 {
5684 Widget label;
5685 label = XmFileSelectionBoxGetChild (dialog, XmDIALOG_SELECTION_LABEL);
5686 XtSetSensitive (text, False);
5687 XtSetSensitive (label, False);
5688 }
5689
5690 /* Manage the dialog, so that list boxes get filled. */
5691 XtManageChild (dialog);
5692
5693 if (STRINGP (default_filename))
5694 {
5695 XmString default_xmstring;
5696 Widget wtext = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5697 Widget list = XmFileSelectionBoxGetChild (dialog, XmDIALOG_LIST);
5698
5699 XmTextPosition last_pos = XmTextFieldGetLastPosition (wtext);
5700 XmTextFieldReplace (wtext, 0, last_pos,
5701 (SSDATA (Ffile_name_nondirectory (default_filename))));
5702
5703 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
5704 must include the path for this to work. */
5705
5706 default_xmstring = XmStringCreateLocalized (SSDATA (default_filename));
5707
5708 if (XmListItemExists (list, default_xmstring))
5709 {
5710 int item_pos = XmListItemPos (list, default_xmstring);
5711 /* Select the item and scroll it into view. */
5712 XmListSelectPos (list, item_pos, True);
5713 XmListSetPos (list, item_pos);
5714 }
5715
5716 XmStringFree (default_xmstring);
5717 }
5718
5719 record_unwind_protect_ptr (clean_up_file_dialog, dialog);
5720
5721 /* Process events until the user presses Cancel or OK. */
5722 x_menu_set_in_use (1);
5723 result = 0;
5724 while (result == 0)
5725 {
5726 XEvent event;
5727 x_menu_wait_for_event (0);
5728 XtAppNextEvent (Xt_app_con, &event);
5729 if (event.type == KeyPress
5730 && FRAME_X_DISPLAY (f) == event.xkey.display)
5731 {
5732 KeySym keysym = XLookupKeysym (&event.xkey, 0);
5733
5734 /* Pop down on C-g. */
5735 if (keysym == XK_g && (event.xkey.state & ControlMask) != 0)
5736 XtUnmanageChild (dialog);
5737 }
5738
5739 (void) x_dispatch_event (&event, FRAME_X_DISPLAY (f));
5740 }
5741
5742 /* Get the result. */
5743 if (result == XmCR_OK)
5744 {
5745 XmString text_string;
5746 String data;
5747
5748 XtVaGetValues (dialog, XmNtextString, &text_string, NULL);
5749 XmStringGetLtoR (text_string, XmFONTLIST_DEFAULT_TAG, &data);
5750 XmStringFree (text_string);
5751 file = build_string (data);
5752 XtFree (data);
5753 }
5754 else
5755 file = Qnil;
5756
5757 unblock_input ();
5758 UNGCPRO;
5759
5760 /* Make "Cancel" equivalent to C-g. */
5761 if (NILP (file))
5762 Fsignal (Qquit, Qnil);
5763
5764 decoded_file = DECODE_FILE (file);
5765
5766 return unbind_to (count, decoded_file);
5767 }
5768
5769 #endif /* USE_MOTIF */
5770
5771 #ifdef USE_GTK
5772
5773 static void
5774 clean_up_dialog (void)
5775 {
5776 x_menu_set_in_use (0);
5777 }
5778
5779 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5780 doc: /* Read file name, prompting with PROMPT in directory DIR.
5781 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5782 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5783 or directory must exist.
5784
5785 This function is only defined on NS, MS Windows, and X Windows with the
5786 Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
5787 Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.
5788 On Windows 7 and later, the file selection dialog "remembers" the last
5789 directory where the user selected a file, and will open that directory
5790 instead of DIR on subsequent invocations of this function with the same
5791 value of DIR as in previous invocations; this is standard Windows behavior. */)
5792 (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p)
5793 {
5794 struct frame *f = SELECTED_FRAME ();
5795 char *fn;
5796 Lisp_Object file = Qnil;
5797 Lisp_Object decoded_file;
5798 ptrdiff_t count = SPECPDL_INDEX ();
5799 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5800 char *cdef_file;
5801
5802 check_window_system (f);
5803
5804 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5805
5806 if (popup_activated ())
5807 error ("Trying to use a menu from within a menu-entry");
5808
5809 CHECK_STRING (prompt);
5810 CHECK_STRING (dir);
5811
5812 /* Prevent redisplay. */
5813 specbind (Qinhibit_redisplay, Qt);
5814 record_unwind_protect_void (clean_up_dialog);
5815
5816 block_input ();
5817
5818 if (STRINGP (default_filename))
5819 cdef_file = SSDATA (default_filename);
5820 else
5821 cdef_file = SSDATA (dir);
5822
5823 fn = xg_get_file_name (f, SSDATA (prompt), cdef_file,
5824 ! NILP (mustmatch),
5825 ! NILP (only_dir_p));
5826
5827 if (fn)
5828 {
5829 file = build_string (fn);
5830 xfree (fn);
5831 }
5832
5833 unblock_input ();
5834 UNGCPRO;
5835
5836 /* Make "Cancel" equivalent to C-g. */
5837 if (NILP (file))
5838 Fsignal (Qquit, Qnil);
5839
5840 decoded_file = DECODE_FILE (file);
5841
5842 return unbind_to (count, decoded_file);
5843 }
5844
5845
5846 #ifdef HAVE_FREETYPE
5847
5848 DEFUN ("x-select-font", Fx_select_font, Sx_select_font, 0, 2, 0,
5849 doc: /* Read a font using a GTK dialog.
5850 Return either a font spec (for GTK versions >= 3.2) or a string
5851 containing a GTK-style font name.
5852
5853 FRAME is the frame on which to pop up the font chooser. If omitted or
5854 nil, it defaults to the selected frame. */)
5855 (Lisp_Object frame, Lisp_Object ignored)
5856 {
5857 struct frame *f = decode_window_system_frame (frame);
5858 Lisp_Object font;
5859 Lisp_Object font_param;
5860 char *default_name = NULL;
5861 struct gcpro gcpro1, gcpro2;
5862 ptrdiff_t count = SPECPDL_INDEX ();
5863
5864 if (popup_activated ())
5865 error ("Trying to use a menu from within a menu-entry");
5866
5867 /* Prevent redisplay. */
5868 specbind (Qinhibit_redisplay, Qt);
5869 record_unwind_protect_void (clean_up_dialog);
5870
5871 block_input ();
5872
5873 GCPRO2 (font_param, font);
5874
5875 XSETFONT (font, FRAME_FONT (f));
5876 font_param = Ffont_get (font, intern (":name"));
5877 if (STRINGP (font_param))
5878 default_name = xstrdup (SSDATA (font_param));
5879 else
5880 {
5881 font_param = Fframe_parameter (frame, Qfont_param);
5882 if (STRINGP (font_param))
5883 default_name = xstrdup (SSDATA (font_param));
5884 }
5885
5886 font = xg_get_font (f, default_name);
5887 xfree (default_name);
5888
5889 unblock_input ();
5890
5891 if (NILP (font))
5892 Fsignal (Qquit, Qnil);
5893
5894 return unbind_to (count, font);
5895 }
5896 #endif /* HAVE_FREETYPE */
5897
5898 #endif /* USE_GTK */
5899
5900 \f
5901 /***********************************************************************
5902 Keyboard
5903 ***********************************************************************/
5904
5905 #ifdef HAVE_XKB
5906 #include <X11/XKBlib.h>
5907 #include <X11/keysym.h>
5908 #endif
5909
5910 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p,
5911 Sx_backspace_delete_keys_p, 0, 1, 0,
5912 doc: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
5913 FRAME nil means use the selected frame.
5914 Value is t if we know that both keys are present, and are mapped to the
5915 usual X keysyms. Value is `lambda' if we cannot determine if both keys are
5916 present and mapped to the usual X keysyms. */)
5917 (Lisp_Object frame)
5918 {
5919 #ifndef HAVE_XKB
5920 return Qlambda;
5921 #else
5922 XkbDescPtr kb;
5923 struct frame *f = decode_window_system_frame (frame);
5924 Display *dpy = FRAME_X_DISPLAY (f);
5925 Lisp_Object have_keys;
5926 int major, minor, op, event, error_code;
5927
5928 block_input ();
5929
5930 /* Check library version in case we're dynamically linked. */
5931 major = XkbMajorVersion;
5932 minor = XkbMinorVersion;
5933 if (!XkbLibraryVersion (&major, &minor))
5934 {
5935 unblock_input ();
5936 return Qlambda;
5937 }
5938
5939 /* Check that the server supports XKB. */
5940 major = XkbMajorVersion;
5941 minor = XkbMinorVersion;
5942 if (!XkbQueryExtension (dpy, &op, &event, &error_code, &major, &minor))
5943 {
5944 unblock_input ();
5945 return Qlambda;
5946 }
5947
5948 /* In this code we check that the keyboard has physical keys with names
5949 that start with BKSP (Backspace) and DELE (Delete), and that they
5950 generate keysym XK_BackSpace and XK_Delete respectively.
5951 This function is used to test if normal-erase-is-backspace should be
5952 turned on.
5953 An alternative approach would be to just check if XK_BackSpace and
5954 XK_Delete are mapped to any key. But if any of those are mapped to
5955 some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the
5956 user doesn't know about it, it is better to return false here.
5957 It is more obvious to the user what to do if she/he has two keys
5958 clearly marked with names/symbols and one key does something not
5959 expected (i.e. she/he then tries the other).
5960 The cases where Backspace/Delete is mapped to some other key combination
5961 are rare, and in those cases, normal-erase-is-backspace can be turned on
5962 manually. */
5963
5964 have_keys = Qnil;
5965 kb = XkbGetMap (dpy, XkbAllMapComponentsMask, XkbUseCoreKbd);
5966 if (kb)
5967 {
5968 int delete_keycode = 0, backspace_keycode = 0, i;
5969
5970 if (XkbGetNames (dpy, XkbAllNamesMask, kb) == Success)
5971 {
5972 for (i = kb->min_key_code;
5973 (i < kb->max_key_code
5974 && (delete_keycode == 0 || backspace_keycode == 0));
5975 ++i)
5976 {
5977 /* The XKB symbolic key names can be seen most easily in
5978 the PS file generated by `xkbprint -label name
5979 $DISPLAY'. */
5980 if (memcmp ("DELE", kb->names->keys[i].name, 4) == 0)
5981 delete_keycode = i;
5982 else if (memcmp ("BKSP", kb->names->keys[i].name, 4) == 0)
5983 backspace_keycode = i;
5984 }
5985
5986 XkbFreeNames (kb, 0, True);
5987 }
5988
5989 /* As of libX11-1.6.2, XkbGetMap manual says that you should use
5990 XkbFreeClientMap to free the data returned by XkbGetMap. But
5991 this function just frees the data referenced from KB and not
5992 KB itself. To free KB as well, call XkbFreeKeyboard. */
5993 XkbFreeKeyboard (kb, XkbAllMapComponentsMask, True);
5994
5995 if (delete_keycode
5996 && backspace_keycode
5997 && XKeysymToKeycode (dpy, XK_Delete) == delete_keycode
5998 && XKeysymToKeycode (dpy, XK_BackSpace) == backspace_keycode)
5999 have_keys = Qt;
6000 }
6001 unblock_input ();
6002 return have_keys;
6003 #endif
6004 }
6005
6006
6007 \f
6008 /***********************************************************************
6009 Initialization
6010 ***********************************************************************/
6011
6012 /* Keep this list in the same order as frame_parms in frame.c.
6013 Use 0 for unsupported frame parameters. */
6014
6015 frame_parm_handler x_frame_parm_handlers[] =
6016 {
6017 x_set_autoraise,
6018 x_set_autolower,
6019 x_set_background_color,
6020 x_set_border_color,
6021 x_set_border_width,
6022 x_set_cursor_color,
6023 x_set_cursor_type,
6024 x_set_font,
6025 x_set_foreground_color,
6026 x_set_icon_name,
6027 x_set_icon_type,
6028 x_set_internal_border_width,
6029 x_set_right_divider_width,
6030 x_set_bottom_divider_width,
6031 x_set_menu_bar_lines,
6032 x_set_mouse_color,
6033 x_explicitly_set_name,
6034 x_set_scroll_bar_width,
6035 x_set_scroll_bar_height,
6036 x_set_title,
6037 x_set_unsplittable,
6038 x_set_vertical_scroll_bars,
6039 x_set_horizontal_scroll_bars,
6040 x_set_visibility,
6041 x_set_tool_bar_lines,
6042 x_set_scroll_bar_foreground,
6043 x_set_scroll_bar_background,
6044 x_set_screen_gamma,
6045 x_set_line_spacing,
6046 x_set_left_fringe,
6047 x_set_right_fringe,
6048 x_set_wait_for_wm,
6049 x_set_fullscreen,
6050 x_set_font_backend,
6051 x_set_alpha,
6052 x_set_sticky,
6053 x_set_tool_bar_position,
6054 };
6055
6056 void
6057 syms_of_xfns (void)
6058 {
6059 DEFSYM (Qundefined_color, "undefined-color");
6060 DEFSYM (Qcompound_text, "compound-text");
6061 DEFSYM (Qcancel_timer, "cancel-timer");
6062 DEFSYM (Qfont_param, "font-parameter");
6063
6064 Fput (Qundefined_color, Qerror_conditions,
6065 listn (CONSTYPE_PURE, 2, Qundefined_color, Qerror));
6066 Fput (Qundefined_color, Qerror_message,
6067 build_pure_c_string ("Undefined color"));
6068
6069 DEFVAR_LISP ("x-pointer-shape", Vx_pointer_shape,
6070 doc: /* The shape of the pointer when over text.
6071 Changing the value does not affect existing frames
6072 unless you set the mouse color. */);
6073 Vx_pointer_shape = Qnil;
6074
6075 #if 0 /* This doesn't really do anything. */
6076 DEFVAR_LISP ("x-nontext-pointer-shape", Vx_nontext_pointer_shape,
6077 doc: /* The shape of the pointer when not over text.
6078 This variable takes effect when you create a new frame
6079 or when you set the mouse color. */);
6080 #endif
6081 Vx_nontext_pointer_shape = Qnil;
6082
6083 DEFVAR_LISP ("x-hourglass-pointer-shape", Vx_hourglass_pointer_shape,
6084 doc: /* The shape of the pointer when Emacs is busy.
6085 This variable takes effect when you create a new frame
6086 or when you set the mouse color. */);
6087 Vx_hourglass_pointer_shape = Qnil;
6088
6089 #if 0 /* This doesn't really do anything. */
6090 DEFVAR_LISP ("x-mode-pointer-shape", Vx_mode_pointer_shape,
6091 doc: /* The shape of the pointer when over the mode line.
6092 This variable takes effect when you create a new frame
6093 or when you set the mouse color. */);
6094 #endif
6095 Vx_mode_pointer_shape = Qnil;
6096
6097 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
6098 Vx_sensitive_text_pointer_shape,
6099 doc: /* The shape of the pointer when over mouse-sensitive text.
6100 This variable takes effect when you create a new frame
6101 or when you set the mouse color. */);
6102 Vx_sensitive_text_pointer_shape = Qnil;
6103
6104 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
6105 Vx_window_horizontal_drag_shape,
6106 doc: /* Pointer shape to use for indicating a window can be dragged horizontally.
6107 This variable takes effect when you create a new frame
6108 or when you set the mouse color. */);
6109 Vx_window_horizontal_drag_shape = Qnil;
6110
6111 DEFVAR_LISP ("x-window-vertical-drag-cursor",
6112 Vx_window_vertical_drag_shape,
6113 doc: /* Pointer shape to use for indicating a window can be dragged vertically.
6114 This variable takes effect when you create a new frame
6115 or when you set the mouse color. */);
6116 Vx_window_vertical_drag_shape = Qnil;
6117
6118 DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel,
6119 doc: /* A string indicating the foreground color of the cursor box. */);
6120 Vx_cursor_fore_pixel = Qnil;
6121
6122 DEFVAR_LISP ("x-max-tooltip-size", Vx_max_tooltip_size,
6123 doc: /* Maximum size for tooltips.
6124 Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */);
6125 Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
6126
6127 DEFVAR_LISP ("x-no-window-manager", Vx_no_window_manager,
6128 doc: /* Non-nil if no X window manager is in use.
6129 Emacs doesn't try to figure this out; this is always nil
6130 unless you set it to something else. */);
6131 /* We don't have any way to find this out, so set it to nil
6132 and maybe the user would like to set it to t. */
6133 Vx_no_window_manager = Qnil;
6134
6135 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
6136 Vx_pixel_size_width_font_regexp,
6137 doc: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
6138
6139 Since Emacs gets width of a font matching with this regexp from
6140 PIXEL_SIZE field of the name, font finding mechanism gets faster for
6141 such a font. This is especially effective for such large fonts as
6142 Chinese, Japanese, and Korean. */);
6143 Vx_pixel_size_width_font_regexp = Qnil;
6144
6145 /* This is not ifdef:ed, so other builds than GTK can customize it. */
6146 DEFVAR_BOOL ("x-gtk-use-old-file-dialog", x_gtk_use_old_file_dialog,
6147 doc: /* Non-nil means prompt with the old GTK file selection dialog.
6148 If nil or if the file selection dialog is not available, the new GTK file
6149 chooser is used instead. To turn off all file dialogs set the
6150 variable `use-file-dialog'. */);
6151 x_gtk_use_old_file_dialog = 0;
6152
6153 DEFVAR_BOOL ("x-gtk-show-hidden-files", x_gtk_show_hidden_files,
6154 doc: /* If non-nil, the GTK file chooser will by default show hidden files.
6155 Note that this is just the default, there is a toggle button on the file
6156 chooser to show or not show hidden files on a case by case basis. */);
6157 x_gtk_show_hidden_files = 0;
6158
6159 DEFVAR_BOOL ("x-gtk-file-dialog-help-text", x_gtk_file_dialog_help_text,
6160 doc: /* If non-nil, the GTK file chooser will show additional help text.
6161 If more space for files in the file chooser dialog is wanted, set this to nil
6162 to turn the additional text off. */);
6163 x_gtk_file_dialog_help_text = 1;
6164
6165 DEFVAR_BOOL ("x-gtk-use-system-tooltips", x_gtk_use_system_tooltips,
6166 doc: /* If non-nil with a Gtk+ built Emacs, the Gtk+ tooltip is used.
6167 Otherwise use Emacs own tooltip implementation.
6168 When using Gtk+ tooltips, the tooltip face is not used. */);
6169 x_gtk_use_system_tooltips = 1;
6170
6171 /* Tell Emacs about this window system. */
6172 Fprovide (Qx, Qnil);
6173
6174 #ifdef USE_X_TOOLKIT
6175 Fprovide (intern_c_string ("x-toolkit"), Qnil);
6176 #ifdef USE_MOTIF
6177 Fprovide (intern_c_string ("motif"), Qnil);
6178
6179 DEFVAR_LISP ("motif-version-string", Vmotif_version_string,
6180 doc: /* Version info for LessTif/Motif. */);
6181 Vmotif_version_string = build_string (XmVERSION_STRING);
6182 #endif /* USE_MOTIF */
6183 #endif /* USE_X_TOOLKIT */
6184
6185 #ifdef USE_GTK
6186 /* Provide x-toolkit also for GTK. Internally GTK does not use Xt so it
6187 is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
6188 But for a user it is a toolkit for X, and indeed, configure
6189 accepts --with-x-toolkit=gtk. */
6190 Fprovide (intern_c_string ("x-toolkit"), Qnil);
6191 Fprovide (intern_c_string ("gtk"), Qnil);
6192 Fprovide (intern_c_string ("move-toolbar"), Qnil);
6193
6194 DEFVAR_LISP ("gtk-version-string", Vgtk_version_string,
6195 doc: /* Version info for GTK+. */);
6196 {
6197 char gtk_version[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
6198 int len = sprintf (gtk_version, "%d.%d.%d",
6199 GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
6200 Vgtk_version_string = make_pure_string (gtk_version, len, len, 0);
6201 }
6202 #endif /* USE_GTK */
6203
6204 /* X window properties. */
6205 defsubr (&Sx_change_window_property);
6206 defsubr (&Sx_delete_window_property);
6207 defsubr (&Sx_window_property);
6208
6209 defsubr (&Sxw_display_color_p);
6210 defsubr (&Sx_display_grayscale_p);
6211 defsubr (&Sxw_color_defined_p);
6212 defsubr (&Sxw_color_values);
6213 defsubr (&Sx_server_max_request_size);
6214 defsubr (&Sx_server_vendor);
6215 defsubr (&Sx_server_version);
6216 defsubr (&Sx_display_pixel_width);
6217 defsubr (&Sx_display_pixel_height);
6218 defsubr (&Sx_display_mm_width);
6219 defsubr (&Sx_display_mm_height);
6220 defsubr (&Sx_display_screens);
6221 defsubr (&Sx_display_planes);
6222 defsubr (&Sx_display_color_cells);
6223 defsubr (&Sx_display_visual_class);
6224 defsubr (&Sx_display_backing_store);
6225 defsubr (&Sx_display_save_under);
6226 defsubr (&Sx_display_monitor_attributes_list);
6227 defsubr (&Sx_wm_set_size_hint);
6228 defsubr (&Sx_create_frame);
6229 defsubr (&Sx_open_connection);
6230 defsubr (&Sx_close_connection);
6231 defsubr (&Sx_display_list);
6232 defsubr (&Sx_synchronize);
6233 defsubr (&Sx_backspace_delete_keys_p);
6234
6235 defsubr (&Sx_show_tip);
6236 defsubr (&Sx_hide_tip);
6237 tip_timer = Qnil;
6238 staticpro (&tip_timer);
6239 tip_frame = Qnil;
6240 staticpro (&tip_frame);
6241
6242 last_show_tip_args = Qnil;
6243 staticpro (&last_show_tip_args);
6244
6245 defsubr (&Sx_uses_old_gtk_dialog);
6246 #if defined (USE_MOTIF) || defined (USE_GTK)
6247 defsubr (&Sx_file_dialog);
6248 #endif
6249
6250 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
6251 defsubr (&Sx_select_font);
6252 #endif
6253 }