* org.texi: Fix typo in previous change (2010-07-19T09:47:27Z!carsten.dominik@gmail...
[emacs.git] / src / xfns.c
blobee020371683df69d41a5588c4f282cf6b65adf17
1 /* Functions for the X window system.
2 Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 #include <config.h>
22 #include <stdio.h>
23 #include <math.h>
24 #include <setjmp.h>
25 #include <ctype.h>
27 #ifdef HAVE_UNISTD_H
28 #include <unistd.h>
29 #endif
31 /* This makes the fields of a Display accessible, in Xlib header files. */
33 #define XLIB_ILLEGAL_ACCESS
35 #include "lisp.h"
36 #include "xterm.h"
37 #include "frame.h"
38 #include "window.h"
39 #include "buffer.h"
40 #include "intervals.h"
41 #include "dispextern.h"
42 #include "keyboard.h"
43 #include "blockinput.h"
44 #include <epaths.h>
45 #include "character.h"
46 #include "charset.h"
47 #include "coding.h"
48 #include "fontset.h"
49 #include "systime.h"
50 #include "termhooks.h"
51 #include "atimer.h"
52 #include "termchar.h"
53 #include "font.h"
55 #ifdef HAVE_X_WINDOWS
57 #include <ctype.h>
58 #include <sys/types.h>
59 #include <sys/stat.h>
61 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */
62 #include "bitmaps/gray.xbm"
63 #else
64 #include <X11/bitmaps/gray>
65 #endif
67 #include "xsettings.h"
69 #ifdef USE_GTK
70 #include "gtkutil.h"
71 #endif
73 #ifdef USE_X_TOOLKIT
74 #include <X11/Shell.h>
76 #ifndef USE_MOTIF
77 #ifdef HAVE_XAW3D
78 #include <X11/Xaw3d/Paned.h>
79 #include <X11/Xaw3d/Label.h>
80 #else /* !HAVE_XAW3D */
81 #include <X11/Xaw/Paned.h>
82 #include <X11/Xaw/Label.h>
83 #endif /* HAVE_XAW3D */
84 #endif /* USE_MOTIF */
86 #ifdef USG
87 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
88 #include <X11/Xos.h>
89 #define USG
90 #else
91 #include <X11/Xos.h>
92 #endif
94 #include "widget.h"
96 #include "../lwlib/lwlib.h"
98 #ifdef USE_MOTIF
99 #include <Xm/Xm.h>
100 #include <Xm/DialogS.h>
101 #include <Xm/FileSB.h>
102 #endif
104 #if !defined(NO_EDITRES)
105 #define HACK_EDITRES
106 extern void _XEditResCheckMessages ();
107 #endif /* not defined NO_EDITRES */
109 /* Unique id counter for widgets created by the Lucid Widget Library. */
111 extern LWLIB_ID widget_id_tick;
113 extern void free_frame_menubar ();
114 extern double atof ();
116 #ifdef USE_MOTIF
118 /* LessTif/Motif version info. */
120 static Lisp_Object Vmotif_version_string;
122 #endif /* USE_MOTIF */
124 #endif /* USE_X_TOOLKIT */
126 #ifdef USE_GTK
128 /* GTK+ version info */
130 static Lisp_Object Vgtk_version_string;
132 #endif /* USE_GTK */
134 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
136 /* The gray bitmap `bitmaps/gray'. This is done because xterm.c uses
137 it, and including `bitmaps/gray' more than once is a problem when
138 config.h defines `static' as an empty replacement string. */
140 int gray_bitmap_width = gray_width;
141 int gray_bitmap_height = gray_height;
142 char *gray_bitmap_bits = gray_bits;
144 /* Non-zero means prompt with the old GTK file selection dialog. */
146 int x_gtk_use_old_file_dialog;
148 /* If non-zero, by default show hidden files in the GTK file chooser. */
150 int x_gtk_show_hidden_files;
152 /* If non-zero, don't show additional help text in the GTK file chooser. */
154 int x_gtk_file_dialog_help_text;
156 /* If non-zero, don't collapse to tool bar when it is detached. */
158 int x_gtk_whole_detached_tool_bar;
160 /* The background and shape of the mouse pointer, and shape when not
161 over text or in the modeline. */
163 Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
164 Lisp_Object Vx_hourglass_pointer_shape;
166 /* The shape when over mouse-sensitive text. */
168 Lisp_Object Vx_sensitive_text_pointer_shape;
170 /* If non-nil, the pointer shape to indicate that windows can be
171 dragged horizontally. */
173 Lisp_Object Vx_window_horizontal_drag_shape;
175 /* Color of chars displayed in cursor box. */
177 Lisp_Object Vx_cursor_fore_pixel;
179 /* Nonzero if using X. */
181 static int x_in_use;
183 /* Non nil if no window manager is in use. */
185 Lisp_Object Vx_no_window_manager;
187 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
189 Lisp_Object Vx_pixel_size_width_font_regexp;
191 Lisp_Object Qnone;
192 Lisp_Object Qsuppress_icon;
193 Lisp_Object Qundefined_color;
194 Lisp_Object Qcompound_text, Qcancel_timer;
195 Lisp_Object Qfont_param;
197 /* In dispnew.c */
199 extern Lisp_Object Vwindow_system_version;
201 /* In editfns.c */
203 extern Lisp_Object Vsystem_name;
205 /* The below are defined in frame.c. */
207 extern Lisp_Object Vmenu_bar_mode, Vtool_bar_mode;
208 extern Lisp_Object Qtooltip;
210 #if GLYPH_DEBUG
211 int image_cache_refcount, dpyinfo_refcount;
212 #endif
214 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
215 char *x_last_font_name;
216 #endif
219 /* Error if we are not connected to X. */
221 void
222 check_x (void)
224 if (! x_in_use)
225 error ("X windows are not in use or not initialized");
228 /* Nonzero if we can use mouse menus.
229 You should not call this unless HAVE_MENUS is defined. */
232 have_menus_p (void)
234 return x_in_use;
237 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
238 and checking validity for X. */
240 FRAME_PTR
241 check_x_frame (Lisp_Object frame)
243 FRAME_PTR f;
245 if (NILP (frame))
246 frame = selected_frame;
247 CHECK_LIVE_FRAME (frame);
248 f = XFRAME (frame);
249 if (! FRAME_X_P (f))
250 error ("Non-X frame used");
251 return f;
254 /* Let the user specify an X display with a Lisp object.
255 OBJECT may be nil, a frame or a terminal object.
256 nil stands for the selected frame--or, if that is not an X frame,
257 the first X display on the list. */
259 struct x_display_info *
260 check_x_display_info (Lisp_Object object)
262 struct x_display_info *dpyinfo = NULL;
264 if (NILP (object))
266 struct frame *sf = XFRAME (selected_frame);
268 if (FRAME_X_P (sf) && FRAME_LIVE_P (sf))
269 dpyinfo = FRAME_X_DISPLAY_INFO (sf);
270 else if (x_display_list != 0)
271 dpyinfo = x_display_list;
272 else
273 error ("X windows are not in use or not initialized");
275 else if (TERMINALP (object))
277 struct terminal *t = get_terminal (object, 1);
279 if (t->type != output_x_window)
280 error ("Terminal %d is not an X display", XINT (object));
282 dpyinfo = t->display_info.x;
284 else if (STRINGP (object))
285 dpyinfo = x_display_info_for_name (object);
286 else
288 FRAME_PTR f = check_x_frame (object);
289 dpyinfo = FRAME_X_DISPLAY_INFO (f);
292 return dpyinfo;
296 /* Return the Emacs frame-object corresponding to an X window.
297 It could be the frame's main window or an icon window. */
299 /* This function can be called during GC, so use GC_xxx type test macros. */
301 struct frame *
302 x_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
304 Lisp_Object tail, frame;
305 struct frame *f;
307 if (wdesc == None) return 0;
309 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
311 frame = XCAR (tail);
312 if (!FRAMEP (frame))
313 continue;
314 f = XFRAME (frame);
315 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
316 continue;
317 if (f->output_data.x->hourglass_window == wdesc)
318 return f;
319 #ifdef USE_X_TOOLKIT
320 if ((f->output_data.x->edit_widget
321 && XtWindow (f->output_data.x->edit_widget) == wdesc)
322 /* A tooltip frame? */
323 || (!f->output_data.x->edit_widget
324 && FRAME_X_WINDOW (f) == wdesc)
325 || f->output_data.x->icon_desc == wdesc)
326 return f;
327 #else /* not USE_X_TOOLKIT */
328 #ifdef USE_GTK
329 if (f->output_data.x->edit_widget)
331 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
332 struct x_output *x = f->output_data.x;
333 if (gwdesc != 0 && gwdesc == x->edit_widget)
334 return f;
336 #endif /* USE_GTK */
337 if (FRAME_X_WINDOW (f) == wdesc
338 || f->output_data.x->icon_desc == wdesc)
339 return f;
340 #endif /* not USE_X_TOOLKIT */
342 return 0;
345 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
346 /* Like x_window_to_frame but also compares the window with the widget's
347 windows. */
349 struct frame *
350 x_any_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
352 Lisp_Object tail, frame;
353 struct frame *f, *found;
354 struct x_output *x;
356 if (wdesc == None) return NULL;
358 found = NULL;
359 for (tail = Vframe_list; CONSP (tail) && !found; tail = XCDR (tail))
361 frame = XCAR (tail);
362 if (!FRAMEP (frame))
363 continue;
365 f = XFRAME (frame);
366 if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) == dpyinfo)
368 /* This frame matches if the window is any of its widgets. */
369 x = f->output_data.x;
370 if (x->hourglass_window == wdesc)
371 found = f;
372 else if (x->widget)
374 #ifdef USE_GTK
375 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
376 if (gwdesc != 0
377 && gtk_widget_get_toplevel (gwdesc) == x->widget)
378 found = f;
379 #else
380 if (wdesc == XtWindow (x->widget)
381 || wdesc == XtWindow (x->column_widget)
382 || wdesc == XtWindow (x->edit_widget))
383 found = f;
384 /* Match if the window is this frame's menubar. */
385 else if (lw_window_is_in_menubar (wdesc, x->menubar_widget))
386 found = f;
387 #endif
389 else if (FRAME_X_WINDOW (f) == wdesc)
390 /* A tooltip frame. */
391 found = f;
395 return found;
398 /* Likewise, but consider only the menu bar widget. */
400 struct frame *
401 x_menubar_window_to_frame (struct x_display_info *dpyinfo, XEvent *event)
403 Window wdesc = event->xany.window;
404 Lisp_Object tail, frame;
405 struct frame *f;
406 struct x_output *x;
408 if (wdesc == None) return 0;
410 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
412 frame = XCAR (tail);
413 if (!FRAMEP (frame))
414 continue;
415 f = XFRAME (frame);
416 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
417 continue;
418 x = f->output_data.x;
419 #ifdef USE_GTK
420 if (x->menubar_widget && xg_event_is_for_menubar (f, event))
421 return f;
422 #else
423 /* Match if the window is this frame's menubar. */
424 if (x->menubar_widget
425 && lw_window_is_in_menubar (wdesc, x->menubar_widget))
426 return f;
427 #endif
429 return 0;
432 /* Return the frame whose principal (outermost) window is WDESC.
433 If WDESC is some other (smaller) window, we return 0. */
435 struct frame *
436 x_top_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
438 Lisp_Object tail, frame;
439 struct frame *f;
440 struct x_output *x;
442 if (wdesc == None) return 0;
444 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
446 frame = XCAR (tail);
447 if (!FRAMEP (frame))
448 continue;
449 f = XFRAME (frame);
450 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
451 continue;
452 x = f->output_data.x;
454 if (x->widget)
456 /* This frame matches if the window is its topmost widget. */
457 #ifdef USE_GTK
458 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
459 if (gwdesc == x->widget)
460 return f;
461 #else
462 if (wdesc == XtWindow (x->widget))
463 return f;
464 #if 0 /* I don't know why it did this,
465 but it seems logically wrong,
466 and it causes trouble for MapNotify events. */
467 /* Match if the window is this frame's menubar. */
468 if (x->menubar_widget
469 && wdesc == XtWindow (x->menubar_widget))
470 return f;
471 #endif
472 #endif
474 else if (FRAME_X_WINDOW (f) == wdesc)
475 /* Tooltip frame. */
476 return f;
478 return 0;
480 #endif /* USE_X_TOOLKIT || USE_GTK */
484 static void x_default_font_parameter (struct frame *, Lisp_Object);
486 static Lisp_Object unwind_create_frame (Lisp_Object);
487 static Lisp_Object unwind_create_tip_frame (Lisp_Object);
489 void x_set_foreground_color (struct frame *, Lisp_Object, Lisp_Object);
490 static void x_set_wait_for_wm (struct frame *, Lisp_Object, Lisp_Object);
491 void x_set_background_color (struct frame *, Lisp_Object, Lisp_Object);
492 void x_set_mouse_color (struct frame *, Lisp_Object, Lisp_Object);
493 void x_set_cursor_color (struct frame *, Lisp_Object, Lisp_Object);
494 void x_set_border_color (struct frame *, Lisp_Object, Lisp_Object);
495 void x_set_cursor_type (struct frame *, Lisp_Object, Lisp_Object);
496 void x_set_icon_type (struct frame *, Lisp_Object, Lisp_Object);
497 void x_set_icon_name (struct frame *, Lisp_Object, Lisp_Object);
498 void x_explicitly_set_name (struct frame *, Lisp_Object, Lisp_Object);
499 void x_set_menu_bar_lines (struct frame *, Lisp_Object, Lisp_Object);
500 void x_set_title (struct frame *, Lisp_Object, Lisp_Object);
501 void x_set_tool_bar_lines (struct frame *, Lisp_Object, Lisp_Object);
502 void x_set_scroll_bar_foreground (struct frame *, Lisp_Object,
503 Lisp_Object);
504 void x_set_scroll_bar_background (struct frame *, Lisp_Object,
505 Lisp_Object);
506 static Lisp_Object x_default_scroll_bar_color_parameter (struct frame *,
507 Lisp_Object,
508 Lisp_Object,
509 char *, char *,
510 int);
513 /* Store the screen positions of frame F into XPTR and YPTR.
514 These are the positions of the containing window manager window,
515 not Emacs's own window. */
517 void
518 x_real_positions (FRAME_PTR f, int *xptr, int *yptr)
520 int win_x, win_y, outer_x, outer_y;
521 int real_x = 0, real_y = 0;
522 int had_errors = 0;
523 Window win = f->output_data.x->parent_desc;
525 BLOCK_INPUT;
527 x_catch_errors (FRAME_X_DISPLAY (f));
529 if (win == FRAME_X_DISPLAY_INFO (f)->root_window)
530 win = FRAME_OUTER_WINDOW (f);
532 /* This loop traverses up the containment tree until we hit the root
533 window. Window managers may intersect many windows between our window
534 and the root window. The window we find just before the root window
535 should be the outer WM window. */
536 for (;;)
538 Window wm_window, rootw;
539 Window *tmp_children;
540 unsigned int tmp_nchildren;
541 int success;
543 success = XQueryTree (FRAME_X_DISPLAY (f), win, &rootw,
544 &wm_window, &tmp_children, &tmp_nchildren);
546 had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
548 /* Don't free tmp_children if XQueryTree failed. */
549 if (! success)
550 break;
552 XFree ((char *) tmp_children);
554 if (wm_window == rootw || had_errors)
555 break;
557 win = wm_window;
560 if (! had_errors)
562 unsigned int ign;
563 Window child, rootw;
565 /* Get the real coordinates for the WM window upper left corner */
566 XGetGeometry (FRAME_X_DISPLAY (f), win,
567 &rootw, &real_x, &real_y, &ign, &ign, &ign, &ign);
569 /* Translate real coordinates to coordinates relative to our
570 window. For our window, the upper left corner is 0, 0.
571 Since the upper left corner of the WM window is outside
572 our window, win_x and win_y will be negative:
574 ------------------ ---> x
575 | title |
576 | ----------------- v y
577 | | our window
579 XTranslateCoordinates (FRAME_X_DISPLAY (f),
581 /* From-window, to-window. */
582 FRAME_X_DISPLAY_INFO (f)->root_window,
583 FRAME_X_WINDOW (f),
585 /* From-position, to-position. */
586 real_x, real_y, &win_x, &win_y,
588 /* Child of win. */
589 &child);
591 if (FRAME_X_WINDOW (f) == FRAME_OUTER_WINDOW (f))
593 outer_x = win_x;
594 outer_y = win_y;
596 else
598 XTranslateCoordinates (FRAME_X_DISPLAY (f),
600 /* From-window, to-window. */
601 FRAME_X_DISPLAY_INFO (f)->root_window,
602 FRAME_OUTER_WINDOW (f),
604 /* From-position, to-position. */
605 real_x, real_y, &outer_x, &outer_y,
607 /* Child of win. */
608 &child);
611 had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
614 x_uncatch_errors ();
616 UNBLOCK_INPUT;
618 if (had_errors) return;
620 f->x_pixels_diff = -win_x;
621 f->y_pixels_diff = -win_y;
623 FRAME_X_OUTPUT (f)->x_pixels_outer_diff = -outer_x;
624 FRAME_X_OUTPUT (f)->y_pixels_outer_diff = -outer_y;
626 *xptr = real_x;
627 *yptr = real_y;
633 /* Gamma-correct COLOR on frame F. */
635 void
636 gamma_correct (struct frame *f, XColor *color)
638 if (f->gamma)
640 color->red = pow (color->red / 65535.0, f->gamma) * 65535.0 + 0.5;
641 color->green = pow (color->green / 65535.0, f->gamma) * 65535.0 + 0.5;
642 color->blue = pow (color->blue / 65535.0, f->gamma) * 65535.0 + 0.5;
647 /* Decide if color named COLOR_NAME is valid for use on frame F. If
648 so, return the RGB values in COLOR. If ALLOC_P is non-zero,
649 allocate the color. Value is zero if COLOR_NAME is invalid, or
650 no color could be allocated. */
653 x_defined_color (struct frame *f, char *color_name, XColor *color, int alloc_p)
655 int success_p;
656 Display *dpy = FRAME_X_DISPLAY (f);
657 Colormap cmap = FRAME_X_COLORMAP (f);
659 BLOCK_INPUT;
660 success_p = XParseColor (dpy, cmap, color_name, color);
661 if (success_p && alloc_p)
662 success_p = x_alloc_nearest_color (f, cmap, color);
663 UNBLOCK_INPUT;
665 return success_p;
669 /* Return the pixel color value for color COLOR_NAME on frame F. If F
670 is a monochrome frame, return MONO_COLOR regardless of what ARG says.
671 Signal an error if color can't be allocated. */
674 x_decode_color (FRAME_PTR f, Lisp_Object color_name, int mono_color)
676 XColor cdef;
678 CHECK_STRING (color_name);
680 #if 0 /* Don't do this. It's wrong when we're not using the default
681 colormap, it makes freeing difficult, and it's probably not
682 an important optimization. */
683 if (strcmp (SDATA (color_name), "black") == 0)
684 return BLACK_PIX_DEFAULT (f);
685 else if (strcmp (SDATA (color_name), "white") == 0)
686 return WHITE_PIX_DEFAULT (f);
687 #endif
689 /* Return MONO_COLOR for monochrome frames. */
690 if (FRAME_X_DISPLAY_INFO (f)->n_planes == 1)
691 return mono_color;
693 /* x_defined_color is responsible for coping with failures
694 by looking for a near-miss. */
695 if (x_defined_color (f, SDATA (color_name), &cdef, 1))
696 return cdef.pixel;
698 signal_error ("Undefined color", color_name);
703 /* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
704 the previous value of that parameter, NEW_VALUE is the new value.
705 See also the comment of wait_for_wm in struct x_output. */
707 static void
708 x_set_wait_for_wm (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
710 f->output_data.x->wait_for_wm = !NILP (new_value);
713 #ifdef USE_GTK
715 /* Set icon from FILE for frame F. By using GTK functions the icon
716 may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
719 xg_set_icon (FRAME_PTR f, Lisp_Object file)
721 int result = 0;
722 Lisp_Object found;
724 found = x_find_image_file (file);
726 if (! NILP (found))
728 GdkPixbuf *pixbuf;
729 GError *err = NULL;
730 char *filename = (char *) SDATA (found);
731 BLOCK_INPUT;
733 pixbuf = gdk_pixbuf_new_from_file (filename, &err);
735 if (pixbuf)
737 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
738 pixbuf);
739 g_object_unref (pixbuf);
741 result = 1;
743 else
744 g_error_free (err);
746 UNBLOCK_INPUT;
749 return result;
753 xg_set_icon_from_xpm_data (FRAME_PTR f, char **data)
755 int result = 0;
756 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) data);
758 if (!pixbuf)
759 return 0;
761 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), pixbuf);
762 g_object_unref (pixbuf);
763 return 1;
765 #endif /* USE_GTK */
768 /* Functions called only from `x_set_frame_param'
769 to set individual parameters.
771 If FRAME_X_WINDOW (f) is 0,
772 the frame is being created and its X-window does not exist yet.
773 In that case, just record the parameter's new value
774 in the standard place; do not attempt to change the window. */
776 void
777 x_set_foreground_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
779 struct x_output *x = f->output_data.x;
780 unsigned long fg, old_fg;
782 fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
783 old_fg = FRAME_FOREGROUND_PIXEL (f);
784 FRAME_FOREGROUND_PIXEL (f) = fg;
786 if (FRAME_X_WINDOW (f) != 0)
788 Display *dpy = FRAME_X_DISPLAY (f);
790 BLOCK_INPUT;
791 XSetForeground (dpy, x->normal_gc, fg);
792 XSetBackground (dpy, x->reverse_gc, fg);
794 if (x->cursor_pixel == old_fg)
796 unload_color (f, x->cursor_pixel);
797 x->cursor_pixel = x_copy_color (f, fg);
798 XSetBackground (dpy, x->cursor_gc, x->cursor_pixel);
801 UNBLOCK_INPUT;
803 update_face_from_frame_parameter (f, Qforeground_color, arg);
805 if (FRAME_VISIBLE_P (f))
806 redraw_frame (f);
809 unload_color (f, old_fg);
812 void
813 x_set_background_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
815 struct x_output *x = f->output_data.x;
816 unsigned long bg;
818 bg = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
819 unload_color (f, FRAME_BACKGROUND_PIXEL (f));
820 FRAME_BACKGROUND_PIXEL (f) = bg;
822 if (FRAME_X_WINDOW (f) != 0)
824 Display *dpy = FRAME_X_DISPLAY (f);
826 BLOCK_INPUT;
827 XSetBackground (dpy, x->normal_gc, bg);
828 XSetForeground (dpy, x->reverse_gc, bg);
829 XSetWindowBackground (dpy, FRAME_X_WINDOW (f), bg);
830 XSetForeground (dpy, x->cursor_gc, bg);
832 #ifdef USE_GTK
833 xg_set_background_color (f, bg);
834 #endif
836 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
837 toolkit scroll bars. */
839 Lisp_Object bar;
840 for (bar = FRAME_SCROLL_BARS (f);
841 !NILP (bar);
842 bar = XSCROLL_BAR (bar)->next)
844 Window window = XSCROLL_BAR (bar)->x_window;
845 XSetWindowBackground (dpy, window, bg);
848 #endif /* USE_TOOLKIT_SCROLL_BARS */
850 UNBLOCK_INPUT;
851 update_face_from_frame_parameter (f, Qbackground_color, arg);
853 if (FRAME_VISIBLE_P (f))
854 redraw_frame (f);
858 static Cursor
859 make_invisible_cursor (struct frame *f)
861 Display *dpy = FRAME_X_DISPLAY (f);
862 static char const no_data[] = { 0 };
863 Pixmap pix;
864 XColor col;
865 Cursor c;
867 x_catch_errors (dpy);
868 pix = XCreateBitmapFromData (dpy, FRAME_X_DISPLAY_INFO (f)->root_window,
869 no_data, 1, 1);
870 if (! x_had_errors_p (dpy) && pix != None)
872 col.pixel = 0;
873 col.red = col.green = col.blue = 0;
874 col.flags = DoRed | DoGreen | DoBlue;
875 c = XCreatePixmapCursor (dpy, pix, pix, &col, &col, 0, 0);
876 if (x_had_errors_p (dpy) || c == None)
877 c = 0;
878 XFreePixmap (dpy, pix);
881 x_uncatch_errors ();
883 return c;
886 void
887 x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
889 struct x_output *x = f->output_data.x;
890 Display *dpy = FRAME_X_DISPLAY (f);
891 Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
892 Cursor hourglass_cursor, horizontal_drag_cursor;
893 unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
894 unsigned long mask_color = FRAME_BACKGROUND_PIXEL (f);
896 /* Don't let pointers be invisible. */
897 if (mask_color == pixel)
899 x_free_colors (f, &pixel, 1);
900 pixel = x_copy_color (f, FRAME_FOREGROUND_PIXEL (f));
903 unload_color (f, x->mouse_pixel);
904 x->mouse_pixel = pixel;
906 BLOCK_INPUT;
908 /* It's not okay to crash if the user selects a screwy cursor. */
909 x_catch_errors (dpy);
911 if (!NILP (Vx_pointer_shape))
913 CHECK_NUMBER (Vx_pointer_shape);
914 cursor = XCreateFontCursor (dpy, XINT (Vx_pointer_shape));
916 else
917 cursor = XCreateFontCursor (dpy, XC_xterm);
918 x_check_errors (dpy, "bad text pointer cursor: %s");
920 if (!NILP (Vx_nontext_pointer_shape))
922 CHECK_NUMBER (Vx_nontext_pointer_shape);
923 nontext_cursor
924 = XCreateFontCursor (dpy, XINT (Vx_nontext_pointer_shape));
926 else
927 nontext_cursor = XCreateFontCursor (dpy, XC_left_ptr);
928 x_check_errors (dpy, "bad nontext pointer cursor: %s");
930 if (!NILP (Vx_hourglass_pointer_shape))
932 CHECK_NUMBER (Vx_hourglass_pointer_shape);
933 hourglass_cursor
934 = XCreateFontCursor (dpy, XINT (Vx_hourglass_pointer_shape));
936 else
937 hourglass_cursor = XCreateFontCursor (dpy, XC_watch);
938 x_check_errors (dpy, "bad hourglass pointer cursor: %s");
940 if (!NILP (Vx_mode_pointer_shape))
942 CHECK_NUMBER (Vx_mode_pointer_shape);
943 mode_cursor = XCreateFontCursor (dpy, XINT (Vx_mode_pointer_shape));
945 else
946 mode_cursor = XCreateFontCursor (dpy, XC_xterm);
947 x_check_errors (dpy, "bad modeline pointer cursor: %s");
949 if (!NILP (Vx_sensitive_text_pointer_shape))
951 CHECK_NUMBER (Vx_sensitive_text_pointer_shape);
952 hand_cursor
953 = XCreateFontCursor (dpy, XINT (Vx_sensitive_text_pointer_shape));
955 else
956 hand_cursor = XCreateFontCursor (dpy, XC_hand2);
958 if (!NILP (Vx_window_horizontal_drag_shape))
960 CHECK_NUMBER (Vx_window_horizontal_drag_shape);
961 horizontal_drag_cursor
962 = XCreateFontCursor (dpy, XINT (Vx_window_horizontal_drag_shape));
964 else
965 horizontal_drag_cursor
966 = XCreateFontCursor (dpy, XC_sb_h_double_arrow);
968 /* Check and report errors with the above calls. */
969 x_check_errors (dpy, "can't set cursor shape: %s");
970 x_uncatch_errors ();
973 XColor fore_color, back_color;
975 fore_color.pixel = x->mouse_pixel;
976 x_query_color (f, &fore_color);
977 back_color.pixel = mask_color;
978 x_query_color (f, &back_color);
980 XRecolorCursor (dpy, cursor, &fore_color, &back_color);
981 XRecolorCursor (dpy, nontext_cursor, &fore_color, &back_color);
982 XRecolorCursor (dpy, mode_cursor, &fore_color, &back_color);
983 XRecolorCursor (dpy, hand_cursor, &fore_color, &back_color);
984 XRecolorCursor (dpy, hourglass_cursor, &fore_color, &back_color);
985 XRecolorCursor (dpy, horizontal_drag_cursor, &fore_color, &back_color);
988 if (FRAME_X_WINDOW (f) != 0)
989 XDefineCursor (dpy, FRAME_X_WINDOW (f),
990 f->output_data.x->current_cursor = cursor);
992 if (FRAME_X_DISPLAY_INFO (f)->invisible_cursor == 0)
993 FRAME_X_DISPLAY_INFO (f)->invisible_cursor = make_invisible_cursor (f);
995 if (cursor != x->text_cursor
996 && x->text_cursor != 0)
997 XFreeCursor (dpy, x->text_cursor);
998 x->text_cursor = cursor;
1000 if (nontext_cursor != x->nontext_cursor
1001 && x->nontext_cursor != 0)
1002 XFreeCursor (dpy, x->nontext_cursor);
1003 x->nontext_cursor = nontext_cursor;
1005 if (hourglass_cursor != x->hourglass_cursor
1006 && x->hourglass_cursor != 0)
1007 XFreeCursor (dpy, x->hourglass_cursor);
1008 x->hourglass_cursor = hourglass_cursor;
1010 if (mode_cursor != x->modeline_cursor
1011 && x->modeline_cursor != 0)
1012 XFreeCursor (dpy, f->output_data.x->modeline_cursor);
1013 x->modeline_cursor = mode_cursor;
1015 if (hand_cursor != x->hand_cursor
1016 && x->hand_cursor != 0)
1017 XFreeCursor (dpy, x->hand_cursor);
1018 x->hand_cursor = hand_cursor;
1020 if (horizontal_drag_cursor != x->horizontal_drag_cursor
1021 && x->horizontal_drag_cursor != 0)
1022 XFreeCursor (dpy, x->horizontal_drag_cursor);
1023 x->horizontal_drag_cursor = horizontal_drag_cursor;
1025 XFlush (dpy);
1026 UNBLOCK_INPUT;
1028 update_face_from_frame_parameter (f, Qmouse_color, arg);
1031 void
1032 x_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1034 unsigned long fore_pixel, pixel;
1035 int fore_pixel_allocated_p = 0, pixel_allocated_p = 0;
1036 struct x_output *x = f->output_data.x;
1038 if (!NILP (Vx_cursor_fore_pixel))
1040 fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
1041 WHITE_PIX_DEFAULT (f));
1042 fore_pixel_allocated_p = 1;
1044 else
1045 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1047 pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1048 pixel_allocated_p = 1;
1050 /* Make sure that the cursor color differs from the background color. */
1051 if (pixel == FRAME_BACKGROUND_PIXEL (f))
1053 if (pixel_allocated_p)
1055 x_free_colors (f, &pixel, 1);
1056 pixel_allocated_p = 0;
1059 pixel = x->mouse_pixel;
1060 if (pixel == fore_pixel)
1062 if (fore_pixel_allocated_p)
1064 x_free_colors (f, &fore_pixel, 1);
1065 fore_pixel_allocated_p = 0;
1067 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1071 unload_color (f, x->cursor_foreground_pixel);
1072 if (!fore_pixel_allocated_p)
1073 fore_pixel = x_copy_color (f, fore_pixel);
1074 x->cursor_foreground_pixel = fore_pixel;
1076 unload_color (f, x->cursor_pixel);
1077 if (!pixel_allocated_p)
1078 pixel = x_copy_color (f, pixel);
1079 x->cursor_pixel = pixel;
1081 if (FRAME_X_WINDOW (f) != 0)
1083 BLOCK_INPUT;
1084 XSetBackground (FRAME_X_DISPLAY (f), x->cursor_gc, x->cursor_pixel);
1085 XSetForeground (FRAME_X_DISPLAY (f), x->cursor_gc, fore_pixel);
1086 UNBLOCK_INPUT;
1088 if (FRAME_VISIBLE_P (f))
1090 x_update_cursor (f, 0);
1091 x_update_cursor (f, 1);
1095 update_face_from_frame_parameter (f, Qcursor_color, arg);
1098 /* Set the border-color of frame F to pixel value PIX.
1099 Note that this does not fully take effect if done before
1100 F has an x-window. */
1102 void
1103 x_set_border_pixel (struct frame *f, int pix)
1105 unload_color (f, f->output_data.x->border_pixel);
1106 f->output_data.x->border_pixel = pix;
1108 if (FRAME_X_WINDOW (f) != 0 && f->border_width > 0)
1110 BLOCK_INPUT;
1111 XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1112 (unsigned long)pix);
1113 UNBLOCK_INPUT;
1115 if (FRAME_VISIBLE_P (f))
1116 redraw_frame (f);
1120 /* Set the border-color of frame F to value described by ARG.
1121 ARG can be a string naming a color.
1122 The border-color is used for the border that is drawn by the X server.
1123 Note that this does not fully take effect if done before
1124 F has an x-window; it must be redone when the window is created.
1126 Note: this is done in two routines because of the way X10 works.
1128 Note: under X11, this is normally the province of the window manager,
1129 and so emacs' border colors may be overridden. */
1131 void
1132 x_set_border_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1134 int pix;
1136 CHECK_STRING (arg);
1137 pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1138 x_set_border_pixel (f, pix);
1139 update_face_from_frame_parameter (f, Qborder_color, arg);
1143 void
1144 x_set_cursor_type (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
1146 set_frame_cursor_types (f, arg);
1148 /* Make sure the cursor gets redrawn. */
1149 cursor_type_changed = 1;
1152 void
1153 x_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1155 int result;
1157 if (STRINGP (arg))
1159 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1160 return;
1162 else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
1163 return;
1165 BLOCK_INPUT;
1166 if (NILP (arg))
1167 result = x_text_icon (f,
1168 (char *) SDATA ((!NILP (f->icon_name)
1169 ? f->icon_name
1170 : f->name)));
1171 else
1172 result = x_bitmap_icon (f, arg);
1174 if (result)
1176 UNBLOCK_INPUT;
1177 error ("No icon window available");
1180 XFlush (FRAME_X_DISPLAY (f));
1181 UNBLOCK_INPUT;
1184 void
1185 x_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1187 int result;
1189 if (STRINGP (arg))
1191 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1192 return;
1194 else if (!NILP (arg) || NILP (oldval))
1195 return;
1197 f->icon_name = arg;
1199 if (f->output_data.x->icon_bitmap != 0)
1200 return;
1202 BLOCK_INPUT;
1204 result = x_text_icon (f,
1205 (char *) SDATA ((!NILP (f->icon_name)
1206 ? f->icon_name
1207 : !NILP (f->title)
1208 ? f->title
1209 : f->name)));
1211 if (result)
1213 UNBLOCK_INPUT;
1214 error ("No icon window available");
1217 XFlush (FRAME_X_DISPLAY (f));
1218 UNBLOCK_INPUT;
1222 void
1223 x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1225 int nlines;
1226 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
1227 int olines = FRAME_MENU_BAR_LINES (f);
1228 #endif
1230 /* Right now, menu bars don't work properly in minibuf-only frames;
1231 most of the commands try to apply themselves to the minibuffer
1232 frame itself, and get an error because you can't switch buffers
1233 in or split the minibuffer window. */
1234 if (FRAME_MINIBUF_ONLY_P (f))
1235 return;
1237 if (INTEGERP (value))
1238 nlines = XINT (value);
1239 else
1240 nlines = 0;
1242 /* Make sure we redisplay all windows in this frame. */
1243 windows_or_buffers_changed++;
1245 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1246 FRAME_MENU_BAR_LINES (f) = 0;
1247 if (nlines)
1249 FRAME_EXTERNAL_MENU_BAR (f) = 1;
1250 if (FRAME_X_P (f) && f->output_data.x->menubar_widget == 0)
1251 /* Make sure next redisplay shows the menu bar. */
1252 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
1254 else
1256 if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
1257 free_frame_menubar (f);
1258 FRAME_EXTERNAL_MENU_BAR (f) = 0;
1259 if (FRAME_X_P (f))
1260 f->output_data.x->menubar_widget = 0;
1262 #else /* not USE_X_TOOLKIT && not USE_GTK */
1263 FRAME_MENU_BAR_LINES (f) = nlines;
1264 change_window_heights (f->root_window, nlines - olines);
1266 /* If the menu bar height gets changed, the internal border below
1267 the top margin has to be cleared. Also, if the menu bar gets
1268 larger, the area for the added lines has to be cleared except for
1269 the first menu bar line that is to be drawn later. */
1270 if (nlines != olines)
1272 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1273 int width = FRAME_PIXEL_WIDTH (f);
1274 int y;
1276 /* height can be zero here. */
1277 if (height > 0 && width > 0)
1279 y = FRAME_TOP_MARGIN_HEIGHT (f);
1281 BLOCK_INPUT;
1282 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1283 0, y, width, height, False);
1284 UNBLOCK_INPUT;
1287 if (nlines > 1 && nlines > olines)
1289 y = (olines == 0 ? 1 : olines) * FRAME_LINE_HEIGHT (f);
1290 height = nlines * FRAME_LINE_HEIGHT (f) - y;
1292 BLOCK_INPUT;
1293 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1294 0, y, width, height, False);
1295 UNBLOCK_INPUT;
1298 if (nlines == 0 && WINDOWP (f->menu_bar_window))
1299 clear_glyph_matrix (XWINDOW (f->menu_bar_window)->current_matrix);
1301 #endif /* not USE_X_TOOLKIT && not USE_GTK */
1302 adjust_glyphs (f);
1306 /* Set the number of lines used for the tool bar of frame F to VALUE.
1307 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1308 is the old number of tool bar lines. This function changes the
1309 height of all windows on frame F to match the new tool bar height.
1310 The frame's height doesn't change. */
1312 void
1313 x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1315 int delta, nlines, root_height;
1316 Lisp_Object root_window;
1318 /* Treat tool bars like menu bars. */
1319 if (FRAME_MINIBUF_ONLY_P (f))
1320 return;
1322 /* Use VALUE only if an integer >= 0. */
1323 if (INTEGERP (value) && XINT (value) >= 0)
1324 nlines = XFASTINT (value);
1325 else
1326 nlines = 0;
1328 #ifdef USE_GTK
1329 FRAME_TOOL_BAR_LINES (f) = 0;
1330 if (nlines)
1332 FRAME_EXTERNAL_TOOL_BAR (f) = 1;
1333 if (FRAME_X_P (f) && f->output_data.x->toolbar_widget == 0)
1334 /* Make sure next redisplay shows the tool bar. */
1335 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
1336 update_frame_tool_bar (f);
1338 else
1340 if (FRAME_EXTERNAL_TOOL_BAR (f))
1341 free_frame_tool_bar (f);
1342 FRAME_EXTERNAL_TOOL_BAR (f) = 0;
1345 return;
1346 #endif
1348 /* Make sure we redisplay all windows in this frame. */
1349 ++windows_or_buffers_changed;
1351 delta = nlines - FRAME_TOOL_BAR_LINES (f);
1353 /* Don't resize the tool-bar to more than we have room for. */
1354 root_window = FRAME_ROOT_WINDOW (f);
1355 root_height = WINDOW_TOTAL_LINES (XWINDOW (root_window));
1356 if (root_height - delta < 1)
1358 delta = root_height - 1;
1359 nlines = FRAME_TOOL_BAR_LINES (f) + delta;
1362 FRAME_TOOL_BAR_LINES (f) = nlines;
1363 change_window_heights (root_window, delta);
1364 adjust_glyphs (f);
1366 /* We also have to make sure that the internal border at the top of
1367 the frame, below the menu bar or tool bar, is redrawn when the
1368 tool bar disappears. This is so because the internal border is
1369 below the tool bar if one is displayed, but is below the menu bar
1370 if there isn't a tool bar. The tool bar draws into the area
1371 below the menu bar. */
1372 if (FRAME_X_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0)
1374 clear_frame (f);
1375 clear_current_matrices (f);
1378 /* If the tool bar gets smaller, the internal border below it
1379 has to be cleared. It was formerly part of the display
1380 of the larger tool bar, and updating windows won't clear it. */
1381 if (delta < 0)
1383 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1384 int width = FRAME_PIXEL_WIDTH (f);
1385 int y = (FRAME_MENU_BAR_LINES (f) + nlines) * FRAME_LINE_HEIGHT (f);
1387 /* height can be zero here. */
1388 if (height > 0 && width > 0)
1390 BLOCK_INPUT;
1391 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1392 0, y, width, height, False);
1393 UNBLOCK_INPUT;
1396 if (WINDOWP (f->tool_bar_window))
1397 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1402 /* Set the foreground color for scroll bars on frame F to VALUE.
1403 VALUE should be a string, a color name. If it isn't a string or
1404 isn't a valid color name, do nothing. OLDVAL is the old value of
1405 the frame parameter. */
1407 void
1408 x_set_scroll_bar_foreground (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1410 unsigned long pixel;
1412 if (STRINGP (value))
1413 pixel = x_decode_color (f, value, BLACK_PIX_DEFAULT (f));
1414 else
1415 pixel = -1;
1417 if (f->output_data.x->scroll_bar_foreground_pixel != -1)
1418 unload_color (f, f->output_data.x->scroll_bar_foreground_pixel);
1420 f->output_data.x->scroll_bar_foreground_pixel = pixel;
1421 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1423 /* Remove all scroll bars because they have wrong colors. */
1424 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1425 (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1426 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1427 (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1429 update_face_from_frame_parameter (f, Qscroll_bar_foreground, value);
1430 redraw_frame (f);
1435 /* Set the background color for scroll bars on frame F to VALUE VALUE
1436 should be a string, a color name. If it isn't a string or isn't a
1437 valid color name, do nothing. OLDVAL is the old value of the frame
1438 parameter. */
1440 void
1441 x_set_scroll_bar_background (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1443 unsigned long pixel;
1445 if (STRINGP (value))
1446 pixel = x_decode_color (f, value, WHITE_PIX_DEFAULT (f));
1447 else
1448 pixel = -1;
1450 if (f->output_data.x->scroll_bar_background_pixel != -1)
1451 unload_color (f, f->output_data.x->scroll_bar_background_pixel);
1453 #ifdef USE_TOOLKIT_SCROLL_BARS
1454 /* Scrollbar shadow colors. */
1455 if (f->output_data.x->scroll_bar_top_shadow_pixel != -1)
1457 unload_color (f, f->output_data.x->scroll_bar_top_shadow_pixel);
1458 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
1460 if (f->output_data.x->scroll_bar_bottom_shadow_pixel != -1)
1462 unload_color (f, f->output_data.x->scroll_bar_bottom_shadow_pixel);
1463 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
1465 #endif /* USE_TOOLKIT_SCROLL_BARS */
1467 f->output_data.x->scroll_bar_background_pixel = pixel;
1468 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1470 /* Remove all scroll bars because they have wrong colors. */
1471 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1472 (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1473 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1474 (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1476 update_face_from_frame_parameter (f, Qscroll_bar_background, value);
1477 redraw_frame (f);
1482 /* Encode Lisp string STRING as a text in a format appropriate for
1483 XICCC (X Inter Client Communication Conventions).
1485 This can call Lisp code, so callers must GCPRO.
1487 If STRING contains only ASCII characters, do no conversion and
1488 return the string data of STRING. Otherwise, encode the text by
1489 CODING_SYSTEM, and return a newly allocated memory area which
1490 should be freed by `xfree' by a caller.
1492 SELECTIONP non-zero means the string is being encoded for an X
1493 selection, so it is safe to run pre-write conversions (which
1494 may run Lisp code).
1496 Store the byte length of resulting text in *TEXT_BYTES.
1498 If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
1499 which means that the `encoding' of the result can be `STRING'.
1500 Otherwise store 0 in *STRINGP, which means that the `encoding' of
1501 the result should be `COMPOUND_TEXT'. */
1503 static unsigned char *
1504 x_encode_text (Lisp_Object string, Lisp_Object coding_system, int selectionp, int *text_bytes, int *stringp, int *freep)
1506 int result = string_xstring_p (string);
1507 struct coding_system coding;
1509 if (result == 0)
1511 /* No multibyte character in OBJ. We need not encode it. */
1512 *text_bytes = SBYTES (string);
1513 *stringp = 1;
1514 *freep = 0;
1515 return SDATA (string);
1518 setup_coding_system (coding_system, &coding);
1519 coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK);
1520 /* We suppress producing escape sequences for composition. */
1521 coding.common_flags &= ~CODING_ANNOTATION_MASK;
1522 coding.dst_bytes = SCHARS (string) * 2;
1523 coding.destination = (unsigned char *) xmalloc (coding.dst_bytes);
1524 encode_coding_object (&coding, string, 0, 0,
1525 SCHARS (string), SBYTES (string), Qnil);
1526 *text_bytes = coding.produced;
1527 *stringp = (result == 1 || !EQ (coding_system, Qcompound_text));
1528 *freep = 1;
1529 return coding.destination;
1533 /* Set the WM name to NAME for frame F. Also set the icon name.
1534 If the frame already has an icon name, use that, otherwise set the
1535 icon name to NAME. */
1537 static void
1538 x_set_name_internal (FRAME_PTR f, Lisp_Object name)
1540 if (FRAME_X_WINDOW (f))
1542 BLOCK_INPUT;
1544 XTextProperty text, icon;
1545 int bytes, stringp;
1546 int do_free_icon_value = 0, do_free_text_value = 0;
1547 Lisp_Object coding_system;
1548 Lisp_Object encoded_name;
1549 Lisp_Object encoded_icon_name;
1550 struct gcpro gcpro1;
1552 /* As ENCODE_UTF_8 may cause GC and relocation of string data,
1553 we use it before x_encode_text that may return string data. */
1554 GCPRO1 (name);
1555 encoded_name = ENCODE_UTF_8 (name);
1556 UNGCPRO;
1558 coding_system = Qcompound_text;
1559 /* Note: Encoding strategy
1561 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1562 text.encoding. But, there are non-internationalized window
1563 managers which don't support that encoding. So, if NAME
1564 contains only ASCII and 8859-1 characters, encode it by
1565 iso-latin-1, and use "STRING" in text.encoding hoping that
1566 such window managers at least analyze this format correctly,
1567 i.e. treat 8-bit bytes as 8859-1 characters.
1569 We may also be able to use "UTF8_STRING" in text.encoding
1570 in the future which can encode all Unicode characters.
1571 But, for the moment, there's no way to know that the
1572 current window manager supports it or not.
1574 Either way, we also set the _NET_WM_NAME and _NET_WM_ICON_NAME
1575 properties. Per the EWMH specification, those two properties
1576 are always UTF8_STRING. This matches what gtk_window_set_title()
1577 does in the USE_GTK case. */
1578 text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp,
1579 &do_free_text_value);
1580 text.encoding = (stringp ? XA_STRING
1581 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1582 text.format = 8;
1583 text.nitems = bytes;
1585 if (!STRINGP (f->icon_name))
1587 icon = text;
1588 encoded_icon_name = encoded_name;
1590 else
1592 /* See the above comment "Note: Encoding strategy". */
1593 icon.value = x_encode_text (f->icon_name, coding_system, 0,
1594 &bytes, &stringp, &do_free_icon_value);
1595 icon.encoding = (stringp ? XA_STRING
1596 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1597 icon.format = 8;
1598 icon.nitems = bytes;
1600 encoded_icon_name = ENCODE_UTF_8 (f->icon_name);
1603 #ifdef USE_GTK
1604 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
1605 (char *) SDATA (encoded_name));
1606 #else /* not USE_GTK */
1607 XSetWMName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &text);
1608 XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
1609 FRAME_X_DISPLAY_INFO (f)->Xatom_net_wm_name,
1610 FRAME_X_DISPLAY_INFO (f)->Xatom_UTF8_STRING,
1611 8, PropModeReplace,
1612 (char *) SDATA (encoded_name),
1613 SBYTES (encoded_name));
1614 #endif /* not USE_GTK */
1616 XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &icon);
1617 XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
1618 FRAME_X_DISPLAY_INFO (f)->Xatom_net_wm_icon_name,
1619 FRAME_X_DISPLAY_INFO (f)->Xatom_UTF8_STRING,
1620 8, PropModeReplace,
1621 (char *) SDATA (encoded_icon_name),
1622 SBYTES (encoded_icon_name));
1624 if (do_free_icon_value)
1625 xfree (icon.value);
1626 if (do_free_text_value)
1627 xfree (text.value);
1629 UNBLOCK_INPUT;
1633 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1634 x_id_name.
1636 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1637 name; if NAME is a string, set F's name to NAME and set
1638 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1640 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1641 suggesting a new name, which lisp code should override; if
1642 F->explicit_name is set, ignore the new name; otherwise, set it. */
1644 void
1645 x_set_name (struct frame *f, Lisp_Object name, int explicit)
1647 /* Make sure that requests from lisp code override requests from
1648 Emacs redisplay code. */
1649 if (explicit)
1651 /* If we're switching from explicit to implicit, we had better
1652 update the mode lines and thereby update the title. */
1653 if (f->explicit_name && NILP (name))
1654 update_mode_lines = 1;
1656 f->explicit_name = ! NILP (name);
1658 else if (f->explicit_name)
1659 return;
1661 /* If NAME is nil, set the name to the x_id_name. */
1662 if (NILP (name))
1664 /* Check for no change needed in this very common case
1665 before we do any consing. */
1666 if (!strcmp (FRAME_X_DISPLAY_INFO (f)->x_id_name,
1667 SDATA (f->name)))
1668 return;
1669 name = build_string (FRAME_X_DISPLAY_INFO (f)->x_id_name);
1671 else
1672 CHECK_STRING (name);
1674 /* Don't change the name if it's already NAME. */
1675 if (! NILP (Fstring_equal (name, f->name)))
1676 return;
1678 f->name = name;
1680 /* For setting the frame title, the title parameter should override
1681 the name parameter. */
1682 if (! NILP (f->title))
1683 name = f->title;
1685 x_set_name_internal (f, name);
1688 /* This function should be called when the user's lisp code has
1689 specified a name for the frame; the name will override any set by the
1690 redisplay code. */
1691 void
1692 x_explicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
1694 x_set_name (f, arg, 1);
1697 /* This function should be called by Emacs redisplay code to set the
1698 name; names set this way will never override names set by the user's
1699 lisp code. */
1700 void
1701 x_implicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
1703 x_set_name (f, arg, 0);
1706 /* Change the title of frame F to NAME.
1707 If NAME is nil, use the frame name as the title. */
1709 void
1710 x_set_title (struct frame *f, Lisp_Object name, Lisp_Object old_name)
1712 /* Don't change the title if it's already NAME. */
1713 if (EQ (name, f->title))
1714 return;
1716 update_mode_lines = 1;
1718 f->title = name;
1720 if (NILP (name))
1721 name = f->name;
1722 else
1723 CHECK_STRING (name);
1725 x_set_name_internal (f, name);
1728 void
1729 x_set_scroll_bar_default_width (struct frame *f)
1731 int wid = FRAME_COLUMN_WIDTH (f);
1733 #ifdef USE_TOOLKIT_SCROLL_BARS
1734 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
1735 int width = 16 + 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM;
1736 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (width + wid - 1) / wid;
1737 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = width;
1738 #else
1739 /* Make the actual width at least 14 pixels and a multiple of a
1740 character width. */
1741 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
1743 /* Use all of that space (aside from required margins) for the
1744 scroll bar. */
1745 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 0;
1746 #endif
1750 /* Record in frame F the specified or default value according to ALIST
1751 of the parameter named PROP (a Lisp symbol). If no value is
1752 specified for PROP, look for an X default for XPROP on the frame
1753 named NAME. If that is not found either, use the value DEFLT. */
1755 static Lisp_Object
1756 x_default_scroll_bar_color_parameter (struct frame *f,
1757 Lisp_Object alist, Lisp_Object prop,
1758 char *xprop, char *xclass,
1759 int foreground_p)
1761 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
1762 Lisp_Object tem;
1764 tem = x_get_arg (dpyinfo, alist, prop, xprop, xclass, RES_TYPE_STRING);
1765 if (EQ (tem, Qunbound))
1767 #ifdef USE_TOOLKIT_SCROLL_BARS
1769 /* See if an X resource for the scroll bar color has been
1770 specified. */
1771 tem = display_x_get_resource (dpyinfo,
1772 build_string (foreground_p
1773 ? "foreground"
1774 : "background"),
1775 empty_unibyte_string,
1776 build_string ("verticalScrollBar"),
1777 empty_unibyte_string);
1778 if (!STRINGP (tem))
1780 /* If nothing has been specified, scroll bars will use a
1781 toolkit-dependent default. Because these defaults are
1782 difficult to get at without actually creating a scroll
1783 bar, use nil to indicate that no color has been
1784 specified. */
1785 tem = Qnil;
1788 #else /* not USE_TOOLKIT_SCROLL_BARS */
1790 tem = Qnil;
1792 #endif /* not USE_TOOLKIT_SCROLL_BARS */
1795 x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));
1796 return tem;
1802 #ifdef USE_X_TOOLKIT
1804 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
1805 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
1806 already be present because of the toolkit (Motif adds some of them,
1807 for example, but Xt doesn't). */
1809 static void
1810 hack_wm_protocols (FRAME_PTR f, Widget widget)
1812 Display *dpy = XtDisplay (widget);
1813 Window w = XtWindow (widget);
1814 int need_delete = 1;
1815 int need_focus = 1;
1816 int need_save = 1;
1818 BLOCK_INPUT;
1820 Atom type;
1821 unsigned char *catoms;
1822 int format = 0;
1823 unsigned long nitems = 0;
1824 unsigned long bytes_after;
1826 if ((XGetWindowProperty (dpy, w,
1827 FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
1828 (long)0, (long)100, False, XA_ATOM,
1829 &type, &format, &nitems, &bytes_after,
1830 &catoms)
1831 == Success)
1832 && format == 32 && type == XA_ATOM)
1834 Atom *atoms = (Atom *) catoms;
1835 while (nitems > 0)
1837 nitems--;
1838 if (atoms[nitems]
1839 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window)
1840 need_delete = 0;
1841 else if (atoms[nitems]
1842 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus)
1843 need_focus = 0;
1844 else if (atoms[nitems]
1845 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself)
1846 need_save = 0;
1849 if (catoms)
1850 XFree (catoms);
1853 Atom props [10];
1854 int count = 0;
1855 if (need_delete)
1856 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window;
1857 if (need_focus)
1858 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus;
1859 if (need_save)
1860 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
1861 if (count)
1862 XChangeProperty (dpy, w, FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
1863 XA_ATOM, 32, PropModeAppend,
1864 (unsigned char *) props, count);
1866 UNBLOCK_INPUT;
1868 #endif
1872 /* Support routines for XIC (X Input Context). */
1874 #ifdef HAVE_X_I18N
1876 static XFontSet xic_create_xfontset (struct frame *);
1877 static XIMStyle best_xim_style (XIMStyles *, XIMStyles *);
1880 /* Supported XIM styles, ordered by preference. */
1882 static XIMStyle supported_xim_styles[] =
1884 XIMPreeditPosition | XIMStatusArea,
1885 XIMPreeditPosition | XIMStatusNothing,
1886 XIMPreeditPosition | XIMStatusNone,
1887 XIMPreeditNothing | XIMStatusArea,
1888 XIMPreeditNothing | XIMStatusNothing,
1889 XIMPreeditNothing | XIMStatusNone,
1890 XIMPreeditNone | XIMStatusArea,
1891 XIMPreeditNone | XIMStatusNothing,
1892 XIMPreeditNone | XIMStatusNone,
1897 /* Create an X fontset on frame F with base font name BASE_FONTNAME. */
1899 char xic_defaut_fontset[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
1901 /* Create an Xt fontset spec from the name of a base font.
1902 If `motif' is True use the Motif syntax. */
1903 char *
1904 xic_create_fontsetname (char *base_fontname, int motif)
1906 const char *sep = motif ? ";" : ",";
1907 char *fontsetname;
1909 /* Make a fontset name from the base font name. */
1910 if (xic_defaut_fontset == base_fontname)
1911 { /* There is no base font name, use the default. */
1912 int len = strlen (base_fontname) + 2;
1913 fontsetname = xmalloc (len);
1914 memset (fontsetname, 0, len);
1915 strcpy (fontsetname, base_fontname);
1917 else
1919 /* Make a fontset name from the base font name.
1920 The font set will be made of the following elements:
1921 - the base font.
1922 - the base font where the charset spec is replaced by -*-*.
1923 - the same but with the family also replaced with -*-*-. */
1924 char *p = base_fontname;
1925 int i;
1927 for (i = 0; *p; p++)
1928 if (*p == '-') i++;
1929 if (i != 14)
1930 { /* As the font name doesn't conform to XLFD, we can't
1931 modify it to generalize it to allcs and allfamilies.
1932 Use the specified font plus the default. */
1933 int len = strlen (base_fontname) + strlen (xic_defaut_fontset) + 3;
1934 fontsetname = xmalloc (len);
1935 memset (fontsetname, 0, len);
1936 strcpy (fontsetname, base_fontname);
1937 strcat (fontsetname, sep);
1938 strcat (fontsetname, xic_defaut_fontset);
1940 else
1942 int len;
1943 char *p1 = NULL, *p2 = NULL, *p3 = NULL;
1944 char *font_allcs = NULL;
1945 char *font_allfamilies = NULL;
1946 char *font_all = NULL;
1947 char *allcs = "*-*-*-*-*-*-*";
1948 char *allfamilies = "-*-*-";
1949 char *all = "*-*-*-*-";
1950 char *base;
1952 for (i = 0, p = base_fontname; i < 8; p++)
1954 if (*p == '-')
1956 i++;
1957 if (i == 3)
1958 p1 = p + 1;
1959 else if (i == 7)
1960 p2 = p + 1;
1961 else if (i == 6)
1962 p3 = p + 1;
1965 /* If base_fontname specifies ADSTYLE, make it a
1966 wildcard. */
1967 if (*p3 != '*')
1969 int diff = (p2 - p3) - 2;
1971 base = alloca (strlen (base_fontname) + 1);
1972 memcpy (base, base_fontname, p3 - base_fontname);
1973 base[p3 - base_fontname] = '*';
1974 base[(p3 - base_fontname) + 1] = '-';
1975 strcpy (base + (p3 - base_fontname) + 2, p2);
1976 p = base + (p - base_fontname) - diff;
1977 p1 = base + (p1 - base_fontname);
1978 p2 = base + (p2 - base_fontname) - diff;
1979 base_fontname = base;
1982 /* Build the font spec that matches all charsets. */
1983 len = p - base_fontname + strlen (allcs) + 1;
1984 font_allcs = (char *) alloca (len);
1985 memset (font_allcs, 0, len);
1986 memcpy (font_allcs, base_fontname, p - base_fontname);
1987 strcat (font_allcs, allcs);
1989 /* Build the font spec that matches all families and
1990 add-styles. */
1991 len = p - p1 + strlen (allcs) + strlen (allfamilies) + 1;
1992 font_allfamilies = (char *) alloca (len);
1993 memset (font_allfamilies, 0, len);
1994 strcpy (font_allfamilies, allfamilies);
1995 memcpy (font_allfamilies + strlen (allfamilies), p1, p - p1);
1996 strcat (font_allfamilies, allcs);
1998 /* Build the font spec that matches all. */
1999 len = p - p2 + strlen (allcs) + strlen (all) + strlen (allfamilies) + 1;
2000 font_all = (char *) alloca (len);
2001 memset (font_all, 0, len);
2002 strcpy (font_all, allfamilies);
2003 strcat (font_all, all);
2004 memcpy (font_all + strlen (all) + strlen (allfamilies), p2, p - p2);
2005 strcat (font_all, allcs);
2007 /* Build the actual font set name. */
2008 len = strlen (base_fontname) + strlen (font_allcs)
2009 + strlen (font_allfamilies) + strlen (font_all) + 5;
2010 fontsetname = xmalloc (len);
2011 memset (fontsetname, 0, len);
2012 strcpy (fontsetname, base_fontname);
2013 strcat (fontsetname, sep);
2014 strcat (fontsetname, font_allcs);
2015 strcat (fontsetname, sep);
2016 strcat (fontsetname, font_allfamilies);
2017 strcat (fontsetname, sep);
2018 strcat (fontsetname, font_all);
2021 if (motif)
2022 strcat (fontsetname, ":");
2023 return fontsetname;
2026 #ifdef DEBUG_XIC_FONTSET
2027 static void
2028 print_fontset_result (xfs, name, missing_list, missing_count)
2029 XFontSet xfs;
2030 char *name;
2031 char **missing_list;
2032 int missing_count;
2034 if (xfs)
2035 fprintf (stderr, "XIC Fontset created: %s\n", name);
2036 else
2038 fprintf (stderr, "XIC Fontset failed: %s\n", name);
2039 while (missing_count-- > 0)
2041 fprintf (stderr, " missing: %s\n", *missing_list);
2042 missing_list++;
2047 #endif
2049 static XFontSet
2050 xic_create_xfontset (struct frame *f)
2052 XFontSet xfs = NULL;
2053 struct font *font = FRAME_FONT (f);
2054 int pixel_size = font->pixel_size;
2055 Lisp_Object rest, frame;
2057 /* See if there is another frame already using same fontset. */
2058 FOR_EACH_FRAME (rest, frame)
2060 struct frame *cf = XFRAME (frame);
2062 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
2063 && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f)
2064 && FRAME_FONT (f)
2065 && FRAME_FONT (f)->pixel_size == pixel_size)
2067 xfs = FRAME_XIC_FONTSET (cf);
2068 break;
2072 if (! xfs)
2074 char buf[256];
2075 char **missing_list;
2076 int missing_count;
2077 char *def_string;
2078 char *xlfd_format = "-*-*-medium-r-normal--%d-*-*-*-*-*";
2080 sprintf (buf, xlfd_format, pixel_size);
2081 missing_list = NULL;
2082 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
2083 &missing_list, &missing_count, &def_string);
2084 #ifdef DEBUG_XIC_FONTSET
2085 print_fontset_result (xfs, buf, missing_list, missing_count);
2086 #endif
2087 if (missing_list)
2088 XFreeStringList (missing_list);
2089 if (! xfs)
2091 /* List of pixel sizes most likely available. Find one that
2092 is closest to pixel_size. */
2093 int sizes[] = {0, 8, 10, 11, 12, 14, 17, 18, 20, 24, 26, 34, 0};
2094 int *smaller, *larger;
2096 for (smaller = sizes; smaller[1]; smaller++)
2097 if (smaller[1] >= pixel_size)
2098 break;
2099 larger = smaller + 1;
2100 if (*larger == pixel_size)
2101 larger++;
2102 while (*smaller || *larger)
2104 int this_size;
2106 if (! *larger)
2107 this_size = *smaller--;
2108 else if (! *smaller)
2109 this_size = *larger++;
2110 else if (pixel_size - *smaller < *larger - pixel_size)
2111 this_size = *smaller--;
2112 else
2113 this_size = *larger++;
2114 sprintf (buf, xlfd_format, this_size);
2115 missing_list = NULL;
2116 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
2117 &missing_list, &missing_count, &def_string);
2118 #ifdef DEBUG_XIC_FONTSET
2119 print_fontset_result (xfs, buf, missing_list, missing_count);
2120 #endif
2121 if (missing_list)
2122 XFreeStringList (missing_list);
2123 if (xfs)
2124 break;
2127 if (! xfs)
2129 char *last_resort = "-*-*-*-r-normal--*-*-*-*-*-*";
2131 missing_list = NULL;
2132 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), last_resort,
2133 &missing_list, &missing_count, &def_string);
2134 #ifdef DEBUG_XIC_FONTSET
2135 print_fontset_result (xfs, last_resort, missing_list, missing_count);
2136 #endif
2137 if (missing_list)
2138 XFreeStringList (missing_list);
2143 return xfs;
2146 /* Free the X fontset of frame F if it is the last frame using it. */
2148 void
2149 xic_free_xfontset (struct frame *f)
2151 Lisp_Object rest, frame;
2152 int shared_p = 0;
2154 if (!FRAME_XIC_FONTSET (f))
2155 return;
2157 /* See if there is another frame sharing the same fontset. */
2158 FOR_EACH_FRAME (rest, frame)
2160 struct frame *cf = XFRAME (frame);
2161 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
2162 && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f)
2163 && FRAME_XIC_FONTSET (cf) == FRAME_XIC_FONTSET (f))
2165 shared_p = 1;
2166 break;
2170 if (!shared_p)
2171 /* The fontset is not used anymore. It is safe to free it. */
2172 XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f));
2174 if (FRAME_XIC_BASE_FONTNAME (f))
2175 xfree (FRAME_XIC_BASE_FONTNAME (f));
2176 FRAME_XIC_BASE_FONTNAME (f) = NULL;
2177 FRAME_XIC_FONTSET (f) = NULL;
2181 /* Value is the best input style, given user preferences USER (already
2182 checked to be supported by Emacs), and styles supported by the
2183 input method XIM. */
2185 static XIMStyle
2186 best_xim_style (XIMStyles *user, XIMStyles *xim)
2188 int i, j;
2190 for (i = 0; i < user->count_styles; ++i)
2191 for (j = 0; j < xim->count_styles; ++j)
2192 if (user->supported_styles[i] == xim->supported_styles[j])
2193 return user->supported_styles[i];
2195 /* Return the default style. */
2196 return XIMPreeditNothing | XIMStatusNothing;
2199 /* Create XIC for frame F. */
2201 static XIMStyle xic_style;
2203 void
2204 create_frame_xic (struct frame *f)
2206 XIM xim;
2207 XIC xic = NULL;
2208 XFontSet xfs = NULL;
2210 if (FRAME_XIC (f))
2211 return;
2213 /* Create X fontset. */
2214 xfs = xic_create_xfontset (f);
2215 xim = FRAME_X_XIM (f);
2216 if (xim)
2218 XRectangle s_area;
2219 XPoint spot;
2220 XVaNestedList preedit_attr;
2221 XVaNestedList status_attr;
2223 s_area.x = 0; s_area.y = 0; s_area.width = 1; s_area.height = 1;
2224 spot.x = 0; spot.y = 1;
2226 /* Determine XIC style. */
2227 if (xic_style == 0)
2229 XIMStyles supported_list;
2230 supported_list.count_styles = (sizeof supported_xim_styles
2231 / sizeof supported_xim_styles[0]);
2232 supported_list.supported_styles = supported_xim_styles;
2233 xic_style = best_xim_style (&supported_list,
2234 FRAME_X_XIM_STYLES (f));
2237 preedit_attr = XVaCreateNestedList (0,
2238 XNFontSet, xfs,
2239 XNForeground,
2240 FRAME_FOREGROUND_PIXEL (f),
2241 XNBackground,
2242 FRAME_BACKGROUND_PIXEL (f),
2243 (xic_style & XIMPreeditPosition
2244 ? XNSpotLocation
2245 : NULL),
2246 &spot,
2247 NULL);
2248 status_attr = XVaCreateNestedList (0,
2249 XNArea,
2250 &s_area,
2251 XNFontSet,
2252 xfs,
2253 XNForeground,
2254 FRAME_FOREGROUND_PIXEL (f),
2255 XNBackground,
2256 FRAME_BACKGROUND_PIXEL (f),
2257 NULL);
2259 xic = XCreateIC (xim,
2260 XNInputStyle, xic_style,
2261 XNClientWindow, FRAME_X_WINDOW (f),
2262 XNFocusWindow, FRAME_X_WINDOW (f),
2263 XNStatusAttributes, status_attr,
2264 XNPreeditAttributes, preedit_attr,
2265 NULL);
2266 XFree (preedit_attr);
2267 XFree (status_attr);
2270 FRAME_XIC (f) = xic;
2271 FRAME_XIC_STYLE (f) = xic_style;
2272 FRAME_XIC_FONTSET (f) = xfs;
2276 /* Destroy XIC and free XIC fontset of frame F, if any. */
2278 void
2279 free_frame_xic (struct frame *f)
2281 if (FRAME_XIC (f) == NULL)
2282 return;
2284 XDestroyIC (FRAME_XIC (f));
2285 xic_free_xfontset (f);
2287 FRAME_XIC (f) = NULL;
2291 /* Place preedit area for XIC of window W's frame to specified
2292 pixel position X/Y. X and Y are relative to window W. */
2294 void
2295 xic_set_preeditarea (struct window *w, int x, int y)
2297 struct frame *f = XFRAME (w->frame);
2298 XVaNestedList attr;
2299 XPoint spot;
2301 spot.x = WINDOW_TO_FRAME_PIXEL_X (w, x) + WINDOW_LEFT_FRINGE_WIDTH (w);
2302 spot.y = WINDOW_TO_FRAME_PIXEL_Y (w, y) + FONT_BASE (FRAME_FONT (f));
2303 attr = XVaCreateNestedList (0, XNSpotLocation, &spot, NULL);
2304 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2305 XFree (attr);
2309 /* Place status area for XIC in bottom right corner of frame F.. */
2311 void
2312 xic_set_statusarea (struct frame *f)
2314 XIC xic = FRAME_XIC (f);
2315 XVaNestedList attr;
2316 XRectangle area;
2317 XRectangle *needed;
2319 /* Negotiate geometry of status area. If input method has existing
2320 status area, use its current size. */
2321 area.x = area.y = area.width = area.height = 0;
2322 attr = XVaCreateNestedList (0, XNAreaNeeded, &area, NULL);
2323 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2324 XFree (attr);
2326 attr = XVaCreateNestedList (0, XNAreaNeeded, &needed, NULL);
2327 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2328 XFree (attr);
2330 if (needed->width == 0) /* Use XNArea instead of XNAreaNeeded */
2332 attr = XVaCreateNestedList (0, XNArea, &needed, NULL);
2333 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2334 XFree (attr);
2337 area.width = needed->width;
2338 area.height = needed->height;
2339 area.x = FRAME_PIXEL_WIDTH (f) - area.width - FRAME_INTERNAL_BORDER_WIDTH (f);
2340 area.y = (FRAME_PIXEL_HEIGHT (f) - area.height
2341 - FRAME_MENUBAR_HEIGHT (f)
2342 - FRAME_TOOLBAR_HEIGHT (f)
2343 - FRAME_INTERNAL_BORDER_WIDTH (f));
2344 XFree (needed);
2346 attr = XVaCreateNestedList (0, XNArea, &area, NULL);
2347 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2348 XFree (attr);
2352 /* Set X fontset for XIC of frame F, using base font name
2353 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2355 void
2356 xic_set_xfontset (struct frame *f, char *base_fontname)
2358 XVaNestedList attr;
2359 XFontSet xfs;
2361 xic_free_xfontset (f);
2363 xfs = xic_create_xfontset (f);
2365 attr = XVaCreateNestedList (0, XNFontSet, xfs, NULL);
2366 if (FRAME_XIC_STYLE (f) & XIMPreeditPosition)
2367 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2368 if (FRAME_XIC_STYLE (f) & XIMStatusArea)
2369 XSetICValues (FRAME_XIC (f), XNStatusAttributes, attr, NULL);
2370 XFree (attr);
2372 FRAME_XIC_FONTSET (f) = xfs;
2375 #endif /* HAVE_X_I18N */
2379 #ifdef USE_X_TOOLKIT
2381 /* Create and set up the X widget for frame F. */
2383 static void
2384 x_window (struct frame *f, long window_prompting, int minibuffer_only)
2386 XClassHint class_hints;
2387 XSetWindowAttributes attributes;
2388 unsigned long attribute_mask;
2389 Widget shell_widget;
2390 Widget pane_widget;
2391 Widget frame_widget;
2392 Arg al [25];
2393 int ac;
2395 BLOCK_INPUT;
2397 /* Use the resource name as the top-level widget name
2398 for looking up resources. Make a non-Lisp copy
2399 for the window manager, so GC relocation won't bother it.
2401 Elsewhere we specify the window name for the window manager. */
2404 char *str = (char *) SDATA (Vx_resource_name);
2405 f->namebuf = (char *) xmalloc (strlen (str) + 1);
2406 strcpy (f->namebuf, str);
2409 ac = 0;
2410 XtSetArg (al[ac], XtNallowShellResize, 1); ac++;
2411 XtSetArg (al[ac], XtNinput, 1); ac++;
2412 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2413 XtSetArg (al[ac], XtNborderWidth, f->border_width); ac++;
2414 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2415 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2416 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2417 shell_widget = XtAppCreateShell (f->namebuf, EMACS_CLASS,
2418 applicationShellWidgetClass,
2419 FRAME_X_DISPLAY (f), al, ac);
2421 f->output_data.x->widget = shell_widget;
2422 /* maybe_set_screen_title_format (shell_widget); */
2424 pane_widget = lw_create_widget ("main", "pane", widget_id_tick++,
2425 (widget_value *) NULL,
2426 shell_widget, False,
2427 (lw_callback) NULL,
2428 (lw_callback) NULL,
2429 (lw_callback) NULL,
2430 (lw_callback) NULL);
2432 ac = 0;
2433 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2434 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2435 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2436 XtSetArg (al[ac], XtNborderWidth, 0); ac++;
2437 XtSetValues (pane_widget, al, ac);
2438 f->output_data.x->column_widget = pane_widget;
2440 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2441 the emacs screen when changing menubar. This reduces flickering. */
2443 ac = 0;
2444 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2445 XtSetArg (al[ac], XtNshowGrip, 0); ac++;
2446 XtSetArg (al[ac], XtNallowResize, 1); ac++;
2447 XtSetArg (al[ac], XtNresizeToPreferred, 1); ac++;
2448 XtSetArg (al[ac], XtNemacsFrame, f); ac++;
2449 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2450 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2451 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2452 XtSetArg (al[ac], XtNborderWidth, 0); ac++;
2453 frame_widget = XtCreateWidget (f->namebuf, emacsFrameClass, pane_widget,
2454 al, ac);
2456 f->output_data.x->edit_widget = frame_widget;
2458 XtManageChild (frame_widget);
2460 /* Do some needed geometry management. */
2462 int len;
2463 char *tem, shell_position[32];
2464 Arg al[10];
2465 int ac = 0;
2466 int extra_borders = 0;
2467 int menubar_size
2468 = (f->output_data.x->menubar_widget
2469 ? (f->output_data.x->menubar_widget->core.height
2470 + f->output_data.x->menubar_widget->core.border_width)
2471 : 0);
2473 #if 0 /* Experimentally, we now get the right results
2474 for -geometry -0-0 without this. 24 Aug 96, rms. */
2475 if (FRAME_EXTERNAL_MENU_BAR (f))
2477 Dimension ibw = 0;
2478 XtVaGetValues (pane_widget, XtNinternalBorderWidth, &ibw, NULL);
2479 menubar_size += ibw;
2481 #endif
2483 f->output_data.x->menubar_height = menubar_size;
2485 #ifndef USE_LUCID
2486 /* Motif seems to need this amount added to the sizes
2487 specified for the shell widget. The Athena/Lucid widgets don't.
2488 Both conclusions reached experimentally. -- rms. */
2489 XtVaGetValues (f->output_data.x->edit_widget, XtNinternalBorderWidth,
2490 &extra_borders, NULL);
2491 extra_borders *= 2;
2492 #endif
2494 /* Convert our geometry parameters into a geometry string
2495 and specify it.
2496 Note that we do not specify here whether the position
2497 is a user-specified or program-specified one.
2498 We pass that information later, in x_wm_set_size_hints. */
2500 int left = f->left_pos;
2501 int xneg = window_prompting & XNegative;
2502 int top = f->top_pos;
2503 int yneg = window_prompting & YNegative;
2504 if (xneg)
2505 left = -left;
2506 if (yneg)
2507 top = -top;
2509 if (window_prompting & USPosition)
2510 sprintf (shell_position, "=%dx%d%c%d%c%d",
2511 FRAME_PIXEL_WIDTH (f) + extra_borders,
2512 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders,
2513 (xneg ? '-' : '+'), left,
2514 (yneg ? '-' : '+'), top);
2515 else
2517 sprintf (shell_position, "=%dx%d",
2518 FRAME_PIXEL_WIDTH (f) + extra_borders,
2519 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders);
2521 /* Setting x and y when the position is not specified in
2522 the geometry string will set program position in the WM hints.
2523 If Emacs had just one program position, we could set it in
2524 fallback resources, but since each make-frame call can specify
2525 different program positions, this is easier. */
2526 XtSetArg (al[ac], XtNx, left); ac++;
2527 XtSetArg (al[ac], XtNy, top); ac++;
2531 len = strlen (shell_position) + 1;
2532 /* We don't free this because we don't know whether
2533 it is safe to free it while the frame exists.
2534 It isn't worth the trouble of arranging to free it
2535 when the frame is deleted. */
2536 tem = (char *) xmalloc (len);
2537 strncpy (tem, shell_position, len);
2538 XtSetArg (al[ac], XtNgeometry, tem); ac++;
2539 XtSetValues (shell_widget, al, ac);
2542 XtManageChild (pane_widget);
2543 XtRealizeWidget (shell_widget);
2545 if (FRAME_X_EMBEDDED_P (f))
2546 XReparentWindow (FRAME_X_DISPLAY (f), XtWindow (shell_widget),
2547 f->output_data.x->parent_desc, 0, 0);
2549 FRAME_X_WINDOW (f) = XtWindow (frame_widget);
2551 validate_x_resource_name ();
2553 class_hints.res_name = (char *) SDATA (Vx_resource_name);
2554 class_hints.res_class = (char *) SDATA (Vx_resource_class);
2555 XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints);
2557 #ifdef HAVE_X_I18N
2558 FRAME_XIC (f) = NULL;
2559 if (use_xim)
2560 create_frame_xic (f);
2561 #endif
2563 f->output_data.x->wm_hints.input = True;
2564 f->output_data.x->wm_hints.flags |= InputHint;
2565 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2566 &f->output_data.x->wm_hints);
2568 hack_wm_protocols (f, shell_widget);
2570 #ifdef HACK_EDITRES
2571 XtAddEventHandler (shell_widget, 0, True, _XEditResCheckMessages, 0);
2572 #endif
2574 /* Do a stupid property change to force the server to generate a
2575 PropertyNotify event so that the event_stream server timestamp will
2576 be initialized to something relevant to the time we created the window.
2578 XChangeProperty (XtDisplay (frame_widget), XtWindow (frame_widget),
2579 FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
2580 XA_ATOM, 32, PropModeAppend,
2581 (unsigned char*) NULL, 0);
2583 /* Make all the standard events reach the Emacs frame. */
2584 attributes.event_mask = STANDARD_EVENT_SET;
2586 #ifdef HAVE_X_I18N
2587 if (FRAME_XIC (f))
2589 /* XIM server might require some X events. */
2590 unsigned long fevent = NoEventMask;
2591 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2592 attributes.event_mask |= fevent;
2594 #endif /* HAVE_X_I18N */
2596 attribute_mask = CWEventMask;
2597 XChangeWindowAttributes (XtDisplay (shell_widget), XtWindow (shell_widget),
2598 attribute_mask, &attributes);
2600 XtMapWidget (frame_widget);
2602 /* x_set_name normally ignores requests to set the name if the
2603 requested name is the same as the current name. This is the one
2604 place where that assumption isn't correct; f->name is set, but
2605 the X server hasn't been told. */
2607 Lisp_Object name;
2608 int explicit = f->explicit_name;
2610 f->explicit_name = 0;
2611 name = f->name;
2612 f->name = Qnil;
2613 x_set_name (f, name, explicit);
2616 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2617 f->output_data.x->current_cursor
2618 = f->output_data.x->text_cursor);
2620 UNBLOCK_INPUT;
2622 /* This is a no-op, except under Motif. Make sure main areas are
2623 set to something reasonable, in case we get an error later. */
2624 lw_set_main_areas (pane_widget, 0, frame_widget);
2627 #else /* not USE_X_TOOLKIT */
2628 #ifdef USE_GTK
2629 void
2630 x_window (FRAME_PTR f)
2632 if (! xg_create_frame_widgets (f))
2633 error ("Unable to create window");
2635 #ifdef HAVE_X_I18N
2636 FRAME_XIC (f) = NULL;
2637 if (use_xim)
2639 BLOCK_INPUT;
2640 create_frame_xic (f);
2641 if (FRAME_XIC (f))
2643 /* XIM server might require some X events. */
2644 unsigned long fevent = NoEventMask;
2645 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2647 if (fevent != NoEventMask)
2649 XSetWindowAttributes attributes;
2650 XWindowAttributes wattr;
2651 unsigned long attribute_mask;
2653 XGetWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2654 &wattr);
2655 attributes.event_mask = wattr.your_event_mask | fevent;
2656 attribute_mask = CWEventMask;
2657 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2658 attribute_mask, &attributes);
2661 UNBLOCK_INPUT;
2663 #endif
2666 #else /*! USE_GTK */
2667 /* Create and set up the X window for frame F. */
2669 void
2670 x_window (struct frame *f)
2672 XClassHint class_hints;
2673 XSetWindowAttributes attributes;
2674 unsigned long attribute_mask;
2676 attributes.background_pixel = FRAME_BACKGROUND_PIXEL (f);
2677 attributes.border_pixel = f->output_data.x->border_pixel;
2678 attributes.bit_gravity = StaticGravity;
2679 attributes.backing_store = NotUseful;
2680 attributes.save_under = True;
2681 attributes.event_mask = STANDARD_EVENT_SET;
2682 attributes.colormap = FRAME_X_COLORMAP (f);
2683 attribute_mask = (CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask
2684 | CWColormap);
2686 BLOCK_INPUT;
2687 FRAME_X_WINDOW (f)
2688 = XCreateWindow (FRAME_X_DISPLAY (f),
2689 f->output_data.x->parent_desc,
2690 f->left_pos,
2691 f->top_pos,
2692 FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
2693 f->border_width,
2694 CopyFromParent, /* depth */
2695 InputOutput, /* class */
2696 FRAME_X_VISUAL (f),
2697 attribute_mask, &attributes);
2699 #ifdef HAVE_X_I18N
2700 if (use_xim)
2702 create_frame_xic (f);
2703 if (FRAME_XIC (f))
2705 /* XIM server might require some X events. */
2706 unsigned long fevent = NoEventMask;
2707 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2708 attributes.event_mask |= fevent;
2709 attribute_mask = CWEventMask;
2710 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2711 attribute_mask, &attributes);
2714 #endif /* HAVE_X_I18N */
2716 validate_x_resource_name ();
2718 class_hints.res_name = (char *) SDATA (Vx_resource_name);
2719 class_hints.res_class = (char *) SDATA (Vx_resource_class);
2720 XSetClassHint (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &class_hints);
2722 /* The menubar is part of the ordinary display;
2723 it does not count in addition to the height of the window. */
2724 f->output_data.x->menubar_height = 0;
2726 /* This indicates that we use the "Passive Input" input model.
2727 Unless we do this, we don't get the Focus{In,Out} events that we
2728 need to draw the cursor correctly. Accursed bureaucrats.
2729 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2731 f->output_data.x->wm_hints.input = True;
2732 f->output_data.x->wm_hints.flags |= InputHint;
2733 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2734 &f->output_data.x->wm_hints);
2735 f->output_data.x->wm_hints.icon_pixmap = None;
2737 /* Request "save yourself" and "delete window" commands from wm. */
2739 Atom protocols[2];
2740 protocols[0] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window;
2741 protocols[1] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
2742 XSetWMProtocols (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), protocols, 2);
2745 /* x_set_name normally ignores requests to set the name if the
2746 requested name is the same as the current name. This is the one
2747 place where that assumption isn't correct; f->name is set, but
2748 the X server hasn't been told. */
2750 Lisp_Object name;
2751 int explicit = f->explicit_name;
2753 f->explicit_name = 0;
2754 name = f->name;
2755 f->name = Qnil;
2756 x_set_name (f, name, explicit);
2759 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2760 f->output_data.x->current_cursor
2761 = f->output_data.x->text_cursor);
2763 UNBLOCK_INPUT;
2765 if (FRAME_X_WINDOW (f) == 0)
2766 error ("Unable to create window");
2769 #endif /* not USE_GTK */
2770 #endif /* not USE_X_TOOLKIT */
2772 /* Verify that the icon position args for this window are valid. */
2774 static void
2775 x_icon_verify (struct frame *f, Lisp_Object parms)
2777 Lisp_Object icon_x, icon_y;
2779 /* Set the position of the icon. Note that twm groups all
2780 icons in an icon window. */
2781 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2782 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2783 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2785 CHECK_NUMBER (icon_x);
2786 CHECK_NUMBER (icon_y);
2788 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2789 error ("Both left and top icon corners of icon must be specified");
2792 /* Handle the icon stuff for this window. Perhaps later we might
2793 want an x_set_icon_position which can be called interactively as
2794 well. */
2796 static void
2797 x_icon (struct frame *f, Lisp_Object parms)
2799 Lisp_Object icon_x, icon_y;
2800 #if 0
2801 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2802 #endif
2804 /* Set the position of the icon. Note that twm groups all
2805 icons in an icon window. */
2806 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2807 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2808 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2810 CHECK_NUMBER (icon_x);
2811 CHECK_NUMBER (icon_y);
2813 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2814 error ("Both left and top icon corners of icon must be specified");
2816 BLOCK_INPUT;
2818 if (! EQ (icon_x, Qunbound))
2819 x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
2821 #if 0 /* x_get_arg removes the visibility parameter as a side effect,
2822 but x_create_frame still needs it. */
2823 /* Start up iconic or window? */
2824 x_wm_set_window_state
2825 (f, (EQ (x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL),
2826 Qicon)
2827 ? IconicState
2828 : NormalState));
2829 #endif
2831 x_text_icon (f, (char *) SDATA ((!NILP (f->icon_name)
2832 ? f->icon_name
2833 : f->name)));
2835 UNBLOCK_INPUT;
2838 /* Make the GCs needed for this window, setting the
2839 background, border and mouse colors; also create the
2840 mouse cursor and the gray border tile. */
2842 static void
2843 x_make_gc (struct frame *f)
2845 XGCValues gc_values;
2847 BLOCK_INPUT;
2849 /* Create the GCs of this frame.
2850 Note that many default values are used. */
2852 gc_values.foreground = FRAME_FOREGROUND_PIXEL (f);
2853 gc_values.background = FRAME_BACKGROUND_PIXEL (f);
2854 gc_values.line_width = 0; /* Means 1 using fast algorithm. */
2855 f->output_data.x->normal_gc
2856 = XCreateGC (FRAME_X_DISPLAY (f),
2857 FRAME_X_WINDOW (f),
2858 GCLineWidth | GCForeground | GCBackground,
2859 &gc_values);
2861 /* Reverse video style. */
2862 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2863 gc_values.background = FRAME_FOREGROUND_PIXEL (f);
2864 f->output_data.x->reverse_gc
2865 = XCreateGC (FRAME_X_DISPLAY (f),
2866 FRAME_X_WINDOW (f),
2867 GCForeground | GCBackground | GCLineWidth,
2868 &gc_values);
2870 /* Cursor has cursor-color background, background-color foreground. */
2871 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2872 gc_values.background = f->output_data.x->cursor_pixel;
2873 gc_values.fill_style = FillOpaqueStippled;
2874 f->output_data.x->cursor_gc
2875 = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2876 (GCForeground | GCBackground
2877 | GCFillStyle | GCLineWidth),
2878 &gc_values);
2880 /* Reliefs. */
2881 f->output_data.x->white_relief.gc = 0;
2882 f->output_data.x->black_relief.gc = 0;
2884 /* Create the gray border tile used when the pointer is not in
2885 the frame. Since this depends on the frame's pixel values,
2886 this must be done on a per-frame basis. */
2887 f->output_data.x->border_tile
2888 = (XCreatePixmapFromBitmapData
2889 (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
2890 gray_bits, gray_width, gray_height,
2891 FRAME_FOREGROUND_PIXEL (f),
2892 FRAME_BACKGROUND_PIXEL (f),
2893 DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
2895 UNBLOCK_INPUT;
2899 /* Free what was allocated in x_make_gc. */
2901 void
2902 x_free_gcs (struct frame *f)
2904 Display *dpy = FRAME_X_DISPLAY (f);
2906 BLOCK_INPUT;
2908 if (f->output_data.x->normal_gc)
2910 XFreeGC (dpy, f->output_data.x->normal_gc);
2911 f->output_data.x->normal_gc = 0;
2914 if (f->output_data.x->reverse_gc)
2916 XFreeGC (dpy, f->output_data.x->reverse_gc);
2917 f->output_data.x->reverse_gc = 0;
2920 if (f->output_data.x->cursor_gc)
2922 XFreeGC (dpy, f->output_data.x->cursor_gc);
2923 f->output_data.x->cursor_gc = 0;
2926 if (f->output_data.x->border_tile)
2928 XFreePixmap (dpy, f->output_data.x->border_tile);
2929 f->output_data.x->border_tile = 0;
2932 UNBLOCK_INPUT;
2936 /* Handler for signals raised during x_create_frame and
2937 x_create_top_frame. FRAME is the frame which is partially
2938 constructed. */
2940 static Lisp_Object
2941 unwind_create_frame (Lisp_Object frame)
2943 struct frame *f = XFRAME (frame);
2945 /* If frame is already dead, nothing to do. This can happen if the
2946 display is disconnected after the frame has become official, but
2947 before x_create_frame removes the unwind protect. */
2948 if (!FRAME_LIVE_P (f))
2949 return Qnil;
2951 /* If frame is ``official'', nothing to do. */
2952 if (!CONSP (Vframe_list) || !EQ (XCAR (Vframe_list), frame))
2954 #if GLYPH_DEBUG
2955 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2956 #endif
2958 x_free_frame_resources (f);
2960 #if GLYPH_DEBUG
2961 /* Check that reference counts are indeed correct. */
2962 xassert (dpyinfo->reference_count == dpyinfo_refcount);
2963 xassert (dpyinfo->image_cache->refcount == image_cache_refcount);
2964 #endif
2965 return Qt;
2968 return Qnil;
2972 static void
2973 x_default_font_parameter (struct frame *f, Lisp_Object parms)
2975 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2976 Lisp_Object font_param = x_get_arg (dpyinfo, parms, Qfont, NULL, NULL,
2977 RES_TYPE_STRING);
2978 Lisp_Object font = Qnil;
2979 if (EQ (font_param, Qunbound))
2980 font_param = Qnil;
2982 if (NILP (font_param))
2984 /* System font should take precedendce over X resources. We suggest this
2985 regardless of font-use-system-font because .emacs may not have been
2986 read yet. */
2987 const char *system_font = xsettings_get_system_font ();
2988 if (system_font)
2990 char *name = xstrdup (system_font);
2991 font = font_open_by_name (f, name);
2992 free (name);
2996 if (NILP (font))
2997 font = !NILP (font_param) ? font_param
2998 : x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
3000 if (! FONTP (font) && ! STRINGP (font))
3002 char *names[]
3004 #ifdef HAVE_XFT
3005 /* This will find the normal Xft font. */
3006 "monospace-10",
3007 #endif
3008 "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
3009 "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3010 "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3011 /* This was formerly the first thing tried, but it finds
3012 too many fonts and takes too long. */
3013 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
3014 /* If those didn't work, look for something which will
3015 at least work. */
3016 "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
3017 "fixed",
3018 NULL };
3019 int i;
3021 for (i = 0; names[i]; i++)
3023 font = font_open_by_name (f, names[i]);
3024 if (! NILP (font))
3025 break;
3027 if (NILP (font))
3028 error ("No suitable font was found");
3030 else if (!NILP (font_param))
3032 /* Remember the explicit font parameter, so we can re-apply it after
3033 we've applied the `default' face settings. */
3034 x_set_frame_parameters (f, Fcons (Fcons (Qfont_param, font_param), Qnil));
3037 /* This call will make X resources override any system font setting. */
3038 x_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING);
3042 DEFUN ("x-wm-set-size-hint", Fx_wm_set_size_hint, Sx_wm_set_size_hint,
3043 0, 1, 0,
3044 doc: /* Send the size hints for frame FRAME to the window manager.
3045 If FRAME is nil, use the selected frame. */)
3046 (Lisp_Object frame)
3048 struct frame *f;
3049 if (NILP (frame))
3050 frame = selected_frame;
3051 f = XFRAME (frame);
3052 BLOCK_INPUT;
3053 if (FRAME_X_P (f))
3054 x_wm_set_size_hint (f, 0, 0);
3055 UNBLOCK_INPUT;
3056 return Qnil;
3059 static void
3060 set_machine_and_pid_properties (struct frame *f)
3062 /* See the above comment "Note: Encoding strategy". */
3063 XTextProperty text;
3064 int bytes, stringp;
3065 int do_free_text_value = 0;
3066 long pid = (long) getpid ();
3068 text.value = x_encode_text (Vsystem_name,
3069 Qcompound_text, 0, &bytes, &stringp,
3070 &do_free_text_value);
3071 text.encoding = (stringp ? XA_STRING
3072 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
3073 text.format = 8;
3074 text.nitems = bytes;
3075 XSetWMClientMachine (FRAME_X_DISPLAY (f),
3076 FRAME_OUTER_WINDOW (f),
3077 &text);
3078 if (do_free_text_value)
3079 xfree (text.value);
3081 XChangeProperty (FRAME_X_DISPLAY (f),
3082 FRAME_OUTER_WINDOW (f),
3083 XInternAtom (FRAME_X_DISPLAY (f),
3084 "_NET_WM_PID",
3085 False),
3086 XA_CARDINAL, 32, PropModeReplace,
3087 (unsigned char *) &pid, 1);
3090 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
3091 1, 1, 0,
3092 doc: /* Make a new X window, which is called a "frame" in Emacs terms.
3093 Return an Emacs frame object.
3094 PARMS is an alist of frame parameters.
3095 If the parameters specify that the frame should not have a minibuffer,
3096 and do not specify a specific minibuffer window to use,
3097 then `default-minibuffer-frame' must be a frame whose minibuffer can
3098 be shared by the new frame.
3100 This function is an internal primitive--use `make-frame' instead. */)
3101 (Lisp_Object parms)
3103 struct frame *f;
3104 Lisp_Object frame, tem;
3105 Lisp_Object name;
3106 int minibuffer_only = 0;
3107 long window_prompting = 0;
3108 int width, height;
3109 int count = SPECPDL_INDEX ();
3110 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
3111 Lisp_Object display;
3112 struct x_display_info *dpyinfo = NULL;
3113 Lisp_Object parent;
3114 struct kboard *kb;
3116 parms = Fcopy_alist (parms);
3118 /* Use this general default value to start with
3119 until we know if this frame has a specified name. */
3120 Vx_resource_name = Vinvocation_name;
3122 display = x_get_arg (dpyinfo, parms, Qterminal, 0, 0, RES_TYPE_NUMBER);
3123 if (EQ (display, Qunbound))
3124 display = x_get_arg (dpyinfo, parms, Qdisplay, 0, 0, RES_TYPE_STRING);
3125 if (EQ (display, Qunbound))
3126 display = Qnil;
3127 dpyinfo = check_x_display_info (display);
3128 kb = dpyinfo->terminal->kboard;
3130 if (!dpyinfo->terminal->name)
3131 error ("Terminal is not live, can't create new frames on it");
3133 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
3134 if (!STRINGP (name)
3135 && ! EQ (name, Qunbound)
3136 && ! NILP (name))
3137 error ("Invalid frame name--not a string or nil");
3139 if (STRINGP (name))
3140 Vx_resource_name = name;
3142 /* See if parent window is specified. */
3143 parent = x_get_arg (dpyinfo, parms, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
3144 if (EQ (parent, Qunbound))
3145 parent = Qnil;
3146 if (! NILP (parent))
3147 CHECK_NUMBER (parent);
3149 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
3150 /* No need to protect DISPLAY because that's not used after passing
3151 it to make_frame_without_minibuffer. */
3152 frame = Qnil;
3153 GCPRO4 (parms, parent, name, frame);
3154 tem = x_get_arg (dpyinfo, parms, Qminibuffer, "minibuffer", "Minibuffer",
3155 RES_TYPE_SYMBOL);
3156 if (EQ (tem, Qnone) || NILP (tem))
3157 f = make_frame_without_minibuffer (Qnil, kb, display);
3158 else if (EQ (tem, Qonly))
3160 f = make_minibuffer_frame ();
3161 minibuffer_only = 1;
3163 else if (WINDOWP (tem))
3164 f = make_frame_without_minibuffer (tem, kb, display);
3165 else
3166 f = make_frame (1);
3168 XSETFRAME (frame, f);
3170 /* Note that X Windows does support scroll bars. */
3171 FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
3173 f->terminal = dpyinfo->terminal;
3174 f->terminal->reference_count++;
3176 f->output_method = output_x_window;
3177 f->output_data.x = (struct x_output *) xmalloc (sizeof (struct x_output));
3178 memset (f->output_data.x, 0, sizeof (struct x_output));
3179 f->output_data.x->icon_bitmap = -1;
3180 FRAME_FONTSET (f) = -1;
3181 f->output_data.x->scroll_bar_foreground_pixel = -1;
3182 f->output_data.x->scroll_bar_background_pixel = -1;
3183 #ifdef USE_TOOLKIT_SCROLL_BARS
3184 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
3185 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
3186 #endif /* USE_TOOLKIT_SCROLL_BARS */
3188 f->icon_name
3189 = x_get_arg (dpyinfo, parms, Qicon_name, "iconName", "Title",
3190 RES_TYPE_STRING);
3191 if (! STRINGP (f->icon_name))
3192 f->icon_name = Qnil;
3194 FRAME_X_DISPLAY_INFO (f) = dpyinfo;
3196 /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe. */
3197 record_unwind_protect (unwind_create_frame, frame);
3198 #if GLYPH_DEBUG
3199 image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
3200 dpyinfo_refcount = dpyinfo->reference_count;
3201 #endif /* GLYPH_DEBUG */
3203 /* These colors will be set anyway later, but it's important
3204 to get the color reference counts right, so initialize them! */
3206 Lisp_Object black;
3207 struct gcpro gcpro1;
3209 /* Function x_decode_color can signal an error. Make
3210 sure to initialize color slots so that we won't try
3211 to free colors we haven't allocated. */
3212 FRAME_FOREGROUND_PIXEL (f) = -1;
3213 FRAME_BACKGROUND_PIXEL (f) = -1;
3214 f->output_data.x->cursor_pixel = -1;
3215 f->output_data.x->cursor_foreground_pixel = -1;
3216 f->output_data.x->border_pixel = -1;
3217 f->output_data.x->mouse_pixel = -1;
3219 black = build_string ("black");
3220 GCPRO1 (black);
3221 FRAME_FOREGROUND_PIXEL (f)
3222 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3223 FRAME_BACKGROUND_PIXEL (f)
3224 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3225 f->output_data.x->cursor_pixel
3226 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3227 f->output_data.x->cursor_foreground_pixel
3228 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3229 f->output_data.x->border_pixel
3230 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3231 f->output_data.x->mouse_pixel
3232 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3233 UNGCPRO;
3236 /* Specify the parent under which to make this X window. */
3238 if (!NILP (parent))
3240 f->output_data.x->parent_desc = (Window) XFASTINT (parent);
3241 f->output_data.x->explicit_parent = 1;
3243 else
3245 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
3246 f->output_data.x->explicit_parent = 0;
3249 /* Set the name; the functions to which we pass f expect the name to
3250 be set. */
3251 if (EQ (name, Qunbound) || NILP (name))
3253 f->name = build_string (dpyinfo->x_id_name);
3254 f->explicit_name = 0;
3256 else
3258 f->name = name;
3259 f->explicit_name = 1;
3260 /* use the frame's title when getting resources for this frame. */
3261 specbind (Qx_resource_name, name);
3264 f->resx = dpyinfo->resx;
3265 f->resy = dpyinfo->resy;
3267 #ifdef HAVE_FREETYPE
3268 #ifdef HAVE_XFT
3269 register_font_driver (&xftfont_driver, f);
3270 #else /* not HAVE_XFT */
3271 register_font_driver (&ftxfont_driver, f);
3272 #endif /* not HAVE_XFT */
3273 #endif /* HAVE_FREETYPE */
3274 register_font_driver (&xfont_driver, f);
3276 x_default_parameter (f, parms, Qfont_backend, Qnil,
3277 "fontBackend", "FontBackend", RES_TYPE_STRING);
3279 /* Extract the window parameters from the supplied values
3280 that are needed to determine window geometry. */
3281 x_default_font_parameter (f, parms);
3282 if (!FRAME_FONT (f))
3284 delete_frame (frame, Qnoelisp);
3285 error ("Invalid frame font");
3288 /* Frame contents get displaced if an embedded X window has a border. */
3289 if (! FRAME_X_EMBEDDED_P (f))
3290 x_default_parameter (f, parms, Qborder_width, make_number (0),
3291 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
3293 /* This defaults to 1 in order to match xterm. We recognize either
3294 internalBorderWidth or internalBorder (which is what xterm calls
3295 it). */
3296 if (NILP (Fassq (Qinternal_border_width, parms)))
3298 Lisp_Object value;
3300 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
3301 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
3302 if (! EQ (value, Qunbound))
3303 parms = Fcons (Fcons (Qinternal_border_width, value),
3304 parms);
3306 x_default_parameter (f, parms, Qinternal_border_width,
3307 #ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */
3308 make_number (0),
3309 #else
3310 make_number (1),
3311 #endif
3312 "internalBorderWidth", "internalBorderWidth",
3313 RES_TYPE_NUMBER);
3314 x_default_parameter (f, parms, Qvertical_scroll_bars,
3315 #if defined(USE_GTK) && defined(USE_TOOLKIT_SCROLL_BARS)
3316 Qright,
3317 #else
3318 Qleft,
3319 #endif
3320 "verticalScrollBars", "ScrollBars",
3321 RES_TYPE_SYMBOL);
3323 /* Also do the stuff which must be set before the window exists. */
3324 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
3325 "foreground", "Foreground", RES_TYPE_STRING);
3326 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
3327 "background", "Background", RES_TYPE_STRING);
3328 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
3329 "pointerColor", "Foreground", RES_TYPE_STRING);
3330 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
3331 "cursorColor", "Foreground", RES_TYPE_STRING);
3332 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
3333 "borderColor", "BorderColor", RES_TYPE_STRING);
3334 x_default_parameter (f, parms, Qscreen_gamma, Qnil,
3335 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
3336 x_default_parameter (f, parms, Qline_spacing, Qnil,
3337 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
3338 x_default_parameter (f, parms, Qleft_fringe, Qnil,
3339 "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
3340 x_default_parameter (f, parms, Qright_fringe, Qnil,
3341 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
3343 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_foreground,
3344 "scrollBarForeground",
3345 "ScrollBarForeground", 1);
3346 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_background,
3347 "scrollBarBackground",
3348 "ScrollBarBackground", 0);
3350 /* Init faces before x_default_parameter is called for scroll-bar
3351 parameters because that function calls x_set_scroll_bar_width,
3352 which calls change_frame_size, which calls Fset_window_buffer,
3353 which runs hooks, which call Fvertical_motion. At the end, we
3354 end up in init_iterator with a null face cache, which should not
3355 happen. */
3356 init_frame_faces (f);
3358 /* The X resources controlling the menu-bar and tool-bar are
3359 processed specially at startup, and reflected in the mode
3360 variables; ignore them here. */
3361 x_default_parameter (f, parms, Qmenu_bar_lines,
3362 NILP (Vmenu_bar_mode)
3363 ? make_number (0) : make_number (1),
3364 NULL, NULL, RES_TYPE_NUMBER);
3365 x_default_parameter (f, parms, Qtool_bar_lines,
3366 NILP (Vtool_bar_mode)
3367 ? make_number (0) : make_number (1),
3368 NULL, NULL, RES_TYPE_NUMBER);
3370 x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
3371 "bufferPredicate", "BufferPredicate",
3372 RES_TYPE_SYMBOL);
3373 x_default_parameter (f, parms, Qtitle, Qnil,
3374 "title", "Title", RES_TYPE_STRING);
3375 x_default_parameter (f, parms, Qwait_for_wm, Qt,
3376 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
3377 x_default_parameter (f, parms, Qfullscreen, Qnil,
3378 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
3380 /* Compute the size of the X window. */
3381 window_prompting = x_figure_window_size (f, parms, 1);
3383 tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
3384 f->no_split = minibuffer_only || EQ (tem, Qt);
3386 x_icon_verify (f, parms);
3388 /* Create the X widget or window. */
3389 #ifdef USE_X_TOOLKIT
3390 x_window (f, window_prompting, minibuffer_only);
3391 #else
3392 x_window (f);
3393 #endif
3395 x_icon (f, parms);
3396 x_make_gc (f);
3398 /* Now consider the frame official. */
3399 FRAME_X_DISPLAY_INFO (f)->reference_count++;
3400 Vframe_list = Fcons (frame, Vframe_list);
3402 /* We need to do this after creating the X window, so that the
3403 icon-creation functions can say whose icon they're describing. */
3404 x_default_parameter (f, parms, Qicon_type, Qt,
3405 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
3407 x_default_parameter (f, parms, Qauto_raise, Qnil,
3408 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3409 x_default_parameter (f, parms, Qauto_lower, Qnil,
3410 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3411 x_default_parameter (f, parms, Qcursor_type, Qbox,
3412 "cursorType", "CursorType", RES_TYPE_SYMBOL);
3413 x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
3414 "scrollBarWidth", "ScrollBarWidth",
3415 RES_TYPE_NUMBER);
3416 x_default_parameter (f, parms, Qalpha, Qnil,
3417 "alpha", "Alpha", RES_TYPE_NUMBER);
3419 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3420 Change will not be effected unless different from the current
3421 FRAME_LINES (f). */
3422 width = FRAME_COLS (f);
3423 height = FRAME_LINES (f);
3425 SET_FRAME_COLS (f, 0);
3426 FRAME_LINES (f) = 0;
3427 change_frame_size (f, height, width, 1, 0, 0);
3429 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3430 /* Create the menu bar. */
3431 if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
3433 /* If this signals an error, we haven't set size hints for the
3434 frame and we didn't make it visible. */
3435 initialize_frame_menubar (f);
3437 #ifndef USE_GTK
3438 /* This is a no-op, except under Motif where it arranges the
3439 main window for the widgets on it. */
3440 lw_set_main_areas (f->output_data.x->column_widget,
3441 f->output_data.x->menubar_widget,
3442 f->output_data.x->edit_widget);
3443 #endif /* not USE_GTK */
3445 #endif /* USE_X_TOOLKIT || USE_GTK */
3447 /* Tell the server what size and position, etc, we want, and how
3448 badly we want them. This should be done after we have the menu
3449 bar so that its size can be taken into account. */
3450 BLOCK_INPUT;
3451 x_wm_set_size_hint (f, window_prompting, 0);
3452 UNBLOCK_INPUT;
3454 /* Make the window appear on the frame and enable display, unless
3455 the caller says not to. However, with explicit parent, Emacs
3456 cannot control visibility, so don't try. */
3457 if (! f->output_data.x->explicit_parent)
3459 Lisp_Object visibility;
3461 visibility = x_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
3462 RES_TYPE_SYMBOL);
3463 if (EQ (visibility, Qunbound))
3464 visibility = Qt;
3466 if (EQ (visibility, Qicon))
3467 x_iconify_frame (f);
3468 else if (! NILP (visibility))
3469 x_make_frame_visible (f);
3470 else
3471 /* Must have been Qnil. */
3475 BLOCK_INPUT;
3477 /* Set machine name and pid for the purpose of window managers. */
3478 set_machine_and_pid_properties(f);
3480 /* Set the WM leader property. GTK does this itself, so this is not
3481 needed when using GTK. */
3482 if (dpyinfo->client_leader_window != 0)
3484 XChangeProperty (FRAME_X_DISPLAY (f),
3485 FRAME_OUTER_WINDOW (f),
3486 dpyinfo->Xatom_wm_client_leader,
3487 XA_WINDOW, 32, PropModeReplace,
3488 (unsigned char *) &dpyinfo->client_leader_window, 1);
3491 UNBLOCK_INPUT;
3493 /* Initialize `default-minibuffer-frame' in case this is the first
3494 frame on this terminal. */
3495 if (FRAME_HAS_MINIBUF_P (f)
3496 && (!FRAMEP (kb->Vdefault_minibuffer_frame)
3497 || !FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame))))
3498 kb->Vdefault_minibuffer_frame = frame;
3500 /* All remaining specified parameters, which have not been "used"
3501 by x_get_arg and friends, now go in the misc. alist of the frame. */
3502 for (tem = parms; CONSP (tem); tem = XCDR (tem))
3503 if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
3504 f->param_alist = Fcons (XCAR (tem), f->param_alist);
3506 UNGCPRO;
3508 /* Make sure windows on this frame appear in calls to next-window
3509 and similar functions. */
3510 Vwindow_list = Qnil;
3512 return unbind_to (count, frame);
3516 /* FRAME is used only to get a handle on the X display. We don't pass the
3517 display info directly because we're called from frame.c, which doesn't
3518 know about that structure. */
3520 Lisp_Object
3521 x_get_focus_frame (struct frame *frame)
3523 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (frame);
3524 Lisp_Object xfocus;
3525 if (! dpyinfo->x_focus_frame)
3526 return Qnil;
3528 XSETFRAME (xfocus, dpyinfo->x_focus_frame);
3529 return xfocus;
3533 /* In certain situations, when the window manager follows a
3534 click-to-focus policy, there seems to be no way around calling
3535 XSetInputFocus to give another frame the input focus .
3537 In an ideal world, XSetInputFocus should generally be avoided so
3538 that applications don't interfere with the window manager's focus
3539 policy. But I think it's okay to use when it's clearly done
3540 following a user-command. */
3542 DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
3543 doc: /* Set the input focus to FRAME.
3544 FRAME nil means use the selected frame. */)
3545 (Lisp_Object frame)
3547 struct frame *f = check_x_frame (frame);
3548 Display *dpy = FRAME_X_DISPLAY (f);
3550 BLOCK_INPUT;
3551 x_catch_errors (dpy);
3552 XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3553 RevertToParent, CurrentTime);
3554 x_ewmh_activate_frame (f);
3555 x_uncatch_errors ();
3556 UNBLOCK_INPUT;
3558 return Qnil;
3562 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
3563 doc: /* Internal function called by `color-defined-p', which see. */)
3564 (Lisp_Object color, Lisp_Object frame)
3566 XColor foo;
3567 FRAME_PTR f = check_x_frame (frame);
3569 CHECK_STRING (color);
3571 if (x_defined_color (f, SDATA (color), &foo, 0))
3572 return Qt;
3573 else
3574 return Qnil;
3577 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
3578 doc: /* Internal function called by `color-values', which see. */)
3579 (Lisp_Object color, Lisp_Object frame)
3581 XColor foo;
3582 FRAME_PTR f = check_x_frame (frame);
3584 CHECK_STRING (color);
3586 if (x_defined_color (f, SDATA (color), &foo, 0))
3587 return list3 (make_number (foo.red),
3588 make_number (foo.green),
3589 make_number (foo.blue));
3590 else
3591 return Qnil;
3594 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
3595 doc: /* Internal function called by `display-color-p', which see. */)
3596 (Lisp_Object terminal)
3598 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3600 if (dpyinfo->n_planes <= 2)
3601 return Qnil;
3603 switch (dpyinfo->visual->class)
3605 case StaticColor:
3606 case PseudoColor:
3607 case TrueColor:
3608 case DirectColor:
3609 return Qt;
3611 default:
3612 return Qnil;
3616 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
3617 0, 1, 0,
3618 doc: /* Return t if the X display supports shades of gray.
3619 Note that color displays do support shades of gray.
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 if (dpyinfo->n_planes <= 1)
3628 return Qnil;
3630 switch (dpyinfo->visual->class)
3632 case StaticColor:
3633 case PseudoColor:
3634 case TrueColor:
3635 case DirectColor:
3636 case StaticGray:
3637 case GrayScale:
3638 return Qt;
3640 default:
3641 return Qnil;
3645 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
3646 0, 1, 0,
3647 doc: /* Return the width in pixels of the X display TERMINAL.
3648 The optional argument TERMINAL specifies which display to ask about.
3649 TERMINAL should be a terminal object, a frame or a display name (a string).
3650 If omitted or nil, that stands for the selected frame's display. */)
3651 (Lisp_Object terminal)
3653 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3655 return make_number (x_display_pixel_width (dpyinfo));
3658 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
3659 Sx_display_pixel_height, 0, 1, 0,
3660 doc: /* Return the height in pixels of the X display TERMINAL.
3661 The optional argument TERMINAL specifies which display to ask about.
3662 TERMINAL should be a terminal object, a frame or a display name (a string).
3663 If omitted or nil, that stands for the selected frame's display. */)
3664 (Lisp_Object terminal)
3666 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3668 return make_number (x_display_pixel_height (dpyinfo));
3671 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
3672 0, 1, 0,
3673 doc: /* Return the number of bitplanes of the X display TERMINAL.
3674 The optional argument TERMINAL specifies which display to ask about.
3675 TERMINAL should be a terminal object, a frame or a display name (a string).
3676 If omitted or nil, that stands for the selected frame's display. */)
3677 (Lisp_Object terminal)
3679 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3681 return make_number (dpyinfo->n_planes);
3684 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
3685 0, 1, 0,
3686 doc: /* Return the number of color cells of the X display TERMINAL.
3687 The optional argument TERMINAL specifies which display to ask about.
3688 TERMINAL should be a terminal object, a frame or a display name (a string).
3689 If omitted or nil, that stands for the selected frame's display. */)
3690 (Lisp_Object terminal)
3692 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3694 int nr_planes = DisplayPlanes (dpyinfo->display,
3695 XScreenNumberOfScreen (dpyinfo->screen));
3697 /* Truncate nr_planes to 24 to avoid integer overflow.
3698 Some displays says 32, but only 24 bits are actually significant.
3699 There are only very few and rare video cards that have more than
3700 24 significant bits. Also 24 bits is more than 16 million colors,
3701 it "should be enough for everyone". */
3702 if (nr_planes > 24) nr_planes = 24;
3704 return make_number (1 << nr_planes);
3707 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
3708 Sx_server_max_request_size,
3709 0, 1, 0,
3710 doc: /* Return the maximum request size of the X server of display TERMINAL.
3711 The optional argument TERMINAL specifies which display to ask about.
3712 TERMINAL should be a terminal object, a frame or a display name (a string).
3713 If omitted or nil, that stands for the selected frame's display. */)
3714 (Lisp_Object terminal)
3716 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3718 return make_number (MAXREQUEST (dpyinfo->display));
3721 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
3722 doc: /* Return the "vendor ID" string of the X server of display TERMINAL.
3723 \(Labelling every distributor as a "vendor" embodies the false assumption
3724 that operating systems cannot be developed and distributed noncommercially.)
3725 The optional argument TERMINAL specifies which display to ask about.
3726 TERMINAL should be a terminal object, a frame or a display name (a string).
3727 If omitted or nil, that stands for the selected frame's display. */)
3728 (Lisp_Object terminal)
3730 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3731 char *vendor = ServerVendor (dpyinfo->display);
3733 if (! vendor) vendor = "";
3734 return build_string (vendor);
3737 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
3738 doc: /* Return the version numbers of the X server of display TERMINAL.
3739 The value is a list of three integers: the major and minor
3740 version numbers of the X Protocol in use, and the distributor-specific release
3741 number. See also the function `x-server-vendor'.
3743 The optional argument TERMINAL specifies which display to ask about.
3744 TERMINAL should be a terminal object, a frame or a display name (a string).
3745 If omitted or nil, that stands for the selected frame's display. */)
3746 (Lisp_Object terminal)
3748 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3749 Display *dpy = dpyinfo->display;
3751 return Fcons (make_number (ProtocolVersion (dpy)),
3752 Fcons (make_number (ProtocolRevision (dpy)),
3753 Fcons (make_number (VendorRelease (dpy)), Qnil)));
3756 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
3757 doc: /* Return the number of screens on the X server of display TERMINAL.
3758 The optional argument TERMINAL specifies which display to ask about.
3759 TERMINAL should be a terminal object, a frame or a display name (a string).
3760 If omitted or nil, that stands for the selected frame's display. */)
3761 (Lisp_Object terminal)
3763 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3765 return make_number (ScreenCount (dpyinfo->display));
3768 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
3769 doc: /* Return the height in millimeters of the X display TERMINAL.
3770 The optional argument TERMINAL specifies which display to ask about.
3771 TERMINAL should be a terminal object, a frame or a display name (a string).
3772 If omitted or nil, that stands for the selected frame's display. */)
3773 (Lisp_Object terminal)
3775 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3777 return make_number (HeightMMOfScreen (dpyinfo->screen));
3780 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
3781 doc: /* Return the width in millimeters of the X display TERMINAL.
3782 The optional argument TERMINAL specifies which display to ask about.
3783 TERMINAL should be a terminal object, a frame or a display name (a string).
3784 If omitted or nil, that stands for the selected frame's display. */)
3785 (Lisp_Object terminal)
3787 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3789 return make_number (WidthMMOfScreen (dpyinfo->screen));
3792 DEFUN ("x-display-backing-store", Fx_display_backing_store,
3793 Sx_display_backing_store, 0, 1, 0,
3794 doc: /* Return an indication of whether X display TERMINAL does backing store.
3795 The value may be `always', `when-mapped', or `not-useful'.
3796 The optional argument TERMINAL specifies which display to ask about.
3797 TERMINAL should be a terminal object, a frame or a display name (a string).
3798 If omitted or nil, that stands for the selected frame's display. */)
3799 (Lisp_Object terminal)
3801 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3802 Lisp_Object result;
3804 switch (DoesBackingStore (dpyinfo->screen))
3806 case Always:
3807 result = intern ("always");
3808 break;
3810 case WhenMapped:
3811 result = intern ("when-mapped");
3812 break;
3814 case NotUseful:
3815 result = intern ("not-useful");
3816 break;
3818 default:
3819 error ("Strange value for BackingStore parameter of screen");
3820 result = Qnil;
3823 return result;
3826 DEFUN ("x-display-visual-class", Fx_display_visual_class,
3827 Sx_display_visual_class, 0, 1, 0,
3828 doc: /* Return the visual class of the X display TERMINAL.
3829 The value is one of the symbols `static-gray', `gray-scale',
3830 `static-color', `pseudo-color', `true-color', or `direct-color'.
3832 The optional argument TERMINAL specifies which display to ask about.
3833 TERMINAL should a terminal object, a frame or a display name (a string).
3834 If omitted or nil, that stands for the selected frame's display. */)
3835 (Lisp_Object terminal)
3837 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3838 Lisp_Object result;
3840 switch (dpyinfo->visual->class)
3842 case StaticGray:
3843 result = intern ("static-gray");
3844 break;
3845 case GrayScale:
3846 result = intern ("gray-scale");
3847 break;
3848 case StaticColor:
3849 result = intern ("static-color");
3850 break;
3851 case PseudoColor:
3852 result = intern ("pseudo-color");
3853 break;
3854 case TrueColor:
3855 result = intern ("true-color");
3856 break;
3857 case DirectColor:
3858 result = intern ("direct-color");
3859 break;
3860 default:
3861 error ("Display has an unknown visual class");
3862 result = Qnil;
3865 return result;
3868 DEFUN ("x-display-save-under", Fx_display_save_under,
3869 Sx_display_save_under, 0, 1, 0,
3870 doc: /* Return t if the X display TERMINAL supports the save-under feature.
3871 The optional argument TERMINAL specifies which display to ask about.
3872 TERMINAL should be a terminal object, a frame or a display name (a string).
3873 If omitted or nil, that stands for the selected frame's display. */)
3874 (Lisp_Object terminal)
3876 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3878 if (DoesSaveUnders (dpyinfo->screen) == True)
3879 return Qt;
3880 else
3881 return Qnil;
3885 x_pixel_width (register struct frame *f)
3887 return FRAME_PIXEL_WIDTH (f);
3891 x_pixel_height (register struct frame *f)
3893 return FRAME_PIXEL_HEIGHT (f);
3897 x_char_width (register struct frame *f)
3899 return FRAME_COLUMN_WIDTH (f);
3903 x_char_height (register struct frame *f)
3905 return FRAME_LINE_HEIGHT (f);
3909 x_screen_planes (register struct frame *f)
3911 return FRAME_X_DISPLAY_INFO (f)->n_planes;
3916 /************************************************************************
3917 X Displays
3918 ************************************************************************/
3921 /* Mapping visual names to visuals. */
3923 static struct visual_class
3925 char *name;
3926 int class;
3928 visual_classes[] =
3930 {"StaticGray", StaticGray},
3931 {"GrayScale", GrayScale},
3932 {"StaticColor", StaticColor},
3933 {"PseudoColor", PseudoColor},
3934 {"TrueColor", TrueColor},
3935 {"DirectColor", DirectColor},
3936 {NULL, 0}
3940 #ifndef HAVE_XSCREENNUMBEROFSCREEN
3942 /* Value is the screen number of screen SCR. This is a substitute for
3943 the X function with the same name when that doesn't exist. */
3946 XScreenNumberOfScreen (scr)
3947 register Screen *scr;
3949 Display *dpy = scr->display;
3950 int i;
3952 for (i = 0; i < dpy->nscreens; ++i)
3953 if (scr == dpy->screens + i)
3954 break;
3956 return i;
3959 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
3962 /* Select the visual that should be used on display DPYINFO. Set
3963 members of DPYINFO appropriately. Called from x_term_init. */
3965 void
3966 select_visual (struct x_display_info *dpyinfo)
3968 Display *dpy = dpyinfo->display;
3969 Screen *screen = dpyinfo->screen;
3970 Lisp_Object value;
3972 /* See if a visual is specified. */
3973 value = display_x_get_resource (dpyinfo,
3974 build_string ("visualClass"),
3975 build_string ("VisualClass"),
3976 Qnil, Qnil);
3977 if (STRINGP (value))
3979 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
3980 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
3981 depth, a decimal number. NAME is compared with case ignored. */
3982 char *s = (char *) alloca (SBYTES (value) + 1);
3983 char *dash;
3984 int i, class = -1;
3985 XVisualInfo vinfo;
3987 strcpy (s, SDATA (value));
3988 dash = strchr (s, '-');
3989 if (dash)
3991 dpyinfo->n_planes = atoi (dash + 1);
3992 *dash = '\0';
3994 else
3995 /* We won't find a matching visual with depth 0, so that
3996 an error will be printed below. */
3997 dpyinfo->n_planes = 0;
3999 /* Determine the visual class. */
4000 for (i = 0; visual_classes[i].name; ++i)
4001 if (xstrcasecmp (s, visual_classes[i].name) == 0)
4003 class = visual_classes[i].class;
4004 break;
4007 /* Look up a matching visual for the specified class. */
4008 if (class == -1
4009 || !XMatchVisualInfo (dpy, XScreenNumberOfScreen (screen),
4010 dpyinfo->n_planes, class, &vinfo))
4011 fatal ("Invalid visual specification `%s'", SDATA (value));
4013 dpyinfo->visual = vinfo.visual;
4015 else
4017 int n_visuals;
4018 XVisualInfo *vinfo, vinfo_template;
4020 dpyinfo->visual = DefaultVisualOfScreen (screen);
4022 vinfo_template.visualid = XVisualIDFromVisual (dpyinfo->visual);
4023 vinfo_template.screen = XScreenNumberOfScreen (screen);
4024 vinfo = XGetVisualInfo (dpy, VisualIDMask | VisualScreenMask,
4025 &vinfo_template, &n_visuals);
4026 if (n_visuals <= 0)
4027 fatal ("Can't get proper X visual info");
4029 dpyinfo->n_planes = vinfo->depth;
4030 XFree ((char *) vinfo);
4035 /* Return the X display structure for the display named NAME.
4036 Open a new connection if necessary. */
4038 struct x_display_info *
4039 x_display_info_for_name (Lisp_Object name)
4041 Lisp_Object names;
4042 struct x_display_info *dpyinfo;
4044 CHECK_STRING (name);
4046 #if 0
4047 if (! EQ (Vinitial_window_system, intern ("x")))
4048 error ("Not using X Windows"); /* That doesn't stop us anymore. */
4049 #endif
4051 for (dpyinfo = x_display_list, names = x_display_name_list;
4052 dpyinfo;
4053 dpyinfo = dpyinfo->next, names = XCDR (names))
4055 Lisp_Object tem;
4056 tem = Fstring_equal (XCAR (XCAR (names)), name);
4057 if (!NILP (tem))
4058 return dpyinfo;
4061 /* Use this general default value to start with. */
4062 Vx_resource_name = Vinvocation_name;
4064 validate_x_resource_name ();
4066 dpyinfo = x_term_init (name, (char *)0,
4067 (char *) SDATA (Vx_resource_name));
4069 if (dpyinfo == 0)
4070 error ("Cannot connect to X server %s", SDATA (name));
4072 x_in_use = 1;
4073 XSETFASTINT (Vwindow_system_version, 11);
4075 return dpyinfo;
4079 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
4080 1, 3, 0,
4081 doc: /* Open a connection to an X server.
4082 DISPLAY is the name of the display to connect to.
4083 Optional second arg XRM-STRING is a string of resources in xrdb format.
4084 If the optional third arg MUST-SUCCEED is non-nil,
4085 terminate Emacs if we can't open the connection. */)
4086 (Lisp_Object display, Lisp_Object xrm_string, Lisp_Object must_succeed)
4088 unsigned char *xrm_option;
4089 struct x_display_info *dpyinfo;
4091 CHECK_STRING (display);
4092 if (! NILP (xrm_string))
4093 CHECK_STRING (xrm_string);
4095 #if 0
4096 if (! EQ (Vinitial_window_system, intern ("x")))
4097 error ("Not using X Windows"); /* That doesn't stop us anymore. */
4098 #endif
4100 if (! NILP (xrm_string))
4101 xrm_option = (unsigned char *) SDATA (xrm_string);
4102 else
4103 xrm_option = (unsigned char *) 0;
4105 validate_x_resource_name ();
4107 /* This is what opens the connection and sets x_current_display.
4108 This also initializes many symbols, such as those used for input. */
4109 dpyinfo = x_term_init (display, xrm_option,
4110 (char *) SDATA (Vx_resource_name));
4112 if (dpyinfo == 0)
4114 if (!NILP (must_succeed))
4115 fatal ("Cannot connect to X server %s.\n\
4116 Check the DISPLAY environment variable or use `-d'.\n\
4117 Also use the `xauth' program to verify that you have the proper\n\
4118 authorization information needed to connect the X server.\n\
4119 An insecure way to solve the problem may be to use `xhost'.\n",
4120 SDATA (display));
4121 else
4122 error ("Cannot connect to X server %s", SDATA (display));
4125 x_in_use = 1;
4127 XSETFASTINT (Vwindow_system_version, 11);
4128 return Qnil;
4131 DEFUN ("x-close-connection", Fx_close_connection,
4132 Sx_close_connection, 1, 1, 0,
4133 doc: /* Close the connection to TERMINAL's X server.
4134 For TERMINAL, specify a terminal object, a frame or a display name (a
4135 string). If TERMINAL is nil, that stands for the selected frame's
4136 terminal. */)
4137 (Lisp_Object terminal)
4139 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4141 if (dpyinfo->reference_count > 0)
4142 error ("Display still has frames on it");
4144 x_delete_terminal (dpyinfo->terminal);
4146 return Qnil;
4149 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
4150 doc: /* Return the list of display names that Emacs has connections to. */)
4151 (void)
4153 Lisp_Object tail, result;
4155 result = Qnil;
4156 for (tail = x_display_name_list; CONSP (tail); tail = XCDR (tail))
4157 result = Fcons (XCAR (XCAR (tail)), result);
4159 return result;
4162 DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
4163 doc: /* If ON is non-nil, report X errors as soon as the erring request is made.
4164 If ON is nil, allow buffering of requests.
4165 Turning on synchronization prohibits the Xlib routines from buffering
4166 requests and seriously degrades performance, but makes debugging much
4167 easier.
4168 The optional second argument TERMINAL specifies which display to act on.
4169 TERMINAL should be a terminal object, a frame or a display name (a string).
4170 If TERMINAL is omitted or nil, that stands for the selected frame's display. */)
4171 (Lisp_Object on, Lisp_Object terminal)
4173 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4175 XSynchronize (dpyinfo->display, !EQ (on, Qnil));
4177 return Qnil;
4180 /* Wait for responses to all X commands issued so far for frame F. */
4182 void
4183 x_sync (FRAME_PTR f)
4185 BLOCK_INPUT;
4186 XSync (FRAME_X_DISPLAY (f), False);
4187 UNBLOCK_INPUT;
4191 /***********************************************************************
4192 Window properties
4193 ***********************************************************************/
4195 DEFUN ("x-change-window-property", Fx_change_window_property,
4196 Sx_change_window_property, 2, 6, 0,
4197 doc: /* Change window property PROP to VALUE on the X window of FRAME.
4198 PROP must be a string.
4199 VALUE may be a string or a list of conses, numbers and/or strings.
4200 If an element in the list is a string, it is converted to
4201 an Atom and the value of the Atom is used. If an element is a cons,
4202 it is converted to a 32 bit number where the car is the 16 top bits and the
4203 cdr is the lower 16 bits.
4204 FRAME nil or omitted means use the selected frame.
4205 If TYPE is given and non-nil, it is the name of the type of VALUE.
4206 If TYPE is not given or nil, the type is STRING.
4207 FORMAT gives the size in bits of each element if VALUE is a list.
4208 It must be one of 8, 16 or 32.
4209 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
4210 If OUTER_P is non-nil, the property is changed for the outer X window of
4211 FRAME. Default is to change on the edit X window.
4213 Value is VALUE. */)
4214 (Lisp_Object prop, Lisp_Object value, Lisp_Object frame, Lisp_Object type, Lisp_Object format, Lisp_Object outer_p)
4216 struct frame *f = check_x_frame (frame);
4217 Atom prop_atom;
4218 Atom target_type = XA_STRING;
4219 int element_format = 8;
4220 unsigned char *data;
4221 int nelements;
4222 Window w;
4224 CHECK_STRING (prop);
4226 if (! NILP (format))
4228 CHECK_NUMBER (format);
4229 element_format = XFASTINT (format);
4231 if (element_format != 8 && element_format != 16
4232 && element_format != 32)
4233 error ("FORMAT must be one of 8, 16 or 32");
4236 if (CONSP (value))
4238 nelements = x_check_property_data (value);
4239 if (nelements == -1)
4240 error ("Bad data in VALUE, must be number, string or cons");
4242 if (element_format == 8)
4243 data = (unsigned char *) xmalloc (nelements);
4244 else if (element_format == 16)
4245 data = (unsigned char *) xmalloc (nelements*2);
4246 else /* format == 32 */
4247 /* The man page for XChangeProperty:
4248 "If the specified format is 32, the property data must be a
4249 long array."
4250 This applies even if long is more than 64 bits. The X library
4251 converts to 32 bits before sending to the X server. */
4252 data = (unsigned char *) xmalloc (nelements * sizeof(long));
4254 x_fill_property_data (FRAME_X_DISPLAY (f), value, data, element_format);
4256 else
4258 CHECK_STRING (value);
4259 data = SDATA (value);
4260 nelements = SCHARS (value);
4263 BLOCK_INPUT;
4264 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4265 if (! NILP (type))
4267 CHECK_STRING (type);
4268 target_type = XInternAtom (FRAME_X_DISPLAY (f), SDATA (type), False);
4271 if (! NILP (outer_p)) w = FRAME_OUTER_WINDOW (f);
4272 else w = FRAME_X_WINDOW (f);
4274 XChangeProperty (FRAME_X_DISPLAY (f), w,
4275 prop_atom, target_type, element_format, PropModeReplace,
4276 data, nelements);
4278 if (CONSP (value)) xfree (data);
4280 /* Make sure the property is set when we return. */
4281 XFlush (FRAME_X_DISPLAY (f));
4282 UNBLOCK_INPUT;
4284 return value;
4288 DEFUN ("x-delete-window-property", Fx_delete_window_property,
4289 Sx_delete_window_property, 1, 2, 0,
4290 doc: /* Remove window property PROP from X window of FRAME.
4291 FRAME nil or omitted means use the selected frame. Value is PROP. */)
4292 (Lisp_Object prop, Lisp_Object frame)
4294 struct frame *f = check_x_frame (frame);
4295 Atom prop_atom;
4297 CHECK_STRING (prop);
4298 BLOCK_INPUT;
4299 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4300 XDeleteProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), prop_atom);
4302 /* Make sure the property is removed when we return. */
4303 XFlush (FRAME_X_DISPLAY (f));
4304 UNBLOCK_INPUT;
4306 return prop;
4310 DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
4311 1, 6, 0,
4312 doc: /* Value is the value of window property PROP on FRAME.
4313 If FRAME is nil or omitted, use the selected frame.
4314 If TYPE is nil or omitted, get the property as a string. Otherwise TYPE
4315 is the name of the Atom that denotes the type expected.
4316 If SOURCE is non-nil, get the property on that window instead of from
4317 FRAME. The number 0 denotes the root window.
4318 If DELETE_P is non-nil, delete the property after retreiving it.
4319 If VECTOR_RET_P is non-nil, don't return a string but a vector of values.
4321 Value is nil if FRAME hasn't a property with name PROP or if PROP has
4322 no value of TYPE. */)
4323 (Lisp_Object prop, Lisp_Object frame, Lisp_Object type, Lisp_Object source, Lisp_Object delete_p, Lisp_Object vector_ret_p)
4325 struct frame *f = check_x_frame (frame);
4326 Atom prop_atom;
4327 int rc;
4328 Lisp_Object prop_value = Qnil;
4329 unsigned char *tmp_data = NULL;
4330 Atom actual_type;
4331 Atom target_type = XA_STRING;
4332 int actual_format;
4333 unsigned long actual_size, bytes_remaining;
4334 Window target_window = FRAME_X_WINDOW (f);
4335 struct gcpro gcpro1;
4337 GCPRO1 (prop_value);
4338 CHECK_STRING (prop);
4340 if (! NILP (source))
4342 if (NUMBERP (source))
4344 if (FLOATP (source))
4345 target_window = (Window) XFLOAT (source);
4346 else
4347 target_window = XFASTINT (source);
4349 if (target_window == 0)
4350 target_window = FRAME_X_DISPLAY_INFO (f)->root_window;
4352 else if (CONSP (source))
4353 target_window = cons_to_long (source);
4356 BLOCK_INPUT;
4357 if (STRINGP (type))
4359 if (strcmp ("AnyPropertyType", SDATA (type)) == 0)
4360 target_type = AnyPropertyType;
4361 else
4362 target_type = XInternAtom (FRAME_X_DISPLAY (f), SDATA (type), False);
4365 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4366 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4367 prop_atom, 0, 0, False, target_type,
4368 &actual_type, &actual_format, &actual_size,
4369 &bytes_remaining, &tmp_data);
4370 if (rc == Success)
4372 int size = bytes_remaining;
4374 XFree (tmp_data);
4375 tmp_data = NULL;
4377 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4378 prop_atom, 0, bytes_remaining,
4379 ! NILP (delete_p), target_type,
4380 &actual_type, &actual_format,
4381 &actual_size, &bytes_remaining,
4382 &tmp_data);
4383 if (rc == Success && tmp_data)
4385 /* The man page for XGetWindowProperty says:
4386 "If the returned format is 32, the returned data is represented
4387 as a long array and should be cast to that type to obtain the
4388 elements."
4389 This applies even if long is more than 32 bits, the X library
4390 converts from 32 bit elements received from the X server to long
4391 and passes the long array to us. Thus, for that case memcpy can not
4392 be used. We convert to a 32 bit type here, because so much code
4393 assume on that.
4395 The bytes and offsets passed to XGetWindowProperty refers to the
4396 property and those are indeed in 32 bit quantities if format is
4397 32. */
4399 if (actual_format == 32 && actual_format < BITS_PER_LONG)
4401 unsigned long i;
4402 int *idata = (int *) tmp_data;
4403 long *ldata = (long *) tmp_data;
4405 for (i = 0; i < actual_size; ++i)
4406 idata[i] = (int) ldata[i];
4409 if (NILP (vector_ret_p))
4410 prop_value = make_string (tmp_data, size);
4411 else
4412 prop_value = x_property_data_to_lisp (f,
4413 tmp_data,
4414 actual_type,
4415 actual_format,
4416 actual_size);
4419 if (tmp_data) XFree (tmp_data);
4422 UNBLOCK_INPUT;
4423 UNGCPRO;
4424 return prop_value;
4429 /***********************************************************************
4430 Busy cursor
4431 ***********************************************************************/
4433 /* Timer function of hourglass_atimer. TIMER is equal to
4434 hourglass_atimer.
4436 Display an hourglass pointer on all frames by mapping the frames'
4437 hourglass_window. Set the hourglass_p flag in the frames'
4438 output_data.x structure to indicate that an hourglass cursor is
4439 shown on the frames. */
4441 void
4442 show_hourglass (struct atimer *timer)
4444 /* The timer implementation will cancel this timer automatically
4445 after this function has run. Set hourglass_atimer to null
4446 so that we know the timer doesn't have to be canceled. */
4447 hourglass_atimer = NULL;
4449 if (!hourglass_shown_p)
4451 Lisp_Object rest, frame;
4453 BLOCK_INPUT;
4455 FOR_EACH_FRAME (rest, frame)
4457 struct frame *f = XFRAME (frame);
4459 if (FRAME_LIVE_P (f) && FRAME_X_P (f) && FRAME_X_DISPLAY (f))
4461 Display *dpy = FRAME_X_DISPLAY (f);
4463 #ifdef USE_X_TOOLKIT
4464 if (f->output_data.x->widget)
4465 #else
4466 if (FRAME_OUTER_WINDOW (f))
4467 #endif
4469 f->output_data.x->hourglass_p = 1;
4471 if (!f->output_data.x->hourglass_window)
4473 unsigned long mask = CWCursor;
4474 XSetWindowAttributes attrs;
4475 #ifdef USE_GTK
4476 Window parent = FRAME_X_WINDOW (f);
4477 #else
4478 Window parent = FRAME_OUTER_WINDOW (f);
4479 #endif
4480 attrs.cursor = f->output_data.x->hourglass_cursor;
4482 f->output_data.x->hourglass_window
4483 = XCreateWindow (dpy, parent,
4484 0, 0, 32000, 32000, 0, 0,
4485 InputOnly,
4486 CopyFromParent,
4487 mask, &attrs);
4490 XMapRaised (dpy, f->output_data.x->hourglass_window);
4491 XFlush (dpy);
4496 hourglass_shown_p = 1;
4497 UNBLOCK_INPUT;
4502 /* Hide the hourglass pointer on all frames, if it is currently
4503 shown. */
4505 void
4506 hide_hourglass (void)
4508 if (hourglass_shown_p)
4510 Lisp_Object rest, frame;
4512 BLOCK_INPUT;
4513 FOR_EACH_FRAME (rest, frame)
4515 struct frame *f = XFRAME (frame);
4517 if (FRAME_X_P (f)
4518 /* Watch out for newly created frames. */
4519 && f->output_data.x->hourglass_window)
4521 XUnmapWindow (FRAME_X_DISPLAY (f),
4522 f->output_data.x->hourglass_window);
4523 /* Sync here because XTread_socket looks at the
4524 hourglass_p flag that is reset to zero below. */
4525 XSync (FRAME_X_DISPLAY (f), False);
4526 f->output_data.x->hourglass_p = 0;
4530 hourglass_shown_p = 0;
4531 UNBLOCK_INPUT;
4537 /***********************************************************************
4538 Tool tips
4539 ***********************************************************************/
4541 static Lisp_Object x_create_tip_frame (struct x_display_info *,
4542 Lisp_Object, Lisp_Object);
4543 static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
4544 Lisp_Object, int, int, int *, int *);
4546 /* The frame of a currently visible tooltip. */
4548 Lisp_Object tip_frame;
4550 /* If non-nil, a timer started that hides the last tooltip when it
4551 fires. */
4553 Lisp_Object tip_timer;
4554 Window tip_window;
4556 /* If non-nil, a vector of 3 elements containing the last args
4557 with which x-show-tip was called. See there. */
4559 Lisp_Object last_show_tip_args;
4561 /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
4563 Lisp_Object Vx_max_tooltip_size;
4566 static Lisp_Object
4567 unwind_create_tip_frame (Lisp_Object frame)
4569 Lisp_Object deleted;
4571 deleted = unwind_create_frame (frame);
4572 if (EQ (deleted, Qt))
4574 tip_window = None;
4575 tip_frame = Qnil;
4578 return deleted;
4582 /* Create a frame for a tooltip on the display described by DPYINFO.
4583 PARMS is a list of frame parameters. TEXT is the string to
4584 display in the tip frame. Value is the frame.
4586 Note that functions called here, esp. x_default_parameter can
4587 signal errors, for instance when a specified color name is
4588 undefined. We have to make sure that we're in a consistent state
4589 when this happens. */
4591 static Lisp_Object
4592 x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms, Lisp_Object text)
4594 struct frame *f;
4595 Lisp_Object frame, tem;
4596 Lisp_Object name;
4597 long window_prompting = 0;
4598 int width, height;
4599 int count = SPECPDL_INDEX ();
4600 struct gcpro gcpro1, gcpro2, gcpro3;
4601 int face_change_count_before = face_change_count;
4602 Lisp_Object buffer;
4603 struct buffer *old_buffer;
4605 check_x ();
4607 if (!dpyinfo->terminal->name)
4608 error ("Terminal is not live, can't create new frames on it");
4610 parms = Fcopy_alist (parms);
4612 /* Get the name of the frame to use for resource lookup. */
4613 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
4614 if (!STRINGP (name)
4615 && !EQ (name, Qunbound)
4616 && !NILP (name))
4617 error ("Invalid frame name--not a string or nil");
4619 frame = Qnil;
4620 GCPRO3 (parms, name, frame);
4621 f = make_frame (1);
4622 XSETFRAME (frame, f);
4624 buffer = Fget_buffer_create (build_string (" *tip*"));
4625 Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer, Qnil);
4626 old_buffer = current_buffer;
4627 set_buffer_internal_1 (XBUFFER (buffer));
4628 current_buffer->truncate_lines = Qnil;
4629 specbind (Qinhibit_read_only, Qt);
4630 specbind (Qinhibit_modification_hooks, Qt);
4631 Ferase_buffer ();
4632 Finsert (1, &text);
4633 set_buffer_internal_1 (old_buffer);
4635 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
4636 record_unwind_protect (unwind_create_tip_frame, frame);
4638 f->terminal = dpyinfo->terminal;
4639 f->terminal->reference_count++;
4641 /* By setting the output method, we're essentially saying that
4642 the frame is live, as per FRAME_LIVE_P. If we get a signal
4643 from this point on, x_destroy_window might screw up reference
4644 counts etc. */
4645 f->output_method = output_x_window;
4646 f->output_data.x = (struct x_output *) xmalloc (sizeof (struct x_output));
4647 memset (f->output_data.x, 0, sizeof (struct x_output));
4648 f->output_data.x->icon_bitmap = -1;
4649 FRAME_FONTSET (f) = -1;
4650 f->output_data.x->scroll_bar_foreground_pixel = -1;
4651 f->output_data.x->scroll_bar_background_pixel = -1;
4652 #ifdef USE_TOOLKIT_SCROLL_BARS
4653 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
4654 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
4655 #endif /* USE_TOOLKIT_SCROLL_BARS */
4656 f->icon_name = Qnil;
4657 FRAME_X_DISPLAY_INFO (f) = dpyinfo;
4658 #if GLYPH_DEBUG
4659 image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
4660 dpyinfo_refcount = dpyinfo->reference_count;
4661 #endif /* GLYPH_DEBUG */
4662 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
4663 f->output_data.x->explicit_parent = 0;
4665 /* These colors will be set anyway later, but it's important
4666 to get the color reference counts right, so initialize them! */
4668 Lisp_Object black;
4669 struct gcpro gcpro1;
4671 /* Function x_decode_color can signal an error. Make
4672 sure to initialize color slots so that we won't try
4673 to free colors we haven't allocated. */
4674 FRAME_FOREGROUND_PIXEL (f) = -1;
4675 FRAME_BACKGROUND_PIXEL (f) = -1;
4676 f->output_data.x->cursor_pixel = -1;
4677 f->output_data.x->cursor_foreground_pixel = -1;
4678 f->output_data.x->border_pixel = -1;
4679 f->output_data.x->mouse_pixel = -1;
4681 black = build_string ("black");
4682 GCPRO1 (black);
4683 FRAME_FOREGROUND_PIXEL (f)
4684 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4685 FRAME_BACKGROUND_PIXEL (f)
4686 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4687 f->output_data.x->cursor_pixel
4688 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4689 f->output_data.x->cursor_foreground_pixel
4690 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4691 f->output_data.x->border_pixel
4692 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4693 f->output_data.x->mouse_pixel
4694 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4695 UNGCPRO;
4698 /* Set the name; the functions to which we pass f expect the name to
4699 be set. */
4700 if (EQ (name, Qunbound) || NILP (name))
4702 f->name = build_string (dpyinfo->x_id_name);
4703 f->explicit_name = 0;
4705 else
4707 f->name = name;
4708 f->explicit_name = 1;
4709 /* use the frame's title when getting resources for this frame. */
4710 specbind (Qx_resource_name, name);
4713 f->resx = dpyinfo->resx;
4714 f->resy = dpyinfo->resy;
4716 register_font_driver (&xfont_driver, f);
4717 #ifdef HAVE_FREETYPE
4718 #ifdef HAVE_XFT
4719 register_font_driver (&xftfont_driver, f);
4720 #else /* not HAVE_XFT */
4721 register_font_driver (&ftxfont_driver, f);
4722 #endif /* not HAVE_XFT */
4723 #endif /* HAVE_FREETYPE */
4725 x_default_parameter (f, parms, Qfont_backend, Qnil,
4726 "fontBackend", "FontBackend", RES_TYPE_STRING);
4728 /* Extract the window parameters from the supplied values that are
4729 needed to determine window geometry. */
4730 x_default_font_parameter (f, parms);
4732 x_default_parameter (f, parms, Qborder_width, make_number (0),
4733 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
4735 /* This defaults to 2 in order to match xterm. We recognize either
4736 internalBorderWidth or internalBorder (which is what xterm calls
4737 it). */
4738 if (NILP (Fassq (Qinternal_border_width, parms)))
4740 Lisp_Object value;
4742 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
4743 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
4744 if (! EQ (value, Qunbound))
4745 parms = Fcons (Fcons (Qinternal_border_width, value),
4746 parms);
4749 x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
4750 "internalBorderWidth", "internalBorderWidth",
4751 RES_TYPE_NUMBER);
4753 /* Also do the stuff which must be set before the window exists. */
4754 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
4755 "foreground", "Foreground", RES_TYPE_STRING);
4756 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
4757 "background", "Background", RES_TYPE_STRING);
4758 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
4759 "pointerColor", "Foreground", RES_TYPE_STRING);
4760 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
4761 "cursorColor", "Foreground", RES_TYPE_STRING);
4762 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
4763 "borderColor", "BorderColor", RES_TYPE_STRING);
4765 /* Init faces before x_default_parameter is called for scroll-bar
4766 parameters because that function calls x_set_scroll_bar_width,
4767 which calls change_frame_size, which calls Fset_window_buffer,
4768 which runs hooks, which call Fvertical_motion. At the end, we
4769 end up in init_iterator with a null face cache, which should not
4770 happen. */
4771 init_frame_faces (f);
4773 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
4775 window_prompting = x_figure_window_size (f, parms, 0);
4778 XSetWindowAttributes attrs;
4779 unsigned long mask;
4780 Atom type = FRAME_X_DISPLAY_INFO (f)->Xatom_net_window_type_tooltip;
4782 BLOCK_INPUT;
4783 mask = CWBackPixel | CWOverrideRedirect | CWEventMask;
4784 if (DoesSaveUnders (dpyinfo->screen))
4785 mask |= CWSaveUnder;
4787 /* Window managers look at the override-redirect flag to determine
4788 whether or net to give windows a decoration (Xlib spec, chapter
4789 3.2.8). */
4790 attrs.override_redirect = True;
4791 attrs.save_under = True;
4792 attrs.background_pixel = FRAME_BACKGROUND_PIXEL (f);
4793 /* Arrange for getting MapNotify and UnmapNotify events. */
4794 attrs.event_mask = StructureNotifyMask;
4795 tip_window
4796 = FRAME_X_WINDOW (f)
4797 = XCreateWindow (FRAME_X_DISPLAY (f),
4798 FRAME_X_DISPLAY_INFO (f)->root_window,
4799 /* x, y, width, height */
4800 0, 0, 1, 1,
4801 /* Border. */
4802 f->border_width,
4803 CopyFromParent, InputOutput, CopyFromParent,
4804 mask, &attrs);
4805 XChangeProperty (FRAME_X_DISPLAY (f), tip_window,
4806 FRAME_X_DISPLAY_INFO (f)->Xatom_net_window_type,
4807 XA_ATOM, 32, PropModeReplace,
4808 (unsigned char *)&type, 1);
4809 UNBLOCK_INPUT;
4812 x_make_gc (f);
4814 x_default_parameter (f, parms, Qauto_raise, Qnil,
4815 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
4816 x_default_parameter (f, parms, Qauto_lower, Qnil,
4817 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
4818 x_default_parameter (f, parms, Qcursor_type, Qbox,
4819 "cursorType", "CursorType", RES_TYPE_SYMBOL);
4821 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
4822 Change will not be effected unless different from the current
4823 FRAME_LINES (f). */
4824 width = FRAME_COLS (f);
4825 height = FRAME_LINES (f);
4826 SET_FRAME_COLS (f, 0);
4827 FRAME_LINES (f) = 0;
4828 change_frame_size (f, height, width, 1, 0, 0);
4830 /* Add `tooltip' frame parameter's default value. */
4831 if (NILP (Fframe_parameter (frame, Qtooltip)))
4832 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtooltip, Qt), Qnil));
4834 /* FIXME - can this be done in a similar way to normal frames?
4835 http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
4837 /* Set the `display-type' frame parameter before setting up faces. */
4839 Lisp_Object disptype;
4841 if (FRAME_X_DISPLAY_INFO (f)->n_planes == 1)
4842 disptype = intern ("mono");
4843 else if (FRAME_X_DISPLAY_INFO (f)->visual->class == GrayScale
4844 || FRAME_X_DISPLAY_INFO (f)->visual->class == StaticGray)
4845 disptype = intern ("grayscale");
4846 else
4847 disptype = intern ("color");
4849 if (NILP (Fframe_parameter (frame, Qdisplay_type)))
4850 Fmodify_frame_parameters (frame, Fcons (Fcons (Qdisplay_type, disptype),
4851 Qnil));
4854 /* Set up faces after all frame parameters are known. This call
4855 also merges in face attributes specified for new frames.
4857 Frame parameters may be changed if .Xdefaults contains
4858 specifications for the default font. For example, if there is an
4859 `Emacs.default.attributeBackground: pink', the `background-color'
4860 attribute of the frame get's set, which let's the internal border
4861 of the tooltip frame appear in pink. Prevent this. */
4863 Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
4865 /* Set tip_frame here, so that */
4866 tip_frame = frame;
4867 call2 (Qface_set_after_frame_default, frame, Qnil);
4869 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
4870 Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg),
4871 Qnil));
4874 f->no_split = 1;
4876 UNGCPRO;
4878 /* It is now ok to make the frame official even if we get an error
4879 below. And the frame needs to be on Vframe_list or making it
4880 visible won't work. */
4881 Vframe_list = Fcons (frame, Vframe_list);
4883 /* Now that the frame is official, it counts as a reference to
4884 its display. */
4885 FRAME_X_DISPLAY_INFO (f)->reference_count++;
4887 /* Setting attributes of faces of the tooltip frame from resources
4888 and similar will increment face_change_count, which leads to the
4889 clearing of all current matrices. Since this isn't necessary
4890 here, avoid it by resetting face_change_count to the value it
4891 had before we created the tip frame. */
4892 face_change_count = face_change_count_before;
4894 /* Discard the unwind_protect. */
4895 return unbind_to (count, frame);
4899 /* Compute where to display tip frame F. PARMS is the list of frame
4900 parameters for F. DX and DY are specified offsets from the current
4901 location of the mouse. WIDTH and HEIGHT are the width and height
4902 of the tooltip. Return coordinates relative to the root window of
4903 the display in *ROOT_X, and *ROOT_Y. */
4905 static void
4906 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)
4908 Lisp_Object left, top;
4909 int win_x, win_y;
4910 Window root, child;
4911 unsigned pmask;
4913 /* User-specified position? */
4914 left = Fcdr (Fassq (Qleft, parms));
4915 top = Fcdr (Fassq (Qtop, parms));
4917 /* Move the tooltip window where the mouse pointer is. Resize and
4918 show it. */
4919 if (!INTEGERP (left) || !INTEGERP (top))
4921 BLOCK_INPUT;
4922 XQueryPointer (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
4923 &root, &child, root_x, root_y, &win_x, &win_y, &pmask);
4924 UNBLOCK_INPUT;
4927 if (INTEGERP (top))
4928 *root_y = XINT (top);
4929 else if (*root_y + XINT (dy) <= 0)
4930 *root_y = 0; /* Can happen for negative dy */
4931 else if (*root_y + XINT (dy) + height
4932 <= x_display_pixel_height (FRAME_X_DISPLAY_INFO (f)))
4933 /* It fits below the pointer */
4934 *root_y += XINT (dy);
4935 else if (height + XINT (dy) <= *root_y)
4936 /* It fits above the pointer. */
4937 *root_y -= height + XINT (dy);
4938 else
4939 /* Put it on the top. */
4940 *root_y = 0;
4942 if (INTEGERP (left))
4943 *root_x = XINT (left);
4944 else if (*root_x + XINT (dx) <= 0)
4945 *root_x = 0; /* Can happen for negative dx */
4946 else if (*root_x + XINT (dx) + width
4947 <= x_display_pixel_width (FRAME_X_DISPLAY_INFO (f)))
4948 /* It fits to the right of the pointer. */
4949 *root_x += XINT (dx);
4950 else if (width + XINT (dx) <= *root_x)
4951 /* It fits to the left of the pointer. */
4952 *root_x -= width + XINT (dx);
4953 else
4954 /* Put it left-justified on the screen--it ought to fit that way. */
4955 *root_x = 0;
4959 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
4960 doc: /* Show STRING in a "tooltip" window on frame FRAME.
4961 A tooltip window is a small X window displaying a string.
4963 This is an internal function; Lisp code should call `tooltip-show'.
4965 FRAME nil or omitted means use the selected frame.
4967 PARMS is an optional list of frame parameters which can be used to
4968 change the tooltip's appearance.
4970 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
4971 means use the default timeout of 5 seconds.
4973 If the list of frame parameters PARAMS contains a `left' parameters,
4974 the tooltip is displayed at that x-position. Otherwise it is
4975 displayed at the mouse position, with offset DX added (default is 5 if
4976 DX isn't specified). Likewise for the y-position; if a `top' frame
4977 parameter is specified, it determines the y-position of the tooltip
4978 window, otherwise it is displayed at the mouse position, with offset
4979 DY added (default is -10).
4981 A tooltip's maximum size is specified by `x-max-tooltip-size'.
4982 Text larger than the specified size is clipped. */)
4983 (Lisp_Object string, Lisp_Object frame, Lisp_Object parms, Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy)
4985 struct frame *f;
4986 struct window *w;
4987 int root_x, root_y;
4988 struct buffer *old_buffer;
4989 struct text_pos pos;
4990 int i, width, height;
4991 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
4992 int old_windows_or_buffers_changed = windows_or_buffers_changed;
4993 int count = SPECPDL_INDEX ();
4995 specbind (Qinhibit_redisplay, Qt);
4997 GCPRO4 (string, parms, frame, timeout);
4999 CHECK_STRING (string);
5000 if (SCHARS (string) == 0)
5001 string = make_unibyte_string (" ", 1);
5003 f = check_x_frame (frame);
5004 if (NILP (timeout))
5005 timeout = make_number (5);
5006 else
5007 CHECK_NATNUM (timeout);
5009 if (NILP (dx))
5010 dx = make_number (5);
5011 else
5012 CHECK_NUMBER (dx);
5014 if (NILP (dy))
5015 dy = make_number (-10);
5016 else
5017 CHECK_NUMBER (dy);
5019 if (NILP (last_show_tip_args))
5020 last_show_tip_args = Fmake_vector (make_number (3), Qnil);
5022 if (!NILP (tip_frame))
5024 Lisp_Object last_string = AREF (last_show_tip_args, 0);
5025 Lisp_Object last_frame = AREF (last_show_tip_args, 1);
5026 Lisp_Object last_parms = AREF (last_show_tip_args, 2);
5028 if (EQ (frame, last_frame)
5029 && !NILP (Fequal (last_string, string))
5030 && !NILP (Fequal (last_parms, parms)))
5032 struct frame *f = XFRAME (tip_frame);
5034 /* Only DX and DY have changed. */
5035 if (!NILP (tip_timer))
5037 Lisp_Object timer = tip_timer;
5038 tip_timer = Qnil;
5039 call1 (Qcancel_timer, timer);
5042 BLOCK_INPUT;
5043 compute_tip_xy (f, parms, dx, dy, FRAME_PIXEL_WIDTH (f),
5044 FRAME_PIXEL_HEIGHT (f), &root_x, &root_y);
5045 XMoveWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5046 root_x, root_y);
5047 UNBLOCK_INPUT;
5048 goto start_timer;
5052 /* Hide a previous tip, if any. */
5053 Fx_hide_tip ();
5055 ASET (last_show_tip_args, 0, string);
5056 ASET (last_show_tip_args, 1, frame);
5057 ASET (last_show_tip_args, 2, parms);
5059 /* Add default values to frame parameters. */
5060 if (NILP (Fassq (Qname, parms)))
5061 parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
5062 if (NILP (Fassq (Qinternal_border_width, parms)))
5063 parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
5064 if (NILP (Fassq (Qborder_width, parms)))
5065 parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
5066 if (NILP (Fassq (Qborder_color, parms)))
5067 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
5068 if (NILP (Fassq (Qbackground_color, parms)))
5069 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
5070 parms);
5072 /* Create a frame for the tooltip, and record it in the global
5073 variable tip_frame. */
5074 frame = x_create_tip_frame (FRAME_X_DISPLAY_INFO (f), parms, string);
5075 f = XFRAME (frame);
5077 /* Set up the frame's root window. */
5078 w = XWINDOW (FRAME_ROOT_WINDOW (f));
5079 w->left_col = w->top_line = make_number (0);
5081 if (CONSP (Vx_max_tooltip_size)
5082 && INTEGERP (XCAR (Vx_max_tooltip_size))
5083 && XINT (XCAR (Vx_max_tooltip_size)) > 0
5084 && INTEGERP (XCDR (Vx_max_tooltip_size))
5085 && XINT (XCDR (Vx_max_tooltip_size)) > 0)
5087 w->total_cols = XCAR (Vx_max_tooltip_size);
5088 w->total_lines = XCDR (Vx_max_tooltip_size);
5090 else
5092 w->total_cols = make_number (80);
5093 w->total_lines = make_number (40);
5096 FRAME_TOTAL_COLS (f) = XINT (w->total_cols);
5097 adjust_glyphs (f);
5098 w->pseudo_window_p = 1;
5100 /* Display the tooltip text in a temporary buffer. */
5101 old_buffer = current_buffer;
5102 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer));
5103 current_buffer->truncate_lines = Qnil;
5104 clear_glyph_matrix (w->desired_matrix);
5105 clear_glyph_matrix (w->current_matrix);
5106 SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
5107 try_window (FRAME_ROOT_WINDOW (f), pos, TRY_WINDOW_IGNORE_FONTS_CHANGE);
5109 /* Compute width and height of the tooltip. */
5110 width = height = 0;
5111 for (i = 0; i < w->desired_matrix->nrows; ++i)
5113 struct glyph_row *row = &w->desired_matrix->rows[i];
5114 struct glyph *last;
5115 int row_width;
5117 /* Stop at the first empty row at the end. */
5118 if (!row->enabled_p || !row->displays_text_p)
5119 break;
5121 /* Let the row go over the full width of the frame. */
5122 row->full_width_p = 1;
5124 row_width = row->pixel_width;
5125 /* There's a glyph at the end of rows that is used to place
5126 the cursor there. Don't include the width of this glyph. */
5127 if (row->used[TEXT_AREA])
5129 last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
5130 if (INTEGERP (last->object))
5131 row_width -= last->pixel_width;
5134 height += row->height;
5135 width = max (width, row_width);
5138 /* Add the frame's internal border to the width and height the X
5139 window should have. */
5140 height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5141 width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5143 /* Move the tooltip window where the mouse pointer is. Resize and
5144 show it. */
5145 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
5147 BLOCK_INPUT;
5148 XMoveResizeWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5149 root_x, root_y, width, height);
5150 XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
5151 UNBLOCK_INPUT;
5153 /* Draw into the window. */
5154 w->must_be_updated_p = 1;
5155 update_single_window (w, 1);
5157 /* Restore original current buffer. */
5158 set_buffer_internal_1 (old_buffer);
5159 windows_or_buffers_changed = old_windows_or_buffers_changed;
5161 start_timer:
5162 /* Let the tip disappear after timeout seconds. */
5163 tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
5164 intern ("x-hide-tip"));
5166 UNGCPRO;
5167 return unbind_to (count, Qnil);
5171 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
5172 doc: /* Hide the current tooltip window, if there is any.
5173 Value is t if tooltip was open, nil otherwise. */)
5174 (void)
5176 int count;
5177 Lisp_Object deleted, frame, timer;
5178 struct gcpro gcpro1, gcpro2;
5180 /* Return quickly if nothing to do. */
5181 if (NILP (tip_timer) && NILP (tip_frame))
5182 return Qnil;
5184 frame = tip_frame;
5185 timer = tip_timer;
5186 GCPRO2 (frame, timer);
5187 tip_frame = tip_timer = deleted = Qnil;
5189 count = SPECPDL_INDEX ();
5190 specbind (Qinhibit_redisplay, Qt);
5191 specbind (Qinhibit_quit, Qt);
5193 if (!NILP (timer))
5194 call1 (Qcancel_timer, timer);
5196 if (FRAMEP (frame))
5198 delete_frame (frame, Qnil);
5199 deleted = Qt;
5201 #ifdef USE_LUCID
5202 /* Bloodcurdling hack alert: The Lucid menu bar widget's
5203 redisplay procedure is not called when a tip frame over menu
5204 items is unmapped. Redisplay the menu manually... */
5206 struct frame *f = SELECTED_FRAME ();
5207 Widget w = f->output_data.x->menubar_widget;
5208 extern void xlwmenu_redisplay (Widget);
5210 if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f)->screen)
5211 && w != NULL)
5213 BLOCK_INPUT;
5214 xlwmenu_redisplay (w);
5215 UNBLOCK_INPUT;
5218 #endif /* USE_LUCID */
5221 UNGCPRO;
5222 return unbind_to (count, deleted);
5227 /***********************************************************************
5228 File selection dialog
5229 ***********************************************************************/
5231 DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog,
5232 Sx_uses_old_gtk_dialog,
5233 0, 0, 0,
5234 doc: /* Return t if the old Gtk+ file selection dialog is used. */)
5235 (void)
5237 #ifdef USE_GTK
5238 extern int use_dialog_box;
5239 extern int use_file_dialog;
5241 if (use_dialog_box
5242 && use_file_dialog
5243 && have_menus_p ()
5244 && xg_uses_old_file_dialog ())
5245 return Qt;
5246 #endif
5247 return Qnil;
5251 #ifdef USE_MOTIF
5252 /* Callback for "OK" and "Cancel" on file selection dialog. */
5254 static void
5255 file_dialog_cb (widget, client_data, call_data)
5256 Widget widget;
5257 XtPointer call_data, client_data;
5259 int *result = (int *) client_data;
5260 XmAnyCallbackStruct *cb = (XmAnyCallbackStruct *) call_data;
5261 *result = cb->reason;
5265 /* Callback for unmapping a file selection dialog. This is used to
5266 capture the case where a dialog is closed via a window manager's
5267 closer button, for example. Using a XmNdestroyCallback didn't work
5268 in this case. */
5270 static void
5271 file_dialog_unmap_cb (widget, client_data, call_data)
5272 Widget widget;
5273 XtPointer call_data, client_data;
5275 int *result = (int *) client_data;
5276 *result = XmCR_CANCEL;
5279 static Lisp_Object
5280 clean_up_file_dialog (arg)
5281 Lisp_Object arg;
5283 struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
5284 Widget dialog = (Widget) p->pointer;
5286 /* Clean up. */
5287 BLOCK_INPUT;
5288 XtUnmanageChild (dialog);
5289 XtDestroyWidget (dialog);
5290 x_menu_set_in_use (0);
5291 UNBLOCK_INPUT;
5293 return Qnil;
5297 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5298 doc: /* Read file name, prompting with PROMPT in directory DIR.
5299 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5300 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5301 or directory must exist. ONLY-DIR-P is ignored." */)
5302 (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p)
5304 int result;
5305 struct frame *f = SELECTED_FRAME ();
5306 Lisp_Object file = Qnil;
5307 Lisp_Object decoded_file;
5308 Widget dialog, text, help;
5309 Arg al[10];
5310 int ac = 0;
5311 extern XtAppContext Xt_app_con;
5312 XmString dir_xmstring, pattern_xmstring;
5313 int count = SPECPDL_INDEX ();
5314 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5316 check_x ();
5318 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5320 if (popup_activated ())
5321 error ("Trying to use a menu from within a menu-entry");
5323 CHECK_STRING (prompt);
5324 CHECK_STRING (dir);
5326 /* Prevent redisplay. */
5327 specbind (Qinhibit_redisplay, Qt);
5329 BLOCK_INPUT;
5331 /* Create the dialog with PROMPT as title, using DIR as initial
5332 directory and using "*" as pattern. */
5333 dir = Fexpand_file_name (dir, Qnil);
5334 dir_xmstring = XmStringCreateLocalized (SDATA (dir));
5335 pattern_xmstring = XmStringCreateLocalized ("*");
5337 XtSetArg (al[ac], XmNtitle, SDATA (prompt)); ++ac;
5338 XtSetArg (al[ac], XmNdirectory, dir_xmstring); ++ac;
5339 XtSetArg (al[ac], XmNpattern, pattern_xmstring); ++ac;
5340 XtSetArg (al[ac], XmNresizePolicy, XmRESIZE_GROW); ++ac;
5341 XtSetArg (al[ac], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); ++ac;
5342 dialog = XmCreateFileSelectionDialog (f->output_data.x->widget,
5343 "fsb", al, ac);
5344 XmStringFree (dir_xmstring);
5345 XmStringFree (pattern_xmstring);
5347 /* Add callbacks for OK and Cancel. */
5348 XtAddCallback (dialog, XmNokCallback, file_dialog_cb,
5349 (XtPointer) &result);
5350 XtAddCallback (dialog, XmNcancelCallback, file_dialog_cb,
5351 (XtPointer) &result);
5352 XtAddCallback (dialog, XmNunmapCallback, file_dialog_unmap_cb,
5353 (XtPointer) &result);
5355 /* Remove the help button since we can't display help. */
5356 help = XmFileSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON);
5357 XtUnmanageChild (help);
5359 /* Mark OK button as default. */
5360 XtVaSetValues (XmFileSelectionBoxGetChild (dialog, XmDIALOG_OK_BUTTON),
5361 XmNshowAsDefault, True, NULL);
5363 /* If MUSTMATCH is non-nil, disable the file entry field of the
5364 dialog, so that the user must select a file from the files list
5365 box. We can't remove it because we wouldn't have a way to get at
5366 the result file name, then. */
5367 text = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5368 if (!NILP (mustmatch))
5370 Widget label;
5371 label = XmFileSelectionBoxGetChild (dialog, XmDIALOG_SELECTION_LABEL);
5372 XtSetSensitive (text, False);
5373 XtSetSensitive (label, False);
5376 /* Manage the dialog, so that list boxes get filled. */
5377 XtManageChild (dialog);
5379 if (STRINGP (default_filename))
5381 XmString default_xmstring;
5382 Widget wtext = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5383 Widget list = XmFileSelectionBoxGetChild (dialog, XmDIALOG_LIST);
5385 XmTextPosition last_pos = XmTextFieldGetLastPosition (wtext);
5386 XmTextFieldReplace (wtext, 0, last_pos,
5387 (SDATA (Ffile_name_nondirectory (default_filename))));
5389 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
5390 must include the path for this to work. */
5392 default_xmstring = XmStringCreateLocalized (SDATA (default_filename));
5394 if (XmListItemExists (list, default_xmstring))
5396 int item_pos = XmListItemPos (list, default_xmstring);
5397 /* Select the item and scroll it into view. */
5398 XmListSelectPos (list, item_pos, True);
5399 XmListSetPos (list, item_pos);
5402 XmStringFree (default_xmstring);
5405 record_unwind_protect (clean_up_file_dialog, make_save_value (dialog, 0));
5407 /* Process events until the user presses Cancel or OK. */
5408 x_menu_set_in_use (1);
5409 result = 0;
5410 while (result == 0)
5412 XEvent event;
5413 x_menu_wait_for_event (0);
5414 XtAppNextEvent (Xt_app_con, &event);
5415 if (event.type == KeyPress
5416 && FRAME_X_DISPLAY (f) == event.xkey.display)
5418 KeySym keysym = XLookupKeysym (&event.xkey, 0);
5420 /* Pop down on C-g. */
5421 if (keysym == XK_g && (event.xkey.state & ControlMask) != 0)
5422 XtUnmanageChild (dialog);
5425 (void) x_dispatch_event (&event, FRAME_X_DISPLAY (f));
5428 /* Get the result. */
5429 if (result == XmCR_OK)
5431 XmString text;
5432 String data;
5434 XtVaGetValues (dialog, XmNtextString, &text, NULL);
5435 XmStringGetLtoR (text, XmFONTLIST_DEFAULT_TAG, &data);
5436 XmStringFree (text);
5437 file = build_string (data);
5438 XtFree (data);
5440 else
5441 file = Qnil;
5443 UNBLOCK_INPUT;
5444 UNGCPRO;
5446 /* Make "Cancel" equivalent to C-g. */
5447 if (NILP (file))
5448 Fsignal (Qquit, Qnil);
5450 decoded_file = DECODE_FILE (file);
5452 return unbind_to (count, decoded_file);
5455 #endif /* USE_MOTIF */
5457 #ifdef USE_GTK
5459 static Lisp_Object
5460 clean_up_dialog (Lisp_Object arg)
5462 x_menu_set_in_use (0);
5464 return Qnil;
5467 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5468 doc: /* Read file name, prompting with PROMPT in directory DIR.
5469 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5470 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5471 or directory must exist. If ONLY-DIR-P is non-nil, the user can only select
5472 directories. */)
5473 (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p)
5475 FRAME_PTR f = SELECTED_FRAME ();
5476 char *fn;
5477 Lisp_Object file = Qnil;
5478 Lisp_Object decoded_file;
5479 int count = SPECPDL_INDEX ();
5480 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5481 char *cdef_file;
5483 check_x ();
5485 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5487 if (popup_activated ())
5488 error ("Trying to use a menu from within a menu-entry");
5490 CHECK_STRING (prompt);
5491 CHECK_STRING (dir);
5493 /* Prevent redisplay. */
5494 specbind (Qinhibit_redisplay, Qt);
5495 record_unwind_protect (clean_up_dialog, Qnil);
5497 BLOCK_INPUT;
5499 if (STRINGP (default_filename))
5500 cdef_file = SDATA (default_filename);
5501 else
5502 cdef_file = SDATA (dir);
5504 fn = xg_get_file_name (f, SDATA (prompt), cdef_file,
5505 ! NILP (mustmatch),
5506 ! NILP (only_dir_p));
5508 if (fn)
5510 file = build_string (fn);
5511 xfree (fn);
5514 UNBLOCK_INPUT;
5515 UNGCPRO;
5517 /* Make "Cancel" equivalent to C-g. */
5518 if (NILP (file))
5519 Fsignal (Qquit, Qnil);
5521 decoded_file = DECODE_FILE (file);
5523 return unbind_to (count, decoded_file);
5527 #ifdef HAVE_FREETYPE
5529 DEFUN ("x-select-font", Fx_select_font, Sx_select_font, 0, 2, 0,
5530 doc: /* Read a font name using a GTK font selection dialog.
5531 Return a GTK-style font string corresponding to the selection.
5533 If FRAME is omitted or nil, it defaults to the selected frame. */)
5534 (Lisp_Object frame, Lisp_Object ignored)
5536 FRAME_PTR f = check_x_frame (frame);
5537 char *name;
5538 Lisp_Object font;
5539 Lisp_Object font_param;
5540 char *default_name = NULL;
5541 struct gcpro gcpro1, gcpro2;
5542 int count = SPECPDL_INDEX ();
5544 check_x ();
5546 if (popup_activated ())
5547 error ("Trying to use a menu from within a menu-entry");
5549 /* Prevent redisplay. */
5550 specbind (Qinhibit_redisplay, Qt);
5551 record_unwind_protect (clean_up_dialog, Qnil);
5553 BLOCK_INPUT;
5555 GCPRO2(font_param, font);
5557 XSETFONT (font, FRAME_FONT (f));
5558 font_param = Ffont_get (font, intern (":name"));
5559 if (STRINGP (font_param))
5560 default_name = xstrdup (SDATA (font_param));
5561 else
5563 font_param = Fframe_parameter (frame, Qfont_param);
5564 if (STRINGP (font_param))
5565 default_name = xstrdup (SDATA (font_param));
5568 if (default_name == NULL && x_last_font_name != NULL)
5569 default_name = xstrdup (x_last_font_name);
5571 /* Convert fontconfig names to Gtk names, i.e. remove - before number */
5572 if (default_name)
5574 char *p = strrchr (default_name, '-');
5575 if (p)
5577 char *ep = p+1;
5578 while (isdigit (*ep))
5579 ++ep;
5580 if (*ep == '\0') *p = ' ';
5584 name = xg_get_font_name (f, default_name);
5585 xfree (default_name);
5587 if (name)
5589 font = build_string (name);
5590 g_free (x_last_font_name);
5591 x_last_font_name = name;
5594 UNBLOCK_INPUT;
5596 if (NILP (font))
5597 Fsignal (Qquit, Qnil);
5599 return unbind_to (count, font);
5601 #endif /* HAVE_FREETYPE */
5603 #endif /* USE_GTK */
5606 /***********************************************************************
5607 Keyboard
5608 ***********************************************************************/
5610 #ifdef HAVE_XKBGETKEYBOARD
5611 #include <X11/XKBlib.h>
5612 #include <X11/keysym.h>
5613 #endif
5615 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p,
5616 Sx_backspace_delete_keys_p, 0, 1, 0,
5617 doc: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
5618 FRAME nil means use the selected frame.
5619 Value is t if we know that both keys are present, and are mapped to the
5620 usual X keysyms. Value is `lambda' if we cannot determine if both keys are
5621 present and mapped to the usual X keysyms. */)
5622 (Lisp_Object frame)
5624 #ifdef HAVE_XKBGETKEYBOARD
5625 XkbDescPtr kb;
5626 struct frame *f = check_x_frame (frame);
5627 Display *dpy = FRAME_X_DISPLAY (f);
5628 Lisp_Object have_keys;
5629 int major, minor, op, event, error;
5631 BLOCK_INPUT;
5633 /* Check library version in case we're dynamically linked. */
5634 major = XkbMajorVersion;
5635 minor = XkbMinorVersion;
5636 if (!XkbLibraryVersion (&major, &minor))
5638 UNBLOCK_INPUT;
5639 return Qlambda;
5642 /* Check that the server supports XKB. */
5643 major = XkbMajorVersion;
5644 minor = XkbMinorVersion;
5645 if (!XkbQueryExtension (dpy, &op, &event, &error, &major, &minor))
5647 UNBLOCK_INPUT;
5648 return Qlambda;
5651 /* In this code we check that the keyboard has physical keys with names
5652 that start with BKSP (Backspace) and DELE (Delete), and that they
5653 generate keysym XK_BackSpace and XK_Delete respectively.
5654 This function is used to test if normal-erase-is-backspace should be
5655 turned on.
5656 An alternative approach would be to just check if XK_BackSpace and
5657 XK_Delete are mapped to any key. But if any of those are mapped to
5658 some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the
5659 user doesn't know about it, it is better to return false here.
5660 It is more obvious to the user what to do if she/he has two keys
5661 clearly marked with names/symbols and one key does something not
5662 expected (i.e. she/he then tries the other).
5663 The cases where Backspace/Delete is mapped to some other key combination
5664 are rare, and in those cases, normal-erase-is-backspace can be turned on
5665 manually. */
5667 have_keys = Qnil;
5668 kb = XkbGetMap (dpy, XkbAllMapComponentsMask, XkbUseCoreKbd);
5669 if (kb)
5671 int delete_keycode = 0, backspace_keycode = 0, i;
5673 if (XkbGetNames (dpy, XkbAllNamesMask, kb) == Success)
5675 for (i = kb->min_key_code;
5676 (i < kb->max_key_code
5677 && (delete_keycode == 0 || backspace_keycode == 0));
5678 ++i)
5680 /* The XKB symbolic key names can be seen most easily in
5681 the PS file generated by `xkbprint -label name
5682 $DISPLAY'. */
5683 if (memcmp ("DELE", kb->names->keys[i].name, 4) == 0)
5684 delete_keycode = i;
5685 else if (memcmp ("BKSP", kb->names->keys[i].name, 4) == 0)
5686 backspace_keycode = i;
5689 XkbFreeNames (kb, 0, True);
5692 XkbFreeClientMap (kb, 0, True);
5694 if (delete_keycode
5695 && backspace_keycode
5696 && XKeysymToKeycode (dpy, XK_Delete) == delete_keycode
5697 && XKeysymToKeycode (dpy, XK_BackSpace) == backspace_keycode)
5698 have_keys = Qt;
5700 UNBLOCK_INPUT;
5701 return have_keys;
5702 #else /* not HAVE_XKBGETKEYBOARD */
5703 return Qlambda;
5704 #endif /* not HAVE_XKBGETKEYBOARD */
5709 /***********************************************************************
5710 Initialization
5711 ***********************************************************************/
5713 /* Keep this list in the same order as frame_parms in frame.c.
5714 Use 0 for unsupported frame parameters. */
5716 frame_parm_handler x_frame_parm_handlers[] =
5718 x_set_autoraise,
5719 x_set_autolower,
5720 x_set_background_color,
5721 x_set_border_color,
5722 x_set_border_width,
5723 x_set_cursor_color,
5724 x_set_cursor_type,
5725 x_set_font,
5726 x_set_foreground_color,
5727 x_set_icon_name,
5728 x_set_icon_type,
5729 x_set_internal_border_width,
5730 x_set_menu_bar_lines,
5731 x_set_mouse_color,
5732 x_explicitly_set_name,
5733 x_set_scroll_bar_width,
5734 x_set_title,
5735 x_set_unsplittable,
5736 x_set_vertical_scroll_bars,
5737 x_set_visibility,
5738 x_set_tool_bar_lines,
5739 x_set_scroll_bar_foreground,
5740 x_set_scroll_bar_background,
5741 x_set_screen_gamma,
5742 x_set_line_spacing,
5743 x_set_fringe_width,
5744 x_set_fringe_width,
5745 x_set_wait_for_wm,
5746 x_set_fullscreen,
5747 x_set_font_backend,
5748 x_set_alpha,
5749 x_set_sticky,
5752 void
5753 syms_of_xfns (void)
5755 /* This is zero if not using X windows. */
5756 x_in_use = 0;
5758 /* The section below is built by the lisp expression at the top of the file,
5759 just above where these variables are declared. */
5760 /*&&& init symbols here &&&*/
5761 Qnone = intern_c_string ("none");
5762 staticpro (&Qnone);
5763 Qsuppress_icon = intern_c_string ("suppress-icon");
5764 staticpro (&Qsuppress_icon);
5765 Qundefined_color = intern_c_string ("undefined-color");
5766 staticpro (&Qundefined_color);
5767 Qcompound_text = intern_c_string ("compound-text");
5768 staticpro (&Qcompound_text);
5769 Qcancel_timer = intern_c_string ("cancel-timer");
5770 staticpro (&Qcancel_timer);
5771 Qfont_param = intern_c_string ("font-parameter");
5772 staticpro (&Qfont_param);
5773 /* This is the end of symbol initialization. */
5775 /* Text property `display' should be nonsticky by default. */
5776 Vtext_property_default_nonsticky
5777 = Fcons (Fcons (Qdisplay, Qt), Vtext_property_default_nonsticky);
5780 Fput (Qundefined_color, Qerror_conditions,
5781 pure_cons (Qundefined_color, pure_cons (Qerror, Qnil)));
5782 Fput (Qundefined_color, Qerror_message,
5783 make_pure_c_string ("Undefined color"));
5785 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
5786 doc: /* The shape of the pointer when over text.
5787 Changing the value does not affect existing frames
5788 unless you set the mouse color. */);
5789 Vx_pointer_shape = Qnil;
5791 #if 0 /* This doesn't really do anything. */
5792 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape,
5793 doc: /* The shape of the pointer when not over text.
5794 This variable takes effect when you create a new frame
5795 or when you set the mouse color. */);
5796 #endif
5797 Vx_nontext_pointer_shape = Qnil;
5799 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape,
5800 doc: /* The shape of the pointer when Emacs is busy.
5801 This variable takes effect when you create a new frame
5802 or when you set the mouse color. */);
5803 Vx_hourglass_pointer_shape = Qnil;
5805 #if 0 /* This doesn't really do anything. */
5806 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape,
5807 doc: /* The shape of the pointer when over the mode line.
5808 This variable takes effect when you create a new frame
5809 or when you set the mouse color. */);
5810 #endif
5811 Vx_mode_pointer_shape = Qnil;
5813 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
5814 &Vx_sensitive_text_pointer_shape,
5815 doc: /* The shape of the pointer when over mouse-sensitive text.
5816 This variable takes effect when you create a new frame
5817 or when you set the mouse color. */);
5818 Vx_sensitive_text_pointer_shape = Qnil;
5820 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
5821 &Vx_window_horizontal_drag_shape,
5822 doc: /* Pointer shape to use for indicating a window can be dragged horizontally.
5823 This variable takes effect when you create a new frame
5824 or when you set the mouse color. */);
5825 Vx_window_horizontal_drag_shape = Qnil;
5827 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel,
5828 doc: /* A string indicating the foreground color of the cursor box. */);
5829 Vx_cursor_fore_pixel = Qnil;
5831 DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size,
5832 doc: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).
5833 Text larger than this is clipped. */);
5834 Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
5836 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
5837 doc: /* Non-nil if no X window manager is in use.
5838 Emacs doesn't try to figure this out; this is always nil
5839 unless you set it to something else. */);
5840 /* We don't have any way to find this out, so set it to nil
5841 and maybe the user would like to set it to t. */
5842 Vx_no_window_manager = Qnil;
5844 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
5845 &Vx_pixel_size_width_font_regexp,
5846 doc: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
5848 Since Emacs gets width of a font matching with this regexp from
5849 PIXEL_SIZE field of the name, font finding mechanism gets faster for
5850 such a font. This is especially effective for such large fonts as
5851 Chinese, Japanese, and Korean. */);
5852 Vx_pixel_size_width_font_regexp = Qnil;
5854 /* This is not ifdef:ed, so other builds than GTK can customize it. */
5855 DEFVAR_BOOL ("x-gtk-use-old-file-dialog", &x_gtk_use_old_file_dialog,
5856 doc: /* *Non-nil means prompt with the old GTK file selection dialog.
5857 If nil or if the file selection dialog is not available, the new GTK file
5858 chooser is used instead. To turn off all file dialogs set the
5859 variable `use-file-dialog'. */);
5860 x_gtk_use_old_file_dialog = 0;
5862 DEFVAR_BOOL ("x-gtk-show-hidden-files", &x_gtk_show_hidden_files,
5863 doc: /* *If non-nil, the GTK file chooser will by default show hidden files.
5864 Note that this is just the default, there is a toggle button on the file
5865 chooser to show or not show hidden files on a case by case basis. */);
5866 x_gtk_show_hidden_files = 0;
5868 DEFVAR_BOOL ("x-gtk-file-dialog-help-text", &x_gtk_file_dialog_help_text,
5869 doc: /* *If non-nil, the GTK file chooser will show additional help text.
5870 If more space for files in the file chooser dialog is wanted, set this to nil
5871 to turn the additional text off. */);
5872 x_gtk_file_dialog_help_text = 1;
5874 DEFVAR_BOOL ("x-gtk-whole-detached-tool-bar", &x_gtk_whole_detached_tool_bar,
5875 doc: /* *If non-nil, a detached tool bar is shown in full.
5876 The default is to just show an arrow and pressing on that arrow shows
5877 the tool bar buttons. */);
5878 x_gtk_whole_detached_tool_bar = 0;
5880 Fprovide (intern_c_string ("x"), Qnil);
5882 #ifdef USE_X_TOOLKIT
5883 Fprovide (intern_c_string ("x-toolkit"), Qnil);
5884 #ifdef USE_MOTIF
5885 Fprovide (intern_c_string ("motif"), Qnil);
5887 DEFVAR_LISP ("motif-version-string", &Vmotif_version_string,
5888 doc: /* Version info for LessTif/Motif. */);
5889 Vmotif_version_string = build_string (XmVERSION_STRING);
5890 #endif /* USE_MOTIF */
5891 #endif /* USE_X_TOOLKIT */
5893 #ifdef USE_GTK
5894 /* Provide x-toolkit also for GTK. Internally GTK does not use Xt so it
5895 is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
5896 But for a user it is a toolkit for X, and indeed, configure
5897 accepts --with-x-toolkit=gtk. */
5898 Fprovide (intern_c_string ("x-toolkit"), Qnil);
5899 Fprovide (intern_c_string ("gtk"), Qnil);
5901 DEFVAR_LISP ("gtk-version-string", &Vgtk_version_string,
5902 doc: /* Version info for GTK+. */);
5904 char gtk_version[40];
5905 g_snprintf (gtk_version, sizeof (gtk_version), "%u.%u.%u",
5906 GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
5907 Vgtk_version_string = make_pure_string (gtk_version, strlen (gtk_version), strlen (gtk_version), 0);
5909 #endif /* USE_GTK */
5911 /* X window properties. */
5912 defsubr (&Sx_change_window_property);
5913 defsubr (&Sx_delete_window_property);
5914 defsubr (&Sx_window_property);
5916 defsubr (&Sxw_display_color_p);
5917 defsubr (&Sx_display_grayscale_p);
5918 defsubr (&Sxw_color_defined_p);
5919 defsubr (&Sxw_color_values);
5920 defsubr (&Sx_server_max_request_size);
5921 defsubr (&Sx_server_vendor);
5922 defsubr (&Sx_server_version);
5923 defsubr (&Sx_display_pixel_width);
5924 defsubr (&Sx_display_pixel_height);
5925 defsubr (&Sx_display_mm_width);
5926 defsubr (&Sx_display_mm_height);
5927 defsubr (&Sx_display_screens);
5928 defsubr (&Sx_display_planes);
5929 defsubr (&Sx_display_color_cells);
5930 defsubr (&Sx_display_visual_class);
5931 defsubr (&Sx_display_backing_store);
5932 defsubr (&Sx_display_save_under);
5933 defsubr (&Sx_wm_set_size_hint);
5934 defsubr (&Sx_create_frame);
5935 defsubr (&Sx_open_connection);
5936 defsubr (&Sx_close_connection);
5937 defsubr (&Sx_display_list);
5938 defsubr (&Sx_synchronize);
5939 defsubr (&Sx_focus_frame);
5940 defsubr (&Sx_backspace_delete_keys_p);
5942 /* Setting callback functions for fontset handler. */
5943 check_window_system_func = check_x;
5945 defsubr (&Sx_show_tip);
5946 defsubr (&Sx_hide_tip);
5947 tip_timer = Qnil;
5948 staticpro (&tip_timer);
5949 tip_frame = Qnil;
5950 staticpro (&tip_frame);
5952 last_show_tip_args = Qnil;
5953 staticpro (&last_show_tip_args);
5955 defsubr (&Sx_uses_old_gtk_dialog);
5956 #if defined (USE_MOTIF) || defined (USE_GTK)
5957 defsubr (&Sx_file_dialog);
5958 #endif
5960 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
5961 defsubr (&Sx_select_font);
5962 x_last_font_name = NULL;
5963 #endif
5966 #endif /* HAVE_X_WINDOWS */
5968 /* arch-tag: 55040d02-5485-4d58-8b22-95a7a05f3288
5969 (do not change this comment) */