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