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