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