(Button Types): For define-button-type, clarify type of NAME.
[emacs.git] / src / xfns.c
blob0bce9eb68c3366f945e122ecb4214d4210c905df
1 /* Functions for the X window system.
2 Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
4 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
23 #include <config.h>
24 #include <stdio.h>
25 #include <math.h>
27 #ifdef HAVE_UNISTD_H
28 #include <unistd.h>
29 #endif
31 /* This makes the fields of a Display accessible, in Xlib header files. */
33 #define XLIB_ILLEGAL_ACCESS
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 #include "termchar.h"
53 #ifdef HAVE_X_WINDOWS
55 #include <ctype.h>
56 #include <sys/types.h>
57 #include <sys/stat.h>
59 #ifndef VMS
60 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */
61 #include "bitmaps/gray.xbm"
62 #else
63 #include <X11/bitmaps/gray>
64 #endif
65 #else
66 #include "[.bitmaps]gray.xbm"
67 #endif
69 #ifdef USE_GTK
70 #include "gtkutil.h"
71 #endif
73 #ifdef USE_X_TOOLKIT
74 #include <X11/Shell.h>
76 #ifndef USE_MOTIF
77 #ifdef HAVE_XAW3D
78 #include <X11/Xaw3d/Paned.h>
79 #include <X11/Xaw3d/Label.h>
80 #else /* !HAVE_XAW3D */
81 #include <X11/Xaw/Paned.h>
82 #include <X11/Xaw/Label.h>
83 #endif /* HAVE_XAW3D */
84 #endif /* USE_MOTIF */
86 #ifdef USG
87 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
88 #include <X11/Xos.h>
89 #define USG
90 #else
91 #include <X11/Xos.h>
92 #endif
94 #include "widget.h"
96 #include "../lwlib/lwlib.h"
98 #ifdef USE_MOTIF
99 #include <Xm/Xm.h>
100 #include <Xm/DialogS.h>
101 #include <Xm/FileSB.h>
102 #endif
104 /* Do the EDITRES protocol if running X11R5
105 Exception: HP-UX (at least version A.09.05) has X11R5 without EditRes */
107 #if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES)
108 #define HACK_EDITRES
109 extern void _XEditResCheckMessages ();
110 #endif /* R5 + Athena */
112 /* Unique id counter for widgets created by the Lucid Widget Library. */
114 extern LWLIB_ID widget_id_tick;
116 #ifdef USE_LUCID
117 /* This is part of a kludge--see lwlib/xlwmenu.c. */
118 extern XFontStruct *xlwmenu_default_font;
119 #endif
121 extern void free_frame_menubar ();
122 extern double atof ();
124 #ifdef USE_MOTIF
126 /* LessTif/Motif version info. */
128 static Lisp_Object Vmotif_version_string;
130 #endif /* USE_MOTIF */
132 #endif /* USE_X_TOOLKIT */
134 #ifdef USE_GTK
136 /* GTK+ version info */
138 static Lisp_Object Vgtk_version_string;
140 #endif /* USE_GTK */
142 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
144 /* The gray bitmap `bitmaps/gray'. This is done because xterm.c uses
145 it, and including `bitmaps/gray' more than once is a problem when
146 config.h defines `static' as an empty replacement string. */
148 int gray_bitmap_width = gray_width;
149 int gray_bitmap_height = gray_height;
150 char *gray_bitmap_bits = gray_bits;
152 /* Non-zero means we're allowed to display an hourglass cursor. */
154 int display_hourglass_p;
156 /* Non-zero means prompt with the old GTK file selection dialog. */
158 int x_gtk_use_old_file_dialog;
160 /* If non-zero, by default show hidden files in the GTK file chooser. */
162 int x_gtk_show_hidden_files;
164 /* If non-zero, don't show additional help text in the GTK file chooser. */
166 int x_gtk_file_dialog_help_text;
168 /* If non-zero, don't collapse to tool bar when it is detached. */
170 int x_gtk_whole_detached_tool_bar;
172 /* The background and shape of the mouse pointer, and shape when not
173 over text or in the modeline. */
175 Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
176 Lisp_Object Vx_hourglass_pointer_shape;
178 /* The shape when over mouse-sensitive text. */
180 Lisp_Object Vx_sensitive_text_pointer_shape;
182 /* If non-nil, the pointer shape to indicate that windows can be
183 dragged horizontally. */
185 Lisp_Object Vx_window_horizontal_drag_shape;
187 /* Color of chars displayed in cursor box. */
189 Lisp_Object Vx_cursor_fore_pixel;
191 /* Nonzero if using X. */
193 static int x_in_use;
195 /* Non nil if no window manager is in use. */
197 Lisp_Object Vx_no_window_manager;
199 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
201 Lisp_Object Vx_pixel_size_width_font_regexp;
203 Lisp_Object Qnone;
204 Lisp_Object Qsuppress_icon;
205 Lisp_Object Qundefined_color;
206 Lisp_Object Qcompound_text, Qcancel_timer;
208 /* In dispnew.c */
210 extern Lisp_Object Vwindow_system_version;
212 /* The below are defined in frame.c. */
214 #if GLYPH_DEBUG
215 int image_cache_refcount, dpyinfo_refcount;
216 #endif
220 /* Error if we are not connected to X. */
222 void
223 check_x ()
225 if (! x_in_use)
226 error ("X windows are not in use or not initialized");
229 /* Nonzero if we can use mouse menus.
230 You should not call this unless HAVE_MENUS is defined. */
233 have_menus_p ()
235 return x_in_use;
238 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
239 and checking validity for X. */
241 FRAME_PTR
242 check_x_frame (frame)
243 Lisp_Object frame;
245 FRAME_PTR f;
247 if (NILP (frame))
248 frame = selected_frame;
249 CHECK_LIVE_FRAME (frame);
250 f = XFRAME (frame);
251 if (! FRAME_X_P (f))
252 error ("Non-X frame used");
253 return f;
256 /* Let the user specify an X display with a Lisp object.
257 OBJECT may be nil, a frame or a terminal id.
258 nil stands for the selected frame--or, if that is not an X frame,
259 the first X display on the list. */
261 struct x_display_info *
262 check_x_display_info (object)
263 Lisp_Object object;
265 struct x_display_info *dpyinfo = NULL;
267 if (NILP (object))
269 struct frame *sf = XFRAME (selected_frame);
271 if (FRAME_X_P (sf) && FRAME_LIVE_P (sf))
272 dpyinfo = FRAME_X_DISPLAY_INFO (sf);
273 else if (x_display_list != 0)
274 dpyinfo = x_display_list;
275 else
276 error ("X windows are not in use or not initialized");
278 else if (INTEGERP (object))
280 struct terminal *t = get_terminal (object, 1);
282 if (t->type != output_x_window)
283 error ("Terminal %d is not an X display", XINT (object));
285 dpyinfo = t->display_info.x;
287 else if (STRINGP (object))
288 dpyinfo = x_display_info_for_name (object);
289 else
291 FRAME_PTR f = check_x_frame (object);
292 dpyinfo = FRAME_X_DISPLAY_INFO (f);
295 return dpyinfo;
299 /* Return the Emacs frame-object corresponding to an X window.
300 It could be the frame's main window or an icon window. */
302 /* This function can be called during GC, so use GC_xxx type test macros. */
304 struct frame *
305 x_window_to_frame (dpyinfo, wdesc)
306 struct x_display_info *dpyinfo;
307 int wdesc;
309 Lisp_Object tail, frame;
310 struct frame *f;
312 if (wdesc == None) return 0;
314 for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail))
316 frame = XCAR (tail);
317 if (!GC_FRAMEP (frame))
318 continue;
319 f = XFRAME (frame);
320 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
321 continue;
322 if (f->output_data.x->hourglass_window == wdesc)
323 return f;
324 #ifdef USE_X_TOOLKIT
325 if ((f->output_data.x->edit_widget
326 && XtWindow (f->output_data.x->edit_widget) == wdesc)
327 /* A tooltip frame? */
328 || (!f->output_data.x->edit_widget
329 && FRAME_X_WINDOW (f) == wdesc)
330 || f->output_data.x->icon_desc == wdesc)
331 return f;
332 #else /* not USE_X_TOOLKIT */
333 #ifdef USE_GTK
334 if (f->output_data.x->edit_widget)
336 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
337 struct x_output *x = f->output_data.x;
338 if (gwdesc != 0 && gwdesc == x->edit_widget)
339 return f;
341 #endif /* USE_GTK */
342 if (FRAME_X_WINDOW (f) == wdesc
343 || f->output_data.x->icon_desc == wdesc)
344 return f;
345 #endif /* not USE_X_TOOLKIT */
347 return 0;
350 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
351 /* Like x_window_to_frame but also compares the window with the widget's
352 windows. */
354 struct frame *
355 x_any_window_to_frame (dpyinfo, wdesc)
356 struct x_display_info *dpyinfo;
357 int wdesc;
359 Lisp_Object tail, frame;
360 struct frame *f, *found;
361 struct x_output *x;
363 if (wdesc == None) return NULL;
365 found = NULL;
366 for (tail = Vframe_list; GC_CONSP (tail) && !found; tail = XCDR (tail))
368 frame = XCAR (tail);
369 if (!GC_FRAMEP (frame))
370 continue;
372 f = XFRAME (frame);
373 if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) == dpyinfo)
375 /* This frame matches if the window is any of its widgets. */
376 x = f->output_data.x;
377 if (x->hourglass_window == wdesc)
378 found = f;
379 else if (x->widget)
381 #ifdef USE_GTK
382 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
383 if (gwdesc != 0
384 && (gwdesc == x->widget
385 || gwdesc == x->edit_widget
386 || gwdesc == x->vbox_widget
387 || gwdesc == x->menubar_widget))
388 found = f;
389 #else
390 if (wdesc == XtWindow (x->widget)
391 || wdesc == XtWindow (x->column_widget)
392 || wdesc == XtWindow (x->edit_widget))
393 found = f;
394 /* Match if the window is this frame's menubar. */
395 else if (lw_window_is_in_menubar (wdesc, x->menubar_widget))
396 found = f;
397 #endif
399 else if (FRAME_X_WINDOW (f) == wdesc)
400 /* A tooltip frame. */
401 found = f;
405 return found;
408 /* Likewise, but exclude the menu bar widget. */
410 struct frame *
411 x_non_menubar_window_to_frame (dpyinfo, wdesc)
412 struct x_display_info *dpyinfo;
413 int wdesc;
415 Lisp_Object tail, frame;
416 struct frame *f;
417 struct x_output *x;
419 if (wdesc == None) return 0;
421 for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail))
423 frame = XCAR (tail);
424 if (!GC_FRAMEP (frame))
425 continue;
426 f = XFRAME (frame);
427 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
428 continue;
429 x = f->output_data.x;
430 /* This frame matches if the window is any of its widgets. */
431 if (x->hourglass_window == wdesc)
432 return f;
433 else if (x->widget)
435 #ifdef USE_GTK
436 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
437 if (gwdesc != 0
438 && (gwdesc == x->widget
439 || gwdesc == x->edit_widget
440 || gwdesc == x->vbox_widget))
441 return f;
442 #else
443 if (wdesc == XtWindow (x->widget)
444 || wdesc == XtWindow (x->column_widget)
445 || wdesc == XtWindow (x->edit_widget))
446 return f;
447 #endif
449 else if (FRAME_X_WINDOW (f) == wdesc)
450 /* A tooltip frame. */
451 return f;
453 return 0;
456 /* Likewise, but consider only the menu bar widget. */
458 struct frame *
459 x_menubar_window_to_frame (dpyinfo, wdesc)
460 struct x_display_info *dpyinfo;
461 int wdesc;
463 Lisp_Object tail, frame;
464 struct frame *f;
465 struct x_output *x;
467 if (wdesc == None) return 0;
469 for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail))
471 frame = XCAR (tail);
472 if (!GC_FRAMEP (frame))
473 continue;
474 f = XFRAME (frame);
475 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
476 continue;
477 x = f->output_data.x;
478 /* Match if the window is this frame's menubar. */
479 #ifdef USE_GTK
480 if (x->menubar_widget)
482 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
483 int found = 0;
485 BLOCK_INPUT;
486 if (gwdesc != 0
487 && (gwdesc == x->menubar_widget
488 || gtk_widget_get_parent (gwdesc) == x->menubar_widget))
489 found = 1;
490 UNBLOCK_INPUT;
491 if (found) return f;
493 #else
494 if (x->menubar_widget
495 && lw_window_is_in_menubar (wdesc, x->menubar_widget))
496 return f;
497 #endif
499 return 0;
502 /* Return the frame whose principal (outermost) window is WDESC.
503 If WDESC is some other (smaller) window, we return 0. */
505 struct frame *
506 x_top_window_to_frame (dpyinfo, wdesc)
507 struct x_display_info *dpyinfo;
508 int wdesc;
510 Lisp_Object tail, frame;
511 struct frame *f;
512 struct x_output *x;
514 if (wdesc == None) return 0;
516 for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail))
518 frame = XCAR (tail);
519 if (!GC_FRAMEP (frame))
520 continue;
521 f = XFRAME (frame);
522 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
523 continue;
524 x = f->output_data.x;
526 if (x->widget)
528 /* This frame matches if the window is its topmost widget. */
529 #ifdef USE_GTK
530 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
531 if (gwdesc == x->widget)
532 return f;
533 #else
534 if (wdesc == XtWindow (x->widget))
535 return f;
536 #if 0 /* I don't know why it did this,
537 but it seems logically wrong,
538 and it causes trouble for MapNotify events. */
539 /* Match if the window is this frame's menubar. */
540 if (x->menubar_widget
541 && wdesc == XtWindow (x->menubar_widget))
542 return f;
543 #endif
544 #endif
546 else if (FRAME_X_WINDOW (f) == wdesc)
547 /* Tooltip frame. */
548 return f;
550 return 0;
552 #endif /* USE_X_TOOLKIT || USE_GTK */
556 static Lisp_Object unwind_create_frame P_ ((Lisp_Object));
557 static Lisp_Object unwind_create_tip_frame P_ ((Lisp_Object));
559 void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
560 static void x_set_wait_for_wm P_ ((struct frame *, Lisp_Object, Lisp_Object));
561 void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
562 void x_set_mouse_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
563 void x_set_cursor_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
564 void x_set_border_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
565 void x_set_cursor_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
566 void x_set_icon_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
567 void x_set_icon_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
568 void x_explicitly_set_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
569 void x_set_menu_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
570 void x_set_title P_ ((struct frame *, Lisp_Object, Lisp_Object));
571 void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
572 void x_set_scroll_bar_foreground P_ ((struct frame *, Lisp_Object,
573 Lisp_Object));
574 void x_set_scroll_bar_background P_ ((struct frame *, Lisp_Object,
575 Lisp_Object));
576 static Lisp_Object x_default_scroll_bar_color_parameter P_ ((struct frame *,
577 Lisp_Object,
578 Lisp_Object,
579 char *, char *,
580 int));
583 /* Store the screen positions of frame F into XPTR and YPTR.
584 These are the positions of the containing window manager window,
585 not Emacs's own window. */
587 void
588 x_real_positions (f, xptr, yptr)
589 FRAME_PTR f;
590 int *xptr, *yptr;
592 int win_x, win_y, outer_x, outer_y;
593 int real_x = 0, real_y = 0;
594 int had_errors = 0;
595 Window win = f->output_data.x->parent_desc;
597 BLOCK_INPUT;
599 x_catch_errors (FRAME_X_DISPLAY (f));
601 if (win == FRAME_X_DISPLAY_INFO (f)->root_window)
602 win = FRAME_OUTER_WINDOW (f);
604 /* This loop traverses up the containment tree until we hit the root
605 window. Window managers may intersect many windows between our window
606 and the root window. The window we find just before the root window
607 should be the outer WM window. */
608 for (;;)
610 Window wm_window, rootw;
611 Window *tmp_children;
612 unsigned int tmp_nchildren;
613 int success;
615 success = XQueryTree (FRAME_X_DISPLAY (f), win, &rootw,
616 &wm_window, &tmp_children, &tmp_nchildren);
618 had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
620 /* Don't free tmp_children if XQueryTree failed. */
621 if (! success)
622 break;
624 XFree ((char *) tmp_children);
626 if (wm_window == rootw || had_errors)
627 break;
629 win = wm_window;
632 if (! had_errors)
634 unsigned int ign;
635 Window child, rootw;
637 /* Get the real coordinates for the WM window upper left corner */
638 XGetGeometry (FRAME_X_DISPLAY (f), win,
639 &rootw, &real_x, &real_y, &ign, &ign, &ign, &ign);
641 /* Translate real coordinates to coordinates relative to our
642 window. For our window, the upper left corner is 0, 0.
643 Since the upper left corner of the WM window is outside
644 our window, win_x and win_y will be negative:
646 ------------------ ---> x
647 | title |
648 | ----------------- v y
649 | | our window
651 XTranslateCoordinates (FRAME_X_DISPLAY (f),
653 /* From-window, to-window. */
654 FRAME_X_DISPLAY_INFO (f)->root_window,
655 FRAME_X_WINDOW (f),
657 /* From-position, to-position. */
658 real_x, real_y, &win_x, &win_y,
660 /* Child of win. */
661 &child);
663 if (FRAME_X_WINDOW (f) == FRAME_OUTER_WINDOW (f))
665 outer_x = win_x;
666 outer_y = win_y;
668 else
670 XTranslateCoordinates (FRAME_X_DISPLAY (f),
672 /* From-window, to-window. */
673 FRAME_X_DISPLAY_INFO (f)->root_window,
674 FRAME_OUTER_WINDOW (f),
676 /* From-position, to-position. */
677 real_x, real_y, &outer_x, &outer_y,
679 /* Child of win. */
680 &child);
683 had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
686 x_uncatch_errors ();
688 UNBLOCK_INPUT;
690 if (had_errors) return;
692 f->x_pixels_diff = -win_x;
693 f->y_pixels_diff = -win_y;
695 FRAME_X_OUTPUT (f)->x_pixels_outer_diff = -outer_x;
696 FRAME_X_OUTPUT (f)->y_pixels_outer_diff = -outer_y;
698 *xptr = real_x;
699 *yptr = real_y;
705 /* Gamma-correct COLOR on frame F. */
707 void
708 gamma_correct (f, color)
709 struct frame *f;
710 XColor *color;
712 if (f->gamma)
714 color->red = pow (color->red / 65535.0, f->gamma) * 65535.0 + 0.5;
715 color->green = pow (color->green / 65535.0, f->gamma) * 65535.0 + 0.5;
716 color->blue = pow (color->blue / 65535.0, f->gamma) * 65535.0 + 0.5;
721 /* Decide if color named COLOR_NAME is valid for use on frame F. If
722 so, return the RGB values in COLOR. If ALLOC_P is non-zero,
723 allocate the color. Value is zero if COLOR_NAME is invalid, or
724 no color could be allocated. */
727 x_defined_color (f, color_name, color, alloc_p)
728 struct frame *f;
729 char *color_name;
730 XColor *color;
731 int alloc_p;
733 int success_p;
734 Display *dpy = FRAME_X_DISPLAY (f);
735 Colormap cmap = FRAME_X_COLORMAP (f);
737 BLOCK_INPUT;
738 success_p = XParseColor (dpy, cmap, color_name, color);
739 if (success_p && alloc_p)
740 success_p = x_alloc_nearest_color (f, cmap, color);
741 UNBLOCK_INPUT;
743 return success_p;
747 /* Return the pixel color value for color COLOR_NAME on frame F. If F
748 is a monochrome frame, return MONO_COLOR regardless of what ARG says.
749 Signal an error if color can't be allocated. */
752 x_decode_color (f, color_name, mono_color)
753 FRAME_PTR f;
754 Lisp_Object color_name;
755 int mono_color;
757 XColor cdef;
759 CHECK_STRING (color_name);
761 #if 0 /* Don't do this. It's wrong when we're not using the default
762 colormap, it makes freeing difficult, and it's probably not
763 an important optimization. */
764 if (strcmp (SDATA (color_name), "black") == 0)
765 return BLACK_PIX_DEFAULT (f);
766 else if (strcmp (SDATA (color_name), "white") == 0)
767 return WHITE_PIX_DEFAULT (f);
768 #endif
770 /* Return MONO_COLOR for monochrome frames. */
771 if (FRAME_X_DISPLAY_INFO (f)->n_planes == 1)
772 return mono_color;
774 /* x_defined_color is responsible for coping with failures
775 by looking for a near-miss. */
776 if (x_defined_color (f, SDATA (color_name), &cdef, 1))
777 return cdef.pixel;
779 signal_error ("Undefined color", color_name);
784 /* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
785 the previous value of that parameter, NEW_VALUE is the new value.
786 See also the comment of wait_for_wm in struct x_output. */
788 static void
789 x_set_wait_for_wm (f, new_value, old_value)
790 struct frame *f;
791 Lisp_Object new_value, old_value;
793 f->output_data.x->wait_for_wm = !NILP (new_value);
796 #ifdef USE_GTK
798 /* Set icon from FILE for frame F. By using GTK functions the icon
799 may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
802 xg_set_icon (f, file)
803 FRAME_PTR f;
804 Lisp_Object file;
806 int result = 0;
807 Lisp_Object found;
809 found = x_find_image_file (file);
811 if (! NILP (found))
813 GdkPixbuf *pixbuf;
814 GError *err = NULL;
815 char *filename = (char *) SDATA (found);
816 BLOCK_INPUT;
818 pixbuf = gdk_pixbuf_new_from_file (filename, &err);
820 if (pixbuf)
822 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
823 pixbuf);
824 g_object_unref (pixbuf);
826 result = 1;
828 else
829 g_error_free (err);
831 UNBLOCK_INPUT;
834 return result;
838 xg_set_icon_from_xpm_data (f, data)
839 FRAME_PTR f;
840 char **data;
842 int result = 0;
843 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) data);
845 if (!pixbuf)
846 return 0;
848 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), pixbuf);
849 g_object_unref (pixbuf);
850 return 1;
852 #endif /* USE_GTK */
855 /* Functions called only from `x_set_frame_param'
856 to set individual parameters.
858 If FRAME_X_WINDOW (f) is 0,
859 the frame is being created and its X-window does not exist yet.
860 In that case, just record the parameter's new value
861 in the standard place; do not attempt to change the window. */
863 void
864 x_set_foreground_color (f, arg, oldval)
865 struct frame *f;
866 Lisp_Object arg, oldval;
868 struct x_output *x = f->output_data.x;
869 unsigned long fg, old_fg;
871 fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
872 old_fg = FRAME_FOREGROUND_PIXEL (f);
873 FRAME_FOREGROUND_PIXEL (f) = fg;
875 if (FRAME_X_WINDOW (f) != 0)
877 Display *dpy = FRAME_X_DISPLAY (f);
879 BLOCK_INPUT;
880 XSetForeground (dpy, x->normal_gc, fg);
881 XSetBackground (dpy, x->reverse_gc, fg);
883 if (x->cursor_pixel == old_fg)
885 unload_color (f, x->cursor_pixel);
886 x->cursor_pixel = x_copy_color (f, fg);
887 XSetBackground (dpy, x->cursor_gc, x->cursor_pixel);
890 UNBLOCK_INPUT;
892 update_face_from_frame_parameter (f, Qforeground_color, arg);
894 if (FRAME_VISIBLE_P (f))
895 redraw_frame (f);
898 unload_color (f, old_fg);
901 void
902 x_set_background_color (f, arg, oldval)
903 struct frame *f;
904 Lisp_Object arg, oldval;
906 struct x_output *x = f->output_data.x;
907 unsigned long bg;
909 bg = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
910 unload_color (f, FRAME_BACKGROUND_PIXEL (f));
911 FRAME_BACKGROUND_PIXEL (f) = bg;
913 if (FRAME_X_WINDOW (f) != 0)
915 Display *dpy = FRAME_X_DISPLAY (f);
917 BLOCK_INPUT;
918 XSetBackground (dpy, x->normal_gc, bg);
919 XSetForeground (dpy, x->reverse_gc, bg);
920 XSetWindowBackground (dpy, FRAME_X_WINDOW (f), bg);
921 XSetForeground (dpy, x->cursor_gc, bg);
923 #ifdef USE_GTK
924 xg_set_background_color (f, bg);
925 #endif
927 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
928 toolkit scroll bars. */
930 Lisp_Object bar;
931 for (bar = FRAME_SCROLL_BARS (f);
932 !NILP (bar);
933 bar = XSCROLL_BAR (bar)->next)
935 Window window = XSCROLL_BAR (bar)->x_window;
936 XSetWindowBackground (dpy, window, bg);
939 #endif /* USE_TOOLKIT_SCROLL_BARS */
941 UNBLOCK_INPUT;
942 update_face_from_frame_parameter (f, Qbackground_color, arg);
944 if (FRAME_VISIBLE_P (f))
945 redraw_frame (f);
949 void
950 x_set_mouse_color (f, arg, oldval)
951 struct frame *f;
952 Lisp_Object arg, oldval;
954 struct x_output *x = f->output_data.x;
955 Display *dpy = FRAME_X_DISPLAY (f);
956 Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
957 Cursor hourglass_cursor, horizontal_drag_cursor;
958 unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
959 unsigned long mask_color = FRAME_BACKGROUND_PIXEL (f);
961 /* Don't let pointers be invisible. */
962 if (mask_color == pixel)
964 x_free_colors (f, &pixel, 1);
965 pixel = x_copy_color (f, FRAME_FOREGROUND_PIXEL (f));
968 unload_color (f, x->mouse_pixel);
969 x->mouse_pixel = pixel;
971 BLOCK_INPUT;
973 /* It's not okay to crash if the user selects a screwy cursor. */
974 x_catch_errors (dpy);
976 if (!NILP (Vx_pointer_shape))
978 CHECK_NUMBER (Vx_pointer_shape);
979 cursor = XCreateFontCursor (dpy, XINT (Vx_pointer_shape));
981 else
982 cursor = XCreateFontCursor (dpy, XC_xterm);
983 x_check_errors (dpy, "bad text pointer cursor: %s");
985 if (!NILP (Vx_nontext_pointer_shape))
987 CHECK_NUMBER (Vx_nontext_pointer_shape);
988 nontext_cursor
989 = XCreateFontCursor (dpy, XINT (Vx_nontext_pointer_shape));
991 else
992 nontext_cursor = XCreateFontCursor (dpy, XC_left_ptr);
993 x_check_errors (dpy, "bad nontext pointer cursor: %s");
995 if (!NILP (Vx_hourglass_pointer_shape))
997 CHECK_NUMBER (Vx_hourglass_pointer_shape);
998 hourglass_cursor
999 = XCreateFontCursor (dpy, XINT (Vx_hourglass_pointer_shape));
1001 else
1002 hourglass_cursor = XCreateFontCursor (dpy, XC_watch);
1003 x_check_errors (dpy, "bad hourglass pointer cursor: %s");
1005 if (!NILP (Vx_mode_pointer_shape))
1007 CHECK_NUMBER (Vx_mode_pointer_shape);
1008 mode_cursor = XCreateFontCursor (dpy, XINT (Vx_mode_pointer_shape));
1010 else
1011 mode_cursor = XCreateFontCursor (dpy, XC_xterm);
1012 x_check_errors (dpy, "bad modeline pointer cursor: %s");
1014 if (!NILP (Vx_sensitive_text_pointer_shape))
1016 CHECK_NUMBER (Vx_sensitive_text_pointer_shape);
1017 hand_cursor
1018 = XCreateFontCursor (dpy, XINT (Vx_sensitive_text_pointer_shape));
1020 else
1021 hand_cursor = XCreateFontCursor (dpy, XC_hand2);
1023 if (!NILP (Vx_window_horizontal_drag_shape))
1025 CHECK_NUMBER (Vx_window_horizontal_drag_shape);
1026 horizontal_drag_cursor
1027 = XCreateFontCursor (dpy, XINT (Vx_window_horizontal_drag_shape));
1029 else
1030 horizontal_drag_cursor
1031 = XCreateFontCursor (dpy, XC_sb_h_double_arrow);
1033 /* Check and report errors with the above calls. */
1034 x_check_errors (dpy, "can't set cursor shape: %s");
1035 x_uncatch_errors ();
1038 XColor fore_color, back_color;
1040 fore_color.pixel = x->mouse_pixel;
1041 x_query_color (f, &fore_color);
1042 back_color.pixel = mask_color;
1043 x_query_color (f, &back_color);
1045 XRecolorCursor (dpy, cursor, &fore_color, &back_color);
1046 XRecolorCursor (dpy, nontext_cursor, &fore_color, &back_color);
1047 XRecolorCursor (dpy, mode_cursor, &fore_color, &back_color);
1048 XRecolorCursor (dpy, hand_cursor, &fore_color, &back_color);
1049 XRecolorCursor (dpy, hourglass_cursor, &fore_color, &back_color);
1050 XRecolorCursor (dpy, horizontal_drag_cursor, &fore_color, &back_color);
1053 if (FRAME_X_WINDOW (f) != 0)
1054 XDefineCursor (dpy, FRAME_X_WINDOW (f), cursor);
1056 if (cursor != x->text_cursor
1057 && x->text_cursor != 0)
1058 XFreeCursor (dpy, x->text_cursor);
1059 x->text_cursor = cursor;
1061 if (nontext_cursor != x->nontext_cursor
1062 && x->nontext_cursor != 0)
1063 XFreeCursor (dpy, x->nontext_cursor);
1064 x->nontext_cursor = nontext_cursor;
1066 if (hourglass_cursor != x->hourglass_cursor
1067 && x->hourglass_cursor != 0)
1068 XFreeCursor (dpy, x->hourglass_cursor);
1069 x->hourglass_cursor = hourglass_cursor;
1071 if (mode_cursor != x->modeline_cursor
1072 && x->modeline_cursor != 0)
1073 XFreeCursor (dpy, f->output_data.x->modeline_cursor);
1074 x->modeline_cursor = mode_cursor;
1076 if (hand_cursor != x->hand_cursor
1077 && x->hand_cursor != 0)
1078 XFreeCursor (dpy, x->hand_cursor);
1079 x->hand_cursor = hand_cursor;
1081 if (horizontal_drag_cursor != x->horizontal_drag_cursor
1082 && x->horizontal_drag_cursor != 0)
1083 XFreeCursor (dpy, x->horizontal_drag_cursor);
1084 x->horizontal_drag_cursor = horizontal_drag_cursor;
1086 XFlush (dpy);
1087 UNBLOCK_INPUT;
1089 update_face_from_frame_parameter (f, Qmouse_color, arg);
1092 void
1093 x_set_cursor_color (f, arg, oldval)
1094 struct frame *f;
1095 Lisp_Object arg, oldval;
1097 unsigned long fore_pixel, pixel;
1098 int fore_pixel_allocated_p = 0, pixel_allocated_p = 0;
1099 struct x_output *x = f->output_data.x;
1101 if (!NILP (Vx_cursor_fore_pixel))
1103 fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
1104 WHITE_PIX_DEFAULT (f));
1105 fore_pixel_allocated_p = 1;
1107 else
1108 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1110 pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1111 pixel_allocated_p = 1;
1113 /* Make sure that the cursor color differs from the background color. */
1114 if (pixel == FRAME_BACKGROUND_PIXEL (f))
1116 if (pixel_allocated_p)
1118 x_free_colors (f, &pixel, 1);
1119 pixel_allocated_p = 0;
1122 pixel = x->mouse_pixel;
1123 if (pixel == fore_pixel)
1125 if (fore_pixel_allocated_p)
1127 x_free_colors (f, &fore_pixel, 1);
1128 fore_pixel_allocated_p = 0;
1130 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1134 unload_color (f, x->cursor_foreground_pixel);
1135 if (!fore_pixel_allocated_p)
1136 fore_pixel = x_copy_color (f, fore_pixel);
1137 x->cursor_foreground_pixel = fore_pixel;
1139 unload_color (f, x->cursor_pixel);
1140 if (!pixel_allocated_p)
1141 pixel = x_copy_color (f, pixel);
1142 x->cursor_pixel = pixel;
1144 if (FRAME_X_WINDOW (f) != 0)
1146 BLOCK_INPUT;
1147 XSetBackground (FRAME_X_DISPLAY (f), x->cursor_gc, x->cursor_pixel);
1148 XSetForeground (FRAME_X_DISPLAY (f), x->cursor_gc, fore_pixel);
1149 UNBLOCK_INPUT;
1151 if (FRAME_VISIBLE_P (f))
1153 x_update_cursor (f, 0);
1154 x_update_cursor (f, 1);
1158 update_face_from_frame_parameter (f, Qcursor_color, arg);
1161 /* Set the border-color of frame F to pixel value PIX.
1162 Note that this does not fully take effect if done before
1163 F has an x-window. */
1165 void
1166 x_set_border_pixel (f, pix)
1167 struct frame *f;
1168 int pix;
1170 unload_color (f, f->output_data.x->border_pixel);
1171 f->output_data.x->border_pixel = pix;
1173 if (FRAME_X_WINDOW (f) != 0 && f->border_width > 0)
1175 BLOCK_INPUT;
1176 XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1177 (unsigned long)pix);
1178 UNBLOCK_INPUT;
1180 if (FRAME_VISIBLE_P (f))
1181 redraw_frame (f);
1185 /* Set the border-color of frame F to value described by ARG.
1186 ARG can be a string naming a color.
1187 The border-color is used for the border that is drawn by the X server.
1188 Note that this does not fully take effect if done before
1189 F has an x-window; it must be redone when the window is created.
1191 Note: this is done in two routines because of the way X10 works.
1193 Note: under X11, this is normally the province of the window manager,
1194 and so emacs' border colors may be overridden. */
1196 void
1197 x_set_border_color (f, arg, oldval)
1198 struct frame *f;
1199 Lisp_Object arg, oldval;
1201 int pix;
1203 CHECK_STRING (arg);
1204 pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1205 x_set_border_pixel (f, pix);
1206 update_face_from_frame_parameter (f, Qborder_color, arg);
1210 void
1211 x_set_cursor_type (f, arg, oldval)
1212 FRAME_PTR f;
1213 Lisp_Object arg, oldval;
1215 set_frame_cursor_types (f, arg);
1217 /* Make sure the cursor gets redrawn. */
1218 cursor_type_changed = 1;
1221 void
1222 x_set_icon_type (f, arg, oldval)
1223 struct frame *f;
1224 Lisp_Object arg, oldval;
1226 int result;
1228 if (STRINGP (arg))
1230 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1231 return;
1233 else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
1234 return;
1236 BLOCK_INPUT;
1237 if (NILP (arg))
1238 result = x_text_icon (f,
1239 (char *) SDATA ((!NILP (f->icon_name)
1240 ? f->icon_name
1241 : f->name)));
1242 else
1243 result = x_bitmap_icon (f, arg);
1245 if (result)
1247 UNBLOCK_INPUT;
1248 error ("No icon window available");
1251 XFlush (FRAME_X_DISPLAY (f));
1252 UNBLOCK_INPUT;
1255 void
1256 x_set_icon_name (f, arg, oldval)
1257 struct frame *f;
1258 Lisp_Object arg, oldval;
1260 int result;
1262 if (STRINGP (arg))
1264 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1265 return;
1267 else if (!NILP (arg) || NILP (oldval))
1268 return;
1270 f->icon_name = arg;
1272 if (f->output_data.x->icon_bitmap != 0)
1273 return;
1275 BLOCK_INPUT;
1277 result = x_text_icon (f,
1278 (char *) SDATA ((!NILP (f->icon_name)
1279 ? f->icon_name
1280 : !NILP (f->title)
1281 ? f->title
1282 : f->name)));
1284 if (result)
1286 UNBLOCK_INPUT;
1287 error ("No icon window available");
1290 XFlush (FRAME_X_DISPLAY (f));
1291 UNBLOCK_INPUT;
1295 void
1296 x_set_menu_bar_lines (f, value, oldval)
1297 struct frame *f;
1298 Lisp_Object value, oldval;
1300 int nlines;
1301 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
1302 int olines = FRAME_MENU_BAR_LINES (f);
1303 #endif
1305 /* Right now, menu bars don't work properly in minibuf-only frames;
1306 most of the commands try to apply themselves to the minibuffer
1307 frame itself, and get an error because you can't switch buffers
1308 in or split the minibuffer window. */
1309 if (FRAME_MINIBUF_ONLY_P (f))
1310 return;
1312 if (INTEGERP (value))
1313 nlines = XINT (value);
1314 else
1315 nlines = 0;
1317 /* Make sure we redisplay all windows in this frame. */
1318 windows_or_buffers_changed++;
1320 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1321 FRAME_MENU_BAR_LINES (f) = 0;
1322 if (nlines)
1324 FRAME_EXTERNAL_MENU_BAR (f) = 1;
1325 if (FRAME_X_P (f) && f->output_data.x->menubar_widget == 0)
1326 /* Make sure next redisplay shows the menu bar. */
1327 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
1329 else
1331 if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
1332 free_frame_menubar (f);
1333 FRAME_EXTERNAL_MENU_BAR (f) = 0;
1334 if (FRAME_X_P (f))
1335 f->output_data.x->menubar_widget = 0;
1337 #else /* not USE_X_TOOLKIT && not USE_GTK */
1338 FRAME_MENU_BAR_LINES (f) = nlines;
1339 change_window_heights (f->root_window, nlines - olines);
1340 #endif /* not USE_X_TOOLKIT */
1341 adjust_glyphs (f);
1345 /* Set the number of lines used for the tool bar of frame F to VALUE.
1346 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1347 is the old number of tool bar lines. This function changes the
1348 height of all windows on frame F to match the new tool bar height.
1349 The frame's height doesn't change. */
1351 void
1352 x_set_tool_bar_lines (f, value, oldval)
1353 struct frame *f;
1354 Lisp_Object value, oldval;
1356 int delta, nlines, root_height;
1357 Lisp_Object root_window;
1359 /* Treat tool bars like menu bars. */
1360 if (FRAME_MINIBUF_ONLY_P (f))
1361 return;
1363 /* Use VALUE only if an integer >= 0. */
1364 if (INTEGERP (value) && XINT (value) >= 0)
1365 nlines = XFASTINT (value);
1366 else
1367 nlines = 0;
1369 #ifdef USE_GTK
1370 FRAME_TOOL_BAR_LINES (f) = 0;
1371 if (nlines)
1373 FRAME_EXTERNAL_TOOL_BAR (f) = 1;
1374 if (FRAME_X_P (f) && f->output_data.x->toolbar_widget == 0)
1375 /* Make sure next redisplay shows the tool bar. */
1376 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
1377 update_frame_tool_bar (f);
1379 else
1381 if (FRAME_EXTERNAL_TOOL_BAR (f))
1382 free_frame_tool_bar (f);
1383 FRAME_EXTERNAL_TOOL_BAR (f) = 0;
1386 return;
1387 #endif
1389 /* Make sure we redisplay all windows in this frame. */
1390 ++windows_or_buffers_changed;
1392 delta = nlines - FRAME_TOOL_BAR_LINES (f);
1394 /* Don't resize the tool-bar to more than we have room for. */
1395 root_window = FRAME_ROOT_WINDOW (f);
1396 root_height = WINDOW_TOTAL_LINES (XWINDOW (root_window));
1397 if (root_height - delta < 1)
1399 delta = root_height - 1;
1400 nlines = FRAME_TOOL_BAR_LINES (f) + delta;
1403 FRAME_TOOL_BAR_LINES (f) = nlines;
1404 change_window_heights (root_window, delta);
1405 adjust_glyphs (f);
1407 /* We also have to make sure that the internal border at the top of
1408 the frame, below the menu bar or tool bar, is redrawn when the
1409 tool bar disappears. This is so because the internal border is
1410 below the tool bar if one is displayed, but is below the menu bar
1411 if there isn't a tool bar. The tool bar draws into the area
1412 below the menu bar. */
1413 if (FRAME_X_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0)
1415 clear_frame (f);
1416 clear_current_matrices (f);
1419 /* If the tool bar gets smaller, the internal border below it
1420 has to be cleared. It was formerly part of the display
1421 of the larger tool bar, and updating windows won't clear it. */
1422 if (delta < 0)
1424 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1425 int width = FRAME_PIXEL_WIDTH (f);
1426 int y = nlines * FRAME_LINE_HEIGHT (f);
1428 /* height can be zero here. */
1429 if (height > 0 && width > 0)
1431 BLOCK_INPUT;
1432 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1433 0, y, width, height, False);
1434 UNBLOCK_INPUT;
1437 if (WINDOWP (f->tool_bar_window))
1438 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1443 /* Set the foreground color for scroll bars on frame F to VALUE.
1444 VALUE should be a string, a color name. If it isn't a string or
1445 isn't a valid color name, do nothing. OLDVAL is the old value of
1446 the frame parameter. */
1448 void
1449 x_set_scroll_bar_foreground (f, value, oldval)
1450 struct frame *f;
1451 Lisp_Object value, oldval;
1453 unsigned long pixel;
1455 if (STRINGP (value))
1456 pixel = x_decode_color (f, value, BLACK_PIX_DEFAULT (f));
1457 else
1458 pixel = -1;
1460 if (f->output_data.x->scroll_bar_foreground_pixel != -1)
1461 unload_color (f, f->output_data.x->scroll_bar_foreground_pixel);
1463 f->output_data.x->scroll_bar_foreground_pixel = pixel;
1464 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1466 /* Remove all scroll bars because they have wrong colors. */
1467 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1468 (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1469 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1470 (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1472 update_face_from_frame_parameter (f, Qscroll_bar_foreground, value);
1473 redraw_frame (f);
1478 /* Set the background color for scroll bars on frame F to VALUE VALUE
1479 should be a string, a color name. If it isn't a string or isn't a
1480 valid color name, do nothing. OLDVAL is the old value of the frame
1481 parameter. */
1483 void
1484 x_set_scroll_bar_background (f, value, oldval)
1485 struct frame *f;
1486 Lisp_Object value, oldval;
1488 unsigned long pixel;
1490 if (STRINGP (value))
1491 pixel = x_decode_color (f, value, WHITE_PIX_DEFAULT (f));
1492 else
1493 pixel = -1;
1495 if (f->output_data.x->scroll_bar_background_pixel != -1)
1496 unload_color (f, f->output_data.x->scroll_bar_background_pixel);
1498 #ifdef USE_TOOLKIT_SCROLL_BARS
1499 /* Scrollbar shadow colors. */
1500 if (f->output_data.x->scroll_bar_top_shadow_pixel != -1)
1502 unload_color (f, f->output_data.x->scroll_bar_top_shadow_pixel);
1503 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
1505 if (f->output_data.x->scroll_bar_bottom_shadow_pixel != -1)
1507 unload_color (f, f->output_data.x->scroll_bar_bottom_shadow_pixel);
1508 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
1510 #endif /* USE_TOOLKIT_SCROLL_BARS */
1512 f->output_data.x->scroll_bar_background_pixel = pixel;
1513 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1515 /* Remove all scroll bars because they have wrong colors. */
1516 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1517 (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1518 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1519 (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1521 update_face_from_frame_parameter (f, Qscroll_bar_background, value);
1522 redraw_frame (f);
1527 /* Encode Lisp string STRING as a text in a format appropriate for
1528 XICCC (X Inter Client Communication Conventions).
1530 This can call Lisp code, so callers must GCPRO.
1532 If STRING contains only ASCII characters, do no conversion and
1533 return the string data of STRING. Otherwise, encode the text by
1534 CODING_SYSTEM, and return a newly allocated memory area which
1535 should be freed by `xfree' by a caller.
1537 SELECTIONP non-zero means the string is being encoded for an X
1538 selection, so it is safe to run pre-write conversions (which
1539 may run Lisp code).
1541 Store the byte length of resulting text in *TEXT_BYTES.
1543 If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
1544 which means that the `encoding' of the result can be `STRING'.
1545 Otherwise store 0 in *STRINGP, which means that the `encoding' of
1546 the result should be `COMPOUND_TEXT'. */
1548 static unsigned char *
1549 x_encode_text (string, coding_system, selectionp, text_bytes, stringp, freep)
1550 Lisp_Object string, coding_system;
1551 int *text_bytes, *stringp;
1552 int selectionp;
1553 int *freep;
1555 unsigned char *str = SDATA (string);
1556 int chars = SCHARS (string);
1557 int bytes = SBYTES (string);
1558 int charset_info;
1559 int bufsize;
1560 unsigned char *buf;
1561 struct coding_system coding;
1562 extern Lisp_Object Qcompound_text_with_extensions;
1564 charset_info = find_charset_in_text (str, chars, bytes, NULL, Qnil);
1565 if (charset_info == 0)
1567 /* No multibyte character in OBJ. We need not encode it. */
1568 *text_bytes = bytes;
1569 *stringp = 1;
1570 *freep = 0;
1571 return str;
1574 setup_coding_system (coding_system, &coding);
1575 if (selectionp
1576 && SYMBOLP (coding.pre_write_conversion)
1577 && !NILP (Ffboundp (coding.pre_write_conversion)))
1579 struct gcpro gcpro1;
1580 /* We don't need to GCPRO string. */
1581 GCPRO1 (coding_system);
1582 string = run_pre_post_conversion_on_str (string, &coding, 1);
1583 UNGCPRO;
1584 str = SDATA (string);
1585 chars = SCHARS (string);
1586 bytes = SBYTES (string);
1588 coding.src_multibyte = 1;
1589 coding.dst_multibyte = 0;
1590 coding.mode |= CODING_MODE_LAST_BLOCK;
1591 if (coding.type == coding_type_iso2022)
1592 coding.flags |= CODING_FLAG_ISO_SAFE;
1593 /* We suppress producing escape sequences for composition. */
1594 coding.composing = COMPOSITION_DISABLED;
1595 bufsize = encoding_buffer_size (&coding, bytes);
1596 buf = (unsigned char *) xmalloc (bufsize);
1597 encode_coding (&coding, str, buf, bytes, bufsize);
1598 *text_bytes = coding.produced;
1599 *stringp = (charset_info == 1
1600 || (!EQ (coding_system, Qcompound_text)
1601 && !EQ (coding_system, Qcompound_text_with_extensions)));
1602 *freep = 1;
1603 return buf;
1607 /* Set the WM name to NAME for frame F. Also set the icon name.
1608 If the frame already has an icon name, use that, otherwise set the
1609 icon name to NAME. */
1611 static void
1612 x_set_name_internal (f, name)
1613 FRAME_PTR f;
1614 Lisp_Object name;
1616 if (FRAME_X_WINDOW (f))
1618 BLOCK_INPUT;
1620 XTextProperty text, icon;
1621 int bytes, stringp;
1622 int do_free_icon_value = 0, do_free_text_value = 0;
1623 Lisp_Object coding_system;
1624 #ifdef USE_GTK
1625 Lisp_Object encoded_name;
1626 struct gcpro gcpro1;
1628 /* As ENCODE_UTF_8 may cause GC and relocation of string data,
1629 we use it before x_encode_text that may return string data. */
1630 GCPRO1 (name);
1631 encoded_name = ENCODE_UTF_8 (name);
1632 UNGCPRO;
1633 #endif
1635 coding_system = Qcompound_text;
1636 /* Note: Encoding strategy
1638 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1639 text.encoding. But, there are non-internationalized window
1640 managers which don't support that encoding. So, if NAME
1641 contains only ASCII and 8859-1 characters, encode it by
1642 iso-latin-1, and use "STRING" in text.encoding hoping that
1643 such window managers at least analyze this format correctly,
1644 i.e. treat 8-bit bytes as 8859-1 characters.
1646 We may also be able to use "UTF8_STRING" in text.encoding
1647 in the future which can encode all Unicode characters.
1648 But, for the moment, there's no way to know that the
1649 current window manager supports it or not. */
1650 text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp,
1651 &do_free_text_value);
1652 text.encoding = (stringp ? XA_STRING
1653 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1654 text.format = 8;
1655 text.nitems = bytes;
1657 if (!STRINGP (f->icon_name))
1659 icon = text;
1661 else
1663 /* See the above comment "Note: Encoding strategy". */
1664 icon.value = x_encode_text (f->icon_name, coding_system, 0,
1665 &bytes, &stringp, &do_free_icon_value);
1666 icon.encoding = (stringp ? XA_STRING
1667 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1668 icon.format = 8;
1669 icon.nitems = bytes;
1672 #ifdef USE_GTK
1673 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
1674 (char *) SDATA (encoded_name));
1675 #else /* not USE_GTK */
1676 XSetWMName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &text);
1677 #endif /* not USE_GTK */
1679 XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &icon);
1681 if (do_free_icon_value)
1682 xfree (icon.value);
1683 if (do_free_text_value)
1684 xfree (text.value);
1686 UNBLOCK_INPUT;
1690 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1691 x_id_name.
1693 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1694 name; if NAME is a string, set F's name to NAME and set
1695 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1697 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1698 suggesting a new name, which lisp code should override; if
1699 F->explicit_name is set, ignore the new name; otherwise, set it. */
1701 void
1702 x_set_name (f, name, explicit)
1703 struct frame *f;
1704 Lisp_Object name;
1705 int explicit;
1707 /* Make sure that requests from lisp code override requests from
1708 Emacs redisplay code. */
1709 if (explicit)
1711 /* If we're switching from explicit to implicit, we had better
1712 update the mode lines and thereby update the title. */
1713 if (f->explicit_name && NILP (name))
1714 update_mode_lines = 1;
1716 f->explicit_name = ! NILP (name);
1718 else if (f->explicit_name)
1719 return;
1721 /* If NAME is nil, set the name to the x_id_name. */
1722 if (NILP (name))
1724 /* Check for no change needed in this very common case
1725 before we do any consing. */
1726 if (!strcmp (FRAME_X_DISPLAY_INFO (f)->x_id_name,
1727 SDATA (f->name)))
1728 return;
1729 name = build_string (FRAME_X_DISPLAY_INFO (f)->x_id_name);
1731 else
1732 CHECK_STRING (name);
1734 /* Don't change the name if it's already NAME. */
1735 if (! NILP (Fstring_equal (name, f->name)))
1736 return;
1738 f->name = name;
1740 /* For setting the frame title, the title parameter should override
1741 the name parameter. */
1742 if (! NILP (f->title))
1743 name = f->title;
1745 x_set_name_internal (f, name);
1748 /* This function should be called when the user's lisp code has
1749 specified a name for the frame; the name will override any set by the
1750 redisplay code. */
1751 void
1752 x_explicitly_set_name (f, arg, oldval)
1753 FRAME_PTR f;
1754 Lisp_Object arg, oldval;
1756 x_set_name (f, arg, 1);
1759 /* This function should be called by Emacs redisplay code to set the
1760 name; names set this way will never override names set by the user's
1761 lisp code. */
1762 void
1763 x_implicitly_set_name (f, arg, oldval)
1764 FRAME_PTR f;
1765 Lisp_Object arg, oldval;
1767 x_set_name (f, arg, 0);
1770 /* Change the title of frame F to NAME.
1771 If NAME is nil, use the frame name as the title. */
1773 void
1774 x_set_title (f, name, old_name)
1775 struct frame *f;
1776 Lisp_Object name, old_name;
1778 /* Don't change the title if it's already NAME. */
1779 if (EQ (name, f->title))
1780 return;
1782 update_mode_lines = 1;
1784 f->title = name;
1786 if (NILP (name))
1787 name = f->name;
1788 else
1789 CHECK_STRING (name);
1791 x_set_name_internal (f, name);
1794 void
1795 x_set_scroll_bar_default_width (f)
1796 struct frame *f;
1798 int wid = FRAME_COLUMN_WIDTH (f);
1800 #ifdef USE_TOOLKIT_SCROLL_BARS
1801 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
1802 int width = 16 + 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM;
1803 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (width + wid - 1) / wid;
1804 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = width;
1805 #else
1806 /* Make the actual width at least 14 pixels and a multiple of a
1807 character width. */
1808 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
1810 /* Use all of that space (aside from required margins) for the
1811 scroll bar. */
1812 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 0;
1813 #endif
1817 /* Record in frame F the specified or default value according to ALIST
1818 of the parameter named PROP (a Lisp symbol). If no value is
1819 specified for PROP, look for an X default for XPROP on the frame
1820 named NAME. If that is not found either, use the value DEFLT. */
1822 static Lisp_Object
1823 x_default_scroll_bar_color_parameter (f, alist, prop, xprop, xclass,
1824 foreground_p)
1825 struct frame *f;
1826 Lisp_Object alist;
1827 Lisp_Object prop;
1828 char *xprop;
1829 char *xclass;
1830 int foreground_p;
1832 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
1833 Lisp_Object tem;
1835 tem = x_get_arg (dpyinfo, alist, prop, xprop, xclass, RES_TYPE_STRING);
1836 if (EQ (tem, Qunbound))
1838 #ifdef USE_TOOLKIT_SCROLL_BARS
1840 /* See if an X resource for the scroll bar color has been
1841 specified. */
1842 tem = display_x_get_resource (dpyinfo,
1843 build_string (foreground_p
1844 ? "foreground"
1845 : "background"),
1846 empty_unibyte_string,
1847 build_string ("verticalScrollBar"),
1848 empty_unibyte_string);
1849 if (!STRINGP (tem))
1851 /* If nothing has been specified, scroll bars will use a
1852 toolkit-dependent default. Because these defaults are
1853 difficult to get at without actually creating a scroll
1854 bar, use nil to indicate that no color has been
1855 specified. */
1856 tem = Qnil;
1859 #else /* not USE_TOOLKIT_SCROLL_BARS */
1861 tem = Qnil;
1863 #endif /* not USE_TOOLKIT_SCROLL_BARS */
1866 x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));
1867 return tem;
1873 #ifdef USE_X_TOOLKIT
1875 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
1876 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
1877 already be present because of the toolkit (Motif adds some of them,
1878 for example, but Xt doesn't). */
1880 static void
1881 hack_wm_protocols (f, widget)
1882 FRAME_PTR f;
1883 Widget widget;
1885 Display *dpy = XtDisplay (widget);
1886 Window w = XtWindow (widget);
1887 int need_delete = 1;
1888 int need_focus = 1;
1889 int need_save = 1;
1891 BLOCK_INPUT;
1893 Atom type;
1894 unsigned char *catoms;
1895 int format = 0;
1896 unsigned long nitems = 0;
1897 unsigned long bytes_after;
1899 if ((XGetWindowProperty (dpy, w,
1900 FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
1901 (long)0, (long)100, False, XA_ATOM,
1902 &type, &format, &nitems, &bytes_after,
1903 &catoms)
1904 == Success)
1905 && format == 32 && type == XA_ATOM)
1907 Atom *atoms = (Atom *) catoms;
1908 while (nitems > 0)
1910 nitems--;
1911 if (atoms[nitems]
1912 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window)
1913 need_delete = 0;
1914 else if (atoms[nitems]
1915 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus)
1916 need_focus = 0;
1917 else if (atoms[nitems]
1918 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself)
1919 need_save = 0;
1922 if (catoms)
1923 XFree (catoms);
1926 Atom props [10];
1927 int count = 0;
1928 if (need_delete)
1929 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window;
1930 if (need_focus)
1931 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus;
1932 if (need_save)
1933 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
1934 if (count)
1935 XChangeProperty (dpy, w, FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
1936 XA_ATOM, 32, PropModeAppend,
1937 (unsigned char *) props, count);
1939 UNBLOCK_INPUT;
1941 #endif
1945 /* Support routines for XIC (X Input Context). */
1947 #ifdef HAVE_X_I18N
1949 static XFontSet xic_create_xfontset P_ ((struct frame *, char *));
1950 static XIMStyle best_xim_style P_ ((XIMStyles *, XIMStyles *));
1953 /* Supported XIM styles, ordered by preference. */
1955 static XIMStyle supported_xim_styles[] =
1957 XIMPreeditPosition | XIMStatusArea,
1958 XIMPreeditPosition | XIMStatusNothing,
1959 XIMPreeditPosition | XIMStatusNone,
1960 XIMPreeditNothing | XIMStatusArea,
1961 XIMPreeditNothing | XIMStatusNothing,
1962 XIMPreeditNothing | XIMStatusNone,
1963 XIMPreeditNone | XIMStatusArea,
1964 XIMPreeditNone | XIMStatusNothing,
1965 XIMPreeditNone | XIMStatusNone,
1970 /* Create an X fontset on frame F with base font name BASE_FONTNAME. */
1972 char xic_defaut_fontset[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
1974 /* Create an Xt fontset spec from the name of a base font.
1975 If `motif' is True use the Motif syntax. */
1976 char *
1977 xic_create_fontsetname (base_fontname, motif)
1978 char *base_fontname;
1979 Bool motif;
1981 const char *sep = motif ? ";" : ",";
1982 char *fontsetname;
1984 /* Make a fontset name from the base font name. */
1985 if (xic_defaut_fontset == base_fontname)
1986 { /* There is no base font name, use the default. */
1987 int len = strlen (base_fontname) + 2;
1988 fontsetname = xmalloc (len);
1989 bzero (fontsetname, len);
1990 strcpy (fontsetname, base_fontname);
1992 else
1994 /* Make a fontset name from the base font name.
1995 The font set will be made of the following elements:
1996 - the base font.
1997 - the base font where the charset spec is replaced by -*-*.
1998 - the same but with the family also replaced with -*-*-. */
1999 char *p = base_fontname;
2000 int i;
2002 for (i = 0; *p; p++)
2003 if (*p == '-') i++;
2004 if (i != 14)
2005 { /* As the font name doesn't conform to XLFD, we can't
2006 modify it to generalize it to allcs and allfamilies.
2007 Use the specified font plus the default. */
2008 int len = strlen (base_fontname) + strlen (xic_defaut_fontset) + 3;
2009 fontsetname = xmalloc (len);
2010 bzero (fontsetname, len);
2011 strcpy (fontsetname, base_fontname);
2012 strcat (fontsetname, sep);
2013 strcat (fontsetname, xic_defaut_fontset);
2015 else
2017 int len;
2018 char *p1 = NULL, *p2 = NULL, *p3 = NULL;
2019 char *font_allcs = NULL;
2020 char *font_allfamilies = NULL;
2021 char *font_all = NULL;
2022 char *allcs = "*-*-*-*-*-*-*";
2023 char *allfamilies = "-*-*-";
2024 char *all = "*-*-*-*-";
2025 char *base;
2027 for (i = 0, p = base_fontname; i < 8; p++)
2029 if (*p == '-')
2031 i++;
2032 if (i == 3)
2033 p1 = p + 1;
2034 else if (i == 7)
2035 p2 = p + 1;
2036 else if (i == 6)
2037 p3 = p + 1;
2040 /* If base_fontname specifies ADSTYLE, make it a
2041 wildcard. */
2042 if (*p3 != '*')
2044 int diff = (p2 - p3) - 2;
2046 base = alloca (strlen (base_fontname) + 1);
2047 bcopy (base_fontname, base, p3 - base_fontname);
2048 base[p3 - base_fontname] = '*';
2049 base[(p3 - base_fontname) + 1] = '-';
2050 strcpy (base + (p3 - base_fontname) + 2, p2);
2051 p = base + (p - base_fontname) - diff;
2052 p1 = base + (p1 - base_fontname);
2053 p2 = base + (p2 - base_fontname) - diff;
2054 base_fontname = base;
2057 /* Build the font spec that matches all charsets. */
2058 len = p - base_fontname + strlen (allcs) + 1;
2059 font_allcs = (char *) alloca (len);
2060 bzero (font_allcs, len);
2061 bcopy (base_fontname, font_allcs, p - base_fontname);
2062 strcat (font_allcs, allcs);
2064 /* Build the font spec that matches all families and
2065 add-styles. */
2066 len = p - p1 + strlen (allcs) + strlen (allfamilies) + 1;
2067 font_allfamilies = (char *) alloca (len);
2068 bzero (font_allfamilies, len);
2069 strcpy (font_allfamilies, allfamilies);
2070 bcopy (p1, font_allfamilies + strlen (allfamilies), p - p1);
2071 strcat (font_allfamilies, allcs);
2073 /* Build the font spec that matches all. */
2074 len = p - p2 + strlen (allcs) + strlen (all) + strlen (allfamilies) + 1;
2075 font_all = (char *) alloca (len);
2076 bzero (font_all, len);
2077 strcpy (font_all, allfamilies);
2078 strcat (font_all, all);
2079 bcopy (p2, font_all + strlen (all) + strlen (allfamilies), p - p2);
2080 strcat (font_all, allcs);
2082 /* Build the actual font set name. */
2083 len = strlen (base_fontname) + strlen (font_allcs)
2084 + strlen (font_allfamilies) + strlen (font_all) + 5;
2085 fontsetname = xmalloc (len);
2086 bzero (fontsetname, len);
2087 strcpy (fontsetname, base_fontname);
2088 strcat (fontsetname, sep);
2089 strcat (fontsetname, font_allcs);
2090 strcat (fontsetname, sep);
2091 strcat (fontsetname, font_allfamilies);
2092 strcat (fontsetname, sep);
2093 strcat (fontsetname, font_all);
2096 if (motif)
2097 strcat (fontsetname, ":");
2098 return fontsetname;
2101 static XFontSet
2102 xic_create_xfontset (f, base_fontname)
2103 struct frame *f;
2104 char *base_fontname;
2106 XFontSet xfs = NULL;
2107 char **missing_list = NULL;
2108 int missing_count;
2109 char *def_string;
2110 Lisp_Object rest, frame;
2112 if (!base_fontname)
2113 base_fontname = xic_defaut_fontset;
2115 /* See if there is another frame already using same fontset. */
2116 FOR_EACH_FRAME (rest, frame)
2118 struct frame *cf = XFRAME (frame);
2119 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
2120 && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f)
2121 && FRAME_XIC_BASE_FONTNAME (cf)
2122 && !strcmp (FRAME_XIC_BASE_FONTNAME (cf), base_fontname))
2124 xfs = FRAME_XIC_FONTSET (cf);
2125 break;
2129 if (!xfs)
2131 char *fontsetname = xic_create_fontsetname (base_fontname, False);
2133 /* New fontset. */
2134 xfs = XCreateFontSet (FRAME_X_DISPLAY (f),
2135 fontsetname, &missing_list,
2136 &missing_count, &def_string);
2137 if (missing_list)
2138 XFreeStringList (missing_list);
2139 if (! xfs)
2141 /* FONTSETNAME contains a list of font names (specific fonts
2142 first, general fonts last), but giving that to
2143 XCreateFontSet at once occasionally fails (bug of X?).
2144 So, we try to call XCreateFontSet for each fontname. */
2145 char *p0 = fontsetname, *p1;
2147 while (p0)
2149 p1 = strchr (p0, ',');
2150 if (p1)
2151 *p1 = '\0';
2152 xfs = XCreateFontSet (FRAME_X_DISPLAY (f),
2153 p0, &missing_list,
2154 &missing_count, &def_string);
2155 if (missing_list)
2156 XFreeStringList (missing_list);
2157 if (xfs)
2158 break;
2159 p0 = p1 ? p1 + 1 : NULL;
2162 xfree (fontsetname);
2165 if (FRAME_XIC_BASE_FONTNAME (f))
2166 xfree (FRAME_XIC_BASE_FONTNAME (f));
2167 FRAME_XIC_BASE_FONTNAME (f) = xstrdup (base_fontname);
2169 /* No need to free def_string. */
2170 return xfs;
2173 /* Free the X fontset of frame F if it is the last frame using it. */
2175 void
2176 xic_free_xfontset (f)
2177 struct frame *f;
2179 Lisp_Object rest, frame;
2180 int shared_p = 0;
2182 if (!FRAME_XIC_FONTSET (f))
2183 return;
2185 /* See if there is another frame sharing the same fontset. */
2186 FOR_EACH_FRAME (rest, frame)
2188 struct frame *cf = XFRAME (frame);
2189 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
2190 && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f)
2191 && FRAME_XIC_FONTSET (cf) == FRAME_XIC_FONTSET (f))
2193 shared_p = 1;
2194 break;
2198 if (!shared_p)
2199 /* The fontset is not used anymore. It is safe to free it. */
2200 XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f));
2202 if (FRAME_XIC_BASE_FONTNAME (f))
2203 xfree (FRAME_XIC_BASE_FONTNAME (f));
2204 FRAME_XIC_BASE_FONTNAME (f) = NULL;
2205 FRAME_XIC_FONTSET (f) = NULL;
2209 /* Value is the best input style, given user preferences USER (already
2210 checked to be supported by Emacs), and styles supported by the
2211 input method XIM. */
2213 static XIMStyle
2214 best_xim_style (user, xim)
2215 XIMStyles *user;
2216 XIMStyles *xim;
2218 int i, j;
2220 for (i = 0; i < user->count_styles; ++i)
2221 for (j = 0; j < xim->count_styles; ++j)
2222 if (user->supported_styles[i] == xim->supported_styles[j])
2223 return user->supported_styles[i];
2225 /* Return the default style. */
2226 return XIMPreeditNothing | XIMStatusNothing;
2229 /* Create XIC for frame F. */
2231 static XIMStyle xic_style;
2233 void
2234 create_frame_xic (f)
2235 struct frame *f;
2237 XIM xim;
2238 XIC xic = NULL;
2239 XFontSet xfs = NULL;
2241 if (FRAME_XIC (f))
2242 return;
2244 /* Create X fontset. */
2245 xfs = xic_create_xfontset
2246 (f, (FRAME_FONTSET (f) < 0) ? NULL
2247 : (char *) SDATA (fontset_ascii (FRAME_FONTSET (f))));
2249 xim = FRAME_X_XIM (f);
2250 if (xim)
2252 XRectangle s_area;
2253 XPoint spot;
2254 XVaNestedList preedit_attr;
2255 XVaNestedList status_attr;
2257 s_area.x = 0; s_area.y = 0; s_area.width = 1; s_area.height = 1;
2258 spot.x = 0; spot.y = 1;
2260 /* Determine XIC style. */
2261 if (xic_style == 0)
2263 XIMStyles supported_list;
2264 supported_list.count_styles = (sizeof supported_xim_styles
2265 / sizeof supported_xim_styles[0]);
2266 supported_list.supported_styles = supported_xim_styles;
2267 xic_style = best_xim_style (&supported_list,
2268 FRAME_X_XIM_STYLES (f));
2271 preedit_attr = XVaCreateNestedList (0,
2272 XNFontSet, xfs,
2273 XNForeground,
2274 FRAME_FOREGROUND_PIXEL (f),
2275 XNBackground,
2276 FRAME_BACKGROUND_PIXEL (f),
2277 (xic_style & XIMPreeditPosition
2278 ? XNSpotLocation
2279 : NULL),
2280 &spot,
2281 NULL);
2282 status_attr = XVaCreateNestedList (0,
2283 XNArea,
2284 &s_area,
2285 XNFontSet,
2286 xfs,
2287 XNForeground,
2288 FRAME_FOREGROUND_PIXEL (f),
2289 XNBackground,
2290 FRAME_BACKGROUND_PIXEL (f),
2291 NULL);
2293 xic = XCreateIC (xim,
2294 XNInputStyle, xic_style,
2295 XNClientWindow, FRAME_X_WINDOW (f),
2296 XNFocusWindow, FRAME_X_WINDOW (f),
2297 XNStatusAttributes, status_attr,
2298 XNPreeditAttributes, preedit_attr,
2299 NULL);
2300 XFree (preedit_attr);
2301 XFree (status_attr);
2304 FRAME_XIC (f) = xic;
2305 FRAME_XIC_STYLE (f) = xic_style;
2306 FRAME_XIC_FONTSET (f) = xfs;
2310 /* Destroy XIC and free XIC fontset of frame F, if any. */
2312 void
2313 free_frame_xic (f)
2314 struct frame *f;
2316 if (FRAME_XIC (f) == NULL)
2317 return;
2319 XDestroyIC (FRAME_XIC (f));
2320 xic_free_xfontset (f);
2322 FRAME_XIC (f) = NULL;
2326 /* Place preedit area for XIC of window W's frame to specified
2327 pixel position X/Y. X and Y are relative to window W. */
2329 void
2330 xic_set_preeditarea (w, x, y)
2331 struct window *w;
2332 int x, y;
2334 struct frame *f = XFRAME (w->frame);
2335 XVaNestedList attr;
2336 XPoint spot;
2338 spot.x = WINDOW_TO_FRAME_PIXEL_X (w, x) + WINDOW_LEFT_FRINGE_WIDTH (w);
2339 spot.y = WINDOW_TO_FRAME_PIXEL_Y (w, y) + FONT_BASE (FRAME_FONT (f));
2340 attr = XVaCreateNestedList (0, XNSpotLocation, &spot, NULL);
2341 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2342 XFree (attr);
2346 /* Place status area for XIC in bottom right corner of frame F.. */
2348 void
2349 xic_set_statusarea (f)
2350 struct frame *f;
2352 XIC xic = FRAME_XIC (f);
2353 XVaNestedList attr;
2354 XRectangle area;
2355 XRectangle *needed;
2357 /* Negotiate geometry of status area. If input method has existing
2358 status area, use its current size. */
2359 area.x = area.y = area.width = area.height = 0;
2360 attr = XVaCreateNestedList (0, XNAreaNeeded, &area, NULL);
2361 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2362 XFree (attr);
2364 attr = XVaCreateNestedList (0, XNAreaNeeded, &needed, NULL);
2365 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2366 XFree (attr);
2368 if (needed->width == 0) /* Use XNArea instead of XNAreaNeeded */
2370 attr = XVaCreateNestedList (0, XNArea, &needed, NULL);
2371 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2372 XFree (attr);
2375 area.width = needed->width;
2376 area.height = needed->height;
2377 area.x = FRAME_PIXEL_WIDTH (f) - area.width - FRAME_INTERNAL_BORDER_WIDTH (f);
2378 area.y = (FRAME_PIXEL_HEIGHT (f) - area.height
2379 - FRAME_MENUBAR_HEIGHT (f)
2380 - FRAME_TOOLBAR_HEIGHT (f)
2381 - FRAME_INTERNAL_BORDER_WIDTH (f));
2382 XFree (needed);
2384 attr = XVaCreateNestedList (0, XNArea, &area, NULL);
2385 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2386 XFree (attr);
2390 /* Set X fontset for XIC of frame F, using base font name
2391 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2393 void
2394 xic_set_xfontset (f, base_fontname)
2395 struct frame *f;
2396 char *base_fontname;
2398 XVaNestedList attr;
2399 XFontSet xfs;
2401 xic_free_xfontset (f);
2403 xfs = xic_create_xfontset (f, base_fontname);
2405 attr = XVaCreateNestedList (0, XNFontSet, xfs, NULL);
2406 if (FRAME_XIC_STYLE (f) & XIMPreeditPosition)
2407 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2408 if (FRAME_XIC_STYLE (f) & XIMStatusArea)
2409 XSetICValues (FRAME_XIC (f), XNStatusAttributes, attr, NULL);
2410 XFree (attr);
2412 FRAME_XIC_FONTSET (f) = xfs;
2415 #endif /* HAVE_X_I18N */
2419 #ifdef USE_X_TOOLKIT
2421 /* Create and set up the X widget for frame F. */
2423 static void
2424 x_window (f, window_prompting, minibuffer_only)
2425 struct frame *f;
2426 long window_prompting;
2427 int minibuffer_only;
2429 XClassHint class_hints;
2430 XSetWindowAttributes attributes;
2431 unsigned long attribute_mask;
2432 Widget shell_widget;
2433 Widget pane_widget;
2434 Widget frame_widget;
2435 Arg al [25];
2436 int ac;
2438 BLOCK_INPUT;
2440 /* Use the resource name as the top-level widget name
2441 for looking up resources. Make a non-Lisp copy
2442 for the window manager, so GC relocation won't bother it.
2444 Elsewhere we specify the window name for the window manager. */
2447 char *str = (char *) SDATA (Vx_resource_name);
2448 f->namebuf = (char *) xmalloc (strlen (str) + 1);
2449 strcpy (f->namebuf, str);
2452 ac = 0;
2453 XtSetArg (al[ac], XtNallowShellResize, 1); ac++;
2454 XtSetArg (al[ac], XtNinput, 1); ac++;
2455 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2456 XtSetArg (al[ac], XtNborderWidth, f->border_width); ac++;
2457 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2458 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2459 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2460 shell_widget = XtAppCreateShell (f->namebuf, EMACS_CLASS,
2461 applicationShellWidgetClass,
2462 FRAME_X_DISPLAY (f), al, ac);
2464 f->output_data.x->widget = shell_widget;
2465 /* maybe_set_screen_title_format (shell_widget); */
2467 pane_widget = lw_create_widget ("main", "pane", widget_id_tick++,
2468 (widget_value *) NULL,
2469 shell_widget, False,
2470 (lw_callback) NULL,
2471 (lw_callback) NULL,
2472 (lw_callback) NULL,
2473 (lw_callback) NULL);
2475 ac = 0;
2476 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2477 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2478 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2479 XtSetValues (pane_widget, al, ac);
2480 f->output_data.x->column_widget = pane_widget;
2482 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2483 the emacs screen when changing menubar. This reduces flickering. */
2485 ac = 0;
2486 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2487 XtSetArg (al[ac], XtNshowGrip, 0); ac++;
2488 XtSetArg (al[ac], XtNallowResize, 1); ac++;
2489 XtSetArg (al[ac], XtNresizeToPreferred, 1); ac++;
2490 XtSetArg (al[ac], XtNemacsFrame, f); ac++;
2491 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2492 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2493 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2494 frame_widget = XtCreateWidget (f->namebuf, emacsFrameClass, pane_widget,
2495 al, ac);
2497 f->output_data.x->edit_widget = frame_widget;
2499 XtManageChild (frame_widget);
2501 /* Do some needed geometry management. */
2503 int len;
2504 char *tem, shell_position[32];
2505 Arg al[10];
2506 int ac = 0;
2507 int extra_borders = 0;
2508 int menubar_size
2509 = (f->output_data.x->menubar_widget
2510 ? (f->output_data.x->menubar_widget->core.height
2511 + f->output_data.x->menubar_widget->core.border_width)
2512 : 0);
2514 #if 0 /* Experimentally, we now get the right results
2515 for -geometry -0-0 without this. 24 Aug 96, rms. */
2516 if (FRAME_EXTERNAL_MENU_BAR (f))
2518 Dimension ibw = 0;
2519 XtVaGetValues (pane_widget, XtNinternalBorderWidth, &ibw, NULL);
2520 menubar_size += ibw;
2522 #endif
2524 f->output_data.x->menubar_height = menubar_size;
2526 #ifndef USE_LUCID
2527 /* Motif seems to need this amount added to the sizes
2528 specified for the shell widget. The Athena/Lucid widgets don't.
2529 Both conclusions reached experimentally. -- rms. */
2530 XtVaGetValues (f->output_data.x->edit_widget, XtNinternalBorderWidth,
2531 &extra_borders, NULL);
2532 extra_borders *= 2;
2533 #endif
2535 /* Convert our geometry parameters into a geometry string
2536 and specify it.
2537 Note that we do not specify here whether the position
2538 is a user-specified or program-specified one.
2539 We pass that information later, in x_wm_set_size_hints. */
2541 int left = f->left_pos;
2542 int xneg = window_prompting & XNegative;
2543 int top = f->top_pos;
2544 int yneg = window_prompting & YNegative;
2545 if (xneg)
2546 left = -left;
2547 if (yneg)
2548 top = -top;
2550 if (window_prompting & USPosition)
2551 sprintf (shell_position, "=%dx%d%c%d%c%d",
2552 FRAME_PIXEL_WIDTH (f) + extra_borders,
2553 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders,
2554 (xneg ? '-' : '+'), left,
2555 (yneg ? '-' : '+'), top);
2556 else
2558 sprintf (shell_position, "=%dx%d",
2559 FRAME_PIXEL_WIDTH (f) + extra_borders,
2560 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders);
2562 /* Setting x and y when the position is not specified in
2563 the geometry string will set program position in the WM hints.
2564 If Emacs had just one program position, we could set it in
2565 fallback resources, but since each make-frame call can specify
2566 different program positions, this is easier. */
2567 XtSetArg (al[ac], XtNx, left); ac++;
2568 XtSetArg (al[ac], XtNy, top); ac++;
2572 len = strlen (shell_position) + 1;
2573 /* We don't free this because we don't know whether
2574 it is safe to free it while the frame exists.
2575 It isn't worth the trouble of arranging to free it
2576 when the frame is deleted. */
2577 tem = (char *) xmalloc (len);
2578 strncpy (tem, shell_position, len);
2579 XtSetArg (al[ac], XtNgeometry, tem); ac++;
2580 XtSetValues (shell_widget, al, ac);
2583 XtManageChild (pane_widget);
2584 XtRealizeWidget (shell_widget);
2586 FRAME_X_WINDOW (f) = XtWindow (frame_widget);
2588 validate_x_resource_name ();
2590 class_hints.res_name = (char *) SDATA (Vx_resource_name);
2591 class_hints.res_class = (char *) SDATA (Vx_resource_class);
2592 XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints);
2594 #ifdef HAVE_X_I18N
2595 FRAME_XIC (f) = NULL;
2596 if (use_xim)
2597 create_frame_xic (f);
2598 #endif
2600 f->output_data.x->wm_hints.input = True;
2601 f->output_data.x->wm_hints.flags |= InputHint;
2602 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2603 &f->output_data.x->wm_hints);
2605 hack_wm_protocols (f, shell_widget);
2607 #ifdef HACK_EDITRES
2608 XtAddEventHandler (shell_widget, 0, True, _XEditResCheckMessages, 0);
2609 #endif
2611 /* Do a stupid property change to force the server to generate a
2612 PropertyNotify event so that the event_stream server timestamp will
2613 be initialized to something relevant to the time we created the window.
2615 XChangeProperty (XtDisplay (frame_widget), XtWindow (frame_widget),
2616 FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
2617 XA_ATOM, 32, PropModeAppend,
2618 (unsigned char*) NULL, 0);
2620 /* Make all the standard events reach the Emacs frame. */
2621 attributes.event_mask = STANDARD_EVENT_SET;
2623 #ifdef HAVE_X_I18N
2624 if (FRAME_XIC (f))
2626 /* XIM server might require some X events. */
2627 unsigned long fevent = NoEventMask;
2628 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2629 attributes.event_mask |= fevent;
2631 #endif /* HAVE_X_I18N */
2633 attribute_mask = CWEventMask;
2634 XChangeWindowAttributes (XtDisplay (shell_widget), XtWindow (shell_widget),
2635 attribute_mask, &attributes);
2637 XtMapWidget (frame_widget);
2639 /* x_set_name normally ignores requests to set the name if the
2640 requested name is the same as the current name. This is the one
2641 place where that assumption isn't correct; f->name is set, but
2642 the X server hasn't been told. */
2644 Lisp_Object name;
2645 int explicit = f->explicit_name;
2647 f->explicit_name = 0;
2648 name = f->name;
2649 f->name = Qnil;
2650 x_set_name (f, name, explicit);
2653 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2654 f->output_data.x->text_cursor);
2656 UNBLOCK_INPUT;
2658 /* This is a no-op, except under Motif. Make sure main areas are
2659 set to something reasonable, in case we get an error later. */
2660 lw_set_main_areas (pane_widget, 0, frame_widget);
2663 #else /* not USE_X_TOOLKIT */
2664 #ifdef USE_GTK
2665 void
2666 x_window (f)
2667 FRAME_PTR f;
2669 if (! xg_create_frame_widgets (f))
2670 error ("Unable to create window");
2672 #ifdef HAVE_X_I18N
2673 FRAME_XIC (f) = NULL;
2674 if (use_xim)
2676 BLOCK_INPUT;
2677 create_frame_xic (f);
2678 if (FRAME_XIC (f))
2680 /* XIM server might require some X events. */
2681 unsigned long fevent = NoEventMask;
2682 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2684 if (fevent != NoEventMask)
2686 XSetWindowAttributes attributes;
2687 XWindowAttributes wattr;
2688 unsigned long attribute_mask;
2690 XGetWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2691 &wattr);
2692 attributes.event_mask = wattr.your_event_mask | fevent;
2693 attribute_mask = CWEventMask;
2694 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2695 attribute_mask, &attributes);
2698 UNBLOCK_INPUT;
2700 #endif
2703 #else /*! USE_GTK */
2704 /* Create and set up the X window for frame F. */
2706 void
2707 x_window (f)
2708 struct frame *f;
2711 XClassHint class_hints;
2712 XSetWindowAttributes attributes;
2713 unsigned long attribute_mask;
2715 attributes.background_pixel = FRAME_BACKGROUND_PIXEL (f);
2716 attributes.border_pixel = f->output_data.x->border_pixel;
2717 attributes.bit_gravity = StaticGravity;
2718 attributes.backing_store = NotUseful;
2719 attributes.save_under = True;
2720 attributes.event_mask = STANDARD_EVENT_SET;
2721 attributes.colormap = FRAME_X_COLORMAP (f);
2722 attribute_mask = (CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask
2723 | CWColormap);
2725 BLOCK_INPUT;
2726 FRAME_X_WINDOW (f)
2727 = XCreateWindow (FRAME_X_DISPLAY (f),
2728 f->output_data.x->parent_desc,
2729 f->left_pos,
2730 f->top_pos,
2731 FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
2732 f->border_width,
2733 CopyFromParent, /* depth */
2734 InputOutput, /* class */
2735 FRAME_X_VISUAL (f),
2736 attribute_mask, &attributes);
2738 #ifdef HAVE_X_I18N
2739 if (use_xim)
2741 create_frame_xic (f);
2742 if (FRAME_XIC (f))
2744 /* XIM server might require some X events. */
2745 unsigned long fevent = NoEventMask;
2746 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2747 attributes.event_mask |= fevent;
2748 attribute_mask = CWEventMask;
2749 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2750 attribute_mask, &attributes);
2753 #endif /* HAVE_X_I18N */
2755 validate_x_resource_name ();
2757 class_hints.res_name = (char *) SDATA (Vx_resource_name);
2758 class_hints.res_class = (char *) SDATA (Vx_resource_class);
2759 XSetClassHint (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &class_hints);
2761 /* The menubar is part of the ordinary display;
2762 it does not count in addition to the height of the window. */
2763 f->output_data.x->menubar_height = 0;
2765 /* This indicates that we use the "Passive Input" input model.
2766 Unless we do this, we don't get the Focus{In,Out} events that we
2767 need to draw the cursor correctly. Accursed bureaucrats.
2768 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2770 f->output_data.x->wm_hints.input = True;
2771 f->output_data.x->wm_hints.flags |= InputHint;
2772 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2773 &f->output_data.x->wm_hints);
2774 f->output_data.x->wm_hints.icon_pixmap = None;
2776 /* Request "save yourself" and "delete window" commands from wm. */
2778 Atom protocols[2];
2779 protocols[0] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window;
2780 protocols[1] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
2781 XSetWMProtocols (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), protocols, 2);
2784 /* x_set_name normally ignores requests to set the name if the
2785 requested name is the same as the current name. This is the one
2786 place where that assumption isn't correct; f->name is set, but
2787 the X server hasn't been told. */
2789 Lisp_Object name;
2790 int explicit = f->explicit_name;
2792 f->explicit_name = 0;
2793 name = f->name;
2794 f->name = Qnil;
2795 x_set_name (f, name, explicit);
2798 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2799 f->output_data.x->text_cursor);
2801 UNBLOCK_INPUT;
2803 if (FRAME_X_WINDOW (f) == 0)
2804 error ("Unable to create window");
2807 #endif /* not USE_GTK */
2808 #endif /* not USE_X_TOOLKIT */
2810 /* Verify that the icon position args for this window are valid. */
2812 static void
2813 x_icon_verify (f, parms)
2814 struct frame *f;
2815 Lisp_Object parms;
2817 Lisp_Object icon_x, icon_y;
2819 /* Set the position of the icon. Note that twm groups all
2820 icons in an icon window. */
2821 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2822 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2823 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2825 CHECK_NUMBER (icon_x);
2826 CHECK_NUMBER (icon_y);
2828 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2829 error ("Both left and top icon corners of icon must be specified");
2832 /* Handle the icon stuff for this window. Perhaps later we might
2833 want an x_set_icon_position which can be called interactively as
2834 well. */
2836 static void
2837 x_icon (f, parms)
2838 struct frame *f;
2839 Lisp_Object parms;
2841 Lisp_Object icon_x, icon_y;
2842 #if 0
2843 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2844 #endif
2846 /* Set the position of the icon. Note that twm groups all
2847 icons in an icon window. */
2848 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2849 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2850 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2852 CHECK_NUMBER (icon_x);
2853 CHECK_NUMBER (icon_y);
2855 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2856 error ("Both left and top icon corners of icon must be specified");
2858 BLOCK_INPUT;
2860 if (! EQ (icon_x, Qunbound))
2861 x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
2863 #if 0 /* x_get_arg removes the visibility parameter as a side effect,
2864 but x_create_frame still needs it. */
2865 /* Start up iconic or window? */
2866 x_wm_set_window_state
2867 (f, (EQ (x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL),
2868 Qicon)
2869 ? IconicState
2870 : NormalState));
2871 #endif
2873 x_text_icon (f, (char *) SDATA ((!NILP (f->icon_name)
2874 ? f->icon_name
2875 : f->name)));
2877 UNBLOCK_INPUT;
2880 /* Make the GCs needed for this window, setting the
2881 background, border and mouse colors; also create the
2882 mouse cursor and the gray border tile. */
2884 static char cursor_bits[] =
2886 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2887 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2888 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2889 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2892 static void
2893 x_make_gc (f)
2894 struct frame *f;
2896 XGCValues gc_values;
2898 BLOCK_INPUT;
2900 /* Create the GCs of this frame.
2901 Note that many default values are used. */
2903 /* Normal video */
2904 gc_values.font = FRAME_FONT (f)->fid;
2905 gc_values.foreground = FRAME_FOREGROUND_PIXEL (f);
2906 gc_values.background = FRAME_BACKGROUND_PIXEL (f);
2907 gc_values.line_width = 0; /* Means 1 using fast algorithm. */
2908 f->output_data.x->normal_gc
2909 = XCreateGC (FRAME_X_DISPLAY (f),
2910 FRAME_X_WINDOW (f),
2911 GCLineWidth | GCFont | GCForeground | GCBackground,
2912 &gc_values);
2914 /* Reverse video style. */
2915 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2916 gc_values.background = FRAME_FOREGROUND_PIXEL (f);
2917 f->output_data.x->reverse_gc
2918 = XCreateGC (FRAME_X_DISPLAY (f),
2919 FRAME_X_WINDOW (f),
2920 GCFont | GCForeground | GCBackground | GCLineWidth,
2921 &gc_values);
2923 /* Cursor has cursor-color background, background-color foreground. */
2924 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2925 gc_values.background = f->output_data.x->cursor_pixel;
2926 gc_values.fill_style = FillOpaqueStippled;
2927 gc_values.stipple
2928 = XCreateBitmapFromData (FRAME_X_DISPLAY (f),
2929 FRAME_X_DISPLAY_INFO (f)->root_window,
2930 cursor_bits, 16, 16);
2931 f->output_data.x->cursor_gc
2932 = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2933 (GCFont | GCForeground | GCBackground
2934 | GCFillStyle /* | GCStipple */ | GCLineWidth),
2935 &gc_values);
2937 /* Reliefs. */
2938 f->output_data.x->white_relief.gc = 0;
2939 f->output_data.x->black_relief.gc = 0;
2941 /* Create the gray border tile used when the pointer is not in
2942 the frame. Since this depends on the frame's pixel values,
2943 this must be done on a per-frame basis. */
2944 f->output_data.x->border_tile
2945 = (XCreatePixmapFromBitmapData
2946 (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
2947 gray_bits, gray_width, gray_height,
2948 FRAME_FOREGROUND_PIXEL (f),
2949 FRAME_BACKGROUND_PIXEL (f),
2950 DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
2952 UNBLOCK_INPUT;
2956 /* Free what was was allocated in x_make_gc. */
2958 void
2959 x_free_gcs (f)
2960 struct frame *f;
2962 Display *dpy = FRAME_X_DISPLAY (f);
2964 BLOCK_INPUT;
2966 if (f->output_data.x->normal_gc)
2968 XFreeGC (dpy, f->output_data.x->normal_gc);
2969 f->output_data.x->normal_gc = 0;
2972 if (f->output_data.x->reverse_gc)
2974 XFreeGC (dpy, f->output_data.x->reverse_gc);
2975 f->output_data.x->reverse_gc = 0;
2978 if (f->output_data.x->cursor_gc)
2980 XFreeGC (dpy, f->output_data.x->cursor_gc);
2981 f->output_data.x->cursor_gc = 0;
2984 if (f->output_data.x->border_tile)
2986 XFreePixmap (dpy, f->output_data.x->border_tile);
2987 f->output_data.x->border_tile = 0;
2990 UNBLOCK_INPUT;
2994 /* Handler for signals raised during x_create_frame and
2995 x_create_top_frame. FRAME is the frame which is partially
2996 constructed. */
2998 static Lisp_Object
2999 unwind_create_frame (frame)
3000 Lisp_Object frame;
3002 struct frame *f = XFRAME (frame);
3004 /* If frame is already dead, nothing to do. This can happen if the
3005 display is disconnected after the frame has become official, but
3006 before x_create_frame removes the unwind protect. */
3007 if (!FRAME_LIVE_P (f))
3008 return Qnil;
3010 /* If frame is ``official'', nothing to do. */
3011 if (!CONSP (Vframe_list) || !EQ (XCAR (Vframe_list), frame))
3013 #if GLYPH_DEBUG
3014 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3015 #endif
3017 x_free_frame_resources (f);
3019 #if GLYPH_DEBUG
3020 /* Check that reference counts are indeed correct. */
3021 xassert (dpyinfo->reference_count == dpyinfo_refcount);
3022 xassert (dpyinfo->image_cache->refcount == image_cache_refcount);
3023 #endif
3024 return Qt;
3027 return Qnil;
3031 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
3032 1, 1, 0,
3033 doc: /* Make a new X window, which is called a "frame" in Emacs terms.
3034 Return an Emacs frame object.
3035 ALIST is an alist of frame parameters.
3036 If the parameters specify that the frame should not have a minibuffer,
3037 and do not specify a specific minibuffer window to use,
3038 then `default-minibuffer-frame' must be a frame whose minibuffer can
3039 be shared by the new frame.
3041 This function is an internal primitive--use `make-frame' instead. */)
3042 (parms)
3043 Lisp_Object parms;
3045 struct frame *f;
3046 Lisp_Object frame, tem;
3047 Lisp_Object name;
3048 int minibuffer_only = 0;
3049 long window_prompting = 0;
3050 int width, height;
3051 int count = SPECPDL_INDEX ();
3052 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
3053 Lisp_Object display;
3054 struct x_display_info *dpyinfo = NULL;
3055 Lisp_Object parent;
3056 struct kboard *kb;
3058 parms = Fcopy_alist (parms);
3060 /* Use this general default value to start with
3061 until we know if this frame has a specified name. */
3062 Vx_resource_name = Vinvocation_name;
3064 display = x_get_arg (dpyinfo, parms, Qterminal, 0, 0, RES_TYPE_NUMBER);
3065 if (EQ (display, Qunbound))
3066 display = x_get_arg (dpyinfo, parms, Qdisplay, 0, 0, RES_TYPE_STRING);
3067 if (EQ (display, Qunbound))
3068 display = Qnil;
3069 dpyinfo = check_x_display_info (display);
3070 #ifdef MULTI_KBOARD
3071 kb = dpyinfo->terminal->kboard;
3072 #else
3073 kb = &the_only_kboard;
3074 #endif
3076 if (!dpyinfo->terminal->name)
3077 error ("Terminal is not live, can't create new frames on it");
3079 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
3080 if (!STRINGP (name)
3081 && ! EQ (name, Qunbound)
3082 && ! NILP (name))
3083 error ("Invalid frame name--not a string or nil");
3085 if (STRINGP (name))
3086 Vx_resource_name = name;
3088 /* See if parent window is specified. */
3089 parent = x_get_arg (dpyinfo, parms, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
3090 if (EQ (parent, Qunbound))
3091 parent = Qnil;
3092 if (! NILP (parent))
3093 CHECK_NUMBER (parent);
3095 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
3096 /* No need to protect DISPLAY because that's not used after passing
3097 it to make_frame_without_minibuffer. */
3098 frame = Qnil;
3099 GCPRO4 (parms, parent, name, frame);
3100 tem = x_get_arg (dpyinfo, parms, Qminibuffer, "minibuffer", "Minibuffer",
3101 RES_TYPE_SYMBOL);
3102 if (EQ (tem, Qnone) || NILP (tem))
3103 f = make_frame_without_minibuffer (Qnil, kb, display);
3104 else if (EQ (tem, Qonly))
3106 f = make_minibuffer_frame ();
3107 minibuffer_only = 1;
3109 else if (WINDOWP (tem))
3110 f = make_frame_without_minibuffer (tem, kb, display);
3111 else
3112 f = make_frame (1);
3114 XSETFRAME (frame, f);
3116 /* Note that X Windows does support scroll bars. */
3117 FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
3119 f->terminal = dpyinfo->terminal;
3120 f->terminal->reference_count++;
3122 f->output_method = output_x_window;
3123 f->output_data.x = (struct x_output *) xmalloc (sizeof (struct x_output));
3124 bzero (f->output_data.x, sizeof (struct x_output));
3125 f->output_data.x->icon_bitmap = -1;
3126 FRAME_FONTSET (f) = -1;
3127 f->output_data.x->scroll_bar_foreground_pixel = -1;
3128 f->output_data.x->scroll_bar_background_pixel = -1;
3129 #ifdef USE_TOOLKIT_SCROLL_BARS
3130 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
3131 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
3132 #endif /* USE_TOOLKIT_SCROLL_BARS */
3134 f->icon_name
3135 = x_get_arg (dpyinfo, parms, Qicon_name, "iconName", "Title",
3136 RES_TYPE_STRING);
3137 if (! STRINGP (f->icon_name))
3138 f->icon_name = Qnil;
3140 FRAME_X_DISPLAY_INFO (f) = dpyinfo;
3142 /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe. */
3143 record_unwind_protect (unwind_create_frame, frame);
3144 #if GLYPH_DEBUG
3145 image_cache_refcount = FRAME_X_IMAGE_CACHE (f)->refcount;
3146 dpyinfo_refcount = dpyinfo->reference_count;
3147 #endif /* GLYPH_DEBUG */
3149 /* These colors will be set anyway later, but it's important
3150 to get the color reference counts right, so initialize them! */
3152 Lisp_Object black;
3153 struct gcpro gcpro1;
3155 /* Function x_decode_color can signal an error. Make
3156 sure to initialize color slots so that we won't try
3157 to free colors we haven't allocated. */
3158 FRAME_FOREGROUND_PIXEL (f) = -1;
3159 FRAME_BACKGROUND_PIXEL (f) = -1;
3160 f->output_data.x->cursor_pixel = -1;
3161 f->output_data.x->cursor_foreground_pixel = -1;
3162 f->output_data.x->border_pixel = -1;
3163 f->output_data.x->mouse_pixel = -1;
3165 black = build_string ("black");
3166 GCPRO1 (black);
3167 FRAME_FOREGROUND_PIXEL (f)
3168 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3169 FRAME_BACKGROUND_PIXEL (f)
3170 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3171 f->output_data.x->cursor_pixel
3172 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3173 f->output_data.x->cursor_foreground_pixel
3174 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3175 f->output_data.x->border_pixel
3176 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3177 f->output_data.x->mouse_pixel
3178 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3179 UNGCPRO;
3182 /* Specify the parent under which to make this X window. */
3184 if (!NILP (parent))
3186 f->output_data.x->parent_desc = (Window) XFASTINT (parent);
3187 f->output_data.x->explicit_parent = 1;
3189 else
3191 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
3192 f->output_data.x->explicit_parent = 0;
3195 /* Set the name; the functions to which we pass f expect the name to
3196 be set. */
3197 if (EQ (name, Qunbound) || NILP (name))
3199 f->name = build_string (dpyinfo->x_id_name);
3200 f->explicit_name = 0;
3202 else
3204 f->name = name;
3205 f->explicit_name = 1;
3206 /* use the frame's title when getting resources for this frame. */
3207 specbind (Qx_resource_name, name);
3210 /* Extract the window parameters from the supplied values
3211 that are needed to determine window geometry. */
3213 Lisp_Object font;
3215 font = x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
3217 BLOCK_INPUT;
3218 /* First, try whatever font the caller has specified. */
3219 if (STRINGP (font))
3221 tem = Fquery_fontset (font, Qnil);
3222 if (STRINGP (tem))
3223 font = x_new_fontset (f, SDATA (tem));
3224 else
3225 font = x_new_font (f, SDATA (font));
3228 /* Try out a font which we hope has bold and italic variations. */
3229 if (!STRINGP (font))
3230 font = x_new_font (f, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
3231 if (!STRINGP (font))
3232 font = x_new_font (f, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3233 if (! STRINGP (font))
3234 font = x_new_font (f, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3235 if (! STRINGP (font))
3236 /* This was formerly the first thing tried, but it finds too many fonts
3237 and takes too long. */
3238 font = x_new_font (f, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
3239 /* If those didn't work, look for something which will at least work. */
3240 if (! STRINGP (font))
3241 font = x_new_font (f, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
3242 UNBLOCK_INPUT;
3243 if (! STRINGP (font))
3244 font = build_string ("fixed");
3246 x_set_frame_parameters (f, Fcons (Fcons (Qfont, font), Qnil));
3249 #ifdef USE_LUCID
3250 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
3251 whereby it fails to get any font. */
3252 xlwmenu_default_font = FRAME_FONT (f);
3253 #endif
3255 x_default_parameter (f, parms, Qborder_width, make_number (2),
3256 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
3258 /* This defaults to 1 in order to match xterm. We recognize either
3259 internalBorderWidth or internalBorder (which is what xterm calls
3260 it). */
3261 if (NILP (Fassq (Qinternal_border_width, parms)))
3263 Lisp_Object value;
3265 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
3266 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
3267 if (! EQ (value, Qunbound))
3268 parms = Fcons (Fcons (Qinternal_border_width, value),
3269 parms);
3271 x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
3272 "internalBorderWidth", "internalBorderWidth",
3273 RES_TYPE_NUMBER);
3274 x_default_parameter (f, parms, Qvertical_scroll_bars, Qleft,
3275 "verticalScrollBars", "ScrollBars",
3276 RES_TYPE_SYMBOL);
3278 /* Also do the stuff which must be set before the window exists. */
3279 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
3280 "foreground", "Foreground", RES_TYPE_STRING);
3281 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
3282 "background", "Background", RES_TYPE_STRING);
3283 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
3284 "pointerColor", "Foreground", RES_TYPE_STRING);
3285 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
3286 "cursorColor", "Foreground", RES_TYPE_STRING);
3287 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
3288 "borderColor", "BorderColor", RES_TYPE_STRING);
3289 x_default_parameter (f, parms, Qscreen_gamma, Qnil,
3290 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
3291 x_default_parameter (f, parms, Qline_spacing, Qnil,
3292 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
3293 x_default_parameter (f, parms, Qleft_fringe, Qnil,
3294 "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
3295 x_default_parameter (f, parms, Qright_fringe, Qnil,
3296 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
3298 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_foreground,
3299 "scrollBarForeground",
3300 "ScrollBarForeground", 1);
3301 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_background,
3302 "scrollBarBackground",
3303 "ScrollBarBackground", 0);
3305 /* Init faces before x_default_parameter is called for scroll-bar
3306 parameters because that function calls x_set_scroll_bar_width,
3307 which calls change_frame_size, which calls Fset_window_buffer,
3308 which runs hooks, which call Fvertical_motion. At the end, we
3309 end up in init_iterator with a null face cache, which should not
3310 happen. */
3311 init_frame_faces (f);
3313 x_default_parameter (f, parms, Qmenu_bar_lines, make_number (1),
3314 "menuBar", "MenuBar", RES_TYPE_NUMBER);
3315 x_default_parameter (f, parms, Qtool_bar_lines, make_number (1),
3316 "toolBar", "ToolBar", RES_TYPE_NUMBER);
3317 x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
3318 "bufferPredicate", "BufferPredicate",
3319 RES_TYPE_SYMBOL);
3320 x_default_parameter (f, parms, Qtitle, Qnil,
3321 "title", "Title", RES_TYPE_STRING);
3322 x_default_parameter (f, parms, Qwait_for_wm, Qt,
3323 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
3324 x_default_parameter (f, parms, Qfullscreen, Qnil,
3325 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
3327 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
3329 /* Compute the size of the X window. */
3330 window_prompting = x_figure_window_size (f, parms, 1);
3332 tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
3333 f->no_split = minibuffer_only || EQ (tem, Qt);
3335 x_icon_verify (f, parms);
3337 /* Create the X widget or window. */
3338 #ifdef USE_X_TOOLKIT
3339 x_window (f, window_prompting, minibuffer_only);
3340 #else
3341 x_window (f);
3342 #endif
3344 x_icon (f, parms);
3345 x_make_gc (f);
3347 /* Now consider the frame official. */
3348 FRAME_X_DISPLAY_INFO (f)->reference_count++;
3349 Vframe_list = Fcons (frame, Vframe_list);
3351 /* We need to do this after creating the X window, so that the
3352 icon-creation functions can say whose icon they're describing. */
3353 x_default_parameter (f, parms, Qicon_type, Qt,
3354 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
3356 x_default_parameter (f, parms, Qauto_raise, Qnil,
3357 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3358 x_default_parameter (f, parms, Qauto_lower, Qnil,
3359 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3360 x_default_parameter (f, parms, Qcursor_type, Qbox,
3361 "cursorType", "CursorType", RES_TYPE_SYMBOL);
3362 x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
3363 "scrollBarWidth", "ScrollBarWidth",
3364 RES_TYPE_NUMBER);
3366 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3367 Change will not be effected unless different from the current
3368 FRAME_LINES (f). */
3369 width = FRAME_COLS (f);
3370 height = FRAME_LINES (f);
3372 SET_FRAME_COLS (f, 0);
3373 FRAME_LINES (f) = 0;
3374 change_frame_size (f, height, width, 1, 0, 0);
3376 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3377 /* Create the menu bar. */
3378 if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
3380 /* If this signals an error, we haven't set size hints for the
3381 frame and we didn't make it visible. */
3382 initialize_frame_menubar (f);
3384 #ifndef USE_GTK
3385 /* This is a no-op, except under Motif where it arranges the
3386 main window for the widgets on it. */
3387 lw_set_main_areas (f->output_data.x->column_widget,
3388 f->output_data.x->menubar_widget,
3389 f->output_data.x->edit_widget);
3390 #endif /* not USE_GTK */
3392 #endif /* USE_X_TOOLKIT || USE_GTK */
3394 /* Tell the server what size and position, etc, we want, and how
3395 badly we want them. This should be done after we have the menu
3396 bar so that its size can be taken into account. */
3397 BLOCK_INPUT;
3398 x_wm_set_size_hint (f, window_prompting, 0);
3399 UNBLOCK_INPUT;
3401 /* Make the window appear on the frame and enable display, unless
3402 the caller says not to. However, with explicit parent, Emacs
3403 cannot control visibility, so don't try. */
3404 if (! f->output_data.x->explicit_parent)
3406 Lisp_Object visibility;
3408 visibility = x_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
3409 RES_TYPE_SYMBOL);
3410 if (EQ (visibility, Qunbound))
3411 visibility = Qt;
3413 if (EQ (visibility, Qicon))
3414 x_iconify_frame (f);
3415 else if (! NILP (visibility))
3416 x_make_frame_visible (f);
3417 else
3418 /* Must have been Qnil. */
3422 /* Set the WM leader property. GTK does this itself, so this is not
3423 needed when using GTK. */
3424 if (dpyinfo->client_leader_window != 0)
3426 BLOCK_INPUT;
3427 XChangeProperty (FRAME_X_DISPLAY (f),
3428 FRAME_OUTER_WINDOW (f),
3429 dpyinfo->Xatom_wm_client_leader,
3430 XA_WINDOW, 32, PropModeReplace,
3431 (unsigned char *) &dpyinfo->client_leader_window, 1);
3432 UNBLOCK_INPUT;
3435 /* Initialize `default-minibuffer-frame' in case this is the first
3436 frame on this terminal. */
3437 if (FRAME_HAS_MINIBUF_P (f)
3438 && (!FRAMEP (kb->Vdefault_minibuffer_frame)
3439 || !FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame))))
3440 kb->Vdefault_minibuffer_frame = frame;
3442 /* All remaining specified parameters, which have not been "used"
3443 by x_get_arg and friends, now go in the misc. alist of the frame. */
3444 for (tem = parms; CONSP (tem); tem = XCDR (tem))
3445 if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
3446 f->param_alist = Fcons (XCAR (tem), f->param_alist);
3448 UNGCPRO;
3450 /* Make sure windows on this frame appear in calls to next-window
3451 and similar functions. */
3452 Vwindow_list = Qnil;
3454 return unbind_to (count, frame);
3458 /* FRAME is used only to get a handle on the X display. We don't pass the
3459 display info directly because we're called from frame.c, which doesn't
3460 know about that structure. */
3462 Lisp_Object
3463 x_get_focus_frame (frame)
3464 struct frame *frame;
3466 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (frame);
3467 Lisp_Object xfocus;
3468 if (! dpyinfo->x_focus_frame)
3469 return Qnil;
3471 XSETFRAME (xfocus, dpyinfo->x_focus_frame);
3472 return xfocus;
3476 /* In certain situations, when the window manager follows a
3477 click-to-focus policy, there seems to be no way around calling
3478 XSetInputFocus to give another frame the input focus .
3480 In an ideal world, XSetInputFocus should generally be avoided so
3481 that applications don't interfere with the window manager's focus
3482 policy. But I think it's okay to use when it's clearly done
3483 following a user-command. */
3485 DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
3486 doc: /* Set the input focus to FRAME.
3487 FRAME nil means use the selected frame. */)
3488 (frame)
3489 Lisp_Object frame;
3491 struct frame *f = check_x_frame (frame);
3492 Display *dpy = FRAME_X_DISPLAY (f);
3494 BLOCK_INPUT;
3495 x_catch_errors (dpy);
3496 XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3497 RevertToParent, CurrentTime);
3498 x_ewmh_activate_frame (f);
3499 x_uncatch_errors ();
3500 UNBLOCK_INPUT;
3502 return Qnil;
3506 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
3507 doc: /* Internal function called by `color-defined-p', which see. */)
3508 (color, frame)
3509 Lisp_Object color, frame;
3511 XColor foo;
3512 FRAME_PTR f = check_x_frame (frame);
3514 CHECK_STRING (color);
3516 if (x_defined_color (f, SDATA (color), &foo, 0))
3517 return Qt;
3518 else
3519 return Qnil;
3522 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
3523 doc: /* Internal function called by `color-values', which see. */)
3524 (color, frame)
3525 Lisp_Object color, frame;
3527 XColor foo;
3528 FRAME_PTR f = check_x_frame (frame);
3530 CHECK_STRING (color);
3532 if (x_defined_color (f, SDATA (color), &foo, 0))
3533 return list3 (make_number (foo.red),
3534 make_number (foo.green),
3535 make_number (foo.blue));
3536 else
3537 return Qnil;
3540 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
3541 doc: /* Internal function called by `display-color-p', which see. */)
3542 (terminal)
3543 Lisp_Object terminal;
3545 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3547 if (dpyinfo->n_planes <= 2)
3548 return Qnil;
3550 switch (dpyinfo->visual->class)
3552 case StaticColor:
3553 case PseudoColor:
3554 case TrueColor:
3555 case DirectColor:
3556 return Qt;
3558 default:
3559 return Qnil;
3563 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
3564 0, 1, 0,
3565 doc: /* Return t if the X display supports shades of gray.
3566 Note that color displays do support shades of gray.
3567 The optional argument TERMINAL specifies which display to ask about.
3568 TERMINAL should be a terminal id, a frame or a display name (a string).
3569 If omitted or nil, that stands for the selected frame's display. */)
3570 (terminal)
3571 Lisp_Object terminal;
3573 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3575 if (dpyinfo->n_planes <= 1)
3576 return Qnil;
3578 switch (dpyinfo->visual->class)
3580 case StaticColor:
3581 case PseudoColor:
3582 case TrueColor:
3583 case DirectColor:
3584 case StaticGray:
3585 case GrayScale:
3586 return Qt;
3588 default:
3589 return Qnil;
3593 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
3594 0, 1, 0,
3595 doc: /* Return the width in pixels of the X display TERMINAL.
3596 The optional argument TERMINAL specifies which display to ask about.
3597 TERMINAL should be a terminal id, a frame or a display name (a string).
3598 If omitted or nil, that stands for the selected frame's display. */)
3599 (terminal)
3600 Lisp_Object terminal;
3602 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3604 return make_number (dpyinfo->width);
3607 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
3608 Sx_display_pixel_height, 0, 1, 0,
3609 doc: /* Return the height in pixels of the X display TERMINAL.
3610 The optional argument TERMINAL specifies which display to ask about.
3611 TERMINAL should be a terminal id, a frame or a display name (a string).
3612 If omitted or nil, that stands for the selected frame's display. */)
3613 (terminal)
3614 Lisp_Object terminal;
3616 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3618 return make_number (dpyinfo->height);
3621 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
3622 0, 1, 0,
3623 doc: /* Return the number of bitplanes of the X display TERMINAL.
3624 The optional argument TERMINAL specifies which display to ask about.
3625 TERMINAL should be a terminal id, a frame or a display name (a string).
3626 If omitted or nil, that stands for the selected frame's display. */)
3627 (terminal)
3628 Lisp_Object terminal;
3630 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3632 return make_number (dpyinfo->n_planes);
3635 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
3636 0, 1, 0,
3637 doc: /* Return the number of color cells of the X display TERMINAL.
3638 The optional argument TERMINAL specifies which display to ask about.
3639 TERMINAL should be a terminal id, a frame or a display name (a string).
3640 If omitted or nil, that stands for the selected frame's display. */)
3641 (terminal)
3642 Lisp_Object terminal;
3644 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3646 int nr_planes = DisplayPlanes (dpyinfo->display,
3647 XScreenNumberOfScreen (dpyinfo->screen));
3649 /* Truncate nr_planes to 24 to avoid integer overflow.
3650 Some displays says 32, but only 24 bits are actually significant.
3651 There are only very few and rare video cards that have more than
3652 24 significant bits. Also 24 bits is more than 16 million colors,
3653 it "should be enough for everyone". */
3654 if (nr_planes > 24) nr_planes = 24;
3656 return make_number (1 << nr_planes);
3659 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
3660 Sx_server_max_request_size,
3661 0, 1, 0,
3662 doc: /* Return the maximum request size of the X server of display TERMINAL.
3663 The optional argument TERMINAL specifies which display to ask about.
3664 TERMINAL should be a terminal id, a frame or a display name (a string).
3665 If omitted or nil, that stands for the selected frame's display. */)
3666 (terminal)
3667 Lisp_Object terminal;
3669 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3671 return make_number (MAXREQUEST (dpyinfo->display));
3674 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
3675 doc: /* Return the "vendor ID" string of the X server of display TERMINAL.
3676 \(Labelling every distributor as a "vendor" embodies the false assumption
3677 that operating systems cannot be developed and distributed noncommercially.)
3678 The optional argument TERMINAL specifies which display to ask about.
3679 TERMINAL should be a terminal id, a frame or a display name (a string).
3680 If omitted or nil, that stands for the selected frame's display. */)
3681 (terminal)
3682 Lisp_Object terminal;
3684 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3685 char *vendor = ServerVendor (dpyinfo->display);
3687 if (! vendor) vendor = "";
3688 return build_string (vendor);
3691 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
3692 doc: /* Return the version numbers of the X server of display TERMINAL.
3693 The value is a list of three integers: the major and minor
3694 version numbers of the X Protocol in use, and the distributor-specific release
3695 number. See also the function `x-server-vendor'.
3697 The optional argument TERMINAL specifies which display to ask about.
3698 TERMINAL should be a terminal id, a frame or a display name (a string).
3699 If omitted or nil, that stands for the selected frame's display. */)
3700 (terminal)
3701 Lisp_Object terminal;
3703 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3704 Display *dpy = dpyinfo->display;
3706 return Fcons (make_number (ProtocolVersion (dpy)),
3707 Fcons (make_number (ProtocolRevision (dpy)),
3708 Fcons (make_number (VendorRelease (dpy)), Qnil)));
3711 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
3712 doc: /* Return the number of screens on the X server of display TERMINAL.
3713 The optional argument TERMINAL specifies which display to ask about.
3714 TERMINAL should be a terminal id, a frame or a display name (a string).
3715 If omitted or nil, that stands for the selected frame's display. */)
3716 (terminal)
3717 Lisp_Object terminal;
3719 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3721 return make_number (ScreenCount (dpyinfo->display));
3724 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
3725 doc: /* Return the height in millimeters of the X display TERMINAL.
3726 The optional argument TERMINAL specifies which display to ask about.
3727 TERMINAL should be a terminal id, a frame or a display name (a string).
3728 If omitted or nil, that stands for the selected frame's display. */)
3729 (terminal)
3730 Lisp_Object terminal;
3732 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3734 return make_number (HeightMMOfScreen (dpyinfo->screen));
3737 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
3738 doc: /* Return the width in millimeters of the X display TERMINAL.
3739 The optional argument TERMINAL specifies which display to ask about.
3740 TERMINAL should be a terminal id, a frame or a display name (a string).
3741 If omitted or nil, that stands for the selected frame's display. */)
3742 (terminal)
3743 Lisp_Object terminal;
3745 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3747 return make_number (WidthMMOfScreen (dpyinfo->screen));
3750 DEFUN ("x-display-backing-store", Fx_display_backing_store,
3751 Sx_display_backing_store, 0, 1, 0,
3752 doc: /* Return an indication of whether X display TERMINAL does backing store.
3753 The value may be `always', `when-mapped', or `not-useful'.
3754 The optional argument TERMINAL specifies which display to ask about.
3755 TERMINAL should be a terminal id, a frame or a display name (a string).
3756 If omitted or nil, that stands for the selected frame's display. */)
3757 (terminal)
3758 Lisp_Object terminal;
3760 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3761 Lisp_Object result;
3763 switch (DoesBackingStore (dpyinfo->screen))
3765 case Always:
3766 result = intern ("always");
3767 break;
3769 case WhenMapped:
3770 result = intern ("when-mapped");
3771 break;
3773 case NotUseful:
3774 result = intern ("not-useful");
3775 break;
3777 default:
3778 error ("Strange value for BackingStore parameter of screen");
3779 result = Qnil;
3782 return result;
3785 DEFUN ("x-display-visual-class", Fx_display_visual_class,
3786 Sx_display_visual_class, 0, 1, 0,
3787 doc: /* Return the visual class of the X display TERMINAL.
3788 The value is one of the symbols `static-gray', `gray-scale',
3789 `static-color', `pseudo-color', `true-color', or `direct-color'.
3791 The optional argument TERMINAL specifies which display to ask about.
3792 TERMINAL should a terminal id, a frame or a display name (a string).
3793 If omitted or nil, that stands for the selected frame's display. */)
3794 (terminal)
3795 Lisp_Object terminal;
3797 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3798 Lisp_Object result;
3800 switch (dpyinfo->visual->class)
3802 case StaticGray:
3803 result = intern ("static-gray");
3804 break;
3805 case GrayScale:
3806 result = intern ("gray-scale");
3807 break;
3808 case StaticColor:
3809 result = intern ("static-color");
3810 break;
3811 case PseudoColor:
3812 result = intern ("pseudo-color");
3813 break;
3814 case TrueColor:
3815 result = intern ("true-color");
3816 break;
3817 case DirectColor:
3818 result = intern ("direct-color");
3819 break;
3820 default:
3821 error ("Display has an unknown visual class");
3822 result = Qnil;
3825 return result;
3828 DEFUN ("x-display-save-under", Fx_display_save_under,
3829 Sx_display_save_under, 0, 1, 0,
3830 doc: /* Return t if the X display TERMINAL supports the save-under feature.
3831 The optional argument TERMINAL specifies which display to ask about.
3832 TERMINAL should be a terminal id, a frame or a display name (a string).
3833 If omitted or nil, that stands for the selected frame's display. */)
3834 (terminal)
3835 Lisp_Object terminal;
3837 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3839 if (DoesSaveUnders (dpyinfo->screen) == True)
3840 return Qt;
3841 else
3842 return Qnil;
3846 x_pixel_width (f)
3847 register struct frame *f;
3849 return FRAME_PIXEL_WIDTH (f);
3853 x_pixel_height (f)
3854 register struct frame *f;
3856 return FRAME_PIXEL_HEIGHT (f);
3860 x_char_width (f)
3861 register struct frame *f;
3863 return FRAME_COLUMN_WIDTH (f);
3867 x_char_height (f)
3868 register struct frame *f;
3870 return FRAME_LINE_HEIGHT (f);
3874 x_screen_planes (f)
3875 register struct frame *f;
3877 return FRAME_X_DISPLAY_INFO (f)->n_planes;
3882 /************************************************************************
3883 X Displays
3884 ************************************************************************/
3887 /* Mapping visual names to visuals. */
3889 static struct visual_class
3891 char *name;
3892 int class;
3894 visual_classes[] =
3896 {"StaticGray", StaticGray},
3897 {"GrayScale", GrayScale},
3898 {"StaticColor", StaticColor},
3899 {"PseudoColor", PseudoColor},
3900 {"TrueColor", TrueColor},
3901 {"DirectColor", DirectColor},
3902 {NULL, 0}
3906 #ifndef HAVE_XSCREENNUMBEROFSCREEN
3908 /* Value is the screen number of screen SCR. This is a substitute for
3909 the X function with the same name when that doesn't exist. */
3912 XScreenNumberOfScreen (scr)
3913 register Screen *scr;
3915 Display *dpy = scr->display;
3916 int i;
3918 for (i = 0; i < dpy->nscreens; ++i)
3919 if (scr == dpy->screens + i)
3920 break;
3922 return i;
3925 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
3928 /* Select the visual that should be used on display DPYINFO. Set
3929 members of DPYINFO appropriately. Called from x_term_init. */
3931 void
3932 select_visual (dpyinfo)
3933 struct x_display_info *dpyinfo;
3935 Display *dpy = dpyinfo->display;
3936 Screen *screen = dpyinfo->screen;
3937 Lisp_Object value;
3939 /* See if a visual is specified. */
3940 value = display_x_get_resource (dpyinfo,
3941 build_string ("visualClass"),
3942 build_string ("VisualClass"),
3943 Qnil, Qnil);
3944 if (STRINGP (value))
3946 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
3947 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
3948 depth, a decimal number. NAME is compared with case ignored. */
3949 char *s = (char *) alloca (SBYTES (value) + 1);
3950 char *dash;
3951 int i, class = -1;
3952 XVisualInfo vinfo;
3954 strcpy (s, SDATA (value));
3955 dash = index (s, '-');
3956 if (dash)
3958 dpyinfo->n_planes = atoi (dash + 1);
3959 *dash = '\0';
3961 else
3962 /* We won't find a matching visual with depth 0, so that
3963 an error will be printed below. */
3964 dpyinfo->n_planes = 0;
3966 /* Determine the visual class. */
3967 for (i = 0; visual_classes[i].name; ++i)
3968 if (xstricmp (s, visual_classes[i].name) == 0)
3970 class = visual_classes[i].class;
3971 break;
3974 /* Look up a matching visual for the specified class. */
3975 if (class == -1
3976 || !XMatchVisualInfo (dpy, XScreenNumberOfScreen (screen),
3977 dpyinfo->n_planes, class, &vinfo))
3978 fatal ("Invalid visual specification `%s'", SDATA (value));
3980 dpyinfo->visual = vinfo.visual;
3982 else
3984 int n_visuals;
3985 XVisualInfo *vinfo, vinfo_template;
3987 dpyinfo->visual = DefaultVisualOfScreen (screen);
3989 vinfo_template.visualid = XVisualIDFromVisual (dpyinfo->visual);
3990 vinfo_template.screen = XScreenNumberOfScreen (screen);
3991 vinfo = XGetVisualInfo (dpy, VisualIDMask | VisualScreenMask,
3992 &vinfo_template, &n_visuals);
3993 if (n_visuals != 1)
3994 fatal ("Can't get proper X visual info");
3996 dpyinfo->n_planes = vinfo->depth;
3997 XFree ((char *) vinfo);
4002 /* Return the X display structure for the display named NAME.
4003 Open a new connection if necessary. */
4005 struct x_display_info *
4006 x_display_info_for_name (name)
4007 Lisp_Object name;
4009 Lisp_Object names;
4010 struct x_display_info *dpyinfo;
4012 CHECK_STRING (name);
4014 #if 0
4015 if (! EQ (Vinitial_window_system, intern ("x")))
4016 error ("Not using X Windows"); /* That doesn't stop us anymore. */
4017 #endif
4019 for (dpyinfo = x_display_list, names = x_display_name_list;
4020 dpyinfo;
4021 dpyinfo = dpyinfo->next, names = XCDR (names))
4023 Lisp_Object tem;
4024 tem = Fstring_equal (XCAR (XCAR (names)), name);
4025 if (!NILP (tem))
4026 return dpyinfo;
4029 /* Use this general default value to start with. */
4030 Vx_resource_name = Vinvocation_name;
4032 validate_x_resource_name ();
4034 dpyinfo = x_term_init (name, (char *)0,
4035 (char *) SDATA (Vx_resource_name));
4037 if (dpyinfo == 0)
4038 error ("Cannot connect to X server %s", SDATA (name));
4040 x_in_use = 1;
4041 XSETFASTINT (Vwindow_system_version, 11);
4043 return dpyinfo;
4047 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
4048 1, 3, 0,
4049 doc: /* Open a connection to an X server.
4050 DISPLAY is the name of the display to connect to.
4051 Optional second arg XRM-STRING is a string of resources in xrdb format.
4052 If the optional third arg MUST-SUCCEED is non-nil,
4053 terminate Emacs if we can't open the connection. */)
4054 (display, xrm_string, must_succeed)
4055 Lisp_Object display, xrm_string, must_succeed;
4057 unsigned char *xrm_option;
4058 struct x_display_info *dpyinfo;
4060 CHECK_STRING (display);
4061 if (! NILP (xrm_string))
4062 CHECK_STRING (xrm_string);
4064 #if 0
4065 if (! EQ (Vinitial_window_system, intern ("x")))
4066 error ("Not using X Windows"); /* That doesn't stop us anymore. */
4067 #endif
4069 if (! NILP (xrm_string))
4070 xrm_option = (unsigned char *) SDATA (xrm_string);
4071 else
4072 xrm_option = (unsigned char *) 0;
4074 validate_x_resource_name ();
4076 /* This is what opens the connection and sets x_current_display.
4077 This also initializes many symbols, such as those used for input. */
4078 dpyinfo = x_term_init (display, xrm_option,
4079 (char *) SDATA (Vx_resource_name));
4081 if (dpyinfo == 0)
4083 if (!NILP (must_succeed))
4084 fatal ("Cannot connect to X server %s.\n\
4085 Check the DISPLAY environment variable or use `-d'.\n\
4086 Also use the `xauth' program to verify that you have the proper\n\
4087 authorization information needed to connect the X server.\n\
4088 An insecure way to solve the problem may be to use `xhost'.\n",
4089 SDATA (display));
4090 else
4091 error ("Cannot connect to X server %s", SDATA (display));
4094 x_in_use = 1;
4096 XSETFASTINT (Vwindow_system_version, 11);
4097 return Qnil;
4100 DEFUN ("x-close-connection", Fx_close_connection,
4101 Sx_close_connection, 1, 1, 0,
4102 doc: /* Close the connection to TERMINAL's X server.
4103 For TERMINAL, specify a terminal id, a frame or a display name (a
4104 string). If TERMINAL is nil, that stands for the selected frame's
4105 terminal. */)
4106 (terminal)
4107 Lisp_Object terminal;
4109 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4111 if (dpyinfo->reference_count > 0)
4112 error ("Display still has frames on it");
4114 x_delete_terminal (dpyinfo->terminal);
4116 return Qnil;
4119 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
4120 doc: /* Return the list of display names that Emacs has connections to. */)
4123 Lisp_Object tail, result;
4125 result = Qnil;
4126 for (tail = x_display_name_list; CONSP (tail); tail = XCDR (tail))
4127 result = Fcons (XCAR (XCAR (tail)), result);
4129 return result;
4132 DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
4133 doc: /* If ON is non-nil, report X errors as soon as the erring request is made.
4134 If ON is nil, allow buffering of requests.
4135 Turning on synchronization prohibits the Xlib routines from buffering
4136 requests and seriously degrades performance, but makes debugging much
4137 easier.
4138 The optional second argument TERMINAL specifies which display to act on.
4139 TERMINAL should be a terminal id, a frame or a display name (a string).
4140 If TERMINAL is omitted or nil, that stands for the selected frame's display. */)
4141 (on, terminal)
4142 Lisp_Object terminal, on;
4144 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4146 XSynchronize (dpyinfo->display, !EQ (on, Qnil));
4148 return Qnil;
4151 /* Wait for responses to all X commands issued so far for frame F. */
4153 void
4154 x_sync (f)
4155 FRAME_PTR f;
4157 BLOCK_INPUT;
4158 XSync (FRAME_X_DISPLAY (f), False);
4159 UNBLOCK_INPUT;
4163 /***********************************************************************
4164 Window properties
4165 ***********************************************************************/
4167 DEFUN ("x-change-window-property", Fx_change_window_property,
4168 Sx_change_window_property, 2, 6, 0,
4169 doc: /* Change window property PROP to VALUE on the X window of FRAME.
4170 PROP must be a string.
4171 VALUE may be a string or a list of conses, numbers and/or strings.
4172 If an element in the list is a string, it is converted to
4173 an Atom and the value of the Atom is used. If an element is a cons,
4174 it is converted to a 32 bit number where the car is the 16 top bits and the
4175 cdr is the lower 16 bits.
4176 FRAME nil or omitted means use the selected frame.
4177 If TYPE is given and non-nil, it is the name of the type of VALUE.
4178 If TYPE is not given or nil, the type is STRING.
4179 FORMAT gives the size in bits of each element if VALUE is a list.
4180 It must be one of 8, 16 or 32.
4181 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
4182 If OUTER_P is non-nil, the property is changed for the outer X window of
4183 FRAME. Default is to change on the edit X window.
4185 Value is VALUE. */)
4186 (prop, value, frame, type, format, outer_p)
4187 Lisp_Object prop, value, frame, type, format, outer_p;
4189 struct frame *f = check_x_frame (frame);
4190 Atom prop_atom;
4191 Atom target_type = XA_STRING;
4192 int element_format = 8;
4193 unsigned char *data;
4194 int nelements;
4195 Window w;
4197 CHECK_STRING (prop);
4199 if (! NILP (format))
4201 CHECK_NUMBER (format);
4202 element_format = XFASTINT (format);
4204 if (element_format != 8 && element_format != 16
4205 && element_format != 32)
4206 error ("FORMAT must be one of 8, 16 or 32");
4209 if (CONSP (value))
4211 nelements = x_check_property_data (value);
4212 if (nelements == -1)
4213 error ("Bad data in VALUE, must be number, string or cons");
4215 if (element_format == 8)
4216 data = (unsigned char *) xmalloc (nelements);
4217 else if (element_format == 16)
4218 data = (unsigned char *) xmalloc (nelements*2);
4219 else /* format == 32 */
4220 /* The man page for XChangeProperty:
4221 "If the specified format is 32, the property data must be a
4222 long array."
4223 This applies even if long is more than 64 bits. The X library
4224 converts to 32 bits before sending to the X server. */
4225 data = (unsigned char *) xmalloc (nelements * sizeof(long));
4227 x_fill_property_data (FRAME_X_DISPLAY (f), value, data, element_format);
4229 else
4231 CHECK_STRING (value);
4232 data = SDATA (value);
4233 nelements = SCHARS (value);
4236 BLOCK_INPUT;
4237 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4238 if (! NILP (type))
4240 CHECK_STRING (type);
4241 target_type = XInternAtom (FRAME_X_DISPLAY (f), SDATA (type), False);
4244 if (! NILP (outer_p)) w = FRAME_OUTER_WINDOW (f);
4245 else w = FRAME_X_WINDOW (f);
4247 XChangeProperty (FRAME_X_DISPLAY (f), w,
4248 prop_atom, target_type, element_format, PropModeReplace,
4249 data, nelements);
4251 if (CONSP (value)) xfree (data);
4253 /* Make sure the property is set when we return. */
4254 XFlush (FRAME_X_DISPLAY (f));
4255 UNBLOCK_INPUT;
4257 return value;
4261 DEFUN ("x-delete-window-property", Fx_delete_window_property,
4262 Sx_delete_window_property, 1, 2, 0,
4263 doc: /* Remove window property PROP from X window of FRAME.
4264 FRAME nil or omitted means use the selected frame. Value is PROP. */)
4265 (prop, frame)
4266 Lisp_Object prop, frame;
4268 struct frame *f = check_x_frame (frame);
4269 Atom prop_atom;
4271 CHECK_STRING (prop);
4272 BLOCK_INPUT;
4273 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4274 XDeleteProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), prop_atom);
4276 /* Make sure the property is removed when we return. */
4277 XFlush (FRAME_X_DISPLAY (f));
4278 UNBLOCK_INPUT;
4280 return prop;
4284 DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
4285 1, 6, 0,
4286 doc: /* Value is the value of window property PROP on FRAME.
4287 If FRAME is nil or omitted, use the selected frame.
4288 If TYPE is nil or omitted, get the property as a string. Otherwise TYPE
4289 is the name of the Atom that denotes the type expected.
4290 If SOURCE is non-nil, get the property on that window instead of from
4291 FRAME. The number 0 denotes the root window.
4292 If DELETE_P is non-nil, delete the property after retreiving it.
4293 If VECTOR_RET_P is non-nil, don't return a string but a vector of values.
4295 Value is nil if FRAME hasn't a property with name PROP or if PROP has
4296 no value of TYPE. */)
4297 (prop, frame, type, source, delete_p, vector_ret_p)
4298 Lisp_Object prop, frame, type, source, delete_p, vector_ret_p;
4300 struct frame *f = check_x_frame (frame);
4301 Atom prop_atom;
4302 int rc;
4303 Lisp_Object prop_value = Qnil;
4304 unsigned char *tmp_data = NULL;
4305 Atom actual_type;
4306 Atom target_type = XA_STRING;
4307 int actual_format;
4308 unsigned long actual_size, bytes_remaining;
4309 Window target_window = FRAME_X_WINDOW (f);
4310 struct gcpro gcpro1;
4312 GCPRO1 (prop_value);
4313 CHECK_STRING (prop);
4315 if (! NILP (source))
4317 if (NUMBERP (source))
4319 if (FLOATP (source))
4320 target_window = (Window) XFLOAT (source);
4321 else
4322 target_window = XFASTINT (source);
4324 if (target_window == 0)
4325 target_window = FRAME_X_DISPLAY_INFO (f)->root_window;
4327 else if (CONSP (source))
4328 target_window = cons_to_long (source);
4331 BLOCK_INPUT;
4332 if (STRINGP (type))
4334 if (strcmp ("AnyPropertyType", SDATA (type)) == 0)
4335 target_type = AnyPropertyType;
4336 else
4337 target_type = XInternAtom (FRAME_X_DISPLAY (f), SDATA (type), False);
4340 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4341 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4342 prop_atom, 0, 0, False, target_type,
4343 &actual_type, &actual_format, &actual_size,
4344 &bytes_remaining, &tmp_data);
4345 if (rc == Success)
4347 int size = bytes_remaining;
4349 XFree (tmp_data);
4350 tmp_data = NULL;
4352 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4353 prop_atom, 0, bytes_remaining,
4354 ! NILP (delete_p), target_type,
4355 &actual_type, &actual_format,
4356 &actual_size, &bytes_remaining,
4357 &tmp_data);
4358 if (rc == Success && tmp_data)
4360 /* The man page for XGetWindowProperty says:
4361 "If the returned format is 32, the returned data is represented
4362 as a long array and should be cast to that type to obtain the
4363 elements."
4364 This applies even if long is more than 32 bits, the X library
4365 converts from 32 bit elements received from the X server to long
4366 and passes the long array to us. Thus, for that case bcopy can not
4367 be used. We convert to a 32 bit type here, because so much code
4368 assume on that.
4370 The bytes and offsets passed to XGetWindowProperty refers to the
4371 property and those are indeed in 32 bit quantities if format is
4372 32. */
4374 if (actual_format == 32 && actual_format < BITS_PER_LONG)
4376 unsigned long i;
4377 int *idata = (int *) tmp_data;
4378 long *ldata = (long *) tmp_data;
4380 for (i = 0; i < actual_size; ++i)
4381 idata[i] = (int) ldata[i];
4384 if (NILP (vector_ret_p))
4385 prop_value = make_string (tmp_data, size);
4386 else
4387 prop_value = x_property_data_to_lisp (f,
4388 tmp_data,
4389 actual_type,
4390 actual_format,
4391 actual_size);
4394 if (tmp_data) XFree (tmp_data);
4397 UNBLOCK_INPUT;
4398 UNGCPRO;
4399 return prop_value;
4404 /***********************************************************************
4405 Busy cursor
4406 ***********************************************************************/
4408 /* If non-null, an asynchronous timer that, when it expires, displays
4409 an hourglass cursor on all frames. */
4411 static struct atimer *hourglass_atimer;
4413 /* Non-zero means an hourglass cursor is currently shown. */
4415 static int hourglass_shown_p;
4417 /* Number of seconds to wait before displaying an hourglass cursor. */
4419 static Lisp_Object Vhourglass_delay;
4421 /* Default number of seconds to wait before displaying an hourglass
4422 cursor. */
4424 #define DEFAULT_HOURGLASS_DELAY 1
4426 /* Function prototypes. */
4428 static void show_hourglass P_ ((struct atimer *));
4429 static void hide_hourglass P_ ((void));
4431 /* Return non-zero if houglass timer has been started or hourglass is shown. */
4434 hourglass_started ()
4436 return hourglass_shown_p || hourglass_atimer != NULL;
4440 /* Cancel a currently active hourglass timer, and start a new one. */
4442 void
4443 start_hourglass ()
4445 EMACS_TIME delay;
4446 int secs, usecs = 0;
4448 cancel_hourglass ();
4450 if (INTEGERP (Vhourglass_delay)
4451 && XINT (Vhourglass_delay) > 0)
4452 secs = XFASTINT (Vhourglass_delay);
4453 else if (FLOATP (Vhourglass_delay)
4454 && XFLOAT_DATA (Vhourglass_delay) > 0)
4456 Lisp_Object tem;
4457 tem = Ftruncate (Vhourglass_delay, Qnil);
4458 secs = XFASTINT (tem);
4459 usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000;
4461 else
4462 secs = DEFAULT_HOURGLASS_DELAY;
4464 EMACS_SET_SECS_USECS (delay, secs, usecs);
4465 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
4466 show_hourglass, NULL);
4470 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
4471 shown. */
4473 void
4474 cancel_hourglass ()
4476 if (hourglass_atimer)
4478 cancel_atimer (hourglass_atimer);
4479 hourglass_atimer = NULL;
4482 if (hourglass_shown_p)
4483 hide_hourglass ();
4487 /* Timer function of hourglass_atimer. TIMER is equal to
4488 hourglass_atimer.
4490 Display an hourglass pointer on all frames by mapping the frames'
4491 hourglass_window. Set the hourglass_p flag in the frames'
4492 output_data.x structure to indicate that an hourglass cursor is
4493 shown on the frames. */
4495 static void
4496 show_hourglass (timer)
4497 struct atimer *timer;
4499 /* The timer implementation will cancel this timer automatically
4500 after this function has run. Set hourglass_atimer to null
4501 so that we know the timer doesn't have to be canceled. */
4502 hourglass_atimer = NULL;
4504 if (!hourglass_shown_p)
4506 Lisp_Object rest, frame;
4508 BLOCK_INPUT;
4510 FOR_EACH_FRAME (rest, frame)
4512 struct frame *f = XFRAME (frame);
4514 if (FRAME_LIVE_P (f) && FRAME_X_P (f) && FRAME_X_DISPLAY (f))
4516 Display *dpy = FRAME_X_DISPLAY (f);
4518 #ifdef USE_X_TOOLKIT
4519 if (f->output_data.x->widget)
4520 #else
4521 if (FRAME_OUTER_WINDOW (f))
4522 #endif
4524 f->output_data.x->hourglass_p = 1;
4526 if (!f->output_data.x->hourglass_window)
4528 unsigned long mask = CWCursor;
4529 XSetWindowAttributes attrs;
4530 #ifdef USE_GTK
4531 Window parent = FRAME_X_WINDOW (f);
4532 #else
4533 Window parent = FRAME_OUTER_WINDOW (f);
4534 #endif
4535 attrs.cursor = f->output_data.x->hourglass_cursor;
4537 f->output_data.x->hourglass_window
4538 = XCreateWindow (dpy, parent,
4539 0, 0, 32000, 32000, 0, 0,
4540 InputOnly,
4541 CopyFromParent,
4542 mask, &attrs);
4545 XMapRaised (dpy, f->output_data.x->hourglass_window);
4546 XFlush (dpy);
4551 hourglass_shown_p = 1;
4552 UNBLOCK_INPUT;
4557 /* Hide the hourglass pointer on all frames, if it is currently
4558 shown. */
4560 static void
4561 hide_hourglass ()
4563 if (hourglass_shown_p)
4565 Lisp_Object rest, frame;
4567 BLOCK_INPUT;
4568 FOR_EACH_FRAME (rest, frame)
4570 struct frame *f = XFRAME (frame);
4572 if (FRAME_X_P (f)
4573 /* Watch out for newly created frames. */
4574 && f->output_data.x->hourglass_window)
4576 XUnmapWindow (FRAME_X_DISPLAY (f),
4577 f->output_data.x->hourglass_window);
4578 /* Sync here because XTread_socket looks at the
4579 hourglass_p flag that is reset to zero below. */
4580 XSync (FRAME_X_DISPLAY (f), False);
4581 f->output_data.x->hourglass_p = 0;
4585 hourglass_shown_p = 0;
4586 UNBLOCK_INPUT;
4592 /***********************************************************************
4593 Tool tips
4594 ***********************************************************************/
4596 static Lisp_Object x_create_tip_frame P_ ((struct x_display_info *,
4597 Lisp_Object, Lisp_Object));
4598 static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object,
4599 Lisp_Object, int, int, int *, int *));
4601 /* The frame of a currently visible tooltip. */
4603 Lisp_Object tip_frame;
4605 /* If non-nil, a timer started that hides the last tooltip when it
4606 fires. */
4608 Lisp_Object tip_timer;
4609 Window tip_window;
4611 /* If non-nil, a vector of 3 elements containing the last args
4612 with which x-show-tip was called. See there. */
4614 Lisp_Object last_show_tip_args;
4616 /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
4618 Lisp_Object Vx_max_tooltip_size;
4621 static Lisp_Object
4622 unwind_create_tip_frame (frame)
4623 Lisp_Object frame;
4625 Lisp_Object deleted;
4627 deleted = unwind_create_frame (frame);
4628 if (EQ (deleted, Qt))
4630 tip_window = None;
4631 tip_frame = Qnil;
4634 return deleted;
4638 /* Create a frame for a tooltip on the display described by DPYINFO.
4639 PARMS is a list of frame parameters. TEXT is the string to
4640 display in the tip frame. Value is the frame.
4642 Note that functions called here, esp. x_default_parameter can
4643 signal errors, for instance when a specified color name is
4644 undefined. We have to make sure that we're in a consistent state
4645 when this happens. */
4647 static Lisp_Object
4648 x_create_tip_frame (dpyinfo, parms, text)
4649 struct x_display_info *dpyinfo;
4650 Lisp_Object parms, text;
4652 struct frame *f;
4653 Lisp_Object frame, tem;
4654 Lisp_Object name;
4655 long window_prompting = 0;
4656 int width, height;
4657 int count = SPECPDL_INDEX ();
4658 struct gcpro gcpro1, gcpro2, gcpro3;
4659 int face_change_count_before = face_change_count;
4660 Lisp_Object buffer;
4661 struct buffer *old_buffer;
4663 check_x ();
4665 if (!dpyinfo->terminal->name)
4666 error ("Terminal is not live, can't create new frames on it");
4668 parms = Fcopy_alist (parms);
4670 /* Get the name of the frame to use for resource lookup. */
4671 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
4672 if (!STRINGP (name)
4673 && !EQ (name, Qunbound)
4674 && !NILP (name))
4675 error ("Invalid frame name--not a string or nil");
4677 frame = Qnil;
4678 GCPRO3 (parms, name, frame);
4679 f = make_frame (1);
4680 XSETFRAME (frame, f);
4682 buffer = Fget_buffer_create (build_string (" *tip*"));
4683 Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer, Qnil);
4684 old_buffer = current_buffer;
4685 set_buffer_internal_1 (XBUFFER (buffer));
4686 current_buffer->truncate_lines = Qnil;
4687 specbind (Qinhibit_read_only, Qt);
4688 specbind (Qinhibit_modification_hooks, Qt);
4689 Ferase_buffer ();
4690 Finsert (1, &text);
4691 set_buffer_internal_1 (old_buffer);
4693 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
4694 record_unwind_protect (unwind_create_tip_frame, frame);
4696 f->terminal = dpyinfo->terminal;
4697 f->terminal->reference_count++;
4699 /* By setting the output method, we're essentially saying that
4700 the frame is live, as per FRAME_LIVE_P. If we get a signal
4701 from this point on, x_destroy_window might screw up reference
4702 counts etc. */
4703 f->output_method = output_x_window;
4704 f->output_data.x = (struct x_output *) xmalloc (sizeof (struct x_output));
4705 bzero (f->output_data.x, sizeof (struct x_output));
4706 f->output_data.x->icon_bitmap = -1;
4707 FRAME_FONTSET (f) = -1;
4708 f->output_data.x->scroll_bar_foreground_pixel = -1;
4709 f->output_data.x->scroll_bar_background_pixel = -1;
4710 #ifdef USE_TOOLKIT_SCROLL_BARS
4711 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
4712 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
4713 #endif /* USE_TOOLKIT_SCROLL_BARS */
4714 f->icon_name = Qnil;
4715 FRAME_X_DISPLAY_INFO (f) = dpyinfo;
4716 #if GLYPH_DEBUG
4717 image_cache_refcount = FRAME_X_IMAGE_CACHE (f)->refcount;
4718 dpyinfo_refcount = dpyinfo->reference_count;
4719 #endif /* GLYPH_DEBUG */
4720 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
4721 f->output_data.x->explicit_parent = 0;
4723 /* These colors will be set anyway later, but it's important
4724 to get the color reference counts right, so initialize them! */
4726 Lisp_Object black;
4727 struct gcpro gcpro1;
4729 /* Function x_decode_color can signal an error. Make
4730 sure to initialize color slots so that we won't try
4731 to free colors we haven't allocated. */
4732 FRAME_FOREGROUND_PIXEL (f) = -1;
4733 FRAME_BACKGROUND_PIXEL (f) = -1;
4734 f->output_data.x->cursor_pixel = -1;
4735 f->output_data.x->cursor_foreground_pixel = -1;
4736 f->output_data.x->border_pixel = -1;
4737 f->output_data.x->mouse_pixel = -1;
4739 black = build_string ("black");
4740 GCPRO1 (black);
4741 FRAME_FOREGROUND_PIXEL (f)
4742 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4743 FRAME_BACKGROUND_PIXEL (f)
4744 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4745 f->output_data.x->cursor_pixel
4746 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4747 f->output_data.x->cursor_foreground_pixel
4748 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4749 f->output_data.x->border_pixel
4750 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4751 f->output_data.x->mouse_pixel
4752 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4753 UNGCPRO;
4756 /* Set the name; the functions to which we pass f expect the name to
4757 be set. */
4758 if (EQ (name, Qunbound) || NILP (name))
4760 f->name = build_string (dpyinfo->x_id_name);
4761 f->explicit_name = 0;
4763 else
4765 f->name = name;
4766 f->explicit_name = 1;
4767 /* use the frame's title when getting resources for this frame. */
4768 specbind (Qx_resource_name, name);
4771 /* Extract the window parameters from the supplied values that are
4772 needed to determine window geometry. */
4774 Lisp_Object font;
4776 font = x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
4778 BLOCK_INPUT;
4779 /* First, try whatever font the caller has specified. */
4780 if (STRINGP (font))
4782 tem = Fquery_fontset (font, Qnil);
4783 if (STRINGP (tem))
4784 font = x_new_fontset (f, SDATA (tem));
4785 else
4786 font = x_new_font (f, SDATA (font));
4789 /* Try out a font which we hope has bold and italic variations. */
4790 if (!STRINGP (font))
4791 font = x_new_font (f, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
4792 if (!STRINGP (font))
4793 font = x_new_font (f, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
4794 if (! STRINGP (font))
4795 font = x_new_font (f, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
4796 if (! STRINGP (font))
4797 /* This was formerly the first thing tried, but it finds too many fonts
4798 and takes too long. */
4799 font = x_new_font (f, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
4800 /* If those didn't work, look for something which will at least work. */
4801 if (! STRINGP (font))
4802 font = x_new_font (f, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
4803 UNBLOCK_INPUT;
4804 if (! STRINGP (font))
4805 font = build_string ("fixed");
4807 x_default_parameter (f, parms, Qfont, font,
4808 "font", "Font", RES_TYPE_STRING);
4811 x_default_parameter (f, parms, Qborder_width, make_number (2),
4812 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
4814 /* This defaults to 2 in order to match xterm. We recognize either
4815 internalBorderWidth or internalBorder (which is what xterm calls
4816 it). */
4817 if (NILP (Fassq (Qinternal_border_width, parms)))
4819 Lisp_Object value;
4821 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
4822 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
4823 if (! EQ (value, Qunbound))
4824 parms = Fcons (Fcons (Qinternal_border_width, value),
4825 parms);
4828 x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
4829 "internalBorderWidth", "internalBorderWidth",
4830 RES_TYPE_NUMBER);
4832 /* Also do the stuff which must be set before the window exists. */
4833 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
4834 "foreground", "Foreground", RES_TYPE_STRING);
4835 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
4836 "background", "Background", RES_TYPE_STRING);
4837 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
4838 "pointerColor", "Foreground", RES_TYPE_STRING);
4839 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
4840 "cursorColor", "Foreground", RES_TYPE_STRING);
4841 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
4842 "borderColor", "BorderColor", RES_TYPE_STRING);
4844 /* Init faces before x_default_parameter is called for scroll-bar
4845 parameters because that function calls x_set_scroll_bar_width,
4846 which calls change_frame_size, which calls Fset_window_buffer,
4847 which runs hooks, which call Fvertical_motion. At the end, we
4848 end up in init_iterator with a null face cache, which should not
4849 happen. */
4850 init_frame_faces (f);
4852 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
4854 window_prompting = x_figure_window_size (f, parms, 0);
4857 XSetWindowAttributes attrs;
4858 unsigned long mask;
4860 BLOCK_INPUT;
4861 mask = CWBackPixel | CWOverrideRedirect | CWEventMask;
4862 if (DoesSaveUnders (dpyinfo->screen))
4863 mask |= CWSaveUnder;
4865 /* Window managers look at the override-redirect flag to determine
4866 whether or net to give windows a decoration (Xlib spec, chapter
4867 3.2.8). */
4868 attrs.override_redirect = True;
4869 attrs.save_under = True;
4870 attrs.background_pixel = FRAME_BACKGROUND_PIXEL (f);
4871 /* Arrange for getting MapNotify and UnmapNotify events. */
4872 attrs.event_mask = StructureNotifyMask;
4873 tip_window
4874 = FRAME_X_WINDOW (f)
4875 = XCreateWindow (FRAME_X_DISPLAY (f),
4876 FRAME_X_DISPLAY_INFO (f)->root_window,
4877 /* x, y, width, height */
4878 0, 0, 1, 1,
4879 /* Border. */
4881 CopyFromParent, InputOutput, CopyFromParent,
4882 mask, &attrs);
4883 UNBLOCK_INPUT;
4886 x_make_gc (f);
4888 x_default_parameter (f, parms, Qauto_raise, Qnil,
4889 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
4890 x_default_parameter (f, parms, Qauto_lower, Qnil,
4891 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
4892 x_default_parameter (f, parms, Qcursor_type, Qbox,
4893 "cursorType", "CursorType", RES_TYPE_SYMBOL);
4895 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
4896 Change will not be effected unless different from the current
4897 FRAME_LINES (f). */
4898 width = FRAME_COLS (f);
4899 height = FRAME_LINES (f);
4900 SET_FRAME_COLS (f, 0);
4901 FRAME_LINES (f) = 0;
4902 change_frame_size (f, height, width, 1, 0, 0);
4904 /* Add `tooltip' frame parameter's default value. */
4905 if (NILP (Fframe_parameter (frame, intern ("tooltip"))))
4906 Fmodify_frame_parameters (frame, Fcons (Fcons (intern ("tooltip"), Qt),
4907 Qnil));
4909 /* FIXME - can this be done in a similar way to normal frames?
4910 http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
4912 /* Set the `display-type' frame parameter before setting up faces. */
4914 Lisp_Object disptype;
4916 if (FRAME_X_DISPLAY_INFO (f)->n_planes == 1)
4917 disptype = intern ("mono");
4918 else if (FRAME_X_DISPLAY_INFO (f)->visual->class == GrayScale
4919 || FRAME_X_DISPLAY_INFO (f)->visual->class == StaticGray)
4920 disptype = intern ("grayscale");
4921 else
4922 disptype = intern ("color");
4924 if (NILP (Fframe_parameter (frame, Qdisplay_type)))
4925 Fmodify_frame_parameters (frame, Fcons (Fcons (Qdisplay_type, disptype),
4926 Qnil));
4929 /* Set up faces after all frame parameters are known. This call
4930 also merges in face attributes specified for new frames.
4932 Frame parameters may be changed if .Xdefaults contains
4933 specifications for the default font. For example, if there is an
4934 `Emacs.default.attributeBackground: pink', the `background-color'
4935 attribute of the frame get's set, which let's the internal border
4936 of the tooltip frame appear in pink. Prevent this. */
4938 Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
4940 /* Set tip_frame here, so that */
4941 tip_frame = frame;
4942 call1 (Qface_set_after_frame_default, frame);
4944 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
4945 Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg),
4946 Qnil));
4949 f->no_split = 1;
4951 UNGCPRO;
4953 /* It is now ok to make the frame official even if we get an error
4954 below. And the frame needs to be on Vframe_list or making it
4955 visible won't work. */
4956 Vframe_list = Fcons (frame, Vframe_list);
4958 /* Now that the frame is official, it counts as a reference to
4959 its display. */
4960 FRAME_X_DISPLAY_INFO (f)->reference_count++;
4962 /* Setting attributes of faces of the tooltip frame from resources
4963 and similar will increment face_change_count, which leads to the
4964 clearing of all current matrices. Since this isn't necessary
4965 here, avoid it by resetting face_change_count to the value it
4966 had before we created the tip frame. */
4967 face_change_count = face_change_count_before;
4969 /* Discard the unwind_protect. */
4970 return unbind_to (count, frame);
4974 /* Compute where to display tip frame F. PARMS is the list of frame
4975 parameters for F. DX and DY are specified offsets from the current
4976 location of the mouse. WIDTH and HEIGHT are the width and height
4977 of the tooltip. Return coordinates relative to the root window of
4978 the display in *ROOT_X, and *ROOT_Y. */
4980 static void
4981 compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
4982 struct frame *f;
4983 Lisp_Object parms, dx, dy;
4984 int width, height;
4985 int *root_x, *root_y;
4987 Lisp_Object left, top;
4988 int win_x, win_y;
4989 Window root, child;
4990 unsigned pmask;
4992 /* User-specified position? */
4993 left = Fcdr (Fassq (Qleft, parms));
4994 top = Fcdr (Fassq (Qtop, parms));
4996 /* Move the tooltip window where the mouse pointer is. Resize and
4997 show it. */
4998 if (!INTEGERP (left) || !INTEGERP (top))
5000 BLOCK_INPUT;
5001 XQueryPointer (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
5002 &root, &child, root_x, root_y, &win_x, &win_y, &pmask);
5003 UNBLOCK_INPUT;
5006 if (INTEGERP (top))
5007 *root_y = XINT (top);
5008 else if (*root_y + XINT (dy) <= 0)
5009 *root_y = 0; /* Can happen for negative dy */
5010 else if (*root_y + XINT (dy) + height <= FRAME_X_DISPLAY_INFO (f)->height)
5011 /* It fits below the pointer */
5012 *root_y += XINT (dy);
5013 else if (height + XINT (dy) <= *root_y)
5014 /* It fits above the pointer. */
5015 *root_y -= height + XINT (dy);
5016 else
5017 /* Put it on the top. */
5018 *root_y = 0;
5020 if (INTEGERP (left))
5021 *root_x = XINT (left);
5022 else if (*root_x + XINT (dx) <= 0)
5023 *root_x = 0; /* Can happen for negative dx */
5024 else if (*root_x + XINT (dx) + width <= FRAME_X_DISPLAY_INFO (f)->width)
5025 /* It fits to the right of the pointer. */
5026 *root_x += XINT (dx);
5027 else if (width + XINT (dx) <= *root_x)
5028 /* It fits to the left of the pointer. */
5029 *root_x -= width + XINT (dx);
5030 else
5031 /* Put it left-justified on the screen--it ought to fit that way. */
5032 *root_x = 0;
5036 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
5037 doc: /* Show STRING in a "tooltip" window on frame FRAME.
5038 A tooltip window is a small X window displaying a string.
5040 This is an internal function; Lisp code should call `tooltip-show'.
5042 FRAME nil or omitted means use the selected frame.
5044 PARMS is an optional list of frame parameters which can be used to
5045 change the tooltip's appearance.
5047 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
5048 means use the default timeout of 5 seconds.
5050 If the list of frame parameters PARAMS contains a `left' parameters,
5051 the tooltip is displayed at that x-position. Otherwise it is
5052 displayed at the mouse position, with offset DX added (default is 5 if
5053 DX isn't specified). Likewise for the y-position; if a `top' frame
5054 parameter is specified, it determines the y-position of the tooltip
5055 window, otherwise it is displayed at the mouse position, with offset
5056 DY added (default is -10).
5058 A tooltip's maximum size is specified by `x-max-tooltip-size'.
5059 Text larger than the specified size is clipped. */)
5060 (string, frame, parms, timeout, dx, dy)
5061 Lisp_Object string, frame, parms, timeout, dx, dy;
5063 struct frame *f;
5064 struct window *w;
5065 int root_x, root_y;
5066 struct buffer *old_buffer;
5067 struct text_pos pos;
5068 int i, width, height;
5069 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
5070 int old_windows_or_buffers_changed = windows_or_buffers_changed;
5071 int count = SPECPDL_INDEX ();
5073 specbind (Qinhibit_redisplay, Qt);
5075 GCPRO4 (string, parms, frame, timeout);
5077 CHECK_STRING (string);
5078 f = check_x_frame (frame);
5079 if (NILP (timeout))
5080 timeout = make_number (5);
5081 else
5082 CHECK_NATNUM (timeout);
5084 if (NILP (dx))
5085 dx = make_number (5);
5086 else
5087 CHECK_NUMBER (dx);
5089 if (NILP (dy))
5090 dy = make_number (-10);
5091 else
5092 CHECK_NUMBER (dy);
5094 if (NILP (last_show_tip_args))
5095 last_show_tip_args = Fmake_vector (make_number (3), Qnil);
5097 if (!NILP (tip_frame))
5099 Lisp_Object last_string = AREF (last_show_tip_args, 0);
5100 Lisp_Object last_frame = AREF (last_show_tip_args, 1);
5101 Lisp_Object last_parms = AREF (last_show_tip_args, 2);
5103 if (EQ (frame, last_frame)
5104 && !NILP (Fequal (last_string, string))
5105 && !NILP (Fequal (last_parms, parms)))
5107 struct frame *f = XFRAME (tip_frame);
5109 /* Only DX and DY have changed. */
5110 if (!NILP (tip_timer))
5112 Lisp_Object timer = tip_timer;
5113 tip_timer = Qnil;
5114 call1 (Qcancel_timer, timer);
5117 BLOCK_INPUT;
5118 compute_tip_xy (f, parms, dx, dy, FRAME_PIXEL_WIDTH (f),
5119 FRAME_PIXEL_HEIGHT (f), &root_x, &root_y);
5120 XMoveWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5121 root_x, root_y);
5122 UNBLOCK_INPUT;
5123 goto start_timer;
5127 /* Hide a previous tip, if any. */
5128 Fx_hide_tip ();
5130 ASET (last_show_tip_args, 0, string);
5131 ASET (last_show_tip_args, 1, frame);
5132 ASET (last_show_tip_args, 2, parms);
5134 /* Add default values to frame parameters. */
5135 if (NILP (Fassq (Qname, parms)))
5136 parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
5137 if (NILP (Fassq (Qinternal_border_width, parms)))
5138 parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
5139 if (NILP (Fassq (Qborder_width, parms)))
5140 parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
5141 if (NILP (Fassq (Qborder_color, parms)))
5142 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
5143 if (NILP (Fassq (Qbackground_color, parms)))
5144 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
5145 parms);
5147 /* Create a frame for the tooltip, and record it in the global
5148 variable tip_frame. */
5149 frame = x_create_tip_frame (FRAME_X_DISPLAY_INFO (f), parms, string);
5150 f = XFRAME (frame);
5152 /* Set up the frame's root window. */
5153 w = XWINDOW (FRAME_ROOT_WINDOW (f));
5154 w->left_col = w->top_line = make_number (0);
5156 if (CONSP (Vx_max_tooltip_size)
5157 && INTEGERP (XCAR (Vx_max_tooltip_size))
5158 && XINT (XCAR (Vx_max_tooltip_size)) > 0
5159 && INTEGERP (XCDR (Vx_max_tooltip_size))
5160 && XINT (XCDR (Vx_max_tooltip_size)) > 0)
5162 w->total_cols = XCAR (Vx_max_tooltip_size);
5163 w->total_lines = XCDR (Vx_max_tooltip_size);
5165 else
5167 w->total_cols = make_number (80);
5168 w->total_lines = make_number (40);
5171 FRAME_TOTAL_COLS (f) = XINT (w->total_cols);
5172 adjust_glyphs (f);
5173 w->pseudo_window_p = 1;
5175 /* Display the tooltip text in a temporary buffer. */
5176 old_buffer = current_buffer;
5177 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer));
5178 current_buffer->truncate_lines = Qnil;
5179 clear_glyph_matrix (w->desired_matrix);
5180 clear_glyph_matrix (w->current_matrix);
5181 SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
5182 try_window (FRAME_ROOT_WINDOW (f), pos, 0);
5184 /* Compute width and height of the tooltip. */
5185 width = height = 0;
5186 for (i = 0; i < w->desired_matrix->nrows; ++i)
5188 struct glyph_row *row = &w->desired_matrix->rows[i];
5189 struct glyph *last;
5190 int row_width;
5192 /* Stop at the first empty row at the end. */
5193 if (!row->enabled_p || !row->displays_text_p)
5194 break;
5196 /* Let the row go over the full width of the frame. */
5197 row->full_width_p = 1;
5199 /* There's a glyph at the end of rows that is used to place
5200 the cursor there. Don't include the width of this glyph. */
5201 if (row->used[TEXT_AREA])
5203 last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
5204 row_width = row->pixel_width - last->pixel_width;
5206 else
5207 row_width = row->pixel_width;
5209 height += row->height;
5210 width = max (width, row_width);
5213 /* Add the frame's internal border to the width and height the X
5214 window should have. */
5215 height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5216 width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5218 /* Move the tooltip window where the mouse pointer is. Resize and
5219 show it. */
5220 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
5222 BLOCK_INPUT;
5223 XMoveResizeWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5224 root_x, root_y, width, height);
5225 XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
5226 UNBLOCK_INPUT;
5228 /* Draw into the window. */
5229 w->must_be_updated_p = 1;
5230 update_single_window (w, 1);
5232 /* Restore original current buffer. */
5233 set_buffer_internal_1 (old_buffer);
5234 windows_or_buffers_changed = old_windows_or_buffers_changed;
5236 start_timer:
5237 /* Let the tip disappear after timeout seconds. */
5238 tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
5239 intern ("x-hide-tip"));
5241 UNGCPRO;
5242 return unbind_to (count, Qnil);
5246 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
5247 doc: /* Hide the current tooltip window, if there is any.
5248 Value is t if tooltip was open, nil otherwise. */)
5251 int count;
5252 Lisp_Object deleted, frame, timer;
5253 struct gcpro gcpro1, gcpro2;
5255 /* Return quickly if nothing to do. */
5256 if (NILP (tip_timer) && NILP (tip_frame))
5257 return Qnil;
5259 frame = tip_frame;
5260 timer = tip_timer;
5261 GCPRO2 (frame, timer);
5262 tip_frame = tip_timer = deleted = Qnil;
5264 count = SPECPDL_INDEX ();
5265 specbind (Qinhibit_redisplay, Qt);
5266 specbind (Qinhibit_quit, Qt);
5268 if (!NILP (timer))
5269 call1 (Qcancel_timer, timer);
5271 if (FRAMEP (frame))
5273 Fdelete_frame (frame, Qnil);
5274 deleted = Qt;
5276 #ifdef USE_LUCID
5277 /* Bloodcurdling hack alert: The Lucid menu bar widget's
5278 redisplay procedure is not called when a tip frame over menu
5279 items is unmapped. Redisplay the menu manually... */
5281 struct frame *f = SELECTED_FRAME ();
5282 Widget w = f->output_data.x->menubar_widget;
5283 extern void xlwmenu_redisplay P_ ((Widget));
5285 if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f)->screen)
5286 && w != NULL)
5288 BLOCK_INPUT;
5289 xlwmenu_redisplay (w);
5290 UNBLOCK_INPUT;
5293 #endif /* USE_LUCID */
5296 UNGCPRO;
5297 return unbind_to (count, deleted);
5302 /***********************************************************************
5303 File selection dialog
5304 ***********************************************************************/
5306 DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog,
5307 Sx_uses_old_gtk_dialog,
5308 0, 0, 0,
5309 doc: /* Return t if the old Gtk+ file selection dialog is used. */)
5312 #ifdef USE_GTK
5313 extern int use_dialog_box;
5314 extern int use_file_dialog;
5316 if (use_dialog_box
5317 && use_file_dialog
5318 && have_menus_p ()
5319 && xg_uses_old_file_dialog ())
5320 return Qt;
5321 #endif
5322 return Qnil;
5326 #ifdef USE_MOTIF
5327 /* Callback for "OK" and "Cancel" on file selection dialog. */
5329 static void
5330 file_dialog_cb (widget, client_data, call_data)
5331 Widget widget;
5332 XtPointer call_data, client_data;
5334 int *result = (int *) client_data;
5335 XmAnyCallbackStruct *cb = (XmAnyCallbackStruct *) call_data;
5336 *result = cb->reason;
5340 /* Callback for unmapping a file selection dialog. This is used to
5341 capture the case where a dialog is closed via a window manager's
5342 closer button, for example. Using a XmNdestroyCallback didn't work
5343 in this case. */
5345 static void
5346 file_dialog_unmap_cb (widget, client_data, call_data)
5347 Widget widget;
5348 XtPointer call_data, client_data;
5350 int *result = (int *) client_data;
5351 *result = XmCR_CANCEL;
5354 static Lisp_Object
5355 clean_up_file_dialog (arg)
5356 Lisp_Object arg;
5358 struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
5359 Widget dialog = (Widget) p->pointer;
5361 /* Clean up. */
5362 BLOCK_INPUT;
5363 XtUnmanageChild (dialog);
5364 XtDestroyWidget (dialog);
5365 x_menu_set_in_use (0);
5366 UNBLOCK_INPUT;
5368 return Qnil;
5372 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5373 doc: /* Read file name, prompting with PROMPT in directory DIR.
5374 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5375 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5376 or directory must exist. ONLY-DIR-P is ignored." */)
5377 (prompt, dir, default_filename, mustmatch, only_dir_p)
5378 Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
5380 int result;
5381 struct frame *f = SELECTED_FRAME ();
5382 Lisp_Object file = Qnil;
5383 Lisp_Object decoded_file;
5384 Widget dialog, text, help;
5385 Arg al[10];
5386 int ac = 0;
5387 extern XtAppContext Xt_app_con;
5388 XmString dir_xmstring, pattern_xmstring;
5389 int count = SPECPDL_INDEX ();
5390 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5392 check_x ();
5394 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5396 if (popup_activated ())
5397 error ("Trying to use a menu from within a menu-entry");
5399 CHECK_STRING (prompt);
5400 CHECK_STRING (dir);
5402 /* Prevent redisplay. */
5403 specbind (Qinhibit_redisplay, Qt);
5405 BLOCK_INPUT;
5407 /* Create the dialog with PROMPT as title, using DIR as initial
5408 directory and using "*" as pattern. */
5409 dir = Fexpand_file_name (dir, Qnil);
5410 dir_xmstring = XmStringCreateLocalized (SDATA (dir));
5411 pattern_xmstring = XmStringCreateLocalized ("*");
5413 XtSetArg (al[ac], XmNtitle, SDATA (prompt)); ++ac;
5414 XtSetArg (al[ac], XmNdirectory, dir_xmstring); ++ac;
5415 XtSetArg (al[ac], XmNpattern, pattern_xmstring); ++ac;
5416 XtSetArg (al[ac], XmNresizePolicy, XmRESIZE_GROW); ++ac;
5417 XtSetArg (al[ac], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); ++ac;
5418 dialog = XmCreateFileSelectionDialog (f->output_data.x->widget,
5419 "fsb", al, ac);
5420 XmStringFree (dir_xmstring);
5421 XmStringFree (pattern_xmstring);
5423 /* Add callbacks for OK and Cancel. */
5424 XtAddCallback (dialog, XmNokCallback, file_dialog_cb,
5425 (XtPointer) &result);
5426 XtAddCallback (dialog, XmNcancelCallback, file_dialog_cb,
5427 (XtPointer) &result);
5428 XtAddCallback (dialog, XmNunmapCallback, file_dialog_unmap_cb,
5429 (XtPointer) &result);
5431 /* Remove the help button since we can't display help. */
5432 help = XmFileSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON);
5433 XtUnmanageChild (help);
5435 /* Mark OK button as default. */
5436 XtVaSetValues (XmFileSelectionBoxGetChild (dialog, XmDIALOG_OK_BUTTON),
5437 XmNshowAsDefault, True, NULL);
5439 /* If MUSTMATCH is non-nil, disable the file entry field of the
5440 dialog, so that the user must select a file from the files list
5441 box. We can't remove it because we wouldn't have a way to get at
5442 the result file name, then. */
5443 text = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5444 if (!NILP (mustmatch))
5446 Widget label;
5447 label = XmFileSelectionBoxGetChild (dialog, XmDIALOG_SELECTION_LABEL);
5448 XtSetSensitive (text, False);
5449 XtSetSensitive (label, False);
5452 /* Manage the dialog, so that list boxes get filled. */
5453 XtManageChild (dialog);
5455 if (STRINGP (default_filename))
5457 XmString default_xmstring;
5458 Widget wtext = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5459 Widget list = XmFileSelectionBoxGetChild (dialog, XmDIALOG_LIST);
5461 XmTextPosition last_pos = XmTextFieldGetLastPosition (wtext);
5462 XmTextFieldReplace (wtext, 0, last_pos,
5463 (SDATA (Ffile_name_nondirectory (default_filename))));
5465 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
5466 must include the path for this to work. */
5468 default_xmstring = XmStringCreateLocalized (SDATA (default_filename));
5470 if (XmListItemExists (list, default_xmstring))
5472 int item_pos = XmListItemPos (list, default_xmstring);
5473 /* Select the item and scroll it into view. */
5474 XmListSelectPos (list, item_pos, True);
5475 XmListSetPos (list, item_pos);
5478 XmStringFree (default_xmstring);
5481 record_unwind_protect (clean_up_file_dialog, make_save_value (dialog, 0));
5483 /* Process events until the user presses Cancel or OK. */
5484 x_menu_set_in_use (1);
5485 result = 0;
5486 while (result == 0)
5488 XEvent event;
5489 x_menu_wait_for_event (0);
5490 XtAppNextEvent (Xt_app_con, &event);
5491 if (event.type == KeyPress
5492 && FRAME_X_DISPLAY (f) == event.xkey.display)
5494 KeySym keysym = XLookupKeysym (&event.xkey, 0);
5496 /* Pop down on C-g. */
5497 if (keysym == XK_g && (event.xkey.state & ControlMask) != 0)
5498 XtUnmanageChild (dialog);
5501 (void) x_dispatch_event (&event, FRAME_X_DISPLAY (f));
5504 /* Get the result. */
5505 if (result == XmCR_OK)
5507 XmString text;
5508 String data;
5510 XtVaGetValues (dialog, XmNtextString, &text, NULL);
5511 XmStringGetLtoR (text, XmFONTLIST_DEFAULT_TAG, &data);
5512 XmStringFree (text);
5513 file = build_string (data);
5514 XtFree (data);
5516 else
5517 file = Qnil;
5519 UNBLOCK_INPUT;
5520 UNGCPRO;
5522 /* Make "Cancel" equivalent to C-g. */
5523 if (NILP (file))
5524 Fsignal (Qquit, Qnil);
5526 decoded_file = DECODE_FILE (file);
5528 return unbind_to (count, decoded_file);
5531 #endif /* USE_MOTIF */
5533 #ifdef USE_GTK
5535 static Lisp_Object
5536 clean_up_dialog (arg)
5537 Lisp_Object arg;
5539 x_menu_set_in_use (0);
5541 return Qnil;
5544 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5545 doc: /* Read file name, prompting with PROMPT in directory DIR.
5546 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5547 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5548 or directory must exist. If ONLY-DIR-P is non-nil, the user can only select
5549 directories. */)
5550 (prompt, dir, default_filename, mustmatch, only_dir_p)
5551 Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
5553 FRAME_PTR f = SELECTED_FRAME ();
5554 char *fn;
5555 Lisp_Object file = Qnil;
5556 Lisp_Object decoded_file;
5557 int count = SPECPDL_INDEX ();
5558 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5559 char *cdef_file;
5561 check_x ();
5563 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5565 if (popup_activated ())
5566 error ("Trying to use a menu from within a menu-entry");
5568 CHECK_STRING (prompt);
5569 CHECK_STRING (dir);
5571 /* Prevent redisplay. */
5572 specbind (Qinhibit_redisplay, Qt);
5573 record_unwind_protect (clean_up_dialog, Qnil);
5575 BLOCK_INPUT;
5577 if (STRINGP (default_filename))
5578 cdef_file = SDATA (default_filename);
5579 else
5580 cdef_file = SDATA (dir);
5582 fn = xg_get_file_name (f, SDATA (prompt), cdef_file,
5583 ! NILP (mustmatch),
5584 ! NILP (only_dir_p));
5586 if (fn)
5588 file = build_string (fn);
5589 xfree (fn);
5592 UNBLOCK_INPUT;
5593 UNGCPRO;
5595 /* Make "Cancel" equivalent to C-g. */
5596 if (NILP (file))
5597 Fsignal (Qquit, Qnil);
5599 decoded_file = DECODE_FILE (file);
5601 return unbind_to (count, decoded_file);
5604 #endif /* USE_GTK */
5607 /***********************************************************************
5608 Keyboard
5609 ***********************************************************************/
5611 #ifdef HAVE_XKBGETKEYBOARD
5612 #include <X11/XKBlib.h>
5613 #include <X11/keysym.h>
5614 #endif
5616 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p,
5617 Sx_backspace_delete_keys_p, 0, 1, 0,
5618 doc: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
5619 FRAME nil means use the selected frame.
5620 Value is t if we know that both keys are present, and are mapped to the
5621 usual X keysyms. Value is `lambda' if we cannot determine if both keys are
5622 present and mapped to the usual X keysyms. */)
5623 (frame)
5624 Lisp_Object frame;
5626 #ifdef HAVE_XKBGETKEYBOARD
5627 XkbDescPtr kb;
5628 struct frame *f = check_x_frame (frame);
5629 Display *dpy = FRAME_X_DISPLAY (f);
5630 Lisp_Object have_keys;
5631 int major, minor, op, event, error;
5633 BLOCK_INPUT;
5635 /* Check library version in case we're dynamically linked. */
5636 major = XkbMajorVersion;
5637 minor = XkbMinorVersion;
5638 if (!XkbLibraryVersion (&major, &minor))
5640 UNBLOCK_INPUT;
5641 return Qlambda;
5644 /* Check that the server supports XKB. */
5645 major = XkbMajorVersion;
5646 minor = XkbMinorVersion;
5647 if (!XkbQueryExtension (dpy, &op, &event, &error, &major, &minor))
5649 UNBLOCK_INPUT;
5650 return Qlambda;
5653 /* In this code we check that the keyboard has physical keys with names
5654 that start with BKSP (Backspace) and DELE (Delete), and that they
5655 generate keysym XK_BackSpace and XK_Delete respectively.
5656 This function is used to test if normal-erase-is-backspace should be
5657 turned on.
5658 An alternative approach would be to just check if XK_BackSpace and
5659 XK_Delete are mapped to any key. But if any of those are mapped to
5660 some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the
5661 user doesn't know about it, it is better to return false here.
5662 It is more obvious to the user what to do if she/he has two keys
5663 clearly marked with names/symbols and one key does something not
5664 expected (i.e. she/he then tries the other).
5665 The cases where Backspace/Delete is mapped to some other key combination
5666 are rare, and in those cases, normal-erase-is-backspace can be turned on
5667 manually. */
5669 have_keys = Qnil;
5670 kb = XkbGetMap (dpy, XkbAllMapComponentsMask, XkbUseCoreKbd);
5671 if (kb)
5673 int delete_keycode = 0, backspace_keycode = 0, i;
5675 if (XkbGetNames (dpy, XkbAllNamesMask, kb) == Success)
5677 for (i = kb->min_key_code;
5678 (i < kb->max_key_code
5679 && (delete_keycode == 0 || backspace_keycode == 0));
5680 ++i)
5682 /* The XKB symbolic key names can be seen most easily in
5683 the PS file generated by `xkbprint -label name
5684 $DISPLAY'. */
5685 if (bcmp ("DELE", kb->names->keys[i].name, 4) == 0)
5686 delete_keycode = i;
5687 else if (bcmp ("BKSP", kb->names->keys[i].name, 4) == 0)
5688 backspace_keycode = i;
5691 XkbFreeNames (kb, 0, True);
5694 XkbFreeClientMap (kb, 0, True);
5696 if (delete_keycode
5697 && backspace_keycode
5698 && XKeysymToKeycode (dpy, XK_Delete) == delete_keycode
5699 && XKeysymToKeycode (dpy, XK_BackSpace) == backspace_keycode)
5700 have_keys = Qt;
5702 UNBLOCK_INPUT;
5703 return have_keys;
5704 #else /* not HAVE_XKBGETKEYBOARD */
5705 return Qlambda;
5706 #endif /* not HAVE_XKBGETKEYBOARD */
5711 /***********************************************************************
5712 Initialization
5713 ***********************************************************************/
5715 /* Keep this list in the same order as frame_parms in frame.c.
5716 Use 0 for unsupported frame parameters. */
5718 frame_parm_handler x_frame_parm_handlers[] =
5720 x_set_autoraise,
5721 x_set_autolower,
5722 x_set_background_color,
5723 x_set_border_color,
5724 x_set_border_width,
5725 x_set_cursor_color,
5726 x_set_cursor_type,
5727 x_set_font,
5728 x_set_foreground_color,
5729 x_set_icon_name,
5730 x_set_icon_type,
5731 x_set_internal_border_width,
5732 x_set_menu_bar_lines,
5733 x_set_mouse_color,
5734 x_explicitly_set_name,
5735 x_set_scroll_bar_width,
5736 x_set_title,
5737 x_set_unsplittable,
5738 x_set_vertical_scroll_bars,
5739 x_set_visibility,
5740 x_set_tool_bar_lines,
5741 x_set_scroll_bar_foreground,
5742 x_set_scroll_bar_background,
5743 x_set_screen_gamma,
5744 x_set_line_spacing,
5745 x_set_fringe_width,
5746 x_set_fringe_width,
5747 x_set_wait_for_wm,
5748 x_set_fullscreen,
5751 void
5752 syms_of_xfns ()
5754 /* This is zero if not using X windows. */
5755 x_in_use = 0;
5757 /* The section below is built by the lisp expression at the top of the file,
5758 just above where these variables are declared. */
5759 /*&&& init symbols here &&&*/
5760 Qnone = intern ("none");
5761 staticpro (&Qnone);
5762 Qsuppress_icon = intern ("suppress-icon");
5763 staticpro (&Qsuppress_icon);
5764 Qundefined_color = intern ("undefined-color");
5765 staticpro (&Qundefined_color);
5766 Qcompound_text = intern ("compound-text");
5767 staticpro (&Qcompound_text);
5768 Qcancel_timer = intern ("cancel-timer");
5769 staticpro (&Qcancel_timer);
5770 /* This is the end of symbol initialization. */
5772 /* Text property `display' should be nonsticky by default. */
5773 Vtext_property_default_nonsticky
5774 = Fcons (Fcons (Qdisplay, Qt), Vtext_property_default_nonsticky);
5777 Fput (Qundefined_color, Qerror_conditions,
5778 Fcons (Qundefined_color, Fcons (Qerror, Qnil)));
5779 Fput (Qundefined_color, Qerror_message,
5780 build_string ("Undefined color"));
5782 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
5783 doc: /* The shape of the pointer when over text.
5784 Changing the value does not affect existing frames
5785 unless you set the mouse color. */);
5786 Vx_pointer_shape = Qnil;
5788 #if 0 /* This doesn't really do anything. */
5789 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape,
5790 doc: /* The shape of the pointer when not over text.
5791 This variable takes effect when you create a new frame
5792 or when you set the mouse color. */);
5793 #endif
5794 Vx_nontext_pointer_shape = Qnil;
5796 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape,
5797 doc: /* The shape of the pointer when Emacs is busy.
5798 This variable takes effect when you create a new frame
5799 or when you set the mouse color. */);
5800 Vx_hourglass_pointer_shape = Qnil;
5802 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p,
5803 doc: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
5804 display_hourglass_p = 1;
5806 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay,
5807 doc: /* *Seconds to wait before displaying an hourglass pointer.
5808 Value must be an integer or float. */);
5809 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
5811 #if 0 /* This doesn't really do anything. */
5812 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape,
5813 doc: /* The shape of the pointer when over the mode line.
5814 This variable takes effect when you create a new frame
5815 or when you set the mouse color. */);
5816 #endif
5817 Vx_mode_pointer_shape = Qnil;
5819 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
5820 &Vx_sensitive_text_pointer_shape,
5821 doc: /* The shape of the pointer when over mouse-sensitive text.
5822 This variable takes effect when you create a new frame
5823 or when you set the mouse color. */);
5824 Vx_sensitive_text_pointer_shape = Qnil;
5826 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
5827 &Vx_window_horizontal_drag_shape,
5828 doc: /* Pointer shape to use for indicating a window can be dragged horizontally.
5829 This variable takes effect when you create a new frame
5830 or when you set the mouse color. */);
5831 Vx_window_horizontal_drag_shape = Qnil;
5833 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel,
5834 doc: /* A string indicating the foreground color of the cursor box. */);
5835 Vx_cursor_fore_pixel = Qnil;
5837 DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size,
5838 doc: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).
5839 Text larger than this is clipped. */);
5840 Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
5842 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
5843 doc: /* Non-nil if no X window manager is in use.
5844 Emacs doesn't try to figure this out; this is always nil
5845 unless you set it to something else. */);
5846 /* We don't have any way to find this out, so set it to nil
5847 and maybe the user would like to set it to t. */
5848 Vx_no_window_manager = Qnil;
5850 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
5851 &Vx_pixel_size_width_font_regexp,
5852 doc: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
5854 Since Emacs gets width of a font matching with this regexp from
5855 PIXEL_SIZE field of the name, font finding mechanism gets faster for
5856 such a font. This is especially effective for such large fonts as
5857 Chinese, Japanese, and Korean. */);
5858 Vx_pixel_size_width_font_regexp = Qnil;
5860 /* This is not ifdef:ed, so other builds than GTK can customize it. */
5861 DEFVAR_BOOL ("x-gtk-use-old-file-dialog", &x_gtk_use_old_file_dialog,
5862 doc: /* *Non-nil means prompt with the old GTK file selection dialog.
5863 If nil or if the file selection dialog is not available, the new GTK file
5864 chooser is used instead. To turn off all file dialogs set the
5865 variable `use-file-dialog'. */);
5866 x_gtk_use_old_file_dialog = 0;
5868 DEFVAR_BOOL ("x-gtk-show-hidden-files", &x_gtk_show_hidden_files,
5869 doc: /* *If non-nil, the GTK file chooser will by default show hidden files.
5870 Note that this is just the default, there is a toggle button on the file
5871 chooser to show or not show hidden files on a case by case basis. */);
5872 x_gtk_show_hidden_files = 0;
5874 DEFVAR_BOOL ("x-gtk-file-dialog-help-text", &x_gtk_file_dialog_help_text,
5875 doc: /* *If non-nil, the GTK file chooser will show additional help text.
5876 If more space for files in the file chooser dialog is wanted, set this to nil
5877 to turn the additional text off. */);
5878 x_gtk_file_dialog_help_text = 1;
5880 DEFVAR_BOOL ("x-gtk-whole-detached-tool-bar", &x_gtk_whole_detached_tool_bar,
5881 doc: /* *If non-nil, a detached tool bar is shown in full.
5882 The default is to just show an arrow and pressing on that arrow shows
5883 the tool bar buttons. */);
5884 x_gtk_whole_detached_tool_bar = 0;
5886 Fprovide (intern ("x"), Qnil);
5888 #ifdef USE_X_TOOLKIT
5889 Fprovide (intern ("x-toolkit"), Qnil);
5890 #ifdef USE_MOTIF
5891 Fprovide (intern ("motif"), Qnil);
5893 DEFVAR_LISP ("motif-version-string", &Vmotif_version_string,
5894 doc: /* Version info for LessTif/Motif. */);
5895 Vmotif_version_string = build_string (XmVERSION_STRING);
5896 #endif /* USE_MOTIF */
5897 #endif /* USE_X_TOOLKIT */
5899 #ifdef USE_GTK
5900 /* Provide x-toolkit also for GTK. Internally GTK does not use Xt so it
5901 is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
5902 But for a user it is a toolkit for X, and indeed, configure
5903 accepts --with-x-toolkit=gtk. */
5904 Fprovide (intern ("x-toolkit"), Qnil);
5905 Fprovide (intern ("gtk"), Qnil);
5907 DEFVAR_LISP ("gtk-version-string", &Vgtk_version_string,
5908 doc: /* Version info for GTK+. */);
5910 char gtk_version[40];
5911 g_snprintf (gtk_version, sizeof (gtk_version), "%u.%u.%u",
5912 GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
5913 Vgtk_version_string = build_string (gtk_version);
5915 #endif /* USE_GTK */
5917 /* X window properties. */
5918 defsubr (&Sx_change_window_property);
5919 defsubr (&Sx_delete_window_property);
5920 defsubr (&Sx_window_property);
5922 defsubr (&Sxw_display_color_p);
5923 defsubr (&Sx_display_grayscale_p);
5924 defsubr (&Sxw_color_defined_p);
5925 defsubr (&Sxw_color_values);
5926 defsubr (&Sx_server_max_request_size);
5927 defsubr (&Sx_server_vendor);
5928 defsubr (&Sx_server_version);
5929 defsubr (&Sx_display_pixel_width);
5930 defsubr (&Sx_display_pixel_height);
5931 defsubr (&Sx_display_mm_width);
5932 defsubr (&Sx_display_mm_height);
5933 defsubr (&Sx_display_screens);
5934 defsubr (&Sx_display_planes);
5935 defsubr (&Sx_display_color_cells);
5936 defsubr (&Sx_display_visual_class);
5937 defsubr (&Sx_display_backing_store);
5938 defsubr (&Sx_display_save_under);
5939 defsubr (&Sx_create_frame);
5940 defsubr (&Sx_open_connection);
5941 defsubr (&Sx_close_connection);
5942 defsubr (&Sx_display_list);
5943 defsubr (&Sx_synchronize);
5944 defsubr (&Sx_focus_frame);
5945 defsubr (&Sx_backspace_delete_keys_p);
5947 /* Setting callback functions for fontset handler. */
5948 get_font_info_func = x_get_font_info;
5950 #if 0 /* This function pointer doesn't seem to be used anywhere.
5951 And the pointer assigned has the wrong type, anyway. */
5952 list_fonts_func = x_list_fonts;
5953 #endif
5955 load_font_func = x_load_font;
5956 find_ccl_program_func = x_find_ccl_program;
5957 query_font_func = x_query_font;
5958 set_frame_fontset_func = x_set_font;
5959 check_window_system_func = check_x;
5961 hourglass_atimer = NULL;
5962 hourglass_shown_p = 0;
5964 defsubr (&Sx_show_tip);
5965 defsubr (&Sx_hide_tip);
5966 tip_timer = Qnil;
5967 staticpro (&tip_timer);
5968 tip_frame = Qnil;
5969 staticpro (&tip_frame);
5971 last_show_tip_args = Qnil;
5972 staticpro (&last_show_tip_args);
5974 defsubr (&Sx_uses_old_gtk_dialog);
5975 #if defined (USE_MOTIF) || defined (USE_GTK)
5976 defsubr (&Sx_file_dialog);
5977 #endif
5980 #endif /* HAVE_X_WINDOWS */
5982 /* arch-tag: 55040d02-5485-4d58-8b22-95a7a05f3288
5983 (do not change this comment) */