mairix.el fix for bug#13294
[emacs.git] / src / xfns.c
blobd497cffe3df6f7bb1f5f6931914db4ed20da62ba
1 /* Functions for the X window system.
3 Copyright (C) 1989, 1992-2012 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20 #include <config.h>
21 #include <stdio.h>
22 #include <math.h>
23 #include <unistd.h>
25 /* This makes the fields of a Display accessible, in Xlib header files. */
27 #define XLIB_ILLEGAL_ACCESS
29 #include "lisp.h"
30 #include "xterm.h"
31 #include "frame.h"
32 #include "window.h"
33 #include "character.h"
34 #include "buffer.h"
35 #include "intervals.h"
36 #include "dispextern.h"
37 #include "keyboard.h"
38 #include "blockinput.h"
39 #include <epaths.h>
40 #include "charset.h"
41 #include "coding.h"
42 #include "fontset.h"
43 #include "systime.h"
44 #include "termhooks.h"
45 #include "atimer.h"
46 #include "termchar.h"
47 #include "font.h"
49 #ifdef HAVE_X_WINDOWS
51 #include <sys/types.h>
52 #include <sys/stat.h>
54 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */
55 #include "bitmaps/gray.xbm"
56 #else
57 #include <X11/bitmaps/gray>
58 #endif
60 #include "xsettings.h"
62 #ifdef USE_GTK
63 #include "gtkutil.h"
64 #endif
66 #ifdef USE_X_TOOLKIT
67 #include <X11/Shell.h>
69 #ifndef USE_MOTIF
70 #ifdef HAVE_XAW3D
71 #include <X11/Xaw3d/Paned.h>
72 #include <X11/Xaw3d/Label.h>
73 #else /* !HAVE_XAW3D */
74 #include <X11/Xaw/Paned.h>
75 #include <X11/Xaw/Label.h>
76 #endif /* HAVE_XAW3D */
77 #endif /* USE_MOTIF */
79 #ifdef USG
80 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
81 #include <X11/Xos.h>
82 #define USG
83 #ifdef USG /* Pacify gcc -Wunused-macros. */
84 #endif
85 #else
86 #include <X11/Xos.h>
87 #endif
89 #include "widget.h"
91 #include "../lwlib/lwlib.h"
93 #ifdef USE_MOTIF
94 #include <Xm/Xm.h>
95 #include <Xm/DialogS.h>
96 #include <Xm/FileSB.h>
97 #include <Xm/List.h>
98 #include <Xm/TextF.h>
99 #endif
101 #ifdef USE_LUCID
102 #include "../lwlib/xlwmenu.h"
103 #endif
105 #if !defined (NO_EDITRES)
106 #define HACK_EDITRES
107 extern void _XEditResCheckMessages (Widget, XtPointer, XEvent *, Boolean *);
108 #endif /* not defined NO_EDITRES */
110 /* Unique id counter for widgets created by the Lucid Widget Library. */
112 extern LWLIB_ID widget_id_tick;
114 #ifdef USE_MOTIF
116 #endif /* USE_MOTIF */
118 #endif /* USE_X_TOOLKIT */
120 #ifdef USE_GTK
122 #endif /* USE_GTK */
124 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
126 /* Nonzero if using X. */
128 int x_in_use;
130 static Lisp_Object Qsuppress_icon;
131 static Lisp_Object Qundefined_color;
132 static Lisp_Object Qcompound_text, Qcancel_timer;
133 Lisp_Object Qfont_param;
135 #ifdef GLYPH_DEBUG
136 static ptrdiff_t image_cache_refcount;
137 static int dpyinfo_refcount;
138 #endif
140 static struct x_display_info *x_display_info_for_name (Lisp_Object);
143 /* Error if we are not connected to X. */
145 void
146 check_x (void)
148 if (! x_in_use)
149 error ("X windows are not in use or not initialized");
152 /* Nonzero if we can use mouse menus.
153 You should not call this unless HAVE_MENUS is defined. */
156 have_menus_p (void)
158 return x_in_use;
161 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
162 and checking validity for X. */
164 FRAME_PTR
165 check_x_frame (Lisp_Object frame)
167 FRAME_PTR f;
169 if (NILP (frame))
170 frame = selected_frame;
171 CHECK_LIVE_FRAME (frame);
172 f = XFRAME (frame);
173 if (! FRAME_X_P (f))
174 error ("Non-X frame used");
175 return f;
178 /* Let the user specify an X display with a Lisp object.
179 OBJECT may be nil, a frame or a terminal object.
180 nil stands for the selected frame--or, if that is not an X frame,
181 the first X display on the list. */
183 struct x_display_info *
184 check_x_display_info (Lisp_Object object)
186 struct x_display_info *dpyinfo = NULL;
188 if (NILP (object))
190 struct frame *sf = XFRAME (selected_frame);
192 if (FRAME_X_P (sf) && FRAME_LIVE_P (sf))
193 dpyinfo = FRAME_X_DISPLAY_INFO (sf);
194 else if (x_display_list != 0)
195 dpyinfo = x_display_list;
196 else
197 error ("X windows are not in use or not initialized");
199 else if (TERMINALP (object))
201 struct terminal *t = get_terminal (object, 1);
203 if (t->type != output_x_window)
204 error ("Terminal %"pI"d is not an X display", XINT (object));
206 dpyinfo = t->display_info.x;
208 else if (STRINGP (object))
209 dpyinfo = x_display_info_for_name (object);
210 else
212 FRAME_PTR f = check_x_frame (object);
213 dpyinfo = FRAME_X_DISPLAY_INFO (f);
216 return dpyinfo;
220 /* Return the Emacs frame-object corresponding to an X window.
221 It could be the frame's main window or an icon window. */
223 /* This function can be called during GC, so use GC_xxx type test macros. */
225 struct frame *
226 x_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
228 Lisp_Object tail, frame;
229 struct frame *f;
231 if (wdesc == None) return 0;
233 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
235 frame = XCAR (tail);
236 if (!FRAMEP (frame))
237 continue;
238 f = XFRAME (frame);
239 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
240 continue;
241 if (f->output_data.x->hourglass_window == wdesc)
242 return f;
243 #ifdef USE_X_TOOLKIT
244 if ((f->output_data.x->edit_widget
245 && XtWindow (f->output_data.x->edit_widget) == wdesc)
246 /* A tooltip frame? */
247 || (!f->output_data.x->edit_widget
248 && FRAME_X_WINDOW (f) == wdesc)
249 || f->output_data.x->icon_desc == wdesc)
250 return f;
251 #else /* not USE_X_TOOLKIT */
252 #ifdef USE_GTK
253 if (f->output_data.x->edit_widget)
255 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
256 struct x_output *x = f->output_data.x;
257 if (gwdesc != 0 && gwdesc == x->edit_widget)
258 return f;
260 #endif /* USE_GTK */
261 if (FRAME_X_WINDOW (f) == wdesc
262 || f->output_data.x->icon_desc == wdesc)
263 return f;
264 #endif /* not USE_X_TOOLKIT */
266 return 0;
269 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
270 /* Like x_window_to_frame but also compares the window with the widget's
271 windows. */
273 struct frame *
274 x_any_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
276 Lisp_Object tail, frame;
277 struct frame *f, *found;
278 struct x_output *x;
280 if (wdesc == None) return NULL;
282 found = NULL;
283 for (tail = Vframe_list; CONSP (tail) && !found; tail = XCDR (tail))
285 frame = XCAR (tail);
286 if (!FRAMEP (frame))
287 continue;
289 f = XFRAME (frame);
290 if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) == dpyinfo)
292 /* This frame matches if the window is any of its widgets. */
293 x = f->output_data.x;
294 if (x->hourglass_window == wdesc)
295 found = f;
296 else if (x->widget)
298 #ifdef USE_GTK
299 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
300 if (gwdesc != 0
301 && gtk_widget_get_toplevel (gwdesc) == x->widget)
302 found = f;
303 #else
304 if (wdesc == XtWindow (x->widget)
305 || wdesc == XtWindow (x->column_widget)
306 || wdesc == XtWindow (x->edit_widget))
307 found = f;
308 /* Match if the window is this frame's menubar. */
309 else if (lw_window_is_in_menubar (wdesc, x->menubar_widget))
310 found = f;
311 #endif
313 else if (FRAME_X_WINDOW (f) == wdesc)
314 /* A tooltip frame. */
315 found = f;
319 return found;
322 /* Likewise, but consider only the menu bar widget. */
324 struct frame *
325 x_menubar_window_to_frame (struct x_display_info *dpyinfo, XEvent *event)
327 Window wdesc = event->xany.window;
328 Lisp_Object tail, frame;
329 struct frame *f;
330 struct x_output *x;
332 if (wdesc == None) return 0;
334 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
336 frame = XCAR (tail);
337 if (!FRAMEP (frame))
338 continue;
339 f = XFRAME (frame);
340 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
341 continue;
342 x = f->output_data.x;
343 #ifdef USE_GTK
344 if (x->menubar_widget && xg_event_is_for_menubar (f, event))
345 return f;
346 #else
347 /* Match if the window is this frame's menubar. */
348 if (x->menubar_widget
349 && lw_window_is_in_menubar (wdesc, x->menubar_widget))
350 return f;
351 #endif
353 return 0;
356 /* Return the frame whose principal (outermost) window is WDESC.
357 If WDESC is some other (smaller) window, we return 0. */
359 struct frame *
360 x_top_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
362 Lisp_Object tail, frame;
363 struct frame *f;
364 struct x_output *x;
366 if (wdesc == None) return 0;
368 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
370 frame = XCAR (tail);
371 if (!FRAMEP (frame))
372 continue;
373 f = XFRAME (frame);
374 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
375 continue;
376 x = f->output_data.x;
378 if (x->widget)
380 /* This frame matches if the window is its topmost widget. */
381 #ifdef USE_GTK
382 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
383 if (gwdesc == x->widget)
384 return f;
385 #else
386 if (wdesc == XtWindow (x->widget))
387 return f;
388 #if 0 /* I don't know why it did this,
389 but it seems logically wrong,
390 and it causes trouble for MapNotify events. */
391 /* Match if the window is this frame's menubar. */
392 if (x->menubar_widget
393 && wdesc == XtWindow (x->menubar_widget))
394 return f;
395 #endif
396 #endif
398 else if (FRAME_X_WINDOW (f) == wdesc)
399 /* Tooltip frame. */
400 return f;
402 return 0;
404 #endif /* USE_X_TOOLKIT || USE_GTK */
408 /* Store the screen positions of frame F into XPTR and YPTR.
409 These are the positions of the containing window manager window,
410 not Emacs's own window. */
412 void
413 x_real_positions (FRAME_PTR f, int *xptr, int *yptr)
415 int win_x, win_y, outer_x IF_LINT (= 0), outer_y IF_LINT (= 0);
416 int real_x = 0, real_y = 0;
417 int had_errors = 0;
418 Window win = f->output_data.x->parent_desc;
419 Atom actual_type;
420 unsigned long actual_size, bytes_remaining;
421 int rc, actual_format;
422 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
423 long max_len = 400;
424 Display *dpy = FRAME_X_DISPLAY (f);
425 unsigned char *tmp_data = NULL;
426 Atom target_type = XA_CARDINAL;
428 block_input ();
430 x_catch_errors (dpy);
432 if (win == dpyinfo->root_window)
433 win = FRAME_OUTER_WINDOW (f);
435 /* This loop traverses up the containment tree until we hit the root
436 window. Window managers may intersect many windows between our window
437 and the root window. The window we find just before the root window
438 should be the outer WM window. */
439 for (;;)
441 Window wm_window, rootw;
442 Window *tmp_children;
443 unsigned int tmp_nchildren;
444 int success;
446 success = XQueryTree (FRAME_X_DISPLAY (f), win, &rootw,
447 &wm_window, &tmp_children, &tmp_nchildren);
449 had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
451 /* Don't free tmp_children if XQueryTree failed. */
452 if (! success)
453 break;
455 XFree (tmp_children);
457 if (wm_window == rootw || had_errors)
458 break;
460 win = wm_window;
463 if (! had_errors)
465 unsigned int ign;
466 Window child, rootw;
468 /* Get the real coordinates for the WM window upper left corner */
469 XGetGeometry (FRAME_X_DISPLAY (f), win,
470 &rootw, &real_x, &real_y, &ign, &ign, &ign, &ign);
472 /* Translate real coordinates to coordinates relative to our
473 window. For our window, the upper left corner is 0, 0.
474 Since the upper left corner of the WM window is outside
475 our window, win_x and win_y will be negative:
477 ------------------ ---> x
478 | title |
479 | ----------------- v y
480 | | our window
482 XTranslateCoordinates (FRAME_X_DISPLAY (f),
484 /* From-window, to-window. */
485 FRAME_X_DISPLAY_INFO (f)->root_window,
486 FRAME_X_WINDOW (f),
488 /* From-position, to-position. */
489 real_x, real_y, &win_x, &win_y,
491 /* Child of win. */
492 &child);
494 if (FRAME_X_WINDOW (f) == FRAME_OUTER_WINDOW (f))
496 outer_x = win_x;
497 outer_y = win_y;
499 else
501 XTranslateCoordinates (FRAME_X_DISPLAY (f),
503 /* From-window, to-window. */
504 FRAME_X_DISPLAY_INFO (f)->root_window,
505 FRAME_OUTER_WINDOW (f),
507 /* From-position, to-position. */
508 real_x, real_y, &outer_x, &outer_y,
510 /* Child of win. */
511 &child);
514 had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
518 if (dpyinfo->root_window == f->output_data.x->parent_desc)
520 /* Try _NET_FRAME_EXTENTS if our parent is the root window. */
521 rc = XGetWindowProperty (dpy, win, dpyinfo->Xatom_net_frame_extents,
522 0, max_len, False, target_type,
523 &actual_type, &actual_format, &actual_size,
524 &bytes_remaining, &tmp_data);
526 if (rc == Success && actual_type == target_type && !x_had_errors_p (dpy)
527 && actual_size == 4 && actual_format == 32)
529 unsigned int ign;
530 Window rootw;
531 long *fe = (long *)tmp_data;
533 XGetGeometry (FRAME_X_DISPLAY (f), win,
534 &rootw, &real_x, &real_y, &ign, &ign, &ign, &ign);
535 outer_x = -fe[0];
536 outer_y = -fe[2];
537 real_x -= fe[0];
538 real_y -= fe[2];
542 if (tmp_data) XFree (tmp_data);
544 x_uncatch_errors ();
546 unblock_input ();
548 if (had_errors) return;
550 f->x_pixels_diff = -win_x;
551 f->y_pixels_diff = -win_y;
553 FRAME_X_OUTPUT (f)->x_pixels_outer_diff = -outer_x;
554 FRAME_X_OUTPUT (f)->y_pixels_outer_diff = -outer_y;
556 *xptr = real_x;
557 *yptr = real_y;
563 /* Gamma-correct COLOR on frame F. */
565 void
566 gamma_correct (struct frame *f, XColor *color)
568 if (f->gamma)
570 color->red = pow (color->red / 65535.0, f->gamma) * 65535.0 + 0.5;
571 color->green = pow (color->green / 65535.0, f->gamma) * 65535.0 + 0.5;
572 color->blue = pow (color->blue / 65535.0, f->gamma) * 65535.0 + 0.5;
577 /* Decide if color named COLOR_NAME is valid for use on frame F. If
578 so, return the RGB values in COLOR. If ALLOC_P,
579 allocate the color. Value is false if COLOR_NAME is invalid, or
580 no color could be allocated. */
582 bool
583 x_defined_color (struct frame *f, const char *color_name,
584 XColor *color, bool alloc_p)
586 bool success_p = 0;
587 Display *dpy = FRAME_X_DISPLAY (f);
588 Colormap cmap = FRAME_X_COLORMAP (f);
590 block_input ();
591 #ifdef USE_GTK
592 success_p = xg_check_special_colors (f, color_name, color);
593 #endif
594 if (!success_p)
595 success_p = XParseColor (dpy, cmap, color_name, color) != 0;
596 if (success_p && alloc_p)
597 success_p = x_alloc_nearest_color (f, cmap, color);
598 unblock_input ();
600 return success_p;
604 /* Return the pixel color value for color COLOR_NAME on frame F. If F
605 is a monochrome frame, return MONO_COLOR regardless of what ARG says.
606 Signal an error if color can't be allocated. */
608 static int
609 x_decode_color (FRAME_PTR f, Lisp_Object color_name, int mono_color)
611 XColor cdef;
613 CHECK_STRING (color_name);
615 #if 0 /* Don't do this. It's wrong when we're not using the default
616 colormap, it makes freeing difficult, and it's probably not
617 an important optimization. */
618 if (strcmp (SDATA (color_name), "black") == 0)
619 return BLACK_PIX_DEFAULT (f);
620 else if (strcmp (SDATA (color_name), "white") == 0)
621 return WHITE_PIX_DEFAULT (f);
622 #endif
624 /* Return MONO_COLOR for monochrome frames. */
625 if (FRAME_X_DISPLAY_INFO (f)->n_planes == 1)
626 return mono_color;
628 /* x_defined_color is responsible for coping with failures
629 by looking for a near-miss. */
630 if (x_defined_color (f, SSDATA (color_name), &cdef, 1))
631 return cdef.pixel;
633 signal_error ("Undefined color", color_name);
638 /* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
639 the previous value of that parameter, NEW_VALUE is the new value.
640 See also the comment of wait_for_wm in struct x_output. */
642 static void
643 x_set_wait_for_wm (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
645 f->output_data.x->wait_for_wm = !NILP (new_value);
648 static void
649 x_set_tool_bar_position (struct frame *f,
650 Lisp_Object new_value,
651 Lisp_Object old_value)
653 if (! EQ (new_value, Qleft) && ! EQ (new_value, Qright)
654 && ! EQ (new_value, Qbottom) && ! EQ (new_value, Qtop))
655 return;
656 if (EQ (new_value, old_value)) return;
658 #ifdef USE_GTK
659 xg_change_toolbar_position (f, new_value);
660 fset_tool_bar_position (f, new_value);
661 #endif
664 #ifdef USE_GTK
666 /* Set icon from FILE for frame F. By using GTK functions the icon
667 may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
670 xg_set_icon (FRAME_PTR f, Lisp_Object file)
672 int result = 0;
673 Lisp_Object found;
675 found = x_find_image_file (file);
677 if (! NILP (found))
679 GdkPixbuf *pixbuf;
680 GError *err = NULL;
681 char *filename = SSDATA (found);
682 block_input ();
684 pixbuf = gdk_pixbuf_new_from_file (filename, &err);
686 if (pixbuf)
688 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
689 pixbuf);
690 g_object_unref (pixbuf);
692 result = 1;
694 else
695 g_error_free (err);
697 unblock_input ();
700 return result;
704 xg_set_icon_from_xpm_data (FRAME_PTR f, const char **data)
706 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data (data);
708 if (!pixbuf)
709 return 0;
711 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), pixbuf);
712 g_object_unref (pixbuf);
713 return 1;
715 #endif /* USE_GTK */
718 /* Functions called only from `x_set_frame_param'
719 to set individual parameters.
721 If FRAME_X_WINDOW (f) is 0,
722 the frame is being created and its X-window does not exist yet.
723 In that case, just record the parameter's new value
724 in the standard place; do not attempt to change the window. */
726 static void
727 x_set_foreground_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
729 struct x_output *x = f->output_data.x;
730 unsigned long fg, old_fg;
732 fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
733 old_fg = FRAME_FOREGROUND_PIXEL (f);
734 FRAME_FOREGROUND_PIXEL (f) = fg;
736 if (FRAME_X_WINDOW (f) != 0)
738 Display *dpy = FRAME_X_DISPLAY (f);
740 block_input ();
741 XSetForeground (dpy, x->normal_gc, fg);
742 XSetBackground (dpy, x->reverse_gc, fg);
744 if (x->cursor_pixel == old_fg)
746 unload_color (f, x->cursor_pixel);
747 x->cursor_pixel = x_copy_color (f, fg);
748 XSetBackground (dpy, x->cursor_gc, x->cursor_pixel);
751 unblock_input ();
753 update_face_from_frame_parameter (f, Qforeground_color, arg);
755 if (FRAME_VISIBLE_P (f))
756 redraw_frame (f);
759 unload_color (f, old_fg);
762 static void
763 x_set_background_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
765 struct x_output *x = f->output_data.x;
766 unsigned long bg;
768 bg = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
769 unload_color (f, FRAME_BACKGROUND_PIXEL (f));
770 FRAME_BACKGROUND_PIXEL (f) = bg;
772 if (FRAME_X_WINDOW (f) != 0)
774 Display *dpy = FRAME_X_DISPLAY (f);
776 block_input ();
777 XSetBackground (dpy, x->normal_gc, bg);
778 XSetForeground (dpy, x->reverse_gc, bg);
779 XSetWindowBackground (dpy, FRAME_X_WINDOW (f), bg);
780 XSetForeground (dpy, x->cursor_gc, bg);
782 #ifdef USE_GTK
783 xg_set_background_color (f, bg);
784 #endif
786 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
787 toolkit scroll bars. */
789 Lisp_Object bar;
790 for (bar = FRAME_SCROLL_BARS (f);
791 !NILP (bar);
792 bar = XSCROLL_BAR (bar)->next)
794 Window window = XSCROLL_BAR (bar)->x_window;
795 XSetWindowBackground (dpy, window, bg);
798 #endif /* USE_TOOLKIT_SCROLL_BARS */
800 unblock_input ();
801 update_face_from_frame_parameter (f, Qbackground_color, arg);
803 if (FRAME_VISIBLE_P (f))
804 redraw_frame (f);
808 static Cursor
809 make_invisible_cursor (struct frame *f)
811 Display *dpy = FRAME_X_DISPLAY (f);
812 static char const no_data[] = { 0 };
813 Pixmap pix;
814 XColor col;
815 Cursor c = 0;
817 x_catch_errors (dpy);
818 pix = XCreateBitmapFromData (dpy, FRAME_X_DISPLAY_INFO (f)->root_window,
819 no_data, 1, 1);
820 if (! x_had_errors_p (dpy) && pix != None)
822 Cursor pixc;
823 col.pixel = 0;
824 col.red = col.green = col.blue = 0;
825 col.flags = DoRed | DoGreen | DoBlue;
826 pixc = XCreatePixmapCursor (dpy, pix, pix, &col, &col, 0, 0);
827 if (! x_had_errors_p (dpy) && pixc != None)
828 c = pixc;
829 XFreePixmap (dpy, pix);
832 x_uncatch_errors ();
834 return c;
837 static void
838 x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
840 struct x_output *x = f->output_data.x;
841 Display *dpy = FRAME_X_DISPLAY (f);
842 Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
843 Cursor hourglass_cursor, horizontal_drag_cursor;
844 unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
845 unsigned long mask_color = FRAME_BACKGROUND_PIXEL (f);
847 /* Don't let pointers be invisible. */
848 if (mask_color == pixel)
850 x_free_colors (f, &pixel, 1);
851 pixel = x_copy_color (f, FRAME_FOREGROUND_PIXEL (f));
854 unload_color (f, x->mouse_pixel);
855 x->mouse_pixel = pixel;
857 block_input ();
859 /* It's not okay to crash if the user selects a screwy cursor. */
860 x_catch_errors (dpy);
862 if (!NILP (Vx_pointer_shape))
864 CHECK_NUMBER (Vx_pointer_shape);
865 cursor = XCreateFontCursor (dpy, XINT (Vx_pointer_shape));
867 else
868 cursor = XCreateFontCursor (dpy, XC_xterm);
869 x_check_errors (dpy, "bad text pointer cursor: %s");
871 if (!NILP (Vx_nontext_pointer_shape))
873 CHECK_NUMBER (Vx_nontext_pointer_shape);
874 nontext_cursor
875 = XCreateFontCursor (dpy, XINT (Vx_nontext_pointer_shape));
877 else
878 nontext_cursor = XCreateFontCursor (dpy, XC_left_ptr);
879 x_check_errors (dpy, "bad nontext pointer cursor: %s");
881 if (!NILP (Vx_hourglass_pointer_shape))
883 CHECK_NUMBER (Vx_hourglass_pointer_shape);
884 hourglass_cursor
885 = XCreateFontCursor (dpy, XINT (Vx_hourglass_pointer_shape));
887 else
888 hourglass_cursor = XCreateFontCursor (dpy, XC_watch);
889 x_check_errors (dpy, "bad hourglass pointer cursor: %s");
891 if (!NILP (Vx_mode_pointer_shape))
893 CHECK_NUMBER (Vx_mode_pointer_shape);
894 mode_cursor = XCreateFontCursor (dpy, XINT (Vx_mode_pointer_shape));
896 else
897 mode_cursor = XCreateFontCursor (dpy, XC_xterm);
898 x_check_errors (dpy, "bad modeline pointer cursor: %s");
900 if (!NILP (Vx_sensitive_text_pointer_shape))
902 CHECK_NUMBER (Vx_sensitive_text_pointer_shape);
903 hand_cursor
904 = XCreateFontCursor (dpy, XINT (Vx_sensitive_text_pointer_shape));
906 else
907 hand_cursor = XCreateFontCursor (dpy, XC_hand2);
909 if (!NILP (Vx_window_horizontal_drag_shape))
911 CHECK_NUMBER (Vx_window_horizontal_drag_shape);
912 horizontal_drag_cursor
913 = XCreateFontCursor (dpy, XINT (Vx_window_horizontal_drag_shape));
915 else
916 horizontal_drag_cursor
917 = XCreateFontCursor (dpy, XC_sb_h_double_arrow);
919 /* Check and report errors with the above calls. */
920 x_check_errors (dpy, "can't set cursor shape: %s");
921 x_uncatch_errors ();
924 XColor fore_color, back_color;
926 fore_color.pixel = x->mouse_pixel;
927 x_query_color (f, &fore_color);
928 back_color.pixel = mask_color;
929 x_query_color (f, &back_color);
931 XRecolorCursor (dpy, cursor, &fore_color, &back_color);
932 XRecolorCursor (dpy, nontext_cursor, &fore_color, &back_color);
933 XRecolorCursor (dpy, mode_cursor, &fore_color, &back_color);
934 XRecolorCursor (dpy, hand_cursor, &fore_color, &back_color);
935 XRecolorCursor (dpy, hourglass_cursor, &fore_color, &back_color);
936 XRecolorCursor (dpy, horizontal_drag_cursor, &fore_color, &back_color);
939 if (FRAME_X_WINDOW (f) != 0)
940 XDefineCursor (dpy, FRAME_X_WINDOW (f),
941 f->output_data.x->current_cursor = cursor);
943 if (FRAME_X_DISPLAY_INFO (f)->invisible_cursor == 0)
944 FRAME_X_DISPLAY_INFO (f)->invisible_cursor = make_invisible_cursor (f);
946 if (cursor != x->text_cursor
947 && x->text_cursor != 0)
948 XFreeCursor (dpy, x->text_cursor);
949 x->text_cursor = cursor;
951 if (nontext_cursor != x->nontext_cursor
952 && x->nontext_cursor != 0)
953 XFreeCursor (dpy, x->nontext_cursor);
954 x->nontext_cursor = nontext_cursor;
956 if (hourglass_cursor != x->hourglass_cursor
957 && x->hourglass_cursor != 0)
958 XFreeCursor (dpy, x->hourglass_cursor);
959 x->hourglass_cursor = hourglass_cursor;
961 if (mode_cursor != x->modeline_cursor
962 && x->modeline_cursor != 0)
963 XFreeCursor (dpy, f->output_data.x->modeline_cursor);
964 x->modeline_cursor = mode_cursor;
966 if (hand_cursor != x->hand_cursor
967 && x->hand_cursor != 0)
968 XFreeCursor (dpy, x->hand_cursor);
969 x->hand_cursor = hand_cursor;
971 if (horizontal_drag_cursor != x->horizontal_drag_cursor
972 && x->horizontal_drag_cursor != 0)
973 XFreeCursor (dpy, x->horizontal_drag_cursor);
974 x->horizontal_drag_cursor = horizontal_drag_cursor;
976 XFlush (dpy);
977 unblock_input ();
979 update_face_from_frame_parameter (f, Qmouse_color, arg);
982 static void
983 x_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
985 unsigned long fore_pixel, pixel;
986 int fore_pixel_allocated_p = 0, pixel_allocated_p = 0;
987 struct x_output *x = f->output_data.x;
989 if (!NILP (Vx_cursor_fore_pixel))
991 fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
992 WHITE_PIX_DEFAULT (f));
993 fore_pixel_allocated_p = 1;
995 else
996 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
998 pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
999 pixel_allocated_p = 1;
1001 /* Make sure that the cursor color differs from the background color. */
1002 if (pixel == FRAME_BACKGROUND_PIXEL (f))
1004 if (pixel_allocated_p)
1006 x_free_colors (f, &pixel, 1);
1007 pixel_allocated_p = 0;
1010 pixel = x->mouse_pixel;
1011 if (pixel == fore_pixel)
1013 if (fore_pixel_allocated_p)
1015 x_free_colors (f, &fore_pixel, 1);
1016 fore_pixel_allocated_p = 0;
1018 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1022 unload_color (f, x->cursor_foreground_pixel);
1023 if (!fore_pixel_allocated_p)
1024 fore_pixel = x_copy_color (f, fore_pixel);
1025 x->cursor_foreground_pixel = fore_pixel;
1027 unload_color (f, x->cursor_pixel);
1028 if (!pixel_allocated_p)
1029 pixel = x_copy_color (f, pixel);
1030 x->cursor_pixel = pixel;
1032 if (FRAME_X_WINDOW (f) != 0)
1034 block_input ();
1035 XSetBackground (FRAME_X_DISPLAY (f), x->cursor_gc, x->cursor_pixel);
1036 XSetForeground (FRAME_X_DISPLAY (f), x->cursor_gc, fore_pixel);
1037 unblock_input ();
1039 if (FRAME_VISIBLE_P (f))
1041 x_update_cursor (f, 0);
1042 x_update_cursor (f, 1);
1046 update_face_from_frame_parameter (f, Qcursor_color, arg);
1049 /* Set the border-color of frame F to pixel value PIX.
1050 Note that this does not fully take effect if done before
1051 F has an x-window. */
1053 static void
1054 x_set_border_pixel (struct frame *f, int pix)
1056 unload_color (f, f->output_data.x->border_pixel);
1057 f->output_data.x->border_pixel = pix;
1059 if (FRAME_X_WINDOW (f) != 0 && f->border_width > 0)
1061 block_input ();
1062 XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), pix);
1063 unblock_input ();
1065 if (FRAME_VISIBLE_P (f))
1066 redraw_frame (f);
1070 /* Set the border-color of frame F to value described by ARG.
1071 ARG can be a string naming a color.
1072 The border-color is used for the border that is drawn by the X server.
1073 Note that this does not fully take effect if done before
1074 F has an x-window; it must be redone when the window is created.
1076 Note: this is done in two routines because of the way X10 works.
1078 Note: under X11, this is normally the province of the window manager,
1079 and so emacs' border colors may be overridden. */
1081 static void
1082 x_set_border_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1084 int pix;
1086 CHECK_STRING (arg);
1087 pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1088 x_set_border_pixel (f, pix);
1089 update_face_from_frame_parameter (f, Qborder_color, arg);
1093 static void
1094 x_set_cursor_type (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
1096 set_frame_cursor_types (f, arg);
1098 /* Make sure the cursor gets redrawn. */
1099 cursor_type_changed = 1;
1102 static void
1103 x_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1105 int result;
1107 if (STRINGP (arg))
1109 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1110 return;
1112 else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
1113 return;
1115 block_input ();
1116 if (NILP (arg))
1117 result = x_text_icon (f,
1118 SSDATA ((!NILP (f->icon_name)
1119 ? f->icon_name
1120 : f->name)));
1121 else
1122 result = x_bitmap_icon (f, arg);
1124 if (result)
1126 unblock_input ();
1127 error ("No icon window available");
1130 XFlush (FRAME_X_DISPLAY (f));
1131 unblock_input ();
1134 static void
1135 x_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1137 int result;
1139 if (STRINGP (arg))
1141 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1142 return;
1144 else if (!NILP (arg) || NILP (oldval))
1145 return;
1147 fset_icon_name (f, arg);
1149 if (f->output_data.x->icon_bitmap != 0)
1150 return;
1152 block_input ();
1154 result = x_text_icon (f,
1155 SSDATA ((!NILP (f->icon_name)
1156 ? f->icon_name
1157 : !NILP (f->title)
1158 ? f->title
1159 : f->name)));
1161 if (result)
1163 unblock_input ();
1164 error ("No icon window available");
1167 XFlush (FRAME_X_DISPLAY (f));
1168 unblock_input ();
1172 void
1173 x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1175 int nlines;
1176 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
1177 int olines = FRAME_MENU_BAR_LINES (f);
1178 #endif
1180 /* Right now, menu bars don't work properly in minibuf-only frames;
1181 most of the commands try to apply themselves to the minibuffer
1182 frame itself, and get an error because you can't switch buffers
1183 in or split the minibuffer window. */
1184 if (FRAME_MINIBUF_ONLY_P (f))
1185 return;
1187 if (TYPE_RANGED_INTEGERP (int, value))
1188 nlines = XINT (value);
1189 else
1190 nlines = 0;
1192 /* Make sure we redisplay all windows in this frame. */
1193 windows_or_buffers_changed++;
1195 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1196 FRAME_MENU_BAR_LINES (f) = 0;
1197 if (nlines)
1199 FRAME_EXTERNAL_MENU_BAR (f) = 1;
1200 if (FRAME_X_P (f) && f->output_data.x->menubar_widget == 0)
1201 /* Make sure next redisplay shows the menu bar. */
1202 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = 1;
1204 else
1206 if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
1207 free_frame_menubar (f);
1208 FRAME_EXTERNAL_MENU_BAR (f) = 0;
1209 if (FRAME_X_P (f))
1210 f->output_data.x->menubar_widget = 0;
1212 #else /* not USE_X_TOOLKIT && not USE_GTK */
1213 FRAME_MENU_BAR_LINES (f) = nlines;
1214 resize_frame_windows (f, FRAME_LINES (f), 0);
1216 /* If the menu bar height gets changed, the internal border below
1217 the top margin has to be cleared. Also, if the menu bar gets
1218 larger, the area for the added lines has to be cleared except for
1219 the first menu bar line that is to be drawn later. */
1220 if (nlines != olines)
1222 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1223 int width = FRAME_PIXEL_WIDTH (f);
1224 int y;
1226 /* height can be zero here. */
1227 if (height > 0 && width > 0)
1229 y = FRAME_TOP_MARGIN_HEIGHT (f);
1231 block_input ();
1232 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1233 0, y, width, height, False);
1234 unblock_input ();
1237 if (nlines > 1 && nlines > olines)
1239 y = (olines == 0 ? 1 : olines) * FRAME_LINE_HEIGHT (f);
1240 height = nlines * FRAME_LINE_HEIGHT (f) - y;
1242 block_input ();
1243 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1244 0, y, width, height, False);
1245 unblock_input ();
1248 if (nlines == 0 && WINDOWP (f->menu_bar_window))
1249 clear_glyph_matrix (XWINDOW (f->menu_bar_window)->current_matrix);
1251 #endif /* not USE_X_TOOLKIT && not USE_GTK */
1252 adjust_glyphs (f);
1253 run_window_configuration_change_hook (f);
1257 /* Set the number of lines used for the tool bar of frame F to VALUE.
1258 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1259 is the old number of tool bar lines. This function changes the
1260 height of all windows on frame F to match the new tool bar height.
1261 The frame's height doesn't change. */
1263 void
1264 x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1266 int delta, nlines, root_height;
1267 Lisp_Object root_window;
1269 /* Treat tool bars like menu bars. */
1270 if (FRAME_MINIBUF_ONLY_P (f))
1271 return;
1273 /* Use VALUE only if an int >= 0. */
1274 if (RANGED_INTEGERP (0, value, INT_MAX))
1275 nlines = XFASTINT (value);
1276 else
1277 nlines = 0;
1279 #ifdef USE_GTK
1280 FRAME_TOOL_BAR_LINES (f) = 0;
1281 if (nlines)
1283 FRAME_EXTERNAL_TOOL_BAR (f) = 1;
1284 if (FRAME_X_P (f) && f->output_data.x->toolbar_widget == 0)
1285 /* Make sure next redisplay shows the tool bar. */
1286 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = 1;
1287 update_frame_tool_bar (f);
1289 else
1291 if (FRAME_EXTERNAL_TOOL_BAR (f))
1292 free_frame_tool_bar (f);
1293 FRAME_EXTERNAL_TOOL_BAR (f) = 0;
1296 return;
1297 #endif
1299 /* Make sure we redisplay all windows in this frame. */
1300 ++windows_or_buffers_changed;
1302 delta = nlines - FRAME_TOOL_BAR_LINES (f);
1304 /* Don't resize the tool-bar to more than we have room for. */
1305 root_window = FRAME_ROOT_WINDOW (f);
1306 root_height = WINDOW_TOTAL_LINES (XWINDOW (root_window));
1307 if (root_height - delta < 1)
1309 delta = root_height - 1;
1310 nlines = FRAME_TOOL_BAR_LINES (f) + delta;
1313 FRAME_TOOL_BAR_LINES (f) = nlines;
1314 resize_frame_windows (f, FRAME_LINES (f), 0);
1315 adjust_glyphs (f);
1317 /* We also have to make sure that the internal border at the top of
1318 the frame, below the menu bar or tool bar, is redrawn when the
1319 tool bar disappears. This is so because the internal border is
1320 below the tool bar if one is displayed, but is below the menu bar
1321 if there isn't a tool bar. The tool bar draws into the area
1322 below the menu bar. */
1323 if (FRAME_X_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0)
1325 clear_frame (f);
1326 clear_current_matrices (f);
1329 /* If the tool bar gets smaller, the internal border below it
1330 has to be cleared. It was formerly part of the display
1331 of the larger tool bar, and updating windows won't clear it. */
1332 if (delta < 0)
1334 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1335 int width = FRAME_PIXEL_WIDTH (f);
1336 int y = (FRAME_MENU_BAR_LINES (f) + nlines) * FRAME_LINE_HEIGHT (f);
1338 /* height can be zero here. */
1339 if (height > 0 && width > 0)
1341 block_input ();
1342 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1343 0, y, width, height, False);
1344 unblock_input ();
1347 if (WINDOWP (f->tool_bar_window))
1348 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1351 run_window_configuration_change_hook (f);
1356 /* Set the foreground color for scroll bars on frame F to VALUE.
1357 VALUE should be a string, a color name. If it isn't a string or
1358 isn't a valid color name, do nothing. OLDVAL is the old value of
1359 the frame parameter. */
1361 static void
1362 x_set_scroll_bar_foreground (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1364 unsigned long pixel;
1366 if (STRINGP (value))
1367 pixel = x_decode_color (f, value, BLACK_PIX_DEFAULT (f));
1368 else
1369 pixel = -1;
1371 if (f->output_data.x->scroll_bar_foreground_pixel != -1)
1372 unload_color (f, f->output_data.x->scroll_bar_foreground_pixel);
1374 f->output_data.x->scroll_bar_foreground_pixel = pixel;
1375 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1377 /* Remove all scroll bars because they have wrong colors. */
1378 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1379 (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1380 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1381 (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1383 update_face_from_frame_parameter (f, Qscroll_bar_foreground, value);
1384 redraw_frame (f);
1389 /* Set the background color for scroll bars on frame F to VALUE VALUE
1390 should be a string, a color name. If it isn't a string or isn't a
1391 valid color name, do nothing. OLDVAL is the old value of the frame
1392 parameter. */
1394 static void
1395 x_set_scroll_bar_background (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1397 unsigned long pixel;
1399 if (STRINGP (value))
1400 pixel = x_decode_color (f, value, WHITE_PIX_DEFAULT (f));
1401 else
1402 pixel = -1;
1404 if (f->output_data.x->scroll_bar_background_pixel != -1)
1405 unload_color (f, f->output_data.x->scroll_bar_background_pixel);
1407 #ifdef USE_TOOLKIT_SCROLL_BARS
1408 /* Scrollbar shadow colors. */
1409 if (f->output_data.x->scroll_bar_top_shadow_pixel != -1)
1411 unload_color (f, f->output_data.x->scroll_bar_top_shadow_pixel);
1412 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
1414 if (f->output_data.x->scroll_bar_bottom_shadow_pixel != -1)
1416 unload_color (f, f->output_data.x->scroll_bar_bottom_shadow_pixel);
1417 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
1419 #endif /* USE_TOOLKIT_SCROLL_BARS */
1421 f->output_data.x->scroll_bar_background_pixel = pixel;
1422 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1424 /* Remove all scroll bars because they have wrong colors. */
1425 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1426 (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1427 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1428 (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1430 update_face_from_frame_parameter (f, Qscroll_bar_background, value);
1431 redraw_frame (f);
1436 /* Encode Lisp string STRING as a text in a format appropriate for
1437 XICCC (X Inter Client Communication Conventions).
1439 This can call Lisp code, so callers must GCPRO.
1441 If STRING contains only ASCII characters, do no conversion and
1442 return the string data of STRING. Otherwise, encode the text by
1443 CODING_SYSTEM, and return a newly allocated memory area which
1444 should be freed by `xfree' by a caller.
1446 SELECTIONP non-zero means the string is being encoded for an X
1447 selection, so it is safe to run pre-write conversions (which
1448 may run Lisp code).
1450 Store the byte length of resulting text in *TEXT_BYTES.
1452 If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
1453 which means that the `encoding' of the result can be `STRING'.
1454 Otherwise store 0 in *STRINGP, which means that the `encoding' of
1455 the result should be `COMPOUND_TEXT'. */
1457 static unsigned char *
1458 x_encode_text (Lisp_Object string, Lisp_Object coding_system, int selectionp,
1459 ptrdiff_t *text_bytes, int *stringp, int *freep)
1461 int result = string_xstring_p (string);
1462 struct coding_system coding;
1464 if (result == 0)
1466 /* No multibyte character in OBJ. We need not encode it. */
1467 *text_bytes = SBYTES (string);
1468 *stringp = 1;
1469 *freep = 0;
1470 return SDATA (string);
1473 setup_coding_system (coding_system, &coding);
1474 coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK);
1475 /* We suppress producing escape sequences for composition. */
1476 coding.common_flags &= ~CODING_ANNOTATION_MASK;
1477 coding.destination = xnmalloc (SCHARS (string), 2);
1478 coding.dst_bytes = SCHARS (string) * 2;
1479 encode_coding_object (&coding, string, 0, 0,
1480 SCHARS (string), SBYTES (string), Qnil);
1481 *text_bytes = coding.produced;
1482 *stringp = (result == 1 || !EQ (coding_system, Qcompound_text));
1483 *freep = 1;
1484 return coding.destination;
1488 /* Set the WM name to NAME for frame F. Also set the icon name.
1489 If the frame already has an icon name, use that, otherwise set the
1490 icon name to NAME. */
1492 static void
1493 x_set_name_internal (FRAME_PTR f, Lisp_Object name)
1495 if (FRAME_X_WINDOW (f))
1497 block_input ();
1499 XTextProperty text, icon;
1500 ptrdiff_t bytes;
1501 int stringp;
1502 int do_free_icon_value = 0, do_free_text_value = 0;
1503 Lisp_Object coding_system;
1504 Lisp_Object encoded_name;
1505 Lisp_Object encoded_icon_name;
1506 struct gcpro gcpro1;
1508 /* As ENCODE_UTF_8 may cause GC and relocation of string data,
1509 we use it before x_encode_text that may return string data. */
1510 GCPRO1 (name);
1511 encoded_name = ENCODE_UTF_8 (name);
1512 UNGCPRO;
1514 coding_system = Qcompound_text;
1515 /* Note: Encoding strategy
1517 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1518 text.encoding. But, there are non-internationalized window
1519 managers which don't support that encoding. So, if NAME
1520 contains only ASCII and 8859-1 characters, encode it by
1521 iso-latin-1, and use "STRING" in text.encoding hoping that
1522 such window managers at least analyze this format correctly,
1523 i.e. treat 8-bit bytes as 8859-1 characters.
1525 We may also be able to use "UTF8_STRING" in text.encoding
1526 in the future which can encode all Unicode characters.
1527 But, for the moment, there's no way to know that the
1528 current window manager supports it or not.
1530 Either way, we also set the _NET_WM_NAME and _NET_WM_ICON_NAME
1531 properties. Per the EWMH specification, those two properties
1532 are always UTF8_STRING. This matches what gtk_window_set_title()
1533 does in the USE_GTK case. */
1534 text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp,
1535 &do_free_text_value);
1536 text.encoding = (stringp ? XA_STRING
1537 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1538 text.format = 8;
1539 text.nitems = bytes;
1540 if (text.nitems != bytes)
1541 error ("Window name too large");
1543 if (!STRINGP (f->icon_name))
1545 icon = text;
1546 encoded_icon_name = encoded_name;
1548 else
1550 /* See the above comment "Note: Encoding strategy". */
1551 icon.value = x_encode_text (f->icon_name, coding_system, 0,
1552 &bytes, &stringp, &do_free_icon_value);
1553 icon.encoding = (stringp ? XA_STRING
1554 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1555 icon.format = 8;
1556 icon.nitems = bytes;
1557 if (icon.nitems != bytes)
1558 error ("Icon name too large");
1560 encoded_icon_name = ENCODE_UTF_8 (f->icon_name);
1563 #ifdef USE_GTK
1564 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
1565 SSDATA (encoded_name));
1566 #else /* not USE_GTK */
1567 XSetWMName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &text);
1568 XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
1569 FRAME_X_DISPLAY_INFO (f)->Xatom_net_wm_name,
1570 FRAME_X_DISPLAY_INFO (f)->Xatom_UTF8_STRING,
1571 8, PropModeReplace,
1572 SDATA (encoded_name),
1573 SBYTES (encoded_name));
1574 #endif /* not USE_GTK */
1576 XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &icon);
1577 XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
1578 FRAME_X_DISPLAY_INFO (f)->Xatom_net_wm_icon_name,
1579 FRAME_X_DISPLAY_INFO (f)->Xatom_UTF8_STRING,
1580 8, PropModeReplace,
1581 SDATA (encoded_icon_name),
1582 SBYTES (encoded_icon_name));
1584 if (do_free_icon_value)
1585 xfree (icon.value);
1586 if (do_free_text_value)
1587 xfree (text.value);
1589 unblock_input ();
1593 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1594 x_id_name.
1596 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1597 name; if NAME is a string, set F's name to NAME and set
1598 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1600 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1601 suggesting a new name, which lisp code should override; if
1602 F->explicit_name is set, ignore the new name; otherwise, set it. */
1604 static void
1605 x_set_name (struct frame *f, Lisp_Object name, int explicit)
1607 /* Make sure that requests from lisp code override requests from
1608 Emacs redisplay code. */
1609 if (explicit)
1611 /* If we're switching from explicit to implicit, we had better
1612 update the mode lines and thereby update the title. */
1613 if (f->explicit_name && NILP (name))
1614 update_mode_lines = 1;
1616 f->explicit_name = ! NILP (name);
1618 else if (f->explicit_name)
1619 return;
1621 /* If NAME is nil, set the name to the x_id_name. */
1622 if (NILP (name))
1624 /* Check for no change needed in this very common case
1625 before we do any consing. */
1626 if (!strcmp (FRAME_X_DISPLAY_INFO (f)->x_id_name,
1627 SSDATA (f->name)))
1628 return;
1629 name = build_string (FRAME_X_DISPLAY_INFO (f)->x_id_name);
1631 else
1632 CHECK_STRING (name);
1634 /* Don't change the name if it's already NAME. */
1635 if (! NILP (Fstring_equal (name, f->name)))
1636 return;
1638 fset_name (f, name);
1640 /* For setting the frame title, the title parameter should override
1641 the name parameter. */
1642 if (! NILP (f->title))
1643 name = f->title;
1645 x_set_name_internal (f, name);
1648 /* This function should be called when the user's lisp code has
1649 specified a name for the frame; the name will override any set by the
1650 redisplay code. */
1651 static void
1652 x_explicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
1654 x_set_name (f, arg, 1);
1657 /* This function should be called by Emacs redisplay code to set the
1658 name; names set this way will never override names set by the user's
1659 lisp code. */
1660 void
1661 x_implicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
1663 x_set_name (f, arg, 0);
1666 /* Change the title of frame F to NAME.
1667 If NAME is nil, use the frame name as the title. */
1669 static void
1670 x_set_title (struct frame *f, Lisp_Object name, Lisp_Object old_name)
1672 /* Don't change the title if it's already NAME. */
1673 if (EQ (name, f->title))
1674 return;
1676 update_mode_lines = 1;
1678 fset_title (f, name);
1680 if (NILP (name))
1681 name = f->name;
1682 else
1683 CHECK_STRING (name);
1685 x_set_name_internal (f, name);
1688 void
1689 x_set_scroll_bar_default_width (struct frame *f)
1691 int wid = FRAME_COLUMN_WIDTH (f);
1692 #ifdef USE_TOOLKIT_SCROLL_BARS
1693 #ifdef USE_GTK
1694 int minw = xg_get_default_scrollbar_width ();
1695 #else
1696 int minw = 16;
1697 #endif
1698 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
1699 int width = minw + 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM;
1700 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (width + wid - 1) / wid;
1701 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = width;
1702 #else
1703 /* Make the actual width at least 14 pixels and a multiple of a
1704 character width. */
1705 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
1707 /* Use all of that space (aside from required margins) for the
1708 scroll bar. */
1709 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 0;
1710 #endif
1714 /* Record in frame F the specified or default value according to ALIST
1715 of the parameter named PROP (a Lisp symbol). If no value is
1716 specified for PROP, look for an X default for XPROP on the frame
1717 named NAME. If that is not found either, use the value DEFLT. */
1719 static Lisp_Object
1720 x_default_scroll_bar_color_parameter (struct frame *f,
1721 Lisp_Object alist, Lisp_Object prop,
1722 const char *xprop, const char *xclass,
1723 int foreground_p)
1725 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
1726 Lisp_Object tem;
1728 tem = x_get_arg (dpyinfo, alist, prop, xprop, xclass, RES_TYPE_STRING);
1729 if (EQ (tem, Qunbound))
1731 #ifdef USE_TOOLKIT_SCROLL_BARS
1733 /* See if an X resource for the scroll bar color has been
1734 specified. */
1735 tem = display_x_get_resource (dpyinfo,
1736 build_string (foreground_p
1737 ? "foreground"
1738 : "background"),
1739 empty_unibyte_string,
1740 build_string ("verticalScrollBar"),
1741 empty_unibyte_string);
1742 if (!STRINGP (tem))
1744 /* If nothing has been specified, scroll bars will use a
1745 toolkit-dependent default. Because these defaults are
1746 difficult to get at without actually creating a scroll
1747 bar, use nil to indicate that no color has been
1748 specified. */
1749 tem = Qnil;
1752 #else /* not USE_TOOLKIT_SCROLL_BARS */
1754 tem = Qnil;
1756 #endif /* not USE_TOOLKIT_SCROLL_BARS */
1759 x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));
1760 return tem;
1766 #ifdef USE_X_TOOLKIT
1768 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
1769 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
1770 already be present because of the toolkit (Motif adds some of them,
1771 for example, but Xt doesn't). */
1773 static void
1774 hack_wm_protocols (FRAME_PTR f, Widget widget)
1776 Display *dpy = XtDisplay (widget);
1777 Window w = XtWindow (widget);
1778 int need_delete = 1;
1779 int need_focus = 1;
1780 int need_save = 1;
1782 block_input ();
1784 Atom type;
1785 unsigned char *catoms;
1786 int format = 0;
1787 unsigned long nitems = 0;
1788 unsigned long bytes_after;
1790 if ((XGetWindowProperty (dpy, w,
1791 FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
1792 (long)0, (long)100, False, XA_ATOM,
1793 &type, &format, &nitems, &bytes_after,
1794 &catoms)
1795 == Success)
1796 && format == 32 && type == XA_ATOM)
1798 Atom *atoms = (Atom *) catoms;
1799 while (nitems > 0)
1801 nitems--;
1802 if (atoms[nitems]
1803 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window)
1804 need_delete = 0;
1805 else if (atoms[nitems]
1806 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus)
1807 need_focus = 0;
1808 else if (atoms[nitems]
1809 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself)
1810 need_save = 0;
1813 if (catoms)
1814 XFree (catoms);
1817 Atom props [10];
1818 int count = 0;
1819 if (need_delete)
1820 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window;
1821 if (need_focus)
1822 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus;
1823 if (need_save)
1824 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
1825 if (count)
1826 XChangeProperty (dpy, w, FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
1827 XA_ATOM, 32, PropModeAppend,
1828 (unsigned char *) props, count);
1830 unblock_input ();
1832 #endif
1836 /* Support routines for XIC (X Input Context). */
1838 #ifdef HAVE_X_I18N
1840 static XFontSet xic_create_xfontset (struct frame *);
1841 static XIMStyle best_xim_style (XIMStyles *, XIMStyles *);
1844 /* Supported XIM styles, ordered by preference. */
1846 static XIMStyle supported_xim_styles[] =
1848 XIMPreeditPosition | XIMStatusArea,
1849 XIMPreeditPosition | XIMStatusNothing,
1850 XIMPreeditPosition | XIMStatusNone,
1851 XIMPreeditNothing | XIMStatusArea,
1852 XIMPreeditNothing | XIMStatusNothing,
1853 XIMPreeditNothing | XIMStatusNone,
1854 XIMPreeditNone | XIMStatusArea,
1855 XIMPreeditNone | XIMStatusNothing,
1856 XIMPreeditNone | XIMStatusNone,
1861 #if defined HAVE_X_WINDOWS && defined USE_X_TOOLKIT
1862 /* Create an X fontset on frame F with base font name BASE_FONTNAME. */
1864 static const char xic_default_fontset[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
1866 /* Create an Xt fontset spec from the name of a base font.
1867 If `motif' is True use the Motif syntax. */
1868 char *
1869 xic_create_fontsetname (const char *base_fontname, int motif)
1871 const char *sep = motif ? ";" : ",";
1872 char *fontsetname;
1874 /* Make a fontset name from the base font name. */
1875 if (xic_default_fontset == base_fontname)
1877 /* There is no base font name, use the default. */
1878 fontsetname = xmalloc (strlen (base_fontname) + 2);
1879 strcpy (fontsetname, base_fontname);
1881 else
1883 /* Make a fontset name from the base font name.
1884 The font set will be made of the following elements:
1885 - the base font.
1886 - the base font where the charset spec is replaced by -*-*.
1887 - the same but with the family also replaced with -*-*-. */
1888 const char *p = base_fontname;
1889 ptrdiff_t i;
1891 for (i = 0; *p; p++)
1892 if (*p == '-') i++;
1893 if (i != 14)
1895 /* As the font name doesn't conform to XLFD, we can't
1896 modify it to generalize it to allcs and allfamilies.
1897 Use the specified font plus the default. */
1898 fontsetname = xmalloc (strlen (base_fontname)
1899 + strlen (xic_default_fontset) + 3);
1900 strcpy (fontsetname, base_fontname);
1901 strcat (fontsetname, sep);
1902 strcat (fontsetname, xic_default_fontset);
1904 else
1906 ptrdiff_t len;
1907 const char *p1 = NULL, *p2 = NULL, *p3 = NULL;
1908 char *font_allcs = NULL;
1909 char *font_allfamilies = NULL;
1910 char *font_all = NULL;
1911 const char *allcs = "*-*-*-*-*-*-*";
1912 const char *allfamilies = "-*-*-";
1913 const char *all = "*-*-*-*-";
1914 char *base;
1916 for (i = 0, p = base_fontname; i < 8; p++)
1918 if (*p == '-')
1920 i++;
1921 if (i == 3)
1922 p1 = p + 1;
1923 else if (i == 7)
1924 p2 = p + 1;
1925 else if (i == 6)
1926 p3 = p + 1;
1929 /* If base_fontname specifies ADSTYLE, make it a
1930 wildcard. */
1931 if (*p3 != '*')
1933 ptrdiff_t diff = (p2 - p3) - 2;
1935 base = alloca (strlen (base_fontname) + 1);
1936 memcpy (base, base_fontname, p3 - base_fontname);
1937 base[p3 - base_fontname] = '*';
1938 base[(p3 - base_fontname) + 1] = '-';
1939 strcpy (base + (p3 - base_fontname) + 2, p2);
1940 p = base + (p - base_fontname) - diff;
1941 p1 = base + (p1 - base_fontname);
1942 p2 = base + (p2 - base_fontname) - diff;
1943 base_fontname = base;
1946 /* Build the font spec that matches all charsets. */
1947 len = p - base_fontname + strlen (allcs) + 1;
1948 font_allcs = alloca (len);
1949 memcpy (font_allcs, base_fontname, p - base_fontname);
1950 strcat (font_allcs, allcs);
1952 /* Build the font spec that matches all families and
1953 add-styles. */
1954 len = p - p1 + strlen (allcs) + strlen (allfamilies) + 1;
1955 font_allfamilies = alloca (len);
1956 strcpy (font_allfamilies, allfamilies);
1957 memcpy (font_allfamilies + strlen (allfamilies), p1, p - p1);
1958 strcat (font_allfamilies, allcs);
1960 /* Build the font spec that matches all. */
1961 len = p - p2 + strlen (allcs) + strlen (all) + strlen (allfamilies) + 1;
1962 font_all = alloca (len);
1963 strcpy (font_all, allfamilies);
1964 strcat (font_all, all);
1965 memcpy (font_all + strlen (all) + strlen (allfamilies), p2, p - p2);
1966 strcat (font_all, allcs);
1968 /* Build the actual font set name. */
1969 len = strlen (base_fontname) + strlen (font_allcs)
1970 + strlen (font_allfamilies) + strlen (font_all) + 5;
1971 fontsetname = xmalloc (len);
1972 strcpy (fontsetname, base_fontname);
1973 strcat (fontsetname, sep);
1974 strcat (fontsetname, font_allcs);
1975 strcat (fontsetname, sep);
1976 strcat (fontsetname, font_allfamilies);
1977 strcat (fontsetname, sep);
1978 strcat (fontsetname, font_all);
1981 if (motif)
1982 strcat (fontsetname, ":");
1983 return fontsetname;
1985 #endif /* HAVE_X_WINDOWS && USE_X_TOOLKIT */
1987 #ifdef DEBUG_XIC_FONTSET
1988 static void
1989 print_fontset_result (XFontSet xfs, char *name, char **missing_list,
1990 int missing_count)
1992 if (xfs)
1993 fprintf (stderr, "XIC Fontset created: %s\n", name);
1994 else
1996 fprintf (stderr, "XIC Fontset failed: %s\n", name);
1997 while (missing_count-- > 0)
1999 fprintf (stderr, " missing: %s\n", *missing_list);
2000 missing_list++;
2005 #endif
2007 static XFontSet
2008 xic_create_xfontset (struct frame *f)
2010 XFontSet xfs = NULL;
2011 struct font *font = FRAME_FONT (f);
2012 int pixel_size = font->pixel_size;
2013 Lisp_Object rest, frame;
2015 /* See if there is another frame already using same fontset. */
2016 FOR_EACH_FRAME (rest, frame)
2018 struct frame *cf = XFRAME (frame);
2020 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
2021 && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f)
2022 && FRAME_FONT (f)
2023 && FRAME_FONT (f)->pixel_size == pixel_size)
2025 xfs = FRAME_XIC_FONTSET (cf);
2026 break;
2030 if (! xfs)
2032 char buf[256];
2033 char **missing_list;
2034 int missing_count;
2035 char *def_string;
2036 const char *xlfd_format = "-*-*-medium-r-normal--%d-*-*-*-*-*";
2038 sprintf (buf, xlfd_format, pixel_size);
2039 missing_list = NULL;
2040 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
2041 &missing_list, &missing_count, &def_string);
2042 #ifdef DEBUG_XIC_FONTSET
2043 print_fontset_result (xfs, buf, missing_list, missing_count);
2044 #endif
2045 if (missing_list)
2046 XFreeStringList (missing_list);
2047 if (! xfs)
2049 /* List of pixel sizes most likely available. Find one that
2050 is closest to pixel_size. */
2051 int sizes[] = {0, 8, 10, 11, 12, 14, 17, 18, 20, 24, 26, 34, 0};
2052 int *smaller, *larger;
2054 for (smaller = sizes; smaller[1]; smaller++)
2055 if (smaller[1] >= pixel_size)
2056 break;
2057 larger = smaller + 1;
2058 if (*larger == pixel_size)
2059 larger++;
2060 while (*smaller || *larger)
2062 int this_size;
2064 if (! *larger)
2065 this_size = *smaller--;
2066 else if (! *smaller)
2067 this_size = *larger++;
2068 else if (pixel_size - *smaller < *larger - pixel_size)
2069 this_size = *smaller--;
2070 else
2071 this_size = *larger++;
2072 sprintf (buf, xlfd_format, this_size);
2073 missing_list = NULL;
2074 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
2075 &missing_list, &missing_count, &def_string);
2076 #ifdef DEBUG_XIC_FONTSET
2077 print_fontset_result (xfs, buf, missing_list, missing_count);
2078 #endif
2079 if (missing_list)
2080 XFreeStringList (missing_list);
2081 if (xfs)
2082 break;
2085 if (! xfs)
2087 const char *last_resort = "-*-*-*-r-normal--*-*-*-*-*-*";
2089 missing_list = NULL;
2090 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), last_resort,
2091 &missing_list, &missing_count, &def_string);
2092 #ifdef DEBUG_XIC_FONTSET
2093 print_fontset_result (xfs, last_resort, missing_list, missing_count);
2094 #endif
2095 if (missing_list)
2096 XFreeStringList (missing_list);
2101 return xfs;
2104 /* Free the X fontset of frame F if it is the last frame using it. */
2106 void
2107 xic_free_xfontset (struct frame *f)
2109 Lisp_Object rest, frame;
2110 int shared_p = 0;
2112 if (!FRAME_XIC_FONTSET (f))
2113 return;
2115 /* See if there is another frame sharing the 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_FONTSET (cf) == FRAME_XIC_FONTSET (f))
2123 shared_p = 1;
2124 break;
2128 if (!shared_p)
2129 /* The fontset is not used anymore. It is safe to free it. */
2130 XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f));
2132 if (FRAME_XIC_BASE_FONTNAME (f))
2133 xfree (FRAME_XIC_BASE_FONTNAME (f));
2134 FRAME_XIC_BASE_FONTNAME (f) = NULL;
2135 FRAME_XIC_FONTSET (f) = NULL;
2139 /* Value is the best input style, given user preferences USER (already
2140 checked to be supported by Emacs), and styles supported by the
2141 input method XIM. */
2143 static XIMStyle
2144 best_xim_style (XIMStyles *user, XIMStyles *xim)
2146 int i, j;
2148 for (i = 0; i < user->count_styles; ++i)
2149 for (j = 0; j < xim->count_styles; ++j)
2150 if (user->supported_styles[i] == xim->supported_styles[j])
2151 return user->supported_styles[i];
2153 /* Return the default style. */
2154 return XIMPreeditNothing | XIMStatusNothing;
2157 /* Create XIC for frame F. */
2159 static XIMStyle xic_style;
2161 void
2162 create_frame_xic (struct frame *f)
2164 XIM xim;
2165 XIC xic = NULL;
2166 XFontSet xfs = NULL;
2168 if (FRAME_XIC (f))
2169 return;
2171 /* Create X fontset. */
2172 xfs = xic_create_xfontset (f);
2173 xim = FRAME_X_XIM (f);
2174 if (xim)
2176 XRectangle s_area;
2177 XPoint spot;
2178 XVaNestedList preedit_attr;
2179 XVaNestedList status_attr;
2181 s_area.x = 0; s_area.y = 0; s_area.width = 1; s_area.height = 1;
2182 spot.x = 0; spot.y = 1;
2184 /* Determine XIC style. */
2185 if (xic_style == 0)
2187 XIMStyles supported_list;
2188 supported_list.count_styles = (sizeof supported_xim_styles
2189 / sizeof supported_xim_styles[0]);
2190 supported_list.supported_styles = supported_xim_styles;
2191 xic_style = best_xim_style (&supported_list,
2192 FRAME_X_XIM_STYLES (f));
2195 preedit_attr = XVaCreateNestedList (0,
2196 XNFontSet, xfs,
2197 XNForeground,
2198 FRAME_FOREGROUND_PIXEL (f),
2199 XNBackground,
2200 FRAME_BACKGROUND_PIXEL (f),
2201 (xic_style & XIMPreeditPosition
2202 ? XNSpotLocation
2203 : NULL),
2204 &spot,
2205 NULL);
2206 status_attr = XVaCreateNestedList (0,
2207 XNArea,
2208 &s_area,
2209 XNFontSet,
2210 xfs,
2211 XNForeground,
2212 FRAME_FOREGROUND_PIXEL (f),
2213 XNBackground,
2214 FRAME_BACKGROUND_PIXEL (f),
2215 NULL);
2217 xic = XCreateIC (xim,
2218 XNInputStyle, xic_style,
2219 XNClientWindow, FRAME_X_WINDOW (f),
2220 XNFocusWindow, FRAME_X_WINDOW (f),
2221 XNStatusAttributes, status_attr,
2222 XNPreeditAttributes, preedit_attr,
2223 NULL);
2224 XFree (preedit_attr);
2225 XFree (status_attr);
2228 FRAME_XIC (f) = xic;
2229 FRAME_XIC_STYLE (f) = xic_style;
2230 FRAME_XIC_FONTSET (f) = xfs;
2234 /* Destroy XIC and free XIC fontset of frame F, if any. */
2236 void
2237 free_frame_xic (struct frame *f)
2239 if (FRAME_XIC (f) == NULL)
2240 return;
2242 XDestroyIC (FRAME_XIC (f));
2243 xic_free_xfontset (f);
2245 FRAME_XIC (f) = NULL;
2249 /* Place preedit area for XIC of window W's frame to specified
2250 pixel position X/Y. X and Y are relative to window W. */
2252 void
2253 xic_set_preeditarea (struct window *w, int x, int y)
2255 struct frame *f = XFRAME (w->frame);
2256 XVaNestedList attr;
2257 XPoint spot;
2259 spot.x = WINDOW_TO_FRAME_PIXEL_X (w, x) + WINDOW_LEFT_FRINGE_WIDTH (w);
2260 spot.y = WINDOW_TO_FRAME_PIXEL_Y (w, y) + FONT_BASE (FRAME_FONT (f));
2261 attr = XVaCreateNestedList (0, XNSpotLocation, &spot, NULL);
2262 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2263 XFree (attr);
2267 /* Place status area for XIC in bottom right corner of frame F.. */
2269 void
2270 xic_set_statusarea (struct frame *f)
2272 XIC xic = FRAME_XIC (f);
2273 XVaNestedList attr;
2274 XRectangle area;
2275 XRectangle *needed;
2277 /* Negotiate geometry of status area. If input method has existing
2278 status area, use its current size. */
2279 area.x = area.y = area.width = area.height = 0;
2280 attr = XVaCreateNestedList (0, XNAreaNeeded, &area, NULL);
2281 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2282 XFree (attr);
2284 attr = XVaCreateNestedList (0, XNAreaNeeded, &needed, NULL);
2285 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2286 XFree (attr);
2288 if (needed->width == 0) /* Use XNArea instead of XNAreaNeeded */
2290 attr = XVaCreateNestedList (0, XNArea, &needed, NULL);
2291 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2292 XFree (attr);
2295 area.width = needed->width;
2296 area.height = needed->height;
2297 area.x = FRAME_PIXEL_WIDTH (f) - area.width - FRAME_INTERNAL_BORDER_WIDTH (f);
2298 area.y = (FRAME_PIXEL_HEIGHT (f) - area.height
2299 - FRAME_MENUBAR_HEIGHT (f)
2300 - FRAME_TOOLBAR_TOP_HEIGHT (f)
2301 - FRAME_INTERNAL_BORDER_WIDTH (f));
2302 XFree (needed);
2304 attr = XVaCreateNestedList (0, XNArea, &area, NULL);
2305 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2306 XFree (attr);
2310 /* Set X fontset for XIC of frame F, using base font name
2311 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2313 void
2314 xic_set_xfontset (struct frame *f, const char *base_fontname)
2316 XVaNestedList attr;
2317 XFontSet xfs;
2319 xic_free_xfontset (f);
2321 xfs = xic_create_xfontset (f);
2323 attr = XVaCreateNestedList (0, XNFontSet, xfs, NULL);
2324 if (FRAME_XIC_STYLE (f) & XIMPreeditPosition)
2325 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2326 if (FRAME_XIC_STYLE (f) & XIMStatusArea)
2327 XSetICValues (FRAME_XIC (f), XNStatusAttributes, attr, NULL);
2328 XFree (attr);
2330 FRAME_XIC_FONTSET (f) = xfs;
2333 #endif /* HAVE_X_I18N */
2337 #ifdef USE_X_TOOLKIT
2339 /* Create and set up the X widget for frame F. */
2341 static void
2342 x_window (struct frame *f, long window_prompting, int minibuffer_only)
2344 XClassHint class_hints;
2345 XSetWindowAttributes attributes;
2346 unsigned long attribute_mask;
2347 Widget shell_widget;
2348 Widget pane_widget;
2349 Widget frame_widget;
2350 Arg al [25];
2351 int ac;
2353 block_input ();
2355 /* Use the resource name as the top-level widget name
2356 for looking up resources. Make a non-Lisp copy
2357 for the window manager, so GC relocation won't bother it.
2359 Elsewhere we specify the window name for the window manager. */
2362 char *str = SSDATA (Vx_resource_name);
2363 f->namebuf = xmalloc (strlen (str) + 1);
2364 strcpy (f->namebuf, str);
2367 ac = 0;
2368 XtSetArg (al[ac], XtNallowShellResize, 1); ac++;
2369 XtSetArg (al[ac], XtNinput, 1); ac++;
2370 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2371 XtSetArg (al[ac], XtNborderWidth, f->border_width); ac++;
2372 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2373 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2374 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2375 shell_widget = XtAppCreateShell (f->namebuf, EMACS_CLASS,
2376 applicationShellWidgetClass,
2377 FRAME_X_DISPLAY (f), al, ac);
2379 f->output_data.x->widget = shell_widget;
2380 /* maybe_set_screen_title_format (shell_widget); */
2382 pane_widget = lw_create_widget ("main", "pane", widget_id_tick++,
2383 (widget_value *) NULL,
2384 shell_widget, False,
2385 (lw_callback) NULL,
2386 (lw_callback) NULL,
2387 (lw_callback) NULL,
2388 (lw_callback) NULL);
2390 ac = 0;
2391 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2392 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2393 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2394 XtSetArg (al[ac], XtNborderWidth, 0); ac++;
2395 XtSetValues (pane_widget, al, ac);
2396 f->output_data.x->column_widget = pane_widget;
2398 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2399 the emacs screen when changing menubar. This reduces flickering. */
2401 ac = 0;
2402 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2403 XtSetArg (al[ac], XtNshowGrip, 0); ac++;
2404 XtSetArg (al[ac], XtNallowResize, 1); ac++;
2405 XtSetArg (al[ac], XtNresizeToPreferred, 1); ac++;
2406 XtSetArg (al[ac], XtNemacsFrame, f); ac++;
2407 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2408 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2409 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2410 XtSetArg (al[ac], XtNborderWidth, 0); ac++;
2411 frame_widget = XtCreateWidget (f->namebuf, emacsFrameClass, pane_widget,
2412 al, ac);
2414 f->output_data.x->edit_widget = frame_widget;
2416 XtManageChild (frame_widget);
2418 /* Do some needed geometry management. */
2420 char *tem, shell_position[sizeof "=x++" + 4 * INT_STRLEN_BOUND (int)];
2421 Arg gal[10];
2422 int gac = 0;
2423 int extra_borders = 0;
2424 int menubar_size
2425 = (f->output_data.x->menubar_widget
2426 ? (f->output_data.x->menubar_widget->core.height
2427 + f->output_data.x->menubar_widget->core.border_width)
2428 : 0);
2430 #if 0 /* Experimentally, we now get the right results
2431 for -geometry -0-0 without this. 24 Aug 96, rms. */
2432 if (FRAME_EXTERNAL_MENU_BAR (f))
2434 Dimension ibw = 0;
2435 XtVaGetValues (pane_widget, XtNinternalBorderWidth, &ibw, NULL);
2436 menubar_size += ibw;
2438 #endif
2440 f->output_data.x->menubar_height = menubar_size;
2442 #ifndef USE_LUCID
2443 /* Motif seems to need this amount added to the sizes
2444 specified for the shell widget. The Athena/Lucid widgets don't.
2445 Both conclusions reached experimentally. -- rms. */
2446 XtVaGetValues (f->output_data.x->edit_widget, XtNinternalBorderWidth,
2447 &extra_borders, NULL);
2448 extra_borders *= 2;
2449 #endif
2451 /* Convert our geometry parameters into a geometry string
2452 and specify it.
2453 Note that we do not specify here whether the position
2454 is a user-specified or program-specified one.
2455 We pass that information later, in x_wm_set_size_hints. */
2457 int left = f->left_pos;
2458 int xneg = window_prompting & XNegative;
2459 int top = f->top_pos;
2460 int yneg = window_prompting & YNegative;
2461 if (xneg)
2462 left = -left;
2463 if (yneg)
2464 top = -top;
2466 if (window_prompting & USPosition)
2467 sprintf (shell_position, "=%dx%d%c%d%c%d",
2468 FRAME_PIXEL_WIDTH (f) + extra_borders,
2469 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders,
2470 (xneg ? '-' : '+'), left,
2471 (yneg ? '-' : '+'), top);
2472 else
2474 sprintf (shell_position, "=%dx%d",
2475 FRAME_PIXEL_WIDTH (f) + extra_borders,
2476 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders);
2478 /* Setting x and y when the position is not specified in
2479 the geometry string will set program position in the WM hints.
2480 If Emacs had just one program position, we could set it in
2481 fallback resources, but since each make-frame call can specify
2482 different program positions, this is easier. */
2483 XtSetArg (gal[gac], XtNx, left); gac++;
2484 XtSetArg (gal[gac], XtNy, top); gac++;
2488 /* We don't free this because we don't know whether
2489 it is safe to free it while the frame exists.
2490 It isn't worth the trouble of arranging to free it
2491 when the frame is deleted. */
2492 tem = xstrdup (shell_position);
2493 XtSetArg (gal[gac], XtNgeometry, tem); gac++;
2494 XtSetValues (shell_widget, gal, gac);
2497 XtManageChild (pane_widget);
2498 XtRealizeWidget (shell_widget);
2500 if (FRAME_X_EMBEDDED_P (f))
2501 XReparentWindow (FRAME_X_DISPLAY (f), XtWindow (shell_widget),
2502 f->output_data.x->parent_desc, 0, 0);
2504 FRAME_X_WINDOW (f) = XtWindow (frame_widget);
2506 validate_x_resource_name ();
2508 class_hints.res_name = SSDATA (Vx_resource_name);
2509 class_hints.res_class = SSDATA (Vx_resource_class);
2510 XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints);
2512 #ifdef HAVE_X_I18N
2513 FRAME_XIC (f) = NULL;
2514 if (use_xim)
2515 create_frame_xic (f);
2516 #endif
2518 f->output_data.x->wm_hints.input = True;
2519 f->output_data.x->wm_hints.flags |= InputHint;
2520 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2521 &f->output_data.x->wm_hints);
2523 hack_wm_protocols (f, shell_widget);
2525 #ifdef HACK_EDITRES
2526 XtAddEventHandler (shell_widget, 0, True, _XEditResCheckMessages, 0);
2527 #endif
2529 /* Do a stupid property change to force the server to generate a
2530 PropertyNotify event so that the event_stream server timestamp will
2531 be initialized to something relevant to the time we created the window.
2533 XChangeProperty (XtDisplay (frame_widget), XtWindow (frame_widget),
2534 FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
2535 XA_ATOM, 32, PropModeAppend,
2536 (unsigned char*) NULL, 0);
2538 /* Make all the standard events reach the Emacs frame. */
2539 attributes.event_mask = STANDARD_EVENT_SET;
2541 #ifdef HAVE_X_I18N
2542 if (FRAME_XIC (f))
2544 /* XIM server might require some X events. */
2545 unsigned long fevent = NoEventMask;
2546 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2547 attributes.event_mask |= fevent;
2549 #endif /* HAVE_X_I18N */
2551 attribute_mask = CWEventMask;
2552 XChangeWindowAttributes (XtDisplay (shell_widget), XtWindow (shell_widget),
2553 attribute_mask, &attributes);
2555 XtMapWidget (frame_widget);
2557 /* x_set_name normally ignores requests to set the name if the
2558 requested name is the same as the current name. This is the one
2559 place where that assumption isn't correct; f->name is set, but
2560 the X server hasn't been told. */
2562 Lisp_Object name;
2563 int explicit = f->explicit_name;
2565 f->explicit_name = 0;
2566 name = f->name;
2567 fset_name (f, Qnil);
2568 x_set_name (f, name, explicit);
2571 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2572 f->output_data.x->current_cursor
2573 = f->output_data.x->text_cursor);
2575 unblock_input ();
2577 /* This is a no-op, except under Motif. Make sure main areas are
2578 set to something reasonable, in case we get an error later. */
2579 lw_set_main_areas (pane_widget, 0, frame_widget);
2582 #else /* not USE_X_TOOLKIT */
2583 #ifdef USE_GTK
2584 static void
2585 x_window (FRAME_PTR f)
2587 if (! xg_create_frame_widgets (f))
2588 error ("Unable to create window");
2590 #ifdef HAVE_X_I18N
2591 FRAME_XIC (f) = NULL;
2592 if (use_xim)
2594 block_input ();
2595 create_frame_xic (f);
2596 if (FRAME_XIC (f))
2598 /* XIM server might require some X events. */
2599 unsigned long fevent = NoEventMask;
2600 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2602 if (fevent != NoEventMask)
2604 XSetWindowAttributes attributes;
2605 XWindowAttributes wattr;
2606 unsigned long attribute_mask;
2608 XGetWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2609 &wattr);
2610 attributes.event_mask = wattr.your_event_mask | fevent;
2611 attribute_mask = CWEventMask;
2612 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2613 attribute_mask, &attributes);
2616 unblock_input ();
2618 #endif
2621 #else /*! USE_GTK */
2622 /* Create and set up the X window for frame F. */
2624 static void
2625 x_window (struct frame *f)
2627 XClassHint class_hints;
2628 XSetWindowAttributes attributes;
2629 unsigned long attribute_mask;
2631 attributes.background_pixel = FRAME_BACKGROUND_PIXEL (f);
2632 attributes.border_pixel = f->output_data.x->border_pixel;
2633 attributes.bit_gravity = StaticGravity;
2634 attributes.backing_store = NotUseful;
2635 attributes.save_under = True;
2636 attributes.event_mask = STANDARD_EVENT_SET;
2637 attributes.colormap = FRAME_X_COLORMAP (f);
2638 attribute_mask = (CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask
2639 | CWColormap);
2641 block_input ();
2642 FRAME_X_WINDOW (f)
2643 = XCreateWindow (FRAME_X_DISPLAY (f),
2644 f->output_data.x->parent_desc,
2645 f->left_pos,
2646 f->top_pos,
2647 FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
2648 f->border_width,
2649 CopyFromParent, /* depth */
2650 InputOutput, /* class */
2651 FRAME_X_VISUAL (f),
2652 attribute_mask, &attributes);
2654 #ifdef HAVE_X_I18N
2655 if (use_xim)
2657 create_frame_xic (f);
2658 if (FRAME_XIC (f))
2660 /* XIM server might require some X events. */
2661 unsigned long fevent = NoEventMask;
2662 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2663 attributes.event_mask |= fevent;
2664 attribute_mask = CWEventMask;
2665 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2666 attribute_mask, &attributes);
2669 #endif /* HAVE_X_I18N */
2671 validate_x_resource_name ();
2673 class_hints.res_name = SSDATA (Vx_resource_name);
2674 class_hints.res_class = SSDATA (Vx_resource_class);
2675 XSetClassHint (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &class_hints);
2677 /* The menubar is part of the ordinary display;
2678 it does not count in addition to the height of the window. */
2679 f->output_data.x->menubar_height = 0;
2681 /* This indicates that we use the "Passive Input" input model.
2682 Unless we do this, we don't get the Focus{In,Out} events that we
2683 need to draw the cursor correctly. Accursed bureaucrats.
2684 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2686 f->output_data.x->wm_hints.input = True;
2687 f->output_data.x->wm_hints.flags |= InputHint;
2688 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2689 &f->output_data.x->wm_hints);
2690 f->output_data.x->wm_hints.icon_pixmap = None;
2692 /* Request "save yourself" and "delete window" commands from wm. */
2694 Atom protocols[2];
2695 protocols[0] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window;
2696 protocols[1] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
2697 XSetWMProtocols (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), protocols, 2);
2700 /* x_set_name normally ignores requests to set the name if the
2701 requested name is the same as the current name. This is the one
2702 place where that assumption isn't correct; f->name is set, but
2703 the X server hasn't been told. */
2705 Lisp_Object name;
2706 int explicit = f->explicit_name;
2708 f->explicit_name = 0;
2709 name = f->name;
2710 fset_name (f, Qnil);
2711 x_set_name (f, name, explicit);
2714 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2715 f->output_data.x->current_cursor
2716 = f->output_data.x->text_cursor);
2718 unblock_input ();
2720 if (FRAME_X_WINDOW (f) == 0)
2721 error ("Unable to create window");
2724 #endif /* not USE_GTK */
2725 #endif /* not USE_X_TOOLKIT */
2727 /* Verify that the icon position args for this window are valid. */
2729 static void
2730 x_icon_verify (struct frame *f, Lisp_Object parms)
2732 Lisp_Object icon_x, icon_y;
2734 /* Set the position of the icon. Note that twm groups all
2735 icons in an icon window. */
2736 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2737 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2738 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2740 CHECK_NUMBER (icon_x);
2741 CHECK_NUMBER (icon_y);
2743 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2744 error ("Both left and top icon corners of icon must be specified");
2747 /* Handle the icon stuff for this window. Perhaps later we might
2748 want an x_set_icon_position which can be called interactively as
2749 well. */
2751 static void
2752 x_icon (struct frame *f, Lisp_Object parms)
2754 Lisp_Object icon_x, icon_y;
2755 #if 0
2756 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2757 #endif
2759 /* Set the position of the icon. Note that twm groups all
2760 icons in an icon window. */
2761 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2762 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2763 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2765 CHECK_TYPE_RANGED_INTEGER (int, icon_x);
2766 CHECK_TYPE_RANGED_INTEGER (int, icon_y);
2768 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2769 error ("Both left and top icon corners of icon must be specified");
2771 block_input ();
2773 if (! EQ (icon_x, Qunbound))
2774 x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
2776 #if 0 /* x_get_arg removes the visibility parameter as a side effect,
2777 but x_create_frame still needs it. */
2778 /* Start up iconic or window? */
2779 x_wm_set_window_state
2780 (f, (EQ (x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL),
2781 Qicon)
2782 ? IconicState
2783 : NormalState));
2784 #endif
2786 x_text_icon (f, SSDATA ((!NILP (f->icon_name)
2787 ? f->icon_name
2788 : f->name)));
2790 unblock_input ();
2793 /* Make the GCs needed for this window, setting the
2794 background, border and mouse colors; also create the
2795 mouse cursor and the gray border tile. */
2797 static void
2798 x_make_gc (struct frame *f)
2800 XGCValues gc_values;
2802 block_input ();
2804 /* Create the GCs of this frame.
2805 Note that many default values are used. */
2807 gc_values.foreground = FRAME_FOREGROUND_PIXEL (f);
2808 gc_values.background = FRAME_BACKGROUND_PIXEL (f);
2809 gc_values.line_width = 0; /* Means 1 using fast algorithm. */
2810 f->output_data.x->normal_gc
2811 = XCreateGC (FRAME_X_DISPLAY (f),
2812 FRAME_X_WINDOW (f),
2813 GCLineWidth | GCForeground | GCBackground,
2814 &gc_values);
2816 /* Reverse video style. */
2817 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2818 gc_values.background = FRAME_FOREGROUND_PIXEL (f);
2819 f->output_data.x->reverse_gc
2820 = XCreateGC (FRAME_X_DISPLAY (f),
2821 FRAME_X_WINDOW (f),
2822 GCForeground | GCBackground | GCLineWidth,
2823 &gc_values);
2825 /* Cursor has cursor-color background, background-color foreground. */
2826 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2827 gc_values.background = f->output_data.x->cursor_pixel;
2828 gc_values.fill_style = FillOpaqueStippled;
2829 f->output_data.x->cursor_gc
2830 = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2831 (GCForeground | GCBackground
2832 | GCFillStyle | GCLineWidth),
2833 &gc_values);
2835 /* Reliefs. */
2836 f->output_data.x->white_relief.gc = 0;
2837 f->output_data.x->black_relief.gc = 0;
2839 /* Create the gray border tile used when the pointer is not in
2840 the frame. Since this depends on the frame's pixel values,
2841 this must be done on a per-frame basis. */
2842 f->output_data.x->border_tile
2843 = (XCreatePixmapFromBitmapData
2844 (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
2845 gray_bits, gray_width, gray_height,
2846 FRAME_FOREGROUND_PIXEL (f),
2847 FRAME_BACKGROUND_PIXEL (f),
2848 DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
2850 unblock_input ();
2854 /* Free what was allocated in x_make_gc. */
2856 void
2857 x_free_gcs (struct frame *f)
2859 Display *dpy = FRAME_X_DISPLAY (f);
2861 block_input ();
2863 if (f->output_data.x->normal_gc)
2865 XFreeGC (dpy, f->output_data.x->normal_gc);
2866 f->output_data.x->normal_gc = 0;
2869 if (f->output_data.x->reverse_gc)
2871 XFreeGC (dpy, f->output_data.x->reverse_gc);
2872 f->output_data.x->reverse_gc = 0;
2875 if (f->output_data.x->cursor_gc)
2877 XFreeGC (dpy, f->output_data.x->cursor_gc);
2878 f->output_data.x->cursor_gc = 0;
2881 if (f->output_data.x->border_tile)
2883 XFreePixmap (dpy, f->output_data.x->border_tile);
2884 f->output_data.x->border_tile = 0;
2887 unblock_input ();
2891 /* Handler for signals raised during x_create_frame and
2892 x_create_tip_frame. FRAME is the frame which is partially
2893 constructed. */
2895 static Lisp_Object
2896 unwind_create_frame (Lisp_Object frame)
2898 struct frame *f = XFRAME (frame);
2900 /* If frame is already dead, nothing to do. This can happen if the
2901 display is disconnected after the frame has become official, but
2902 before x_create_frame removes the unwind protect. */
2903 if (!FRAME_LIVE_P (f))
2904 return Qnil;
2906 /* If frame is ``official'', nothing to do. */
2907 if (NILP (Fmemq (frame, Vframe_list)))
2909 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2910 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2911 #endif
2913 x_free_frame_resources (f);
2914 free_glyphs (f);
2916 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2917 /* Check that reference counts are indeed correct. */
2918 eassert (dpyinfo->reference_count == dpyinfo_refcount);
2919 eassert (dpyinfo->terminal->image_cache->refcount == image_cache_refcount);
2920 #endif
2921 return Qt;
2924 return Qnil;
2927 static Lisp_Object
2928 unwind_create_frame_1 (Lisp_Object val)
2930 inhibit_lisp_code = val;
2931 return Qnil;
2934 static void
2935 x_default_font_parameter (struct frame *f, Lisp_Object parms)
2937 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2938 Lisp_Object font_param = x_get_arg (dpyinfo, parms, Qfont, NULL, NULL,
2939 RES_TYPE_STRING);
2940 Lisp_Object font = Qnil;
2941 if (EQ (font_param, Qunbound))
2942 font_param = Qnil;
2944 if (NILP (font_param))
2946 /* System font should take precedence over X resources. We suggest this
2947 regardless of font-use-system-font because .emacs may not have been
2948 read yet. */
2949 const char *system_font = xsettings_get_system_font ();
2950 if (system_font)
2951 font = font_open_by_name (f, build_unibyte_string (system_font));
2954 if (NILP (font))
2955 font = !NILP (font_param) ? font_param
2956 : x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
2958 if (! FONTP (font) && ! STRINGP (font))
2960 const char *names[]
2962 #ifdef HAVE_XFT
2963 /* This will find the normal Xft font. */
2964 "monospace-10",
2965 #endif
2966 "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
2967 "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
2968 "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
2969 /* This was formerly the first thing tried, but it finds
2970 too many fonts and takes too long. */
2971 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
2972 /* If those didn't work, look for something which will
2973 at least work. */
2974 "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
2975 "fixed",
2976 NULL };
2977 int i;
2979 for (i = 0; names[i]; i++)
2981 font = font_open_by_name (f, build_unibyte_string (names[i]));
2982 if (! NILP (font))
2983 break;
2985 if (NILP (font))
2986 error ("No suitable font was found");
2988 else if (!NILP (font_param))
2990 /* Remember the explicit font parameter, so we can re-apply it after
2991 we've applied the `default' face settings. */
2992 x_set_frame_parameters (f, Fcons (Fcons (Qfont_param, font_param), Qnil));
2995 /* This call will make X resources override any system font setting. */
2996 x_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING);
3000 DEFUN ("x-wm-set-size-hint", Fx_wm_set_size_hint, Sx_wm_set_size_hint,
3001 0, 1, 0,
3002 doc: /* Send the size hints for frame FRAME to the window manager.
3003 If FRAME is nil, use the selected frame. */)
3004 (Lisp_Object frame)
3006 struct frame *f;
3007 if (NILP (frame))
3008 frame = selected_frame;
3009 f = XFRAME (frame);
3010 block_input ();
3011 if (FRAME_X_P (f))
3012 x_wm_set_size_hint (f, 0, 0);
3013 unblock_input ();
3014 return Qnil;
3017 static void
3018 set_machine_and_pid_properties (struct frame *f)
3020 long pid = (long) getpid ();
3022 /* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME. */
3023 XSetWMProperties (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), NULL, NULL,
3024 NULL, 0, NULL, NULL, NULL);
3025 XChangeProperty (FRAME_X_DISPLAY (f),
3026 FRAME_OUTER_WINDOW (f),
3027 XInternAtom (FRAME_X_DISPLAY (f),
3028 "_NET_WM_PID",
3029 False),
3030 XA_CARDINAL, 32, PropModeReplace,
3031 (unsigned char *) &pid, 1);
3034 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
3035 1, 1, 0,
3036 doc: /* Make a new X window, which is called a "frame" in Emacs terms.
3037 Return an Emacs frame object.
3038 PARMS is an alist of frame parameters.
3039 If the parameters specify that the frame should not have a minibuffer,
3040 and do not specify a specific minibuffer window to use,
3041 then `default-minibuffer-frame' must be a frame whose minibuffer can
3042 be shared by the new frame.
3044 This function is an internal primitive--use `make-frame' instead. */)
3045 (Lisp_Object parms)
3047 struct frame *f;
3048 Lisp_Object frame, tem;
3049 Lisp_Object name;
3050 int minibuffer_only = 0;
3051 long window_prompting = 0;
3052 int width, height;
3053 ptrdiff_t count = SPECPDL_INDEX ();
3054 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
3055 Lisp_Object display;
3056 struct x_display_info *dpyinfo = NULL;
3057 Lisp_Object parent;
3058 struct kboard *kb;
3060 parms = Fcopy_alist (parms);
3062 /* Use this general default value to start with
3063 until we know if this frame has a specified name. */
3064 Vx_resource_name = Vinvocation_name;
3066 display = x_get_arg (dpyinfo, parms, Qterminal, 0, 0, RES_TYPE_NUMBER);
3067 if (EQ (display, Qunbound))
3068 display = x_get_arg (dpyinfo, parms, Qdisplay, 0, 0, RES_TYPE_STRING);
3069 if (EQ (display, Qunbound))
3070 display = Qnil;
3071 dpyinfo = check_x_display_info (display);
3072 kb = dpyinfo->terminal->kboard;
3074 if (!dpyinfo->terminal->name)
3075 error ("Terminal is not live, can't create new frames on it");
3077 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
3078 if (!STRINGP (name)
3079 && ! EQ (name, Qunbound)
3080 && ! NILP (name))
3081 error ("Invalid frame name--not a string or nil");
3083 if (STRINGP (name))
3084 Vx_resource_name = name;
3086 /* See if parent window is specified. */
3087 parent = x_get_arg (dpyinfo, parms, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
3088 if (EQ (parent, Qunbound))
3089 parent = Qnil;
3090 if (! NILP (parent))
3091 CHECK_NUMBER (parent);
3093 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
3094 /* No need to protect DISPLAY because that's not used after passing
3095 it to make_frame_without_minibuffer. */
3096 frame = Qnil;
3097 GCPRO4 (parms, parent, name, frame);
3098 tem = x_get_arg (dpyinfo, parms, Qminibuffer, "minibuffer", "Minibuffer",
3099 RES_TYPE_SYMBOL);
3100 if (EQ (tem, Qnone) || NILP (tem))
3101 f = make_frame_without_minibuffer (Qnil, kb, display);
3102 else if (EQ (tem, Qonly))
3104 f = make_minibuffer_frame ();
3105 minibuffer_only = 1;
3107 else if (WINDOWP (tem))
3108 f = make_frame_without_minibuffer (tem, kb, display);
3109 else
3110 f = make_frame (1);
3112 XSETFRAME (frame, f);
3114 /* Note that X Windows does support scroll bars. */
3115 FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
3117 f->terminal = dpyinfo->terminal;
3119 f->output_method = output_x_window;
3120 f->output_data.x = xzalloc (sizeof *f->output_data.x);
3121 f->output_data.x->icon_bitmap = -1;
3122 FRAME_FONTSET (f) = -1;
3123 f->output_data.x->scroll_bar_foreground_pixel = -1;
3124 f->output_data.x->scroll_bar_background_pixel = -1;
3125 #ifdef USE_TOOLKIT_SCROLL_BARS
3126 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
3127 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
3128 #endif /* USE_TOOLKIT_SCROLL_BARS */
3130 fset_icon_name (f,
3131 x_get_arg (dpyinfo, parms, Qicon_name, "iconName", "Title",
3132 RES_TYPE_STRING));
3133 if (! STRINGP (f->icon_name))
3134 fset_icon_name (f, Qnil);
3136 FRAME_X_DISPLAY_INFO (f) = dpyinfo;
3138 /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe. */
3139 record_unwind_protect (unwind_create_frame, frame);
3141 /* These colors will be set anyway later, but it's important
3142 to get the color reference counts right, so initialize them! */
3144 Lisp_Object black;
3145 struct gcpro gcpro1;
3147 /* Function x_decode_color can signal an error. Make
3148 sure to initialize color slots so that we won't try
3149 to free colors we haven't allocated. */
3150 FRAME_FOREGROUND_PIXEL (f) = -1;
3151 FRAME_BACKGROUND_PIXEL (f) = -1;
3152 f->output_data.x->cursor_pixel = -1;
3153 f->output_data.x->cursor_foreground_pixel = -1;
3154 f->output_data.x->border_pixel = -1;
3155 f->output_data.x->mouse_pixel = -1;
3157 black = build_string ("black");
3158 GCPRO1 (black);
3159 FRAME_FOREGROUND_PIXEL (f)
3160 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3161 FRAME_BACKGROUND_PIXEL (f)
3162 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3163 f->output_data.x->cursor_pixel
3164 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3165 f->output_data.x->cursor_foreground_pixel
3166 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3167 f->output_data.x->border_pixel
3168 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3169 f->output_data.x->mouse_pixel
3170 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3171 UNGCPRO;
3174 /* Specify the parent under which to make this X window. */
3176 if (!NILP (parent))
3178 f->output_data.x->parent_desc = (Window) XFASTINT (parent);
3179 f->output_data.x->explicit_parent = 1;
3181 else
3183 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
3184 f->output_data.x->explicit_parent = 0;
3187 /* Set the name; the functions to which we pass f expect the name to
3188 be set. */
3189 if (EQ (name, Qunbound) || NILP (name))
3191 fset_name (f, build_string (dpyinfo->x_id_name));
3192 f->explicit_name = 0;
3194 else
3196 fset_name (f, name);
3197 f->explicit_name = 1;
3198 /* use the frame's title when getting resources for this frame. */
3199 specbind (Qx_resource_name, name);
3202 f->resx = dpyinfo->resx;
3203 f->resy = dpyinfo->resy;
3205 #ifdef HAVE_FREETYPE
3206 #ifdef HAVE_XFT
3207 register_font_driver (&xftfont_driver, f);
3208 #else /* not HAVE_XFT */
3209 register_font_driver (&ftxfont_driver, f);
3210 #endif /* not HAVE_XFT */
3211 #endif /* HAVE_FREETYPE */
3212 register_font_driver (&xfont_driver, f);
3214 x_default_parameter (f, parms, Qfont_backend, Qnil,
3215 "fontBackend", "FontBackend", RES_TYPE_STRING);
3217 /* Extract the window parameters from the supplied values
3218 that are needed to determine window geometry. */
3219 x_default_font_parameter (f, parms);
3220 if (!FRAME_FONT (f))
3222 delete_frame (frame, Qnoelisp);
3223 error ("Invalid frame font");
3226 /* Frame contents get displaced if an embedded X window has a border. */
3227 if (! FRAME_X_EMBEDDED_P (f))
3228 x_default_parameter (f, parms, Qborder_width, make_number (0),
3229 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
3231 /* This defaults to 1 in order to match xterm. We recognize either
3232 internalBorderWidth or internalBorder (which is what xterm calls
3233 it). */
3234 if (NILP (Fassq (Qinternal_border_width, parms)))
3236 Lisp_Object value;
3238 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
3239 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
3240 if (! EQ (value, Qunbound))
3241 parms = Fcons (Fcons (Qinternal_border_width, value),
3242 parms);
3244 x_default_parameter (f, parms, Qinternal_border_width,
3245 #ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */
3246 make_number (0),
3247 #else
3248 make_number (1),
3249 #endif
3250 "internalBorderWidth", "internalBorderWidth",
3251 RES_TYPE_NUMBER);
3252 x_default_parameter (f, parms, Qvertical_scroll_bars,
3253 #if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
3254 Qright,
3255 #else
3256 Qleft,
3257 #endif
3258 "verticalScrollBars", "ScrollBars",
3259 RES_TYPE_SYMBOL);
3261 /* Also do the stuff which must be set before the window exists. */
3262 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
3263 "foreground", "Foreground", RES_TYPE_STRING);
3264 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
3265 "background", "Background", RES_TYPE_STRING);
3266 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
3267 "pointerColor", "Foreground", RES_TYPE_STRING);
3268 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
3269 "borderColor", "BorderColor", RES_TYPE_STRING);
3270 x_default_parameter (f, parms, Qscreen_gamma, Qnil,
3271 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
3272 x_default_parameter (f, parms, Qline_spacing, Qnil,
3273 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
3274 x_default_parameter (f, parms, Qleft_fringe, Qnil,
3275 "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
3276 x_default_parameter (f, parms, Qright_fringe, Qnil,
3277 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
3279 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_foreground,
3280 "scrollBarForeground",
3281 "ScrollBarForeground", 1);
3282 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_background,
3283 "scrollBarBackground",
3284 "ScrollBarBackground", 0);
3286 #ifdef GLYPH_DEBUG
3287 image_cache_refcount =
3288 FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
3289 dpyinfo_refcount = dpyinfo->reference_count;
3290 #endif /* GLYPH_DEBUG */
3292 /* Init faces before x_default_parameter is called for scroll-bar
3293 parameters because that function calls x_set_scroll_bar_width,
3294 which calls change_frame_size, which calls Fset_window_buffer,
3295 which runs hooks, which call Fvertical_motion. At the end, we
3296 end up in init_iterator with a null face cache, which should not
3297 happen. */
3298 init_frame_faces (f);
3300 /* Set the menu-bar-lines and tool-bar-lines parameters. We don't
3301 look up the X resources controlling the menu-bar and tool-bar
3302 here; they are processed specially at startup, and reflected in
3303 the values of the mode variables.
3305 Avoid calling window-configuration-change-hook; otherwise we
3306 could get an infloop in next_frame since the frame is not yet in
3307 Vframe_list. */
3309 ptrdiff_t count2 = SPECPDL_INDEX ();
3310 record_unwind_protect (unwind_create_frame_1, inhibit_lisp_code);
3311 inhibit_lisp_code = Qt;
3313 x_default_parameter (f, parms, Qmenu_bar_lines,
3314 NILP (Vmenu_bar_mode)
3315 ? make_number (0) : make_number (1),
3316 NULL, NULL, RES_TYPE_NUMBER);
3317 x_default_parameter (f, parms, Qtool_bar_lines,
3318 NILP (Vtool_bar_mode)
3319 ? make_number (0) : make_number (1),
3320 NULL, NULL, RES_TYPE_NUMBER);
3322 unbind_to (count2, Qnil);
3325 x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
3326 "bufferPredicate", "BufferPredicate",
3327 RES_TYPE_SYMBOL);
3328 x_default_parameter (f, parms, Qtitle, Qnil,
3329 "title", "Title", RES_TYPE_STRING);
3330 x_default_parameter (f, parms, Qwait_for_wm, Qt,
3331 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
3332 x_default_parameter (f, parms, Qfullscreen, Qnil,
3333 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
3334 x_default_parameter (f, parms, Qtool_bar_position,
3335 f->tool_bar_position, 0, 0, RES_TYPE_SYMBOL);
3337 /* Compute the size of the X window. */
3338 window_prompting = x_figure_window_size (f, parms, 1);
3340 tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
3341 f->no_split = minibuffer_only || EQ (tem, Qt);
3343 x_icon_verify (f, parms);
3345 /* Create the X widget or window. */
3346 #ifdef USE_X_TOOLKIT
3347 x_window (f, window_prompting, minibuffer_only);
3348 #else
3349 x_window (f);
3350 #endif
3352 x_icon (f, parms);
3353 x_make_gc (f);
3355 /* Now consider the frame official. */
3356 f->terminal->reference_count++;
3357 FRAME_X_DISPLAY_INFO (f)->reference_count++;
3358 Vframe_list = Fcons (frame, Vframe_list);
3360 /* We need to do this after creating the X window, so that the
3361 icon-creation functions can say whose icon they're describing. */
3362 x_default_parameter (f, parms, Qicon_type, Qt,
3363 "bitmapIcon", "BitmapIcon", RES_TYPE_BOOLEAN);
3365 x_default_parameter (f, parms, Qauto_raise, Qnil,
3366 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3367 x_default_parameter (f, parms, Qauto_lower, Qnil,
3368 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3369 x_default_parameter (f, parms, Qcursor_type, Qbox,
3370 "cursorType", "CursorType", RES_TYPE_SYMBOL);
3371 x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
3372 "scrollBarWidth", "ScrollBarWidth",
3373 RES_TYPE_NUMBER);
3374 x_default_parameter (f, parms, Qalpha, Qnil,
3375 "alpha", "Alpha", RES_TYPE_NUMBER);
3377 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3378 Change will not be effected unless different from the current
3379 FRAME_LINES (f). */
3380 width = FRAME_COLS (f);
3381 height = FRAME_LINES (f);
3383 SET_FRAME_COLS (f, 0);
3384 FRAME_LINES (f) = 0;
3385 change_frame_size (f, height, width, 1, 0, 0);
3387 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3388 /* Create the menu bar. */
3389 if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
3391 /* If this signals an error, we haven't set size hints for the
3392 frame and we didn't make it visible. */
3393 initialize_frame_menubar (f);
3395 #ifndef USE_GTK
3396 /* This is a no-op, except under Motif where it arranges the
3397 main window for the widgets on it. */
3398 lw_set_main_areas (f->output_data.x->column_widget,
3399 f->output_data.x->menubar_widget,
3400 f->output_data.x->edit_widget);
3401 #endif /* not USE_GTK */
3403 #endif /* USE_X_TOOLKIT || USE_GTK */
3405 /* Tell the server what size and position, etc, we want, and how
3406 badly we want them. This should be done after we have the menu
3407 bar so that its size can be taken into account. */
3408 block_input ();
3409 x_wm_set_size_hint (f, window_prompting, 0);
3410 unblock_input ();
3412 /* Make the window appear on the frame and enable display, unless
3413 the caller says not to. However, with explicit parent, Emacs
3414 cannot control visibility, so don't try. */
3415 if (! f->output_data.x->explicit_parent)
3417 Lisp_Object visibility;
3419 visibility = x_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
3420 RES_TYPE_SYMBOL);
3421 if (EQ (visibility, Qunbound))
3422 visibility = Qt;
3424 if (EQ (visibility, Qicon))
3425 x_iconify_frame (f);
3426 else if (! NILP (visibility))
3427 x_make_frame_visible (f);
3428 else
3430 /* Must have been Qnil. */
3434 block_input ();
3436 /* Set machine name and pid for the purpose of window managers. */
3437 set_machine_and_pid_properties (f);
3439 /* Set the WM leader property. GTK does this itself, so this is not
3440 needed when using GTK. */
3441 if (dpyinfo->client_leader_window != 0)
3443 XChangeProperty (FRAME_X_DISPLAY (f),
3444 FRAME_OUTER_WINDOW (f),
3445 dpyinfo->Xatom_wm_client_leader,
3446 XA_WINDOW, 32, PropModeReplace,
3447 (unsigned char *) &dpyinfo->client_leader_window, 1);
3450 unblock_input ();
3452 /* Initialize `default-minibuffer-frame' in case this is the first
3453 frame on this terminal. */
3454 if (FRAME_HAS_MINIBUF_P (f)
3455 && (!FRAMEP (KVAR (kb, Vdefault_minibuffer_frame))
3456 || !FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame)))))
3457 kset_default_minibuffer_frame (kb, frame);
3459 /* All remaining specified parameters, which have not been "used"
3460 by x_get_arg and friends, now go in the misc. alist of the frame. */
3461 for (tem = parms; CONSP (tem); tem = XCDR (tem))
3462 if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
3463 fset_param_alist (f, Fcons (XCAR (tem), f->param_alist));
3465 UNGCPRO;
3467 /* Make sure windows on this frame appear in calls to next-window
3468 and similar functions. */
3469 Vwindow_list = Qnil;
3471 return unbind_to (count, frame);
3475 /* FRAME is used only to get a handle on the X display. We don't pass the
3476 display info directly because we're called from frame.c, which doesn't
3477 know about that structure. */
3479 Lisp_Object
3480 x_get_focus_frame (struct frame *frame)
3482 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (frame);
3483 Lisp_Object xfocus;
3484 if (! dpyinfo->x_focus_frame)
3485 return Qnil;
3487 XSETFRAME (xfocus, dpyinfo->x_focus_frame);
3488 return xfocus;
3492 /* In certain situations, when the window manager follows a
3493 click-to-focus policy, there seems to be no way around calling
3494 XSetInputFocus to give another frame the input focus .
3496 In an ideal world, XSetInputFocus should generally be avoided so
3497 that applications don't interfere with the window manager's focus
3498 policy. But I think it's okay to use when it's clearly done
3499 following a user-command. */
3501 DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
3502 doc: /* Set the input focus to FRAME.
3503 FRAME nil means use the selected frame. */)
3504 (Lisp_Object frame)
3506 struct frame *f = check_x_frame (frame);
3507 Display *dpy = FRAME_X_DISPLAY (f);
3509 block_input ();
3510 x_catch_errors (dpy);
3512 if (FRAME_X_EMBEDDED_P (f))
3514 /* For Xembedded frames, normally the embedder forwards key
3515 events. See XEmbed Protocol Specification at
3516 http://freedesktop.org/wiki/Specifications/xembed-spec */
3517 xembed_request_focus (f);
3519 else
3521 XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3522 RevertToParent, CurrentTime);
3523 x_ewmh_activate_frame (f);
3526 x_uncatch_errors ();
3527 unblock_input ();
3529 return Qnil;
3533 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
3534 doc: /* Internal function called by `color-defined-p', which see
3535 .\(Note that the Nextstep version of this function ignores FRAME.) */)
3536 (Lisp_Object color, Lisp_Object frame)
3538 XColor foo;
3539 FRAME_PTR f = check_x_frame (frame);
3541 CHECK_STRING (color);
3543 if (x_defined_color (f, SSDATA (color), &foo, 0))
3544 return Qt;
3545 else
3546 return Qnil;
3549 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
3550 doc: /* Internal function called by `color-values', which see. */)
3551 (Lisp_Object color, Lisp_Object frame)
3553 XColor foo;
3554 FRAME_PTR f = check_x_frame (frame);
3556 CHECK_STRING (color);
3558 if (x_defined_color (f, SSDATA (color), &foo, 0))
3559 return list3 (make_number (foo.red),
3560 make_number (foo.green),
3561 make_number (foo.blue));
3562 else
3563 return Qnil;
3566 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
3567 doc: /* Internal function called by `display-color-p', which see. */)
3568 (Lisp_Object terminal)
3570 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3572 if (dpyinfo->n_planes <= 2)
3573 return Qnil;
3575 switch (dpyinfo->visual->class)
3577 case StaticColor:
3578 case PseudoColor:
3579 case TrueColor:
3580 case DirectColor:
3581 return Qt;
3583 default:
3584 return Qnil;
3588 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
3589 0, 1, 0,
3590 doc: /* Return t if the X display supports shades of gray.
3591 Note that color displays do support shades of gray.
3592 The optional argument TERMINAL specifies which display to ask about.
3593 TERMINAL should be a terminal object, a frame or a display name (a string).
3594 If omitted or nil, that stands for the selected frame's display. */)
3595 (Lisp_Object terminal)
3597 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3599 if (dpyinfo->n_planes <= 1)
3600 return Qnil;
3602 switch (dpyinfo->visual->class)
3604 case StaticColor:
3605 case PseudoColor:
3606 case TrueColor:
3607 case DirectColor:
3608 case StaticGray:
3609 case GrayScale:
3610 return Qt;
3612 default:
3613 return Qnil;
3617 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
3618 0, 1, 0,
3619 doc: /* Return the width in pixels of the X display TERMINAL.
3620 The optional argument TERMINAL specifies which display to ask about.
3621 TERMINAL should be a terminal object, a frame or a display name (a string).
3622 If omitted or nil, that stands for the selected frame's display. */)
3623 (Lisp_Object terminal)
3625 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3627 return make_number (x_display_pixel_width (dpyinfo));
3630 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
3631 Sx_display_pixel_height, 0, 1, 0,
3632 doc: /* Return the height in pixels of the X display TERMINAL.
3633 The optional argument TERMINAL specifies which display to ask about.
3634 TERMINAL should be a terminal object, a frame or a display name (a string).
3635 If omitted or nil, that stands for the selected frame's display. */)
3636 (Lisp_Object terminal)
3638 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3640 return make_number (x_display_pixel_height (dpyinfo));
3643 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
3644 0, 1, 0,
3645 doc: /* Return the number of bitplanes of the X display TERMINAL.
3646 The optional argument TERMINAL specifies which display to ask about.
3647 TERMINAL should be a terminal object, a frame or a display name (a string).
3648 If omitted or nil, that stands for the selected frame's display. */)
3649 (Lisp_Object terminal)
3651 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3653 return make_number (dpyinfo->n_planes);
3656 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
3657 0, 1, 0,
3658 doc: /* Return the number of color cells of the X display TERMINAL.
3659 The optional argument TERMINAL specifies which display to ask about.
3660 TERMINAL should be a terminal object, a frame or a display name (a string).
3661 If omitted or nil, that stands for the selected frame's display. */)
3662 (Lisp_Object terminal)
3664 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3666 int nr_planes = DisplayPlanes (dpyinfo->display,
3667 XScreenNumberOfScreen (dpyinfo->screen));
3669 /* Truncate nr_planes to 24 to avoid integer overflow.
3670 Some displays says 32, but only 24 bits are actually significant.
3671 There are only very few and rare video cards that have more than
3672 24 significant bits. Also 24 bits is more than 16 million colors,
3673 it "should be enough for everyone". */
3674 if (nr_planes > 24) nr_planes = 24;
3676 return make_number (1 << nr_planes);
3679 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
3680 Sx_server_max_request_size,
3681 0, 1, 0,
3682 doc: /* Return the maximum request size of the X server of display TERMINAL.
3683 The optional argument TERMINAL specifies which display to ask about.
3684 TERMINAL should be a terminal object, a frame or a display name (a string).
3685 If omitted or nil, that stands for the selected frame's display. */)
3686 (Lisp_Object terminal)
3688 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3690 return make_number (MAXREQUEST (dpyinfo->display));
3693 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
3694 doc: /* Return the "vendor ID" string of the X server of display TERMINAL.
3695 \(Labeling every distributor as a "vendor" embodies the false assumption
3696 that operating systems cannot be developed and distributed noncommercially.)
3697 The optional argument TERMINAL specifies which display to ask about.
3698 TERMINAL should be a terminal object, a frame or a display name (a string).
3699 If omitted or nil, that stands for the selected frame's display. */)
3700 (Lisp_Object terminal)
3702 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3703 const char *vendor = ServerVendor (dpyinfo->display);
3705 if (! vendor) vendor = "";
3706 return build_string (vendor);
3709 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
3710 doc: /* Return the version numbers of the X server of display TERMINAL.
3711 The value is a list of three integers: the major and minor
3712 version numbers of the X Protocol in use, and the distributor-specific release
3713 number. See also the function `x-server-vendor'.
3715 The optional argument TERMINAL specifies which display to ask about.
3716 TERMINAL should be a terminal object, a frame or a display name (a string).
3717 If omitted or nil, that stands for the selected frame's display. */)
3718 (Lisp_Object terminal)
3720 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3721 Display *dpy = dpyinfo->display;
3723 return Fcons (make_number (ProtocolVersion (dpy)),
3724 Fcons (make_number (ProtocolRevision (dpy)),
3725 Fcons (make_number (VendorRelease (dpy)), Qnil)));
3728 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
3729 doc: /* Return the number of screens on the X server of display TERMINAL.
3730 The optional argument TERMINAL specifies which display to ask about.
3731 TERMINAL should be a terminal object, a frame or a display name (a string).
3732 If omitted or nil, that stands for the selected frame's display. */)
3733 (Lisp_Object terminal)
3735 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3737 return make_number (ScreenCount (dpyinfo->display));
3740 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
3741 doc: /* Return the height in millimeters of the X display TERMINAL.
3742 The optional argument TERMINAL specifies which display to ask about.
3743 TERMINAL should be a terminal object, a frame or a display name (a string).
3744 If omitted or nil, that stands for the selected frame's display. */)
3745 (Lisp_Object terminal)
3747 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3749 return make_number (HeightMMOfScreen (dpyinfo->screen));
3752 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
3753 doc: /* Return the width in millimeters of the X display TERMINAL.
3754 The optional argument TERMINAL specifies which display to ask about.
3755 TERMINAL should be a terminal object, a frame or a display name (a string).
3756 If omitted or nil, that stands for the selected frame's display. */)
3757 (Lisp_Object terminal)
3759 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3761 return make_number (WidthMMOfScreen (dpyinfo->screen));
3764 DEFUN ("x-display-backing-store", Fx_display_backing_store,
3765 Sx_display_backing_store, 0, 1, 0,
3766 doc: /* Return an indication of whether X display TERMINAL does backing store.
3767 The value may be `always', `when-mapped', or `not-useful'.
3768 The optional argument TERMINAL specifies which display to ask about.
3769 TERMINAL should be a terminal object, a frame or a display name (a string).
3770 If omitted or nil, that stands for the selected frame's display. */)
3771 (Lisp_Object terminal)
3773 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3774 Lisp_Object result;
3776 switch (DoesBackingStore (dpyinfo->screen))
3778 case Always:
3779 result = intern ("always");
3780 break;
3782 case WhenMapped:
3783 result = intern ("when-mapped");
3784 break;
3786 case NotUseful:
3787 result = intern ("not-useful");
3788 break;
3790 default:
3791 error ("Strange value for BackingStore parameter of screen");
3792 result = Qnil;
3795 return result;
3798 DEFUN ("x-display-visual-class", Fx_display_visual_class,
3799 Sx_display_visual_class, 0, 1, 0,
3800 doc: /* Return the visual class of the X display TERMINAL.
3801 The value is one of the symbols `static-gray', `gray-scale',
3802 `static-color', `pseudo-color', `true-color', or `direct-color'.
3804 The optional argument TERMINAL specifies which display to ask about.
3805 TERMINAL should a terminal object, a frame or a display name (a string).
3806 If omitted or nil, that stands for the selected frame's display. */)
3807 (Lisp_Object terminal)
3809 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3810 Lisp_Object result;
3812 switch (dpyinfo->visual->class)
3814 case StaticGray:
3815 result = intern ("static-gray");
3816 break;
3817 case GrayScale:
3818 result = intern ("gray-scale");
3819 break;
3820 case StaticColor:
3821 result = intern ("static-color");
3822 break;
3823 case PseudoColor:
3824 result = intern ("pseudo-color");
3825 break;
3826 case TrueColor:
3827 result = intern ("true-color");
3828 break;
3829 case DirectColor:
3830 result = intern ("direct-color");
3831 break;
3832 default:
3833 error ("Display has an unknown visual class");
3834 result = Qnil;
3837 return result;
3840 DEFUN ("x-display-save-under", Fx_display_save_under,
3841 Sx_display_save_under, 0, 1, 0,
3842 doc: /* Return t if the X display TERMINAL supports the save-under feature.
3843 The optional argument TERMINAL specifies which display to ask about.
3844 TERMINAL should be a terminal object, a frame or a display name (a string).
3845 If omitted or nil, that stands for the selected frame's display. */)
3846 (Lisp_Object terminal)
3848 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3850 if (DoesSaveUnders (dpyinfo->screen) == True)
3851 return Qt;
3852 else
3853 return Qnil;
3857 x_pixel_width (register struct frame *f)
3859 return FRAME_PIXEL_WIDTH (f);
3863 x_pixel_height (register struct frame *f)
3865 return FRAME_PIXEL_HEIGHT (f);
3869 x_char_width (register struct frame *f)
3871 return FRAME_COLUMN_WIDTH (f);
3875 x_char_height (register struct frame *f)
3877 return FRAME_LINE_HEIGHT (f);
3882 /************************************************************************
3883 X Displays
3884 ************************************************************************/
3887 /* Mapping visual names to visuals. */
3889 static struct visual_class
3891 const 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 (struct x_display_info *dpyinfo)
3934 Display *dpy = dpyinfo->display;
3935 Screen *screen = dpyinfo->screen;
3936 Lisp_Object value;
3938 /* See if a visual is specified. */
3939 value = display_x_get_resource (dpyinfo,
3940 build_string ("visualClass"),
3941 build_string ("VisualClass"),
3942 Qnil, Qnil);
3943 if (STRINGP (value))
3945 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
3946 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
3947 depth, a decimal number. NAME is compared with case ignored. */
3948 char *s = alloca (SBYTES (value) + 1);
3949 char *dash;
3950 int i, class = -1;
3951 XVisualInfo vinfo;
3953 strcpy (s, SSDATA (value));
3954 dash = strchr (s, '-');
3955 if (dash)
3957 dpyinfo->n_planes = atoi (dash + 1);
3958 *dash = '\0';
3960 else
3961 /* We won't find a matching visual with depth 0, so that
3962 an error will be printed below. */
3963 dpyinfo->n_planes = 0;
3965 /* Determine the visual class. */
3966 for (i = 0; visual_classes[i].name; ++i)
3967 if (xstrcasecmp (s, visual_classes[i].name) == 0)
3969 class = visual_classes[i].class;
3970 break;
3973 /* Look up a matching visual for the specified class. */
3974 if (class == -1
3975 || !XMatchVisualInfo (dpy, XScreenNumberOfScreen (screen),
3976 dpyinfo->n_planes, class, &vinfo))
3977 fatal ("Invalid visual specification `%s'", SDATA (value));
3979 dpyinfo->visual = vinfo.visual;
3981 else
3983 int n_visuals;
3984 XVisualInfo *vinfo, vinfo_template;
3986 dpyinfo->visual = DefaultVisualOfScreen (screen);
3988 vinfo_template.visualid = XVisualIDFromVisual (dpyinfo->visual);
3989 vinfo_template.screen = XScreenNumberOfScreen (screen);
3990 vinfo = XGetVisualInfo (dpy, VisualIDMask | VisualScreenMask,
3991 &vinfo_template, &n_visuals);
3992 if (n_visuals <= 0)
3993 fatal ("Can't get proper X visual info");
3995 dpyinfo->n_planes = vinfo->depth;
3996 XFree (vinfo);
4001 /* Return the X display structure for the display named NAME.
4002 Open a new connection if necessary. */
4004 static struct x_display_info *
4005 x_display_info_for_name (Lisp_Object name)
4007 Lisp_Object names;
4008 struct x_display_info *dpyinfo;
4010 CHECK_STRING (name);
4012 #if 0
4013 if (! EQ (Vinitial_window_system, intern ("x")))
4014 error ("Not using X Windows"); /* That doesn't stop us anymore. */
4015 #endif
4017 for (dpyinfo = x_display_list, names = x_display_name_list;
4018 dpyinfo;
4019 dpyinfo = dpyinfo->next, names = XCDR (names))
4021 Lisp_Object tem;
4022 tem = Fstring_equal (XCAR (XCAR (names)), name);
4023 if (!NILP (tem))
4024 return dpyinfo;
4027 /* Use this general default value to start with. */
4028 Vx_resource_name = Vinvocation_name;
4030 validate_x_resource_name ();
4032 dpyinfo = x_term_init (name, (char *)0,
4033 SSDATA (Vx_resource_name));
4035 if (dpyinfo == 0)
4036 error ("Cannot connect to X server %s", SDATA (name));
4038 x_in_use = 1;
4039 XSETFASTINT (Vwindow_system_version, 11);
4041 return dpyinfo;
4045 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
4046 1, 3, 0,
4047 doc: /* Open a connection to a display server.
4048 DISPLAY is the name of the display to connect to.
4049 Optional second arg XRM-STRING is a string of resources in xrdb format.
4050 If the optional third arg MUST-SUCCEED is non-nil,
4051 terminate Emacs if we can't open the connection.
4052 \(In the Nextstep version, the last two arguments are currently ignored.) */)
4053 (Lisp_Object display, Lisp_Object xrm_string, Lisp_Object must_succeed)
4055 char *xrm_option;
4056 struct x_display_info *dpyinfo;
4058 CHECK_STRING (display);
4059 if (! NILP (xrm_string))
4060 CHECK_STRING (xrm_string);
4062 #if 0
4063 if (! EQ (Vinitial_window_system, intern ("x")))
4064 error ("Not using X Windows"); /* That doesn't stop us anymore. */
4065 #endif
4067 if (! NILP (xrm_string))
4068 xrm_option = SSDATA (xrm_string);
4069 else
4070 xrm_option = (char *) 0;
4072 validate_x_resource_name ();
4074 /* This is what opens the connection and sets x_current_display.
4075 This also initializes many symbols, such as those used for input. */
4076 dpyinfo = x_term_init (display, xrm_option,
4077 SSDATA (Vx_resource_name));
4079 if (dpyinfo == 0)
4081 if (!NILP (must_succeed))
4082 fatal ("Cannot connect to X server %s.\n\
4083 Check the DISPLAY environment variable or use `-d'.\n\
4084 Also use the `xauth' program to verify that you have the proper\n\
4085 authorization information needed to connect the X server.\n\
4086 An insecure way to solve the problem may be to use `xhost'.\n",
4087 SDATA (display));
4088 else
4089 error ("Cannot connect to X server %s", SDATA (display));
4092 x_in_use = 1;
4094 XSETFASTINT (Vwindow_system_version, 11);
4095 return Qnil;
4098 DEFUN ("x-close-connection", Fx_close_connection,
4099 Sx_close_connection, 1, 1, 0,
4100 doc: /* Close the connection to TERMINAL's X server.
4101 For TERMINAL, specify a terminal object, a frame or a display name (a
4102 string). If TERMINAL is nil, that stands for the selected frame's
4103 terminal. */)
4104 (Lisp_Object terminal)
4106 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4108 if (dpyinfo->reference_count > 0)
4109 error ("Display still has frames on it");
4111 x_delete_terminal (dpyinfo->terminal);
4113 return Qnil;
4116 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
4117 doc: /* Return the list of display names that Emacs has connections to. */)
4118 (void)
4120 Lisp_Object tail, result;
4122 result = Qnil;
4123 for (tail = x_display_name_list; CONSP (tail); tail = XCDR (tail))
4124 result = Fcons (XCAR (XCAR (tail)), result);
4126 return result;
4129 DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
4130 doc: /* If ON is non-nil, report X errors as soon as the erring request is made.
4131 This function only has an effect on X Windows. With MS Windows, it is
4132 defined but does nothing.
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 object, a frame or a display name (a string).
4140 If TERMINAL is omitted or nil, that stands for the selected frame's display. */)
4141 (Lisp_Object on, Lisp_Object terminal)
4143 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4145 XSynchronize (dpyinfo->display, !EQ (on, Qnil));
4147 return Qnil;
4150 /* Wait for responses to all X commands issued so far for frame F. */
4152 void
4153 x_sync (FRAME_PTR f)
4155 block_input ();
4156 XSync (FRAME_X_DISPLAY (f), False);
4157 unblock_input ();
4161 /***********************************************************************
4162 Window properties
4163 ***********************************************************************/
4165 DEFUN ("x-change-window-property", Fx_change_window_property,
4166 Sx_change_window_property, 2, 6, 0,
4167 doc: /* Change window property PROP to VALUE on the X window of FRAME.
4168 PROP must be a string. VALUE may be a string or a list of conses,
4169 numbers and/or strings. If an element in the list is a string, it is
4170 converted to an atom and the value of the atom is used. If an element
4171 is a cons, it is converted to a 32 bit number where the car is the 16
4172 top bits and the cdr is the lower 16 bits.
4174 FRAME nil or omitted means use the selected frame.
4175 If TYPE is given and non-nil, it is the name of the type of VALUE.
4176 If TYPE is not given or nil, the type is STRING.
4177 FORMAT gives the size in bits of each element if VALUE is a list.
4178 It must be one of 8, 16 or 32.
4179 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
4180 If OUTER-P is non-nil, the property is changed for the outer X window of
4181 FRAME. Default is to change on the edit X window. */)
4182 (Lisp_Object prop, Lisp_Object value, Lisp_Object frame,
4183 Lisp_Object type, Lisp_Object format, Lisp_Object outer_p)
4185 struct frame *f = check_x_frame (frame);
4186 Atom prop_atom;
4187 Atom target_type = XA_STRING;
4188 int element_format = 8;
4189 unsigned char *data;
4190 int nelements;
4191 Window w;
4193 CHECK_STRING (prop);
4195 if (! NILP (format))
4197 CHECK_NUMBER (format);
4199 if (XINT (format) != 8 && XINT (format) != 16
4200 && XINT (format) != 32)
4201 error ("FORMAT must be one of 8, 16 or 32");
4202 element_format = XINT (format);
4205 if (CONSP (value))
4207 ptrdiff_t elsize;
4209 nelements = x_check_property_data (value);
4210 if (nelements == -1)
4211 error ("Bad data in VALUE, must be number, string or cons");
4213 /* The man page for XChangeProperty:
4214 "If the specified format is 32, the property data must be a
4215 long array."
4216 This applies even if long is more than 32 bits. The X library
4217 converts to 32 bits before sending to the X server. */
4218 elsize = element_format == 32 ? sizeof (long) : element_format >> 3;
4219 data = xnmalloc (nelements, elsize);
4221 x_fill_property_data (FRAME_X_DISPLAY (f), value, data, element_format);
4223 else
4225 CHECK_STRING (value);
4226 data = SDATA (value);
4227 if (INT_MAX < SBYTES (value))
4228 error ("VALUE too long");
4229 nelements = SBYTES (value);
4232 block_input ();
4233 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (prop), False);
4234 if (! NILP (type))
4236 CHECK_STRING (type);
4237 target_type = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (type), False);
4240 if (! NILP (outer_p)) w = FRAME_OUTER_WINDOW (f);
4241 else w = FRAME_X_WINDOW (f);
4243 XChangeProperty (FRAME_X_DISPLAY (f), w,
4244 prop_atom, target_type, element_format, PropModeReplace,
4245 data, nelements);
4247 if (CONSP (value)) xfree (data);
4249 /* Make sure the property is set when we return. */
4250 XFlush (FRAME_X_DISPLAY (f));
4251 unblock_input ();
4253 return value;
4257 DEFUN ("x-delete-window-property", Fx_delete_window_property,
4258 Sx_delete_window_property, 1, 2, 0,
4259 doc: /* Remove window property PROP from X window of FRAME.
4260 FRAME nil or omitted means use the selected frame. Value is PROP. */)
4261 (Lisp_Object prop, Lisp_Object frame)
4263 struct frame *f = check_x_frame (frame);
4264 Atom prop_atom;
4266 CHECK_STRING (prop);
4267 block_input ();
4268 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (prop), False);
4269 XDeleteProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), prop_atom);
4271 /* Make sure the property is removed when we return. */
4272 XFlush (FRAME_X_DISPLAY (f));
4273 unblock_input ();
4275 return prop;
4279 DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
4280 1, 6, 0,
4281 doc: /* Value is the value of window property PROP on FRAME.
4282 If FRAME is nil or omitted, use the selected frame.
4284 On X Windows, the following optional arguments are also accepted:
4285 If TYPE is nil or omitted, get the property as a string.
4286 Otherwise TYPE is the name of the atom that denotes the type expected.
4287 If SOURCE is non-nil, get the property on that window instead of from
4288 FRAME. The number 0 denotes the root window.
4289 If DELETE-P is non-nil, delete the property after retrieving it.
4290 If VECTOR-RET-P is non-nil, don't return a string but a vector of values.
4292 On MS Windows, this function accepts but ignores those optional arguments.
4294 Value is nil if FRAME hasn't a property with name PROP or if PROP has
4295 no value of TYPE (always string in the MS Windows case). */)
4296 (Lisp_Object prop, Lisp_Object frame, Lisp_Object type,
4297 Lisp_Object source, Lisp_Object delete_p, Lisp_Object vector_ret_p)
4299 struct frame *f = check_x_frame (frame);
4300 Atom prop_atom;
4301 int rc;
4302 Lisp_Object prop_value = Qnil;
4303 unsigned char *tmp_data = NULL;
4304 Atom actual_type;
4305 Atom target_type = XA_STRING;
4306 int actual_format;
4307 unsigned long actual_size, bytes_remaining;
4308 Window target_window = FRAME_X_WINDOW (f);
4309 struct gcpro gcpro1;
4311 GCPRO1 (prop_value);
4312 CHECK_STRING (prop);
4314 if (! NILP (source))
4316 CONS_TO_INTEGER (source, Window, target_window);
4317 if (! target_window)
4318 target_window = FRAME_X_DISPLAY_INFO (f)->root_window;
4321 block_input ();
4322 if (STRINGP (type))
4324 if (strcmp ("AnyPropertyType", SSDATA (type)) == 0)
4325 target_type = AnyPropertyType;
4326 else
4327 target_type = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (type), False);
4330 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (prop), False);
4331 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4332 prop_atom, 0, 0, False, target_type,
4333 &actual_type, &actual_format, &actual_size,
4334 &bytes_remaining, &tmp_data);
4335 if (rc == Success)
4337 int size = bytes_remaining;
4339 XFree (tmp_data);
4340 tmp_data = NULL;
4342 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4343 prop_atom, 0, bytes_remaining,
4344 ! NILP (delete_p), target_type,
4345 &actual_type, &actual_format,
4346 &actual_size, &bytes_remaining,
4347 &tmp_data);
4348 if (rc == Success && tmp_data)
4350 /* The man page for XGetWindowProperty says:
4351 "If the returned format is 32, the returned data is represented
4352 as a long array and should be cast to that type to obtain the
4353 elements."
4354 This applies even if long is more than 32 bits, the X library
4355 converts from 32 bit elements received from the X server to long
4356 and passes the long array to us. Thus, for that case memcpy can not
4357 be used. We convert to a 32 bit type here, because so much code
4358 assume on that.
4360 The bytes and offsets passed to XGetWindowProperty refers to the
4361 property and those are indeed in 32 bit quantities if format is
4362 32. */
4364 if (32 < BITS_PER_LONG && actual_format == 32)
4366 unsigned long i;
4367 int *idata = (int *) tmp_data;
4368 long *ldata = (long *) tmp_data;
4370 for (i = 0; i < actual_size; ++i)
4371 idata[i] = (int) ldata[i];
4374 if (NILP (vector_ret_p))
4375 prop_value = make_string ((char *) tmp_data, size);
4376 else
4377 prop_value = x_property_data_to_lisp (f,
4378 tmp_data,
4379 actual_type,
4380 actual_format,
4381 actual_size);
4384 if (tmp_data) XFree (tmp_data);
4387 unblock_input ();
4388 UNGCPRO;
4389 return prop_value;
4394 /***********************************************************************
4395 Busy cursor
4396 ***********************************************************************/
4398 /* Timer function of hourglass_atimer. TIMER is equal to
4399 hourglass_atimer.
4401 Display an hourglass pointer on all frames by mapping the frames'
4402 hourglass_window. Set the hourglass_p flag in the frames'
4403 output_data.x structure to indicate that an hourglass cursor is
4404 shown on the frames. */
4406 void
4407 show_hourglass (struct atimer *timer)
4409 /* The timer implementation will cancel this timer automatically
4410 after this function has run. Set hourglass_atimer to null
4411 so that we know the timer doesn't have to be canceled. */
4412 hourglass_atimer = NULL;
4414 if (!hourglass_shown_p)
4416 Lisp_Object rest, frame;
4418 block_input ();
4420 FOR_EACH_FRAME (rest, frame)
4422 struct frame *f = XFRAME (frame);
4424 if (FRAME_LIVE_P (f) && FRAME_X_P (f) && FRAME_X_DISPLAY (f))
4426 Display *dpy = FRAME_X_DISPLAY (f);
4428 #ifdef USE_X_TOOLKIT
4429 if (f->output_data.x->widget)
4430 #else
4431 if (FRAME_OUTER_WINDOW (f))
4432 #endif
4434 f->output_data.x->hourglass_p = 1;
4436 if (!f->output_data.x->hourglass_window)
4438 unsigned long mask = CWCursor;
4439 XSetWindowAttributes attrs;
4440 #ifdef USE_GTK
4441 Window parent = FRAME_X_WINDOW (f);
4442 #else
4443 Window parent = FRAME_OUTER_WINDOW (f);
4444 #endif
4445 attrs.cursor = f->output_data.x->hourglass_cursor;
4447 f->output_data.x->hourglass_window
4448 = XCreateWindow (dpy, parent,
4449 0, 0, 32000, 32000, 0, 0,
4450 InputOnly,
4451 CopyFromParent,
4452 mask, &attrs);
4455 XMapRaised (dpy, f->output_data.x->hourglass_window);
4456 XFlush (dpy);
4461 hourglass_shown_p = 1;
4462 unblock_input ();
4467 /* Hide the hourglass pointer on all frames, if it is currently
4468 shown. */
4470 void
4471 hide_hourglass (void)
4473 if (hourglass_shown_p)
4475 Lisp_Object rest, frame;
4477 block_input ();
4478 FOR_EACH_FRAME (rest, frame)
4480 struct frame *f = XFRAME (frame);
4482 if (FRAME_X_P (f)
4483 /* Watch out for newly created frames. */
4484 && f->output_data.x->hourglass_window)
4486 XUnmapWindow (FRAME_X_DISPLAY (f),
4487 f->output_data.x->hourglass_window);
4488 /* Sync here because XTread_socket looks at the
4489 hourglass_p flag that is reset to zero below. */
4490 XSync (FRAME_X_DISPLAY (f), False);
4491 f->output_data.x->hourglass_p = 0;
4495 hourglass_shown_p = 0;
4496 unblock_input ();
4502 /***********************************************************************
4503 Tool tips
4504 ***********************************************************************/
4506 static Lisp_Object x_create_tip_frame (struct x_display_info *,
4507 Lisp_Object, Lisp_Object);
4508 static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
4509 Lisp_Object, int, int, int *, int *);
4511 /* The frame of a currently visible tooltip. */
4513 Lisp_Object tip_frame;
4515 /* If non-nil, a timer started that hides the last tooltip when it
4516 fires. */
4518 static Lisp_Object tip_timer;
4519 Window tip_window;
4521 /* If non-nil, a vector of 3 elements containing the last args
4522 with which x-show-tip was called. See there. */
4524 static Lisp_Object last_show_tip_args;
4527 static Lisp_Object
4528 unwind_create_tip_frame (Lisp_Object frame)
4530 Lisp_Object deleted;
4532 deleted = unwind_create_frame (frame);
4533 if (EQ (deleted, Qt))
4535 tip_window = None;
4536 tip_frame = Qnil;
4539 return deleted;
4543 /* Create a frame for a tooltip on the display described by DPYINFO.
4544 PARMS is a list of frame parameters. TEXT is the string to
4545 display in the tip frame. Value is the frame.
4547 Note that functions called here, esp. x_default_parameter can
4548 signal errors, for instance when a specified color name is
4549 undefined. We have to make sure that we're in a consistent state
4550 when this happens. */
4552 static Lisp_Object
4553 x_create_tip_frame (struct x_display_info *dpyinfo,
4554 Lisp_Object parms,
4555 Lisp_Object text)
4557 struct frame *f;
4558 Lisp_Object frame;
4559 Lisp_Object name;
4560 int width, height;
4561 ptrdiff_t count = SPECPDL_INDEX ();
4562 struct gcpro gcpro1, gcpro2, gcpro3;
4563 int face_change_count_before = face_change_count;
4564 Lisp_Object buffer;
4565 struct buffer *old_buffer;
4567 check_x ();
4569 if (!dpyinfo->terminal->name)
4570 error ("Terminal is not live, can't create new frames on it");
4572 parms = Fcopy_alist (parms);
4574 /* Get the name of the frame to use for resource lookup. */
4575 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
4576 if (!STRINGP (name)
4577 && !EQ (name, Qunbound)
4578 && !NILP (name))
4579 error ("Invalid frame name--not a string or nil");
4581 frame = Qnil;
4582 GCPRO3 (parms, name, frame);
4583 f = make_frame (1);
4584 XSETFRAME (frame, f);
4586 buffer = Fget_buffer_create (build_string (" *tip*"));
4587 /* Use set_window_buffer instead of Fset_window_buffer (see
4588 discussion of bug#11984, bug#12025, bug#12026). */
4589 set_window_buffer (FRAME_ROOT_WINDOW (f), buffer, 0, 0);
4590 old_buffer = current_buffer;
4591 set_buffer_internal_1 (XBUFFER (buffer));
4592 bset_truncate_lines (current_buffer, Qnil);
4593 specbind (Qinhibit_read_only, Qt);
4594 specbind (Qinhibit_modification_hooks, Qt);
4595 Ferase_buffer ();
4596 Finsert (1, &text);
4597 set_buffer_internal_1 (old_buffer);
4599 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
4600 record_unwind_protect (unwind_create_tip_frame, frame);
4602 f->terminal = dpyinfo->terminal;
4604 /* By setting the output method, we're essentially saying that
4605 the frame is live, as per FRAME_LIVE_P. If we get a signal
4606 from this point on, x_destroy_window might screw up reference
4607 counts etc. */
4608 f->output_method = output_x_window;
4609 f->output_data.x = xzalloc (sizeof *f->output_data.x);
4610 f->output_data.x->icon_bitmap = -1;
4611 FRAME_FONTSET (f) = -1;
4612 f->output_data.x->scroll_bar_foreground_pixel = -1;
4613 f->output_data.x->scroll_bar_background_pixel = -1;
4614 #ifdef USE_TOOLKIT_SCROLL_BARS
4615 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
4616 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
4617 #endif /* USE_TOOLKIT_SCROLL_BARS */
4618 fset_icon_name (f, Qnil);
4619 FRAME_X_DISPLAY_INFO (f) = dpyinfo;
4620 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
4621 f->output_data.x->explicit_parent = 0;
4623 /* These colors will be set anyway later, but it's important
4624 to get the color reference counts right, so initialize them! */
4626 Lisp_Object black;
4627 struct gcpro gcpro1;
4629 /* Function x_decode_color can signal an error. Make
4630 sure to initialize color slots so that we won't try
4631 to free colors we haven't allocated. */
4632 FRAME_FOREGROUND_PIXEL (f) = -1;
4633 FRAME_BACKGROUND_PIXEL (f) = -1;
4634 f->output_data.x->cursor_pixel = -1;
4635 f->output_data.x->cursor_foreground_pixel = -1;
4636 f->output_data.x->border_pixel = -1;
4637 f->output_data.x->mouse_pixel = -1;
4639 black = build_string ("black");
4640 GCPRO1 (black);
4641 FRAME_FOREGROUND_PIXEL (f)
4642 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4643 FRAME_BACKGROUND_PIXEL (f)
4644 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4645 f->output_data.x->cursor_pixel
4646 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4647 f->output_data.x->cursor_foreground_pixel
4648 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4649 f->output_data.x->border_pixel
4650 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4651 f->output_data.x->mouse_pixel
4652 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4653 UNGCPRO;
4656 /* Set the name; the functions to which we pass f expect the name to
4657 be set. */
4658 if (EQ (name, Qunbound) || NILP (name))
4660 fset_name (f, build_string (dpyinfo->x_id_name));
4661 f->explicit_name = 0;
4663 else
4665 fset_name (f, name);
4666 f->explicit_name = 1;
4667 /* use the frame's title when getting resources for this frame. */
4668 specbind (Qx_resource_name, name);
4671 f->resx = dpyinfo->resx;
4672 f->resy = dpyinfo->resy;
4674 register_font_driver (&xfont_driver, f);
4675 #ifdef HAVE_FREETYPE
4676 #ifdef HAVE_XFT
4677 register_font_driver (&xftfont_driver, f);
4678 #else /* not HAVE_XFT */
4679 register_font_driver (&ftxfont_driver, f);
4680 #endif /* not HAVE_XFT */
4681 #endif /* HAVE_FREETYPE */
4683 x_default_parameter (f, parms, Qfont_backend, Qnil,
4684 "fontBackend", "FontBackend", RES_TYPE_STRING);
4686 /* Extract the window parameters from the supplied values that are
4687 needed to determine window geometry. */
4688 x_default_font_parameter (f, parms);
4690 x_default_parameter (f, parms, Qborder_width, make_number (0),
4691 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
4693 /* This defaults to 2 in order to match xterm. We recognize either
4694 internalBorderWidth or internalBorder (which is what xterm calls
4695 it). */
4696 if (NILP (Fassq (Qinternal_border_width, parms)))
4698 Lisp_Object value;
4700 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
4701 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
4702 if (! EQ (value, Qunbound))
4703 parms = Fcons (Fcons (Qinternal_border_width, value),
4704 parms);
4707 x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
4708 "internalBorderWidth", "internalBorderWidth",
4709 RES_TYPE_NUMBER);
4711 /* Also do the stuff which must be set before the window exists. */
4712 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
4713 "foreground", "Foreground", RES_TYPE_STRING);
4714 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
4715 "background", "Background", RES_TYPE_STRING);
4716 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
4717 "pointerColor", "Foreground", RES_TYPE_STRING);
4718 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
4719 "cursorColor", "Foreground", RES_TYPE_STRING);
4720 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
4721 "borderColor", "BorderColor", RES_TYPE_STRING);
4723 #ifdef GLYPH_DEBUG
4724 image_cache_refcount =
4725 FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
4726 dpyinfo_refcount = dpyinfo->reference_count;
4727 #endif /* GLYPH_DEBUG */
4729 /* Init faces before x_default_parameter is called for scroll-bar
4730 parameters because that function calls x_set_scroll_bar_width,
4731 which calls change_frame_size, which calls Fset_window_buffer,
4732 which runs hooks, which call Fvertical_motion. At the end, we
4733 end up in init_iterator with a null face cache, which should not
4734 happen. */
4735 init_frame_faces (f);
4737 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
4739 x_figure_window_size (f, parms, 0);
4742 XSetWindowAttributes attrs;
4743 unsigned long mask;
4744 Atom type = FRAME_X_DISPLAY_INFO (f)->Xatom_net_window_type_tooltip;
4746 block_input ();
4747 mask = CWBackPixel | CWOverrideRedirect | CWEventMask;
4748 if (DoesSaveUnders (dpyinfo->screen))
4749 mask |= CWSaveUnder;
4751 /* Window managers look at the override-redirect flag to determine
4752 whether or net to give windows a decoration (Xlib spec, chapter
4753 3.2.8). */
4754 attrs.override_redirect = True;
4755 attrs.save_under = True;
4756 attrs.background_pixel = FRAME_BACKGROUND_PIXEL (f);
4757 /* Arrange for getting MapNotify and UnmapNotify events. */
4758 attrs.event_mask = StructureNotifyMask;
4759 tip_window
4760 = FRAME_X_WINDOW (f)
4761 = XCreateWindow (FRAME_X_DISPLAY (f),
4762 FRAME_X_DISPLAY_INFO (f)->root_window,
4763 /* x, y, width, height */
4764 0, 0, 1, 1,
4765 /* Border. */
4766 f->border_width,
4767 CopyFromParent, InputOutput, CopyFromParent,
4768 mask, &attrs);
4769 XChangeProperty (FRAME_X_DISPLAY (f), tip_window,
4770 FRAME_X_DISPLAY_INFO (f)->Xatom_net_window_type,
4771 XA_ATOM, 32, PropModeReplace,
4772 (unsigned char *)&type, 1);
4773 unblock_input ();
4776 x_make_gc (f);
4778 x_default_parameter (f, parms, Qauto_raise, Qnil,
4779 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
4780 x_default_parameter (f, parms, Qauto_lower, Qnil,
4781 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
4782 x_default_parameter (f, parms, Qcursor_type, Qbox,
4783 "cursorType", "CursorType", RES_TYPE_SYMBOL);
4785 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
4786 Change will not be effected unless different from the current
4787 FRAME_LINES (f). */
4788 width = FRAME_COLS (f);
4789 height = FRAME_LINES (f);
4790 SET_FRAME_COLS (f, 0);
4791 FRAME_LINES (f) = 0;
4792 change_frame_size (f, height, width, 1, 0, 0);
4794 /* Add `tooltip' frame parameter's default value. */
4795 if (NILP (Fframe_parameter (frame, Qtooltip)))
4796 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtooltip, Qt), Qnil));
4798 /* FIXME - can this be done in a similar way to normal frames?
4799 http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
4801 /* Set the `display-type' frame parameter before setting up faces. */
4803 Lisp_Object disptype;
4805 if (FRAME_X_DISPLAY_INFO (f)->n_planes == 1)
4806 disptype = intern ("mono");
4807 else if (FRAME_X_DISPLAY_INFO (f)->visual->class == GrayScale
4808 || FRAME_X_DISPLAY_INFO (f)->visual->class == StaticGray)
4809 disptype = intern ("grayscale");
4810 else
4811 disptype = intern ("color");
4813 if (NILP (Fframe_parameter (frame, Qdisplay_type)))
4814 Fmodify_frame_parameters (frame, Fcons (Fcons (Qdisplay_type, disptype),
4815 Qnil));
4818 /* Set up faces after all frame parameters are known. This call
4819 also merges in face attributes specified for new frames.
4821 Frame parameters may be changed if .Xdefaults contains
4822 specifications for the default font. For example, if there is an
4823 `Emacs.default.attributeBackground: pink', the `background-color'
4824 attribute of the frame get's set, which let's the internal border
4825 of the tooltip frame appear in pink. Prevent this. */
4827 Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
4829 /* Set tip_frame here, so that */
4830 tip_frame = frame;
4831 call2 (Qface_set_after_frame_default, frame, Qnil);
4833 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
4834 Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg),
4835 Qnil));
4838 f->no_split = 1;
4840 UNGCPRO;
4842 /* Now that the frame will be official, it counts as a reference to
4843 its display and terminal. */
4844 FRAME_X_DISPLAY_INFO (f)->reference_count++;
4845 f->terminal->reference_count++;
4847 /* It is now ok to make the frame official even if we get an error
4848 below. And the frame needs to be on Vframe_list or making it
4849 visible won't work. */
4850 Vframe_list = Fcons (frame, Vframe_list);
4853 /* Setting attributes of faces of the tooltip frame from resources
4854 and similar will increment face_change_count, which leads to the
4855 clearing of all current matrices. Since this isn't necessary
4856 here, avoid it by resetting face_change_count to the value it
4857 had before we created the tip frame. */
4858 face_change_count = face_change_count_before;
4860 /* Discard the unwind_protect. */
4861 return unbind_to (count, frame);
4865 /* Compute where to display tip frame F. PARMS is the list of frame
4866 parameters for F. DX and DY are specified offsets from the current
4867 location of the mouse. WIDTH and HEIGHT are the width and height
4868 of the tooltip. Return coordinates relative to the root window of
4869 the display in *ROOT_X, and *ROOT_Y. */
4871 static void
4872 compute_tip_xy (struct frame *f, Lisp_Object parms, Lisp_Object dx, Lisp_Object dy, int width, int height, int *root_x, int *root_y)
4874 Lisp_Object left, top;
4875 int win_x, win_y;
4876 Window root, child;
4877 unsigned pmask;
4879 /* User-specified position? */
4880 left = Fcdr (Fassq (Qleft, parms));
4881 top = Fcdr (Fassq (Qtop, parms));
4883 /* Move the tooltip window where the mouse pointer is. Resize and
4884 show it. */
4885 if (!INTEGERP (left) || !INTEGERP (top))
4887 block_input ();
4888 XQueryPointer (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
4889 &root, &child, root_x, root_y, &win_x, &win_y, &pmask);
4890 unblock_input ();
4893 if (INTEGERP (top))
4894 *root_y = XINT (top);
4895 else if (*root_y + XINT (dy) <= 0)
4896 *root_y = 0; /* Can happen for negative dy */
4897 else if (*root_y + XINT (dy) + height
4898 <= x_display_pixel_height (FRAME_X_DISPLAY_INFO (f)))
4899 /* It fits below the pointer */
4900 *root_y += XINT (dy);
4901 else if (height + XINT (dy) <= *root_y)
4902 /* It fits above the pointer. */
4903 *root_y -= height + XINT (dy);
4904 else
4905 /* Put it on the top. */
4906 *root_y = 0;
4908 if (INTEGERP (left))
4909 *root_x = XINT (left);
4910 else if (*root_x + XINT (dx) <= 0)
4911 *root_x = 0; /* Can happen for negative dx */
4912 else if (*root_x + XINT (dx) + width
4913 <= x_display_pixel_width (FRAME_X_DISPLAY_INFO (f)))
4914 /* It fits to the right of the pointer. */
4915 *root_x += XINT (dx);
4916 else if (width + XINT (dx) <= *root_x)
4917 /* It fits to the left of the pointer. */
4918 *root_x -= width + XINT (dx);
4919 else
4920 /* Put it left-justified on the screen--it ought to fit that way. */
4921 *root_x = 0;
4925 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
4926 doc: /* Show STRING in a "tooltip" window on frame FRAME.
4927 A tooltip window is a small X window displaying a string.
4929 This is an internal function; Lisp code should call `tooltip-show'.
4931 FRAME nil or omitted means use the selected frame.
4933 PARMS is an optional list of frame parameters which can be used to
4934 change the tooltip's appearance.
4936 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
4937 means use the default timeout of 5 seconds.
4939 If the list of frame parameters PARMS contains a `left' parameters,
4940 the tooltip is displayed at that x-position. Otherwise it is
4941 displayed at the mouse position, with offset DX added (default is 5 if
4942 DX isn't specified). Likewise for the y-position; if a `top' frame
4943 parameter is specified, it determines the y-position of the tooltip
4944 window, otherwise it is displayed at the mouse position, with offset
4945 DY added (default is -10).
4947 A tooltip's maximum size is specified by `x-max-tooltip-size'.
4948 Text larger than the specified size is clipped. */)
4949 (Lisp_Object string, Lisp_Object frame, Lisp_Object parms, Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy)
4951 struct frame *f;
4952 struct window *w;
4953 int root_x, root_y;
4954 struct buffer *old_buffer;
4955 struct text_pos pos;
4956 int i, width, height, seen_reversed_p;
4957 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
4958 int old_windows_or_buffers_changed = windows_or_buffers_changed;
4959 ptrdiff_t count = SPECPDL_INDEX ();
4961 specbind (Qinhibit_redisplay, Qt);
4963 GCPRO4 (string, parms, frame, timeout);
4965 CHECK_STRING (string);
4966 if (SCHARS (string) == 0)
4967 string = make_unibyte_string (" ", 1);
4969 f = check_x_frame (frame);
4970 if (NILP (timeout))
4971 timeout = make_number (5);
4972 else
4973 CHECK_NATNUM (timeout);
4975 if (NILP (dx))
4976 dx = make_number (5);
4977 else
4978 CHECK_NUMBER (dx);
4980 if (NILP (dy))
4981 dy = make_number (-10);
4982 else
4983 CHECK_NUMBER (dy);
4985 #ifdef USE_GTK
4986 if (x_gtk_use_system_tooltips)
4988 bool ok;
4990 /* Hide a previous tip, if any. */
4991 Fx_hide_tip ();
4993 block_input ();
4994 ok = xg_prepare_tooltip (f, string, &width, &height);
4995 if (ok)
4997 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
4998 xg_show_tooltip (f, root_x, root_y);
4999 /* This is used in Fx_hide_tip. */
5000 XSETFRAME (tip_frame, f);
5002 unblock_input ();
5003 if (ok) goto start_timer;
5005 #endif /* USE_GTK */
5007 if (NILP (last_show_tip_args))
5008 last_show_tip_args = Fmake_vector (make_number (3), Qnil);
5010 if (!NILP (tip_frame))
5012 Lisp_Object last_string = AREF (last_show_tip_args, 0);
5013 Lisp_Object last_frame = AREF (last_show_tip_args, 1);
5014 Lisp_Object last_parms = AREF (last_show_tip_args, 2);
5016 if (EQ (frame, last_frame)
5017 && !NILP (Fequal (last_string, string))
5018 && !NILP (Fequal (last_parms, parms)))
5020 struct frame *tip_f = XFRAME (tip_frame);
5022 /* Only DX and DY have changed. */
5023 if (!NILP (tip_timer))
5025 Lisp_Object timer = tip_timer;
5026 tip_timer = Qnil;
5027 call1 (Qcancel_timer, timer);
5030 block_input ();
5031 compute_tip_xy (tip_f, parms, dx, dy, FRAME_PIXEL_WIDTH (tip_f),
5032 FRAME_PIXEL_HEIGHT (tip_f), &root_x, &root_y);
5033 XMoveWindow (FRAME_X_DISPLAY (tip_f), FRAME_X_WINDOW (tip_f),
5034 root_x, root_y);
5035 unblock_input ();
5036 goto start_timer;
5040 /* Hide a previous tip, if any. */
5041 Fx_hide_tip ();
5043 ASET (last_show_tip_args, 0, string);
5044 ASET (last_show_tip_args, 1, frame);
5045 ASET (last_show_tip_args, 2, parms);
5047 /* Add default values to frame parameters. */
5048 if (NILP (Fassq (Qname, parms)))
5049 parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
5050 if (NILP (Fassq (Qinternal_border_width, parms)))
5051 parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
5052 if (NILP (Fassq (Qborder_width, parms)))
5053 parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
5054 if (NILP (Fassq (Qborder_color, parms)))
5055 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
5056 if (NILP (Fassq (Qbackground_color, parms)))
5057 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
5058 parms);
5060 /* Create a frame for the tooltip, and record it in the global
5061 variable tip_frame. */
5062 frame = x_create_tip_frame (FRAME_X_DISPLAY_INFO (f), parms, string);
5063 f = XFRAME (frame);
5065 /* Set up the frame's root window. */
5066 w = XWINDOW (FRAME_ROOT_WINDOW (f));
5067 wset_left_col (w, make_number (0));
5068 wset_top_line (w, make_number (0));
5070 if (CONSP (Vx_max_tooltip_size)
5071 && RANGED_INTEGERP (1, XCAR (Vx_max_tooltip_size), INT_MAX)
5072 && RANGED_INTEGERP (1, XCDR (Vx_max_tooltip_size), INT_MAX))
5074 wset_total_cols (w, XCAR (Vx_max_tooltip_size));
5075 wset_total_lines (w, XCDR (Vx_max_tooltip_size));
5077 else
5079 wset_total_cols (w, make_number (80));
5080 wset_total_lines (w, make_number (40));
5083 FRAME_TOTAL_COLS (f) = XINT (w->total_cols);
5084 adjust_glyphs (f);
5085 w->pseudo_window_p = 1;
5087 /* Display the tooltip text in a temporary buffer. */
5088 old_buffer = current_buffer;
5089 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer));
5090 bset_truncate_lines (current_buffer, Qnil);
5091 clear_glyph_matrix (w->desired_matrix);
5092 clear_glyph_matrix (w->current_matrix);
5093 SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
5094 try_window (FRAME_ROOT_WINDOW (f), pos, TRY_WINDOW_IGNORE_FONTS_CHANGE);
5096 /* Compute width and height of the tooltip. */
5097 width = height = seen_reversed_p = 0;
5098 for (i = 0; i < w->desired_matrix->nrows; ++i)
5100 struct glyph_row *row = &w->desired_matrix->rows[i];
5101 struct glyph *last;
5102 int row_width;
5104 /* Stop at the first empty row at the end. */
5105 if (!row->enabled_p || !row->displays_text_p)
5106 break;
5108 /* Let the row go over the full width of the frame. */
5109 row->full_width_p = 1;
5111 row_width = row->pixel_width;
5112 if (row->used[TEXT_AREA])
5114 /* There's a glyph at the end of rows that is used to place
5115 the cursor there. Don't include the width of this glyph. */
5116 if (!row->reversed_p)
5118 last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
5119 if (INTEGERP (last->object))
5120 row_width -= last->pixel_width;
5122 else
5124 /* There could be a stretch glyph at the beginning of R2L
5125 rows that is produced by extend_face_to_end_of_line.
5126 Don't count that glyph. */
5127 struct glyph *g = row->glyphs[TEXT_AREA];
5129 if (g->type == STRETCH_GLYPH && INTEGERP (g->object))
5131 row_width -= g->pixel_width;
5132 seen_reversed_p = 1;
5137 height += row->height;
5138 width = max (width, row_width);
5141 /* If we've seen partial-length R2L rows, we need to re-adjust the
5142 tool-tip frame width and redisplay it again, to avoid over-wide
5143 tips due to the stretch glyph that extends R2L lines to full
5144 width of the frame. */
5145 if (seen_reversed_p)
5147 /* w->total_cols and FRAME_TOTAL_COLS want the width in columns,
5148 not in pixels. */
5149 width /= WINDOW_FRAME_COLUMN_WIDTH (w);
5150 wset_total_cols (w, make_number (width));
5151 FRAME_TOTAL_COLS (f) = width;
5152 adjust_glyphs (f);
5153 clear_glyph_matrix (w->desired_matrix);
5154 clear_glyph_matrix (w->current_matrix);
5155 try_window (FRAME_ROOT_WINDOW (f), pos, 0);
5156 width = height = 0;
5157 /* Recompute width and height of the tooltip. */
5158 for (i = 0; i < w->desired_matrix->nrows; ++i)
5160 struct glyph_row *row = &w->desired_matrix->rows[i];
5161 struct glyph *last;
5162 int row_width;
5164 if (!row->enabled_p || !row->displays_text_p)
5165 break;
5166 row->full_width_p = 1;
5167 row_width = row->pixel_width;
5168 if (row->used[TEXT_AREA] && !row->reversed_p)
5170 last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
5171 if (INTEGERP (last->object))
5172 row_width -= last->pixel_width;
5175 height += row->height;
5176 width = max (width, row_width);
5180 /* Add the frame's internal border to the width and height the X
5181 window should have. */
5182 height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5183 width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5185 /* Move the tooltip window where the mouse pointer is. Resize and
5186 show it. */
5187 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
5189 block_input ();
5190 XMoveResizeWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5191 root_x, root_y, width, height);
5192 XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
5193 unblock_input ();
5195 /* Draw into the window. */
5196 w->must_be_updated_p = 1;
5197 update_single_window (w, 1);
5199 /* Restore original current buffer. */
5200 set_buffer_internal_1 (old_buffer);
5201 windows_or_buffers_changed = old_windows_or_buffers_changed;
5203 start_timer:
5204 /* Let the tip disappear after timeout seconds. */
5205 tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
5206 intern ("x-hide-tip"));
5208 UNGCPRO;
5209 return unbind_to (count, Qnil);
5213 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
5214 doc: /* Hide the current tooltip window, if there is any.
5215 Value is t if tooltip was open, nil otherwise. */)
5216 (void)
5218 ptrdiff_t count;
5219 Lisp_Object deleted, frame, timer;
5220 struct gcpro gcpro1, gcpro2;
5222 /* Return quickly if nothing to do. */
5223 if (NILP (tip_timer) && NILP (tip_frame))
5224 return Qnil;
5226 frame = tip_frame;
5227 timer = tip_timer;
5228 GCPRO2 (frame, timer);
5229 tip_frame = tip_timer = deleted = Qnil;
5231 count = SPECPDL_INDEX ();
5232 specbind (Qinhibit_redisplay, Qt);
5233 specbind (Qinhibit_quit, Qt);
5235 if (!NILP (timer))
5236 call1 (Qcancel_timer, timer);
5238 #ifdef USE_GTK
5240 /* When using system tooltip, tip_frame is the Emacs frame on which
5241 the tip is shown. */
5242 struct frame *f = XFRAME (frame);
5243 if (FRAME_LIVE_P (f) && xg_hide_tooltip (f))
5244 frame = Qnil;
5246 #endif
5248 if (FRAMEP (frame))
5250 delete_frame (frame, Qnil);
5251 deleted = Qt;
5253 #ifdef USE_LUCID
5254 /* Bloodcurdling hack alert: The Lucid menu bar widget's
5255 redisplay procedure is not called when a tip frame over menu
5256 items is unmapped. Redisplay the menu manually... */
5258 Widget w;
5259 struct frame *f = SELECTED_FRAME ();
5260 w = f->output_data.x->menubar_widget;
5262 if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f)->screen)
5263 && w != NULL)
5265 block_input ();
5266 xlwmenu_redisplay (w);
5267 unblock_input ();
5270 #endif /* USE_LUCID */
5273 UNGCPRO;
5274 return unbind_to (count, deleted);
5279 /***********************************************************************
5280 File selection dialog
5281 ***********************************************************************/
5283 DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog,
5284 Sx_uses_old_gtk_dialog,
5285 0, 0, 0,
5286 doc: /* Return t if the old Gtk+ file selection dialog is used. */)
5287 (void)
5289 #ifdef USE_GTK
5290 if (use_dialog_box
5291 && use_file_dialog
5292 && have_menus_p ()
5293 && xg_uses_old_file_dialog ())
5294 return Qt;
5295 #endif
5296 return Qnil;
5300 #ifdef USE_MOTIF
5301 /* Callback for "OK" and "Cancel" on file selection dialog. */
5303 static void
5304 file_dialog_cb (Widget widget, XtPointer client_data, XtPointer call_data)
5306 int *result = (int *) client_data;
5307 XmAnyCallbackStruct *cb = (XmAnyCallbackStruct *) call_data;
5308 *result = cb->reason;
5312 /* Callback for unmapping a file selection dialog. This is used to
5313 capture the case where a dialog is closed via a window manager's
5314 closer button, for example. Using a XmNdestroyCallback didn't work
5315 in this case. */
5317 static void
5318 file_dialog_unmap_cb (Widget widget, XtPointer client_data, XtPointer call_data)
5320 int *result = (int *) client_data;
5321 *result = XmCR_CANCEL;
5324 static Lisp_Object
5325 clean_up_file_dialog (Lisp_Object arg)
5327 struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
5328 Widget dialog = (Widget) p->pointer;
5330 /* Clean up. */
5331 block_input ();
5332 XtUnmanageChild (dialog);
5333 XtDestroyWidget (dialog);
5334 x_menu_set_in_use (0);
5335 unblock_input ();
5337 return Qnil;
5341 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5342 doc: /* Read file name, prompting with PROMPT in directory DIR.
5343 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5344 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5345 or directory must exist.
5347 This function is only defined on NS, MS Windows, and X Windows with the
5348 Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
5349 Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */)
5350 (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p)
5352 int result;
5353 struct frame *f = SELECTED_FRAME ();
5354 Lisp_Object file = Qnil;
5355 Lisp_Object decoded_file;
5356 Widget dialog, text, help;
5357 Arg al[10];
5358 int ac = 0;
5359 XmString dir_xmstring, pattern_xmstring;
5360 ptrdiff_t count = SPECPDL_INDEX ();
5361 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5363 check_x ();
5365 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5367 if (popup_activated ())
5368 error ("Trying to use a menu from within a menu-entry");
5370 CHECK_STRING (prompt);
5371 CHECK_STRING (dir);
5373 /* Prevent redisplay. */
5374 specbind (Qinhibit_redisplay, Qt);
5376 block_input ();
5378 /* Create the dialog with PROMPT as title, using DIR as initial
5379 directory and using "*" as pattern. */
5380 dir = Fexpand_file_name (dir, Qnil);
5381 dir_xmstring = XmStringCreateLocalized (SSDATA (dir));
5382 pattern_xmstring = XmStringCreateLocalized ("*");
5384 XtSetArg (al[ac], XmNtitle, SDATA (prompt)); ++ac;
5385 XtSetArg (al[ac], XmNdirectory, dir_xmstring); ++ac;
5386 XtSetArg (al[ac], XmNpattern, pattern_xmstring); ++ac;
5387 XtSetArg (al[ac], XmNresizePolicy, XmRESIZE_GROW); ++ac;
5388 XtSetArg (al[ac], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); ++ac;
5389 dialog = XmCreateFileSelectionDialog (f->output_data.x->widget,
5390 "fsb", al, ac);
5391 XmStringFree (dir_xmstring);
5392 XmStringFree (pattern_xmstring);
5394 /* Add callbacks for OK and Cancel. */
5395 XtAddCallback (dialog, XmNokCallback, file_dialog_cb,
5396 (XtPointer) &result);
5397 XtAddCallback (dialog, XmNcancelCallback, file_dialog_cb,
5398 (XtPointer) &result);
5399 XtAddCallback (dialog, XmNunmapCallback, file_dialog_unmap_cb,
5400 (XtPointer) &result);
5402 /* Remove the help button since we can't display help. */
5403 help = XmFileSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON);
5404 XtUnmanageChild (help);
5406 /* Mark OK button as default. */
5407 XtVaSetValues (XmFileSelectionBoxGetChild (dialog, XmDIALOG_OK_BUTTON),
5408 XmNshowAsDefault, True, NULL);
5410 /* If MUSTMATCH is non-nil, disable the file entry field of the
5411 dialog, so that the user must select a file from the files list
5412 box. We can't remove it because we wouldn't have a way to get at
5413 the result file name, then. */
5414 text = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5415 if (!NILP (mustmatch))
5417 Widget label;
5418 label = XmFileSelectionBoxGetChild (dialog, XmDIALOG_SELECTION_LABEL);
5419 XtSetSensitive (text, False);
5420 XtSetSensitive (label, False);
5423 /* Manage the dialog, so that list boxes get filled. */
5424 XtManageChild (dialog);
5426 if (STRINGP (default_filename))
5428 XmString default_xmstring;
5429 Widget wtext = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5430 Widget list = XmFileSelectionBoxGetChild (dialog, XmDIALOG_LIST);
5432 XmTextPosition last_pos = XmTextFieldGetLastPosition (wtext);
5433 XmTextFieldReplace (wtext, 0, last_pos,
5434 (SSDATA (Ffile_name_nondirectory (default_filename))));
5436 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
5437 must include the path for this to work. */
5439 default_xmstring = XmStringCreateLocalized (SSDATA (default_filename));
5441 if (XmListItemExists (list, default_xmstring))
5443 int item_pos = XmListItemPos (list, default_xmstring);
5444 /* Select the item and scroll it into view. */
5445 XmListSelectPos (list, item_pos, True);
5446 XmListSetPos (list, item_pos);
5449 XmStringFree (default_xmstring);
5452 record_unwind_protect (clean_up_file_dialog, make_save_value (dialog, 0));
5454 /* Process events until the user presses Cancel or OK. */
5455 x_menu_set_in_use (1);
5456 result = 0;
5457 while (result == 0)
5459 XEvent event;
5460 x_menu_wait_for_event (0);
5461 XtAppNextEvent (Xt_app_con, &event);
5462 if (event.type == KeyPress
5463 && FRAME_X_DISPLAY (f) == event.xkey.display)
5465 KeySym keysym = XLookupKeysym (&event.xkey, 0);
5467 /* Pop down on C-g. */
5468 if (keysym == XK_g && (event.xkey.state & ControlMask) != 0)
5469 XtUnmanageChild (dialog);
5472 (void) x_dispatch_event (&event, FRAME_X_DISPLAY (f));
5475 /* Get the result. */
5476 if (result == XmCR_OK)
5478 XmString text_string;
5479 String data;
5481 XtVaGetValues (dialog, XmNtextString, &text_string, NULL);
5482 XmStringGetLtoR (text_string, XmFONTLIST_DEFAULT_TAG, &data);
5483 XmStringFree (text_string);
5484 file = build_string (data);
5485 XtFree (data);
5487 else
5488 file = Qnil;
5490 unblock_input ();
5491 UNGCPRO;
5493 /* Make "Cancel" equivalent to C-g. */
5494 if (NILP (file))
5495 Fsignal (Qquit, Qnil);
5497 decoded_file = DECODE_FILE (file);
5499 return unbind_to (count, decoded_file);
5502 #endif /* USE_MOTIF */
5504 #ifdef USE_GTK
5506 static Lisp_Object
5507 clean_up_dialog (Lisp_Object arg)
5509 x_menu_set_in_use (0);
5511 return Qnil;
5514 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5515 doc: /* Read file name, prompting with PROMPT in directory DIR.
5516 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5517 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5518 or directory must exist.
5520 This function is only defined on NS, MS Windows, and X Windows with the
5521 Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
5522 Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */)
5523 (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p)
5525 FRAME_PTR f = SELECTED_FRAME ();
5526 char *fn;
5527 Lisp_Object file = Qnil;
5528 Lisp_Object decoded_file;
5529 ptrdiff_t count = SPECPDL_INDEX ();
5530 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5531 char *cdef_file;
5533 check_x ();
5535 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5537 if (popup_activated ())
5538 error ("Trying to use a menu from within a menu-entry");
5540 CHECK_STRING (prompt);
5541 CHECK_STRING (dir);
5543 /* Prevent redisplay. */
5544 specbind (Qinhibit_redisplay, Qt);
5545 record_unwind_protect (clean_up_dialog, Qnil);
5547 block_input ();
5549 if (STRINGP (default_filename))
5550 cdef_file = SSDATA (default_filename);
5551 else
5552 cdef_file = SSDATA (dir);
5554 fn = xg_get_file_name (f, SSDATA (prompt), cdef_file,
5555 ! NILP (mustmatch),
5556 ! NILP (only_dir_p));
5558 if (fn)
5560 file = build_string (fn);
5561 xfree (fn);
5564 unblock_input ();
5565 UNGCPRO;
5567 /* Make "Cancel" equivalent to C-g. */
5568 if (NILP (file))
5569 Fsignal (Qquit, Qnil);
5571 decoded_file = DECODE_FILE (file);
5573 return unbind_to (count, decoded_file);
5577 #ifdef HAVE_FREETYPE
5579 DEFUN ("x-select-font", Fx_select_font, Sx_select_font, 0, 2, 0,
5580 doc: /* Read a font using a GTK dialog.
5581 Return either a font spec (for GTK versions >= 3.2) or a string
5582 containing a GTK-style font name.
5584 FRAME is the frame on which to pop up the font chooser. If omitted or
5585 nil, it defaults to the selected frame. */)
5586 (Lisp_Object frame, Lisp_Object ignored)
5588 FRAME_PTR f = check_x_frame (frame);
5589 Lisp_Object font;
5590 Lisp_Object font_param;
5591 char *default_name = NULL;
5592 struct gcpro gcpro1, gcpro2;
5593 ptrdiff_t count = SPECPDL_INDEX ();
5595 check_x ();
5597 if (popup_activated ())
5598 error ("Trying to use a menu from within a menu-entry");
5600 /* Prevent redisplay. */
5601 specbind (Qinhibit_redisplay, Qt);
5602 record_unwind_protect (clean_up_dialog, Qnil);
5604 block_input ();
5606 GCPRO2 (font_param, font);
5608 XSETFONT (font, FRAME_FONT (f));
5609 font_param = Ffont_get (font, intern (":name"));
5610 if (STRINGP (font_param))
5611 default_name = xstrdup (SSDATA (font_param));
5612 else
5614 font_param = Fframe_parameter (frame, Qfont_param);
5615 if (STRINGP (font_param))
5616 default_name = xstrdup (SSDATA (font_param));
5619 font = xg_get_font (f, default_name);
5620 xfree (default_name);
5622 unblock_input ();
5624 if (NILP (font))
5625 Fsignal (Qquit, Qnil);
5627 return unbind_to (count, font);
5629 #endif /* HAVE_FREETYPE */
5631 #endif /* USE_GTK */
5634 /***********************************************************************
5635 Keyboard
5636 ***********************************************************************/
5638 #ifdef HAVE_XKBGETKEYBOARD
5639 #include <X11/XKBlib.h>
5640 #include <X11/keysym.h>
5641 #endif
5643 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p,
5644 Sx_backspace_delete_keys_p, 0, 1, 0,
5645 doc: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
5646 FRAME nil means use the selected frame.
5647 Value is t if we know that both keys are present, and are mapped to the
5648 usual X keysyms. Value is `lambda' if we cannot determine if both keys are
5649 present and mapped to the usual X keysyms. */)
5650 (Lisp_Object frame)
5652 #ifdef HAVE_XKBGETKEYBOARD
5653 XkbDescPtr kb;
5654 struct frame *f = check_x_frame (frame);
5655 Display *dpy = FRAME_X_DISPLAY (f);
5656 Lisp_Object have_keys;
5657 int major, minor, op, event, error_code;
5659 block_input ();
5661 /* Check library version in case we're dynamically linked. */
5662 major = XkbMajorVersion;
5663 minor = XkbMinorVersion;
5664 if (!XkbLibraryVersion (&major, &minor))
5666 unblock_input ();
5667 return Qlambda;
5670 /* Check that the server supports XKB. */
5671 major = XkbMajorVersion;
5672 minor = XkbMinorVersion;
5673 if (!XkbQueryExtension (dpy, &op, &event, &error_code, &major, &minor))
5675 unblock_input ();
5676 return Qlambda;
5679 /* In this code we check that the keyboard has physical keys with names
5680 that start with BKSP (Backspace) and DELE (Delete), and that they
5681 generate keysym XK_BackSpace and XK_Delete respectively.
5682 This function is used to test if normal-erase-is-backspace should be
5683 turned on.
5684 An alternative approach would be to just check if XK_BackSpace and
5685 XK_Delete are mapped to any key. But if any of those are mapped to
5686 some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the
5687 user doesn't know about it, it is better to return false here.
5688 It is more obvious to the user what to do if she/he has two keys
5689 clearly marked with names/symbols and one key does something not
5690 expected (i.e. she/he then tries the other).
5691 The cases where Backspace/Delete is mapped to some other key combination
5692 are rare, and in those cases, normal-erase-is-backspace can be turned on
5693 manually. */
5695 have_keys = Qnil;
5696 kb = XkbGetMap (dpy, XkbAllMapComponentsMask, XkbUseCoreKbd);
5697 if (kb)
5699 int delete_keycode = 0, backspace_keycode = 0, i;
5701 if (XkbGetNames (dpy, XkbAllNamesMask, kb) == Success)
5703 for (i = kb->min_key_code;
5704 (i < kb->max_key_code
5705 && (delete_keycode == 0 || backspace_keycode == 0));
5706 ++i)
5708 /* The XKB symbolic key names can be seen most easily in
5709 the PS file generated by `xkbprint -label name
5710 $DISPLAY'. */
5711 if (memcmp ("DELE", kb->names->keys[i].name, 4) == 0)
5712 delete_keycode = i;
5713 else if (memcmp ("BKSP", kb->names->keys[i].name, 4) == 0)
5714 backspace_keycode = i;
5717 XkbFreeNames (kb, 0, True);
5720 XkbFreeClientMap (kb, 0, True);
5722 if (delete_keycode
5723 && backspace_keycode
5724 && XKeysymToKeycode (dpy, XK_Delete) == delete_keycode
5725 && XKeysymToKeycode (dpy, XK_BackSpace) == backspace_keycode)
5726 have_keys = Qt;
5728 unblock_input ();
5729 return have_keys;
5730 #else /* not HAVE_XKBGETKEYBOARD */
5731 return Qlambda;
5732 #endif /* not HAVE_XKBGETKEYBOARD */
5737 /***********************************************************************
5738 Initialization
5739 ***********************************************************************/
5741 /* Keep this list in the same order as frame_parms in frame.c.
5742 Use 0 for unsupported frame parameters. */
5744 frame_parm_handler x_frame_parm_handlers[] =
5746 x_set_autoraise,
5747 x_set_autolower,
5748 x_set_background_color,
5749 x_set_border_color,
5750 x_set_border_width,
5751 x_set_cursor_color,
5752 x_set_cursor_type,
5753 x_set_font,
5754 x_set_foreground_color,
5755 x_set_icon_name,
5756 x_set_icon_type,
5757 x_set_internal_border_width,
5758 x_set_menu_bar_lines,
5759 x_set_mouse_color,
5760 x_explicitly_set_name,
5761 x_set_scroll_bar_width,
5762 x_set_title,
5763 x_set_unsplittable,
5764 x_set_vertical_scroll_bars,
5765 x_set_visibility,
5766 x_set_tool_bar_lines,
5767 x_set_scroll_bar_foreground,
5768 x_set_scroll_bar_background,
5769 x_set_screen_gamma,
5770 x_set_line_spacing,
5771 x_set_fringe_width,
5772 x_set_fringe_width,
5773 x_set_wait_for_wm,
5774 x_set_fullscreen,
5775 x_set_font_backend,
5776 x_set_alpha,
5777 x_set_sticky,
5778 x_set_tool_bar_position,
5781 void
5782 syms_of_xfns (void)
5784 /* This is zero if not using X windows. */
5785 x_in_use = 0;
5787 /* The section below is built by the lisp expression at the top of the file,
5788 just above where these variables are declared. */
5789 /*&&& init symbols here &&&*/
5790 DEFSYM (Qsuppress_icon, "suppress-icon");
5791 DEFSYM (Qundefined_color, "undefined-color");
5792 DEFSYM (Qcompound_text, "compound-text");
5793 DEFSYM (Qcancel_timer, "cancel-timer");
5794 DEFSYM (Qfont_param, "font-parameter");
5795 /* This is the end of symbol initialization. */
5797 Fput (Qundefined_color, Qerror_conditions,
5798 listn (CONSTYPE_PURE, 2, Qundefined_color, Qerror));
5799 Fput (Qundefined_color, Qerror_message,
5800 build_pure_c_string ("Undefined color"));
5802 DEFVAR_LISP ("x-pointer-shape", Vx_pointer_shape,
5803 doc: /* The shape of the pointer when over text.
5804 Changing the value does not affect existing frames
5805 unless you set the mouse color. */);
5806 Vx_pointer_shape = Qnil;
5808 #if 0 /* This doesn't really do anything. */
5809 DEFVAR_LISP ("x-nontext-pointer-shape", Vx_nontext_pointer_shape,
5810 doc: /* The shape of the pointer when not over text.
5811 This variable takes effect when you create a new frame
5812 or when you set the mouse color. */);
5813 #endif
5814 Vx_nontext_pointer_shape = Qnil;
5816 DEFVAR_LISP ("x-hourglass-pointer-shape", Vx_hourglass_pointer_shape,
5817 doc: /* The shape of the pointer when Emacs is busy.
5818 This variable takes effect when you create a new frame
5819 or when you set the mouse color. */);
5820 Vx_hourglass_pointer_shape = Qnil;
5822 #if 0 /* This doesn't really do anything. */
5823 DEFVAR_LISP ("x-mode-pointer-shape", Vx_mode_pointer_shape,
5824 doc: /* The shape of the pointer when over the mode line.
5825 This variable takes effect when you create a new frame
5826 or when you set the mouse color. */);
5827 #endif
5828 Vx_mode_pointer_shape = Qnil;
5830 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
5831 Vx_sensitive_text_pointer_shape,
5832 doc: /* The shape of the pointer when over mouse-sensitive text.
5833 This variable takes effect when you create a new frame
5834 or when you set the mouse color. */);
5835 Vx_sensitive_text_pointer_shape = Qnil;
5837 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
5838 Vx_window_horizontal_drag_shape,
5839 doc: /* Pointer shape to use for indicating a window can be dragged horizontally.
5840 This variable takes effect when you create a new frame
5841 or when you set the mouse color. */);
5842 Vx_window_horizontal_drag_shape = Qnil;
5844 DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel,
5845 doc: /* A string indicating the foreground color of the cursor box. */);
5846 Vx_cursor_fore_pixel = Qnil;
5848 DEFVAR_LISP ("x-max-tooltip-size", Vx_max_tooltip_size,
5849 doc: /* Maximum size for tooltips.
5850 Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */);
5851 Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
5853 DEFVAR_LISP ("x-no-window-manager", Vx_no_window_manager,
5854 doc: /* Non-nil if no X window manager is in use.
5855 Emacs doesn't try to figure this out; this is always nil
5856 unless you set it to something else. */);
5857 /* We don't have any way to find this out, so set it to nil
5858 and maybe the user would like to set it to t. */
5859 Vx_no_window_manager = Qnil;
5861 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
5862 Vx_pixel_size_width_font_regexp,
5863 doc: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
5865 Since Emacs gets width of a font matching with this regexp from
5866 PIXEL_SIZE field of the name, font finding mechanism gets faster for
5867 such a font. This is especially effective for such large fonts as
5868 Chinese, Japanese, and Korean. */);
5869 Vx_pixel_size_width_font_regexp = Qnil;
5871 /* This is not ifdef:ed, so other builds than GTK can customize it. */
5872 DEFVAR_BOOL ("x-gtk-use-old-file-dialog", x_gtk_use_old_file_dialog,
5873 doc: /* Non-nil means prompt with the old GTK file selection dialog.
5874 If nil or if the file selection dialog is not available, the new GTK file
5875 chooser is used instead. To turn off all file dialogs set the
5876 variable `use-file-dialog'. */);
5877 x_gtk_use_old_file_dialog = 0;
5879 DEFVAR_BOOL ("x-gtk-show-hidden-files", x_gtk_show_hidden_files,
5880 doc: /* If non-nil, the GTK file chooser will by default show hidden files.
5881 Note that this is just the default, there is a toggle button on the file
5882 chooser to show or not show hidden files on a case by case basis. */);
5883 x_gtk_show_hidden_files = 0;
5885 DEFVAR_BOOL ("x-gtk-file-dialog-help-text", x_gtk_file_dialog_help_text,
5886 doc: /* If non-nil, the GTK file chooser will show additional help text.
5887 If more space for files in the file chooser dialog is wanted, set this to nil
5888 to turn the additional text off. */);
5889 x_gtk_file_dialog_help_text = 1;
5891 DEFVAR_BOOL ("x-gtk-whole-detached-tool-bar", x_gtk_whole_detached_tool_bar,
5892 doc: /* If non-nil, a detached tool bar is shown in full.
5893 The default is to just show an arrow and pressing on that arrow shows
5894 the tool bar buttons. */);
5895 x_gtk_whole_detached_tool_bar = 0;
5897 DEFVAR_BOOL ("x-gtk-use-system-tooltips", x_gtk_use_system_tooltips,
5898 doc: /* If non-nil with a Gtk+ built Emacs, the Gtk+ tooltip is used.
5899 Otherwise use Emacs own tooltip implementation.
5900 When using Gtk+ tooltips, the tooltip face is not used. */);
5901 x_gtk_use_system_tooltips = 1;
5903 Fprovide (intern_c_string ("x"), Qnil);
5905 #ifdef USE_X_TOOLKIT
5906 Fprovide (intern_c_string ("x-toolkit"), Qnil);
5907 #ifdef USE_MOTIF
5908 Fprovide (intern_c_string ("motif"), Qnil);
5910 DEFVAR_LISP ("motif-version-string", Vmotif_version_string,
5911 doc: /* Version info for LessTif/Motif. */);
5912 Vmotif_version_string = build_string (XmVERSION_STRING);
5913 #endif /* USE_MOTIF */
5914 #endif /* USE_X_TOOLKIT */
5916 #ifdef USE_GTK
5917 /* Provide x-toolkit also for GTK. Internally GTK does not use Xt so it
5918 is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
5919 But for a user it is a toolkit for X, and indeed, configure
5920 accepts --with-x-toolkit=gtk. */
5921 Fprovide (intern_c_string ("x-toolkit"), Qnil);
5922 Fprovide (intern_c_string ("gtk"), Qnil);
5923 Fprovide (intern_c_string ("move-toolbar"), Qnil);
5925 DEFVAR_LISP ("gtk-version-string", Vgtk_version_string,
5926 doc: /* Version info for GTK+. */);
5928 char gtk_version[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
5929 int len = sprintf (gtk_version, "%d.%d.%d",
5930 GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
5931 Vgtk_version_string = make_pure_string (gtk_version, len, len, 0);
5933 #endif /* USE_GTK */
5935 /* X window properties. */
5936 defsubr (&Sx_change_window_property);
5937 defsubr (&Sx_delete_window_property);
5938 defsubr (&Sx_window_property);
5940 defsubr (&Sxw_display_color_p);
5941 defsubr (&Sx_display_grayscale_p);
5942 defsubr (&Sxw_color_defined_p);
5943 defsubr (&Sxw_color_values);
5944 defsubr (&Sx_server_max_request_size);
5945 defsubr (&Sx_server_vendor);
5946 defsubr (&Sx_server_version);
5947 defsubr (&Sx_display_pixel_width);
5948 defsubr (&Sx_display_pixel_height);
5949 defsubr (&Sx_display_mm_width);
5950 defsubr (&Sx_display_mm_height);
5951 defsubr (&Sx_display_screens);
5952 defsubr (&Sx_display_planes);
5953 defsubr (&Sx_display_color_cells);
5954 defsubr (&Sx_display_visual_class);
5955 defsubr (&Sx_display_backing_store);
5956 defsubr (&Sx_display_save_under);
5957 defsubr (&Sx_wm_set_size_hint);
5958 defsubr (&Sx_create_frame);
5959 defsubr (&Sx_open_connection);
5960 defsubr (&Sx_close_connection);
5961 defsubr (&Sx_display_list);
5962 defsubr (&Sx_synchronize);
5963 defsubr (&Sx_focus_frame);
5964 defsubr (&Sx_backspace_delete_keys_p);
5966 /* Setting callback functions for fontset handler. */
5967 check_window_system_func = check_x;
5969 defsubr (&Sx_show_tip);
5970 defsubr (&Sx_hide_tip);
5971 tip_timer = Qnil;
5972 staticpro (&tip_timer);
5973 tip_frame = Qnil;
5974 staticpro (&tip_frame);
5976 last_show_tip_args = Qnil;
5977 staticpro (&last_show_tip_args);
5979 defsubr (&Sx_uses_old_gtk_dialog);
5980 #if defined (USE_MOTIF) || defined (USE_GTK)
5981 defsubr (&Sx_file_dialog);
5982 #endif
5984 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
5985 defsubr (&Sx_select_font);
5986 #endif
5989 #endif /* HAVE_X_WINDOWS */