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