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