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