If available, use Xfixes extension to do pointer blanking.
[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 DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
4554 1, 6, 0,
4555 doc: /* Value is the value of window property PROP on FRAME.
4556 If FRAME is nil or omitted, use the selected frame.
4557
4558 On X Windows, the following optional arguments are also accepted:
4559 If TYPE is nil or omitted, get the property as a string.
4560 Otherwise TYPE is the name of the atom that denotes the type expected.
4561 If SOURCE is non-nil, get the property on that window instead of from
4562 FRAME. The number 0 denotes the root window.
4563 If DELETE-P is non-nil, delete the property after retrieving it.
4564 If VECTOR-RET-P is non-nil, don't return a string but a vector of values.
4565
4566 On MS Windows, this function accepts but ignores those optional arguments.
4567
4568 Value is nil if FRAME hasn't a property with name PROP or if PROP has
4569 no value of TYPE (always string in the MS Windows case). */)
4570 (Lisp_Object prop, Lisp_Object frame, Lisp_Object type,
4571 Lisp_Object source, Lisp_Object delete_p, Lisp_Object vector_ret_p)
4572 {
4573 struct frame *f = decode_window_system_frame (frame);
4574 Atom prop_atom;
4575 int rc;
4576 Lisp_Object prop_value = Qnil;
4577 unsigned char *tmp_data = NULL;
4578 Atom actual_type;
4579 Atom target_type = XA_STRING;
4580 int actual_format;
4581 unsigned long actual_size, bytes_remaining;
4582 Window target_window = FRAME_X_WINDOW (f);
4583 struct gcpro gcpro1;
4584
4585 GCPRO1 (prop_value);
4586 CHECK_STRING (prop);
4587
4588 if (! NILP (source))
4589 {
4590 CONS_TO_INTEGER (source, Window, target_window);
4591 if (! target_window)
4592 target_window = FRAME_DISPLAY_INFO (f)->root_window;
4593 }
4594
4595 block_input ();
4596 if (STRINGP (type))
4597 {
4598 if (strcmp ("AnyPropertyType", SSDATA (type)) == 0)
4599 target_type = AnyPropertyType;
4600 else
4601 target_type = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (type), False);
4602 }
4603
4604 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (prop), False);
4605 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4606 prop_atom, 0, 0, False, target_type,
4607 &actual_type, &actual_format, &actual_size,
4608 &bytes_remaining, &tmp_data);
4609 if (rc == Success)
4610 {
4611 int size = bytes_remaining;
4612
4613 XFree (tmp_data);
4614 tmp_data = NULL;
4615
4616 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4617 prop_atom, 0, bytes_remaining,
4618 ! NILP (delete_p), target_type,
4619 &actual_type, &actual_format,
4620 &actual_size, &bytes_remaining,
4621 &tmp_data);
4622 if (rc == Success && tmp_data)
4623 {
4624 /* The man page for XGetWindowProperty says:
4625 "If the returned format is 32, the returned data is represented
4626 as a long array and should be cast to that type to obtain the
4627 elements."
4628 This applies even if long is more than 32 bits, the X library
4629 converts from 32 bit elements received from the X server to long
4630 and passes the long array to us. Thus, for that case memcpy can not
4631 be used. We convert to a 32 bit type here, because so much code
4632 assume on that.
4633
4634 The bytes and offsets passed to XGetWindowProperty refers to the
4635 property and those are indeed in 32 bit quantities if format is
4636 32. */
4637
4638 if (BITS_PER_LONG > 32 && actual_format == 32)
4639 {
4640 unsigned long i;
4641 int *idata = (int *) tmp_data;
4642 long *ldata = (long *) tmp_data;
4643
4644 for (i = 0; i < actual_size; ++i)
4645 idata[i] = (int) ldata[i];
4646 }
4647
4648 if (NILP (vector_ret_p))
4649 prop_value = make_string ((char *) tmp_data, size);
4650 else
4651 prop_value = x_property_data_to_lisp (f,
4652 tmp_data,
4653 actual_type,
4654 actual_format,
4655 actual_size);
4656 }
4657
4658 if (tmp_data) XFree (tmp_data);
4659 }
4660
4661 unblock_input ();
4662 UNGCPRO;
4663 return prop_value;
4664 }
4665
4666
4667 \f
4668 /***********************************************************************
4669 Busy cursor
4670 ***********************************************************************/
4671
4672 /* Timer function of hourglass_atimer. TIMER is equal to
4673 hourglass_atimer.
4674
4675 Display an hourglass pointer on all frames by mapping the frames'
4676 hourglass_window. Set the hourglass_p flag in the frames'
4677 output_data.x structure to indicate that an hourglass cursor is
4678 shown on the frames. */
4679
4680 void
4681 show_hourglass (struct atimer *timer)
4682 {
4683 /* The timer implementation will cancel this timer automatically
4684 after this function has run. Set hourglass_atimer to null
4685 so that we know the timer doesn't have to be canceled. */
4686 hourglass_atimer = NULL;
4687
4688 if (!hourglass_shown_p)
4689 {
4690 Lisp_Object rest, frame;
4691
4692 block_input ();
4693
4694 FOR_EACH_FRAME (rest, frame)
4695 {
4696 struct frame *f = XFRAME (frame);
4697
4698 if (FRAME_LIVE_P (f) && FRAME_X_P (f) && FRAME_X_DISPLAY (f))
4699 {
4700 Display *dpy = FRAME_X_DISPLAY (f);
4701
4702 #ifdef USE_X_TOOLKIT
4703 if (f->output_data.x->widget)
4704 #else
4705 if (FRAME_OUTER_WINDOW (f))
4706 #endif
4707 {
4708 f->output_data.x->hourglass_p = 1;
4709
4710 if (!f->output_data.x->hourglass_window)
4711 {
4712 unsigned long mask = CWCursor;
4713 XSetWindowAttributes attrs;
4714 #ifdef USE_GTK
4715 Window parent = FRAME_X_WINDOW (f);
4716 #else
4717 Window parent = FRAME_OUTER_WINDOW (f);
4718 #endif
4719 attrs.cursor = f->output_data.x->hourglass_cursor;
4720
4721 f->output_data.x->hourglass_window
4722 = XCreateWindow (dpy, parent,
4723 0, 0, 32000, 32000, 0, 0,
4724 InputOnly,
4725 CopyFromParent,
4726 mask, &attrs);
4727 }
4728
4729 XMapRaised (dpy, f->output_data.x->hourglass_window);
4730 XFlush (dpy);
4731 }
4732 }
4733 }
4734
4735 hourglass_shown_p = 1;
4736 unblock_input ();
4737 }
4738 }
4739
4740
4741 /* Hide the hourglass pointer on all frames, if it is currently
4742 shown. */
4743
4744 void
4745 hide_hourglass (void)
4746 {
4747 if (hourglass_shown_p)
4748 {
4749 Lisp_Object rest, frame;
4750
4751 block_input ();
4752 FOR_EACH_FRAME (rest, frame)
4753 {
4754 struct frame *f = XFRAME (frame);
4755
4756 if (FRAME_X_P (f)
4757 /* Watch out for newly created frames. */
4758 && f->output_data.x->hourglass_window)
4759 {
4760 XUnmapWindow (FRAME_X_DISPLAY (f),
4761 f->output_data.x->hourglass_window);
4762 /* Sync here because XTread_socket looks at the
4763 hourglass_p flag that is reset to zero below. */
4764 XSync (FRAME_X_DISPLAY (f), False);
4765 f->output_data.x->hourglass_p = 0;
4766 }
4767 }
4768
4769 hourglass_shown_p = 0;
4770 unblock_input ();
4771 }
4772 }
4773
4774
4775 \f
4776 /***********************************************************************
4777 Tool tips
4778 ***********************************************************************/
4779
4780 static Lisp_Object x_create_tip_frame (struct x_display_info *,
4781 Lisp_Object, Lisp_Object);
4782 static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
4783 Lisp_Object, int, int, int *, int *);
4784
4785 /* The frame of a currently visible tooltip. */
4786
4787 Lisp_Object tip_frame;
4788
4789 /* If non-nil, a timer started that hides the last tooltip when it
4790 fires. */
4791
4792 static Lisp_Object tip_timer;
4793 Window tip_window;
4794
4795 /* If non-nil, a vector of 3 elements containing the last args
4796 with which x-show-tip was called. See there. */
4797
4798 static Lisp_Object last_show_tip_args;
4799
4800
4801 static void
4802 unwind_create_tip_frame (Lisp_Object frame)
4803 {
4804 Lisp_Object deleted;
4805
4806 deleted = unwind_create_frame (frame);
4807 if (EQ (deleted, Qt))
4808 {
4809 tip_window = None;
4810 tip_frame = Qnil;
4811 }
4812 }
4813
4814
4815 /* Create a frame for a tooltip on the display described by DPYINFO.
4816 PARMS is a list of frame parameters. TEXT is the string to
4817 display in the tip frame. Value is the frame.
4818
4819 Note that functions called here, esp. x_default_parameter can
4820 signal errors, for instance when a specified color name is
4821 undefined. We have to make sure that we're in a consistent state
4822 when this happens. */
4823
4824 static Lisp_Object
4825 x_create_tip_frame (struct x_display_info *dpyinfo,
4826 Lisp_Object parms,
4827 Lisp_Object text)
4828 {
4829 struct frame *f;
4830 Lisp_Object frame;
4831 Lisp_Object name;
4832 int width, height;
4833 ptrdiff_t count = SPECPDL_INDEX ();
4834 struct gcpro gcpro1, gcpro2, gcpro3;
4835 int face_change_count_before = face_change_count;
4836 Lisp_Object buffer;
4837 struct buffer *old_buffer;
4838
4839 if (!dpyinfo->terminal->name)
4840 error ("Terminal is not live, can't create new frames on it");
4841
4842 parms = Fcopy_alist (parms);
4843
4844 /* Get the name of the frame to use for resource lookup. */
4845 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
4846 if (!STRINGP (name)
4847 && !EQ (name, Qunbound)
4848 && !NILP (name))
4849 error ("Invalid frame name--not a string or nil");
4850
4851 frame = Qnil;
4852 GCPRO3 (parms, name, frame);
4853 f = make_frame (1);
4854 XSETFRAME (frame, f);
4855
4856 buffer = Fget_buffer_create (build_string (" *tip*"));
4857 /* Use set_window_buffer instead of Fset_window_buffer (see
4858 discussion of bug#11984, bug#12025, bug#12026). */
4859 set_window_buffer (FRAME_ROOT_WINDOW (f), buffer, 0, 0);
4860 old_buffer = current_buffer;
4861 set_buffer_internal_1 (XBUFFER (buffer));
4862 bset_truncate_lines (current_buffer, Qnil);
4863 specbind (Qinhibit_read_only, Qt);
4864 specbind (Qinhibit_modification_hooks, Qt);
4865 Ferase_buffer ();
4866 Finsert (1, &text);
4867 set_buffer_internal_1 (old_buffer);
4868
4869 record_unwind_protect (unwind_create_tip_frame, frame);
4870
4871 f->terminal = dpyinfo->terminal;
4872
4873 /* By setting the output method, we're essentially saying that
4874 the frame is live, as per FRAME_LIVE_P. If we get a signal
4875 from this point on, x_destroy_window might screw up reference
4876 counts etc. */
4877 f->output_method = output_x_window;
4878 f->output_data.x = xzalloc (sizeof *f->output_data.x);
4879 f->output_data.x->icon_bitmap = -1;
4880 FRAME_FONTSET (f) = -1;
4881 f->output_data.x->scroll_bar_foreground_pixel = -1;
4882 f->output_data.x->scroll_bar_background_pixel = -1;
4883 #ifdef USE_TOOLKIT_SCROLL_BARS
4884 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
4885 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
4886 #endif /* USE_TOOLKIT_SCROLL_BARS */
4887 f->output_data.x->white_relief.pixel = -1;
4888 f->output_data.x->black_relief.pixel = -1;
4889
4890 fset_icon_name (f, Qnil);
4891 FRAME_DISPLAY_INFO (f) = dpyinfo;
4892 f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
4893 f->output_data.x->explicit_parent = 0;
4894
4895 /* These colors will be set anyway later, but it's important
4896 to get the color reference counts right, so initialize them! */
4897 {
4898 Lisp_Object black;
4899 struct gcpro gcpro1;
4900
4901 /* Function x_decode_color can signal an error. Make
4902 sure to initialize color slots so that we won't try
4903 to free colors we haven't allocated. */
4904 FRAME_FOREGROUND_PIXEL (f) = -1;
4905 FRAME_BACKGROUND_PIXEL (f) = -1;
4906 f->output_data.x->cursor_pixel = -1;
4907 f->output_data.x->cursor_foreground_pixel = -1;
4908 f->output_data.x->border_pixel = -1;
4909 f->output_data.x->mouse_pixel = -1;
4910
4911 black = build_string ("black");
4912 GCPRO1 (black);
4913 FRAME_FOREGROUND_PIXEL (f)
4914 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4915 FRAME_BACKGROUND_PIXEL (f)
4916 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4917 f->output_data.x->cursor_pixel
4918 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4919 f->output_data.x->cursor_foreground_pixel
4920 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4921 f->output_data.x->border_pixel
4922 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4923 f->output_data.x->mouse_pixel
4924 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4925 UNGCPRO;
4926 }
4927
4928 /* Set the name; the functions to which we pass f expect the name to
4929 be set. */
4930 if (EQ (name, Qunbound) || NILP (name))
4931 {
4932 fset_name (f, build_string (dpyinfo->x_id_name));
4933 f->explicit_name = 0;
4934 }
4935 else
4936 {
4937 fset_name (f, name);
4938 f->explicit_name = 1;
4939 /* use the frame's title when getting resources for this frame. */
4940 specbind (Qx_resource_name, name);
4941 }
4942
4943 register_font_driver (&xfont_driver, f);
4944 #ifdef HAVE_FREETYPE
4945 #ifdef HAVE_XFT
4946 register_font_driver (&xftfont_driver, f);
4947 #else /* not HAVE_XFT */
4948 register_font_driver (&ftxfont_driver, f);
4949 #endif /* not HAVE_XFT */
4950 #endif /* HAVE_FREETYPE */
4951
4952 x_default_parameter (f, parms, Qfont_backend, Qnil,
4953 "fontBackend", "FontBackend", RES_TYPE_STRING);
4954
4955 /* Extract the window parameters from the supplied values that are
4956 needed to determine window geometry. */
4957 x_default_font_parameter (f, parms);
4958
4959 x_default_parameter (f, parms, Qborder_width, make_number (0),
4960 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
4961
4962 /* This defaults to 2 in order to match xterm. We recognize either
4963 internalBorderWidth or internalBorder (which is what xterm calls
4964 it). */
4965 if (NILP (Fassq (Qinternal_border_width, parms)))
4966 {
4967 Lisp_Object value;
4968
4969 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
4970 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
4971 if (! EQ (value, Qunbound))
4972 parms = Fcons (Fcons (Qinternal_border_width, value),
4973 parms);
4974 }
4975
4976 x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
4977 "internalBorderWidth", "internalBorderWidth",
4978 RES_TYPE_NUMBER);
4979 x_default_parameter (f, parms, Qright_divider_width, make_number (0),
4980 NULL, NULL, RES_TYPE_NUMBER);
4981 x_default_parameter (f, parms, Qbottom_divider_width, make_number (0),
4982 NULL, NULL, RES_TYPE_NUMBER);
4983
4984 /* Also do the stuff which must be set before the window exists. */
4985 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
4986 "foreground", "Foreground", RES_TYPE_STRING);
4987 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
4988 "background", "Background", RES_TYPE_STRING);
4989 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
4990 "pointerColor", "Foreground", RES_TYPE_STRING);
4991 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
4992 "cursorColor", "Foreground", RES_TYPE_STRING);
4993 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
4994 "borderColor", "BorderColor", RES_TYPE_STRING);
4995
4996 #ifdef GLYPH_DEBUG
4997 image_cache_refcount =
4998 FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
4999 dpyinfo_refcount = dpyinfo->reference_count;
5000 #endif /* GLYPH_DEBUG */
5001
5002 /* Init faces before x_default_parameter is called for scroll-bar
5003 parameters because that function calls x_set_scroll_bar_width,
5004 which calls change_frame_size, which calls Fset_window_buffer,
5005 which runs hooks, which call Fvertical_motion. At the end, we
5006 end up in init_iterator with a null face cache, which should not
5007 happen. */
5008 init_frame_faces (f);
5009
5010 f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
5011
5012 x_figure_window_size (f, parms, 0);
5013
5014 {
5015 XSetWindowAttributes attrs;
5016 unsigned long mask;
5017 Atom type = FRAME_DISPLAY_INFO (f)->Xatom_net_window_type_tooltip;
5018
5019 block_input ();
5020 mask = CWBackPixel | CWOverrideRedirect | CWEventMask;
5021 if (DoesSaveUnders (dpyinfo->screen))
5022 mask |= CWSaveUnder;
5023
5024 /* Window managers look at the override-redirect flag to determine
5025 whether or net to give windows a decoration (Xlib spec, chapter
5026 3.2.8). */
5027 attrs.override_redirect = True;
5028 attrs.save_under = True;
5029 attrs.background_pixel = FRAME_BACKGROUND_PIXEL (f);
5030 /* Arrange for getting MapNotify and UnmapNotify events. */
5031 attrs.event_mask = StructureNotifyMask;
5032 tip_window
5033 = FRAME_X_WINDOW (f)
5034 = XCreateWindow (FRAME_X_DISPLAY (f),
5035 FRAME_DISPLAY_INFO (f)->root_window,
5036 /* x, y, width, height */
5037 0, 0, 1, 1,
5038 /* Border. */
5039 f->border_width,
5040 CopyFromParent, InputOutput, CopyFromParent,
5041 mask, &attrs);
5042 XChangeProperty (FRAME_X_DISPLAY (f), tip_window,
5043 FRAME_DISPLAY_INFO (f)->Xatom_net_window_type,
5044 XA_ATOM, 32, PropModeReplace,
5045 (unsigned char *)&type, 1);
5046 unblock_input ();
5047 }
5048
5049 x_make_gc (f);
5050
5051 x_default_parameter (f, parms, Qauto_raise, Qnil,
5052 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
5053 x_default_parameter (f, parms, Qauto_lower, Qnil,
5054 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
5055 x_default_parameter (f, parms, Qcursor_type, Qbox,
5056 "cursorType", "CursorType", RES_TYPE_SYMBOL);
5057
5058 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
5059 Change will not be effected unless different from the current
5060 FRAME_LINES (f). */
5061 width = FRAME_COLS (f);
5062 height = FRAME_LINES (f);
5063 SET_FRAME_COLS (f, 0);
5064 FRAME_LINES (f) = 0;
5065 change_frame_size (f, width, height, 1, 0, 0, 0);
5066
5067 /* Add `tooltip' frame parameter's default value. */
5068 if (NILP (Fframe_parameter (frame, Qtooltip)))
5069 Fmodify_frame_parameters (frame, list1 (Fcons (Qtooltip, Qt)));
5070
5071 /* FIXME - can this be done in a similar way to normal frames?
5072 http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
5073
5074 /* Set the `display-type' frame parameter before setting up faces. */
5075 {
5076 Lisp_Object disptype;
5077
5078 if (FRAME_DISPLAY_INFO (f)->n_planes == 1)
5079 disptype = intern ("mono");
5080 else if (FRAME_DISPLAY_INFO (f)->visual->class == GrayScale
5081 || FRAME_DISPLAY_INFO (f)->visual->class == StaticGray)
5082 disptype = intern ("grayscale");
5083 else
5084 disptype = intern ("color");
5085
5086 if (NILP (Fframe_parameter (frame, Qdisplay_type)))
5087 Fmodify_frame_parameters (frame, list1 (Fcons (Qdisplay_type, disptype)));
5088 }
5089
5090 /* Set up faces after all frame parameters are known. This call
5091 also merges in face attributes specified for new frames.
5092
5093 Frame parameters may be changed if .Xdefaults contains
5094 specifications for the default font. For example, if there is an
5095 `Emacs.default.attributeBackground: pink', the `background-color'
5096 attribute of the frame get's set, which let's the internal border
5097 of the tooltip frame appear in pink. Prevent this. */
5098 {
5099 Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
5100
5101 /* Set tip_frame here, so that */
5102 tip_frame = frame;
5103 call2 (Qface_set_after_frame_default, frame, Qnil);
5104
5105 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
5106 Fmodify_frame_parameters (frame, list1 (Fcons (Qbackground_color, bg)));
5107 }
5108
5109 f->no_split = 1;
5110
5111 UNGCPRO;
5112
5113 /* Now that the frame will be official, it counts as a reference to
5114 its display and terminal. */
5115 FRAME_DISPLAY_INFO (f)->reference_count++;
5116 f->terminal->reference_count++;
5117
5118 /* It is now ok to make the frame official even if we get an error
5119 below. And the frame needs to be on Vframe_list or making it
5120 visible won't work. */
5121 Vframe_list = Fcons (frame, Vframe_list);
5122
5123
5124 /* Setting attributes of faces of the tooltip frame from resources
5125 and similar will increment face_change_count, which leads to the
5126 clearing of all current matrices. Since this isn't necessary
5127 here, avoid it by resetting face_change_count to the value it
5128 had before we created the tip frame. */
5129 face_change_count = face_change_count_before;
5130
5131 /* Discard the unwind_protect. */
5132 return unbind_to (count, frame);
5133 }
5134
5135
5136 /* Compute where to display tip frame F. PARMS is the list of frame
5137 parameters for F. DX and DY are specified offsets from the current
5138 location of the mouse. WIDTH and HEIGHT are the width and height
5139 of the tooltip. Return coordinates relative to the root window of
5140 the display in *ROOT_X, and *ROOT_Y. */
5141
5142 static void
5143 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)
5144 {
5145 Lisp_Object left, top;
5146 int win_x, win_y;
5147 Window root, child;
5148 unsigned pmask;
5149
5150 /* User-specified position? */
5151 left = Fcdr (Fassq (Qleft, parms));
5152 top = Fcdr (Fassq (Qtop, parms));
5153
5154 /* Move the tooltip window where the mouse pointer is. Resize and
5155 show it. */
5156 if (!INTEGERP (left) || !INTEGERP (top))
5157 {
5158 block_input ();
5159 XQueryPointer (FRAME_X_DISPLAY (f), FRAME_DISPLAY_INFO (f)->root_window,
5160 &root, &child, root_x, root_y, &win_x, &win_y, &pmask);
5161 unblock_input ();
5162 }
5163
5164 if (INTEGERP (top))
5165 *root_y = XINT (top);
5166 else if (*root_y + XINT (dy) <= 0)
5167 *root_y = 0; /* Can happen for negative dy */
5168 else if (*root_y + XINT (dy) + height
5169 <= x_display_pixel_height (FRAME_DISPLAY_INFO (f)))
5170 /* It fits below the pointer */
5171 *root_y += XINT (dy);
5172 else if (height + XINT (dy) <= *root_y)
5173 /* It fits above the pointer. */
5174 *root_y -= height + XINT (dy);
5175 else
5176 /* Put it on the top. */
5177 *root_y = 0;
5178
5179 if (INTEGERP (left))
5180 *root_x = XINT (left);
5181 else if (*root_x + XINT (dx) <= 0)
5182 *root_x = 0; /* Can happen for negative dx */
5183 else if (*root_x + XINT (dx) + width
5184 <= x_display_pixel_width (FRAME_DISPLAY_INFO (f)))
5185 /* It fits to the right of the pointer. */
5186 *root_x += XINT (dx);
5187 else if (width + XINT (dx) <= *root_x)
5188 /* It fits to the left of the pointer. */
5189 *root_x -= width + XINT (dx);
5190 else
5191 /* Put it left-justified on the screen--it ought to fit that way. */
5192 *root_x = 0;
5193 }
5194
5195
5196 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
5197 doc: /* Show STRING in a "tooltip" window on frame FRAME.
5198 A tooltip window is a small X window displaying a string.
5199
5200 This is an internal function; Lisp code should call `tooltip-show'.
5201
5202 FRAME nil or omitted means use the selected frame.
5203
5204 PARMS is an optional list of frame parameters which can be used to
5205 change the tooltip's appearance.
5206
5207 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
5208 means use the default timeout of 5 seconds.
5209
5210 If the list of frame parameters PARMS contains a `left' parameters,
5211 the tooltip is displayed at that x-position. Otherwise it is
5212 displayed at the mouse position, with offset DX added (default is 5 if
5213 DX isn't specified). Likewise for the y-position; if a `top' frame
5214 parameter is specified, it determines the y-position of the tooltip
5215 window, otherwise it is displayed at the mouse position, with offset
5216 DY added (default is -10).
5217
5218 A tooltip's maximum size is specified by `x-max-tooltip-size'.
5219 Text larger than the specified size is clipped. */)
5220 (Lisp_Object string, Lisp_Object frame, Lisp_Object parms, Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy)
5221 {
5222 struct frame *f;
5223 struct window *w;
5224 int root_x, root_y;
5225 struct buffer *old_buffer;
5226 struct text_pos pos;
5227 int i, width, height, seen_reversed_p;
5228 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
5229 int old_windows_or_buffers_changed = windows_or_buffers_changed;
5230 ptrdiff_t count = SPECPDL_INDEX ();
5231
5232 specbind (Qinhibit_redisplay, Qt);
5233
5234 GCPRO4 (string, parms, frame, timeout);
5235
5236 CHECK_STRING (string);
5237 if (SCHARS (string) == 0)
5238 string = make_unibyte_string (" ", 1);
5239
5240 f = decode_window_system_frame (frame);
5241 if (NILP (timeout))
5242 timeout = make_number (5);
5243 else
5244 CHECK_NATNUM (timeout);
5245
5246 if (NILP (dx))
5247 dx = make_number (5);
5248 else
5249 CHECK_NUMBER (dx);
5250
5251 if (NILP (dy))
5252 dy = make_number (-10);
5253 else
5254 CHECK_NUMBER (dy);
5255
5256 #ifdef USE_GTK
5257 if (x_gtk_use_system_tooltips)
5258 {
5259 bool ok;
5260
5261 /* Hide a previous tip, if any. */
5262 Fx_hide_tip ();
5263
5264 block_input ();
5265 ok = xg_prepare_tooltip (f, string, &width, &height);
5266 if (ok)
5267 {
5268 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
5269 xg_show_tooltip (f, root_x, root_y);
5270 /* This is used in Fx_hide_tip. */
5271 XSETFRAME (tip_frame, f);
5272 }
5273 unblock_input ();
5274 if (ok) goto start_timer;
5275 }
5276 #endif /* USE_GTK */
5277
5278 if (NILP (last_show_tip_args))
5279 last_show_tip_args = Fmake_vector (make_number (3), Qnil);
5280
5281 if (!NILP (tip_frame))
5282 {
5283 Lisp_Object last_string = AREF (last_show_tip_args, 0);
5284 Lisp_Object last_frame = AREF (last_show_tip_args, 1);
5285 Lisp_Object last_parms = AREF (last_show_tip_args, 2);
5286
5287 if (EQ (frame, last_frame)
5288 && !NILP (Fequal (last_string, string))
5289 && !NILP (Fequal (last_parms, parms)))
5290 {
5291 struct frame *tip_f = XFRAME (tip_frame);
5292
5293 /* Only DX and DY have changed. */
5294 if (!NILP (tip_timer))
5295 {
5296 Lisp_Object timer = tip_timer;
5297 tip_timer = Qnil;
5298 call1 (Qcancel_timer, timer);
5299 }
5300
5301 block_input ();
5302 compute_tip_xy (tip_f, parms, dx, dy, FRAME_PIXEL_WIDTH (tip_f),
5303 FRAME_PIXEL_HEIGHT (tip_f), &root_x, &root_y);
5304 XMoveWindow (FRAME_X_DISPLAY (tip_f), FRAME_X_WINDOW (tip_f),
5305 root_x, root_y);
5306 unblock_input ();
5307 goto start_timer;
5308 }
5309 }
5310
5311 /* Hide a previous tip, if any. */
5312 Fx_hide_tip ();
5313
5314 ASET (last_show_tip_args, 0, string);
5315 ASET (last_show_tip_args, 1, frame);
5316 ASET (last_show_tip_args, 2, parms);
5317
5318 /* Add default values to frame parameters. */
5319 if (NILP (Fassq (Qname, parms)))
5320 parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
5321 if (NILP (Fassq (Qinternal_border_width, parms)))
5322 parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
5323 if (NILP (Fassq (Qborder_width, parms)))
5324 parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
5325 if (NILP (Fassq (Qbottom_divider_width, parms)))
5326 parms = Fcons (Fcons (Qbottom_divider_width, make_number (0)), parms);
5327 if (NILP (Fassq (Qright_divider_width, parms)))
5328 parms = Fcons (Fcons (Qright_divider_width, make_number (0)), parms);
5329 if (NILP (Fassq (Qborder_color, parms)))
5330 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
5331 if (NILP (Fassq (Qbackground_color, parms)))
5332 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
5333 parms);
5334
5335 /* Create a frame for the tooltip, and record it in the global
5336 variable tip_frame. */
5337 frame = x_create_tip_frame (FRAME_DISPLAY_INFO (f), parms, string);
5338 f = XFRAME (frame);
5339
5340 /* Set up the frame's root window. */
5341 w = XWINDOW (FRAME_ROOT_WINDOW (f));
5342 w->left_col = 0;
5343 w->top_line = 0;
5344 w->pixel_left = 0;
5345 w->pixel_top = 0;
5346
5347 if (CONSP (Vx_max_tooltip_size)
5348 && RANGED_INTEGERP (1, XCAR (Vx_max_tooltip_size), INT_MAX)
5349 && RANGED_INTEGERP (1, XCDR (Vx_max_tooltip_size), INT_MAX))
5350 {
5351 w->total_cols = XFASTINT (XCAR (Vx_max_tooltip_size));
5352 w->total_lines = XFASTINT (XCDR (Vx_max_tooltip_size));
5353 }
5354 else
5355 {
5356 w->total_cols = 80;
5357 w->total_lines = 40;
5358 }
5359
5360 w->pixel_width = w->total_cols * FRAME_COLUMN_WIDTH (f);
5361 w->pixel_height = w->total_lines * FRAME_LINE_HEIGHT (f);
5362
5363 FRAME_TOTAL_COLS (f) = w->total_cols;
5364 adjust_frame_glyphs (f);
5365 w->pseudo_window_p = 1;
5366
5367 /* Display the tooltip text in a temporary buffer. */
5368 old_buffer = current_buffer;
5369 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->contents));
5370 bset_truncate_lines (current_buffer, Qnil);
5371 clear_glyph_matrix (w->desired_matrix);
5372 clear_glyph_matrix (w->current_matrix);
5373 SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
5374 try_window (FRAME_ROOT_WINDOW (f), pos, TRY_WINDOW_IGNORE_FONTS_CHANGE);
5375
5376 /* Compute width and height of the tooltip. */
5377 width = height = seen_reversed_p = 0;
5378 for (i = 0; i < w->desired_matrix->nrows; ++i)
5379 {
5380 struct glyph_row *row = &w->desired_matrix->rows[i];
5381 struct glyph *last;
5382 int row_width;
5383
5384 /* Stop at the first empty row at the end. */
5385 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
5386 break;
5387
5388 /* Let the row go over the full width of the frame. */
5389 row->full_width_p = 1;
5390
5391 row_width = row->pixel_width;
5392 if (row->used[TEXT_AREA])
5393 {
5394 /* There's a glyph at the end of rows that is used to place
5395 the cursor there. Don't include the width of this glyph. */
5396 if (!row->reversed_p)
5397 {
5398 last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
5399 if (INTEGERP (last->object))
5400 row_width -= last->pixel_width;
5401 }
5402 else
5403 {
5404 /* There could be a stretch glyph at the beginning of R2L
5405 rows that is produced by extend_face_to_end_of_line.
5406 Don't count that glyph. */
5407 struct glyph *g = row->glyphs[TEXT_AREA];
5408
5409 if (g->type == STRETCH_GLYPH && INTEGERP (g->object))
5410 {
5411 row_width -= g->pixel_width;
5412 seen_reversed_p = 1;
5413 }
5414 }
5415 }
5416
5417 height += row->height;
5418 width = max (width, row_width);
5419 }
5420
5421 /* If we've seen partial-length R2L rows, we need to re-adjust the
5422 tool-tip frame width and redisplay it again, to avoid over-wide
5423 tips due to the stretch glyph that extends R2L lines to full
5424 width of the frame. */
5425 if (seen_reversed_p)
5426 {
5427 /* w->total_cols and FRAME_TOTAL_COLS want the width in columns,
5428 not in pixels. */
5429 w->pixel_width = width;
5430 width /= WINDOW_FRAME_COLUMN_WIDTH (w);
5431 w->total_cols = width;
5432 FRAME_TOTAL_COLS (f) = width;
5433 SET_FRAME_WIDTH (f, width);
5434 adjust_frame_glyphs (f);
5435 clear_glyph_matrix (w->desired_matrix);
5436 clear_glyph_matrix (w->current_matrix);
5437 try_window (FRAME_ROOT_WINDOW (f), pos, 0);
5438 width = height = 0;
5439 /* Recompute width and height of the tooltip. */
5440 for (i = 0; i < w->desired_matrix->nrows; ++i)
5441 {
5442 struct glyph_row *row = &w->desired_matrix->rows[i];
5443 struct glyph *last;
5444 int row_width;
5445
5446 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
5447 break;
5448 row->full_width_p = 1;
5449 row_width = row->pixel_width;
5450 if (row->used[TEXT_AREA] && !row->reversed_p)
5451 {
5452 last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
5453 if (INTEGERP (last->object))
5454 row_width -= last->pixel_width;
5455 }
5456
5457 height += row->height;
5458 width = max (width, row_width);
5459 }
5460 }
5461
5462 /* Add the frame's internal border to the width and height the X
5463 window should have. */
5464 height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5465 width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5466
5467 /* Move the tooltip window where the mouse pointer is. Resize and
5468 show it. */
5469 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
5470
5471 block_input ();
5472 XMoveResizeWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5473 root_x, root_y, width, height);
5474 XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
5475 unblock_input ();
5476
5477 /* Draw into the window. */
5478 w->must_be_updated_p = 1;
5479 update_single_window (w, 1);
5480
5481 /* Restore original current buffer. */
5482 set_buffer_internal_1 (old_buffer);
5483 windows_or_buffers_changed = old_windows_or_buffers_changed;
5484
5485 start_timer:
5486 /* Let the tip disappear after timeout seconds. */
5487 tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
5488 intern ("x-hide-tip"));
5489
5490 UNGCPRO;
5491 return unbind_to (count, Qnil);
5492 }
5493
5494
5495 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
5496 doc: /* Hide the current tooltip window, if there is any.
5497 Value is t if tooltip was open, nil otherwise. */)
5498 (void)
5499 {
5500 ptrdiff_t count;
5501 Lisp_Object deleted, frame, timer;
5502 struct gcpro gcpro1, gcpro2;
5503
5504 /* Return quickly if nothing to do. */
5505 if (NILP (tip_timer) && NILP (tip_frame))
5506 return Qnil;
5507
5508 frame = tip_frame;
5509 timer = tip_timer;
5510 GCPRO2 (frame, timer);
5511 tip_frame = tip_timer = deleted = Qnil;
5512
5513 count = SPECPDL_INDEX ();
5514 specbind (Qinhibit_redisplay, Qt);
5515 specbind (Qinhibit_quit, Qt);
5516
5517 if (!NILP (timer))
5518 call1 (Qcancel_timer, timer);
5519
5520 #ifdef USE_GTK
5521 {
5522 /* When using system tooltip, tip_frame is the Emacs frame on which
5523 the tip is shown. */
5524 struct frame *f = XFRAME (frame);
5525 if (FRAME_LIVE_P (f) && xg_hide_tooltip (f))
5526 frame = Qnil;
5527 }
5528 #endif
5529
5530 if (FRAMEP (frame))
5531 {
5532 delete_frame (frame, Qnil);
5533 deleted = Qt;
5534
5535 #ifdef USE_LUCID
5536 /* Bloodcurdling hack alert: The Lucid menu bar widget's
5537 redisplay procedure is not called when a tip frame over menu
5538 items is unmapped. Redisplay the menu manually... */
5539 {
5540 Widget w;
5541 struct frame *f = SELECTED_FRAME ();
5542 w = f->output_data.x->menubar_widget;
5543
5544 if (!DoesSaveUnders (FRAME_DISPLAY_INFO (f)->screen)
5545 && w != NULL)
5546 {
5547 block_input ();
5548 xlwmenu_redisplay (w);
5549 unblock_input ();
5550 }
5551 }
5552 #endif /* USE_LUCID */
5553 }
5554
5555 UNGCPRO;
5556 return unbind_to (count, deleted);
5557 }
5558
5559
5560 \f
5561 /***********************************************************************
5562 File selection dialog
5563 ***********************************************************************/
5564
5565 DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog,
5566 Sx_uses_old_gtk_dialog,
5567 0, 0, 0,
5568 doc: /* Return t if the old Gtk+ file selection dialog is used. */)
5569 (void)
5570 {
5571 #ifdef USE_GTK
5572 if (use_dialog_box
5573 && use_file_dialog
5574 && window_system_available (SELECTED_FRAME ())
5575 && xg_uses_old_file_dialog ())
5576 return Qt;
5577 #endif
5578 return Qnil;
5579 }
5580
5581
5582 #ifdef USE_MOTIF
5583 /* Callback for "OK" and "Cancel" on file selection dialog. */
5584
5585 static void
5586 file_dialog_cb (Widget widget, XtPointer client_data, XtPointer call_data)
5587 {
5588 int *result = client_data;
5589 XmAnyCallbackStruct *cb = call_data;
5590 *result = cb->reason;
5591 }
5592
5593
5594 /* Callback for unmapping a file selection dialog. This is used to
5595 capture the case where a dialog is closed via a window manager's
5596 closer button, for example. Using a XmNdestroyCallback didn't work
5597 in this case. */
5598
5599 static void
5600 file_dialog_unmap_cb (Widget widget, XtPointer client_data, XtPointer call_data)
5601 {
5602 int *result = client_data;
5603 *result = XmCR_CANCEL;
5604 }
5605
5606 static void
5607 clean_up_file_dialog (void *arg)
5608 {
5609 Widget dialog = arg;
5610
5611 /* Clean up. */
5612 block_input ();
5613 XtUnmanageChild (dialog);
5614 XtDestroyWidget (dialog);
5615 x_menu_set_in_use (0);
5616 unblock_input ();
5617 }
5618
5619
5620 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5621 doc: /* Read file name, prompting with PROMPT in directory DIR.
5622 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5623 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5624 or directory must exist.
5625
5626 This function is only defined on NS, MS Windows, and X Windows with the
5627 Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
5628 Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */)
5629 (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename,
5630 Lisp_Object mustmatch, Lisp_Object only_dir_p)
5631 {
5632 int result;
5633 struct frame *f = SELECTED_FRAME ();
5634 Lisp_Object file = Qnil;
5635 Lisp_Object decoded_file;
5636 Widget dialog, text, help;
5637 Arg al[10];
5638 int ac = 0;
5639 XmString dir_xmstring, pattern_xmstring;
5640 ptrdiff_t count = SPECPDL_INDEX ();
5641 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5642
5643 check_window_system (f);
5644
5645 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5646
5647 if (popup_activated ())
5648 error ("Trying to use a menu from within a menu-entry");
5649
5650 CHECK_STRING (prompt);
5651 CHECK_STRING (dir);
5652
5653 /* Prevent redisplay. */
5654 specbind (Qinhibit_redisplay, Qt);
5655
5656 block_input ();
5657
5658 /* Create the dialog with PROMPT as title, using DIR as initial
5659 directory and using "*" as pattern. */
5660 dir = Fexpand_file_name (dir, Qnil);
5661 dir_xmstring = XmStringCreateLocalized (SSDATA (dir));
5662 pattern_xmstring = XmStringCreateLocalized ("*");
5663
5664 XtSetArg (al[ac], XmNtitle, SDATA (prompt)); ++ac;
5665 XtSetArg (al[ac], XmNdirectory, dir_xmstring); ++ac;
5666 XtSetArg (al[ac], XmNpattern, pattern_xmstring); ++ac;
5667 XtSetArg (al[ac], XmNresizePolicy, XmRESIZE_GROW); ++ac;
5668 XtSetArg (al[ac], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); ++ac;
5669 dialog = XmCreateFileSelectionDialog (f->output_data.x->widget,
5670 "fsb", al, ac);
5671 XmStringFree (dir_xmstring);
5672 XmStringFree (pattern_xmstring);
5673
5674 /* Add callbacks for OK and Cancel. */
5675 XtAddCallback (dialog, XmNokCallback, file_dialog_cb,
5676 (XtPointer) &result);
5677 XtAddCallback (dialog, XmNcancelCallback, file_dialog_cb,
5678 (XtPointer) &result);
5679 XtAddCallback (dialog, XmNunmapCallback, file_dialog_unmap_cb,
5680 (XtPointer) &result);
5681
5682 /* Remove the help button since we can't display help. */
5683 help = XmFileSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON);
5684 XtUnmanageChild (help);
5685
5686 /* Mark OK button as default. */
5687 XtVaSetValues (XmFileSelectionBoxGetChild (dialog, XmDIALOG_OK_BUTTON),
5688 XmNshowAsDefault, True, NULL);
5689
5690 /* If MUSTMATCH is non-nil, disable the file entry field of the
5691 dialog, so that the user must select a file from the files list
5692 box. We can't remove it because we wouldn't have a way to get at
5693 the result file name, then. */
5694 text = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5695 if (!NILP (mustmatch))
5696 {
5697 Widget label;
5698 label = XmFileSelectionBoxGetChild (dialog, XmDIALOG_SELECTION_LABEL);
5699 XtSetSensitive (text, False);
5700 XtSetSensitive (label, False);
5701 }
5702
5703 /* Manage the dialog, so that list boxes get filled. */
5704 XtManageChild (dialog);
5705
5706 if (STRINGP (default_filename))
5707 {
5708 XmString default_xmstring;
5709 Widget wtext = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5710 Widget list = XmFileSelectionBoxGetChild (dialog, XmDIALOG_LIST);
5711
5712 XmTextPosition last_pos = XmTextFieldGetLastPosition (wtext);
5713 XmTextFieldReplace (wtext, 0, last_pos,
5714 (SSDATA (Ffile_name_nondirectory (default_filename))));
5715
5716 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
5717 must include the path for this to work. */
5718
5719 default_xmstring = XmStringCreateLocalized (SSDATA (default_filename));
5720
5721 if (XmListItemExists (list, default_xmstring))
5722 {
5723 int item_pos = XmListItemPos (list, default_xmstring);
5724 /* Select the item and scroll it into view. */
5725 XmListSelectPos (list, item_pos, True);
5726 XmListSetPos (list, item_pos);
5727 }
5728
5729 XmStringFree (default_xmstring);
5730 }
5731
5732 record_unwind_protect_ptr (clean_up_file_dialog, dialog);
5733
5734 /* Process events until the user presses Cancel or OK. */
5735 x_menu_set_in_use (1);
5736 result = 0;
5737 while (result == 0)
5738 {
5739 XEvent event;
5740 x_menu_wait_for_event (0);
5741 XtAppNextEvent (Xt_app_con, &event);
5742 if (event.type == KeyPress
5743 && FRAME_X_DISPLAY (f) == event.xkey.display)
5744 {
5745 KeySym keysym = XLookupKeysym (&event.xkey, 0);
5746
5747 /* Pop down on C-g. */
5748 if (keysym == XK_g && (event.xkey.state & ControlMask) != 0)
5749 XtUnmanageChild (dialog);
5750 }
5751
5752 (void) x_dispatch_event (&event, FRAME_X_DISPLAY (f));
5753 }
5754
5755 /* Get the result. */
5756 if (result == XmCR_OK)
5757 {
5758 XmString text_string;
5759 String data;
5760
5761 XtVaGetValues (dialog, XmNtextString, &text_string, NULL);
5762 XmStringGetLtoR (text_string, XmFONTLIST_DEFAULT_TAG, &data);
5763 XmStringFree (text_string);
5764 file = build_string (data);
5765 XtFree (data);
5766 }
5767 else
5768 file = Qnil;
5769
5770 unblock_input ();
5771 UNGCPRO;
5772
5773 /* Make "Cancel" equivalent to C-g. */
5774 if (NILP (file))
5775 Fsignal (Qquit, Qnil);
5776
5777 decoded_file = DECODE_FILE (file);
5778
5779 return unbind_to (count, decoded_file);
5780 }
5781
5782 #endif /* USE_MOTIF */
5783
5784 #ifdef USE_GTK
5785
5786 static void
5787 clean_up_dialog (void)
5788 {
5789 x_menu_set_in_use (0);
5790 }
5791
5792 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5793 doc: /* Read file name, prompting with PROMPT in directory DIR.
5794 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5795 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5796 or directory must exist.
5797
5798 This function is only defined on NS, MS Windows, and X Windows with the
5799 Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
5800 Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */)
5801 (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p)
5802 {
5803 struct frame *f = SELECTED_FRAME ();
5804 char *fn;
5805 Lisp_Object file = Qnil;
5806 Lisp_Object decoded_file;
5807 ptrdiff_t count = SPECPDL_INDEX ();
5808 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5809 char *cdef_file;
5810
5811 check_window_system (f);
5812
5813 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5814
5815 if (popup_activated ())
5816 error ("Trying to use a menu from within a menu-entry");
5817
5818 CHECK_STRING (prompt);
5819 CHECK_STRING (dir);
5820
5821 /* Prevent redisplay. */
5822 specbind (Qinhibit_redisplay, Qt);
5823 record_unwind_protect_void (clean_up_dialog);
5824
5825 block_input ();
5826
5827 if (STRINGP (default_filename))
5828 cdef_file = SSDATA (default_filename);
5829 else
5830 cdef_file = SSDATA (dir);
5831
5832 fn = xg_get_file_name (f, SSDATA (prompt), cdef_file,
5833 ! NILP (mustmatch),
5834 ! NILP (only_dir_p));
5835
5836 if (fn)
5837 {
5838 file = build_string (fn);
5839 xfree (fn);
5840 }
5841
5842 unblock_input ();
5843 UNGCPRO;
5844
5845 /* Make "Cancel" equivalent to C-g. */
5846 if (NILP (file))
5847 Fsignal (Qquit, Qnil);
5848
5849 decoded_file = DECODE_FILE (file);
5850
5851 return unbind_to (count, decoded_file);
5852 }
5853
5854
5855 #ifdef HAVE_FREETYPE
5856
5857 DEFUN ("x-select-font", Fx_select_font, Sx_select_font, 0, 2, 0,
5858 doc: /* Read a font using a GTK dialog.
5859 Return either a font spec (for GTK versions >= 3.2) or a string
5860 containing a GTK-style font name.
5861
5862 FRAME is the frame on which to pop up the font chooser. If omitted or
5863 nil, it defaults to the selected frame. */)
5864 (Lisp_Object frame, Lisp_Object ignored)
5865 {
5866 struct frame *f = decode_window_system_frame (frame);
5867 Lisp_Object font;
5868 Lisp_Object font_param;
5869 char *default_name = NULL;
5870 struct gcpro gcpro1, gcpro2;
5871 ptrdiff_t count = SPECPDL_INDEX ();
5872
5873 if (popup_activated ())
5874 error ("Trying to use a menu from within a menu-entry");
5875
5876 /* Prevent redisplay. */
5877 specbind (Qinhibit_redisplay, Qt);
5878 record_unwind_protect_void (clean_up_dialog);
5879
5880 block_input ();
5881
5882 GCPRO2 (font_param, font);
5883
5884 XSETFONT (font, FRAME_FONT (f));
5885 font_param = Ffont_get (font, intern (":name"));
5886 if (STRINGP (font_param))
5887 default_name = xstrdup (SSDATA (font_param));
5888 else
5889 {
5890 font_param = Fframe_parameter (frame, Qfont_param);
5891 if (STRINGP (font_param))
5892 default_name = xstrdup (SSDATA (font_param));
5893 }
5894
5895 font = xg_get_font (f, default_name);
5896 xfree (default_name);
5897
5898 unblock_input ();
5899
5900 if (NILP (font))
5901 Fsignal (Qquit, Qnil);
5902
5903 return unbind_to (count, font);
5904 }
5905 #endif /* HAVE_FREETYPE */
5906
5907 #endif /* USE_GTK */
5908
5909 \f
5910 /***********************************************************************
5911 Keyboard
5912 ***********************************************************************/
5913
5914 #ifdef HAVE_XKB
5915 #include <X11/XKBlib.h>
5916 #include <X11/keysym.h>
5917 #endif
5918
5919 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p,
5920 Sx_backspace_delete_keys_p, 0, 1, 0,
5921 doc: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
5922 FRAME nil means use the selected frame.
5923 Value is t if we know that both keys are present, and are mapped to the
5924 usual X keysyms. Value is `lambda' if we cannot determine if both keys are
5925 present and mapped to the usual X keysyms. */)
5926 (Lisp_Object frame)
5927 {
5928 #ifndef HAVE_XKB
5929 return Qlambda;
5930 #else
5931 XkbDescPtr kb;
5932 struct frame *f = decode_window_system_frame (frame);
5933 Display *dpy = FRAME_X_DISPLAY (f);
5934 Lisp_Object have_keys;
5935 int major, minor, op, event, error_code;
5936
5937 block_input ();
5938
5939 /* Check library version in case we're dynamically linked. */
5940 major = XkbMajorVersion;
5941 minor = XkbMinorVersion;
5942 if (!XkbLibraryVersion (&major, &minor))
5943 {
5944 unblock_input ();
5945 return Qlambda;
5946 }
5947
5948 /* Check that the server supports XKB. */
5949 major = XkbMajorVersion;
5950 minor = XkbMinorVersion;
5951 if (!XkbQueryExtension (dpy, &op, &event, &error_code, &major, &minor))
5952 {
5953 unblock_input ();
5954 return Qlambda;
5955 }
5956
5957 /* In this code we check that the keyboard has physical keys with names
5958 that start with BKSP (Backspace) and DELE (Delete), and that they
5959 generate keysym XK_BackSpace and XK_Delete respectively.
5960 This function is used to test if normal-erase-is-backspace should be
5961 turned on.
5962 An alternative approach would be to just check if XK_BackSpace and
5963 XK_Delete are mapped to any key. But if any of those are mapped to
5964 some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the
5965 user doesn't know about it, it is better to return false here.
5966 It is more obvious to the user what to do if she/he has two keys
5967 clearly marked with names/symbols and one key does something not
5968 expected (i.e. she/he then tries the other).
5969 The cases where Backspace/Delete is mapped to some other key combination
5970 are rare, and in those cases, normal-erase-is-backspace can be turned on
5971 manually. */
5972
5973 have_keys = Qnil;
5974 kb = XkbGetMap (dpy, XkbAllMapComponentsMask, XkbUseCoreKbd);
5975 if (kb)
5976 {
5977 int delete_keycode = 0, backspace_keycode = 0, i;
5978
5979 if (XkbGetNames (dpy, XkbAllNamesMask, kb) == Success)
5980 {
5981 for (i = kb->min_key_code;
5982 (i < kb->max_key_code
5983 && (delete_keycode == 0 || backspace_keycode == 0));
5984 ++i)
5985 {
5986 /* The XKB symbolic key names can be seen most easily in
5987 the PS file generated by `xkbprint -label name
5988 $DISPLAY'. */
5989 if (memcmp ("DELE", kb->names->keys[i].name, 4) == 0)
5990 delete_keycode = i;
5991 else if (memcmp ("BKSP", kb->names->keys[i].name, 4) == 0)
5992 backspace_keycode = i;
5993 }
5994
5995 XkbFreeNames (kb, 0, True);
5996 }
5997
5998 XkbFreeClientMap (kb, 0, True);
5999
6000 if (delete_keycode
6001 && backspace_keycode
6002 && XKeysymToKeycode (dpy, XK_Delete) == delete_keycode
6003 && XKeysymToKeycode (dpy, XK_BackSpace) == backspace_keycode)
6004 have_keys = Qt;
6005 }
6006 unblock_input ();
6007 return have_keys;
6008 #endif
6009 }
6010
6011
6012 \f
6013 /***********************************************************************
6014 Initialization
6015 ***********************************************************************/
6016
6017 /* Keep this list in the same order as frame_parms in frame.c.
6018 Use 0 for unsupported frame parameters. */
6019
6020 frame_parm_handler x_frame_parm_handlers[] =
6021 {
6022 x_set_autoraise,
6023 x_set_autolower,
6024 x_set_background_color,
6025 x_set_border_color,
6026 x_set_border_width,
6027 x_set_cursor_color,
6028 x_set_cursor_type,
6029 x_set_font,
6030 x_set_foreground_color,
6031 x_set_icon_name,
6032 x_set_icon_type,
6033 x_set_internal_border_width,
6034 x_set_right_divider_width,
6035 x_set_bottom_divider_width,
6036 x_set_menu_bar_lines,
6037 x_set_mouse_color,
6038 x_explicitly_set_name,
6039 x_set_scroll_bar_width,
6040 x_set_title,
6041 x_set_unsplittable,
6042 x_set_vertical_scroll_bars,
6043 x_set_visibility,
6044 x_set_tool_bar_lines,
6045 x_set_scroll_bar_foreground,
6046 x_set_scroll_bar_background,
6047 x_set_screen_gamma,
6048 x_set_line_spacing,
6049 x_set_fringe_width,
6050 x_set_fringe_width,
6051 x_set_wait_for_wm,
6052 x_set_fullscreen,
6053 x_set_font_backend,
6054 x_set_alpha,
6055 x_set_sticky,
6056 x_set_tool_bar_position,
6057 };
6058
6059 void
6060 syms_of_xfns (void)
6061 {
6062 /* The section below is built by the lisp expression at the top of the file,
6063 just above where these variables are declared. */
6064 /*&&& init symbols here &&&*/
6065 DEFSYM (Qsuppress_icon, "suppress-icon");
6066 DEFSYM (Qundefined_color, "undefined-color");
6067 DEFSYM (Qcompound_text, "compound-text");
6068 DEFSYM (Qcancel_timer, "cancel-timer");
6069 DEFSYM (Qfont_param, "font-parameter");
6070 /* This is the end of symbol initialization. */
6071
6072 Fput (Qundefined_color, Qerror_conditions,
6073 listn (CONSTYPE_PURE, 2, Qundefined_color, Qerror));
6074 Fput (Qundefined_color, Qerror_message,
6075 build_pure_c_string ("Undefined color"));
6076
6077 DEFVAR_LISP ("x-pointer-shape", Vx_pointer_shape,
6078 doc: /* The shape of the pointer when over text.
6079 Changing the value does not affect existing frames
6080 unless you set the mouse color. */);
6081 Vx_pointer_shape = Qnil;
6082
6083 #if 0 /* This doesn't really do anything. */
6084 DEFVAR_LISP ("x-nontext-pointer-shape", Vx_nontext_pointer_shape,
6085 doc: /* The shape of the pointer when not over text.
6086 This variable takes effect when you create a new frame
6087 or when you set the mouse color. */);
6088 #endif
6089 Vx_nontext_pointer_shape = Qnil;
6090
6091 DEFVAR_LISP ("x-hourglass-pointer-shape", Vx_hourglass_pointer_shape,
6092 doc: /* The shape of the pointer when Emacs is busy.
6093 This variable takes effect when you create a new frame
6094 or when you set the mouse color. */);
6095 Vx_hourglass_pointer_shape = Qnil;
6096
6097 #if 0 /* This doesn't really do anything. */
6098 DEFVAR_LISP ("x-mode-pointer-shape", Vx_mode_pointer_shape,
6099 doc: /* The shape of the pointer when over the mode line.
6100 This variable takes effect when you create a new frame
6101 or when you set the mouse color. */);
6102 #endif
6103 Vx_mode_pointer_shape = Qnil;
6104
6105 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
6106 Vx_sensitive_text_pointer_shape,
6107 doc: /* The shape of the pointer when over mouse-sensitive text.
6108 This variable takes effect when you create a new frame
6109 or when you set the mouse color. */);
6110 Vx_sensitive_text_pointer_shape = Qnil;
6111
6112 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
6113 Vx_window_horizontal_drag_shape,
6114 doc: /* Pointer shape to use for indicating a window can be dragged horizontally.
6115 This variable takes effect when you create a new frame
6116 or when you set the mouse color. */);
6117 Vx_window_horizontal_drag_shape = Qnil;
6118
6119 DEFVAR_LISP ("x-window-vertical-drag-cursor",
6120 Vx_window_vertical_drag_shape,
6121 doc: /* Pointer shape to use for indicating a window can be dragged vertically.
6122 This variable takes effect when you create a new frame
6123 or when you set the mouse color. */);
6124 Vx_window_vertical_drag_shape = Qnil;
6125
6126 DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel,
6127 doc: /* A string indicating the foreground color of the cursor box. */);
6128 Vx_cursor_fore_pixel = Qnil;
6129
6130 DEFVAR_LISP ("x-max-tooltip-size", Vx_max_tooltip_size,
6131 doc: /* Maximum size for tooltips.
6132 Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */);
6133 Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
6134
6135 DEFVAR_LISP ("x-no-window-manager", Vx_no_window_manager,
6136 doc: /* Non-nil if no X window manager is in use.
6137 Emacs doesn't try to figure this out; this is always nil
6138 unless you set it to something else. */);
6139 /* We don't have any way to find this out, so set it to nil
6140 and maybe the user would like to set it to t. */
6141 Vx_no_window_manager = Qnil;
6142
6143 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
6144 Vx_pixel_size_width_font_regexp,
6145 doc: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
6146
6147 Since Emacs gets width of a font matching with this regexp from
6148 PIXEL_SIZE field of the name, font finding mechanism gets faster for
6149 such a font. This is especially effective for such large fonts as
6150 Chinese, Japanese, and Korean. */);
6151 Vx_pixel_size_width_font_regexp = Qnil;
6152
6153 /* This is not ifdef:ed, so other builds than GTK can customize it. */
6154 DEFVAR_BOOL ("x-gtk-use-old-file-dialog", x_gtk_use_old_file_dialog,
6155 doc: /* Non-nil means prompt with the old GTK file selection dialog.
6156 If nil or if the file selection dialog is not available, the new GTK file
6157 chooser is used instead. To turn off all file dialogs set the
6158 variable `use-file-dialog'. */);
6159 x_gtk_use_old_file_dialog = 0;
6160
6161 DEFVAR_BOOL ("x-gtk-show-hidden-files", x_gtk_show_hidden_files,
6162 doc: /* If non-nil, the GTK file chooser will by default show hidden files.
6163 Note that this is just the default, there is a toggle button on the file
6164 chooser to show or not show hidden files on a case by case basis. */);
6165 x_gtk_show_hidden_files = 0;
6166
6167 DEFVAR_BOOL ("x-gtk-file-dialog-help-text", x_gtk_file_dialog_help_text,
6168 doc: /* If non-nil, the GTK file chooser will show additional help text.
6169 If more space for files in the file chooser dialog is wanted, set this to nil
6170 to turn the additional text off. */);
6171 x_gtk_file_dialog_help_text = 1;
6172
6173 DEFVAR_BOOL ("x-gtk-whole-detached-tool-bar", x_gtk_whole_detached_tool_bar,
6174 doc: /* If non-nil, a detached tool bar is shown in full.
6175 The default is to just show an arrow and pressing on that arrow shows
6176 the tool bar buttons. */);
6177 x_gtk_whole_detached_tool_bar = 0;
6178
6179 DEFVAR_BOOL ("x-gtk-use-system-tooltips", x_gtk_use_system_tooltips,
6180 doc: /* If non-nil with a Gtk+ built Emacs, the Gtk+ tooltip is used.
6181 Otherwise use Emacs own tooltip implementation.
6182 When using Gtk+ tooltips, the tooltip face is not used. */);
6183 x_gtk_use_system_tooltips = 1;
6184
6185 /* Tell Emacs about this window system. */
6186 Fprovide (Qx, Qnil);
6187
6188 #ifdef USE_X_TOOLKIT
6189 Fprovide (intern_c_string ("x-toolkit"), Qnil);
6190 #ifdef USE_MOTIF
6191 Fprovide (intern_c_string ("motif"), Qnil);
6192
6193 DEFVAR_LISP ("motif-version-string", Vmotif_version_string,
6194 doc: /* Version info for LessTif/Motif. */);
6195 Vmotif_version_string = build_string (XmVERSION_STRING);
6196 #endif /* USE_MOTIF */
6197 #endif /* USE_X_TOOLKIT */
6198
6199 #ifdef USE_GTK
6200 /* Provide x-toolkit also for GTK. Internally GTK does not use Xt so it
6201 is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
6202 But for a user it is a toolkit for X, and indeed, configure
6203 accepts --with-x-toolkit=gtk. */
6204 Fprovide (intern_c_string ("x-toolkit"), Qnil);
6205 Fprovide (intern_c_string ("gtk"), Qnil);
6206 Fprovide (intern_c_string ("move-toolbar"), Qnil);
6207
6208 DEFVAR_LISP ("gtk-version-string", Vgtk_version_string,
6209 doc: /* Version info for GTK+. */);
6210 {
6211 char gtk_version[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
6212 int len = sprintf (gtk_version, "%d.%d.%d",
6213 GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
6214 Vgtk_version_string = make_pure_string (gtk_version, len, len, 0);
6215 }
6216 #endif /* USE_GTK */
6217
6218 /* X window properties. */
6219 defsubr (&Sx_change_window_property);
6220 defsubr (&Sx_delete_window_property);
6221 defsubr (&Sx_window_property);
6222
6223 defsubr (&Sxw_display_color_p);
6224 defsubr (&Sx_display_grayscale_p);
6225 defsubr (&Sxw_color_defined_p);
6226 defsubr (&Sxw_color_values);
6227 defsubr (&Sx_server_max_request_size);
6228 defsubr (&Sx_server_vendor);
6229 defsubr (&Sx_server_version);
6230 defsubr (&Sx_display_pixel_width);
6231 defsubr (&Sx_display_pixel_height);
6232 defsubr (&Sx_display_mm_width);
6233 defsubr (&Sx_display_mm_height);
6234 defsubr (&Sx_display_screens);
6235 defsubr (&Sx_display_planes);
6236 defsubr (&Sx_display_color_cells);
6237 defsubr (&Sx_display_visual_class);
6238 defsubr (&Sx_display_backing_store);
6239 defsubr (&Sx_display_save_under);
6240 defsubr (&Sx_display_monitor_attributes_list);
6241 defsubr (&Sx_wm_set_size_hint);
6242 defsubr (&Sx_create_frame);
6243 defsubr (&Sx_open_connection);
6244 defsubr (&Sx_close_connection);
6245 defsubr (&Sx_display_list);
6246 defsubr (&Sx_synchronize);
6247 defsubr (&Sx_backspace_delete_keys_p);
6248
6249 defsubr (&Sx_show_tip);
6250 defsubr (&Sx_hide_tip);
6251 tip_timer = Qnil;
6252 staticpro (&tip_timer);
6253 tip_frame = Qnil;
6254 staticpro (&tip_frame);
6255
6256 last_show_tip_args = Qnil;
6257 staticpro (&last_show_tip_args);
6258
6259 defsubr (&Sx_uses_old_gtk_dialog);
6260 #if defined (USE_MOTIF) || defined (USE_GTK)
6261 defsubr (&Sx_file_dialog);
6262 #endif
6263
6264 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
6265 defsubr (&Sx_select_font);
6266 #endif
6267 }