* process.c (ifflag_def): Make flag_sym constant.
[emacs.git] / src / xfns.c
blob0a041a7dc9dfd6a10d7f2f24f9ebc8172f8eb332
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
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>
26 #ifdef HAVE_UNISTD_H
27 #include <unistd.h>
28 #endif
30 /* This makes the fields of a Display accessible, in Xlib header files. */
32 #define XLIB_ILLEGAL_ACCESS
34 #include "lisp.h"
35 #include "xterm.h"
36 #include "frame.h"
37 #include "window.h"
38 #include "buffer.h"
39 #include "intervals.h"
40 #include "dispextern.h"
41 #include "keyboard.h"
42 #include "blockinput.h"
43 #include <epaths.h>
44 #include "character.h"
45 #include "charset.h"
46 #include "coding.h"
47 #include "fontset.h"
48 #include "systime.h"
49 #include "termhooks.h"
50 #include "atimer.h"
51 #include "termchar.h"
52 #include "font.h"
54 #ifdef HAVE_X_WINDOWS
56 #include <ctype.h>
57 #include <sys/types.h>
58 #include <sys/stat.h>
60 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */
61 #include "bitmaps/gray.xbm"
62 #else
63 #include <X11/bitmaps/gray>
64 #endif
66 #ifdef USE_GTK
67 #include "gtkutil.h"
68 #endif
70 #ifdef USE_X_TOOLKIT
71 #include <X11/Shell.h>
73 #ifndef USE_MOTIF
74 #ifdef HAVE_XAW3D
75 #include <X11/Xaw3d/Paned.h>
76 #include <X11/Xaw3d/Label.h>
77 #else /* !HAVE_XAW3D */
78 #include <X11/Xaw/Paned.h>
79 #include <X11/Xaw/Label.h>
80 #endif /* HAVE_XAW3D */
81 #endif /* USE_MOTIF */
83 #ifdef USG
84 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
85 #include <X11/Xos.h>
86 #define USG
87 #else
88 #include <X11/Xos.h>
89 #endif
91 #include "widget.h"
93 #include "../lwlib/lwlib.h"
95 #ifdef USE_MOTIF
96 #include <Xm/Xm.h>
97 #include <Xm/DialogS.h>
98 #include <Xm/FileSB.h>
99 #endif
101 #if !defined(NO_EDITRES)
102 #define HACK_EDITRES
103 extern void _XEditResCheckMessages ();
104 #endif /* not defined NO_EDITRES */
106 /* Unique id counter for widgets created by the Lucid Widget Library. */
108 extern LWLIB_ID widget_id_tick;
110 #ifdef USE_LUCID
111 /* This is part of a kludge--see lwlib/xlwmenu.c. */
112 extern XFontStruct *xlwmenu_default_font;
113 #endif
115 extern void free_frame_menubar ();
116 extern double atof ();
118 #ifdef USE_MOTIF
120 /* LessTif/Motif version info. */
122 static Lisp_Object Vmotif_version_string;
124 #endif /* USE_MOTIF */
126 #endif /* USE_X_TOOLKIT */
128 #ifdef USE_GTK
130 /* GTK+ version info */
132 static Lisp_Object Vgtk_version_string;
134 #endif /* USE_GTK */
136 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
138 /* The gray bitmap `bitmaps/gray'. This is done because xterm.c uses
139 it, and including `bitmaps/gray' more than once is a problem when
140 config.h defines `static' as an empty replacement string. */
142 int gray_bitmap_width = gray_width;
143 int gray_bitmap_height = gray_height;
144 char *gray_bitmap_bits = gray_bits;
146 /* Non-zero means prompt with the old GTK file selection dialog. */
148 int x_gtk_use_old_file_dialog;
150 /* If non-zero, by default show hidden files in the GTK file chooser. */
152 int x_gtk_show_hidden_files;
154 /* If non-zero, don't show additional help text in the GTK file chooser. */
156 int x_gtk_file_dialog_help_text;
158 /* If non-zero, don't collapse to tool bar when it is detached. */
160 int x_gtk_whole_detached_tool_bar;
162 /* The background and shape of the mouse pointer, and shape when not
163 over text or in the modeline. */
165 Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
166 Lisp_Object Vx_hourglass_pointer_shape;
168 /* The shape when over mouse-sensitive text. */
170 Lisp_Object Vx_sensitive_text_pointer_shape;
172 /* If non-nil, the pointer shape to indicate that windows can be
173 dragged horizontally. */
175 Lisp_Object Vx_window_horizontal_drag_shape;
177 /* Color of chars displayed in cursor box. */
179 Lisp_Object Vx_cursor_fore_pixel;
181 /* Nonzero if using X. */
183 static int x_in_use;
185 /* Non nil if no window manager is in use. */
187 Lisp_Object Vx_no_window_manager;
189 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
191 Lisp_Object Vx_pixel_size_width_font_regexp;
193 Lisp_Object Qnone;
194 Lisp_Object Qsuppress_icon;
195 Lisp_Object Qundefined_color;
196 Lisp_Object Qcompound_text, Qcancel_timer;
197 static Lisp_Object Qfont_param;
199 /* In dispnew.c */
201 extern Lisp_Object Vwindow_system_version;
203 /* The below are defined in frame.c. */
205 #if GLYPH_DEBUG
206 int image_cache_refcount, dpyinfo_refcount;
207 #endif
209 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
210 char *x_last_font_name;
211 #endif
214 /* Error if we are not connected to X. */
216 void
217 check_x ()
219 if (! x_in_use)
220 error ("X windows are not in use or not initialized");
223 /* Nonzero if we can use mouse menus.
224 You should not call this unless HAVE_MENUS is defined. */
227 have_menus_p ()
229 return x_in_use;
232 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
233 and checking validity for X. */
235 FRAME_PTR
236 check_x_frame (frame)
237 Lisp_Object frame;
239 FRAME_PTR f;
241 if (NILP (frame))
242 frame = selected_frame;
243 CHECK_LIVE_FRAME (frame);
244 f = XFRAME (frame);
245 if (! FRAME_X_P (f))
246 error ("Non-X frame used");
247 return f;
250 /* Let the user specify an X display with a Lisp object.
251 OBJECT may be nil, a frame or a terminal object.
252 nil stands for the selected frame--or, if that is not an X frame,
253 the first X display on the list. */
255 struct x_display_info *
256 check_x_display_info (object)
257 Lisp_Object object;
259 struct x_display_info *dpyinfo = NULL;
261 if (NILP (object))
263 struct frame *sf = XFRAME (selected_frame);
265 if (FRAME_X_P (sf) && FRAME_LIVE_P (sf))
266 dpyinfo = FRAME_X_DISPLAY_INFO (sf);
267 else if (x_display_list != 0)
268 dpyinfo = x_display_list;
269 else
270 error ("X windows are not in use or not initialized");
272 else if (TERMINALP (object))
274 struct terminal *t = get_terminal (object, 1);
276 if (t->type != output_x_window)
277 error ("Terminal %d is not an X display", XINT (object));
279 dpyinfo = t->display_info.x;
281 else if (STRINGP (object))
282 dpyinfo = x_display_info_for_name (object);
283 else
285 FRAME_PTR f = check_x_frame (object);
286 dpyinfo = FRAME_X_DISPLAY_INFO (f);
289 return dpyinfo;
293 /* Return the Emacs frame-object corresponding to an X window.
294 It could be the frame's main window or an icon window. */
296 /* This function can be called during GC, so use GC_xxx type test macros. */
298 struct frame *
299 x_window_to_frame (dpyinfo, wdesc)
300 struct x_display_info *dpyinfo;
301 int wdesc;
303 Lisp_Object tail, frame;
304 struct frame *f;
306 if (wdesc == None) return 0;
308 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
310 frame = XCAR (tail);
311 if (!FRAMEP (frame))
312 continue;
313 f = XFRAME (frame);
314 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
315 continue;
316 if (f->output_data.x->hourglass_window == wdesc)
317 return f;
318 #ifdef USE_X_TOOLKIT
319 if ((f->output_data.x->edit_widget
320 && XtWindow (f->output_data.x->edit_widget) == wdesc)
321 /* A tooltip frame? */
322 || (!f->output_data.x->edit_widget
323 && FRAME_X_WINDOW (f) == wdesc)
324 || f->output_data.x->icon_desc == wdesc)
325 return f;
326 #else /* not USE_X_TOOLKIT */
327 #ifdef USE_GTK
328 if (f->output_data.x->edit_widget)
330 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
331 struct x_output *x = f->output_data.x;
332 if (gwdesc != 0 && gwdesc == x->edit_widget)
333 return f;
335 #endif /* USE_GTK */
336 if (FRAME_X_WINDOW (f) == wdesc
337 || f->output_data.x->icon_desc == wdesc)
338 return f;
339 #endif /* not USE_X_TOOLKIT */
341 return 0;
344 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
345 /* Like x_window_to_frame but also compares the window with the widget's
346 windows. */
348 struct frame *
349 x_any_window_to_frame (dpyinfo, wdesc)
350 struct x_display_info *dpyinfo;
351 int wdesc;
353 Lisp_Object tail, frame;
354 struct frame *f, *found;
355 struct x_output *x;
357 if (wdesc == None) return NULL;
359 found = NULL;
360 for (tail = Vframe_list; CONSP (tail) && !found; tail = XCDR (tail))
362 frame = XCAR (tail);
363 if (!FRAMEP (frame))
364 continue;
366 f = XFRAME (frame);
367 if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) == dpyinfo)
369 /* This frame matches if the window is any of its widgets. */
370 x = f->output_data.x;
371 if (x->hourglass_window == wdesc)
372 found = f;
373 else if (x->widget)
375 #ifdef USE_GTK
376 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
377 if (gwdesc != 0
378 && gtk_widget_get_toplevel (gwdesc) == x->widget)
379 found = f;
380 #else
381 if (wdesc == XtWindow (x->widget)
382 || wdesc == XtWindow (x->column_widget)
383 || wdesc == XtWindow (x->edit_widget))
384 found = f;
385 /* Match if the window is this frame's menubar. */
386 else if (lw_window_is_in_menubar (wdesc, x->menubar_widget))
387 found = f;
388 #endif
390 else if (FRAME_X_WINDOW (f) == wdesc)
391 /* A tooltip frame. */
392 found = f;
396 return found;
399 /* Likewise, but consider only the menu bar widget. */
401 struct frame *
402 x_menubar_window_to_frame (dpyinfo, wdesc)
403 struct x_display_info *dpyinfo;
404 int wdesc;
406 Lisp_Object tail, frame;
407 struct frame *f;
408 struct x_output *x;
410 if (wdesc == None) return 0;
412 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
414 frame = XCAR (tail);
415 if (!FRAMEP (frame))
416 continue;
417 f = XFRAME (frame);
418 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
419 continue;
420 x = f->output_data.x;
421 /* Match if the window is this frame's menubar. */
422 #ifdef USE_GTK
423 if (x->menubar_widget)
425 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
427 /* This gives false positives, but the rectangle check in xterm.c
428 where this is called takes care of that. */
429 if (gwdesc != 0
430 && (gwdesc == x->menubar_widget
431 || gtk_widget_is_ancestor (x->menubar_widget, gwdesc)
432 || gtk_widget_is_ancestor (gwdesc, x->menubar_widget)))
433 return f;
435 #else
436 if (x->menubar_widget
437 && lw_window_is_in_menubar (wdesc, x->menubar_widget))
438 return f;
439 #endif
441 return 0;
444 /* Return the frame whose principal (outermost) window is WDESC.
445 If WDESC is some other (smaller) window, we return 0. */
447 struct frame *
448 x_top_window_to_frame (dpyinfo, wdesc)
449 struct x_display_info *dpyinfo;
450 int wdesc;
452 Lisp_Object tail, frame;
453 struct frame *f;
454 struct x_output *x;
456 if (wdesc == None) return 0;
458 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
460 frame = XCAR (tail);
461 if (!FRAMEP (frame))
462 continue;
463 f = XFRAME (frame);
464 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
465 continue;
466 x = f->output_data.x;
468 if (x->widget)
470 /* This frame matches if the window is its topmost widget. */
471 #ifdef USE_GTK
472 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
473 if (gwdesc == x->widget)
474 return f;
475 #else
476 if (wdesc == XtWindow (x->widget))
477 return f;
478 #if 0 /* I don't know why it did this,
479 but it seems logically wrong,
480 and it causes trouble for MapNotify events. */
481 /* Match if the window is this frame's menubar. */
482 if (x->menubar_widget
483 && wdesc == XtWindow (x->menubar_widget))
484 return f;
485 #endif
486 #endif
488 else if (FRAME_X_WINDOW (f) == wdesc)
489 /* Tooltip frame. */
490 return f;
492 return 0;
494 #endif /* USE_X_TOOLKIT || USE_GTK */
498 static void x_default_font_parameter P_ ((struct frame *, Lisp_Object));
500 static Lisp_Object unwind_create_frame P_ ((Lisp_Object));
501 static Lisp_Object unwind_create_tip_frame P_ ((Lisp_Object));
503 void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
504 static void x_set_wait_for_wm P_ ((struct frame *, Lisp_Object, Lisp_Object));
505 void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
506 void x_set_mouse_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
507 void x_set_cursor_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
508 void x_set_border_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
509 void x_set_cursor_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
510 void x_set_icon_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
511 void x_set_icon_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
512 void x_explicitly_set_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
513 void x_set_menu_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
514 void x_set_title P_ ((struct frame *, Lisp_Object, Lisp_Object));
515 void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
516 void x_set_scroll_bar_foreground P_ ((struct frame *, Lisp_Object,
517 Lisp_Object));
518 void x_set_scroll_bar_background P_ ((struct frame *, Lisp_Object,
519 Lisp_Object));
520 static Lisp_Object x_default_scroll_bar_color_parameter P_ ((struct frame *,
521 Lisp_Object,
522 Lisp_Object,
523 char *, char *,
524 int));
527 /* Store the screen positions of frame F into XPTR and YPTR.
528 These are the positions of the containing window manager window,
529 not Emacs's own window. */
531 void
532 x_real_positions (f, xptr, yptr)
533 FRAME_PTR f;
534 int *xptr, *yptr;
536 int win_x, win_y, outer_x, outer_y;
537 int real_x = 0, real_y = 0;
538 int had_errors = 0;
539 Window win = f->output_data.x->parent_desc;
541 BLOCK_INPUT;
543 x_catch_errors (FRAME_X_DISPLAY (f));
545 if (win == FRAME_X_DISPLAY_INFO (f)->root_window)
546 win = FRAME_OUTER_WINDOW (f);
548 /* This loop traverses up the containment tree until we hit the root
549 window. Window managers may intersect many windows between our window
550 and the root window. The window we find just before the root window
551 should be the outer WM window. */
552 for (;;)
554 Window wm_window, rootw;
555 Window *tmp_children;
556 unsigned int tmp_nchildren;
557 int success;
559 success = XQueryTree (FRAME_X_DISPLAY (f), win, &rootw,
560 &wm_window, &tmp_children, &tmp_nchildren);
562 had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
564 /* Don't free tmp_children if XQueryTree failed. */
565 if (! success)
566 break;
568 XFree ((char *) tmp_children);
570 if (wm_window == rootw || had_errors)
571 break;
573 win = wm_window;
576 if (! had_errors)
578 unsigned int ign;
579 Window child, rootw;
581 /* Get the real coordinates for the WM window upper left corner */
582 XGetGeometry (FRAME_X_DISPLAY (f), win,
583 &rootw, &real_x, &real_y, &ign, &ign, &ign, &ign);
585 /* Translate real coordinates to coordinates relative to our
586 window. For our window, the upper left corner is 0, 0.
587 Since the upper left corner of the WM window is outside
588 our window, win_x and win_y will be negative:
590 ------------------ ---> x
591 | title |
592 | ----------------- v y
593 | | our window
595 XTranslateCoordinates (FRAME_X_DISPLAY (f),
597 /* From-window, to-window. */
598 FRAME_X_DISPLAY_INFO (f)->root_window,
599 FRAME_X_WINDOW (f),
601 /* From-position, to-position. */
602 real_x, real_y, &win_x, &win_y,
604 /* Child of win. */
605 &child);
607 if (FRAME_X_WINDOW (f) == FRAME_OUTER_WINDOW (f))
609 outer_x = win_x;
610 outer_y = win_y;
612 else
614 XTranslateCoordinates (FRAME_X_DISPLAY (f),
616 /* From-window, to-window. */
617 FRAME_X_DISPLAY_INFO (f)->root_window,
618 FRAME_OUTER_WINDOW (f),
620 /* From-position, to-position. */
621 real_x, real_y, &outer_x, &outer_y,
623 /* Child of win. */
624 &child);
627 had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
630 x_uncatch_errors ();
632 UNBLOCK_INPUT;
634 if (had_errors) return;
636 f->x_pixels_diff = -win_x;
637 f->y_pixels_diff = -win_y;
639 FRAME_X_OUTPUT (f)->x_pixels_outer_diff = -outer_x;
640 FRAME_X_OUTPUT (f)->y_pixels_outer_diff = -outer_y;
642 *xptr = real_x;
643 *yptr = real_y;
649 /* Gamma-correct COLOR on frame F. */
651 void
652 gamma_correct (f, color)
653 struct frame *f;
654 XColor *color;
656 if (f->gamma)
658 color->red = pow (color->red / 65535.0, f->gamma) * 65535.0 + 0.5;
659 color->green = pow (color->green / 65535.0, f->gamma) * 65535.0 + 0.5;
660 color->blue = pow (color->blue / 65535.0, f->gamma) * 65535.0 + 0.5;
665 /* Decide if color named COLOR_NAME is valid for use on frame F. If
666 so, return the RGB values in COLOR. If ALLOC_P is non-zero,
667 allocate the color. Value is zero if COLOR_NAME is invalid, or
668 no color could be allocated. */
671 x_defined_color (f, color_name, color, alloc_p)
672 struct frame *f;
673 char *color_name;
674 XColor *color;
675 int alloc_p;
677 int success_p;
678 Display *dpy = FRAME_X_DISPLAY (f);
679 Colormap cmap = FRAME_X_COLORMAP (f);
681 BLOCK_INPUT;
682 success_p = XParseColor (dpy, cmap, color_name, color);
683 if (success_p && alloc_p)
684 success_p = x_alloc_nearest_color (f, cmap, color);
685 UNBLOCK_INPUT;
687 return success_p;
691 /* Return the pixel color value for color COLOR_NAME on frame F. If F
692 is a monochrome frame, return MONO_COLOR regardless of what ARG says.
693 Signal an error if color can't be allocated. */
696 x_decode_color (f, color_name, mono_color)
697 FRAME_PTR f;
698 Lisp_Object color_name;
699 int mono_color;
701 XColor cdef;
703 CHECK_STRING (color_name);
705 #if 0 /* Don't do this. It's wrong when we're not using the default
706 colormap, it makes freeing difficult, and it's probably not
707 an important optimization. */
708 if (strcmp (SDATA (color_name), "black") == 0)
709 return BLACK_PIX_DEFAULT (f);
710 else if (strcmp (SDATA (color_name), "white") == 0)
711 return WHITE_PIX_DEFAULT (f);
712 #endif
714 /* Return MONO_COLOR for monochrome frames. */
715 if (FRAME_X_DISPLAY_INFO (f)->n_planes == 1)
716 return mono_color;
718 /* x_defined_color is responsible for coping with failures
719 by looking for a near-miss. */
720 if (x_defined_color (f, SDATA (color_name), &cdef, 1))
721 return cdef.pixel;
723 signal_error ("Undefined color", color_name);
728 /* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
729 the previous value of that parameter, NEW_VALUE is the new value.
730 See also the comment of wait_for_wm in struct x_output. */
732 static void
733 x_set_wait_for_wm (f, new_value, old_value)
734 struct frame *f;
735 Lisp_Object new_value, old_value;
737 f->output_data.x->wait_for_wm = !NILP (new_value);
740 #ifdef USE_GTK
742 /* Set icon from FILE for frame F. By using GTK functions the icon
743 may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
746 xg_set_icon (f, file)
747 FRAME_PTR f;
748 Lisp_Object file;
750 int result = 0;
751 Lisp_Object found;
753 found = x_find_image_file (file);
755 if (! NILP (found))
757 GdkPixbuf *pixbuf;
758 GError *err = NULL;
759 char *filename = (char *) SDATA (found);
760 BLOCK_INPUT;
762 pixbuf = gdk_pixbuf_new_from_file (filename, &err);
764 if (pixbuf)
766 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
767 pixbuf);
768 g_object_unref (pixbuf);
770 result = 1;
772 else
773 g_error_free (err);
775 UNBLOCK_INPUT;
778 return result;
782 xg_set_icon_from_xpm_data (f, data)
783 FRAME_PTR f;
784 char **data;
786 int result = 0;
787 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) data);
789 if (!pixbuf)
790 return 0;
792 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), pixbuf);
793 g_object_unref (pixbuf);
794 return 1;
796 #endif /* USE_GTK */
799 /* Functions called only from `x_set_frame_param'
800 to set individual parameters.
802 If FRAME_X_WINDOW (f) is 0,
803 the frame is being created and its X-window does not exist yet.
804 In that case, just record the parameter's new value
805 in the standard place; do not attempt to change the window. */
807 void
808 x_set_foreground_color (f, arg, oldval)
809 struct frame *f;
810 Lisp_Object arg, oldval;
812 struct x_output *x = f->output_data.x;
813 unsigned long fg, old_fg;
815 fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
816 old_fg = FRAME_FOREGROUND_PIXEL (f);
817 FRAME_FOREGROUND_PIXEL (f) = fg;
819 if (FRAME_X_WINDOW (f) != 0)
821 Display *dpy = FRAME_X_DISPLAY (f);
823 BLOCK_INPUT;
824 XSetForeground (dpy, x->normal_gc, fg);
825 XSetBackground (dpy, x->reverse_gc, fg);
827 if (x->cursor_pixel == old_fg)
829 unload_color (f, x->cursor_pixel);
830 x->cursor_pixel = x_copy_color (f, fg);
831 XSetBackground (dpy, x->cursor_gc, x->cursor_pixel);
834 UNBLOCK_INPUT;
836 update_face_from_frame_parameter (f, Qforeground_color, arg);
838 if (FRAME_VISIBLE_P (f))
839 redraw_frame (f);
842 unload_color (f, old_fg);
845 void
846 x_set_background_color (f, arg, oldval)
847 struct frame *f;
848 Lisp_Object arg, oldval;
850 struct x_output *x = f->output_data.x;
851 unsigned long bg;
853 bg = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
854 unload_color (f, FRAME_BACKGROUND_PIXEL (f));
855 FRAME_BACKGROUND_PIXEL (f) = bg;
857 if (FRAME_X_WINDOW (f) != 0)
859 Display *dpy = FRAME_X_DISPLAY (f);
861 BLOCK_INPUT;
862 XSetBackground (dpy, x->normal_gc, bg);
863 XSetForeground (dpy, x->reverse_gc, bg);
864 XSetWindowBackground (dpy, FRAME_X_WINDOW (f), bg);
865 XSetForeground (dpy, x->cursor_gc, bg);
867 #ifdef USE_GTK
868 xg_set_background_color (f, bg);
869 #endif
871 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
872 toolkit scroll bars. */
874 Lisp_Object bar;
875 for (bar = FRAME_SCROLL_BARS (f);
876 !NILP (bar);
877 bar = XSCROLL_BAR (bar)->next)
879 Window window = XSCROLL_BAR (bar)->x_window;
880 XSetWindowBackground (dpy, window, bg);
883 #endif /* USE_TOOLKIT_SCROLL_BARS */
885 UNBLOCK_INPUT;
886 update_face_from_frame_parameter (f, Qbackground_color, arg);
888 if (FRAME_VISIBLE_P (f))
889 redraw_frame (f);
893 static Cursor
894 make_invisible_cursor (f)
895 struct frame *f;
897 Display *dpy = FRAME_X_DISPLAY (f);
898 static char const no_data[] = { 0 };
899 Pixmap pix;
900 XColor col;
901 Cursor c;
903 x_catch_errors (dpy);
904 pix = XCreateBitmapFromData (dpy, FRAME_X_DISPLAY_INFO (f)->root_window,
905 no_data, 1, 1);
906 if (! x_had_errors_p (dpy) && pix != None)
908 col.pixel = 0;
909 col.red = col.green = col.blue = 0;
910 col.flags = DoRed | DoGreen | DoBlue;
911 c = XCreatePixmapCursor (dpy, pix, pix, &col, &col, 0, 0);
912 if (x_had_errors_p (dpy) || c == None)
913 c = 0;
914 XFreePixmap (dpy, pix);
917 x_uncatch_errors ();
919 return c;
922 void
923 x_set_mouse_color (f, arg, oldval)
924 struct frame *f;
925 Lisp_Object arg, oldval;
927 struct x_output *x = f->output_data.x;
928 Display *dpy = FRAME_X_DISPLAY (f);
929 Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
930 Cursor hourglass_cursor, horizontal_drag_cursor;
931 unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
932 unsigned long mask_color = FRAME_BACKGROUND_PIXEL (f);
934 /* Don't let pointers be invisible. */
935 if (mask_color == pixel)
937 x_free_colors (f, &pixel, 1);
938 pixel = x_copy_color (f, FRAME_FOREGROUND_PIXEL (f));
941 unload_color (f, x->mouse_pixel);
942 x->mouse_pixel = pixel;
944 BLOCK_INPUT;
946 /* It's not okay to crash if the user selects a screwy cursor. */
947 x_catch_errors (dpy);
949 if (!NILP (Vx_pointer_shape))
951 CHECK_NUMBER (Vx_pointer_shape);
952 cursor = XCreateFontCursor (dpy, XINT (Vx_pointer_shape));
954 else
955 cursor = XCreateFontCursor (dpy, XC_xterm);
956 x_check_errors (dpy, "bad text pointer cursor: %s");
958 if (!NILP (Vx_nontext_pointer_shape))
960 CHECK_NUMBER (Vx_nontext_pointer_shape);
961 nontext_cursor
962 = XCreateFontCursor (dpy, XINT (Vx_nontext_pointer_shape));
964 else
965 nontext_cursor = XCreateFontCursor (dpy, XC_left_ptr);
966 x_check_errors (dpy, "bad nontext pointer cursor: %s");
968 if (!NILP (Vx_hourglass_pointer_shape))
970 CHECK_NUMBER (Vx_hourglass_pointer_shape);
971 hourglass_cursor
972 = XCreateFontCursor (dpy, XINT (Vx_hourglass_pointer_shape));
974 else
975 hourglass_cursor = XCreateFontCursor (dpy, XC_watch);
976 x_check_errors (dpy, "bad hourglass pointer cursor: %s");
978 if (!NILP (Vx_mode_pointer_shape))
980 CHECK_NUMBER (Vx_mode_pointer_shape);
981 mode_cursor = XCreateFontCursor (dpy, XINT (Vx_mode_pointer_shape));
983 else
984 mode_cursor = XCreateFontCursor (dpy, XC_xterm);
985 x_check_errors (dpy, "bad modeline pointer cursor: %s");
987 if (!NILP (Vx_sensitive_text_pointer_shape))
989 CHECK_NUMBER (Vx_sensitive_text_pointer_shape);
990 hand_cursor
991 = XCreateFontCursor (dpy, XINT (Vx_sensitive_text_pointer_shape));
993 else
994 hand_cursor = XCreateFontCursor (dpy, XC_hand2);
996 if (!NILP (Vx_window_horizontal_drag_shape))
998 CHECK_NUMBER (Vx_window_horizontal_drag_shape);
999 horizontal_drag_cursor
1000 = XCreateFontCursor (dpy, XINT (Vx_window_horizontal_drag_shape));
1002 else
1003 horizontal_drag_cursor
1004 = XCreateFontCursor (dpy, XC_sb_h_double_arrow);
1006 /* Check and report errors with the above calls. */
1007 x_check_errors (dpy, "can't set cursor shape: %s");
1008 x_uncatch_errors ();
1011 XColor fore_color, back_color;
1013 fore_color.pixel = x->mouse_pixel;
1014 x_query_color (f, &fore_color);
1015 back_color.pixel = mask_color;
1016 x_query_color (f, &back_color);
1018 XRecolorCursor (dpy, cursor, &fore_color, &back_color);
1019 XRecolorCursor (dpy, nontext_cursor, &fore_color, &back_color);
1020 XRecolorCursor (dpy, mode_cursor, &fore_color, &back_color);
1021 XRecolorCursor (dpy, hand_cursor, &fore_color, &back_color);
1022 XRecolorCursor (dpy, hourglass_cursor, &fore_color, &back_color);
1023 XRecolorCursor (dpy, horizontal_drag_cursor, &fore_color, &back_color);
1026 if (FRAME_X_WINDOW (f) != 0)
1027 XDefineCursor (dpy, FRAME_X_WINDOW (f),
1028 f->output_data.x->current_cursor = cursor);
1030 if (FRAME_X_DISPLAY_INFO (f)->invisible_cursor == 0)
1031 FRAME_X_DISPLAY_INFO (f)->invisible_cursor = make_invisible_cursor (f);
1033 if (cursor != x->text_cursor
1034 && x->text_cursor != 0)
1035 XFreeCursor (dpy, x->text_cursor);
1036 x->text_cursor = cursor;
1038 if (nontext_cursor != x->nontext_cursor
1039 && x->nontext_cursor != 0)
1040 XFreeCursor (dpy, x->nontext_cursor);
1041 x->nontext_cursor = nontext_cursor;
1043 if (hourglass_cursor != x->hourglass_cursor
1044 && x->hourglass_cursor != 0)
1045 XFreeCursor (dpy, x->hourglass_cursor);
1046 x->hourglass_cursor = hourglass_cursor;
1048 if (mode_cursor != x->modeline_cursor
1049 && x->modeline_cursor != 0)
1050 XFreeCursor (dpy, f->output_data.x->modeline_cursor);
1051 x->modeline_cursor = mode_cursor;
1053 if (hand_cursor != x->hand_cursor
1054 && x->hand_cursor != 0)
1055 XFreeCursor (dpy, x->hand_cursor);
1056 x->hand_cursor = hand_cursor;
1058 if (horizontal_drag_cursor != x->horizontal_drag_cursor
1059 && x->horizontal_drag_cursor != 0)
1060 XFreeCursor (dpy, x->horizontal_drag_cursor);
1061 x->horizontal_drag_cursor = horizontal_drag_cursor;
1063 XFlush (dpy);
1064 UNBLOCK_INPUT;
1066 update_face_from_frame_parameter (f, Qmouse_color, arg);
1069 void
1070 x_set_cursor_color (f, arg, oldval)
1071 struct frame *f;
1072 Lisp_Object arg, oldval;
1074 unsigned long fore_pixel, pixel;
1075 int fore_pixel_allocated_p = 0, pixel_allocated_p = 0;
1076 struct x_output *x = f->output_data.x;
1078 if (!NILP (Vx_cursor_fore_pixel))
1080 fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
1081 WHITE_PIX_DEFAULT (f));
1082 fore_pixel_allocated_p = 1;
1084 else
1085 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1087 pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1088 pixel_allocated_p = 1;
1090 /* Make sure that the cursor color differs from the background color. */
1091 if (pixel == FRAME_BACKGROUND_PIXEL (f))
1093 if (pixel_allocated_p)
1095 x_free_colors (f, &pixel, 1);
1096 pixel_allocated_p = 0;
1099 pixel = x->mouse_pixel;
1100 if (pixel == fore_pixel)
1102 if (fore_pixel_allocated_p)
1104 x_free_colors (f, &fore_pixel, 1);
1105 fore_pixel_allocated_p = 0;
1107 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1111 unload_color (f, x->cursor_foreground_pixel);
1112 if (!fore_pixel_allocated_p)
1113 fore_pixel = x_copy_color (f, fore_pixel);
1114 x->cursor_foreground_pixel = fore_pixel;
1116 unload_color (f, x->cursor_pixel);
1117 if (!pixel_allocated_p)
1118 pixel = x_copy_color (f, pixel);
1119 x->cursor_pixel = pixel;
1121 if (FRAME_X_WINDOW (f) != 0)
1123 BLOCK_INPUT;
1124 XSetBackground (FRAME_X_DISPLAY (f), x->cursor_gc, x->cursor_pixel);
1125 XSetForeground (FRAME_X_DISPLAY (f), x->cursor_gc, fore_pixel);
1126 UNBLOCK_INPUT;
1128 if (FRAME_VISIBLE_P (f))
1130 x_update_cursor (f, 0);
1131 x_update_cursor (f, 1);
1135 update_face_from_frame_parameter (f, Qcursor_color, arg);
1138 /* Set the border-color of frame F to pixel value PIX.
1139 Note that this does not fully take effect if done before
1140 F has an x-window. */
1142 void
1143 x_set_border_pixel (f, pix)
1144 struct frame *f;
1145 int pix;
1147 unload_color (f, f->output_data.x->border_pixel);
1148 f->output_data.x->border_pixel = pix;
1150 if (FRAME_X_WINDOW (f) != 0 && f->border_width > 0)
1152 BLOCK_INPUT;
1153 XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1154 (unsigned long)pix);
1155 UNBLOCK_INPUT;
1157 if (FRAME_VISIBLE_P (f))
1158 redraw_frame (f);
1162 /* Set the border-color of frame F to value described by ARG.
1163 ARG can be a string naming a color.
1164 The border-color is used for the border that is drawn by the X server.
1165 Note that this does not fully take effect if done before
1166 F has an x-window; it must be redone when the window is created.
1168 Note: this is done in two routines because of the way X10 works.
1170 Note: under X11, this is normally the province of the window manager,
1171 and so emacs' border colors may be overridden. */
1173 void
1174 x_set_border_color (f, arg, oldval)
1175 struct frame *f;
1176 Lisp_Object arg, oldval;
1178 int pix;
1180 CHECK_STRING (arg);
1181 pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1182 x_set_border_pixel (f, pix);
1183 update_face_from_frame_parameter (f, Qborder_color, arg);
1187 void
1188 x_set_cursor_type (f, arg, oldval)
1189 FRAME_PTR f;
1190 Lisp_Object arg, oldval;
1192 set_frame_cursor_types (f, arg);
1194 /* Make sure the cursor gets redrawn. */
1195 cursor_type_changed = 1;
1198 void
1199 x_set_icon_type (f, arg, oldval)
1200 struct frame *f;
1201 Lisp_Object arg, oldval;
1203 int result;
1205 if (STRINGP (arg))
1207 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1208 return;
1210 else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
1211 return;
1213 BLOCK_INPUT;
1214 if (NILP (arg))
1215 result = x_text_icon (f,
1216 (char *) SDATA ((!NILP (f->icon_name)
1217 ? f->icon_name
1218 : f->name)));
1219 else
1220 result = x_bitmap_icon (f, arg);
1222 if (result)
1224 UNBLOCK_INPUT;
1225 error ("No icon window available");
1228 XFlush (FRAME_X_DISPLAY (f));
1229 UNBLOCK_INPUT;
1232 void
1233 x_set_icon_name (f, arg, oldval)
1234 struct frame *f;
1235 Lisp_Object arg, oldval;
1237 int result;
1239 if (STRINGP (arg))
1241 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1242 return;
1244 else if (!NILP (arg) || NILP (oldval))
1245 return;
1247 f->icon_name = arg;
1249 if (f->output_data.x->icon_bitmap != 0)
1250 return;
1252 BLOCK_INPUT;
1254 result = x_text_icon (f,
1255 (char *) SDATA ((!NILP (f->icon_name)
1256 ? f->icon_name
1257 : !NILP (f->title)
1258 ? f->title
1259 : f->name)));
1261 if (result)
1263 UNBLOCK_INPUT;
1264 error ("No icon window available");
1267 XFlush (FRAME_X_DISPLAY (f));
1268 UNBLOCK_INPUT;
1272 void
1273 x_set_menu_bar_lines (f, value, oldval)
1274 struct frame *f;
1275 Lisp_Object value, oldval;
1277 int nlines;
1278 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
1279 int olines = FRAME_MENU_BAR_LINES (f);
1280 #endif
1282 /* Right now, menu bars don't work properly in minibuf-only frames;
1283 most of the commands try to apply themselves to the minibuffer
1284 frame itself, and get an error because you can't switch buffers
1285 in or split the minibuffer window. */
1286 if (FRAME_MINIBUF_ONLY_P (f))
1287 return;
1289 if (INTEGERP (value))
1290 nlines = XINT (value);
1291 else
1292 nlines = 0;
1294 /* Make sure we redisplay all windows in this frame. */
1295 windows_or_buffers_changed++;
1297 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1298 FRAME_MENU_BAR_LINES (f) = 0;
1299 if (nlines)
1301 FRAME_EXTERNAL_MENU_BAR (f) = 1;
1302 if (FRAME_X_P (f) && f->output_data.x->menubar_widget == 0)
1303 /* Make sure next redisplay shows the menu bar. */
1304 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
1306 else
1308 if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
1309 free_frame_menubar (f);
1310 FRAME_EXTERNAL_MENU_BAR (f) = 0;
1311 if (FRAME_X_P (f))
1312 f->output_data.x->menubar_widget = 0;
1314 #else /* not USE_X_TOOLKIT && not USE_GTK */
1315 FRAME_MENU_BAR_LINES (f) = nlines;
1316 change_window_heights (f->root_window, nlines - olines);
1317 #endif /* not USE_X_TOOLKIT */
1318 adjust_glyphs (f);
1322 /* Set the number of lines used for the tool bar of frame F to VALUE.
1323 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1324 is the old number of tool bar lines. This function changes the
1325 height of all windows on frame F to match the new tool bar height.
1326 The frame's height doesn't change. */
1328 void
1329 x_set_tool_bar_lines (f, value, oldval)
1330 struct frame *f;
1331 Lisp_Object value, oldval;
1333 int delta, nlines, root_height;
1334 Lisp_Object root_window;
1336 /* Treat tool bars like menu bars. */
1337 if (FRAME_MINIBUF_ONLY_P (f))
1338 return;
1340 /* Use VALUE only if an integer >= 0. */
1341 if (INTEGERP (value) && XINT (value) >= 0)
1342 nlines = XFASTINT (value);
1343 else
1344 nlines = 0;
1346 #ifdef USE_GTK
1347 FRAME_TOOL_BAR_LINES (f) = 0;
1348 if (nlines)
1350 FRAME_EXTERNAL_TOOL_BAR (f) = 1;
1351 if (FRAME_X_P (f) && f->output_data.x->toolbar_widget == 0)
1352 /* Make sure next redisplay shows the tool bar. */
1353 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
1354 update_frame_tool_bar (f);
1356 else
1358 if (FRAME_EXTERNAL_TOOL_BAR (f))
1359 free_frame_tool_bar (f);
1360 FRAME_EXTERNAL_TOOL_BAR (f) = 0;
1363 return;
1364 #endif
1366 /* Make sure we redisplay all windows in this frame. */
1367 ++windows_or_buffers_changed;
1369 delta = nlines - FRAME_TOOL_BAR_LINES (f);
1371 /* Don't resize the tool-bar to more than we have room for. */
1372 root_window = FRAME_ROOT_WINDOW (f);
1373 root_height = WINDOW_TOTAL_LINES (XWINDOW (root_window));
1374 if (root_height - delta < 1)
1376 delta = root_height - 1;
1377 nlines = FRAME_TOOL_BAR_LINES (f) + delta;
1380 FRAME_TOOL_BAR_LINES (f) = nlines;
1381 change_window_heights (root_window, delta);
1382 adjust_glyphs (f);
1384 /* We also have to make sure that the internal border at the top of
1385 the frame, below the menu bar or tool bar, is redrawn when the
1386 tool bar disappears. This is so because the internal border is
1387 below the tool bar if one is displayed, but is below the menu bar
1388 if there isn't a tool bar. The tool bar draws into the area
1389 below the menu bar. */
1390 if (FRAME_X_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0)
1392 clear_frame (f);
1393 clear_current_matrices (f);
1396 /* If the tool bar gets smaller, the internal border below it
1397 has to be cleared. It was formerly part of the display
1398 of the larger tool bar, and updating windows won't clear it. */
1399 if (delta < 0)
1401 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1402 int width = FRAME_PIXEL_WIDTH (f);
1403 int y = nlines * FRAME_LINE_HEIGHT (f);
1405 /* height can be zero here. */
1406 if (height > 0 && width > 0)
1408 BLOCK_INPUT;
1409 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1410 0, y, width, height, False);
1411 UNBLOCK_INPUT;
1414 if (WINDOWP (f->tool_bar_window))
1415 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1420 /* Set the foreground color for scroll bars on frame F to VALUE.
1421 VALUE should be a string, a color name. If it isn't a string or
1422 isn't a valid color name, do nothing. OLDVAL is the old value of
1423 the frame parameter. */
1425 void
1426 x_set_scroll_bar_foreground (f, value, oldval)
1427 struct frame *f;
1428 Lisp_Object value, oldval;
1430 unsigned long pixel;
1432 if (STRINGP (value))
1433 pixel = x_decode_color (f, value, BLACK_PIX_DEFAULT (f));
1434 else
1435 pixel = -1;
1437 if (f->output_data.x->scroll_bar_foreground_pixel != -1)
1438 unload_color (f, f->output_data.x->scroll_bar_foreground_pixel);
1440 f->output_data.x->scroll_bar_foreground_pixel = pixel;
1441 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1443 /* Remove all scroll bars because they have wrong colors. */
1444 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1445 (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1446 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1447 (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1449 update_face_from_frame_parameter (f, Qscroll_bar_foreground, value);
1450 redraw_frame (f);
1455 /* Set the background color for scroll bars on frame F to VALUE VALUE
1456 should be a string, a color name. If it isn't a string or isn't a
1457 valid color name, do nothing. OLDVAL is the old value of the frame
1458 parameter. */
1460 void
1461 x_set_scroll_bar_background (f, value, oldval)
1462 struct frame *f;
1463 Lisp_Object value, oldval;
1465 unsigned long pixel;
1467 if (STRINGP (value))
1468 pixel = x_decode_color (f, value, WHITE_PIX_DEFAULT (f));
1469 else
1470 pixel = -1;
1472 if (f->output_data.x->scroll_bar_background_pixel != -1)
1473 unload_color (f, f->output_data.x->scroll_bar_background_pixel);
1475 #ifdef USE_TOOLKIT_SCROLL_BARS
1476 /* Scrollbar shadow colors. */
1477 if (f->output_data.x->scroll_bar_top_shadow_pixel != -1)
1479 unload_color (f, f->output_data.x->scroll_bar_top_shadow_pixel);
1480 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
1482 if (f->output_data.x->scroll_bar_bottom_shadow_pixel != -1)
1484 unload_color (f, f->output_data.x->scroll_bar_bottom_shadow_pixel);
1485 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
1487 #endif /* USE_TOOLKIT_SCROLL_BARS */
1489 f->output_data.x->scroll_bar_background_pixel = pixel;
1490 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1492 /* Remove all scroll bars because they have wrong colors. */
1493 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1494 (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1495 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1496 (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1498 update_face_from_frame_parameter (f, Qscroll_bar_background, value);
1499 redraw_frame (f);
1504 /* Encode Lisp string STRING as a text in a format appropriate for
1505 XICCC (X Inter Client Communication Conventions).
1507 This can call Lisp code, so callers must GCPRO.
1509 If STRING contains only ASCII characters, do no conversion and
1510 return the string data of STRING. Otherwise, encode the text by
1511 CODING_SYSTEM, and return a newly allocated memory area which
1512 should be freed by `xfree' by a caller.
1514 SELECTIONP non-zero means the string is being encoded for an X
1515 selection, so it is safe to run pre-write conversions (which
1516 may run Lisp code).
1518 Store the byte length of resulting text in *TEXT_BYTES.
1520 If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
1521 which means that the `encoding' of the result can be `STRING'.
1522 Otherwise store 0 in *STRINGP, which means that the `encoding' of
1523 the result should be `COMPOUND_TEXT'. */
1525 static unsigned char *
1526 x_encode_text (string, coding_system, selectionp, text_bytes, stringp, freep)
1527 Lisp_Object string, coding_system;
1528 int *text_bytes, *stringp;
1529 int selectionp;
1530 int *freep;
1532 int result = string_xstring_p (string);
1533 struct coding_system coding;
1535 if (result == 0)
1537 /* No multibyte character in OBJ. We need not encode it. */
1538 *text_bytes = SBYTES (string);
1539 *stringp = 1;
1540 *freep = 0;
1541 return SDATA (string);
1544 setup_coding_system (coding_system, &coding);
1545 coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK);
1546 /* We suppress producing escape sequences for composition. */
1547 coding.common_flags &= ~CODING_ANNOTATION_MASK;
1548 coding.dst_bytes = SCHARS (string) * 2;
1549 coding.destination = (unsigned char *) xmalloc (coding.dst_bytes);
1550 encode_coding_object (&coding, string, 0, 0,
1551 SCHARS (string), SBYTES (string), Qnil);
1552 *text_bytes = coding.produced;
1553 *stringp = (result == 1 || !EQ (coding_system, Qcompound_text));
1554 *freep = 1;
1555 return coding.destination;
1559 /* Set the WM name to NAME for frame F. Also set the icon name.
1560 If the frame already has an icon name, use that, otherwise set the
1561 icon name to NAME. */
1563 static void
1564 x_set_name_internal (f, name)
1565 FRAME_PTR f;
1566 Lisp_Object name;
1568 if (FRAME_X_WINDOW (f))
1570 BLOCK_INPUT;
1572 XTextProperty text, icon;
1573 int bytes, stringp;
1574 int do_free_icon_value = 0, do_free_text_value = 0;
1575 Lisp_Object coding_system;
1576 #ifdef USE_GTK
1577 Lisp_Object encoded_name;
1578 struct gcpro gcpro1;
1580 /* As ENCODE_UTF_8 may cause GC and relocation of string data,
1581 we use it before x_encode_text that may return string data. */
1582 GCPRO1 (name);
1583 encoded_name = ENCODE_UTF_8 (name);
1584 UNGCPRO;
1585 #endif
1587 coding_system = Qcompound_text;
1588 /* Note: Encoding strategy
1590 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1591 text.encoding. But, there are non-internationalized window
1592 managers which don't support that encoding. So, if NAME
1593 contains only ASCII and 8859-1 characters, encode it by
1594 iso-latin-1, and use "STRING" in text.encoding hoping that
1595 such window managers at least analyze this format correctly,
1596 i.e. treat 8-bit bytes as 8859-1 characters.
1598 We may also be able to use "UTF8_STRING" in text.encoding
1599 in the future which can encode all Unicode characters.
1600 But, for the moment, there's no way to know that the
1601 current window manager supports it or not. */
1602 text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp,
1603 &do_free_text_value);
1604 text.encoding = (stringp ? XA_STRING
1605 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1606 text.format = 8;
1607 text.nitems = bytes;
1609 if (!STRINGP (f->icon_name))
1611 icon = text;
1613 else
1615 /* See the above comment "Note: Encoding strategy". */
1616 icon.value = x_encode_text (f->icon_name, coding_system, 0,
1617 &bytes, &stringp, &do_free_icon_value);
1618 icon.encoding = (stringp ? XA_STRING
1619 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1620 icon.format = 8;
1621 icon.nitems = bytes;
1624 #ifdef USE_GTK
1625 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
1626 (char *) SDATA (encoded_name));
1627 #else /* not USE_GTK */
1628 XSetWMName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &text);
1629 #endif /* not USE_GTK */
1631 XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &icon);
1633 if (do_free_icon_value)
1634 xfree (icon.value);
1635 if (do_free_text_value)
1636 xfree (text.value);
1638 UNBLOCK_INPUT;
1642 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1643 x_id_name.
1645 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1646 name; if NAME is a string, set F's name to NAME and set
1647 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1649 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1650 suggesting a new name, which lisp code should override; if
1651 F->explicit_name is set, ignore the new name; otherwise, set it. */
1653 void
1654 x_set_name (f, name, explicit)
1655 struct frame *f;
1656 Lisp_Object name;
1657 int explicit;
1659 /* Make sure that requests from lisp code override requests from
1660 Emacs redisplay code. */
1661 if (explicit)
1663 /* If we're switching from explicit to implicit, we had better
1664 update the mode lines and thereby update the title. */
1665 if (f->explicit_name && NILP (name))
1666 update_mode_lines = 1;
1668 f->explicit_name = ! NILP (name);
1670 else if (f->explicit_name)
1671 return;
1673 /* If NAME is nil, set the name to the x_id_name. */
1674 if (NILP (name))
1676 /* Check for no change needed in this very common case
1677 before we do any consing. */
1678 if (!strcmp (FRAME_X_DISPLAY_INFO (f)->x_id_name,
1679 SDATA (f->name)))
1680 return;
1681 name = build_string (FRAME_X_DISPLAY_INFO (f)->x_id_name);
1683 else
1684 CHECK_STRING (name);
1686 /* Don't change the name if it's already NAME. */
1687 if (! NILP (Fstring_equal (name, f->name)))
1688 return;
1690 f->name = name;
1692 /* For setting the frame title, the title parameter should override
1693 the name parameter. */
1694 if (! NILP (f->title))
1695 name = f->title;
1697 x_set_name_internal (f, name);
1700 /* This function should be called when the user's lisp code has
1701 specified a name for the frame; the name will override any set by the
1702 redisplay code. */
1703 void
1704 x_explicitly_set_name (f, arg, oldval)
1705 FRAME_PTR f;
1706 Lisp_Object arg, oldval;
1708 x_set_name (f, arg, 1);
1711 /* This function should be called by Emacs redisplay code to set the
1712 name; names set this way will never override names set by the user's
1713 lisp code. */
1714 void
1715 x_implicitly_set_name (f, arg, oldval)
1716 FRAME_PTR f;
1717 Lisp_Object arg, oldval;
1719 x_set_name (f, arg, 0);
1722 /* Change the title of frame F to NAME.
1723 If NAME is nil, use the frame name as the title. */
1725 void
1726 x_set_title (f, name, old_name)
1727 struct frame *f;
1728 Lisp_Object name, old_name;
1730 /* Don't change the title if it's already NAME. */
1731 if (EQ (name, f->title))
1732 return;
1734 update_mode_lines = 1;
1736 f->title = name;
1738 if (NILP (name))
1739 name = f->name;
1740 else
1741 CHECK_STRING (name);
1743 x_set_name_internal (f, name);
1746 void
1747 x_set_scroll_bar_default_width (f)
1748 struct frame *f;
1750 int wid = FRAME_COLUMN_WIDTH (f);
1752 #ifdef USE_TOOLKIT_SCROLL_BARS
1753 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
1754 int width = 16 + 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM;
1755 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (width + wid - 1) / wid;
1756 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = width;
1757 #else
1758 /* Make the actual width at least 14 pixels and a multiple of a
1759 character width. */
1760 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
1762 /* Use all of that space (aside from required margins) for the
1763 scroll bar. */
1764 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 0;
1765 #endif
1769 /* Record in frame F the specified or default value according to ALIST
1770 of the parameter named PROP (a Lisp symbol). If no value is
1771 specified for PROP, look for an X default for XPROP on the frame
1772 named NAME. If that is not found either, use the value DEFLT. */
1774 static Lisp_Object
1775 x_default_scroll_bar_color_parameter (f, alist, prop, xprop, xclass,
1776 foreground_p)
1777 struct frame *f;
1778 Lisp_Object alist;
1779 Lisp_Object prop;
1780 char *xprop;
1781 char *xclass;
1782 int foreground_p;
1784 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
1785 Lisp_Object tem;
1787 tem = x_get_arg (dpyinfo, alist, prop, xprop, xclass, RES_TYPE_STRING);
1788 if (EQ (tem, Qunbound))
1790 #ifdef USE_TOOLKIT_SCROLL_BARS
1792 /* See if an X resource for the scroll bar color has been
1793 specified. */
1794 tem = display_x_get_resource (dpyinfo,
1795 build_string (foreground_p
1796 ? "foreground"
1797 : "background"),
1798 empty_unibyte_string,
1799 build_string ("verticalScrollBar"),
1800 empty_unibyte_string);
1801 if (!STRINGP (tem))
1803 /* If nothing has been specified, scroll bars will use a
1804 toolkit-dependent default. Because these defaults are
1805 difficult to get at without actually creating a scroll
1806 bar, use nil to indicate that no color has been
1807 specified. */
1808 tem = Qnil;
1811 #else /* not USE_TOOLKIT_SCROLL_BARS */
1813 tem = Qnil;
1815 #endif /* not USE_TOOLKIT_SCROLL_BARS */
1818 x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));
1819 return tem;
1825 #ifdef USE_X_TOOLKIT
1827 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
1828 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
1829 already be present because of the toolkit (Motif adds some of them,
1830 for example, but Xt doesn't). */
1832 static void
1833 hack_wm_protocols (f, widget)
1834 FRAME_PTR f;
1835 Widget widget;
1837 Display *dpy = XtDisplay (widget);
1838 Window w = XtWindow (widget);
1839 int need_delete = 1;
1840 int need_focus = 1;
1841 int need_save = 1;
1843 BLOCK_INPUT;
1845 Atom type;
1846 unsigned char *catoms;
1847 int format = 0;
1848 unsigned long nitems = 0;
1849 unsigned long bytes_after;
1851 if ((XGetWindowProperty (dpy, w,
1852 FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
1853 (long)0, (long)100, False, XA_ATOM,
1854 &type, &format, &nitems, &bytes_after,
1855 &catoms)
1856 == Success)
1857 && format == 32 && type == XA_ATOM)
1859 Atom *atoms = (Atom *) catoms;
1860 while (nitems > 0)
1862 nitems--;
1863 if (atoms[nitems]
1864 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window)
1865 need_delete = 0;
1866 else if (atoms[nitems]
1867 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus)
1868 need_focus = 0;
1869 else if (atoms[nitems]
1870 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself)
1871 need_save = 0;
1874 if (catoms)
1875 XFree (catoms);
1878 Atom props [10];
1879 int count = 0;
1880 if (need_delete)
1881 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window;
1882 if (need_focus)
1883 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus;
1884 if (need_save)
1885 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
1886 if (count)
1887 XChangeProperty (dpy, w, FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
1888 XA_ATOM, 32, PropModeAppend,
1889 (unsigned char *) props, count);
1891 UNBLOCK_INPUT;
1893 #endif
1897 /* Support routines for XIC (X Input Context). */
1899 #ifdef HAVE_X_I18N
1901 static XFontSet xic_create_xfontset P_ ((struct frame *));
1902 static XIMStyle best_xim_style P_ ((XIMStyles *, XIMStyles *));
1905 /* Supported XIM styles, ordered by preference. */
1907 static XIMStyle supported_xim_styles[] =
1909 XIMPreeditPosition | XIMStatusArea,
1910 XIMPreeditPosition | XIMStatusNothing,
1911 XIMPreeditPosition | XIMStatusNone,
1912 XIMPreeditNothing | XIMStatusArea,
1913 XIMPreeditNothing | XIMStatusNothing,
1914 XIMPreeditNothing | XIMStatusNone,
1915 XIMPreeditNone | XIMStatusArea,
1916 XIMPreeditNone | XIMStatusNothing,
1917 XIMPreeditNone | XIMStatusNone,
1922 /* Create an X fontset on frame F with base font name BASE_FONTNAME. */
1924 char xic_defaut_fontset[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
1926 /* Create an Xt fontset spec from the name of a base font.
1927 If `motif' is True use the Motif syntax. */
1928 char *
1929 xic_create_fontsetname (base_fontname, motif)
1930 char *base_fontname;
1931 Bool motif;
1933 const char *sep = motif ? ";" : ",";
1934 char *fontsetname;
1936 /* Make a fontset name from the base font name. */
1937 if (xic_defaut_fontset == base_fontname)
1938 { /* There is no base font name, use the default. */
1939 int len = strlen (base_fontname) + 2;
1940 fontsetname = xmalloc (len);
1941 bzero (fontsetname, len);
1942 strcpy (fontsetname, base_fontname);
1944 else
1946 /* Make a fontset name from the base font name.
1947 The font set will be made of the following elements:
1948 - the base font.
1949 - the base font where the charset spec is replaced by -*-*.
1950 - the same but with the family also replaced with -*-*-. */
1951 char *p = base_fontname;
1952 int i;
1954 for (i = 0; *p; p++)
1955 if (*p == '-') i++;
1956 if (i != 14)
1957 { /* As the font name doesn't conform to XLFD, we can't
1958 modify it to generalize it to allcs and allfamilies.
1959 Use the specified font plus the default. */
1960 int len = strlen (base_fontname) + strlen (xic_defaut_fontset) + 3;
1961 fontsetname = xmalloc (len);
1962 bzero (fontsetname, len);
1963 strcpy (fontsetname, base_fontname);
1964 strcat (fontsetname, sep);
1965 strcat (fontsetname, xic_defaut_fontset);
1967 else
1969 int len;
1970 char *p1 = NULL, *p2 = NULL, *p3 = NULL;
1971 char *font_allcs = NULL;
1972 char *font_allfamilies = NULL;
1973 char *font_all = NULL;
1974 char *allcs = "*-*-*-*-*-*-*";
1975 char *allfamilies = "-*-*-";
1976 char *all = "*-*-*-*-";
1977 char *base;
1979 for (i = 0, p = base_fontname; i < 8; p++)
1981 if (*p == '-')
1983 i++;
1984 if (i == 3)
1985 p1 = p + 1;
1986 else if (i == 7)
1987 p2 = p + 1;
1988 else if (i == 6)
1989 p3 = p + 1;
1992 /* If base_fontname specifies ADSTYLE, make it a
1993 wildcard. */
1994 if (*p3 != '*')
1996 int diff = (p2 - p3) - 2;
1998 base = alloca (strlen (base_fontname) + 1);
1999 bcopy (base_fontname, base, p3 - base_fontname);
2000 base[p3 - base_fontname] = '*';
2001 base[(p3 - base_fontname) + 1] = '-';
2002 strcpy (base + (p3 - base_fontname) + 2, p2);
2003 p = base + (p - base_fontname) - diff;
2004 p1 = base + (p1 - base_fontname);
2005 p2 = base + (p2 - base_fontname) - diff;
2006 base_fontname = base;
2009 /* Build the font spec that matches all charsets. */
2010 len = p - base_fontname + strlen (allcs) + 1;
2011 font_allcs = (char *) alloca (len);
2012 bzero (font_allcs, len);
2013 bcopy (base_fontname, font_allcs, p - base_fontname);
2014 strcat (font_allcs, allcs);
2016 /* Build the font spec that matches all families and
2017 add-styles. */
2018 len = p - p1 + strlen (allcs) + strlen (allfamilies) + 1;
2019 font_allfamilies = (char *) alloca (len);
2020 bzero (font_allfamilies, len);
2021 strcpy (font_allfamilies, allfamilies);
2022 bcopy (p1, font_allfamilies + strlen (allfamilies), p - p1);
2023 strcat (font_allfamilies, allcs);
2025 /* Build the font spec that matches all. */
2026 len = p - p2 + strlen (allcs) + strlen (all) + strlen (allfamilies) + 1;
2027 font_all = (char *) alloca (len);
2028 bzero (font_all, len);
2029 strcpy (font_all, allfamilies);
2030 strcat (font_all, all);
2031 bcopy (p2, font_all + strlen (all) + strlen (allfamilies), p - p2);
2032 strcat (font_all, allcs);
2034 /* Build the actual font set name. */
2035 len = strlen (base_fontname) + strlen (font_allcs)
2036 + strlen (font_allfamilies) + strlen (font_all) + 5;
2037 fontsetname = xmalloc (len);
2038 bzero (fontsetname, len);
2039 strcpy (fontsetname, base_fontname);
2040 strcat (fontsetname, sep);
2041 strcat (fontsetname, font_allcs);
2042 strcat (fontsetname, sep);
2043 strcat (fontsetname, font_allfamilies);
2044 strcat (fontsetname, sep);
2045 strcat (fontsetname, font_all);
2048 if (motif)
2049 strcat (fontsetname, ":");
2050 return fontsetname;
2053 #ifdef DEBUG_XIC_FONTSET
2054 static void
2055 print_fontset_result (xfs, name, missing_list, missing_count)
2056 XFontSet xfs;
2057 char *name;
2058 char **missing_list;
2059 int missing_count;
2061 if (xfs)
2062 fprintf (stderr, "XIC Fontset created: %s\n", name);
2063 else
2065 fprintf (stderr, "XIC Fontset failed: %s\n", name);
2066 while (missing_count-- > 0)
2068 fprintf (stderr, " missing: %s\n", *missing_list);
2069 missing_list++;
2074 #endif
2076 static XFontSet
2077 xic_create_xfontset (f)
2078 struct frame *f;
2080 XFontSet xfs = NULL;
2081 struct font *font = FRAME_FONT (f);
2082 int pixel_size = font->pixel_size;
2083 Lisp_Object rest, frame;
2085 /* See if there is another frame already using same fontset. */
2086 FOR_EACH_FRAME (rest, frame)
2088 struct frame *cf = XFRAME (frame);
2090 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
2091 && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f)
2092 && FRAME_FONT (f)
2093 && FRAME_FONT (f)->pixel_size == pixel_size)
2095 xfs = FRAME_XIC_FONTSET (cf);
2096 break;
2100 if (! xfs)
2102 char buf[256];
2103 char **missing_list;
2104 int missing_count;
2105 char *def_string;
2106 char *xlfd_format = "-*-*-medium-r-normal--%d-*-*-*-*-*";
2108 sprintf (buf, xlfd_format, pixel_size);
2109 missing_list = NULL;
2110 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
2111 &missing_list, &missing_count, &def_string);
2112 #ifdef DEBUG_XIC_FONTSET
2113 print_fontset_result (xfs, buf, missing_list, missing_count);
2114 #endif
2115 if (missing_list)
2116 XFreeStringList (missing_list);
2117 if (! xfs)
2119 /* List of pixel sizes most likely available. Find one that
2120 is closest to pixel_size. */
2121 int sizes[] = {0, 8, 10, 11, 12, 14, 17, 18, 20, 24, 26, 34, 0};
2122 int *smaller, *larger;
2124 for (smaller = sizes; smaller[1]; smaller++)
2125 if (smaller[1] >= pixel_size)
2126 break;
2127 larger = smaller + 1;
2128 if (*larger == pixel_size)
2129 larger++;
2130 while (*smaller || *larger)
2132 int this_size;
2134 if (! *larger)
2135 this_size = *smaller--;
2136 else if (! *smaller)
2137 this_size = *larger++;
2138 else if (pixel_size - *smaller < *larger - pixel_size)
2139 this_size = *smaller--;
2140 else
2141 this_size = *larger++;
2142 sprintf (buf, xlfd_format, this_size);
2143 missing_list = NULL;
2144 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
2145 &missing_list, &missing_count, &def_string);
2146 #ifdef DEBUG_XIC_FONTSET
2147 print_fontset_result (xfs, buf, missing_list, missing_count);
2148 #endif
2149 if (missing_list)
2150 XFreeStringList (missing_list);
2151 if (xfs)
2152 break;
2155 if (! xfs)
2157 char *last_resort = "-*-*-*-r-normal--*-*-*-*-*-*";
2159 missing_list = NULL;
2160 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), last_resort,
2161 &missing_list, &missing_count, &def_string);
2162 #ifdef DEBUG_XIC_FONTSET
2163 print_fontset_result (xfs, last_resort, missing_list, missing_count);
2164 #endif
2165 if (missing_list)
2166 XFreeStringList (missing_list);
2171 return xfs;
2174 /* Free the X fontset of frame F if it is the last frame using it. */
2176 void
2177 xic_free_xfontset (f)
2178 struct frame *f;
2180 Lisp_Object rest, frame;
2181 int shared_p = 0;
2183 if (!FRAME_XIC_FONTSET (f))
2184 return;
2186 /* See if there is another frame sharing the same fontset. */
2187 FOR_EACH_FRAME (rest, frame)
2189 struct frame *cf = XFRAME (frame);
2190 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
2191 && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f)
2192 && FRAME_XIC_FONTSET (cf) == FRAME_XIC_FONTSET (f))
2194 shared_p = 1;
2195 break;
2199 if (!shared_p)
2200 /* The fontset is not used anymore. It is safe to free it. */
2201 XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f));
2203 if (FRAME_XIC_BASE_FONTNAME (f))
2204 xfree (FRAME_XIC_BASE_FONTNAME (f));
2205 FRAME_XIC_BASE_FONTNAME (f) = NULL;
2206 FRAME_XIC_FONTSET (f) = NULL;
2210 /* Value is the best input style, given user preferences USER (already
2211 checked to be supported by Emacs), and styles supported by the
2212 input method XIM. */
2214 static XIMStyle
2215 best_xim_style (user, xim)
2216 XIMStyles *user;
2217 XIMStyles *xim;
2219 int i, j;
2221 for (i = 0; i < user->count_styles; ++i)
2222 for (j = 0; j < xim->count_styles; ++j)
2223 if (user->supported_styles[i] == xim->supported_styles[j])
2224 return user->supported_styles[i];
2226 /* Return the default style. */
2227 return XIMPreeditNothing | XIMStatusNothing;
2230 /* Create XIC for frame F. */
2232 static XIMStyle xic_style;
2234 void
2235 create_frame_xic (f)
2236 struct frame *f;
2238 XIM xim;
2239 XIC xic = NULL;
2240 XFontSet xfs = NULL;
2242 if (FRAME_XIC (f))
2243 return;
2245 /* Create X fontset. */
2246 xfs = xic_create_xfontset (f);
2247 xim = FRAME_X_XIM (f);
2248 if (xim)
2250 XRectangle s_area;
2251 XPoint spot;
2252 XVaNestedList preedit_attr;
2253 XVaNestedList status_attr;
2255 s_area.x = 0; s_area.y = 0; s_area.width = 1; s_area.height = 1;
2256 spot.x = 0; spot.y = 1;
2258 /* Determine XIC style. */
2259 if (xic_style == 0)
2261 XIMStyles supported_list;
2262 supported_list.count_styles = (sizeof supported_xim_styles
2263 / sizeof supported_xim_styles[0]);
2264 supported_list.supported_styles = supported_xim_styles;
2265 xic_style = best_xim_style (&supported_list,
2266 FRAME_X_XIM_STYLES (f));
2269 preedit_attr = XVaCreateNestedList (0,
2270 XNFontSet, xfs,
2271 XNForeground,
2272 FRAME_FOREGROUND_PIXEL (f),
2273 XNBackground,
2274 FRAME_BACKGROUND_PIXEL (f),
2275 (xic_style & XIMPreeditPosition
2276 ? XNSpotLocation
2277 : NULL),
2278 &spot,
2279 NULL);
2280 status_attr = XVaCreateNestedList (0,
2281 XNArea,
2282 &s_area,
2283 XNFontSet,
2284 xfs,
2285 XNForeground,
2286 FRAME_FOREGROUND_PIXEL (f),
2287 XNBackground,
2288 FRAME_BACKGROUND_PIXEL (f),
2289 NULL);
2291 xic = XCreateIC (xim,
2292 XNInputStyle, xic_style,
2293 XNClientWindow, FRAME_X_WINDOW (f),
2294 XNFocusWindow, FRAME_X_WINDOW (f),
2295 XNStatusAttributes, status_attr,
2296 XNPreeditAttributes, preedit_attr,
2297 NULL);
2298 XFree (preedit_attr);
2299 XFree (status_attr);
2302 FRAME_XIC (f) = xic;
2303 FRAME_XIC_STYLE (f) = xic_style;
2304 FRAME_XIC_FONTSET (f) = xfs;
2308 /* Destroy XIC and free XIC fontset of frame F, if any. */
2310 void
2311 free_frame_xic (f)
2312 struct frame *f;
2314 if (FRAME_XIC (f) == NULL)
2315 return;
2317 XDestroyIC (FRAME_XIC (f));
2318 xic_free_xfontset (f);
2320 FRAME_XIC (f) = NULL;
2324 /* Place preedit area for XIC of window W's frame to specified
2325 pixel position X/Y. X and Y are relative to window W. */
2327 void
2328 xic_set_preeditarea (w, x, y)
2329 struct window *w;
2330 int x, y;
2332 struct frame *f = XFRAME (w->frame);
2333 XVaNestedList attr;
2334 XPoint spot;
2336 spot.x = WINDOW_TO_FRAME_PIXEL_X (w, x) + WINDOW_LEFT_FRINGE_WIDTH (w);
2337 spot.y = WINDOW_TO_FRAME_PIXEL_Y (w, y) + FONT_BASE (FRAME_FONT (f));
2338 attr = XVaCreateNestedList (0, XNSpotLocation, &spot, NULL);
2339 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2340 XFree (attr);
2344 /* Place status area for XIC in bottom right corner of frame F.. */
2346 void
2347 xic_set_statusarea (f)
2348 struct frame *f;
2350 XIC xic = FRAME_XIC (f);
2351 XVaNestedList attr;
2352 XRectangle area;
2353 XRectangle *needed;
2355 /* Negotiate geometry of status area. If input method has existing
2356 status area, use its current size. */
2357 area.x = area.y = area.width = area.height = 0;
2358 attr = XVaCreateNestedList (0, XNAreaNeeded, &area, NULL);
2359 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2360 XFree (attr);
2362 attr = XVaCreateNestedList (0, XNAreaNeeded, &needed, NULL);
2363 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2364 XFree (attr);
2366 if (needed->width == 0) /* Use XNArea instead of XNAreaNeeded */
2368 attr = XVaCreateNestedList (0, XNArea, &needed, NULL);
2369 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2370 XFree (attr);
2373 area.width = needed->width;
2374 area.height = needed->height;
2375 area.x = FRAME_PIXEL_WIDTH (f) - area.width - FRAME_INTERNAL_BORDER_WIDTH (f);
2376 area.y = (FRAME_PIXEL_HEIGHT (f) - area.height
2377 - FRAME_MENUBAR_HEIGHT (f)
2378 - FRAME_TOOLBAR_HEIGHT (f)
2379 - FRAME_INTERNAL_BORDER_WIDTH (f));
2380 XFree (needed);
2382 attr = XVaCreateNestedList (0, XNArea, &area, NULL);
2383 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2384 XFree (attr);
2388 /* Set X fontset for XIC of frame F, using base font name
2389 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2391 void
2392 xic_set_xfontset (f, base_fontname)
2393 struct frame *f;
2394 char *base_fontname;
2396 XVaNestedList attr;
2397 XFontSet xfs;
2399 xic_free_xfontset (f);
2401 xfs = xic_create_xfontset (f);
2403 attr = XVaCreateNestedList (0, XNFontSet, xfs, NULL);
2404 if (FRAME_XIC_STYLE (f) & XIMPreeditPosition)
2405 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2406 if (FRAME_XIC_STYLE (f) & XIMStatusArea)
2407 XSetICValues (FRAME_XIC (f), XNStatusAttributes, attr, NULL);
2408 XFree (attr);
2410 FRAME_XIC_FONTSET (f) = xfs;
2413 #endif /* HAVE_X_I18N */
2417 #ifdef USE_X_TOOLKIT
2419 /* Create and set up the X widget for frame F. */
2421 static void
2422 x_window (f, window_prompting, minibuffer_only)
2423 struct frame *f;
2424 long window_prompting;
2425 int minibuffer_only;
2427 XClassHint class_hints;
2428 XSetWindowAttributes attributes;
2429 unsigned long attribute_mask;
2430 Widget shell_widget;
2431 Widget pane_widget;
2432 Widget frame_widget;
2433 Arg al [25];
2434 int ac;
2436 BLOCK_INPUT;
2438 /* Use the resource name as the top-level widget name
2439 for looking up resources. Make a non-Lisp copy
2440 for the window manager, so GC relocation won't bother it.
2442 Elsewhere we specify the window name for the window manager. */
2445 char *str = (char *) SDATA (Vx_resource_name);
2446 f->namebuf = (char *) xmalloc (strlen (str) + 1);
2447 strcpy (f->namebuf, str);
2450 ac = 0;
2451 XtSetArg (al[ac], XtNallowShellResize, 1); ac++;
2452 XtSetArg (al[ac], XtNinput, 1); ac++;
2453 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2454 XtSetArg (al[ac], XtNborderWidth, f->border_width); ac++;
2455 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2456 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2457 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2458 shell_widget = XtAppCreateShell (f->namebuf, EMACS_CLASS,
2459 applicationShellWidgetClass,
2460 FRAME_X_DISPLAY (f), al, ac);
2462 f->output_data.x->widget = shell_widget;
2463 /* maybe_set_screen_title_format (shell_widget); */
2465 pane_widget = lw_create_widget ("main", "pane", widget_id_tick++,
2466 (widget_value *) NULL,
2467 shell_widget, False,
2468 (lw_callback) NULL,
2469 (lw_callback) NULL,
2470 (lw_callback) NULL,
2471 (lw_callback) NULL);
2473 ac = 0;
2474 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2475 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2476 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2477 XtSetValues (pane_widget, al, ac);
2478 f->output_data.x->column_widget = pane_widget;
2480 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2481 the emacs screen when changing menubar. This reduces flickering. */
2483 ac = 0;
2484 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2485 XtSetArg (al[ac], XtNshowGrip, 0); ac++;
2486 XtSetArg (al[ac], XtNallowResize, 1); ac++;
2487 XtSetArg (al[ac], XtNresizeToPreferred, 1); ac++;
2488 XtSetArg (al[ac], XtNemacsFrame, f); ac++;
2489 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2490 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2491 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2492 frame_widget = XtCreateWidget (f->namebuf, emacsFrameClass, pane_widget,
2493 al, ac);
2495 f->output_data.x->edit_widget = frame_widget;
2497 XtManageChild (frame_widget);
2499 /* Do some needed geometry management. */
2501 int len;
2502 char *tem, shell_position[32];
2503 Arg al[10];
2504 int ac = 0;
2505 int extra_borders = 0;
2506 int menubar_size
2507 = (f->output_data.x->menubar_widget
2508 ? (f->output_data.x->menubar_widget->core.height
2509 + f->output_data.x->menubar_widget->core.border_width)
2510 : 0);
2512 #if 0 /* Experimentally, we now get the right results
2513 for -geometry -0-0 without this. 24 Aug 96, rms. */
2514 if (FRAME_EXTERNAL_MENU_BAR (f))
2516 Dimension ibw = 0;
2517 XtVaGetValues (pane_widget, XtNinternalBorderWidth, &ibw, NULL);
2518 menubar_size += ibw;
2520 #endif
2522 f->output_data.x->menubar_height = menubar_size;
2524 #ifndef USE_LUCID
2525 /* Motif seems to need this amount added to the sizes
2526 specified for the shell widget. The Athena/Lucid widgets don't.
2527 Both conclusions reached experimentally. -- rms. */
2528 XtVaGetValues (f->output_data.x->edit_widget, XtNinternalBorderWidth,
2529 &extra_borders, NULL);
2530 extra_borders *= 2;
2531 #endif
2533 /* Convert our geometry parameters into a geometry string
2534 and specify it.
2535 Note that we do not specify here whether the position
2536 is a user-specified or program-specified one.
2537 We pass that information later, in x_wm_set_size_hints. */
2539 int left = f->left_pos;
2540 int xneg = window_prompting & XNegative;
2541 int top = f->top_pos;
2542 int yneg = window_prompting & YNegative;
2543 if (xneg)
2544 left = -left;
2545 if (yneg)
2546 top = -top;
2548 if (window_prompting & USPosition)
2549 sprintf (shell_position, "=%dx%d%c%d%c%d",
2550 FRAME_PIXEL_WIDTH (f) + extra_borders,
2551 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders,
2552 (xneg ? '-' : '+'), left,
2553 (yneg ? '-' : '+'), top);
2554 else
2556 sprintf (shell_position, "=%dx%d",
2557 FRAME_PIXEL_WIDTH (f) + extra_borders,
2558 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders);
2560 /* Setting x and y when the position is not specified in
2561 the geometry string will set program position in the WM hints.
2562 If Emacs had just one program position, we could set it in
2563 fallback resources, but since each make-frame call can specify
2564 different program positions, this is easier. */
2565 XtSetArg (al[ac], XtNx, left); ac++;
2566 XtSetArg (al[ac], XtNy, top); ac++;
2570 len = strlen (shell_position) + 1;
2571 /* We don't free this because we don't know whether
2572 it is safe to free it while the frame exists.
2573 It isn't worth the trouble of arranging to free it
2574 when the frame is deleted. */
2575 tem = (char *) xmalloc (len);
2576 strncpy (tem, shell_position, len);
2577 XtSetArg (al[ac], XtNgeometry, tem); ac++;
2578 XtSetValues (shell_widget, al, ac);
2581 XtManageChild (pane_widget);
2582 XtRealizeWidget (shell_widget);
2584 if (FRAME_X_EMBEDDED_P (f))
2585 XReparentWindow (FRAME_X_DISPLAY (f), XtWindow (shell_widget),
2586 f->output_data.x->parent_desc, 0, 0);
2588 FRAME_X_WINDOW (f) = XtWindow (frame_widget);
2590 validate_x_resource_name ();
2592 class_hints.res_name = (char *) SDATA (Vx_resource_name);
2593 class_hints.res_class = (char *) SDATA (Vx_resource_class);
2594 XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints);
2596 #ifdef HAVE_X_I18N
2597 FRAME_XIC (f) = NULL;
2598 if (use_xim)
2599 create_frame_xic (f);
2600 #endif
2602 f->output_data.x->wm_hints.input = True;
2603 f->output_data.x->wm_hints.flags |= InputHint;
2604 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2605 &f->output_data.x->wm_hints);
2607 hack_wm_protocols (f, shell_widget);
2609 #ifdef HACK_EDITRES
2610 XtAddEventHandler (shell_widget, 0, True, _XEditResCheckMessages, 0);
2611 #endif
2613 /* Do a stupid property change to force the server to generate a
2614 PropertyNotify event so that the event_stream server timestamp will
2615 be initialized to something relevant to the time we created the window.
2617 XChangeProperty (XtDisplay (frame_widget), XtWindow (frame_widget),
2618 FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
2619 XA_ATOM, 32, PropModeAppend,
2620 (unsigned char*) NULL, 0);
2622 /* Make all the standard events reach the Emacs frame. */
2623 attributes.event_mask = STANDARD_EVENT_SET;
2625 #ifdef HAVE_X_I18N
2626 if (FRAME_XIC (f))
2628 /* XIM server might require some X events. */
2629 unsigned long fevent = NoEventMask;
2630 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2631 attributes.event_mask |= fevent;
2633 #endif /* HAVE_X_I18N */
2635 attribute_mask = CWEventMask;
2636 XChangeWindowAttributes (XtDisplay (shell_widget), XtWindow (shell_widget),
2637 attribute_mask, &attributes);
2639 XtMapWidget (frame_widget);
2641 /* x_set_name normally ignores requests to set the name if the
2642 requested name is the same as the current name. This is the one
2643 place where that assumption isn't correct; f->name is set, but
2644 the X server hasn't been told. */
2646 Lisp_Object name;
2647 int explicit = f->explicit_name;
2649 f->explicit_name = 0;
2650 name = f->name;
2651 f->name = Qnil;
2652 x_set_name (f, name, explicit);
2655 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2656 f->output_data.x->current_cursor
2657 = f->output_data.x->text_cursor);
2659 UNBLOCK_INPUT;
2661 /* This is a no-op, except under Motif. Make sure main areas are
2662 set to something reasonable, in case we get an error later. */
2663 lw_set_main_areas (pane_widget, 0, frame_widget);
2666 #else /* not USE_X_TOOLKIT */
2667 #ifdef USE_GTK
2668 void
2669 x_window (f)
2670 FRAME_PTR f;
2672 if (! xg_create_frame_widgets (f))
2673 error ("Unable to create window");
2675 #ifdef HAVE_X_I18N
2676 FRAME_XIC (f) = NULL;
2677 if (use_xim)
2679 BLOCK_INPUT;
2680 create_frame_xic (f);
2681 if (FRAME_XIC (f))
2683 /* XIM server might require some X events. */
2684 unsigned long fevent = NoEventMask;
2685 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2687 if (fevent != NoEventMask)
2689 XSetWindowAttributes attributes;
2690 XWindowAttributes wattr;
2691 unsigned long attribute_mask;
2693 XGetWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2694 &wattr);
2695 attributes.event_mask = wattr.your_event_mask | fevent;
2696 attribute_mask = CWEventMask;
2697 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2698 attribute_mask, &attributes);
2701 UNBLOCK_INPUT;
2703 #endif
2706 #else /*! USE_GTK */
2707 /* Create and set up the X window for frame F. */
2709 void
2710 x_window (f)
2711 struct frame *f;
2714 XClassHint class_hints;
2715 XSetWindowAttributes attributes;
2716 unsigned long attribute_mask;
2718 attributes.background_pixel = FRAME_BACKGROUND_PIXEL (f);
2719 attributes.border_pixel = f->output_data.x->border_pixel;
2720 attributes.bit_gravity = StaticGravity;
2721 attributes.backing_store = NotUseful;
2722 attributes.save_under = True;
2723 attributes.event_mask = STANDARD_EVENT_SET;
2724 attributes.colormap = FRAME_X_COLORMAP (f);
2725 attribute_mask = (CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask
2726 | CWColormap);
2728 BLOCK_INPUT;
2729 FRAME_X_WINDOW (f)
2730 = XCreateWindow (FRAME_X_DISPLAY (f),
2731 f->output_data.x->parent_desc,
2732 f->left_pos,
2733 f->top_pos,
2734 FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
2735 f->border_width,
2736 CopyFromParent, /* depth */
2737 InputOutput, /* class */
2738 FRAME_X_VISUAL (f),
2739 attribute_mask, &attributes);
2741 #ifdef HAVE_X_I18N
2742 if (use_xim)
2744 create_frame_xic (f);
2745 if (FRAME_XIC (f))
2747 /* XIM server might require some X events. */
2748 unsigned long fevent = NoEventMask;
2749 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2750 attributes.event_mask |= fevent;
2751 attribute_mask = CWEventMask;
2752 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2753 attribute_mask, &attributes);
2756 #endif /* HAVE_X_I18N */
2758 validate_x_resource_name ();
2760 class_hints.res_name = (char *) SDATA (Vx_resource_name);
2761 class_hints.res_class = (char *) SDATA (Vx_resource_class);
2762 XSetClassHint (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &class_hints);
2764 /* The menubar is part of the ordinary display;
2765 it does not count in addition to the height of the window. */
2766 f->output_data.x->menubar_height = 0;
2768 /* This indicates that we use the "Passive Input" input model.
2769 Unless we do this, we don't get the Focus{In,Out} events that we
2770 need to draw the cursor correctly. Accursed bureaucrats.
2771 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2773 f->output_data.x->wm_hints.input = True;
2774 f->output_data.x->wm_hints.flags |= InputHint;
2775 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2776 &f->output_data.x->wm_hints);
2777 f->output_data.x->wm_hints.icon_pixmap = None;
2779 /* Request "save yourself" and "delete window" commands from wm. */
2781 Atom protocols[2];
2782 protocols[0] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window;
2783 protocols[1] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
2784 XSetWMProtocols (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), protocols, 2);
2787 /* x_set_name normally ignores requests to set the name if the
2788 requested name is the same as the current name. This is the one
2789 place where that assumption isn't correct; f->name is set, but
2790 the X server hasn't been told. */
2792 Lisp_Object name;
2793 int explicit = f->explicit_name;
2795 f->explicit_name = 0;
2796 name = f->name;
2797 f->name = Qnil;
2798 x_set_name (f, name, explicit);
2801 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2802 f->output_data.x->current_cursor
2803 = f->output_data.x->text_cursor);
2805 UNBLOCK_INPUT;
2807 if (FRAME_X_WINDOW (f) == 0)
2808 error ("Unable to create window");
2811 #endif /* not USE_GTK */
2812 #endif /* not USE_X_TOOLKIT */
2814 /* Verify that the icon position args for this window are valid. */
2816 static void
2817 x_icon_verify (f, parms)
2818 struct frame *f;
2819 Lisp_Object parms;
2821 Lisp_Object icon_x, icon_y;
2823 /* Set the position of the icon. Note that twm groups all
2824 icons in an icon window. */
2825 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2826 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2827 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2829 CHECK_NUMBER (icon_x);
2830 CHECK_NUMBER (icon_y);
2832 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2833 error ("Both left and top icon corners of icon must be specified");
2836 /* Handle the icon stuff for this window. Perhaps later we might
2837 want an x_set_icon_position which can be called interactively as
2838 well. */
2840 static void
2841 x_icon (f, parms)
2842 struct frame *f;
2843 Lisp_Object parms;
2845 Lisp_Object icon_x, icon_y;
2846 #if 0
2847 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2848 #endif
2850 /* Set the position of the icon. Note that twm groups all
2851 icons in an icon window. */
2852 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2853 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2854 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2856 CHECK_NUMBER (icon_x);
2857 CHECK_NUMBER (icon_y);
2859 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2860 error ("Both left and top icon corners of icon must be specified");
2862 BLOCK_INPUT;
2864 if (! EQ (icon_x, Qunbound))
2865 x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
2867 #if 0 /* x_get_arg removes the visibility parameter as a side effect,
2868 but x_create_frame still needs it. */
2869 /* Start up iconic or window? */
2870 x_wm_set_window_state
2871 (f, (EQ (x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL),
2872 Qicon)
2873 ? IconicState
2874 : NormalState));
2875 #endif
2877 x_text_icon (f, (char *) SDATA ((!NILP (f->icon_name)
2878 ? f->icon_name
2879 : f->name)));
2881 UNBLOCK_INPUT;
2884 /* Make the GCs needed for this window, setting the
2885 background, border and mouse colors; also create the
2886 mouse cursor and the gray border tile. */
2888 static void
2889 x_make_gc (f)
2890 struct frame *f;
2892 XGCValues gc_values;
2894 BLOCK_INPUT;
2896 /* Create the GCs of this frame.
2897 Note that many default values are used. */
2899 gc_values.foreground = FRAME_FOREGROUND_PIXEL (f);
2900 gc_values.background = FRAME_BACKGROUND_PIXEL (f);
2901 gc_values.line_width = 0; /* Means 1 using fast algorithm. */
2902 f->output_data.x->normal_gc
2903 = XCreateGC (FRAME_X_DISPLAY (f),
2904 FRAME_X_WINDOW (f),
2905 GCLineWidth | GCForeground | GCBackground,
2906 &gc_values);
2908 /* Reverse video style. */
2909 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2910 gc_values.background = FRAME_FOREGROUND_PIXEL (f);
2911 f->output_data.x->reverse_gc
2912 = XCreateGC (FRAME_X_DISPLAY (f),
2913 FRAME_X_WINDOW (f),
2914 GCForeground | GCBackground | GCLineWidth,
2915 &gc_values);
2917 /* Cursor has cursor-color background, background-color foreground. */
2918 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2919 gc_values.background = f->output_data.x->cursor_pixel;
2920 gc_values.fill_style = FillOpaqueStippled;
2921 f->output_data.x->cursor_gc
2922 = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2923 (GCForeground | GCBackground
2924 | GCFillStyle | GCLineWidth),
2925 &gc_values);
2927 /* Reliefs. */
2928 f->output_data.x->white_relief.gc = 0;
2929 f->output_data.x->black_relief.gc = 0;
2931 /* Create the gray border tile used when the pointer is not in
2932 the frame. Since this depends on the frame's pixel values,
2933 this must be done on a per-frame basis. */
2934 f->output_data.x->border_tile
2935 = (XCreatePixmapFromBitmapData
2936 (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
2937 gray_bits, gray_width, gray_height,
2938 FRAME_FOREGROUND_PIXEL (f),
2939 FRAME_BACKGROUND_PIXEL (f),
2940 DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
2942 UNBLOCK_INPUT;
2946 /* Free what was allocated in x_make_gc. */
2948 void
2949 x_free_gcs (f)
2950 struct frame *f;
2952 Display *dpy = FRAME_X_DISPLAY (f);
2954 BLOCK_INPUT;
2956 if (f->output_data.x->normal_gc)
2958 XFreeGC (dpy, f->output_data.x->normal_gc);
2959 f->output_data.x->normal_gc = 0;
2962 if (f->output_data.x->reverse_gc)
2964 XFreeGC (dpy, f->output_data.x->reverse_gc);
2965 f->output_data.x->reverse_gc = 0;
2968 if (f->output_data.x->cursor_gc)
2970 XFreeGC (dpy, f->output_data.x->cursor_gc);
2971 f->output_data.x->cursor_gc = 0;
2974 if (f->output_data.x->border_tile)
2976 XFreePixmap (dpy, f->output_data.x->border_tile);
2977 f->output_data.x->border_tile = 0;
2980 UNBLOCK_INPUT;
2984 /* Handler for signals raised during x_create_frame and
2985 x_create_top_frame. FRAME is the frame which is partially
2986 constructed. */
2988 static Lisp_Object
2989 unwind_create_frame (frame)
2990 Lisp_Object frame;
2992 struct frame *f = XFRAME (frame);
2994 /* If frame is already dead, nothing to do. This can happen if the
2995 display is disconnected after the frame has become official, but
2996 before x_create_frame removes the unwind protect. */
2997 if (!FRAME_LIVE_P (f))
2998 return Qnil;
3000 /* If frame is ``official'', nothing to do. */
3001 if (!CONSP (Vframe_list) || !EQ (XCAR (Vframe_list), frame))
3003 #if GLYPH_DEBUG
3004 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3005 #endif
3007 x_free_frame_resources (f);
3009 #if GLYPH_DEBUG
3010 /* Check that reference counts are indeed correct. */
3011 xassert (dpyinfo->reference_count == dpyinfo_refcount);
3012 xassert (dpyinfo->image_cache->refcount == image_cache_refcount);
3013 #endif
3014 return Qt;
3017 return Qnil;
3021 static void
3022 x_default_font_parameter (f, parms)
3023 struct frame *f;
3024 Lisp_Object parms;
3026 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3027 Lisp_Object font_param = x_get_arg (dpyinfo, parms, Qfont, NULL, NULL,
3028 RES_TYPE_STRING);
3029 Lisp_Object font;
3030 if (EQ (font_param, Qunbound))
3031 font_param = Qnil;
3032 font = !NILP (font_param) ? font_param
3033 : x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
3035 if (! STRINGP (font))
3037 char *names[]
3039 #ifdef HAVE_XFT
3040 /* This will find the normal Xft font. */
3041 "monospace-12",
3042 #endif
3043 "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
3044 "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3045 "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3046 /* This was formerly the first thing tried, but it finds
3047 too many fonts and takes too long. */
3048 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
3049 /* If those didn't work, look for something which will
3050 at least work. */
3051 "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
3052 "fixed",
3053 NULL };
3054 int i;
3056 for (i = 0; names[i]; i++)
3058 font = font_open_by_name (f, names[i]);
3059 if (! NILP (font))
3060 break;
3062 if (NILP (font))
3063 error ("No suitable font was found");
3065 else if (!NILP (font_param))
3067 /* Remember the explicit font parameter, so we can re-apply it after
3068 we've applied the `default' face settings. */
3069 x_set_frame_parameters (f, Fcons (Fcons (Qfont_param, font_param), Qnil));
3071 x_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING);
3075 DEFUN ("x-wm-set-size-hint", Fx_wm_set_size_hint, Sx_wm_set_size_hint,
3076 0, 1, 0,
3077 doc: /* Send the size hints for frame FRAME to the window manager.
3078 If FRAME is nil, use the selected frame. */)
3079 (frame)
3080 Lisp_Object frame;
3082 struct frame *f;
3083 if (NILP (frame))
3084 frame = selected_frame;
3085 f = XFRAME (frame);
3086 BLOCK_INPUT;
3087 if (FRAME_X_P (f))
3088 x_wm_set_size_hint (f, 0, 0);
3089 UNBLOCK_INPUT;
3090 return Qnil;
3093 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
3094 1, 1, 0,
3095 doc: /* Make a new X window, which is called a "frame" in Emacs terms.
3096 Return an Emacs frame object.
3097 PARMS is an alist of frame parameters.
3098 If the parameters specify that the frame should not have a minibuffer,
3099 and do not specify a specific minibuffer window to use,
3100 then `default-minibuffer-frame' must be a frame whose minibuffer can
3101 be shared by the new frame.
3103 This function is an internal primitive--use `make-frame' instead. */)
3104 (parms)
3105 Lisp_Object parms;
3107 struct frame *f;
3108 Lisp_Object frame, tem;
3109 Lisp_Object name;
3110 int minibuffer_only = 0;
3111 long window_prompting = 0;
3112 int width, height;
3113 int count = SPECPDL_INDEX ();
3114 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
3115 Lisp_Object display;
3116 struct x_display_info *dpyinfo = NULL;
3117 Lisp_Object parent;
3118 struct kboard *kb;
3120 parms = Fcopy_alist (parms);
3122 /* Use this general default value to start with
3123 until we know if this frame has a specified name. */
3124 Vx_resource_name = Vinvocation_name;
3126 display = x_get_arg (dpyinfo, parms, Qterminal, 0, 0, RES_TYPE_NUMBER);
3127 if (EQ (display, Qunbound))
3128 display = x_get_arg (dpyinfo, parms, Qdisplay, 0, 0, RES_TYPE_STRING);
3129 if (EQ (display, Qunbound))
3130 display = Qnil;
3131 dpyinfo = check_x_display_info (display);
3132 kb = dpyinfo->terminal->kboard;
3134 if (!dpyinfo->terminal->name)
3135 error ("Terminal is not live, can't create new frames on it");
3137 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
3138 if (!STRINGP (name)
3139 && ! EQ (name, Qunbound)
3140 && ! NILP (name))
3141 error ("Invalid frame name--not a string or nil");
3143 if (STRINGP (name))
3144 Vx_resource_name = name;
3146 /* See if parent window is specified. */
3147 parent = x_get_arg (dpyinfo, parms, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
3148 if (EQ (parent, Qunbound))
3149 parent = Qnil;
3150 if (! NILP (parent))
3151 CHECK_NUMBER (parent);
3153 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
3154 /* No need to protect DISPLAY because that's not used after passing
3155 it to make_frame_without_minibuffer. */
3156 frame = Qnil;
3157 GCPRO4 (parms, parent, name, frame);
3158 tem = x_get_arg (dpyinfo, parms, Qminibuffer, "minibuffer", "Minibuffer",
3159 RES_TYPE_SYMBOL);
3160 if (EQ (tem, Qnone) || NILP (tem))
3161 f = make_frame_without_minibuffer (Qnil, kb, display);
3162 else if (EQ (tem, Qonly))
3164 f = make_minibuffer_frame ();
3165 minibuffer_only = 1;
3167 else if (WINDOWP (tem))
3168 f = make_frame_without_minibuffer (tem, kb, display);
3169 else
3170 f = make_frame (1);
3172 XSETFRAME (frame, f);
3174 /* Note that X Windows does support scroll bars. */
3175 FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
3177 f->terminal = dpyinfo->terminal;
3178 f->terminal->reference_count++;
3180 f->output_method = output_x_window;
3181 f->output_data.x = (struct x_output *) xmalloc (sizeof (struct x_output));
3182 bzero (f->output_data.x, sizeof (struct x_output));
3183 f->output_data.x->icon_bitmap = -1;
3184 FRAME_FONTSET (f) = -1;
3185 f->output_data.x->scroll_bar_foreground_pixel = -1;
3186 f->output_data.x->scroll_bar_background_pixel = -1;
3187 #ifdef USE_TOOLKIT_SCROLL_BARS
3188 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
3189 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
3190 #endif /* USE_TOOLKIT_SCROLL_BARS */
3192 f->icon_name
3193 = x_get_arg (dpyinfo, parms, Qicon_name, "iconName", "Title",
3194 RES_TYPE_STRING);
3195 if (! STRINGP (f->icon_name))
3196 f->icon_name = Qnil;
3198 FRAME_X_DISPLAY_INFO (f) = dpyinfo;
3200 /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe. */
3201 record_unwind_protect (unwind_create_frame, frame);
3202 #if GLYPH_DEBUG
3203 image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
3204 dpyinfo_refcount = dpyinfo->reference_count;
3205 #endif /* GLYPH_DEBUG */
3207 /* These colors will be set anyway later, but it's important
3208 to get the color reference counts right, so initialize them! */
3210 Lisp_Object black;
3211 struct gcpro gcpro1;
3213 /* Function x_decode_color can signal an error. Make
3214 sure to initialize color slots so that we won't try
3215 to free colors we haven't allocated. */
3216 FRAME_FOREGROUND_PIXEL (f) = -1;
3217 FRAME_BACKGROUND_PIXEL (f) = -1;
3218 f->output_data.x->cursor_pixel = -1;
3219 f->output_data.x->cursor_foreground_pixel = -1;
3220 f->output_data.x->border_pixel = -1;
3221 f->output_data.x->mouse_pixel = -1;
3223 black = build_string ("black");
3224 GCPRO1 (black);
3225 FRAME_FOREGROUND_PIXEL (f)
3226 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3227 FRAME_BACKGROUND_PIXEL (f)
3228 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3229 f->output_data.x->cursor_pixel
3230 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3231 f->output_data.x->cursor_foreground_pixel
3232 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3233 f->output_data.x->border_pixel
3234 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3235 f->output_data.x->mouse_pixel
3236 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3237 UNGCPRO;
3240 /* Specify the parent under which to make this X window. */
3242 if (!NILP (parent))
3244 f->output_data.x->parent_desc = (Window) XFASTINT (parent);
3245 f->output_data.x->explicit_parent = 1;
3247 else
3249 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
3250 f->output_data.x->explicit_parent = 0;
3253 /* Set the name; the functions to which we pass f expect the name to
3254 be set. */
3255 if (EQ (name, Qunbound) || NILP (name))
3257 f->name = build_string (dpyinfo->x_id_name);
3258 f->explicit_name = 0;
3260 else
3262 f->name = name;
3263 f->explicit_name = 1;
3264 /* use the frame's title when getting resources for this frame. */
3265 specbind (Qx_resource_name, name);
3268 f->resx = dpyinfo->resx;
3269 f->resy = dpyinfo->resy;
3271 #ifdef HAVE_FREETYPE
3272 #ifdef HAVE_XFT
3273 register_font_driver (&xftfont_driver, f);
3274 #else /* not HAVE_XFT */
3275 register_font_driver (&ftxfont_driver, f);
3276 #endif /* not HAVE_XFT */
3277 #endif /* HAVE_FREETYPE */
3278 register_font_driver (&xfont_driver, f);
3280 x_default_parameter (f, parms, Qfont_backend, Qnil,
3281 "fontBackend", "FontBackend", RES_TYPE_STRING);
3283 /* Extract the window parameters from the supplied values
3284 that are needed to determine window geometry. */
3285 x_default_font_parameter (f, parms);
3286 if (!FRAME_FONT (f))
3288 delete_frame (frame, Qnoelisp);
3289 error ("Invalid frame font");
3292 #ifdef USE_LUCID
3293 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
3294 whereby it fails to get any font. */
3295 xlwmenu_default_font = XLoadQueryFont (FRAME_X_DISPLAY (f), "fixed");
3296 #endif
3298 /* Frame contents get displaced if an embedded X window has a border. */
3299 if (! FRAME_X_EMBEDDED_P (f))
3300 x_default_parameter (f, parms, Qborder_width, make_number (2),
3301 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
3303 /* This defaults to 1 in order to match xterm. We recognize either
3304 internalBorderWidth or internalBorder (which is what xterm calls
3305 it). */
3306 if (NILP (Fassq (Qinternal_border_width, parms)))
3308 Lisp_Object value;
3310 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
3311 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
3312 if (! EQ (value, Qunbound))
3313 parms = Fcons (Fcons (Qinternal_border_width, value),
3314 parms);
3316 x_default_parameter (f, parms, Qinternal_border_width,
3317 #ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */
3318 make_number (0),
3319 #else
3320 make_number (1),
3321 #endif
3322 "internalBorderWidth", "internalBorderWidth",
3323 RES_TYPE_NUMBER);
3324 x_default_parameter (f, parms, Qvertical_scroll_bars, Qleft,
3325 "verticalScrollBars", "ScrollBars",
3326 RES_TYPE_SYMBOL);
3328 /* Also do the stuff which must be set before the window exists. */
3329 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
3330 "foreground", "Foreground", RES_TYPE_STRING);
3331 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
3332 "background", "Background", RES_TYPE_STRING);
3333 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
3334 "pointerColor", "Foreground", RES_TYPE_STRING);
3335 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
3336 "cursorColor", "Foreground", RES_TYPE_STRING);
3337 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
3338 "borderColor", "BorderColor", RES_TYPE_STRING);
3339 x_default_parameter (f, parms, Qscreen_gamma, Qnil,
3340 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
3341 x_default_parameter (f, parms, Qline_spacing, Qnil,
3342 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
3343 x_default_parameter (f, parms, Qleft_fringe, Qnil,
3344 "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
3345 x_default_parameter (f, parms, Qright_fringe, Qnil,
3346 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
3348 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_foreground,
3349 "scrollBarForeground",
3350 "ScrollBarForeground", 1);
3351 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_background,
3352 "scrollBarBackground",
3353 "ScrollBarBackground", 0);
3355 /* Init faces before x_default_parameter is called for scroll-bar
3356 parameters because that function calls x_set_scroll_bar_width,
3357 which calls change_frame_size, which calls Fset_window_buffer,
3358 which runs hooks, which call Fvertical_motion. At the end, we
3359 end up in init_iterator with a null face cache, which should not
3360 happen. */
3361 init_frame_faces (f);
3363 x_default_parameter (f, parms, Qmenu_bar_lines, make_number (1),
3364 "menuBar", "MenuBar", RES_TYPE_NUMBER);
3365 x_default_parameter (f, parms, Qtool_bar_lines, make_number (1),
3366 "toolBar", "ToolBar", RES_TYPE_NUMBER);
3367 x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
3368 "bufferPredicate", "BufferPredicate",
3369 RES_TYPE_SYMBOL);
3370 x_default_parameter (f, parms, Qtitle, Qnil,
3371 "title", "Title", RES_TYPE_STRING);
3372 x_default_parameter (f, parms, Qwait_for_wm, Qt,
3373 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
3374 x_default_parameter (f, parms, Qfullscreen, Qnil,
3375 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
3377 /* Compute the size of the X window. */
3378 window_prompting = x_figure_window_size (f, parms, 1);
3380 tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
3381 f->no_split = minibuffer_only || EQ (tem, Qt);
3383 x_icon_verify (f, parms);
3385 /* Create the X widget or window. */
3386 #ifdef USE_X_TOOLKIT
3387 x_window (f, window_prompting, minibuffer_only);
3388 #else
3389 x_window (f);
3390 #endif
3392 x_icon (f, parms);
3393 x_make_gc (f);
3395 /* Now consider the frame official. */
3396 FRAME_X_DISPLAY_INFO (f)->reference_count++;
3397 Vframe_list = Fcons (frame, Vframe_list);
3399 /* We need to do this after creating the X window, so that the
3400 icon-creation functions can say whose icon they're describing. */
3401 x_default_parameter (f, parms, Qicon_type, Qt,
3402 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
3404 x_default_parameter (f, parms, Qauto_raise, Qnil,
3405 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3406 x_default_parameter (f, parms, Qauto_lower, Qnil,
3407 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3408 x_default_parameter (f, parms, Qcursor_type, Qbox,
3409 "cursorType", "CursorType", RES_TYPE_SYMBOL);
3410 x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
3411 "scrollBarWidth", "ScrollBarWidth",
3412 RES_TYPE_NUMBER);
3413 x_default_parameter (f, parms, Qalpha, Qnil,
3414 "alpha", "Alpha", RES_TYPE_NUMBER);
3416 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3417 Change will not be effected unless different from the current
3418 FRAME_LINES (f). */
3419 width = FRAME_COLS (f);
3420 height = FRAME_LINES (f);
3422 SET_FRAME_COLS (f, 0);
3423 FRAME_LINES (f) = 0;
3424 change_frame_size (f, height, width, 1, 0, 0);
3426 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3427 /* Create the menu bar. */
3428 if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
3430 /* If this signals an error, we haven't set size hints for the
3431 frame and we didn't make it visible. */
3432 initialize_frame_menubar (f);
3434 #ifndef USE_GTK
3435 /* This is a no-op, except under Motif where it arranges the
3436 main window for the widgets on it. */
3437 lw_set_main_areas (f->output_data.x->column_widget,
3438 f->output_data.x->menubar_widget,
3439 f->output_data.x->edit_widget);
3440 #endif /* not USE_GTK */
3442 #endif /* USE_X_TOOLKIT || USE_GTK */
3444 /* Tell the server what size and position, etc, we want, and how
3445 badly we want them. This should be done after we have the menu
3446 bar so that its size can be taken into account. */
3447 BLOCK_INPUT;
3448 x_wm_set_size_hint (f, window_prompting, 0);
3449 UNBLOCK_INPUT;
3451 /* Make the window appear on the frame and enable display, unless
3452 the caller says not to. However, with explicit parent, Emacs
3453 cannot control visibility, so don't try. */
3454 if (! f->output_data.x->explicit_parent)
3456 Lisp_Object visibility;
3458 visibility = x_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
3459 RES_TYPE_SYMBOL);
3460 if (EQ (visibility, Qunbound))
3461 visibility = Qt;
3463 if (EQ (visibility, Qicon))
3464 x_iconify_frame (f);
3465 else if (! NILP (visibility))
3466 x_make_frame_visible (f);
3467 else
3468 /* Must have been Qnil. */
3472 /* Set the WM leader property. GTK does this itself, so this is not
3473 needed when using GTK. */
3474 if (dpyinfo->client_leader_window != 0)
3476 BLOCK_INPUT;
3477 XChangeProperty (FRAME_X_DISPLAY (f),
3478 FRAME_OUTER_WINDOW (f),
3479 dpyinfo->Xatom_wm_client_leader,
3480 XA_WINDOW, 32, PropModeReplace,
3481 (unsigned char *) &dpyinfo->client_leader_window, 1);
3482 UNBLOCK_INPUT;
3485 /* Initialize `default-minibuffer-frame' in case this is the first
3486 frame on this terminal. */
3487 if (FRAME_HAS_MINIBUF_P (f)
3488 && (!FRAMEP (kb->Vdefault_minibuffer_frame)
3489 || !FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame))))
3490 kb->Vdefault_minibuffer_frame = frame;
3492 /* All remaining specified parameters, which have not been "used"
3493 by x_get_arg and friends, now go in the misc. alist of the frame. */
3494 for (tem = parms; CONSP (tem); tem = XCDR (tem))
3495 if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
3496 f->param_alist = Fcons (XCAR (tem), f->param_alist);
3498 UNGCPRO;
3500 /* Make sure windows on this frame appear in calls to next-window
3501 and similar functions. */
3502 Vwindow_list = Qnil;
3504 return unbind_to (count, frame);
3508 /* FRAME is used only to get a handle on the X display. We don't pass the
3509 display info directly because we're called from frame.c, which doesn't
3510 know about that structure. */
3512 Lisp_Object
3513 x_get_focus_frame (frame)
3514 struct frame *frame;
3516 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (frame);
3517 Lisp_Object xfocus;
3518 if (! dpyinfo->x_focus_frame)
3519 return Qnil;
3521 XSETFRAME (xfocus, dpyinfo->x_focus_frame);
3522 return xfocus;
3526 /* In certain situations, when the window manager follows a
3527 click-to-focus policy, there seems to be no way around calling
3528 XSetInputFocus to give another frame the input focus .
3530 In an ideal world, XSetInputFocus should generally be avoided so
3531 that applications don't interfere with the window manager's focus
3532 policy. But I think it's okay to use when it's clearly done
3533 following a user-command. */
3535 DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
3536 doc: /* Set the input focus to FRAME.
3537 FRAME nil means use the selected frame. */)
3538 (frame)
3539 Lisp_Object frame;
3541 struct frame *f = check_x_frame (frame);
3542 Display *dpy = FRAME_X_DISPLAY (f);
3544 BLOCK_INPUT;
3545 x_catch_errors (dpy);
3546 XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3547 RevertToParent, CurrentTime);
3548 x_ewmh_activate_frame (f);
3549 x_uncatch_errors ();
3550 UNBLOCK_INPUT;
3552 return Qnil;
3556 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
3557 doc: /* Internal function called by `color-defined-p', which see. */)
3558 (color, frame)
3559 Lisp_Object color, frame;
3561 XColor foo;
3562 FRAME_PTR f = check_x_frame (frame);
3564 CHECK_STRING (color);
3566 if (x_defined_color (f, SDATA (color), &foo, 0))
3567 return Qt;
3568 else
3569 return Qnil;
3572 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
3573 doc: /* Internal function called by `color-values', which see. */)
3574 (color, frame)
3575 Lisp_Object color, frame;
3577 XColor foo;
3578 FRAME_PTR f = check_x_frame (frame);
3580 CHECK_STRING (color);
3582 if (x_defined_color (f, SDATA (color), &foo, 0))
3583 return list3 (make_number (foo.red),
3584 make_number (foo.green),
3585 make_number (foo.blue));
3586 else
3587 return Qnil;
3590 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
3591 doc: /* Internal function called by `display-color-p', which see. */)
3592 (terminal)
3593 Lisp_Object terminal;
3595 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3597 if (dpyinfo->n_planes <= 2)
3598 return Qnil;
3600 switch (dpyinfo->visual->class)
3602 case StaticColor:
3603 case PseudoColor:
3604 case TrueColor:
3605 case DirectColor:
3606 return Qt;
3608 default:
3609 return Qnil;
3613 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
3614 0, 1, 0,
3615 doc: /* Return t if the X display supports shades of gray.
3616 Note that color displays do support shades of gray.
3617 The optional argument TERMINAL specifies which display to ask about.
3618 TERMINAL should be a terminal object, a frame or a display name (a string).
3619 If omitted or nil, that stands for the selected frame's display. */)
3620 (terminal)
3621 Lisp_Object terminal;
3623 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3625 if (dpyinfo->n_planes <= 1)
3626 return Qnil;
3628 switch (dpyinfo->visual->class)
3630 case StaticColor:
3631 case PseudoColor:
3632 case TrueColor:
3633 case DirectColor:
3634 case StaticGray:
3635 case GrayScale:
3636 return Qt;
3638 default:
3639 return Qnil;
3643 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
3644 0, 1, 0,
3645 doc: /* Return the width in pixels of the X display TERMINAL.
3646 The optional argument TERMINAL specifies which display to ask about.
3647 TERMINAL should be a terminal object, a frame or a display name (a string).
3648 If omitted or nil, that stands for the selected frame's display. */)
3649 (terminal)
3650 Lisp_Object terminal;
3652 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3654 return make_number (x_display_pixel_width (dpyinfo));
3657 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
3658 Sx_display_pixel_height, 0, 1, 0,
3659 doc: /* Return the height in pixels of the X display TERMINAL.
3660 The optional argument TERMINAL specifies which display to ask about.
3661 TERMINAL should be a terminal object, a frame or a display name (a string).
3662 If omitted or nil, that stands for the selected frame's display. */)
3663 (terminal)
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 (terminal)
3678 Lisp_Object terminal;
3680 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3682 return make_number (dpyinfo->n_planes);
3685 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
3686 0, 1, 0,
3687 doc: /* Return the number of color cells of the X display TERMINAL.
3688 The optional argument TERMINAL specifies which display to ask about.
3689 TERMINAL should be a terminal object, a frame or a display name (a string).
3690 If omitted or nil, that stands for the selected frame's display. */)
3691 (terminal)
3692 Lisp_Object terminal;
3694 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3696 int nr_planes = DisplayPlanes (dpyinfo->display,
3697 XScreenNumberOfScreen (dpyinfo->screen));
3699 /* Truncate nr_planes to 24 to avoid integer overflow.
3700 Some displays says 32, but only 24 bits are actually significant.
3701 There are only very few and rare video cards that have more than
3702 24 significant bits. Also 24 bits is more than 16 million colors,
3703 it "should be enough for everyone". */
3704 if (nr_planes > 24) nr_planes = 24;
3706 return make_number (1 << nr_planes);
3709 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
3710 Sx_server_max_request_size,
3711 0, 1, 0,
3712 doc: /* Return the maximum request size of the X server of display TERMINAL.
3713 The optional argument TERMINAL specifies which display to ask about.
3714 TERMINAL should be a terminal object, a frame or a display name (a string).
3715 If omitted or nil, that stands for the selected frame's display. */)
3716 (terminal)
3717 Lisp_Object terminal;
3719 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3721 return make_number (MAXREQUEST (dpyinfo->display));
3724 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
3725 doc: /* Return the "vendor ID" string of the X server of display TERMINAL.
3726 \(Labelling every distributor as a "vendor" embodies the false assumption
3727 that operating systems cannot be developed and distributed noncommercially.)
3728 The optional argument TERMINAL specifies which display to ask about.
3729 TERMINAL should be a terminal object, a frame or a display name (a string).
3730 If omitted or nil, that stands for the selected frame's display. */)
3731 (terminal)
3732 Lisp_Object terminal;
3734 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3735 char *vendor = ServerVendor (dpyinfo->display);
3737 if (! vendor) vendor = "";
3738 return build_string (vendor);
3741 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
3742 doc: /* Return the version numbers of the X server of display TERMINAL.
3743 The value is a list of three integers: the major and minor
3744 version numbers of the X Protocol in use, and the distributor-specific release
3745 number. See also the function `x-server-vendor'.
3747 The optional argument TERMINAL specifies which display to ask about.
3748 TERMINAL should be a terminal object, a frame or a display name (a string).
3749 If omitted or nil, that stands for the selected frame's display. */)
3750 (terminal)
3751 Lisp_Object terminal;
3753 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3754 Display *dpy = dpyinfo->display;
3756 return Fcons (make_number (ProtocolVersion (dpy)),
3757 Fcons (make_number (ProtocolRevision (dpy)),
3758 Fcons (make_number (VendorRelease (dpy)), Qnil)));
3761 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
3762 doc: /* Return the number of screens on the X server of display TERMINAL.
3763 The optional argument TERMINAL specifies which display to ask about.
3764 TERMINAL should be a terminal object, a frame or a display name (a string).
3765 If omitted or nil, that stands for the selected frame's display. */)
3766 (terminal)
3767 Lisp_Object terminal;
3769 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3771 return make_number (ScreenCount (dpyinfo->display));
3774 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
3775 doc: /* Return the height in millimeters of the X display TERMINAL.
3776 The optional argument TERMINAL specifies which display to ask about.
3777 TERMINAL should be a terminal object, a frame or a display name (a string).
3778 If omitted or nil, that stands for the selected frame's display. */)
3779 (terminal)
3780 Lisp_Object terminal;
3782 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3784 return make_number (HeightMMOfScreen (dpyinfo->screen));
3787 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
3788 doc: /* Return the width in millimeters of the X display TERMINAL.
3789 The optional argument TERMINAL specifies which display to ask about.
3790 TERMINAL should be a terminal object, a frame or a display name (a string).
3791 If omitted or nil, that stands for the selected frame's display. */)
3792 (terminal)
3793 Lisp_Object terminal;
3795 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3797 return make_number (WidthMMOfScreen (dpyinfo->screen));
3800 DEFUN ("x-display-backing-store", Fx_display_backing_store,
3801 Sx_display_backing_store, 0, 1, 0,
3802 doc: /* Return an indication of whether X display TERMINAL does backing store.
3803 The value may be `always', `when-mapped', or `not-useful'.
3804 The optional argument TERMINAL specifies which display to ask about.
3805 TERMINAL should be a terminal object, a frame or a display name (a string).
3806 If omitted or nil, that stands for the selected frame's display. */)
3807 (terminal)
3808 Lisp_Object terminal;
3810 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3811 Lisp_Object result;
3813 switch (DoesBackingStore (dpyinfo->screen))
3815 case Always:
3816 result = intern ("always");
3817 break;
3819 case WhenMapped:
3820 result = intern ("when-mapped");
3821 break;
3823 case NotUseful:
3824 result = intern ("not-useful");
3825 break;
3827 default:
3828 error ("Strange value for BackingStore parameter of screen");
3829 result = Qnil;
3832 return result;
3835 DEFUN ("x-display-visual-class", Fx_display_visual_class,
3836 Sx_display_visual_class, 0, 1, 0,
3837 doc: /* Return the visual class of the X display TERMINAL.
3838 The value is one of the symbols `static-gray', `gray-scale',
3839 `static-color', `pseudo-color', `true-color', or `direct-color'.
3841 The optional argument TERMINAL specifies which display to ask about.
3842 TERMINAL should a terminal object, a frame or a display name (a string).
3843 If omitted or nil, that stands for the selected frame's display. */)
3844 (terminal)
3845 Lisp_Object terminal;
3847 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3848 Lisp_Object result;
3850 switch (dpyinfo->visual->class)
3852 case StaticGray:
3853 result = intern ("static-gray");
3854 break;
3855 case GrayScale:
3856 result = intern ("gray-scale");
3857 break;
3858 case StaticColor:
3859 result = intern ("static-color");
3860 break;
3861 case PseudoColor:
3862 result = intern ("pseudo-color");
3863 break;
3864 case TrueColor:
3865 result = intern ("true-color");
3866 break;
3867 case DirectColor:
3868 result = intern ("direct-color");
3869 break;
3870 default:
3871 error ("Display has an unknown visual class");
3872 result = Qnil;
3875 return result;
3878 DEFUN ("x-display-save-under", Fx_display_save_under,
3879 Sx_display_save_under, 0, 1, 0,
3880 doc: /* Return t if the X display TERMINAL supports the save-under feature.
3881 The optional argument TERMINAL specifies which display to ask about.
3882 TERMINAL should be a terminal object, a frame or a display name (a string).
3883 If omitted or nil, that stands for the selected frame's display. */)
3884 (terminal)
3885 Lisp_Object terminal;
3887 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3889 if (DoesSaveUnders (dpyinfo->screen) == True)
3890 return Qt;
3891 else
3892 return Qnil;
3896 x_pixel_width (f)
3897 register struct frame *f;
3899 return FRAME_PIXEL_WIDTH (f);
3903 x_pixel_height (f)
3904 register struct frame *f;
3906 return FRAME_PIXEL_HEIGHT (f);
3910 x_char_width (f)
3911 register struct frame *f;
3913 return FRAME_COLUMN_WIDTH (f);
3917 x_char_height (f)
3918 register struct frame *f;
3920 return FRAME_LINE_HEIGHT (f);
3924 x_screen_planes (f)
3925 register struct frame *f;
3927 return FRAME_X_DISPLAY_INFO (f)->n_planes;
3932 /************************************************************************
3933 X Displays
3934 ************************************************************************/
3937 /* Mapping visual names to visuals. */
3939 static struct visual_class
3941 char *name;
3942 int class;
3944 visual_classes[] =
3946 {"StaticGray", StaticGray},
3947 {"GrayScale", GrayScale},
3948 {"StaticColor", StaticColor},
3949 {"PseudoColor", PseudoColor},
3950 {"TrueColor", TrueColor},
3951 {"DirectColor", DirectColor},
3952 {NULL, 0}
3956 #ifndef HAVE_XSCREENNUMBEROFSCREEN
3958 /* Value is the screen number of screen SCR. This is a substitute for
3959 the X function with the same name when that doesn't exist. */
3962 XScreenNumberOfScreen (scr)
3963 register Screen *scr;
3965 Display *dpy = scr->display;
3966 int i;
3968 for (i = 0; i < dpy->nscreens; ++i)
3969 if (scr == dpy->screens + i)
3970 break;
3972 return i;
3975 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
3978 /* Select the visual that should be used on display DPYINFO. Set
3979 members of DPYINFO appropriately. Called from x_term_init. */
3981 void
3982 select_visual (dpyinfo)
3983 struct x_display_info *dpyinfo;
3985 Display *dpy = dpyinfo->display;
3986 Screen *screen = dpyinfo->screen;
3987 Lisp_Object value;
3989 /* See if a visual is specified. */
3990 value = display_x_get_resource (dpyinfo,
3991 build_string ("visualClass"),
3992 build_string ("VisualClass"),
3993 Qnil, Qnil);
3994 if (STRINGP (value))
3996 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
3997 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
3998 depth, a decimal number. NAME is compared with case ignored. */
3999 char *s = (char *) alloca (SBYTES (value) + 1);
4000 char *dash;
4001 int i, class = -1;
4002 XVisualInfo vinfo;
4004 strcpy (s, SDATA (value));
4005 dash = index (s, '-');
4006 if (dash)
4008 dpyinfo->n_planes = atoi (dash + 1);
4009 *dash = '\0';
4011 else
4012 /* We won't find a matching visual with depth 0, so that
4013 an error will be printed below. */
4014 dpyinfo->n_planes = 0;
4016 /* Determine the visual class. */
4017 for (i = 0; visual_classes[i].name; ++i)
4018 if (xstrcasecmp (s, visual_classes[i].name) == 0)
4020 class = visual_classes[i].class;
4021 break;
4024 /* Look up a matching visual for the specified class. */
4025 if (class == -1
4026 || !XMatchVisualInfo (dpy, XScreenNumberOfScreen (screen),
4027 dpyinfo->n_planes, class, &vinfo))
4028 fatal ("Invalid visual specification `%s'", SDATA (value));
4030 dpyinfo->visual = vinfo.visual;
4032 else
4034 int n_visuals;
4035 XVisualInfo *vinfo, vinfo_template;
4037 dpyinfo->visual = DefaultVisualOfScreen (screen);
4039 vinfo_template.visualid = XVisualIDFromVisual (dpyinfo->visual);
4040 vinfo_template.screen = XScreenNumberOfScreen (screen);
4041 vinfo = XGetVisualInfo (dpy, VisualIDMask | VisualScreenMask,
4042 &vinfo_template, &n_visuals);
4043 if (n_visuals != 1)
4044 fatal ("Can't get proper X visual info");
4046 dpyinfo->n_planes = vinfo->depth;
4047 XFree ((char *) vinfo);
4052 /* Return the X display structure for the display named NAME.
4053 Open a new connection if necessary. */
4055 struct x_display_info *
4056 x_display_info_for_name (name)
4057 Lisp_Object name;
4059 Lisp_Object names;
4060 struct x_display_info *dpyinfo;
4062 CHECK_STRING (name);
4064 #if 0
4065 if (! EQ (Vinitial_window_system, intern ("x")))
4066 error ("Not using X Windows"); /* That doesn't stop us anymore. */
4067 #endif
4069 for (dpyinfo = x_display_list, names = x_display_name_list;
4070 dpyinfo;
4071 dpyinfo = dpyinfo->next, names = XCDR (names))
4073 Lisp_Object tem;
4074 tem = Fstring_equal (XCAR (XCAR (names)), name);
4075 if (!NILP (tem))
4076 return dpyinfo;
4079 /* Use this general default value to start with. */
4080 Vx_resource_name = Vinvocation_name;
4082 validate_x_resource_name ();
4084 dpyinfo = x_term_init (name, (char *)0,
4085 (char *) SDATA (Vx_resource_name));
4087 if (dpyinfo == 0)
4088 error ("Cannot connect to X server %s", SDATA (name));
4090 x_in_use = 1;
4091 XSETFASTINT (Vwindow_system_version, 11);
4093 return dpyinfo;
4097 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
4098 1, 3, 0,
4099 doc: /* Open a connection to an X server.
4100 DISPLAY is the name of the display to connect to.
4101 Optional second arg XRM-STRING is a string of resources in xrdb format.
4102 If the optional third arg MUST-SUCCEED is non-nil,
4103 terminate Emacs if we can't open the connection. */)
4104 (display, xrm_string, must_succeed)
4105 Lisp_Object display, xrm_string, must_succeed;
4107 unsigned char *xrm_option;
4108 struct x_display_info *dpyinfo;
4110 CHECK_STRING (display);
4111 if (! NILP (xrm_string))
4112 CHECK_STRING (xrm_string);
4114 #if 0
4115 if (! EQ (Vinitial_window_system, intern ("x")))
4116 error ("Not using X Windows"); /* That doesn't stop us anymore. */
4117 #endif
4119 if (! NILP (xrm_string))
4120 xrm_option = (unsigned char *) SDATA (xrm_string);
4121 else
4122 xrm_option = (unsigned char *) 0;
4124 validate_x_resource_name ();
4126 /* This is what opens the connection and sets x_current_display.
4127 This also initializes many symbols, such as those used for input. */
4128 dpyinfo = x_term_init (display, xrm_option,
4129 (char *) SDATA (Vx_resource_name));
4131 if (dpyinfo == 0)
4133 if (!NILP (must_succeed))
4134 fatal ("Cannot connect to X server %s.\n\
4135 Check the DISPLAY environment variable or use `-d'.\n\
4136 Also use the `xauth' program to verify that you have the proper\n\
4137 authorization information needed to connect the X server.\n\
4138 An insecure way to solve the problem may be to use `xhost'.\n",
4139 SDATA (display));
4140 else
4141 error ("Cannot connect to X server %s", SDATA (display));
4144 x_in_use = 1;
4146 XSETFASTINT (Vwindow_system_version, 11);
4147 return Qnil;
4150 DEFUN ("x-close-connection", Fx_close_connection,
4151 Sx_close_connection, 1, 1, 0,
4152 doc: /* Close the connection to TERMINAL's X server.
4153 For TERMINAL, specify a terminal object, a frame or a display name (a
4154 string). If TERMINAL is nil, that stands for the selected frame's
4155 terminal. */)
4156 (terminal)
4157 Lisp_Object terminal;
4159 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4161 if (dpyinfo->reference_count > 0)
4162 error ("Display still has frames on it");
4164 x_delete_terminal (dpyinfo->terminal);
4166 return Qnil;
4169 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
4170 doc: /* Return the list of display names that Emacs has connections to. */)
4173 Lisp_Object tail, result;
4175 result = Qnil;
4176 for (tail = x_display_name_list; CONSP (tail); tail = XCDR (tail))
4177 result = Fcons (XCAR (XCAR (tail)), result);
4179 return result;
4182 DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
4183 doc: /* If ON is non-nil, report X errors as soon as the erring request is made.
4184 If ON is nil, allow buffering of requests.
4185 Turning on synchronization prohibits the Xlib routines from buffering
4186 requests and seriously degrades performance, but makes debugging much
4187 easier.
4188 The optional second argument TERMINAL specifies which display to act on.
4189 TERMINAL should be a terminal object, a frame or a display name (a string).
4190 If TERMINAL is omitted or nil, that stands for the selected frame's display. */)
4191 (on, terminal)
4192 Lisp_Object terminal, on;
4194 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4196 XSynchronize (dpyinfo->display, !EQ (on, Qnil));
4198 return Qnil;
4201 /* Wait for responses to all X commands issued so far for frame F. */
4203 void
4204 x_sync (f)
4205 FRAME_PTR f;
4207 BLOCK_INPUT;
4208 XSync (FRAME_X_DISPLAY (f), False);
4209 UNBLOCK_INPUT;
4213 /***********************************************************************
4214 Window properties
4215 ***********************************************************************/
4217 DEFUN ("x-change-window-property", Fx_change_window_property,
4218 Sx_change_window_property, 2, 6, 0,
4219 doc: /* Change window property PROP to VALUE on the X window of FRAME.
4220 PROP must be a string.
4221 VALUE may be a string or a list of conses, numbers and/or strings.
4222 If an element in the list is a string, it is converted to
4223 an Atom and the value of the Atom is used. If an element is a cons,
4224 it is converted to a 32 bit number where the car is the 16 top bits and the
4225 cdr is the lower 16 bits.
4226 FRAME nil or omitted means use the selected frame.
4227 If TYPE is given and non-nil, it is the name of the type of VALUE.
4228 If TYPE is not given or nil, the type is STRING.
4229 FORMAT gives the size in bits of each element if VALUE is a list.
4230 It must be one of 8, 16 or 32.
4231 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
4232 If OUTER_P is non-nil, the property is changed for the outer X window of
4233 FRAME. Default is to change on the edit X window.
4235 Value is VALUE. */)
4236 (prop, value, frame, type, format, outer_p)
4237 Lisp_Object prop, value, frame, type, format, outer_p;
4239 struct frame *f = check_x_frame (frame);
4240 Atom prop_atom;
4241 Atom target_type = XA_STRING;
4242 int element_format = 8;
4243 unsigned char *data;
4244 int nelements;
4245 Window w;
4247 CHECK_STRING (prop);
4249 if (! NILP (format))
4251 CHECK_NUMBER (format);
4252 element_format = XFASTINT (format);
4254 if (element_format != 8 && element_format != 16
4255 && element_format != 32)
4256 error ("FORMAT must be one of 8, 16 or 32");
4259 if (CONSP (value))
4261 nelements = x_check_property_data (value);
4262 if (nelements == -1)
4263 error ("Bad data in VALUE, must be number, string or cons");
4265 if (element_format == 8)
4266 data = (unsigned char *) xmalloc (nelements);
4267 else if (element_format == 16)
4268 data = (unsigned char *) xmalloc (nelements*2);
4269 else /* format == 32 */
4270 /* The man page for XChangeProperty:
4271 "If the specified format is 32, the property data must be a
4272 long array."
4273 This applies even if long is more than 64 bits. The X library
4274 converts to 32 bits before sending to the X server. */
4275 data = (unsigned char *) xmalloc (nelements * sizeof(long));
4277 x_fill_property_data (FRAME_X_DISPLAY (f), value, data, element_format);
4279 else
4281 CHECK_STRING (value);
4282 data = SDATA (value);
4283 nelements = SCHARS (value);
4286 BLOCK_INPUT;
4287 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4288 if (! NILP (type))
4290 CHECK_STRING (type);
4291 target_type = XInternAtom (FRAME_X_DISPLAY (f), SDATA (type), False);
4294 if (! NILP (outer_p)) w = FRAME_OUTER_WINDOW (f);
4295 else w = FRAME_X_WINDOW (f);
4297 XChangeProperty (FRAME_X_DISPLAY (f), w,
4298 prop_atom, target_type, element_format, PropModeReplace,
4299 data, nelements);
4301 if (CONSP (value)) xfree (data);
4303 /* Make sure the property is set when we return. */
4304 XFlush (FRAME_X_DISPLAY (f));
4305 UNBLOCK_INPUT;
4307 return value;
4311 DEFUN ("x-delete-window-property", Fx_delete_window_property,
4312 Sx_delete_window_property, 1, 2, 0,
4313 doc: /* Remove window property PROP from X window of FRAME.
4314 FRAME nil or omitted means use the selected frame. Value is PROP. */)
4315 (prop, frame)
4316 Lisp_Object prop, frame;
4318 struct frame *f = check_x_frame (frame);
4319 Atom prop_atom;
4321 CHECK_STRING (prop);
4322 BLOCK_INPUT;
4323 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4324 XDeleteProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), prop_atom);
4326 /* Make sure the property is removed when we return. */
4327 XFlush (FRAME_X_DISPLAY (f));
4328 UNBLOCK_INPUT;
4330 return prop;
4334 DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
4335 1, 6, 0,
4336 doc: /* Value is the value of window property PROP on FRAME.
4337 If FRAME is nil or omitted, use the selected frame.
4338 If TYPE is nil or omitted, get the property as a string. Otherwise TYPE
4339 is the name of the Atom that denotes the type expected.
4340 If SOURCE is non-nil, get the property on that window instead of from
4341 FRAME. The number 0 denotes the root window.
4342 If DELETE_P is non-nil, delete the property after retreiving it.
4343 If VECTOR_RET_P is non-nil, don't return a string but a vector of values.
4345 Value is nil if FRAME hasn't a property with name PROP or if PROP has
4346 no value of TYPE. */)
4347 (prop, frame, type, source, delete_p, vector_ret_p)
4348 Lisp_Object prop, frame, type, source, delete_p, vector_ret_p;
4350 struct frame *f = check_x_frame (frame);
4351 Atom prop_atom;
4352 int rc;
4353 Lisp_Object prop_value = Qnil;
4354 unsigned char *tmp_data = NULL;
4355 Atom actual_type;
4356 Atom target_type = XA_STRING;
4357 int actual_format;
4358 unsigned long actual_size, bytes_remaining;
4359 Window target_window = FRAME_X_WINDOW (f);
4360 struct gcpro gcpro1;
4362 GCPRO1 (prop_value);
4363 CHECK_STRING (prop);
4365 if (! NILP (source))
4367 if (NUMBERP (source))
4369 if (FLOATP (source))
4370 target_window = (Window) XFLOAT (source);
4371 else
4372 target_window = XFASTINT (source);
4374 if (target_window == 0)
4375 target_window = FRAME_X_DISPLAY_INFO (f)->root_window;
4377 else if (CONSP (source))
4378 target_window = cons_to_long (source);
4381 BLOCK_INPUT;
4382 if (STRINGP (type))
4384 if (strcmp ("AnyPropertyType", SDATA (type)) == 0)
4385 target_type = AnyPropertyType;
4386 else
4387 target_type = XInternAtom (FRAME_X_DISPLAY (f), SDATA (type), False);
4390 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4391 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4392 prop_atom, 0, 0, False, target_type,
4393 &actual_type, &actual_format, &actual_size,
4394 &bytes_remaining, &tmp_data);
4395 if (rc == Success)
4397 int size = bytes_remaining;
4399 XFree (tmp_data);
4400 tmp_data = NULL;
4402 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4403 prop_atom, 0, bytes_remaining,
4404 ! NILP (delete_p), target_type,
4405 &actual_type, &actual_format,
4406 &actual_size, &bytes_remaining,
4407 &tmp_data);
4408 if (rc == Success && tmp_data)
4410 /* The man page for XGetWindowProperty says:
4411 "If the returned format is 32, the returned data is represented
4412 as a long array and should be cast to that type to obtain the
4413 elements."
4414 This applies even if long is more than 32 bits, the X library
4415 converts from 32 bit elements received from the X server to long
4416 and passes the long array to us. Thus, for that case bcopy can not
4417 be used. We convert to a 32 bit type here, because so much code
4418 assume on that.
4420 The bytes and offsets passed to XGetWindowProperty refers to the
4421 property and those are indeed in 32 bit quantities if format is
4422 32. */
4424 if (actual_format == 32 && actual_format < BITS_PER_LONG)
4426 unsigned long i;
4427 int *idata = (int *) tmp_data;
4428 long *ldata = (long *) tmp_data;
4430 for (i = 0; i < actual_size; ++i)
4431 idata[i] = (int) ldata[i];
4434 if (NILP (vector_ret_p))
4435 prop_value = make_string (tmp_data, size);
4436 else
4437 prop_value = x_property_data_to_lisp (f,
4438 tmp_data,
4439 actual_type,
4440 actual_format,
4441 actual_size);
4444 if (tmp_data) XFree (tmp_data);
4447 UNBLOCK_INPUT;
4448 UNGCPRO;
4449 return prop_value;
4454 /***********************************************************************
4455 Busy cursor
4456 ***********************************************************************/
4458 /* Timer function of hourglass_atimer. TIMER is equal to
4459 hourglass_atimer.
4461 Display an hourglass pointer on all frames by mapping the frames'
4462 hourglass_window. Set the hourglass_p flag in the frames'
4463 output_data.x structure to indicate that an hourglass cursor is
4464 shown on the frames. */
4466 void
4467 show_hourglass (timer)
4468 struct atimer *timer;
4470 /* The timer implementation will cancel this timer automatically
4471 after this function has run. Set hourglass_atimer to null
4472 so that we know the timer doesn't have to be canceled. */
4473 hourglass_atimer = NULL;
4475 if (!hourglass_shown_p)
4477 Lisp_Object rest, frame;
4479 BLOCK_INPUT;
4481 FOR_EACH_FRAME (rest, frame)
4483 struct frame *f = XFRAME (frame);
4485 if (FRAME_LIVE_P (f) && FRAME_X_P (f) && FRAME_X_DISPLAY (f))
4487 Display *dpy = FRAME_X_DISPLAY (f);
4489 #ifdef USE_X_TOOLKIT
4490 if (f->output_data.x->widget)
4491 #else
4492 if (FRAME_OUTER_WINDOW (f))
4493 #endif
4495 f->output_data.x->hourglass_p = 1;
4497 if (!f->output_data.x->hourglass_window)
4499 unsigned long mask = CWCursor;
4500 XSetWindowAttributes attrs;
4501 #ifdef USE_GTK
4502 Window parent = FRAME_X_WINDOW (f);
4503 #else
4504 Window parent = FRAME_OUTER_WINDOW (f);
4505 #endif
4506 attrs.cursor = f->output_data.x->hourglass_cursor;
4508 f->output_data.x->hourglass_window
4509 = XCreateWindow (dpy, parent,
4510 0, 0, 32000, 32000, 0, 0,
4511 InputOnly,
4512 CopyFromParent,
4513 mask, &attrs);
4516 XMapRaised (dpy, f->output_data.x->hourglass_window);
4517 XFlush (dpy);
4522 hourglass_shown_p = 1;
4523 UNBLOCK_INPUT;
4528 /* Hide the hourglass pointer on all frames, if it is currently
4529 shown. */
4531 void
4532 hide_hourglass ()
4534 if (hourglass_shown_p)
4536 Lisp_Object rest, frame;
4538 BLOCK_INPUT;
4539 FOR_EACH_FRAME (rest, frame)
4541 struct frame *f = XFRAME (frame);
4543 if (FRAME_X_P (f)
4544 /* Watch out for newly created frames. */
4545 && f->output_data.x->hourglass_window)
4547 XUnmapWindow (FRAME_X_DISPLAY (f),
4548 f->output_data.x->hourglass_window);
4549 /* Sync here because XTread_socket looks at the
4550 hourglass_p flag that is reset to zero below. */
4551 XSync (FRAME_X_DISPLAY (f), False);
4552 f->output_data.x->hourglass_p = 0;
4556 hourglass_shown_p = 0;
4557 UNBLOCK_INPUT;
4563 /***********************************************************************
4564 Tool tips
4565 ***********************************************************************/
4567 static Lisp_Object x_create_tip_frame P_ ((struct x_display_info *,
4568 Lisp_Object, Lisp_Object));
4569 static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object,
4570 Lisp_Object, int, int, int *, int *));
4572 /* The frame of a currently visible tooltip. */
4574 Lisp_Object tip_frame;
4576 /* If non-nil, a timer started that hides the last tooltip when it
4577 fires. */
4579 Lisp_Object tip_timer;
4580 Window tip_window;
4582 /* If non-nil, a vector of 3 elements containing the last args
4583 with which x-show-tip was called. See there. */
4585 Lisp_Object last_show_tip_args;
4587 /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
4589 Lisp_Object Vx_max_tooltip_size;
4592 static Lisp_Object
4593 unwind_create_tip_frame (frame)
4594 Lisp_Object frame;
4596 Lisp_Object deleted;
4598 deleted = unwind_create_frame (frame);
4599 if (EQ (deleted, Qt))
4601 tip_window = None;
4602 tip_frame = Qnil;
4605 return deleted;
4609 /* Create a frame for a tooltip on the display described by DPYINFO.
4610 PARMS is a list of frame parameters. TEXT is the string to
4611 display in the tip frame. Value is the frame.
4613 Note that functions called here, esp. x_default_parameter can
4614 signal errors, for instance when a specified color name is
4615 undefined. We have to make sure that we're in a consistent state
4616 when this happens. */
4618 static Lisp_Object
4619 x_create_tip_frame (dpyinfo, parms, text)
4620 struct x_display_info *dpyinfo;
4621 Lisp_Object parms, text;
4623 struct frame *f;
4624 Lisp_Object frame, tem;
4625 Lisp_Object name;
4626 long window_prompting = 0;
4627 int width, height;
4628 int count = SPECPDL_INDEX ();
4629 struct gcpro gcpro1, gcpro2, gcpro3;
4630 int face_change_count_before = face_change_count;
4631 Lisp_Object buffer;
4632 struct buffer *old_buffer;
4634 check_x ();
4636 if (!dpyinfo->terminal->name)
4637 error ("Terminal is not live, can't create new frames on it");
4639 parms = Fcopy_alist (parms);
4641 /* Get the name of the frame to use for resource lookup. */
4642 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
4643 if (!STRINGP (name)
4644 && !EQ (name, Qunbound)
4645 && !NILP (name))
4646 error ("Invalid frame name--not a string or nil");
4648 frame = Qnil;
4649 GCPRO3 (parms, name, frame);
4650 f = make_frame (1);
4651 XSETFRAME (frame, f);
4653 buffer = Fget_buffer_create (build_string (" *tip*"));
4654 Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer, Qnil);
4655 old_buffer = current_buffer;
4656 set_buffer_internal_1 (XBUFFER (buffer));
4657 current_buffer->truncate_lines = Qnil;
4658 specbind (Qinhibit_read_only, Qt);
4659 specbind (Qinhibit_modification_hooks, Qt);
4660 Ferase_buffer ();
4661 Finsert (1, &text);
4662 set_buffer_internal_1 (old_buffer);
4664 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
4665 record_unwind_protect (unwind_create_tip_frame, frame);
4667 f->terminal = dpyinfo->terminal;
4668 f->terminal->reference_count++;
4670 /* By setting the output method, we're essentially saying that
4671 the frame is live, as per FRAME_LIVE_P. If we get a signal
4672 from this point on, x_destroy_window might screw up reference
4673 counts etc. */
4674 f->output_method = output_x_window;
4675 f->output_data.x = (struct x_output *) xmalloc (sizeof (struct x_output));
4676 bzero (f->output_data.x, sizeof (struct x_output));
4677 f->output_data.x->icon_bitmap = -1;
4678 FRAME_FONTSET (f) = -1;
4679 f->output_data.x->scroll_bar_foreground_pixel = -1;
4680 f->output_data.x->scroll_bar_background_pixel = -1;
4681 #ifdef USE_TOOLKIT_SCROLL_BARS
4682 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
4683 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
4684 #endif /* USE_TOOLKIT_SCROLL_BARS */
4685 f->icon_name = Qnil;
4686 FRAME_X_DISPLAY_INFO (f) = dpyinfo;
4687 #if GLYPH_DEBUG
4688 image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
4689 dpyinfo_refcount = dpyinfo->reference_count;
4690 #endif /* GLYPH_DEBUG */
4691 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
4692 f->output_data.x->explicit_parent = 0;
4694 /* These colors will be set anyway later, but it's important
4695 to get the color reference counts right, so initialize them! */
4697 Lisp_Object black;
4698 struct gcpro gcpro1;
4700 /* Function x_decode_color can signal an error. Make
4701 sure to initialize color slots so that we won't try
4702 to free colors we haven't allocated. */
4703 FRAME_FOREGROUND_PIXEL (f) = -1;
4704 FRAME_BACKGROUND_PIXEL (f) = -1;
4705 f->output_data.x->cursor_pixel = -1;
4706 f->output_data.x->cursor_foreground_pixel = -1;
4707 f->output_data.x->border_pixel = -1;
4708 f->output_data.x->mouse_pixel = -1;
4710 black = build_string ("black");
4711 GCPRO1 (black);
4712 FRAME_FOREGROUND_PIXEL (f)
4713 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4714 FRAME_BACKGROUND_PIXEL (f)
4715 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4716 f->output_data.x->cursor_pixel
4717 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4718 f->output_data.x->cursor_foreground_pixel
4719 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4720 f->output_data.x->border_pixel
4721 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4722 f->output_data.x->mouse_pixel
4723 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4724 UNGCPRO;
4727 /* Set the name; the functions to which we pass f expect the name to
4728 be set. */
4729 if (EQ (name, Qunbound) || NILP (name))
4731 f->name = build_string (dpyinfo->x_id_name);
4732 f->explicit_name = 0;
4734 else
4736 f->name = name;
4737 f->explicit_name = 1;
4738 /* use the frame's title when getting resources for this frame. */
4739 specbind (Qx_resource_name, name);
4742 f->resx = dpyinfo->resx;
4743 f->resy = dpyinfo->resy;
4745 register_font_driver (&xfont_driver, f);
4746 #ifdef HAVE_FREETYPE
4747 #ifdef HAVE_XFT
4748 register_font_driver (&xftfont_driver, f);
4749 #else /* not HAVE_XFT */
4750 register_font_driver (&ftxfont_driver, f);
4751 #endif /* not HAVE_XFT */
4752 #endif /* HAVE_FREETYPE */
4754 x_default_parameter (f, parms, Qfont_backend, Qnil,
4755 "fontBackend", "FontBackend", RES_TYPE_STRING);
4757 /* Extract the window parameters from the supplied values that are
4758 needed to determine window geometry. */
4759 x_default_font_parameter (f, parms);
4761 x_default_parameter (f, parms, Qborder_width, make_number (2),
4762 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
4764 /* This defaults to 2 in order to match xterm. We recognize either
4765 internalBorderWidth or internalBorder (which is what xterm calls
4766 it). */
4767 if (NILP (Fassq (Qinternal_border_width, parms)))
4769 Lisp_Object value;
4771 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
4772 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
4773 if (! EQ (value, Qunbound))
4774 parms = Fcons (Fcons (Qinternal_border_width, value),
4775 parms);
4778 x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
4779 "internalBorderWidth", "internalBorderWidth",
4780 RES_TYPE_NUMBER);
4782 /* Also do the stuff which must be set before the window exists. */
4783 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
4784 "foreground", "Foreground", RES_TYPE_STRING);
4785 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
4786 "background", "Background", RES_TYPE_STRING);
4787 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
4788 "pointerColor", "Foreground", RES_TYPE_STRING);
4789 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
4790 "cursorColor", "Foreground", RES_TYPE_STRING);
4791 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
4792 "borderColor", "BorderColor", RES_TYPE_STRING);
4794 /* Init faces before x_default_parameter is called for scroll-bar
4795 parameters because that function calls x_set_scroll_bar_width,
4796 which calls change_frame_size, which calls Fset_window_buffer,
4797 which runs hooks, which call Fvertical_motion. At the end, we
4798 end up in init_iterator with a null face cache, which should not
4799 happen. */
4800 init_frame_faces (f);
4802 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
4804 window_prompting = x_figure_window_size (f, parms, 0);
4807 XSetWindowAttributes attrs;
4808 unsigned long mask;
4810 BLOCK_INPUT;
4811 mask = CWBackPixel | CWOverrideRedirect | CWEventMask;
4812 if (DoesSaveUnders (dpyinfo->screen))
4813 mask |= CWSaveUnder;
4815 /* Window managers look at the override-redirect flag to determine
4816 whether or net to give windows a decoration (Xlib spec, chapter
4817 3.2.8). */
4818 attrs.override_redirect = True;
4819 attrs.save_under = True;
4820 attrs.background_pixel = FRAME_BACKGROUND_PIXEL (f);
4821 /* Arrange for getting MapNotify and UnmapNotify events. */
4822 attrs.event_mask = StructureNotifyMask;
4823 tip_window
4824 = FRAME_X_WINDOW (f)
4825 = XCreateWindow (FRAME_X_DISPLAY (f),
4826 FRAME_X_DISPLAY_INFO (f)->root_window,
4827 /* x, y, width, height */
4828 0, 0, 1, 1,
4829 /* Border. */
4830 f->border_width,
4831 CopyFromParent, InputOutput, CopyFromParent,
4832 mask, &attrs);
4833 UNBLOCK_INPUT;
4836 x_make_gc (f);
4838 x_default_parameter (f, parms, Qauto_raise, Qnil,
4839 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
4840 x_default_parameter (f, parms, Qauto_lower, Qnil,
4841 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
4842 x_default_parameter (f, parms, Qcursor_type, Qbox,
4843 "cursorType", "CursorType", RES_TYPE_SYMBOL);
4845 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
4846 Change will not be effected unless different from the current
4847 FRAME_LINES (f). */
4848 width = FRAME_COLS (f);
4849 height = FRAME_LINES (f);
4850 SET_FRAME_COLS (f, 0);
4851 FRAME_LINES (f) = 0;
4852 change_frame_size (f, height, width, 1, 0, 0);
4854 /* Add `tooltip' frame parameter's default value. */
4855 if (NILP (Fframe_parameter (frame, intern ("tooltip"))))
4856 Fmodify_frame_parameters (frame, Fcons (Fcons (intern ("tooltip"), Qt),
4857 Qnil));
4859 /* FIXME - can this be done in a similar way to normal frames?
4860 http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
4862 /* Set the `display-type' frame parameter before setting up faces. */
4864 Lisp_Object disptype;
4866 if (FRAME_X_DISPLAY_INFO (f)->n_planes == 1)
4867 disptype = intern ("mono");
4868 else if (FRAME_X_DISPLAY_INFO (f)->visual->class == GrayScale
4869 || FRAME_X_DISPLAY_INFO (f)->visual->class == StaticGray)
4870 disptype = intern ("grayscale");
4871 else
4872 disptype = intern ("color");
4874 if (NILP (Fframe_parameter (frame, Qdisplay_type)))
4875 Fmodify_frame_parameters (frame, Fcons (Fcons (Qdisplay_type, disptype),
4876 Qnil));
4879 /* Set up faces after all frame parameters are known. This call
4880 also merges in face attributes specified for new frames.
4882 Frame parameters may be changed if .Xdefaults contains
4883 specifications for the default font. For example, if there is an
4884 `Emacs.default.attributeBackground: pink', the `background-color'
4885 attribute of the frame get's set, which let's the internal border
4886 of the tooltip frame appear in pink. Prevent this. */
4888 Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
4890 /* Set tip_frame here, so that */
4891 tip_frame = frame;
4892 call2 (Qface_set_after_frame_default, frame, Qnil);
4894 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
4895 Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg),
4896 Qnil));
4899 f->no_split = 1;
4901 UNGCPRO;
4903 /* It is now ok to make the frame official even if we get an error
4904 below. And the frame needs to be on Vframe_list or making it
4905 visible won't work. */
4906 Vframe_list = Fcons (frame, Vframe_list);
4908 /* Now that the frame is official, it counts as a reference to
4909 its display. */
4910 FRAME_X_DISPLAY_INFO (f)->reference_count++;
4912 /* Setting attributes of faces of the tooltip frame from resources
4913 and similar will increment face_change_count, which leads to the
4914 clearing of all current matrices. Since this isn't necessary
4915 here, avoid it by resetting face_change_count to the value it
4916 had before we created the tip frame. */
4917 face_change_count = face_change_count_before;
4919 /* Discard the unwind_protect. */
4920 return unbind_to (count, frame);
4924 /* Compute where to display tip frame F. PARMS is the list of frame
4925 parameters for F. DX and DY are specified offsets from the current
4926 location of the mouse. WIDTH and HEIGHT are the width and height
4927 of the tooltip. Return coordinates relative to the root window of
4928 the display in *ROOT_X, and *ROOT_Y. */
4930 static void
4931 compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
4932 struct frame *f;
4933 Lisp_Object parms, dx, dy;
4934 int width, height;
4935 int *root_x, *root_y;
4937 Lisp_Object left, top;
4938 int win_x, win_y;
4939 Window root, child;
4940 unsigned pmask;
4942 /* User-specified position? */
4943 left = Fcdr (Fassq (Qleft, parms));
4944 top = Fcdr (Fassq (Qtop, parms));
4946 /* Move the tooltip window where the mouse pointer is. Resize and
4947 show it. */
4948 if (!INTEGERP (left) || !INTEGERP (top))
4950 BLOCK_INPUT;
4951 XQueryPointer (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
4952 &root, &child, root_x, root_y, &win_x, &win_y, &pmask);
4953 UNBLOCK_INPUT;
4956 if (INTEGERP (top))
4957 *root_y = XINT (top);
4958 else if (*root_y + XINT (dy) <= 0)
4959 *root_y = 0; /* Can happen for negative dy */
4960 else if (*root_y + XINT (dy) + height
4961 <= x_display_pixel_height (FRAME_X_DISPLAY_INFO (f)))
4962 /* It fits below the pointer */
4963 *root_y += XINT (dy);
4964 else if (height + XINT (dy) <= *root_y)
4965 /* It fits above the pointer. */
4966 *root_y -= height + XINT (dy);
4967 else
4968 /* Put it on the top. */
4969 *root_y = 0;
4971 if (INTEGERP (left))
4972 *root_x = XINT (left);
4973 else if (*root_x + XINT (dx) <= 0)
4974 *root_x = 0; /* Can happen for negative dx */
4975 else if (*root_x + XINT (dx) + width
4976 <= x_display_pixel_width (FRAME_X_DISPLAY_INFO (f)))
4977 /* It fits to the right of the pointer. */
4978 *root_x += XINT (dx);
4979 else if (width + XINT (dx) <= *root_x)
4980 /* It fits to the left of the pointer. */
4981 *root_x -= width + XINT (dx);
4982 else
4983 /* Put it left-justified on the screen--it ought to fit that way. */
4984 *root_x = 0;
4988 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
4989 doc: /* Show STRING in a "tooltip" window on frame FRAME.
4990 A tooltip window is a small X window displaying a string.
4992 This is an internal function; Lisp code should call `tooltip-show'.
4994 FRAME nil or omitted means use the selected frame.
4996 PARMS is an optional list of frame parameters which can be used to
4997 change the tooltip's appearance.
4999 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
5000 means use the default timeout of 5 seconds.
5002 If the list of frame parameters PARAMS contains a `left' parameters,
5003 the tooltip is displayed at that x-position. Otherwise it is
5004 displayed at the mouse position, with offset DX added (default is 5 if
5005 DX isn't specified). Likewise for the y-position; if a `top' frame
5006 parameter is specified, it determines the y-position of the tooltip
5007 window, otherwise it is displayed at the mouse position, with offset
5008 DY added (default is -10).
5010 A tooltip's maximum size is specified by `x-max-tooltip-size'.
5011 Text larger than the specified size is clipped. */)
5012 (string, frame, parms, timeout, dx, dy)
5013 Lisp_Object string, frame, parms, timeout, dx, dy;
5015 struct frame *f;
5016 struct window *w;
5017 int root_x, root_y;
5018 struct buffer *old_buffer;
5019 struct text_pos pos;
5020 int i, width, height;
5021 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
5022 int old_windows_or_buffers_changed = windows_or_buffers_changed;
5023 int count = SPECPDL_INDEX ();
5025 specbind (Qinhibit_redisplay, Qt);
5027 GCPRO4 (string, parms, frame, timeout);
5029 CHECK_STRING (string);
5030 if (SCHARS (string) == 0)
5031 string = make_unibyte_string (" ", 1);
5033 f = check_x_frame (frame);
5034 if (NILP (timeout))
5035 timeout = make_number (5);
5036 else
5037 CHECK_NATNUM (timeout);
5039 if (NILP (dx))
5040 dx = make_number (5);
5041 else
5042 CHECK_NUMBER (dx);
5044 if (NILP (dy))
5045 dy = make_number (-10);
5046 else
5047 CHECK_NUMBER (dy);
5049 if (NILP (last_show_tip_args))
5050 last_show_tip_args = Fmake_vector (make_number (3), Qnil);
5052 if (!NILP (tip_frame))
5054 Lisp_Object last_string = AREF (last_show_tip_args, 0);
5055 Lisp_Object last_frame = AREF (last_show_tip_args, 1);
5056 Lisp_Object last_parms = AREF (last_show_tip_args, 2);
5058 if (EQ (frame, last_frame)
5059 && !NILP (Fequal (last_string, string))
5060 && !NILP (Fequal (last_parms, parms)))
5062 struct frame *f = XFRAME (tip_frame);
5064 /* Only DX and DY have changed. */
5065 if (!NILP (tip_timer))
5067 Lisp_Object timer = tip_timer;
5068 tip_timer = Qnil;
5069 call1 (Qcancel_timer, timer);
5072 BLOCK_INPUT;
5073 compute_tip_xy (f, parms, dx, dy, FRAME_PIXEL_WIDTH (f),
5074 FRAME_PIXEL_HEIGHT (f), &root_x, &root_y);
5075 XMoveWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5076 root_x, root_y);
5077 UNBLOCK_INPUT;
5078 goto start_timer;
5082 /* Hide a previous tip, if any. */
5083 Fx_hide_tip ();
5085 ASET (last_show_tip_args, 0, string);
5086 ASET (last_show_tip_args, 1, frame);
5087 ASET (last_show_tip_args, 2, parms);
5089 /* Add default values to frame parameters. */
5090 if (NILP (Fassq (Qname, parms)))
5091 parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
5092 if (NILP (Fassq (Qinternal_border_width, parms)))
5093 parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
5094 if (NILP (Fassq (Qborder_width, parms)))
5095 parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
5096 if (NILP (Fassq (Qborder_color, parms)))
5097 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
5098 if (NILP (Fassq (Qbackground_color, parms)))
5099 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
5100 parms);
5102 /* Create a frame for the tooltip, and record it in the global
5103 variable tip_frame. */
5104 frame = x_create_tip_frame (FRAME_X_DISPLAY_INFO (f), parms, string);
5105 f = XFRAME (frame);
5107 /* Set up the frame's root window. */
5108 w = XWINDOW (FRAME_ROOT_WINDOW (f));
5109 w->left_col = w->top_line = make_number (0);
5111 if (CONSP (Vx_max_tooltip_size)
5112 && INTEGERP (XCAR (Vx_max_tooltip_size))
5113 && XINT (XCAR (Vx_max_tooltip_size)) > 0
5114 && INTEGERP (XCDR (Vx_max_tooltip_size))
5115 && XINT (XCDR (Vx_max_tooltip_size)) > 0)
5117 w->total_cols = XCAR (Vx_max_tooltip_size);
5118 w->total_lines = XCDR (Vx_max_tooltip_size);
5120 else
5122 w->total_cols = make_number (80);
5123 w->total_lines = make_number (40);
5126 FRAME_TOTAL_COLS (f) = XINT (w->total_cols);
5127 adjust_glyphs (f);
5128 w->pseudo_window_p = 1;
5130 /* Display the tooltip text in a temporary buffer. */
5131 old_buffer = current_buffer;
5132 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer));
5133 current_buffer->truncate_lines = Qnil;
5134 clear_glyph_matrix (w->desired_matrix);
5135 clear_glyph_matrix (w->current_matrix);
5136 SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
5137 try_window (FRAME_ROOT_WINDOW (f), pos, 0);
5139 /* Compute width and height of the tooltip. */
5140 width = height = 0;
5141 for (i = 0; i < w->desired_matrix->nrows; ++i)
5143 struct glyph_row *row = &w->desired_matrix->rows[i];
5144 struct glyph *last;
5145 int row_width;
5147 /* Stop at the first empty row at the end. */
5148 if (!row->enabled_p || !row->displays_text_p)
5149 break;
5151 /* Let the row go over the full width of the frame. */
5152 row->full_width_p = 1;
5154 /* There's a glyph at the end of rows that is used to place
5155 the cursor there. Don't include the width of this glyph. */
5156 if (row->used[TEXT_AREA])
5158 last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
5159 row_width = row->pixel_width - last->pixel_width;
5161 else
5162 row_width = row->pixel_width;
5164 height += row->height;
5165 width = max (width, row_width);
5168 /* Add the frame's internal border to the width and height the X
5169 window should have. */
5170 height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5171 width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5173 /* Move the tooltip window where the mouse pointer is. Resize and
5174 show it. */
5175 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
5177 BLOCK_INPUT;
5178 XMoveResizeWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5179 root_x, root_y, width, height);
5180 XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
5181 UNBLOCK_INPUT;
5183 /* Draw into the window. */
5184 w->must_be_updated_p = 1;
5185 update_single_window (w, 1);
5187 /* Restore original current buffer. */
5188 set_buffer_internal_1 (old_buffer);
5189 windows_or_buffers_changed = old_windows_or_buffers_changed;
5191 start_timer:
5192 /* Let the tip disappear after timeout seconds. */
5193 tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
5194 intern ("x-hide-tip"));
5196 UNGCPRO;
5197 return unbind_to (count, Qnil);
5201 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
5202 doc: /* Hide the current tooltip window, if there is any.
5203 Value is t if tooltip was open, nil otherwise. */)
5206 int count;
5207 Lisp_Object deleted, frame, timer;
5208 struct gcpro gcpro1, gcpro2;
5210 /* Return quickly if nothing to do. */
5211 if (NILP (tip_timer) && NILP (tip_frame))
5212 return Qnil;
5214 frame = tip_frame;
5215 timer = tip_timer;
5216 GCPRO2 (frame, timer);
5217 tip_frame = tip_timer = deleted = Qnil;
5219 count = SPECPDL_INDEX ();
5220 specbind (Qinhibit_redisplay, Qt);
5221 specbind (Qinhibit_quit, Qt);
5223 if (!NILP (timer))
5224 call1 (Qcancel_timer, timer);
5226 if (FRAMEP (frame))
5228 delete_frame (frame, Qnil);
5229 deleted = Qt;
5231 #ifdef USE_LUCID
5232 /* Bloodcurdling hack alert: The Lucid menu bar widget's
5233 redisplay procedure is not called when a tip frame over menu
5234 items is unmapped. Redisplay the menu manually... */
5236 struct frame *f = SELECTED_FRAME ();
5237 Widget w = f->output_data.x->menubar_widget;
5238 extern void xlwmenu_redisplay P_ ((Widget));
5240 if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f)->screen)
5241 && w != NULL)
5243 BLOCK_INPUT;
5244 xlwmenu_redisplay (w);
5245 UNBLOCK_INPUT;
5248 #endif /* USE_LUCID */
5251 UNGCPRO;
5252 return unbind_to (count, deleted);
5257 /***********************************************************************
5258 File selection dialog
5259 ***********************************************************************/
5261 DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog,
5262 Sx_uses_old_gtk_dialog,
5263 0, 0, 0,
5264 doc: /* Return t if the old Gtk+ file selection dialog is used. */)
5267 #ifdef USE_GTK
5268 extern int use_dialog_box;
5269 extern int use_file_dialog;
5271 if (use_dialog_box
5272 && use_file_dialog
5273 && have_menus_p ()
5274 && xg_uses_old_file_dialog ())
5275 return Qt;
5276 #endif
5277 return Qnil;
5281 #ifdef USE_MOTIF
5282 /* Callback for "OK" and "Cancel" on file selection dialog. */
5284 static void
5285 file_dialog_cb (widget, client_data, call_data)
5286 Widget widget;
5287 XtPointer call_data, client_data;
5289 int *result = (int *) client_data;
5290 XmAnyCallbackStruct *cb = (XmAnyCallbackStruct *) call_data;
5291 *result = cb->reason;
5295 /* Callback for unmapping a file selection dialog. This is used to
5296 capture the case where a dialog is closed via a window manager's
5297 closer button, for example. Using a XmNdestroyCallback didn't work
5298 in this case. */
5300 static void
5301 file_dialog_unmap_cb (widget, client_data, call_data)
5302 Widget widget;
5303 XtPointer call_data, client_data;
5305 int *result = (int *) client_data;
5306 *result = XmCR_CANCEL;
5309 static Lisp_Object
5310 clean_up_file_dialog (arg)
5311 Lisp_Object arg;
5313 struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
5314 Widget dialog = (Widget) p->pointer;
5316 /* Clean up. */
5317 BLOCK_INPUT;
5318 XtUnmanageChild (dialog);
5319 XtDestroyWidget (dialog);
5320 x_menu_set_in_use (0);
5321 UNBLOCK_INPUT;
5323 return Qnil;
5327 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5328 doc: /* Read file name, prompting with PROMPT in directory DIR.
5329 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5330 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5331 or directory must exist. ONLY-DIR-P is ignored." */)
5332 (prompt, dir, default_filename, mustmatch, only_dir_p)
5333 Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
5335 int result;
5336 struct frame *f = SELECTED_FRAME ();
5337 Lisp_Object file = Qnil;
5338 Lisp_Object decoded_file;
5339 Widget dialog, text, help;
5340 Arg al[10];
5341 int ac = 0;
5342 extern XtAppContext Xt_app_con;
5343 XmString dir_xmstring, pattern_xmstring;
5344 int count = SPECPDL_INDEX ();
5345 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5347 check_x ();
5349 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5351 if (popup_activated ())
5352 error ("Trying to use a menu from within a menu-entry");
5354 CHECK_STRING (prompt);
5355 CHECK_STRING (dir);
5357 /* Prevent redisplay. */
5358 specbind (Qinhibit_redisplay, Qt);
5360 BLOCK_INPUT;
5362 /* Create the dialog with PROMPT as title, using DIR as initial
5363 directory and using "*" as pattern. */
5364 dir = Fexpand_file_name (dir, Qnil);
5365 dir_xmstring = XmStringCreateLocalized (SDATA (dir));
5366 pattern_xmstring = XmStringCreateLocalized ("*");
5368 XtSetArg (al[ac], XmNtitle, SDATA (prompt)); ++ac;
5369 XtSetArg (al[ac], XmNdirectory, dir_xmstring); ++ac;
5370 XtSetArg (al[ac], XmNpattern, pattern_xmstring); ++ac;
5371 XtSetArg (al[ac], XmNresizePolicy, XmRESIZE_GROW); ++ac;
5372 XtSetArg (al[ac], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); ++ac;
5373 dialog = XmCreateFileSelectionDialog (f->output_data.x->widget,
5374 "fsb", al, ac);
5375 XmStringFree (dir_xmstring);
5376 XmStringFree (pattern_xmstring);
5378 /* Add callbacks for OK and Cancel. */
5379 XtAddCallback (dialog, XmNokCallback, file_dialog_cb,
5380 (XtPointer) &result);
5381 XtAddCallback (dialog, XmNcancelCallback, file_dialog_cb,
5382 (XtPointer) &result);
5383 XtAddCallback (dialog, XmNunmapCallback, file_dialog_unmap_cb,
5384 (XtPointer) &result);
5386 /* Remove the help button since we can't display help. */
5387 help = XmFileSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON);
5388 XtUnmanageChild (help);
5390 /* Mark OK button as default. */
5391 XtVaSetValues (XmFileSelectionBoxGetChild (dialog, XmDIALOG_OK_BUTTON),
5392 XmNshowAsDefault, True, NULL);
5394 /* If MUSTMATCH is non-nil, disable the file entry field of the
5395 dialog, so that the user must select a file from the files list
5396 box. We can't remove it because we wouldn't have a way to get at
5397 the result file name, then. */
5398 text = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5399 if (!NILP (mustmatch))
5401 Widget label;
5402 label = XmFileSelectionBoxGetChild (dialog, XmDIALOG_SELECTION_LABEL);
5403 XtSetSensitive (text, False);
5404 XtSetSensitive (label, False);
5407 /* Manage the dialog, so that list boxes get filled. */
5408 XtManageChild (dialog);
5410 if (STRINGP (default_filename))
5412 XmString default_xmstring;
5413 Widget wtext = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5414 Widget list = XmFileSelectionBoxGetChild (dialog, XmDIALOG_LIST);
5416 XmTextPosition last_pos = XmTextFieldGetLastPosition (wtext);
5417 XmTextFieldReplace (wtext, 0, last_pos,
5418 (SDATA (Ffile_name_nondirectory (default_filename))));
5420 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
5421 must include the path for this to work. */
5423 default_xmstring = XmStringCreateLocalized (SDATA (default_filename));
5425 if (XmListItemExists (list, default_xmstring))
5427 int item_pos = XmListItemPos (list, default_xmstring);
5428 /* Select the item and scroll it into view. */
5429 XmListSelectPos (list, item_pos, True);
5430 XmListSetPos (list, item_pos);
5433 XmStringFree (default_xmstring);
5436 record_unwind_protect (clean_up_file_dialog, make_save_value (dialog, 0));
5438 /* Process events until the user presses Cancel or OK. */
5439 x_menu_set_in_use (1);
5440 result = 0;
5441 while (result == 0)
5443 XEvent event;
5444 x_menu_wait_for_event (0);
5445 XtAppNextEvent (Xt_app_con, &event);
5446 if (event.type == KeyPress
5447 && FRAME_X_DISPLAY (f) == event.xkey.display)
5449 KeySym keysym = XLookupKeysym (&event.xkey, 0);
5451 /* Pop down on C-g. */
5452 if (keysym == XK_g && (event.xkey.state & ControlMask) != 0)
5453 XtUnmanageChild (dialog);
5456 (void) x_dispatch_event (&event, FRAME_X_DISPLAY (f));
5459 /* Get the result. */
5460 if (result == XmCR_OK)
5462 XmString text;
5463 String data;
5465 XtVaGetValues (dialog, XmNtextString, &text, NULL);
5466 XmStringGetLtoR (text, XmFONTLIST_DEFAULT_TAG, &data);
5467 XmStringFree (text);
5468 file = build_string (data);
5469 XtFree (data);
5471 else
5472 file = Qnil;
5474 UNBLOCK_INPUT;
5475 UNGCPRO;
5477 /* Make "Cancel" equivalent to C-g. */
5478 if (NILP (file))
5479 Fsignal (Qquit, Qnil);
5481 decoded_file = DECODE_FILE (file);
5483 return unbind_to (count, decoded_file);
5486 #endif /* USE_MOTIF */
5488 #ifdef USE_GTK
5490 static Lisp_Object
5491 clean_up_dialog (arg)
5492 Lisp_Object arg;
5494 x_menu_set_in_use (0);
5496 return Qnil;
5499 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5500 doc: /* Read file name, prompting with PROMPT in directory DIR.
5501 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5502 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5503 or directory must exist. If ONLY-DIR-P is non-nil, the user can only select
5504 directories. */)
5505 (prompt, dir, default_filename, mustmatch, only_dir_p)
5506 Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
5508 FRAME_PTR f = SELECTED_FRAME ();
5509 char *fn;
5510 Lisp_Object file = Qnil;
5511 Lisp_Object decoded_file;
5512 int count = SPECPDL_INDEX ();
5513 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5514 char *cdef_file;
5516 check_x ();
5518 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5520 if (popup_activated ())
5521 error ("Trying to use a menu from within a menu-entry");
5523 CHECK_STRING (prompt);
5524 CHECK_STRING (dir);
5526 /* Prevent redisplay. */
5527 specbind (Qinhibit_redisplay, Qt);
5528 record_unwind_protect (clean_up_dialog, Qnil);
5530 BLOCK_INPUT;
5532 if (STRINGP (default_filename))
5533 cdef_file = SDATA (default_filename);
5534 else
5535 cdef_file = SDATA (dir);
5537 fn = xg_get_file_name (f, SDATA (prompt), cdef_file,
5538 ! NILP (mustmatch),
5539 ! NILP (only_dir_p));
5541 if (fn)
5543 file = build_string (fn);
5544 xfree (fn);
5547 UNBLOCK_INPUT;
5548 UNGCPRO;
5550 /* Make "Cancel" equivalent to C-g. */
5551 if (NILP (file))
5552 Fsignal (Qquit, Qnil);
5554 decoded_file = DECODE_FILE (file);
5556 return unbind_to (count, decoded_file);
5560 #ifdef HAVE_FREETYPE
5562 DEFUN ("x-select-font", Fx_select_font, Sx_select_font, 0, 2, 0,
5563 doc: /* Read a font name using a GTK font selection dialog.
5564 Return a GTK-style font string corresponding to the selection.
5566 If FRAME is omitted or nil, it defaults to the selected frame. */)
5567 (frame, ignored)
5568 Lisp_Object frame, ignored;
5570 FRAME_PTR f = check_x_frame (frame);
5571 char *name;
5572 Lisp_Object default_font, font = Qnil;
5573 Lisp_Object font_param;
5574 char *default_name = NULL;
5575 struct gcpro gcpro1;
5576 int count = SPECPDL_INDEX ();
5578 check_x ();
5580 if (popup_activated ())
5581 error ("Trying to use a menu from within a menu-entry");
5583 /* Prevent redisplay. */
5584 specbind (Qinhibit_redisplay, Qt);
5585 record_unwind_protect (clean_up_dialog, Qnil);
5587 BLOCK_INPUT;
5589 GCPRO1(font_param);
5590 font_param = Fframe_parameter (frame, Qfont_param);
5592 if (x_last_font_name != NULL)
5593 default_name = x_last_font_name;
5594 else if (STRINGP (font_param))
5595 default_name = SDATA (font_param);
5596 else if (FONTP (default_font))
5598 XSETFONT (default_font, FRAME_FONT (f));
5599 default_name = alloca (256);
5600 if (font_unparse_gtkname (default_font, f, default_name, 256) < 0)
5601 default_name = NULL;
5604 name = xg_get_font_name (f, default_name);
5606 if (name)
5608 font = build_string (name);
5609 g_free (x_last_font_name);
5610 x_last_font_name = name;
5613 UNBLOCK_INPUT;
5615 if (NILP (font))
5616 Fsignal (Qquit, Qnil);
5618 return unbind_to (count, font);
5620 #endif /* HAVE_FREETYPE */
5622 #endif /* USE_GTK */
5625 /***********************************************************************
5626 Keyboard
5627 ***********************************************************************/
5629 #ifdef HAVE_XKBGETKEYBOARD
5630 #include <X11/XKBlib.h>
5631 #include <X11/keysym.h>
5632 #endif
5634 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p,
5635 Sx_backspace_delete_keys_p, 0, 1, 0,
5636 doc: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
5637 FRAME nil means use the selected frame.
5638 Value is t if we know that both keys are present, and are mapped to the
5639 usual X keysyms. Value is `lambda' if we cannot determine if both keys are
5640 present and mapped to the usual X keysyms. */)
5641 (frame)
5642 Lisp_Object frame;
5644 #ifdef HAVE_XKBGETKEYBOARD
5645 XkbDescPtr kb;
5646 struct frame *f = check_x_frame (frame);
5647 Display *dpy = FRAME_X_DISPLAY (f);
5648 Lisp_Object have_keys;
5649 int major, minor, op, event, error;
5651 BLOCK_INPUT;
5653 /* Check library version in case we're dynamically linked. */
5654 major = XkbMajorVersion;
5655 minor = XkbMinorVersion;
5656 if (!XkbLibraryVersion (&major, &minor))
5658 UNBLOCK_INPUT;
5659 return Qlambda;
5662 /* Check that the server supports XKB. */
5663 major = XkbMajorVersion;
5664 minor = XkbMinorVersion;
5665 if (!XkbQueryExtension (dpy, &op, &event, &error, &major, &minor))
5667 UNBLOCK_INPUT;
5668 return Qlambda;
5671 /* In this code we check that the keyboard has physical keys with names
5672 that start with BKSP (Backspace) and DELE (Delete), and that they
5673 generate keysym XK_BackSpace and XK_Delete respectively.
5674 This function is used to test if normal-erase-is-backspace should be
5675 turned on.
5676 An alternative approach would be to just check if XK_BackSpace and
5677 XK_Delete are mapped to any key. But if any of those are mapped to
5678 some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the
5679 user doesn't know about it, it is better to return false here.
5680 It is more obvious to the user what to do if she/he has two keys
5681 clearly marked with names/symbols and one key does something not
5682 expected (i.e. she/he then tries the other).
5683 The cases where Backspace/Delete is mapped to some other key combination
5684 are rare, and in those cases, normal-erase-is-backspace can be turned on
5685 manually. */
5687 have_keys = Qnil;
5688 kb = XkbGetMap (dpy, XkbAllMapComponentsMask, XkbUseCoreKbd);
5689 if (kb)
5691 int delete_keycode = 0, backspace_keycode = 0, i;
5693 if (XkbGetNames (dpy, XkbAllNamesMask, kb) == Success)
5695 for (i = kb->min_key_code;
5696 (i < kb->max_key_code
5697 && (delete_keycode == 0 || backspace_keycode == 0));
5698 ++i)
5700 /* The XKB symbolic key names can be seen most easily in
5701 the PS file generated by `xkbprint -label name
5702 $DISPLAY'. */
5703 if (bcmp ("DELE", kb->names->keys[i].name, 4) == 0)
5704 delete_keycode = i;
5705 else if (bcmp ("BKSP", kb->names->keys[i].name, 4) == 0)
5706 backspace_keycode = i;
5709 XkbFreeNames (kb, 0, True);
5712 XkbFreeClientMap (kb, 0, True);
5714 if (delete_keycode
5715 && backspace_keycode
5716 && XKeysymToKeycode (dpy, XK_Delete) == delete_keycode
5717 && XKeysymToKeycode (dpy, XK_BackSpace) == backspace_keycode)
5718 have_keys = Qt;
5720 UNBLOCK_INPUT;
5721 return have_keys;
5722 #else /* not HAVE_XKBGETKEYBOARD */
5723 return Qlambda;
5724 #endif /* not HAVE_XKBGETKEYBOARD */
5729 /***********************************************************************
5730 Initialization
5731 ***********************************************************************/
5733 /* Keep this list in the same order as frame_parms in frame.c.
5734 Use 0 for unsupported frame parameters. */
5736 frame_parm_handler x_frame_parm_handlers[] =
5738 x_set_autoraise,
5739 x_set_autolower,
5740 x_set_background_color,
5741 x_set_border_color,
5742 x_set_border_width,
5743 x_set_cursor_color,
5744 x_set_cursor_type,
5745 x_set_font,
5746 x_set_foreground_color,
5747 x_set_icon_name,
5748 x_set_icon_type,
5749 x_set_internal_border_width,
5750 x_set_menu_bar_lines,
5751 x_set_mouse_color,
5752 x_explicitly_set_name,
5753 x_set_scroll_bar_width,
5754 x_set_title,
5755 x_set_unsplittable,
5756 x_set_vertical_scroll_bars,
5757 x_set_visibility,
5758 x_set_tool_bar_lines,
5759 x_set_scroll_bar_foreground,
5760 x_set_scroll_bar_background,
5761 x_set_screen_gamma,
5762 x_set_line_spacing,
5763 x_set_fringe_width,
5764 x_set_fringe_width,
5765 x_set_wait_for_wm,
5766 x_set_fullscreen,
5767 x_set_font_backend,
5768 x_set_alpha,
5769 x_set_sticky,
5772 void
5773 syms_of_xfns ()
5775 /* This is zero if not using X windows. */
5776 x_in_use = 0;
5778 /* The section below is built by the lisp expression at the top of the file,
5779 just above where these variables are declared. */
5780 /*&&& init symbols here &&&*/
5781 Qnone = intern_c_string ("none");
5782 staticpro (&Qnone);
5783 Qsuppress_icon = intern_c_string ("suppress-icon");
5784 staticpro (&Qsuppress_icon);
5785 Qundefined_color = intern_c_string ("undefined-color");
5786 staticpro (&Qundefined_color);
5787 Qcompound_text = intern_c_string ("compound-text");
5788 staticpro (&Qcompound_text);
5789 Qcancel_timer = intern_c_string ("cancel-timer");
5790 staticpro (&Qcancel_timer);
5791 Qfont_param = intern_c_string ("font-parameter");
5792 staticpro (&Qfont_param);
5793 /* This is the end of symbol initialization. */
5795 /* Text property `display' should be nonsticky by default. */
5796 Vtext_property_default_nonsticky
5797 = Fcons (Fcons (Qdisplay, Qt), Vtext_property_default_nonsticky);
5800 Fput (Qundefined_color, Qerror_conditions,
5801 pure_cons (Qundefined_color, pure_cons (Qerror, Qnil)));
5802 Fput (Qundefined_color, Qerror_message,
5803 make_pure_c_string ("Undefined color"));
5805 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
5806 doc: /* The shape of the pointer when over text.
5807 Changing the value does not affect existing frames
5808 unless you set the mouse color. */);
5809 Vx_pointer_shape = Qnil;
5811 #if 0 /* This doesn't really do anything. */
5812 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape,
5813 doc: /* The shape of the pointer when not over text.
5814 This variable takes effect when you create a new frame
5815 or when you set the mouse color. */);
5816 #endif
5817 Vx_nontext_pointer_shape = Qnil;
5819 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape,
5820 doc: /* The shape of the pointer when Emacs is busy.
5821 This variable takes effect when you create a new frame
5822 or when you set the mouse color. */);
5823 Vx_hourglass_pointer_shape = Qnil;
5825 #if 0 /* This doesn't really do anything. */
5826 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape,
5827 doc: /* The shape of the pointer when over the mode line.
5828 This variable takes effect when you create a new frame
5829 or when you set the mouse color. */);
5830 #endif
5831 Vx_mode_pointer_shape = Qnil;
5833 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
5834 &Vx_sensitive_text_pointer_shape,
5835 doc: /* The shape of the pointer when over mouse-sensitive text.
5836 This variable takes effect when you create a new frame
5837 or when you set the mouse color. */);
5838 Vx_sensitive_text_pointer_shape = Qnil;
5840 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
5841 &Vx_window_horizontal_drag_shape,
5842 doc: /* Pointer shape to use for indicating a window can be dragged horizontally.
5843 This variable takes effect when you create a new frame
5844 or when you set the mouse color. */);
5845 Vx_window_horizontal_drag_shape = Qnil;
5847 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel,
5848 doc: /* A string indicating the foreground color of the cursor box. */);
5849 Vx_cursor_fore_pixel = Qnil;
5851 DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size,
5852 doc: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).
5853 Text larger than this is clipped. */);
5854 Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
5856 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
5857 doc: /* Non-nil if no X window manager is in use.
5858 Emacs doesn't try to figure this out; this is always nil
5859 unless you set it to something else. */);
5860 /* We don't have any way to find this out, so set it to nil
5861 and maybe the user would like to set it to t. */
5862 Vx_no_window_manager = Qnil;
5864 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
5865 &Vx_pixel_size_width_font_regexp,
5866 doc: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
5868 Since Emacs gets width of a font matching with this regexp from
5869 PIXEL_SIZE field of the name, font finding mechanism gets faster for
5870 such a font. This is especially effective for such large fonts as
5871 Chinese, Japanese, and Korean. */);
5872 Vx_pixel_size_width_font_regexp = Qnil;
5874 /* This is not ifdef:ed, so other builds than GTK can customize it. */
5875 DEFVAR_BOOL ("x-gtk-use-old-file-dialog", &x_gtk_use_old_file_dialog,
5876 doc: /* *Non-nil means prompt with the old GTK file selection dialog.
5877 If nil or if the file selection dialog is not available, the new GTK file
5878 chooser is used instead. To turn off all file dialogs set the
5879 variable `use-file-dialog'. */);
5880 x_gtk_use_old_file_dialog = 0;
5882 DEFVAR_BOOL ("x-gtk-show-hidden-files", &x_gtk_show_hidden_files,
5883 doc: /* *If non-nil, the GTK file chooser will by default show hidden files.
5884 Note that this is just the default, there is a toggle button on the file
5885 chooser to show or not show hidden files on a case by case basis. */);
5886 x_gtk_show_hidden_files = 0;
5888 DEFVAR_BOOL ("x-gtk-file-dialog-help-text", &x_gtk_file_dialog_help_text,
5889 doc: /* *If non-nil, the GTK file chooser will show additional help text.
5890 If more space for files in the file chooser dialog is wanted, set this to nil
5891 to turn the additional text off. */);
5892 x_gtk_file_dialog_help_text = 1;
5894 DEFVAR_BOOL ("x-gtk-whole-detached-tool-bar", &x_gtk_whole_detached_tool_bar,
5895 doc: /* *If non-nil, a detached tool bar is shown in full.
5896 The default is to just show an arrow and pressing on that arrow shows
5897 the tool bar buttons. */);
5898 x_gtk_whole_detached_tool_bar = 0;
5900 Fprovide (intern_c_string ("x"), Qnil);
5902 #ifdef USE_X_TOOLKIT
5903 Fprovide (intern_c_string ("x-toolkit"), Qnil);
5904 #ifdef USE_MOTIF
5905 Fprovide (intern_c_string ("motif"), Qnil);
5907 DEFVAR_LISP ("motif-version-string", &Vmotif_version_string,
5908 doc: /* Version info for LessTif/Motif. */);
5909 Vmotif_version_string = build_string (XmVERSION_STRING);
5910 #endif /* USE_MOTIF */
5911 #endif /* USE_X_TOOLKIT */
5913 #ifdef USE_GTK
5914 /* Provide x-toolkit also for GTK. Internally GTK does not use Xt so it
5915 is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
5916 But for a user it is a toolkit for X, and indeed, configure
5917 accepts --with-x-toolkit=gtk. */
5918 Fprovide (intern_c_string ("x-toolkit"), Qnil);
5919 Fprovide (intern_c_string ("gtk"), Qnil);
5921 DEFVAR_LISP ("gtk-version-string", &Vgtk_version_string,
5922 doc: /* Version info for GTK+. */);
5924 char gtk_version[40];
5925 g_snprintf (gtk_version, sizeof (gtk_version), "%u.%u.%u",
5926 GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
5927 Vgtk_version_string = make_pure_string (gtk_version, strlen (gtk_version), strlen (gtk_version), 0);
5929 #endif /* USE_GTK */
5931 /* X window properties. */
5932 defsubr (&Sx_change_window_property);
5933 defsubr (&Sx_delete_window_property);
5934 defsubr (&Sx_window_property);
5936 defsubr (&Sxw_display_color_p);
5937 defsubr (&Sx_display_grayscale_p);
5938 defsubr (&Sxw_color_defined_p);
5939 defsubr (&Sxw_color_values);
5940 defsubr (&Sx_server_max_request_size);
5941 defsubr (&Sx_server_vendor);
5942 defsubr (&Sx_server_version);
5943 defsubr (&Sx_display_pixel_width);
5944 defsubr (&Sx_display_pixel_height);
5945 defsubr (&Sx_display_mm_width);
5946 defsubr (&Sx_display_mm_height);
5947 defsubr (&Sx_display_screens);
5948 defsubr (&Sx_display_planes);
5949 defsubr (&Sx_display_color_cells);
5950 defsubr (&Sx_display_visual_class);
5951 defsubr (&Sx_display_backing_store);
5952 defsubr (&Sx_display_save_under);
5953 defsubr (&Sx_wm_set_size_hint);
5954 defsubr (&Sx_create_frame);
5955 defsubr (&Sx_open_connection);
5956 defsubr (&Sx_close_connection);
5957 defsubr (&Sx_display_list);
5958 defsubr (&Sx_synchronize);
5959 defsubr (&Sx_focus_frame);
5960 defsubr (&Sx_backspace_delete_keys_p);
5962 /* Setting callback functions for fontset handler. */
5963 check_window_system_func = check_x;
5965 defsubr (&Sx_show_tip);
5966 defsubr (&Sx_hide_tip);
5967 tip_timer = Qnil;
5968 staticpro (&tip_timer);
5969 tip_frame = Qnil;
5970 staticpro (&tip_frame);
5972 last_show_tip_args = Qnil;
5973 staticpro (&last_show_tip_args);
5975 defsubr (&Sx_uses_old_gtk_dialog);
5976 #if defined (USE_MOTIF) || defined (USE_GTK)
5977 defsubr (&Sx_file_dialog);
5978 #endif
5980 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
5981 defsubr (&Sx_select_font);
5982 x_last_font_name = NULL;
5983 #endif
5986 #endif /* HAVE_X_WINDOWS */
5988 /* arch-tag: 55040d02-5485-4d58-8b22-95a7a05f3288
5989 (do not change this comment) */