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