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