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