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