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