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