(parse_menu_item): Don't use cachelist, even under NS.
[emacs.git] / src / xfns.c
blob6aeb04ba1f86e7936106c852461ff418f32a4c8a
1 /* Functions for the X window system.
2 Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
4 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 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>
25 #ifdef HAVE_UNISTD_H
26 #include <unistd.h>
27 #endif
29 /* This makes the fields of a Display accessible, in Xlib header files. */
31 #define XLIB_ILLEGAL_ACCESS
33 #include "lisp.h"
34 #include "xterm.h"
35 #include "frame.h"
36 #include "window.h"
37 #include "buffer.h"
38 #include "intervals.h"
39 #include "dispextern.h"
40 #include "keyboard.h"
41 #include "blockinput.h"
42 #include <epaths.h>
43 #include "character.h"
44 #include "charset.h"
45 #include "coding.h"
46 #include "fontset.h"
47 #include "systime.h"
48 #include "termhooks.h"
49 #include "atimer.h"
50 #include "termchar.h"
51 #include "font.h"
53 #ifdef HAVE_X_WINDOWS
55 #include <ctype.h>
56 #include <sys/types.h>
57 #include <sys/stat.h>
59 #ifndef VMS
60 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */
61 #include "bitmaps/gray.xbm"
62 #else
63 #include <X11/bitmaps/gray>
64 #endif
65 #else
66 #include "[.bitmaps]gray.xbm"
67 #endif
69 #ifdef USE_GTK
70 #include "gtkutil.h"
71 #endif
73 #ifdef USE_X_TOOLKIT
74 #include <X11/Shell.h>
76 #ifndef USE_MOTIF
77 #ifdef HAVE_XAW3D
78 #include <X11/Xaw3d/Paned.h>
79 #include <X11/Xaw3d/Label.h>
80 #else /* !HAVE_XAW3D */
81 #include <X11/Xaw/Paned.h>
82 #include <X11/Xaw/Label.h>
83 #endif /* HAVE_XAW3D */
84 #endif /* USE_MOTIF */
86 #ifdef USG
87 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
88 #include <X11/Xos.h>
89 #define USG
90 #else
91 #include <X11/Xos.h>
92 #endif
94 #include "widget.h"
96 #include "../lwlib/lwlib.h"
98 #ifdef USE_MOTIF
99 #include <Xm/Xm.h>
100 #include <Xm/DialogS.h>
101 #include <Xm/FileSB.h>
102 #endif
104 /* Do the EDITRES protocol if running X11R5
105 Exception: HP-UX (at least version A.09.05) has X11R5 without EditRes */
107 #if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES)
108 #define HACK_EDITRES
109 extern void _XEditResCheckMessages ();
110 #endif /* R5 + Athena */
112 /* Unique id counter for widgets created by the Lucid Widget Library. */
114 extern LWLIB_ID widget_id_tick;
116 #ifdef USE_LUCID
117 /* This is part of a kludge--see lwlib/xlwmenu.c. */
118 extern XFontStruct *xlwmenu_default_font;
119 #endif
121 extern void free_frame_menubar ();
122 extern double atof ();
124 #ifdef USE_MOTIF
126 /* LessTif/Motif version info. */
128 static Lisp_Object Vmotif_version_string;
130 #endif /* USE_MOTIF */
132 #endif /* USE_X_TOOLKIT */
134 #ifdef USE_GTK
136 /* GTK+ version info */
138 static Lisp_Object Vgtk_version_string;
140 #endif /* USE_GTK */
142 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
144 /* The gray bitmap `bitmaps/gray'. This is done because xterm.c uses
145 it, and including `bitmaps/gray' more than once is a problem when
146 config.h defines `static' as an empty replacement string. */
148 int gray_bitmap_width = gray_width;
149 int gray_bitmap_height = gray_height;
150 char *gray_bitmap_bits = gray_bits;
152 /* Non-zero means prompt with the old GTK file selection dialog. */
154 int x_gtk_use_old_file_dialog;
156 /* If non-zero, by default show hidden files in the GTK file chooser. */
158 int x_gtk_show_hidden_files;
160 /* If non-zero, don't show additional help text in the GTK file chooser. */
162 int x_gtk_file_dialog_help_text;
164 /* If non-zero, don't collapse to tool bar when it is detached. */
166 int x_gtk_whole_detached_tool_bar;
168 /* The background and shape of the mouse pointer, and shape when not
169 over text or in the modeline. */
171 Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
172 Lisp_Object Vx_hourglass_pointer_shape;
174 /* The shape when over mouse-sensitive text. */
176 Lisp_Object Vx_sensitive_text_pointer_shape;
178 /* If non-nil, the pointer shape to indicate that windows can be
179 dragged horizontally. */
181 Lisp_Object Vx_window_horizontal_drag_shape;
183 /* Color of chars displayed in cursor box. */
185 Lisp_Object Vx_cursor_fore_pixel;
187 /* Nonzero if using X. */
189 static int x_in_use;
191 /* Non nil if no window manager is in use. */
193 Lisp_Object Vx_no_window_manager;
195 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
197 Lisp_Object Vx_pixel_size_width_font_regexp;
199 Lisp_Object Qnone;
200 Lisp_Object Qsuppress_icon;
201 Lisp_Object Qundefined_color;
202 Lisp_Object Qcompound_text, Qcancel_timer;
203 static Lisp_Object Qfont_param;
205 /* In dispnew.c */
207 extern Lisp_Object Vwindow_system_version;
209 /* The below are defined in frame.c. */
211 #if GLYPH_DEBUG
212 int image_cache_refcount, dpyinfo_refcount;
213 #endif
217 /* Error if we are not connected to X. */
219 void
220 check_x ()
222 if (! x_in_use)
223 error ("X windows are not in use or not initialized");
226 /* Nonzero if we can use mouse menus.
227 You should not call this unless HAVE_MENUS is defined. */
230 have_menus_p ()
232 return x_in_use;
235 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
236 and checking validity for X. */
238 FRAME_PTR
239 check_x_frame (frame)
240 Lisp_Object frame;
242 FRAME_PTR f;
244 if (NILP (frame))
245 frame = selected_frame;
246 CHECK_LIVE_FRAME (frame);
247 f = XFRAME (frame);
248 if (! FRAME_X_P (f))
249 error ("Non-X frame used");
250 return f;
253 /* Let the user specify an X display with a Lisp object.
254 OBJECT may be nil, a frame or a terminal id.
255 nil stands for the selected frame--or, if that is not an X frame,
256 the first X display on the list. */
258 struct x_display_info *
259 check_x_display_info (object)
260 Lisp_Object object;
262 struct x_display_info *dpyinfo = NULL;
264 if (NILP (object))
266 struct frame *sf = XFRAME (selected_frame);
268 if (FRAME_X_P (sf) && FRAME_LIVE_P (sf))
269 dpyinfo = FRAME_X_DISPLAY_INFO (sf);
270 else if (x_display_list != 0)
271 dpyinfo = x_display_list;
272 else
273 error ("X windows are not in use or not initialized");
275 else if (INTEGERP (object))
277 struct terminal *t = get_terminal (object, 1);
279 if (t->type != output_x_window)
280 error ("Terminal %d is not an X display", XINT (object));
282 dpyinfo = t->display_info.x;
284 else if (STRINGP (object))
285 dpyinfo = x_display_info_for_name (object);
286 else
288 FRAME_PTR f = check_x_frame (object);
289 dpyinfo = FRAME_X_DISPLAY_INFO (f);
292 return dpyinfo;
296 /* Return the Emacs frame-object corresponding to an X window.
297 It could be the frame's main window or an icon window. */
299 /* This function can be called during GC, so use GC_xxx type test macros. */
301 struct frame *
302 x_window_to_frame (dpyinfo, wdesc)
303 struct x_display_info *dpyinfo;
304 int wdesc;
306 Lisp_Object tail, frame;
307 struct frame *f;
309 if (wdesc == None) return 0;
311 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
313 frame = XCAR (tail);
314 if (!FRAMEP (frame))
315 continue;
316 f = XFRAME (frame);
317 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
318 continue;
319 if (f->output_data.x->hourglass_window == wdesc)
320 return f;
321 #ifdef USE_X_TOOLKIT
322 if ((f->output_data.x->edit_widget
323 && XtWindow (f->output_data.x->edit_widget) == wdesc)
324 /* A tooltip frame? */
325 || (!f->output_data.x->edit_widget
326 && FRAME_X_WINDOW (f) == wdesc)
327 || f->output_data.x->icon_desc == wdesc)
328 return f;
329 #else /* not USE_X_TOOLKIT */
330 #ifdef USE_GTK
331 if (f->output_data.x->edit_widget)
333 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
334 struct x_output *x = f->output_data.x;
335 if (gwdesc != 0 && gwdesc == x->edit_widget)
336 return f;
338 #endif /* USE_GTK */
339 if (FRAME_X_WINDOW (f) == wdesc
340 || f->output_data.x->icon_desc == wdesc)
341 return f;
342 #endif /* not USE_X_TOOLKIT */
344 return 0;
347 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
348 /* Like x_window_to_frame but also compares the window with the widget's
349 windows. */
351 struct frame *
352 x_any_window_to_frame (dpyinfo, wdesc)
353 struct x_display_info *dpyinfo;
354 int wdesc;
356 Lisp_Object tail, frame;
357 struct frame *f, *found;
358 struct x_output *x;
360 if (wdesc == None) return NULL;
362 found = NULL;
363 for (tail = Vframe_list; CONSP (tail) && !found; tail = XCDR (tail))
365 frame = XCAR (tail);
366 if (!FRAMEP (frame))
367 continue;
369 f = XFRAME (frame);
370 if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) == dpyinfo)
372 /* This frame matches if the window is any of its widgets. */
373 x = f->output_data.x;
374 if (x->hourglass_window == wdesc)
375 found = f;
376 else if (x->widget)
378 #ifdef USE_GTK
379 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
380 if (gwdesc != 0
381 && (gwdesc == x->widget
382 || gwdesc == x->edit_widget
383 || gwdesc == x->vbox_widget
384 || gwdesc == x->menubar_widget))
385 found = f;
386 #else
387 if (wdesc == XtWindow (x->widget)
388 || wdesc == XtWindow (x->column_widget)
389 || wdesc == XtWindow (x->edit_widget))
390 found = f;
391 /* Match if the window is this frame's menubar. */
392 else if (lw_window_is_in_menubar (wdesc, x->menubar_widget))
393 found = f;
394 #endif
396 else if (FRAME_X_WINDOW (f) == wdesc)
397 /* A tooltip frame. */
398 found = f;
402 return found;
405 /* Likewise, but exclude the menu bar widget. */
407 struct frame *
408 x_non_menubar_window_to_frame (dpyinfo, wdesc)
409 struct x_display_info *dpyinfo;
410 int wdesc;
412 Lisp_Object tail, frame;
413 struct frame *f;
414 struct x_output *x;
416 if (wdesc == None) return 0;
418 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
420 frame = XCAR (tail);
421 if (!FRAMEP (frame))
422 continue;
423 f = XFRAME (frame);
424 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
425 continue;
426 x = f->output_data.x;
427 /* This frame matches if the window is any of its widgets. */
428 if (x->hourglass_window == wdesc)
429 return f;
430 else if (x->widget)
432 #ifdef USE_GTK
433 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
434 if (gwdesc != 0
435 && (gwdesc == x->widget
436 || gwdesc == x->edit_widget
437 || gwdesc == x->vbox_widget))
438 return f;
439 #else
440 if (wdesc == XtWindow (x->widget)
441 || wdesc == XtWindow (x->column_widget)
442 || wdesc == XtWindow (x->edit_widget))
443 return f;
444 #endif
446 else if (FRAME_X_WINDOW (f) == wdesc)
447 /* A tooltip frame. */
448 return f;
450 return 0;
453 /* Likewise, but consider only the menu bar widget. */
455 struct frame *
456 x_menubar_window_to_frame (dpyinfo, wdesc)
457 struct x_display_info *dpyinfo;
458 int wdesc;
460 Lisp_Object tail, frame;
461 struct frame *f;
462 struct x_output *x;
464 if (wdesc == None) return 0;
466 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
468 frame = XCAR (tail);
469 if (!FRAMEP (frame))
470 continue;
471 f = XFRAME (frame);
472 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
473 continue;
474 x = f->output_data.x;
475 /* Match if the window is this frame's menubar. */
476 #ifdef USE_GTK
477 if (x->menubar_widget)
479 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
480 int found = 0;
482 BLOCK_INPUT;
483 if (gwdesc != 0
484 && (gwdesc == x->menubar_widget
485 || gtk_widget_get_parent (gwdesc) == x->menubar_widget))
486 found = 1;
487 UNBLOCK_INPUT;
488 if (found) return f;
490 #else
491 if (x->menubar_widget
492 && lw_window_is_in_menubar (wdesc, x->menubar_widget))
493 return f;
494 #endif
496 return 0;
499 /* Return the frame whose principal (outermost) window is WDESC.
500 If WDESC is some other (smaller) window, we return 0. */
502 struct frame *
503 x_top_window_to_frame (dpyinfo, wdesc)
504 struct x_display_info *dpyinfo;
505 int wdesc;
507 Lisp_Object tail, frame;
508 struct frame *f;
509 struct x_output *x;
511 if (wdesc == None) return 0;
513 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
515 frame = XCAR (tail);
516 if (!FRAMEP (frame))
517 continue;
518 f = XFRAME (frame);
519 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
520 continue;
521 x = f->output_data.x;
523 if (x->widget)
525 /* This frame matches if the window is its topmost widget. */
526 #ifdef USE_GTK
527 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
528 if (gwdesc == x->widget)
529 return f;
530 #else
531 if (wdesc == XtWindow (x->widget))
532 return f;
533 #if 0 /* I don't know why it did this,
534 but it seems logically wrong,
535 and it causes trouble for MapNotify events. */
536 /* Match if the window is this frame's menubar. */
537 if (x->menubar_widget
538 && wdesc == XtWindow (x->menubar_widget))
539 return f;
540 #endif
541 #endif
543 else if (FRAME_X_WINDOW (f) == wdesc)
544 /* Tooltip frame. */
545 return f;
547 return 0;
549 #endif /* USE_X_TOOLKIT || USE_GTK */
553 static void x_default_font_parameter P_ ((struct frame *, Lisp_Object));
555 static Lisp_Object unwind_create_frame P_ ((Lisp_Object));
556 static Lisp_Object unwind_create_tip_frame P_ ((Lisp_Object));
558 void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
559 static void x_set_wait_for_wm P_ ((struct frame *, Lisp_Object, Lisp_Object));
560 void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
561 void x_set_mouse_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
562 void x_set_cursor_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
563 void x_set_border_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
564 void x_set_cursor_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
565 void x_set_icon_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
566 void x_set_icon_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
567 void x_explicitly_set_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
568 void x_set_menu_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
569 void x_set_title P_ ((struct frame *, Lisp_Object, Lisp_Object));
570 void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
571 void x_set_scroll_bar_foreground P_ ((struct frame *, Lisp_Object,
572 Lisp_Object));
573 void x_set_scroll_bar_background P_ ((struct frame *, Lisp_Object,
574 Lisp_Object));
575 static Lisp_Object x_default_scroll_bar_color_parameter P_ ((struct frame *,
576 Lisp_Object,
577 Lisp_Object,
578 char *, char *,
579 int));
582 /* Store the screen positions of frame F into XPTR and YPTR.
583 These are the positions of the containing window manager window,
584 not Emacs's own window. */
586 void
587 x_real_positions (f, xptr, yptr)
588 FRAME_PTR f;
589 int *xptr, *yptr;
591 int win_x, win_y, outer_x, outer_y;
592 int real_x = 0, real_y = 0;
593 int had_errors = 0;
594 Window win = f->output_data.x->parent_desc;
596 BLOCK_INPUT;
598 x_catch_errors (FRAME_X_DISPLAY (f));
600 if (win == FRAME_X_DISPLAY_INFO (f)->root_window)
601 win = FRAME_OUTER_WINDOW (f);
603 /* This loop traverses up the containment tree until we hit the root
604 window. Window managers may intersect many windows between our window
605 and the root window. The window we find just before the root window
606 should be the outer WM window. */
607 for (;;)
609 Window wm_window, rootw;
610 Window *tmp_children;
611 unsigned int tmp_nchildren;
612 int success;
614 success = XQueryTree (FRAME_X_DISPLAY (f), win, &rootw,
615 &wm_window, &tmp_children, &tmp_nchildren);
617 had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
619 /* Don't free tmp_children if XQueryTree failed. */
620 if (! success)
621 break;
623 XFree ((char *) tmp_children);
625 if (wm_window == rootw || had_errors)
626 break;
628 win = wm_window;
631 if (! had_errors)
633 unsigned int ign;
634 Window child, rootw;
636 /* Get the real coordinates for the WM window upper left corner */
637 XGetGeometry (FRAME_X_DISPLAY (f), win,
638 &rootw, &real_x, &real_y, &ign, &ign, &ign, &ign);
640 /* Translate real coordinates to coordinates relative to our
641 window. For our window, the upper left corner is 0, 0.
642 Since the upper left corner of the WM window is outside
643 our window, win_x and win_y will be negative:
645 ------------------ ---> x
646 | title |
647 | ----------------- v y
648 | | our window
650 XTranslateCoordinates (FRAME_X_DISPLAY (f),
652 /* From-window, to-window. */
653 FRAME_X_DISPLAY_INFO (f)->root_window,
654 FRAME_X_WINDOW (f),
656 /* From-position, to-position. */
657 real_x, real_y, &win_x, &win_y,
659 /* Child of win. */
660 &child);
662 if (FRAME_X_WINDOW (f) == FRAME_OUTER_WINDOW (f))
664 outer_x = win_x;
665 outer_y = win_y;
667 else
669 XTranslateCoordinates (FRAME_X_DISPLAY (f),
671 /* From-window, to-window. */
672 FRAME_X_DISPLAY_INFO (f)->root_window,
673 FRAME_OUTER_WINDOW (f),
675 /* From-position, to-position. */
676 real_x, real_y, &outer_x, &outer_y,
678 /* Child of win. */
679 &child);
682 had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
685 x_uncatch_errors ();
687 UNBLOCK_INPUT;
689 if (had_errors) return;
691 f->x_pixels_diff = -win_x;
692 f->y_pixels_diff = -win_y;
694 FRAME_X_OUTPUT (f)->x_pixels_outer_diff = -outer_x;
695 FRAME_X_OUTPUT (f)->y_pixels_outer_diff = -outer_y;
697 *xptr = real_x;
698 *yptr = real_y;
704 /* Gamma-correct COLOR on frame F. */
706 void
707 gamma_correct (f, color)
708 struct frame *f;
709 XColor *color;
711 if (f->gamma)
713 color->red = pow (color->red / 65535.0, f->gamma) * 65535.0 + 0.5;
714 color->green = pow (color->green / 65535.0, f->gamma) * 65535.0 + 0.5;
715 color->blue = pow (color->blue / 65535.0, f->gamma) * 65535.0 + 0.5;
720 /* Decide if color named COLOR_NAME is valid for use on frame F. If
721 so, return the RGB values in COLOR. If ALLOC_P is non-zero,
722 allocate the color. Value is zero if COLOR_NAME is invalid, or
723 no color could be allocated. */
726 x_defined_color (f, color_name, color, alloc_p)
727 struct frame *f;
728 char *color_name;
729 XColor *color;
730 int alloc_p;
732 int success_p;
733 Display *dpy = FRAME_X_DISPLAY (f);
734 Colormap cmap = FRAME_X_COLORMAP (f);
736 BLOCK_INPUT;
737 success_p = XParseColor (dpy, cmap, color_name, color);
738 if (success_p && alloc_p)
739 success_p = x_alloc_nearest_color (f, cmap, color);
740 UNBLOCK_INPUT;
742 return success_p;
746 /* Return the pixel color value for color COLOR_NAME on frame F. If F
747 is a monochrome frame, return MONO_COLOR regardless of what ARG says.
748 Signal an error if color can't be allocated. */
751 x_decode_color (f, color_name, mono_color)
752 FRAME_PTR f;
753 Lisp_Object color_name;
754 int mono_color;
756 XColor cdef;
758 CHECK_STRING (color_name);
760 #if 0 /* Don't do this. It's wrong when we're not using the default
761 colormap, it makes freeing difficult, and it's probably not
762 an important optimization. */
763 if (strcmp (SDATA (color_name), "black") == 0)
764 return BLACK_PIX_DEFAULT (f);
765 else if (strcmp (SDATA (color_name), "white") == 0)
766 return WHITE_PIX_DEFAULT (f);
767 #endif
769 /* Return MONO_COLOR for monochrome frames. */
770 if (FRAME_X_DISPLAY_INFO (f)->n_planes == 1)
771 return mono_color;
773 /* x_defined_color is responsible for coping with failures
774 by looking for a near-miss. */
775 if (x_defined_color (f, SDATA (color_name), &cdef, 1))
776 return cdef.pixel;
778 signal_error ("Undefined color", color_name);
783 /* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
784 the previous value of that parameter, NEW_VALUE is the new value.
785 See also the comment of wait_for_wm in struct x_output. */
787 static void
788 x_set_wait_for_wm (f, new_value, old_value)
789 struct frame *f;
790 Lisp_Object new_value, old_value;
792 f->output_data.x->wait_for_wm = !NILP (new_value);
795 #ifdef USE_GTK
797 /* Set icon from FILE for frame F. By using GTK functions the icon
798 may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
801 xg_set_icon (f, file)
802 FRAME_PTR f;
803 Lisp_Object file;
805 int result = 0;
806 Lisp_Object found;
808 found = x_find_image_file (file);
810 if (! NILP (found))
812 GdkPixbuf *pixbuf;
813 GError *err = NULL;
814 char *filename = (char *) SDATA (found);
815 BLOCK_INPUT;
817 pixbuf = gdk_pixbuf_new_from_file (filename, &err);
819 if (pixbuf)
821 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
822 pixbuf);
823 g_object_unref (pixbuf);
825 result = 1;
827 else
828 g_error_free (err);
830 UNBLOCK_INPUT;
833 return result;
837 xg_set_icon_from_xpm_data (f, data)
838 FRAME_PTR f;
839 char **data;
841 int result = 0;
842 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) data);
844 if (!pixbuf)
845 return 0;
847 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), pixbuf);
848 g_object_unref (pixbuf);
849 return 1;
851 #endif /* USE_GTK */
854 /* Functions called only from `x_set_frame_param'
855 to set individual parameters.
857 If FRAME_X_WINDOW (f) is 0,
858 the frame is being created and its X-window does not exist yet.
859 In that case, just record the parameter's new value
860 in the standard place; do not attempt to change the window. */
862 void
863 x_set_foreground_color (f, arg, oldval)
864 struct frame *f;
865 Lisp_Object arg, oldval;
867 struct x_output *x = f->output_data.x;
868 unsigned long fg, old_fg;
870 fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
871 old_fg = FRAME_FOREGROUND_PIXEL (f);
872 FRAME_FOREGROUND_PIXEL (f) = fg;
874 if (FRAME_X_WINDOW (f) != 0)
876 Display *dpy = FRAME_X_DISPLAY (f);
878 BLOCK_INPUT;
879 XSetForeground (dpy, x->normal_gc, fg);
880 XSetBackground (dpy, x->reverse_gc, fg);
882 if (x->cursor_pixel == old_fg)
884 unload_color (f, x->cursor_pixel);
885 x->cursor_pixel = x_copy_color (f, fg);
886 XSetBackground (dpy, x->cursor_gc, x->cursor_pixel);
889 UNBLOCK_INPUT;
891 update_face_from_frame_parameter (f, Qforeground_color, arg);
893 if (FRAME_VISIBLE_P (f))
894 redraw_frame (f);
897 unload_color (f, old_fg);
900 void
901 x_set_background_color (f, arg, oldval)
902 struct frame *f;
903 Lisp_Object arg, oldval;
905 struct x_output *x = f->output_data.x;
906 unsigned long bg;
908 bg = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
909 unload_color (f, FRAME_BACKGROUND_PIXEL (f));
910 FRAME_BACKGROUND_PIXEL (f) = bg;
912 if (FRAME_X_WINDOW (f) != 0)
914 Display *dpy = FRAME_X_DISPLAY (f);
916 BLOCK_INPUT;
917 XSetBackground (dpy, x->normal_gc, bg);
918 XSetForeground (dpy, x->reverse_gc, bg);
919 XSetWindowBackground (dpy, FRAME_X_WINDOW (f), bg);
920 XSetForeground (dpy, x->cursor_gc, bg);
922 #ifdef USE_GTK
923 xg_set_background_color (f, bg);
924 #endif
926 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
927 toolkit scroll bars. */
929 Lisp_Object bar;
930 for (bar = FRAME_SCROLL_BARS (f);
931 !NILP (bar);
932 bar = XSCROLL_BAR (bar)->next)
934 Window window = XSCROLL_BAR (bar)->x_window;
935 XSetWindowBackground (dpy, window, bg);
938 #endif /* USE_TOOLKIT_SCROLL_BARS */
940 UNBLOCK_INPUT;
941 update_face_from_frame_parameter (f, Qbackground_color, arg);
943 if (FRAME_VISIBLE_P (f))
944 redraw_frame (f);
948 void
949 x_set_mouse_color (f, arg, oldval)
950 struct frame *f;
951 Lisp_Object arg, oldval;
953 struct x_output *x = f->output_data.x;
954 Display *dpy = FRAME_X_DISPLAY (f);
955 Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
956 Cursor hourglass_cursor, horizontal_drag_cursor;
957 unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
958 unsigned long mask_color = FRAME_BACKGROUND_PIXEL (f);
960 /* Don't let pointers be invisible. */
961 if (mask_color == pixel)
963 x_free_colors (f, &pixel, 1);
964 pixel = x_copy_color (f, FRAME_FOREGROUND_PIXEL (f));
967 unload_color (f, x->mouse_pixel);
968 x->mouse_pixel = pixel;
970 BLOCK_INPUT;
972 /* It's not okay to crash if the user selects a screwy cursor. */
973 x_catch_errors (dpy);
975 if (!NILP (Vx_pointer_shape))
977 CHECK_NUMBER (Vx_pointer_shape);
978 cursor = XCreateFontCursor (dpy, XINT (Vx_pointer_shape));
980 else
981 cursor = XCreateFontCursor (dpy, XC_xterm);
982 x_check_errors (dpy, "bad text pointer cursor: %s");
984 if (!NILP (Vx_nontext_pointer_shape))
986 CHECK_NUMBER (Vx_nontext_pointer_shape);
987 nontext_cursor
988 = XCreateFontCursor (dpy, XINT (Vx_nontext_pointer_shape));
990 else
991 nontext_cursor = XCreateFontCursor (dpy, XC_left_ptr);
992 x_check_errors (dpy, "bad nontext pointer cursor: %s");
994 if (!NILP (Vx_hourglass_pointer_shape))
996 CHECK_NUMBER (Vx_hourglass_pointer_shape);
997 hourglass_cursor
998 = XCreateFontCursor (dpy, XINT (Vx_hourglass_pointer_shape));
1000 else
1001 hourglass_cursor = XCreateFontCursor (dpy, XC_watch);
1002 x_check_errors (dpy, "bad hourglass pointer cursor: %s");
1004 if (!NILP (Vx_mode_pointer_shape))
1006 CHECK_NUMBER (Vx_mode_pointer_shape);
1007 mode_cursor = XCreateFontCursor (dpy, XINT (Vx_mode_pointer_shape));
1009 else
1010 mode_cursor = XCreateFontCursor (dpy, XC_xterm);
1011 x_check_errors (dpy, "bad modeline pointer cursor: %s");
1013 if (!NILP (Vx_sensitive_text_pointer_shape))
1015 CHECK_NUMBER (Vx_sensitive_text_pointer_shape);
1016 hand_cursor
1017 = XCreateFontCursor (dpy, XINT (Vx_sensitive_text_pointer_shape));
1019 else
1020 hand_cursor = XCreateFontCursor (dpy, XC_hand2);
1022 if (!NILP (Vx_window_horizontal_drag_shape))
1024 CHECK_NUMBER (Vx_window_horizontal_drag_shape);
1025 horizontal_drag_cursor
1026 = XCreateFontCursor (dpy, XINT (Vx_window_horizontal_drag_shape));
1028 else
1029 horizontal_drag_cursor
1030 = XCreateFontCursor (dpy, XC_sb_h_double_arrow);
1032 /* Check and report errors with the above calls. */
1033 x_check_errors (dpy, "can't set cursor shape: %s");
1034 x_uncatch_errors ();
1037 XColor fore_color, back_color;
1039 fore_color.pixel = x->mouse_pixel;
1040 x_query_color (f, &fore_color);
1041 back_color.pixel = mask_color;
1042 x_query_color (f, &back_color);
1044 XRecolorCursor (dpy, cursor, &fore_color, &back_color);
1045 XRecolorCursor (dpy, nontext_cursor, &fore_color, &back_color);
1046 XRecolorCursor (dpy, mode_cursor, &fore_color, &back_color);
1047 XRecolorCursor (dpy, hand_cursor, &fore_color, &back_color);
1048 XRecolorCursor (dpy, hourglass_cursor, &fore_color, &back_color);
1049 XRecolorCursor (dpy, horizontal_drag_cursor, &fore_color, &back_color);
1052 if (FRAME_X_WINDOW (f) != 0)
1053 XDefineCursor (dpy, FRAME_X_WINDOW (f), cursor);
1055 if (cursor != x->text_cursor
1056 && x->text_cursor != 0)
1057 XFreeCursor (dpy, x->text_cursor);
1058 x->text_cursor = cursor;
1060 if (nontext_cursor != x->nontext_cursor
1061 && x->nontext_cursor != 0)
1062 XFreeCursor (dpy, x->nontext_cursor);
1063 x->nontext_cursor = nontext_cursor;
1065 if (hourglass_cursor != x->hourglass_cursor
1066 && x->hourglass_cursor != 0)
1067 XFreeCursor (dpy, x->hourglass_cursor);
1068 x->hourglass_cursor = hourglass_cursor;
1070 if (mode_cursor != x->modeline_cursor
1071 && x->modeline_cursor != 0)
1072 XFreeCursor (dpy, f->output_data.x->modeline_cursor);
1073 x->modeline_cursor = mode_cursor;
1075 if (hand_cursor != x->hand_cursor
1076 && x->hand_cursor != 0)
1077 XFreeCursor (dpy, x->hand_cursor);
1078 x->hand_cursor = hand_cursor;
1080 if (horizontal_drag_cursor != x->horizontal_drag_cursor
1081 && x->horizontal_drag_cursor != 0)
1082 XFreeCursor (dpy, x->horizontal_drag_cursor);
1083 x->horizontal_drag_cursor = horizontal_drag_cursor;
1085 XFlush (dpy);
1086 UNBLOCK_INPUT;
1088 update_face_from_frame_parameter (f, Qmouse_color, arg);
1091 void
1092 x_set_cursor_color (f, arg, oldval)
1093 struct frame *f;
1094 Lisp_Object arg, oldval;
1096 unsigned long fore_pixel, pixel;
1097 int fore_pixel_allocated_p = 0, pixel_allocated_p = 0;
1098 struct x_output *x = f->output_data.x;
1100 if (!NILP (Vx_cursor_fore_pixel))
1102 fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
1103 WHITE_PIX_DEFAULT (f));
1104 fore_pixel_allocated_p = 1;
1106 else
1107 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1109 pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1110 pixel_allocated_p = 1;
1112 /* Make sure that the cursor color differs from the background color. */
1113 if (pixel == FRAME_BACKGROUND_PIXEL (f))
1115 if (pixel_allocated_p)
1117 x_free_colors (f, &pixel, 1);
1118 pixel_allocated_p = 0;
1121 pixel = x->mouse_pixel;
1122 if (pixel == fore_pixel)
1124 if (fore_pixel_allocated_p)
1126 x_free_colors (f, &fore_pixel, 1);
1127 fore_pixel_allocated_p = 0;
1129 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1133 unload_color (f, x->cursor_foreground_pixel);
1134 if (!fore_pixel_allocated_p)
1135 fore_pixel = x_copy_color (f, fore_pixel);
1136 x->cursor_foreground_pixel = fore_pixel;
1138 unload_color (f, x->cursor_pixel);
1139 if (!pixel_allocated_p)
1140 pixel = x_copy_color (f, pixel);
1141 x->cursor_pixel = pixel;
1143 if (FRAME_X_WINDOW (f) != 0)
1145 BLOCK_INPUT;
1146 XSetBackground (FRAME_X_DISPLAY (f), x->cursor_gc, x->cursor_pixel);
1147 XSetForeground (FRAME_X_DISPLAY (f), x->cursor_gc, fore_pixel);
1148 UNBLOCK_INPUT;
1150 if (FRAME_VISIBLE_P (f))
1152 x_update_cursor (f, 0);
1153 x_update_cursor (f, 1);
1157 update_face_from_frame_parameter (f, Qcursor_color, arg);
1160 /* Set the border-color of frame F to pixel value PIX.
1161 Note that this does not fully take effect if done before
1162 F has an x-window. */
1164 void
1165 x_set_border_pixel (f, pix)
1166 struct frame *f;
1167 int pix;
1169 unload_color (f, f->output_data.x->border_pixel);
1170 f->output_data.x->border_pixel = pix;
1172 if (FRAME_X_WINDOW (f) != 0 && f->border_width > 0)
1174 BLOCK_INPUT;
1175 XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1176 (unsigned long)pix);
1177 UNBLOCK_INPUT;
1179 if (FRAME_VISIBLE_P (f))
1180 redraw_frame (f);
1184 /* Set the border-color of frame F to value described by ARG.
1185 ARG can be a string naming a color.
1186 The border-color is used for the border that is drawn by the X server.
1187 Note that this does not fully take effect if done before
1188 F has an x-window; it must be redone when the window is created.
1190 Note: this is done in two routines because of the way X10 works.
1192 Note: under X11, this is normally the province of the window manager,
1193 and so emacs' border colors may be overridden. */
1195 void
1196 x_set_border_color (f, arg, oldval)
1197 struct frame *f;
1198 Lisp_Object arg, oldval;
1200 int pix;
1202 CHECK_STRING (arg);
1203 pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1204 x_set_border_pixel (f, pix);
1205 update_face_from_frame_parameter (f, Qborder_color, arg);
1209 void
1210 x_set_cursor_type (f, arg, oldval)
1211 FRAME_PTR f;
1212 Lisp_Object arg, oldval;
1214 set_frame_cursor_types (f, arg);
1216 /* Make sure the cursor gets redrawn. */
1217 cursor_type_changed = 1;
1220 void
1221 x_set_icon_type (f, arg, oldval)
1222 struct frame *f;
1223 Lisp_Object arg, oldval;
1225 int result;
1227 if (STRINGP (arg))
1229 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1230 return;
1232 else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
1233 return;
1235 BLOCK_INPUT;
1236 if (NILP (arg))
1237 result = x_text_icon (f,
1238 (char *) SDATA ((!NILP (f->icon_name)
1239 ? f->icon_name
1240 : f->name)));
1241 else
1242 result = x_bitmap_icon (f, arg);
1244 if (result)
1246 UNBLOCK_INPUT;
1247 error ("No icon window available");
1250 XFlush (FRAME_X_DISPLAY (f));
1251 UNBLOCK_INPUT;
1254 void
1255 x_set_icon_name (f, arg, oldval)
1256 struct frame *f;
1257 Lisp_Object arg, oldval;
1259 int result;
1261 if (STRINGP (arg))
1263 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1264 return;
1266 else if (!NILP (arg) || NILP (oldval))
1267 return;
1269 f->icon_name = arg;
1271 if (f->output_data.x->icon_bitmap != 0)
1272 return;
1274 BLOCK_INPUT;
1276 result = x_text_icon (f,
1277 (char *) SDATA ((!NILP (f->icon_name)
1278 ? f->icon_name
1279 : !NILP (f->title)
1280 ? f->title
1281 : f->name)));
1283 if (result)
1285 UNBLOCK_INPUT;
1286 error ("No icon window available");
1289 XFlush (FRAME_X_DISPLAY (f));
1290 UNBLOCK_INPUT;
1294 void
1295 x_set_menu_bar_lines (f, value, oldval)
1296 struct frame *f;
1297 Lisp_Object value, oldval;
1299 int nlines;
1300 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
1301 int olines = FRAME_MENU_BAR_LINES (f);
1302 #endif
1304 /* Right now, menu bars don't work properly in minibuf-only frames;
1305 most of the commands try to apply themselves to the minibuffer
1306 frame itself, and get an error because you can't switch buffers
1307 in or split the minibuffer window. */
1308 if (FRAME_MINIBUF_ONLY_P (f))
1309 return;
1311 if (INTEGERP (value))
1312 nlines = XINT (value);
1313 else
1314 nlines = 0;
1316 /* Make sure we redisplay all windows in this frame. */
1317 windows_or_buffers_changed++;
1319 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1320 FRAME_MENU_BAR_LINES (f) = 0;
1321 if (nlines)
1323 FRAME_EXTERNAL_MENU_BAR (f) = 1;
1324 if (FRAME_X_P (f) && f->output_data.x->menubar_widget == 0)
1325 /* Make sure next redisplay shows the menu bar. */
1326 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
1328 else
1330 if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
1331 free_frame_menubar (f);
1332 FRAME_EXTERNAL_MENU_BAR (f) = 0;
1333 if (FRAME_X_P (f))
1334 f->output_data.x->menubar_widget = 0;
1336 #else /* not USE_X_TOOLKIT && not USE_GTK */
1337 FRAME_MENU_BAR_LINES (f) = nlines;
1338 change_window_heights (f->root_window, nlines - olines);
1339 #endif /* not USE_X_TOOLKIT */
1340 adjust_glyphs (f);
1344 /* Set the number of lines used for the tool bar of frame F to VALUE.
1345 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1346 is the old number of tool bar lines. This function changes the
1347 height of all windows on frame F to match the new tool bar height.
1348 The frame's height doesn't change. */
1350 void
1351 x_set_tool_bar_lines (f, value, oldval)
1352 struct frame *f;
1353 Lisp_Object value, oldval;
1355 int delta, nlines, root_height;
1356 Lisp_Object root_window;
1358 /* Treat tool bars like menu bars. */
1359 if (FRAME_MINIBUF_ONLY_P (f))
1360 return;
1362 /* Use VALUE only if an integer >= 0. */
1363 if (INTEGERP (value) && XINT (value) >= 0)
1364 nlines = XFASTINT (value);
1365 else
1366 nlines = 0;
1368 #ifdef USE_GTK
1369 FRAME_TOOL_BAR_LINES (f) = 0;
1370 if (nlines)
1372 FRAME_EXTERNAL_TOOL_BAR (f) = 1;
1373 if (FRAME_X_P (f) && f->output_data.x->toolbar_widget == 0)
1374 /* Make sure next redisplay shows the tool bar. */
1375 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
1376 update_frame_tool_bar (f);
1378 else
1380 if (FRAME_EXTERNAL_TOOL_BAR (f))
1381 free_frame_tool_bar (f);
1382 FRAME_EXTERNAL_TOOL_BAR (f) = 0;
1385 return;
1386 #endif
1388 /* Make sure we redisplay all windows in this frame. */
1389 ++windows_or_buffers_changed;
1391 delta = nlines - FRAME_TOOL_BAR_LINES (f);
1393 /* Don't resize the tool-bar to more than we have room for. */
1394 root_window = FRAME_ROOT_WINDOW (f);
1395 root_height = WINDOW_TOTAL_LINES (XWINDOW (root_window));
1396 if (root_height - delta < 1)
1398 delta = root_height - 1;
1399 nlines = FRAME_TOOL_BAR_LINES (f) + delta;
1402 FRAME_TOOL_BAR_LINES (f) = nlines;
1403 change_window_heights (root_window, delta);
1404 adjust_glyphs (f);
1406 /* We also have to make sure that the internal border at the top of
1407 the frame, below the menu bar or tool bar, is redrawn when the
1408 tool bar disappears. This is so because the internal border is
1409 below the tool bar if one is displayed, but is below the menu bar
1410 if there isn't a tool bar. The tool bar draws into the area
1411 below the menu bar. */
1412 if (FRAME_X_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0)
1414 clear_frame (f);
1415 clear_current_matrices (f);
1418 /* If the tool bar gets smaller, the internal border below it
1419 has to be cleared. It was formerly part of the display
1420 of the larger tool bar, and updating windows won't clear it. */
1421 if (delta < 0)
1423 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1424 int width = FRAME_PIXEL_WIDTH (f);
1425 int y = nlines * FRAME_LINE_HEIGHT (f);
1427 /* height can be zero here. */
1428 if (height > 0 && width > 0)
1430 BLOCK_INPUT;
1431 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1432 0, y, width, height, False);
1433 UNBLOCK_INPUT;
1436 if (WINDOWP (f->tool_bar_window))
1437 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1442 /* Set the foreground color for scroll bars on frame F to VALUE.
1443 VALUE should be a string, a color name. If it isn't a string or
1444 isn't a valid color name, do nothing. OLDVAL is the old value of
1445 the frame parameter. */
1447 void
1448 x_set_scroll_bar_foreground (f, value, oldval)
1449 struct frame *f;
1450 Lisp_Object value, oldval;
1452 unsigned long pixel;
1454 if (STRINGP (value))
1455 pixel = x_decode_color (f, value, BLACK_PIX_DEFAULT (f));
1456 else
1457 pixel = -1;
1459 if (f->output_data.x->scroll_bar_foreground_pixel != -1)
1460 unload_color (f, f->output_data.x->scroll_bar_foreground_pixel);
1462 f->output_data.x->scroll_bar_foreground_pixel = pixel;
1463 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1465 /* Remove all scroll bars because they have wrong colors. */
1466 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1467 (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1468 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1469 (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1471 update_face_from_frame_parameter (f, Qscroll_bar_foreground, value);
1472 redraw_frame (f);
1477 /* Set the background color for scroll bars on frame F to VALUE VALUE
1478 should be a string, a color name. If it isn't a string or isn't a
1479 valid color name, do nothing. OLDVAL is the old value of the frame
1480 parameter. */
1482 void
1483 x_set_scroll_bar_background (f, value, oldval)
1484 struct frame *f;
1485 Lisp_Object value, oldval;
1487 unsigned long pixel;
1489 if (STRINGP (value))
1490 pixel = x_decode_color (f, value, WHITE_PIX_DEFAULT (f));
1491 else
1492 pixel = -1;
1494 if (f->output_data.x->scroll_bar_background_pixel != -1)
1495 unload_color (f, f->output_data.x->scroll_bar_background_pixel);
1497 #ifdef USE_TOOLKIT_SCROLL_BARS
1498 /* Scrollbar shadow colors. */
1499 if (f->output_data.x->scroll_bar_top_shadow_pixel != -1)
1501 unload_color (f, f->output_data.x->scroll_bar_top_shadow_pixel);
1502 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
1504 if (f->output_data.x->scroll_bar_bottom_shadow_pixel != -1)
1506 unload_color (f, f->output_data.x->scroll_bar_bottom_shadow_pixel);
1507 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
1509 #endif /* USE_TOOLKIT_SCROLL_BARS */
1511 f->output_data.x->scroll_bar_background_pixel = pixel;
1512 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1514 /* Remove all scroll bars because they have wrong colors. */
1515 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1516 (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1517 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1518 (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1520 update_face_from_frame_parameter (f, Qscroll_bar_background, value);
1521 redraw_frame (f);
1526 /* Encode Lisp string STRING as a text in a format appropriate for
1527 XICCC (X Inter Client Communication Conventions).
1529 This can call Lisp code, so callers must GCPRO.
1531 If STRING contains only ASCII characters, do no conversion and
1532 return the string data of STRING. Otherwise, encode the text by
1533 CODING_SYSTEM, and return a newly allocated memory area which
1534 should be freed by `xfree' by a caller.
1536 SELECTIONP non-zero means the string is being encoded for an X
1537 selection, so it is safe to run pre-write conversions (which
1538 may run Lisp code).
1540 Store the byte length of resulting text in *TEXT_BYTES.
1542 If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
1543 which means that the `encoding' of the result can be `STRING'.
1544 Otherwise store 0 in *STRINGP, which means that the `encoding' of
1545 the result should be `COMPOUND_TEXT'. */
1547 static unsigned char *
1548 x_encode_text (string, coding_system, selectionp, text_bytes, stringp, freep)
1549 Lisp_Object string, coding_system;
1550 int *text_bytes, *stringp;
1551 int selectionp;
1552 int *freep;
1554 int result = string_xstring_p (string);
1555 struct coding_system coding;
1557 if (result == 0)
1559 /* No multibyte character in OBJ. We need not encode it. */
1560 *text_bytes = SBYTES (string);
1561 *stringp = 1;
1562 *freep = 0;
1563 return SDATA (string);
1566 setup_coding_system (coding_system, &coding);
1567 coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK);
1568 /* We suppress producing escape sequences for composition. */
1569 coding.common_flags &= ~CODING_ANNOTATION_MASK;
1570 coding.dst_bytes = SCHARS (string) * 2;
1571 coding.destination = (unsigned char *) xmalloc (coding.dst_bytes);
1572 encode_coding_object (&coding, string, 0, 0,
1573 SCHARS (string), SBYTES (string), Qnil);
1574 *text_bytes = coding.produced;
1575 *stringp = (result == 1 || !EQ (coding_system, Qcompound_text));
1576 *freep = 1;
1577 return coding.destination;
1581 /* Set the WM name to NAME for frame F. Also set the icon name.
1582 If the frame already has an icon name, use that, otherwise set the
1583 icon name to NAME. */
1585 static void
1586 x_set_name_internal (f, name)
1587 FRAME_PTR f;
1588 Lisp_Object name;
1590 if (FRAME_X_WINDOW (f))
1592 BLOCK_INPUT;
1594 XTextProperty text, icon;
1595 int bytes, stringp;
1596 int do_free_icon_value = 0, do_free_text_value = 0;
1597 Lisp_Object coding_system;
1598 #ifdef USE_GTK
1599 Lisp_Object encoded_name;
1600 struct gcpro gcpro1;
1602 /* As ENCODE_UTF_8 may cause GC and relocation of string data,
1603 we use it before x_encode_text that may return string data. */
1604 GCPRO1 (name);
1605 encoded_name = ENCODE_UTF_8 (name);
1606 UNGCPRO;
1607 #endif
1609 coding_system = Qcompound_text;
1610 /* Note: Encoding strategy
1612 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1613 text.encoding. But, there are non-internationalized window
1614 managers which don't support that encoding. So, if NAME
1615 contains only ASCII and 8859-1 characters, encode it by
1616 iso-latin-1, and use "STRING" in text.encoding hoping that
1617 such window managers at least analyze this format correctly,
1618 i.e. treat 8-bit bytes as 8859-1 characters.
1620 We may also be able to use "UTF8_STRING" in text.encoding
1621 in the future which can encode all Unicode characters.
1622 But, for the moment, there's no way to know that the
1623 current window manager supports it or not. */
1624 text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp,
1625 &do_free_text_value);
1626 text.encoding = (stringp ? XA_STRING
1627 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1628 text.format = 8;
1629 text.nitems = bytes;
1631 if (!STRINGP (f->icon_name))
1633 icon = text;
1635 else
1637 /* See the above comment "Note: Encoding strategy". */
1638 icon.value = x_encode_text (f->icon_name, coding_system, 0,
1639 &bytes, &stringp, &do_free_icon_value);
1640 icon.encoding = (stringp ? XA_STRING
1641 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1642 icon.format = 8;
1643 icon.nitems = bytes;
1646 #ifdef USE_GTK
1647 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
1648 (char *) SDATA (encoded_name));
1649 #else /* not USE_GTK */
1650 XSetWMName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &text);
1651 #endif /* not USE_GTK */
1653 XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &icon);
1655 if (do_free_icon_value)
1656 xfree (icon.value);
1657 if (do_free_text_value)
1658 xfree (text.value);
1660 UNBLOCK_INPUT;
1664 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1665 x_id_name.
1667 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1668 name; if NAME is a string, set F's name to NAME and set
1669 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1671 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1672 suggesting a new name, which lisp code should override; if
1673 F->explicit_name is set, ignore the new name; otherwise, set it. */
1675 void
1676 x_set_name (f, name, explicit)
1677 struct frame *f;
1678 Lisp_Object name;
1679 int explicit;
1681 /* Make sure that requests from lisp code override requests from
1682 Emacs redisplay code. */
1683 if (explicit)
1685 /* If we're switching from explicit to implicit, we had better
1686 update the mode lines and thereby update the title. */
1687 if (f->explicit_name && NILP (name))
1688 update_mode_lines = 1;
1690 f->explicit_name = ! NILP (name);
1692 else if (f->explicit_name)
1693 return;
1695 /* If NAME is nil, set the name to the x_id_name. */
1696 if (NILP (name))
1698 /* Check for no change needed in this very common case
1699 before we do any consing. */
1700 if (!strcmp (FRAME_X_DISPLAY_INFO (f)->x_id_name,
1701 SDATA (f->name)))
1702 return;
1703 name = build_string (FRAME_X_DISPLAY_INFO (f)->x_id_name);
1705 else
1706 CHECK_STRING (name);
1708 /* Don't change the name if it's already NAME. */
1709 if (! NILP (Fstring_equal (name, f->name)))
1710 return;
1712 f->name = name;
1714 /* For setting the frame title, the title parameter should override
1715 the name parameter. */
1716 if (! NILP (f->title))
1717 name = f->title;
1719 x_set_name_internal (f, name);
1722 /* This function should be called when the user's lisp code has
1723 specified a name for the frame; the name will override any set by the
1724 redisplay code. */
1725 void
1726 x_explicitly_set_name (f, arg, oldval)
1727 FRAME_PTR f;
1728 Lisp_Object arg, oldval;
1730 x_set_name (f, arg, 1);
1733 /* This function should be called by Emacs redisplay code to set the
1734 name; names set this way will never override names set by the user's
1735 lisp code. */
1736 void
1737 x_implicitly_set_name (f, arg, oldval)
1738 FRAME_PTR f;
1739 Lisp_Object arg, oldval;
1741 x_set_name (f, arg, 0);
1744 /* Change the title of frame F to NAME.
1745 If NAME is nil, use the frame name as the title. */
1747 void
1748 x_set_title (f, name, old_name)
1749 struct frame *f;
1750 Lisp_Object name, old_name;
1752 /* Don't change the title if it's already NAME. */
1753 if (EQ (name, f->title))
1754 return;
1756 update_mode_lines = 1;
1758 f->title = name;
1760 if (NILP (name))
1761 name = f->name;
1762 else
1763 CHECK_STRING (name);
1765 x_set_name_internal (f, name);
1768 void
1769 x_set_scroll_bar_default_width (f)
1770 struct frame *f;
1772 int wid = FRAME_COLUMN_WIDTH (f);
1774 #ifdef USE_TOOLKIT_SCROLL_BARS
1775 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
1776 int width = 16 + 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM;
1777 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (width + wid - 1) / wid;
1778 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = width;
1779 #else
1780 /* Make the actual width at least 14 pixels and a multiple of a
1781 character width. */
1782 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
1784 /* Use all of that space (aside from required margins) for the
1785 scroll bar. */
1786 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 0;
1787 #endif
1791 /* Record in frame F the specified or default value according to ALIST
1792 of the parameter named PROP (a Lisp symbol). If no value is
1793 specified for PROP, look for an X default for XPROP on the frame
1794 named NAME. If that is not found either, use the value DEFLT. */
1796 static Lisp_Object
1797 x_default_scroll_bar_color_parameter (f, alist, prop, xprop, xclass,
1798 foreground_p)
1799 struct frame *f;
1800 Lisp_Object alist;
1801 Lisp_Object prop;
1802 char *xprop;
1803 char *xclass;
1804 int foreground_p;
1806 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
1807 Lisp_Object tem;
1809 tem = x_get_arg (dpyinfo, alist, prop, xprop, xclass, RES_TYPE_STRING);
1810 if (EQ (tem, Qunbound))
1812 #ifdef USE_TOOLKIT_SCROLL_BARS
1814 /* See if an X resource for the scroll bar color has been
1815 specified. */
1816 tem = display_x_get_resource (dpyinfo,
1817 build_string (foreground_p
1818 ? "foreground"
1819 : "background"),
1820 empty_unibyte_string,
1821 build_string ("verticalScrollBar"),
1822 empty_unibyte_string);
1823 if (!STRINGP (tem))
1825 /* If nothing has been specified, scroll bars will use a
1826 toolkit-dependent default. Because these defaults are
1827 difficult to get at without actually creating a scroll
1828 bar, use nil to indicate that no color has been
1829 specified. */
1830 tem = Qnil;
1833 #else /* not USE_TOOLKIT_SCROLL_BARS */
1835 tem = Qnil;
1837 #endif /* not USE_TOOLKIT_SCROLL_BARS */
1840 x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));
1841 return tem;
1847 #ifdef USE_X_TOOLKIT
1849 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
1850 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
1851 already be present because of the toolkit (Motif adds some of them,
1852 for example, but Xt doesn't). */
1854 static void
1855 hack_wm_protocols (f, widget)
1856 FRAME_PTR f;
1857 Widget widget;
1859 Display *dpy = XtDisplay (widget);
1860 Window w = XtWindow (widget);
1861 int need_delete = 1;
1862 int need_focus = 1;
1863 int need_save = 1;
1865 BLOCK_INPUT;
1867 Atom type;
1868 unsigned char *catoms;
1869 int format = 0;
1870 unsigned long nitems = 0;
1871 unsigned long bytes_after;
1873 if ((XGetWindowProperty (dpy, w,
1874 FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
1875 (long)0, (long)100, False, XA_ATOM,
1876 &type, &format, &nitems, &bytes_after,
1877 &catoms)
1878 == Success)
1879 && format == 32 && type == XA_ATOM)
1881 Atom *atoms = (Atom *) catoms;
1882 while (nitems > 0)
1884 nitems--;
1885 if (atoms[nitems]
1886 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window)
1887 need_delete = 0;
1888 else if (atoms[nitems]
1889 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus)
1890 need_focus = 0;
1891 else if (atoms[nitems]
1892 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself)
1893 need_save = 0;
1896 if (catoms)
1897 XFree (catoms);
1900 Atom props [10];
1901 int count = 0;
1902 if (need_delete)
1903 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window;
1904 if (need_focus)
1905 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus;
1906 if (need_save)
1907 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
1908 if (count)
1909 XChangeProperty (dpy, w, FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
1910 XA_ATOM, 32, PropModeAppend,
1911 (unsigned char *) props, count);
1913 UNBLOCK_INPUT;
1915 #endif
1919 /* Support routines for XIC (X Input Context). */
1921 #ifdef HAVE_X_I18N
1923 static XFontSet xic_create_xfontset P_ ((struct frame *));
1924 static XIMStyle best_xim_style P_ ((XIMStyles *, XIMStyles *));
1927 /* Supported XIM styles, ordered by preference. */
1929 static XIMStyle supported_xim_styles[] =
1931 XIMPreeditPosition | XIMStatusArea,
1932 XIMPreeditPosition | XIMStatusNothing,
1933 XIMPreeditPosition | XIMStatusNone,
1934 XIMPreeditNothing | XIMStatusArea,
1935 XIMPreeditNothing | XIMStatusNothing,
1936 XIMPreeditNothing | XIMStatusNone,
1937 XIMPreeditNone | XIMStatusArea,
1938 XIMPreeditNone | XIMStatusNothing,
1939 XIMPreeditNone | XIMStatusNone,
1944 /* Create an X fontset on frame F with base font name BASE_FONTNAME. */
1946 char xic_defaut_fontset[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
1948 /* Create an Xt fontset spec from the name of a base font.
1949 If `motif' is True use the Motif syntax. */
1950 char *
1951 xic_create_fontsetname (base_fontname, motif)
1952 char *base_fontname;
1953 Bool motif;
1955 const char *sep = motif ? ";" : ",";
1956 char *fontsetname;
1958 /* Make a fontset name from the base font name. */
1959 if (xic_defaut_fontset == base_fontname)
1960 { /* There is no base font name, use the default. */
1961 int len = strlen (base_fontname) + 2;
1962 fontsetname = xmalloc (len);
1963 bzero (fontsetname, len);
1964 strcpy (fontsetname, base_fontname);
1966 else
1968 /* Make a fontset name from the base font name.
1969 The font set will be made of the following elements:
1970 - the base font.
1971 - the base font where the charset spec is replaced by -*-*.
1972 - the same but with the family also replaced with -*-*-. */
1973 char *p = base_fontname;
1974 int i;
1976 for (i = 0; *p; p++)
1977 if (*p == '-') i++;
1978 if (i != 14)
1979 { /* As the font name doesn't conform to XLFD, we can't
1980 modify it to generalize it to allcs and allfamilies.
1981 Use the specified font plus the default. */
1982 int len = strlen (base_fontname) + strlen (xic_defaut_fontset) + 3;
1983 fontsetname = xmalloc (len);
1984 bzero (fontsetname, len);
1985 strcpy (fontsetname, base_fontname);
1986 strcat (fontsetname, sep);
1987 strcat (fontsetname, xic_defaut_fontset);
1989 else
1991 int len;
1992 char *p1 = NULL, *p2 = NULL, *p3 = NULL;
1993 char *font_allcs = NULL;
1994 char *font_allfamilies = NULL;
1995 char *font_all = NULL;
1996 char *allcs = "*-*-*-*-*-*-*";
1997 char *allfamilies = "-*-*-";
1998 char *all = "*-*-*-*-";
1999 char *base;
2001 for (i = 0, p = base_fontname; i < 8; p++)
2003 if (*p == '-')
2005 i++;
2006 if (i == 3)
2007 p1 = p + 1;
2008 else if (i == 7)
2009 p2 = p + 1;
2010 else if (i == 6)
2011 p3 = p + 1;
2014 /* If base_fontname specifies ADSTYLE, make it a
2015 wildcard. */
2016 if (*p3 != '*')
2018 int diff = (p2 - p3) - 2;
2020 base = alloca (strlen (base_fontname) + 1);
2021 bcopy (base_fontname, base, p3 - base_fontname);
2022 base[p3 - base_fontname] = '*';
2023 base[(p3 - base_fontname) + 1] = '-';
2024 strcpy (base + (p3 - base_fontname) + 2, p2);
2025 p = base + (p - base_fontname) - diff;
2026 p1 = base + (p1 - base_fontname);
2027 p2 = base + (p2 - base_fontname) - diff;
2028 base_fontname = base;
2031 /* Build the font spec that matches all charsets. */
2032 len = p - base_fontname + strlen (allcs) + 1;
2033 font_allcs = (char *) alloca (len);
2034 bzero (font_allcs, len);
2035 bcopy (base_fontname, font_allcs, p - base_fontname);
2036 strcat (font_allcs, allcs);
2038 /* Build the font spec that matches all families and
2039 add-styles. */
2040 len = p - p1 + strlen (allcs) + strlen (allfamilies) + 1;
2041 font_allfamilies = (char *) alloca (len);
2042 bzero (font_allfamilies, len);
2043 strcpy (font_allfamilies, allfamilies);
2044 bcopy (p1, font_allfamilies + strlen (allfamilies), p - p1);
2045 strcat (font_allfamilies, allcs);
2047 /* Build the font spec that matches all. */
2048 len = p - p2 + strlen (allcs) + strlen (all) + strlen (allfamilies) + 1;
2049 font_all = (char *) alloca (len);
2050 bzero (font_all, len);
2051 strcpy (font_all, allfamilies);
2052 strcat (font_all, all);
2053 bcopy (p2, font_all + strlen (all) + strlen (allfamilies), p - p2);
2054 strcat (font_all, allcs);
2056 /* Build the actual font set name. */
2057 len = strlen (base_fontname) + strlen (font_allcs)
2058 + strlen (font_allfamilies) + strlen (font_all) + 5;
2059 fontsetname = xmalloc (len);
2060 bzero (fontsetname, len);
2061 strcpy (fontsetname, base_fontname);
2062 strcat (fontsetname, sep);
2063 strcat (fontsetname, font_allcs);
2064 strcat (fontsetname, sep);
2065 strcat (fontsetname, font_allfamilies);
2066 strcat (fontsetname, sep);
2067 strcat (fontsetname, font_all);
2070 if (motif)
2071 strcat (fontsetname, ":");
2072 return fontsetname;
2075 #ifdef DEBUG_XIC_FONTSET
2076 static void
2077 print_fontset_result (xfs, name, missing_list, missing_count)
2078 XFontSet xfs;
2079 char *name;
2080 char **missing_list;
2081 int missing_count;
2083 if (xfs)
2084 fprintf (stderr, "XIC Fontset created: %s\n", name);
2085 else
2087 fprintf (stderr, "XIC Fontset failed: %s\n", name);
2088 while (missing_count-- > 0)
2090 fprintf (stderr, " missing: %s\n", *missing_list);
2091 missing_list++;
2096 #endif
2098 static XFontSet
2099 xic_create_xfontset (f)
2100 struct frame *f;
2102 XFontSet xfs = NULL;
2103 struct font *font = FRAME_FONT (f);
2104 int pixel_size = font->pixel_size;
2105 Lisp_Object rest, frame;
2107 /* See if there is another frame already using same fontset. */
2108 FOR_EACH_FRAME (rest, frame)
2110 struct frame *cf = XFRAME (frame);
2112 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
2113 && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f)
2114 && FRAME_FONT (f)
2115 && FRAME_FONT (f)->pixel_size == pixel_size)
2117 xfs = FRAME_XIC_FONTSET (cf);
2118 break;
2122 if (! xfs)
2124 char buf[256];
2125 char **missing_list;
2126 int missing_count;
2127 char *def_string;
2128 char *xlfd_format = "-*-*-medium-r-normal--%d-*-*-*-*-*";
2130 sprintf (buf, xlfd_format, pixel_size);
2131 missing_list = NULL;
2132 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
2133 &missing_list, &missing_count, &def_string);
2134 #ifdef DEBUG_XIC_FONTSET
2135 print_fontset_result (xfs, buf, missing_list, missing_count);
2136 #endif
2137 if (missing_list)
2138 XFreeStringList (missing_list);
2139 if (! xfs)
2141 /* List of pixel sizes most likely available. Find one that
2142 is closest to pixel_size. */
2143 int sizes[] = {0, 8, 10, 11, 12, 14, 17, 18, 20, 24, 26, 34, 0};
2144 int *smaller, *larger;
2146 for (smaller = sizes; smaller[1]; smaller++)
2147 if (smaller[1] >= pixel_size)
2148 break;
2149 larger = smaller + 1;
2150 if (*larger == pixel_size)
2151 larger++;
2152 while (*smaller || *larger)
2154 int this_size;
2156 if (! *larger)
2157 this_size = *smaller--;
2158 else if (! *smaller)
2159 this_size = *larger++;
2160 else if (pixel_size - *smaller < *larger - pixel_size)
2161 this_size = *smaller--;
2162 else
2163 this_size = *larger++;
2164 sprintf (buf, xlfd_format, this_size);
2165 missing_list = NULL;
2166 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
2167 &missing_list, &missing_count, &def_string);
2168 #ifdef DEBUG_XIC_FONTSET
2169 print_fontset_result (xfs, buf, missing_list, missing_count);
2170 #endif
2171 if (missing_list)
2172 XFreeStringList (missing_list);
2173 if (xfs)
2174 break;
2177 if (! xfs)
2179 char *last_resort = "-*-*-*-r-normal--*-*-*-*-*-*";
2181 missing_list = NULL;
2182 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), last_resort,
2183 &missing_list, &missing_count, &def_string);
2184 #ifdef DEBUG_XIC_FONTSET
2185 print_fontset_result (xfs, last_resort, missing_list, missing_count);
2186 #endif
2187 if (missing_list)
2188 XFreeStringList (missing_list);
2193 return xfs;
2196 /* Free the X fontset of frame F if it is the last frame using it. */
2198 void
2199 xic_free_xfontset (f)
2200 struct frame *f;
2202 Lisp_Object rest, frame;
2203 int shared_p = 0;
2205 if (!FRAME_XIC_FONTSET (f))
2206 return;
2208 /* See if there is another frame sharing the same fontset. */
2209 FOR_EACH_FRAME (rest, frame)
2211 struct frame *cf = XFRAME (frame);
2212 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
2213 && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f)
2214 && FRAME_XIC_FONTSET (cf) == FRAME_XIC_FONTSET (f))
2216 shared_p = 1;
2217 break;
2221 if (!shared_p)
2222 /* The fontset is not used anymore. It is safe to free it. */
2223 XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f));
2225 if (FRAME_XIC_BASE_FONTNAME (f))
2226 xfree (FRAME_XIC_BASE_FONTNAME (f));
2227 FRAME_XIC_BASE_FONTNAME (f) = NULL;
2228 FRAME_XIC_FONTSET (f) = NULL;
2232 /* Value is the best input style, given user preferences USER (already
2233 checked to be supported by Emacs), and styles supported by the
2234 input method XIM. */
2236 static XIMStyle
2237 best_xim_style (user, xim)
2238 XIMStyles *user;
2239 XIMStyles *xim;
2241 int i, j;
2243 for (i = 0; i < user->count_styles; ++i)
2244 for (j = 0; j < xim->count_styles; ++j)
2245 if (user->supported_styles[i] == xim->supported_styles[j])
2246 return user->supported_styles[i];
2248 /* Return the default style. */
2249 return XIMPreeditNothing | XIMStatusNothing;
2252 /* Create XIC for frame F. */
2254 static XIMStyle xic_style;
2256 void
2257 create_frame_xic (f)
2258 struct frame *f;
2260 XIM xim;
2261 XIC xic = NULL;
2262 XFontSet xfs = NULL;
2264 if (FRAME_XIC (f))
2265 return;
2267 /* Create X fontset. */
2268 xfs = xic_create_xfontset (f);
2269 xim = FRAME_X_XIM (f);
2270 if (xim)
2272 XRectangle s_area;
2273 XPoint spot;
2274 XVaNestedList preedit_attr;
2275 XVaNestedList status_attr;
2277 s_area.x = 0; s_area.y = 0; s_area.width = 1; s_area.height = 1;
2278 spot.x = 0; spot.y = 1;
2280 /* Determine XIC style. */
2281 if (xic_style == 0)
2283 XIMStyles supported_list;
2284 supported_list.count_styles = (sizeof supported_xim_styles
2285 / sizeof supported_xim_styles[0]);
2286 supported_list.supported_styles = supported_xim_styles;
2287 xic_style = best_xim_style (&supported_list,
2288 FRAME_X_XIM_STYLES (f));
2291 preedit_attr = XVaCreateNestedList (0,
2292 XNFontSet, xfs,
2293 XNForeground,
2294 FRAME_FOREGROUND_PIXEL (f),
2295 XNBackground,
2296 FRAME_BACKGROUND_PIXEL (f),
2297 (xic_style & XIMPreeditPosition
2298 ? XNSpotLocation
2299 : NULL),
2300 &spot,
2301 NULL);
2302 status_attr = XVaCreateNestedList (0,
2303 XNArea,
2304 &s_area,
2305 XNFontSet,
2306 xfs,
2307 XNForeground,
2308 FRAME_FOREGROUND_PIXEL (f),
2309 XNBackground,
2310 FRAME_BACKGROUND_PIXEL (f),
2311 NULL);
2313 xic = XCreateIC (xim,
2314 XNInputStyle, xic_style,
2315 XNClientWindow, FRAME_X_WINDOW (f),
2316 XNFocusWindow, FRAME_X_WINDOW (f),
2317 XNStatusAttributes, status_attr,
2318 XNPreeditAttributes, preedit_attr,
2319 NULL);
2320 XFree (preedit_attr);
2321 XFree (status_attr);
2324 FRAME_XIC (f) = xic;
2325 FRAME_XIC_STYLE (f) = xic_style;
2326 FRAME_XIC_FONTSET (f) = xfs;
2330 /* Destroy XIC and free XIC fontset of frame F, if any. */
2332 void
2333 free_frame_xic (f)
2334 struct frame *f;
2336 if (FRAME_XIC (f) == NULL)
2337 return;
2339 XDestroyIC (FRAME_XIC (f));
2340 xic_free_xfontset (f);
2342 FRAME_XIC (f) = NULL;
2346 /* Place preedit area for XIC of window W's frame to specified
2347 pixel position X/Y. X and Y are relative to window W. */
2349 void
2350 xic_set_preeditarea (w, x, y)
2351 struct window *w;
2352 int x, y;
2354 struct frame *f = XFRAME (w->frame);
2355 XVaNestedList attr;
2356 XPoint spot;
2358 spot.x = WINDOW_TO_FRAME_PIXEL_X (w, x) + WINDOW_LEFT_FRINGE_WIDTH (w);
2359 spot.y = WINDOW_TO_FRAME_PIXEL_Y (w, y) + FONT_BASE (FRAME_FONT (f));
2360 attr = XVaCreateNestedList (0, XNSpotLocation, &spot, NULL);
2361 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2362 XFree (attr);
2366 /* Place status area for XIC in bottom right corner of frame F.. */
2368 void
2369 xic_set_statusarea (f)
2370 struct frame *f;
2372 XIC xic = FRAME_XIC (f);
2373 XVaNestedList attr;
2374 XRectangle area;
2375 XRectangle *needed;
2377 /* Negotiate geometry of status area. If input method has existing
2378 status area, use its current size. */
2379 area.x = area.y = area.width = area.height = 0;
2380 attr = XVaCreateNestedList (0, XNAreaNeeded, &area, NULL);
2381 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2382 XFree (attr);
2384 attr = XVaCreateNestedList (0, XNAreaNeeded, &needed, NULL);
2385 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2386 XFree (attr);
2388 if (needed->width == 0) /* Use XNArea instead of XNAreaNeeded */
2390 attr = XVaCreateNestedList (0, XNArea, &needed, NULL);
2391 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2392 XFree (attr);
2395 area.width = needed->width;
2396 area.height = needed->height;
2397 area.x = FRAME_PIXEL_WIDTH (f) - area.width - FRAME_INTERNAL_BORDER_WIDTH (f);
2398 area.y = (FRAME_PIXEL_HEIGHT (f) - area.height
2399 - FRAME_MENUBAR_HEIGHT (f)
2400 - FRAME_TOOLBAR_HEIGHT (f)
2401 - FRAME_INTERNAL_BORDER_WIDTH (f));
2402 XFree (needed);
2404 attr = XVaCreateNestedList (0, XNArea, &area, NULL);
2405 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2406 XFree (attr);
2410 /* Set X fontset for XIC of frame F, using base font name
2411 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2413 void
2414 xic_set_xfontset (f, base_fontname)
2415 struct frame *f;
2416 char *base_fontname;
2418 XVaNestedList attr;
2419 XFontSet xfs;
2421 xic_free_xfontset (f);
2423 xfs = xic_create_xfontset (f);
2425 attr = XVaCreateNestedList (0, XNFontSet, xfs, NULL);
2426 if (FRAME_XIC_STYLE (f) & XIMPreeditPosition)
2427 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2428 if (FRAME_XIC_STYLE (f) & XIMStatusArea)
2429 XSetICValues (FRAME_XIC (f), XNStatusAttributes, attr, NULL);
2430 XFree (attr);
2432 FRAME_XIC_FONTSET (f) = xfs;
2435 #endif /* HAVE_X_I18N */
2439 #ifdef USE_X_TOOLKIT
2441 /* Create and set up the X widget for frame F. */
2443 static void
2444 x_window (f, window_prompting, minibuffer_only)
2445 struct frame *f;
2446 long window_prompting;
2447 int minibuffer_only;
2449 XClassHint class_hints;
2450 XSetWindowAttributes attributes;
2451 unsigned long attribute_mask;
2452 Widget shell_widget;
2453 Widget pane_widget;
2454 Widget frame_widget;
2455 Arg al [25];
2456 int ac;
2458 BLOCK_INPUT;
2460 /* Use the resource name as the top-level widget name
2461 for looking up resources. Make a non-Lisp copy
2462 for the window manager, so GC relocation won't bother it.
2464 Elsewhere we specify the window name for the window manager. */
2467 char *str = (char *) SDATA (Vx_resource_name);
2468 f->namebuf = (char *) xmalloc (strlen (str) + 1);
2469 strcpy (f->namebuf, str);
2472 ac = 0;
2473 XtSetArg (al[ac], XtNallowShellResize, 1); ac++;
2474 XtSetArg (al[ac], XtNinput, 1); ac++;
2475 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2476 XtSetArg (al[ac], XtNborderWidth, f->border_width); ac++;
2477 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2478 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2479 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2480 shell_widget = XtAppCreateShell (f->namebuf, EMACS_CLASS,
2481 applicationShellWidgetClass,
2482 FRAME_X_DISPLAY (f), al, ac);
2484 f->output_data.x->widget = shell_widget;
2485 /* maybe_set_screen_title_format (shell_widget); */
2487 pane_widget = lw_create_widget ("main", "pane", widget_id_tick++,
2488 (widget_value *) NULL,
2489 shell_widget, False,
2490 (lw_callback) NULL,
2491 (lw_callback) NULL,
2492 (lw_callback) NULL,
2493 (lw_callback) NULL);
2495 ac = 0;
2496 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2497 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2498 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2499 XtSetValues (pane_widget, al, ac);
2500 f->output_data.x->column_widget = pane_widget;
2502 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2503 the emacs screen when changing menubar. This reduces flickering. */
2505 ac = 0;
2506 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2507 XtSetArg (al[ac], XtNshowGrip, 0); ac++;
2508 XtSetArg (al[ac], XtNallowResize, 1); ac++;
2509 XtSetArg (al[ac], XtNresizeToPreferred, 1); ac++;
2510 XtSetArg (al[ac], XtNemacsFrame, f); ac++;
2511 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2512 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2513 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2514 frame_widget = XtCreateWidget (f->namebuf, emacsFrameClass, pane_widget,
2515 al, ac);
2517 f->output_data.x->edit_widget = frame_widget;
2519 XtManageChild (frame_widget);
2521 /* Do some needed geometry management. */
2523 int len;
2524 char *tem, shell_position[32];
2525 Arg al[10];
2526 int ac = 0;
2527 int extra_borders = 0;
2528 int menubar_size
2529 = (f->output_data.x->menubar_widget
2530 ? (f->output_data.x->menubar_widget->core.height
2531 + f->output_data.x->menubar_widget->core.border_width)
2532 : 0);
2534 #if 0 /* Experimentally, we now get the right results
2535 for -geometry -0-0 without this. 24 Aug 96, rms. */
2536 if (FRAME_EXTERNAL_MENU_BAR (f))
2538 Dimension ibw = 0;
2539 XtVaGetValues (pane_widget, XtNinternalBorderWidth, &ibw, NULL);
2540 menubar_size += ibw;
2542 #endif
2544 f->output_data.x->menubar_height = menubar_size;
2546 #ifndef USE_LUCID
2547 /* Motif seems to need this amount added to the sizes
2548 specified for the shell widget. The Athena/Lucid widgets don't.
2549 Both conclusions reached experimentally. -- rms. */
2550 XtVaGetValues (f->output_data.x->edit_widget, XtNinternalBorderWidth,
2551 &extra_borders, NULL);
2552 extra_borders *= 2;
2553 #endif
2555 /* Convert our geometry parameters into a geometry string
2556 and specify it.
2557 Note that we do not specify here whether the position
2558 is a user-specified or program-specified one.
2559 We pass that information later, in x_wm_set_size_hints. */
2561 int left = f->left_pos;
2562 int xneg = window_prompting & XNegative;
2563 int top = f->top_pos;
2564 int yneg = window_prompting & YNegative;
2565 if (xneg)
2566 left = -left;
2567 if (yneg)
2568 top = -top;
2570 if (window_prompting & USPosition)
2571 sprintf (shell_position, "=%dx%d%c%d%c%d",
2572 FRAME_PIXEL_WIDTH (f) + extra_borders,
2573 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders,
2574 (xneg ? '-' : '+'), left,
2575 (yneg ? '-' : '+'), top);
2576 else
2578 sprintf (shell_position, "=%dx%d",
2579 FRAME_PIXEL_WIDTH (f) + extra_borders,
2580 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders);
2582 /* Setting x and y when the position is not specified in
2583 the geometry string will set program position in the WM hints.
2584 If Emacs had just one program position, we could set it in
2585 fallback resources, but since each make-frame call can specify
2586 different program positions, this is easier. */
2587 XtSetArg (al[ac], XtNx, left); ac++;
2588 XtSetArg (al[ac], XtNy, top); ac++;
2592 len = strlen (shell_position) + 1;
2593 /* We don't free this because we don't know whether
2594 it is safe to free it while the frame exists.
2595 It isn't worth the trouble of arranging to free it
2596 when the frame is deleted. */
2597 tem = (char *) xmalloc (len);
2598 strncpy (tem, shell_position, len);
2599 XtSetArg (al[ac], XtNgeometry, tem); ac++;
2600 XtSetValues (shell_widget, al, ac);
2603 XtManageChild (pane_widget);
2604 XtRealizeWidget (shell_widget);
2606 if (FRAME_X_EMBEDDED_P (f))
2607 XReparentWindow (FRAME_X_DISPLAY (f), XtWindow (shell_widget),
2608 f->output_data.x->parent_desc, 0, 0);
2610 FRAME_X_WINDOW (f) = XtWindow (frame_widget);
2612 validate_x_resource_name ();
2614 class_hints.res_name = (char *) SDATA (Vx_resource_name);
2615 class_hints.res_class = (char *) SDATA (Vx_resource_class);
2616 XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints);
2618 #ifdef HAVE_X_I18N
2619 FRAME_XIC (f) = NULL;
2620 if (use_xim)
2621 create_frame_xic (f);
2622 #endif
2624 f->output_data.x->wm_hints.input = True;
2625 f->output_data.x->wm_hints.flags |= InputHint;
2626 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2627 &f->output_data.x->wm_hints);
2629 hack_wm_protocols (f, shell_widget);
2631 #ifdef HACK_EDITRES
2632 XtAddEventHandler (shell_widget, 0, True, _XEditResCheckMessages, 0);
2633 #endif
2635 /* Do a stupid property change to force the server to generate a
2636 PropertyNotify event so that the event_stream server timestamp will
2637 be initialized to something relevant to the time we created the window.
2639 XChangeProperty (XtDisplay (frame_widget), XtWindow (frame_widget),
2640 FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
2641 XA_ATOM, 32, PropModeAppend,
2642 (unsigned char*) NULL, 0);
2644 /* Make all the standard events reach the Emacs frame. */
2645 attributes.event_mask = STANDARD_EVENT_SET;
2647 #ifdef HAVE_X_I18N
2648 if (FRAME_XIC (f))
2650 /* XIM server might require some X events. */
2651 unsigned long fevent = NoEventMask;
2652 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2653 attributes.event_mask |= fevent;
2655 #endif /* HAVE_X_I18N */
2657 attribute_mask = CWEventMask;
2658 XChangeWindowAttributes (XtDisplay (shell_widget), XtWindow (shell_widget),
2659 attribute_mask, &attributes);
2661 XtMapWidget (frame_widget);
2663 /* x_set_name normally ignores requests to set the name if the
2664 requested name is the same as the current name. This is the one
2665 place where that assumption isn't correct; f->name is set, but
2666 the X server hasn't been told. */
2668 Lisp_Object name;
2669 int explicit = f->explicit_name;
2671 f->explicit_name = 0;
2672 name = f->name;
2673 f->name = Qnil;
2674 x_set_name (f, name, explicit);
2677 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2678 f->output_data.x->text_cursor);
2680 UNBLOCK_INPUT;
2682 /* This is a no-op, except under Motif. Make sure main areas are
2683 set to something reasonable, in case we get an error later. */
2684 lw_set_main_areas (pane_widget, 0, frame_widget);
2687 #else /* not USE_X_TOOLKIT */
2688 #ifdef USE_GTK
2689 void
2690 x_window (f)
2691 FRAME_PTR f;
2693 if (! xg_create_frame_widgets (f))
2694 error ("Unable to create window");
2696 #ifdef HAVE_X_I18N
2697 FRAME_XIC (f) = NULL;
2698 if (use_xim)
2700 BLOCK_INPUT;
2701 create_frame_xic (f);
2702 if (FRAME_XIC (f))
2704 /* XIM server might require some X events. */
2705 unsigned long fevent = NoEventMask;
2706 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2708 if (fevent != NoEventMask)
2710 XSetWindowAttributes attributes;
2711 XWindowAttributes wattr;
2712 unsigned long attribute_mask;
2714 XGetWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2715 &wattr);
2716 attributes.event_mask = wattr.your_event_mask | fevent;
2717 attribute_mask = CWEventMask;
2718 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2719 attribute_mask, &attributes);
2722 UNBLOCK_INPUT;
2724 #endif
2727 #else /*! USE_GTK */
2728 /* Create and set up the X window for frame F. */
2730 void
2731 x_window (f)
2732 struct frame *f;
2735 XClassHint class_hints;
2736 XSetWindowAttributes attributes;
2737 unsigned long attribute_mask;
2739 attributes.background_pixel = FRAME_BACKGROUND_PIXEL (f);
2740 attributes.border_pixel = f->output_data.x->border_pixel;
2741 attributes.bit_gravity = StaticGravity;
2742 attributes.backing_store = NotUseful;
2743 attributes.save_under = True;
2744 attributes.event_mask = STANDARD_EVENT_SET;
2745 attributes.colormap = FRAME_X_COLORMAP (f);
2746 attribute_mask = (CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask
2747 | CWColormap);
2749 BLOCK_INPUT;
2750 FRAME_X_WINDOW (f)
2751 = XCreateWindow (FRAME_X_DISPLAY (f),
2752 f->output_data.x->parent_desc,
2753 f->left_pos,
2754 f->top_pos,
2755 FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
2756 f->border_width,
2757 CopyFromParent, /* depth */
2758 InputOutput, /* class */
2759 FRAME_X_VISUAL (f),
2760 attribute_mask, &attributes);
2762 #ifdef HAVE_X_I18N
2763 if (use_xim)
2765 create_frame_xic (f);
2766 if (FRAME_XIC (f))
2768 /* XIM server might require some X events. */
2769 unsigned long fevent = NoEventMask;
2770 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2771 attributes.event_mask |= fevent;
2772 attribute_mask = CWEventMask;
2773 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2774 attribute_mask, &attributes);
2777 #endif /* HAVE_X_I18N */
2779 validate_x_resource_name ();
2781 class_hints.res_name = (char *) SDATA (Vx_resource_name);
2782 class_hints.res_class = (char *) SDATA (Vx_resource_class);
2783 XSetClassHint (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &class_hints);
2785 /* The menubar is part of the ordinary display;
2786 it does not count in addition to the height of the window. */
2787 f->output_data.x->menubar_height = 0;
2789 /* This indicates that we use the "Passive Input" input model.
2790 Unless we do this, we don't get the Focus{In,Out} events that we
2791 need to draw the cursor correctly. Accursed bureaucrats.
2792 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2794 f->output_data.x->wm_hints.input = True;
2795 f->output_data.x->wm_hints.flags |= InputHint;
2796 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2797 &f->output_data.x->wm_hints);
2798 f->output_data.x->wm_hints.icon_pixmap = None;
2800 /* Request "save yourself" and "delete window" commands from wm. */
2802 Atom protocols[2];
2803 protocols[0] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window;
2804 protocols[1] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
2805 XSetWMProtocols (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), protocols, 2);
2808 /* x_set_name normally ignores requests to set the name if the
2809 requested name is the same as the current name. This is the one
2810 place where that assumption isn't correct; f->name is set, but
2811 the X server hasn't been told. */
2813 Lisp_Object name;
2814 int explicit = f->explicit_name;
2816 f->explicit_name = 0;
2817 name = f->name;
2818 f->name = Qnil;
2819 x_set_name (f, name, explicit);
2822 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2823 f->output_data.x->text_cursor);
2825 UNBLOCK_INPUT;
2827 if (FRAME_X_WINDOW (f) == 0)
2828 error ("Unable to create window");
2831 #endif /* not USE_GTK */
2832 #endif /* not USE_X_TOOLKIT */
2834 /* Verify that the icon position args for this window are valid. */
2836 static void
2837 x_icon_verify (f, parms)
2838 struct frame *f;
2839 Lisp_Object parms;
2841 Lisp_Object icon_x, icon_y;
2843 /* Set the position of the icon. Note that twm groups all
2844 icons in an icon window. */
2845 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2846 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2847 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2849 CHECK_NUMBER (icon_x);
2850 CHECK_NUMBER (icon_y);
2852 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2853 error ("Both left and top icon corners of icon must be specified");
2856 /* Handle the icon stuff for this window. Perhaps later we might
2857 want an x_set_icon_position which can be called interactively as
2858 well. */
2860 static void
2861 x_icon (f, parms)
2862 struct frame *f;
2863 Lisp_Object parms;
2865 Lisp_Object icon_x, icon_y;
2866 #if 0
2867 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2868 #endif
2870 /* Set the position of the icon. Note that twm groups all
2871 icons in an icon window. */
2872 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2873 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2874 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2876 CHECK_NUMBER (icon_x);
2877 CHECK_NUMBER (icon_y);
2879 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2880 error ("Both left and top icon corners of icon must be specified");
2882 BLOCK_INPUT;
2884 if (! EQ (icon_x, Qunbound))
2885 x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
2887 #if 0 /* x_get_arg removes the visibility parameter as a side effect,
2888 but x_create_frame still needs it. */
2889 /* Start up iconic or window? */
2890 x_wm_set_window_state
2891 (f, (EQ (x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL),
2892 Qicon)
2893 ? IconicState
2894 : NormalState));
2895 #endif
2897 x_text_icon (f, (char *) SDATA ((!NILP (f->icon_name)
2898 ? f->icon_name
2899 : f->name)));
2901 UNBLOCK_INPUT;
2904 /* Make the GCs needed for this window, setting the
2905 background, border and mouse colors; also create the
2906 mouse cursor and the gray border tile. */
2908 static char cursor_bits[] =
2910 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2911 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2912 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2913 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2916 static void
2917 x_make_gc (f)
2918 struct frame *f;
2920 XGCValues gc_values;
2922 BLOCK_INPUT;
2924 /* Create the GCs of this frame.
2925 Note that many default values are used. */
2927 gc_values.foreground = FRAME_FOREGROUND_PIXEL (f);
2928 gc_values.background = FRAME_BACKGROUND_PIXEL (f);
2929 gc_values.line_width = 0; /* Means 1 using fast algorithm. */
2930 f->output_data.x->normal_gc
2931 = XCreateGC (FRAME_X_DISPLAY (f),
2932 FRAME_X_WINDOW (f),
2933 GCLineWidth | GCForeground | GCBackground,
2934 &gc_values);
2936 /* Reverse video style. */
2937 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2938 gc_values.background = FRAME_FOREGROUND_PIXEL (f);
2939 f->output_data.x->reverse_gc
2940 = XCreateGC (FRAME_X_DISPLAY (f),
2941 FRAME_X_WINDOW (f),
2942 GCForeground | GCBackground | GCLineWidth,
2943 &gc_values);
2945 /* Cursor has cursor-color background, background-color foreground. */
2946 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2947 gc_values.background = f->output_data.x->cursor_pixel;
2948 gc_values.fill_style = FillOpaqueStippled;
2949 gc_values.stipple
2950 = XCreateBitmapFromData (FRAME_X_DISPLAY (f),
2951 FRAME_X_DISPLAY_INFO (f)->root_window,
2952 cursor_bits, 16, 16);
2953 f->output_data.x->cursor_gc
2954 = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2955 (GCForeground | GCBackground
2956 | GCFillStyle /* | GCStipple */ | GCLineWidth),
2957 &gc_values);
2959 /* Reliefs. */
2960 f->output_data.x->white_relief.gc = 0;
2961 f->output_data.x->black_relief.gc = 0;
2963 /* Create the gray border tile used when the pointer is not in
2964 the frame. Since this depends on the frame's pixel values,
2965 this must be done on a per-frame basis. */
2966 f->output_data.x->border_tile
2967 = (XCreatePixmapFromBitmapData
2968 (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
2969 gray_bits, gray_width, gray_height,
2970 FRAME_FOREGROUND_PIXEL (f),
2971 FRAME_BACKGROUND_PIXEL (f),
2972 DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
2974 UNBLOCK_INPUT;
2978 /* Free what was was allocated in x_make_gc. */
2980 void
2981 x_free_gcs (f)
2982 struct frame *f;
2984 Display *dpy = FRAME_X_DISPLAY (f);
2986 BLOCK_INPUT;
2988 if (f->output_data.x->normal_gc)
2990 XFreeGC (dpy, f->output_data.x->normal_gc);
2991 f->output_data.x->normal_gc = 0;
2994 if (f->output_data.x->reverse_gc)
2996 XFreeGC (dpy, f->output_data.x->reverse_gc);
2997 f->output_data.x->reverse_gc = 0;
3000 if (f->output_data.x->cursor_gc)
3002 XFreeGC (dpy, f->output_data.x->cursor_gc);
3003 f->output_data.x->cursor_gc = 0;
3006 if (f->output_data.x->border_tile)
3008 XFreePixmap (dpy, f->output_data.x->border_tile);
3009 f->output_data.x->border_tile = 0;
3012 UNBLOCK_INPUT;
3016 /* Handler for signals raised during x_create_frame and
3017 x_create_top_frame. FRAME is the frame which is partially
3018 constructed. */
3020 static Lisp_Object
3021 unwind_create_frame (frame)
3022 Lisp_Object frame;
3024 struct frame *f = XFRAME (frame);
3026 /* If frame is already dead, nothing to do. This can happen if the
3027 display is disconnected after the frame has become official, but
3028 before x_create_frame removes the unwind protect. */
3029 if (!FRAME_LIVE_P (f))
3030 return Qnil;
3032 /* If frame is ``official'', nothing to do. */
3033 if (!CONSP (Vframe_list) || !EQ (XCAR (Vframe_list), frame))
3035 #if GLYPH_DEBUG
3036 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3037 #endif
3039 x_free_frame_resources (f);
3041 #if GLYPH_DEBUG
3042 /* Check that reference counts are indeed correct. */
3043 xassert (dpyinfo->reference_count == dpyinfo_refcount);
3044 xassert (dpyinfo->image_cache->refcount == image_cache_refcount);
3045 #endif
3046 return Qt;
3049 return Qnil;
3053 static void
3054 x_default_font_parameter (f, parms)
3055 struct frame *f;
3056 Lisp_Object parms;
3058 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3059 Lisp_Object font_param = x_get_arg (dpyinfo, parms, Qfont, NULL, NULL,
3060 RES_TYPE_STRING);
3061 Lisp_Object font;
3062 if (EQ (font_param, Qunbound))
3063 font_param = Qnil;
3064 font = !NILP (font_param) ? font_param
3065 : x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
3067 if (! STRINGP (font))
3069 char *names[]
3071 #ifdef HAVE_XFT
3072 /* This will find the normal Xft font. */
3073 "monospace-12",
3074 #endif
3075 "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
3076 "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3077 "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3078 /* This was formerly the first thing tried, but it finds
3079 too many fonts and takes too long. */
3080 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
3081 /* If those didn't work, look for something which will
3082 at least work. */
3083 "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
3084 "fixed",
3085 NULL };
3086 int i;
3088 for (i = 0; names[i]; i++)
3090 font = font_open_by_name (f, names[i]);
3091 if (! NILP (font))
3092 break;
3094 if (NILP (font))
3095 error ("No suitable font was found");
3097 else if (!NILP (font_param))
3099 /* Remember the explicit font parameter, so we can re-apply it after
3100 we've applied the `default' face settings. */
3101 x_set_frame_parameters (f, Fcons (Fcons (Qfont_param, font_param), Qnil));
3103 x_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING);
3107 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
3108 1, 1, 0,
3109 doc: /* Make a new X window, which is called a "frame" in Emacs terms.
3110 Return an Emacs frame object.
3111 PARMS is an alist of frame parameters.
3112 If the parameters specify that the frame should not have a minibuffer,
3113 and do not specify a specific minibuffer window to use,
3114 then `default-minibuffer-frame' must be a frame whose minibuffer can
3115 be shared by the new frame.
3117 This function is an internal primitive--use `make-frame' instead. */)
3118 (parms)
3119 Lisp_Object parms;
3121 struct frame *f;
3122 Lisp_Object frame, tem;
3123 Lisp_Object name;
3124 int minibuffer_only = 0;
3125 long window_prompting = 0;
3126 int width, height;
3127 int count = SPECPDL_INDEX ();
3128 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
3129 Lisp_Object display;
3130 struct x_display_info *dpyinfo = NULL;
3131 Lisp_Object parent;
3132 struct kboard *kb;
3134 parms = Fcopy_alist (parms);
3136 /* Use this general default value to start with
3137 until we know if this frame has a specified name. */
3138 Vx_resource_name = Vinvocation_name;
3140 display = x_get_arg (dpyinfo, parms, Qterminal, 0, 0, RES_TYPE_NUMBER);
3141 if (EQ (display, Qunbound))
3142 display = x_get_arg (dpyinfo, parms, Qdisplay, 0, 0, RES_TYPE_STRING);
3143 if (EQ (display, Qunbound))
3144 display = Qnil;
3145 dpyinfo = check_x_display_info (display);
3146 #ifdef MULTI_KBOARD
3147 kb = dpyinfo->terminal->kboard;
3148 #else
3149 kb = &the_only_kboard;
3150 #endif
3152 if (!dpyinfo->terminal->name)
3153 error ("Terminal is not live, can't create new frames on it");
3155 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
3156 if (!STRINGP (name)
3157 && ! EQ (name, Qunbound)
3158 && ! NILP (name))
3159 error ("Invalid frame name--not a string or nil");
3161 if (STRINGP (name))
3162 Vx_resource_name = name;
3164 /* See if parent window is specified. */
3165 parent = x_get_arg (dpyinfo, parms, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
3166 if (EQ (parent, Qunbound))
3167 parent = Qnil;
3168 if (! NILP (parent))
3169 CHECK_NUMBER (parent);
3171 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
3172 /* No need to protect DISPLAY because that's not used after passing
3173 it to make_frame_without_minibuffer. */
3174 frame = Qnil;
3175 GCPRO4 (parms, parent, name, frame);
3176 tem = x_get_arg (dpyinfo, parms, Qminibuffer, "minibuffer", "Minibuffer",
3177 RES_TYPE_SYMBOL);
3178 if (EQ (tem, Qnone) || NILP (tem))
3179 f = make_frame_without_minibuffer (Qnil, kb, display);
3180 else if (EQ (tem, Qonly))
3182 f = make_minibuffer_frame ();
3183 minibuffer_only = 1;
3185 else if (WINDOWP (tem))
3186 f = make_frame_without_minibuffer (tem, kb, display);
3187 else
3188 f = make_frame (1);
3190 XSETFRAME (frame, f);
3192 /* Note that X Windows does support scroll bars. */
3193 FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
3195 f->terminal = dpyinfo->terminal;
3196 f->terminal->reference_count++;
3198 f->output_method = output_x_window;
3199 f->output_data.x = (struct x_output *) xmalloc (sizeof (struct x_output));
3200 bzero (f->output_data.x, sizeof (struct x_output));
3201 f->output_data.x->icon_bitmap = -1;
3202 FRAME_FONTSET (f) = -1;
3203 f->output_data.x->scroll_bar_foreground_pixel = -1;
3204 f->output_data.x->scroll_bar_background_pixel = -1;
3205 #ifdef USE_TOOLKIT_SCROLL_BARS
3206 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
3207 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
3208 #endif /* USE_TOOLKIT_SCROLL_BARS */
3210 f->icon_name
3211 = x_get_arg (dpyinfo, parms, Qicon_name, "iconName", "Title",
3212 RES_TYPE_STRING);
3213 if (! STRINGP (f->icon_name))
3214 f->icon_name = Qnil;
3216 FRAME_X_DISPLAY_INFO (f) = dpyinfo;
3218 /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe. */
3219 record_unwind_protect (unwind_create_frame, frame);
3220 #if GLYPH_DEBUG
3221 image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
3222 dpyinfo_refcount = dpyinfo->reference_count;
3223 #endif /* GLYPH_DEBUG */
3225 /* These colors will be set anyway later, but it's important
3226 to get the color reference counts right, so initialize them! */
3228 Lisp_Object black;
3229 struct gcpro gcpro1;
3231 /* Function x_decode_color can signal an error. Make
3232 sure to initialize color slots so that we won't try
3233 to free colors we haven't allocated. */
3234 FRAME_FOREGROUND_PIXEL (f) = -1;
3235 FRAME_BACKGROUND_PIXEL (f) = -1;
3236 f->output_data.x->cursor_pixel = -1;
3237 f->output_data.x->cursor_foreground_pixel = -1;
3238 f->output_data.x->border_pixel = -1;
3239 f->output_data.x->mouse_pixel = -1;
3241 black = build_string ("black");
3242 GCPRO1 (black);
3243 FRAME_FOREGROUND_PIXEL (f)
3244 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3245 FRAME_BACKGROUND_PIXEL (f)
3246 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3247 f->output_data.x->cursor_pixel
3248 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3249 f->output_data.x->cursor_foreground_pixel
3250 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3251 f->output_data.x->border_pixel
3252 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3253 f->output_data.x->mouse_pixel
3254 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3255 UNGCPRO;
3258 /* Specify the parent under which to make this X window. */
3260 if (!NILP (parent))
3262 f->output_data.x->parent_desc = (Window) XFASTINT (parent);
3263 f->output_data.x->explicit_parent = 1;
3265 else
3267 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
3268 f->output_data.x->explicit_parent = 0;
3271 /* Set the name; the functions to which we pass f expect the name to
3272 be set. */
3273 if (EQ (name, Qunbound) || NILP (name))
3275 f->name = build_string (dpyinfo->x_id_name);
3276 f->explicit_name = 0;
3278 else
3280 f->name = name;
3281 f->explicit_name = 1;
3282 /* use the frame's title when getting resources for this frame. */
3283 specbind (Qx_resource_name, name);
3286 f->resx = dpyinfo->resx;
3287 f->resy = dpyinfo->resy;
3289 register_font_driver (&xfont_driver, f);
3290 #ifdef HAVE_FREETYPE
3291 #ifdef HAVE_XFT
3292 register_font_driver (&xftfont_driver, f);
3293 #else /* not HAVE_XFT */
3294 register_font_driver (&ftxfont_driver, f);
3295 #endif /* not HAVE_XFT */
3296 #endif /* HAVE_FREETYPE */
3298 x_default_parameter (f, parms, Qfont_backend, Qnil,
3299 "fontBackend", "FontBackend", RES_TYPE_STRING);
3301 /* Extract the window parameters from the supplied values
3302 that are needed to determine window geometry. */
3303 x_default_font_parameter (f, parms);
3305 #ifdef USE_LUCID
3306 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
3307 whereby it fails to get any font. */
3308 xlwmenu_default_font = XLoadQueryFont (FRAME_X_DISPLAY (f), "fixed");
3309 #endif
3311 /* Frame contents get displaced if an embedded X window has a border. */
3312 if (! FRAME_X_EMBEDDED_P (f))
3313 x_default_parameter (f, parms, Qborder_width, make_number (2),
3314 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
3316 /* This defaults to 1 in order to match xterm. We recognize either
3317 internalBorderWidth or internalBorder (which is what xterm calls
3318 it). */
3319 if (NILP (Fassq (Qinternal_border_width, parms)))
3321 Lisp_Object value;
3323 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
3324 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
3325 if (! EQ (value, Qunbound))
3326 parms = Fcons (Fcons (Qinternal_border_width, value),
3327 parms);
3329 x_default_parameter (f, parms, Qinternal_border_width,
3330 #ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */
3331 make_number (0),
3332 #else
3333 make_number (1),
3334 #endif
3335 "internalBorderWidth", "internalBorderWidth",
3336 RES_TYPE_NUMBER);
3337 x_default_parameter (f, parms, Qvertical_scroll_bars, Qleft,
3338 "verticalScrollBars", "ScrollBars",
3339 RES_TYPE_SYMBOL);
3341 /* Also do the stuff which must be set before the window exists. */
3342 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
3343 "foreground", "Foreground", RES_TYPE_STRING);
3344 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
3345 "background", "Background", RES_TYPE_STRING);
3346 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
3347 "pointerColor", "Foreground", RES_TYPE_STRING);
3348 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
3349 "cursorColor", "Foreground", RES_TYPE_STRING);
3350 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
3351 "borderColor", "BorderColor", RES_TYPE_STRING);
3352 x_default_parameter (f, parms, Qscreen_gamma, Qnil,
3353 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
3354 x_default_parameter (f, parms, Qline_spacing, Qnil,
3355 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
3356 x_default_parameter (f, parms, Qleft_fringe, Qnil,
3357 "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
3358 x_default_parameter (f, parms, Qright_fringe, Qnil,
3359 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
3361 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_foreground,
3362 "scrollBarForeground",
3363 "ScrollBarForeground", 1);
3364 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_background,
3365 "scrollBarBackground",
3366 "ScrollBarBackground", 0);
3368 /* Init faces before x_default_parameter is called for scroll-bar
3369 parameters because that function calls x_set_scroll_bar_width,
3370 which calls change_frame_size, which calls Fset_window_buffer,
3371 which runs hooks, which call Fvertical_motion. At the end, we
3372 end up in init_iterator with a null face cache, which should not
3373 happen. */
3374 init_frame_faces (f);
3376 x_default_parameter (f, parms, Qmenu_bar_lines, make_number (1),
3377 "menuBar", "MenuBar", RES_TYPE_NUMBER);
3378 x_default_parameter (f, parms, Qtool_bar_lines, make_number (1),
3379 "toolBar", "ToolBar", RES_TYPE_NUMBER);
3380 x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
3381 "bufferPredicate", "BufferPredicate",
3382 RES_TYPE_SYMBOL);
3383 x_default_parameter (f, parms, Qtitle, Qnil,
3384 "title", "Title", RES_TYPE_STRING);
3385 x_default_parameter (f, parms, Qwait_for_wm, Qt,
3386 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
3387 x_default_parameter (f, parms, Qfullscreen, Qnil,
3388 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
3390 /* Compute the size of the X window. */
3391 window_prompting = x_figure_window_size (f, parms, 1);
3393 tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
3394 f->no_split = minibuffer_only || EQ (tem, Qt);
3396 x_icon_verify (f, parms);
3398 /* Create the X widget or window. */
3399 #ifdef USE_X_TOOLKIT
3400 x_window (f, window_prompting, minibuffer_only);
3401 #else
3402 x_window (f);
3403 #endif
3405 x_icon (f, parms);
3406 x_make_gc (f);
3408 /* Now consider the frame official. */
3409 FRAME_X_DISPLAY_INFO (f)->reference_count++;
3410 Vframe_list = Fcons (frame, Vframe_list);
3412 /* We need to do this after creating the X window, so that the
3413 icon-creation functions can say whose icon they're describing. */
3414 x_default_parameter (f, parms, Qicon_type, Qt,
3415 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
3417 x_default_parameter (f, parms, Qauto_raise, Qnil,
3418 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3419 x_default_parameter (f, parms, Qauto_lower, Qnil,
3420 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3421 x_default_parameter (f, parms, Qcursor_type, Qbox,
3422 "cursorType", "CursorType", RES_TYPE_SYMBOL);
3423 x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
3424 "scrollBarWidth", "ScrollBarWidth",
3425 RES_TYPE_NUMBER);
3426 x_default_parameter (f, parms, Qalpha, Qnil,
3427 "alpha", "Alpha", RES_TYPE_NUMBER);
3429 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3430 Change will not be effected unless different from the current
3431 FRAME_LINES (f). */
3432 width = FRAME_COLS (f);
3433 height = FRAME_LINES (f);
3435 SET_FRAME_COLS (f, 0);
3436 FRAME_LINES (f) = 0;
3437 change_frame_size (f, height, width, 1, 0, 0);
3439 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3440 /* Create the menu bar. */
3441 if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
3443 /* If this signals an error, we haven't set size hints for the
3444 frame and we didn't make it visible. */
3445 initialize_frame_menubar (f);
3447 #ifndef USE_GTK
3448 /* This is a no-op, except under Motif where it arranges the
3449 main window for the widgets on it. */
3450 lw_set_main_areas (f->output_data.x->column_widget,
3451 f->output_data.x->menubar_widget,
3452 f->output_data.x->edit_widget);
3453 #endif /* not USE_GTK */
3455 #endif /* USE_X_TOOLKIT || USE_GTK */
3457 /* Tell the server what size and position, etc, we want, and how
3458 badly we want them. This should be done after we have the menu
3459 bar so that its size can be taken into account. */
3460 BLOCK_INPUT;
3461 x_wm_set_size_hint (f, window_prompting, 0);
3462 UNBLOCK_INPUT;
3464 /* Make the window appear on the frame and enable display, unless
3465 the caller says not to. However, with explicit parent, Emacs
3466 cannot control visibility, so don't try. */
3467 if (! f->output_data.x->explicit_parent)
3469 Lisp_Object visibility;
3471 visibility = x_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
3472 RES_TYPE_SYMBOL);
3473 if (EQ (visibility, Qunbound))
3474 visibility = Qt;
3476 if (EQ (visibility, Qicon))
3477 x_iconify_frame (f);
3478 else if (! NILP (visibility))
3479 x_make_frame_visible (f);
3480 else
3481 /* Must have been Qnil. */
3485 /* Set the WM leader property. GTK does this itself, so this is not
3486 needed when using GTK. */
3487 if (dpyinfo->client_leader_window != 0)
3489 BLOCK_INPUT;
3490 XChangeProperty (FRAME_X_DISPLAY (f),
3491 FRAME_OUTER_WINDOW (f),
3492 dpyinfo->Xatom_wm_client_leader,
3493 XA_WINDOW, 32, PropModeReplace,
3494 (unsigned char *) &dpyinfo->client_leader_window, 1);
3495 UNBLOCK_INPUT;
3498 /* Initialize `default-minibuffer-frame' in case this is the first
3499 frame on this terminal. */
3500 if (FRAME_HAS_MINIBUF_P (f)
3501 && (!FRAMEP (kb->Vdefault_minibuffer_frame)
3502 || !FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame))))
3503 kb->Vdefault_minibuffer_frame = frame;
3505 /* All remaining specified parameters, which have not been "used"
3506 by x_get_arg and friends, now go in the misc. alist of the frame. */
3507 for (tem = parms; CONSP (tem); tem = XCDR (tem))
3508 if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
3509 f->param_alist = Fcons (XCAR (tem), f->param_alist);
3511 UNGCPRO;
3513 /* Make sure windows on this frame appear in calls to next-window
3514 and similar functions. */
3515 Vwindow_list = Qnil;
3517 return unbind_to (count, frame);
3521 /* FRAME is used only to get a handle on the X display. We don't pass the
3522 display info directly because we're called from frame.c, which doesn't
3523 know about that structure. */
3525 Lisp_Object
3526 x_get_focus_frame (frame)
3527 struct frame *frame;
3529 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (frame);
3530 Lisp_Object xfocus;
3531 if (! dpyinfo->x_focus_frame)
3532 return Qnil;
3534 XSETFRAME (xfocus, dpyinfo->x_focus_frame);
3535 return xfocus;
3539 /* In certain situations, when the window manager follows a
3540 click-to-focus policy, there seems to be no way around calling
3541 XSetInputFocus to give another frame the input focus .
3543 In an ideal world, XSetInputFocus should generally be avoided so
3544 that applications don't interfere with the window manager's focus
3545 policy. But I think it's okay to use when it's clearly done
3546 following a user-command. */
3548 DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
3549 doc: /* Set the input focus to FRAME.
3550 FRAME nil means use the selected frame. */)
3551 (frame)
3552 Lisp_Object frame;
3554 struct frame *f = check_x_frame (frame);
3555 Display *dpy = FRAME_X_DISPLAY (f);
3557 BLOCK_INPUT;
3558 x_catch_errors (dpy);
3559 XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3560 RevertToParent, CurrentTime);
3561 x_ewmh_activate_frame (f);
3562 x_uncatch_errors ();
3563 UNBLOCK_INPUT;
3565 return Qnil;
3569 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
3570 doc: /* Internal function called by `color-defined-p', which see. */)
3571 (color, frame)
3572 Lisp_Object color, frame;
3574 XColor foo;
3575 FRAME_PTR f = check_x_frame (frame);
3577 CHECK_STRING (color);
3579 if (x_defined_color (f, SDATA (color), &foo, 0))
3580 return Qt;
3581 else
3582 return Qnil;
3585 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
3586 doc: /* Internal function called by `color-values', which see. */)
3587 (color, frame)
3588 Lisp_Object color, frame;
3590 XColor foo;
3591 FRAME_PTR f = check_x_frame (frame);
3593 CHECK_STRING (color);
3595 if (x_defined_color (f, SDATA (color), &foo, 0))
3596 return list3 (make_number (foo.red),
3597 make_number (foo.green),
3598 make_number (foo.blue));
3599 else
3600 return Qnil;
3603 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
3604 doc: /* Internal function called by `display-color-p', which see. */)
3605 (terminal)
3606 Lisp_Object terminal;
3608 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3610 if (dpyinfo->n_planes <= 2)
3611 return Qnil;
3613 switch (dpyinfo->visual->class)
3615 case StaticColor:
3616 case PseudoColor:
3617 case TrueColor:
3618 case DirectColor:
3619 return Qt;
3621 default:
3622 return Qnil;
3626 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
3627 0, 1, 0,
3628 doc: /* Return t if the X display supports shades of gray.
3629 Note that color displays do support shades of gray.
3630 The optional argument TERMINAL specifies which display to ask about.
3631 TERMINAL should be a terminal id, a frame or a display name (a string).
3632 If omitted or nil, that stands for the selected frame's display. */)
3633 (terminal)
3634 Lisp_Object terminal;
3636 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3638 if (dpyinfo->n_planes <= 1)
3639 return Qnil;
3641 switch (dpyinfo->visual->class)
3643 case StaticColor:
3644 case PseudoColor:
3645 case TrueColor:
3646 case DirectColor:
3647 case StaticGray:
3648 case GrayScale:
3649 return Qt;
3651 default:
3652 return Qnil;
3656 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
3657 0, 1, 0,
3658 doc: /* Return the width in pixels of the X display TERMINAL.
3659 The optional argument TERMINAL specifies which display to ask about.
3660 TERMINAL should be a terminal id, a frame or a display name (a string).
3661 If omitted or nil, that stands for the selected frame's display. */)
3662 (terminal)
3663 Lisp_Object terminal;
3665 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3667 return make_number (dpyinfo->width);
3670 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
3671 Sx_display_pixel_height, 0, 1, 0,
3672 doc: /* Return the height in pixels of the X display TERMINAL.
3673 The optional argument TERMINAL specifies which display to ask about.
3674 TERMINAL should be a terminal id, a frame or a display name (a string).
3675 If omitted or nil, that stands for the selected frame's display. */)
3676 (terminal)
3677 Lisp_Object terminal;
3679 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3681 return make_number (dpyinfo->height);
3684 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
3685 0, 1, 0,
3686 doc: /* Return the number of bitplanes of the X display TERMINAL.
3687 The optional argument TERMINAL specifies which display to ask about.
3688 TERMINAL should be a terminal id, a frame or a display name (a string).
3689 If omitted or nil, that stands for the selected frame's display. */)
3690 (terminal)
3691 Lisp_Object terminal;
3693 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3695 return make_number (dpyinfo->n_planes);
3698 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
3699 0, 1, 0,
3700 doc: /* Return the number of color cells of the X display TERMINAL.
3701 The optional argument TERMINAL specifies which display to ask about.
3702 TERMINAL should be a terminal id, a frame or a display name (a string).
3703 If omitted or nil, that stands for the selected frame's display. */)
3704 (terminal)
3705 Lisp_Object terminal;
3707 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3709 int nr_planes = DisplayPlanes (dpyinfo->display,
3710 XScreenNumberOfScreen (dpyinfo->screen));
3712 /* Truncate nr_planes to 24 to avoid integer overflow.
3713 Some displays says 32, but only 24 bits are actually significant.
3714 There are only very few and rare video cards that have more than
3715 24 significant bits. Also 24 bits is more than 16 million colors,
3716 it "should be enough for everyone". */
3717 if (nr_planes > 24) nr_planes = 24;
3719 return make_number (1 << nr_planes);
3722 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
3723 Sx_server_max_request_size,
3724 0, 1, 0,
3725 doc: /* Return the maximum request size of the X server of display TERMINAL.
3726 The optional argument TERMINAL specifies which display to ask about.
3727 TERMINAL should be a terminal id, a frame or a display name (a string).
3728 If omitted or nil, that stands for the selected frame's display. */)
3729 (terminal)
3730 Lisp_Object terminal;
3732 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3734 return make_number (MAXREQUEST (dpyinfo->display));
3737 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
3738 doc: /* Return the "vendor ID" string of the X server of display TERMINAL.
3739 \(Labelling every distributor as a "vendor" embodies the false assumption
3740 that operating systems cannot be developed and distributed noncommercially.)
3741 The optional argument TERMINAL specifies which display to ask about.
3742 TERMINAL should be a terminal id, a frame or a display name (a string).
3743 If omitted or nil, that stands for the selected frame's display. */)
3744 (terminal)
3745 Lisp_Object terminal;
3747 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3748 char *vendor = ServerVendor (dpyinfo->display);
3750 if (! vendor) vendor = "";
3751 return build_string (vendor);
3754 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
3755 doc: /* Return the version numbers of the X server of display TERMINAL.
3756 The value is a list of three integers: the major and minor
3757 version numbers of the X Protocol in use, and the distributor-specific release
3758 number. See also the function `x-server-vendor'.
3760 The optional argument TERMINAL specifies which display to ask about.
3761 TERMINAL should be a terminal id, a frame or a display name (a string).
3762 If omitted or nil, that stands for the selected frame's display. */)
3763 (terminal)
3764 Lisp_Object terminal;
3766 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3767 Display *dpy = dpyinfo->display;
3769 return Fcons (make_number (ProtocolVersion (dpy)),
3770 Fcons (make_number (ProtocolRevision (dpy)),
3771 Fcons (make_number (VendorRelease (dpy)), Qnil)));
3774 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
3775 doc: /* Return the number of screens on the X server of display TERMINAL.
3776 The optional argument TERMINAL specifies which display to ask about.
3777 TERMINAL should be a terminal id, 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 (ScreenCount (dpyinfo->display));
3787 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
3788 doc: /* Return the height in millimeters of the X display TERMINAL.
3789 The optional argument TERMINAL specifies which display to ask about.
3790 TERMINAL should be a terminal id, 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 (HeightMMOfScreen (dpyinfo->screen));
3800 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
3801 doc: /* Return the width in millimeters of the X display TERMINAL.
3802 The optional argument TERMINAL specifies which display to ask about.
3803 TERMINAL should be a terminal id, a frame or a display name (a string).
3804 If omitted or nil, that stands for the selected frame's display. */)
3805 (terminal)
3806 Lisp_Object terminal;
3808 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3810 return make_number (WidthMMOfScreen (dpyinfo->screen));
3813 DEFUN ("x-display-backing-store", Fx_display_backing_store,
3814 Sx_display_backing_store, 0, 1, 0,
3815 doc: /* Return an indication of whether X display TERMINAL does backing store.
3816 The value may be `always', `when-mapped', or `not-useful'.
3817 The optional argument TERMINAL specifies which display to ask about.
3818 TERMINAL should be a terminal id, a frame or a display name (a string).
3819 If omitted or nil, that stands for the selected frame's display. */)
3820 (terminal)
3821 Lisp_Object terminal;
3823 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3824 Lisp_Object result;
3826 switch (DoesBackingStore (dpyinfo->screen))
3828 case Always:
3829 result = intern ("always");
3830 break;
3832 case WhenMapped:
3833 result = intern ("when-mapped");
3834 break;
3836 case NotUseful:
3837 result = intern ("not-useful");
3838 break;
3840 default:
3841 error ("Strange value for BackingStore parameter of screen");
3842 result = Qnil;
3845 return result;
3848 DEFUN ("x-display-visual-class", Fx_display_visual_class,
3849 Sx_display_visual_class, 0, 1, 0,
3850 doc: /* Return the visual class of the X display TERMINAL.
3851 The value is one of the symbols `static-gray', `gray-scale',
3852 `static-color', `pseudo-color', `true-color', or `direct-color'.
3854 The optional argument TERMINAL specifies which display to ask about.
3855 TERMINAL should a terminal id, a frame or a display name (a string).
3856 If omitted or nil, that stands for the selected frame's display. */)
3857 (terminal)
3858 Lisp_Object terminal;
3860 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3861 Lisp_Object result;
3863 switch (dpyinfo->visual->class)
3865 case StaticGray:
3866 result = intern ("static-gray");
3867 break;
3868 case GrayScale:
3869 result = intern ("gray-scale");
3870 break;
3871 case StaticColor:
3872 result = intern ("static-color");
3873 break;
3874 case PseudoColor:
3875 result = intern ("pseudo-color");
3876 break;
3877 case TrueColor:
3878 result = intern ("true-color");
3879 break;
3880 case DirectColor:
3881 result = intern ("direct-color");
3882 break;
3883 default:
3884 error ("Display has an unknown visual class");
3885 result = Qnil;
3888 return result;
3891 DEFUN ("x-display-save-under", Fx_display_save_under,
3892 Sx_display_save_under, 0, 1, 0,
3893 doc: /* Return t if the X display TERMINAL supports the save-under feature.
3894 The optional argument TERMINAL specifies which display to ask about.
3895 TERMINAL should be a terminal id, a frame or a display name (a string).
3896 If omitted or nil, that stands for the selected frame's display. */)
3897 (terminal)
3898 Lisp_Object terminal;
3900 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3902 if (DoesSaveUnders (dpyinfo->screen) == True)
3903 return Qt;
3904 else
3905 return Qnil;
3909 x_pixel_width (f)
3910 register struct frame *f;
3912 return FRAME_PIXEL_WIDTH (f);
3916 x_pixel_height (f)
3917 register struct frame *f;
3919 return FRAME_PIXEL_HEIGHT (f);
3923 x_char_width (f)
3924 register struct frame *f;
3926 return FRAME_COLUMN_WIDTH (f);
3930 x_char_height (f)
3931 register struct frame *f;
3933 return FRAME_LINE_HEIGHT (f);
3937 x_screen_planes (f)
3938 register struct frame *f;
3940 return FRAME_X_DISPLAY_INFO (f)->n_planes;
3945 /************************************************************************
3946 X Displays
3947 ************************************************************************/
3950 /* Mapping visual names to visuals. */
3952 static struct visual_class
3954 char *name;
3955 int class;
3957 visual_classes[] =
3959 {"StaticGray", StaticGray},
3960 {"GrayScale", GrayScale},
3961 {"StaticColor", StaticColor},
3962 {"PseudoColor", PseudoColor},
3963 {"TrueColor", TrueColor},
3964 {"DirectColor", DirectColor},
3965 {NULL, 0}
3969 #ifndef HAVE_XSCREENNUMBEROFSCREEN
3971 /* Value is the screen number of screen SCR. This is a substitute for
3972 the X function with the same name when that doesn't exist. */
3975 XScreenNumberOfScreen (scr)
3976 register Screen *scr;
3978 Display *dpy = scr->display;
3979 int i;
3981 for (i = 0; i < dpy->nscreens; ++i)
3982 if (scr == dpy->screens + i)
3983 break;
3985 return i;
3988 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
3991 /* Select the visual that should be used on display DPYINFO. Set
3992 members of DPYINFO appropriately. Called from x_term_init. */
3994 void
3995 select_visual (dpyinfo)
3996 struct x_display_info *dpyinfo;
3998 Display *dpy = dpyinfo->display;
3999 Screen *screen = dpyinfo->screen;
4000 Lisp_Object value;
4002 /* See if a visual is specified. */
4003 value = display_x_get_resource (dpyinfo,
4004 build_string ("visualClass"),
4005 build_string ("VisualClass"),
4006 Qnil, Qnil);
4007 if (STRINGP (value))
4009 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
4010 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
4011 depth, a decimal number. NAME is compared with case ignored. */
4012 char *s = (char *) alloca (SBYTES (value) + 1);
4013 char *dash;
4014 int i, class = -1;
4015 XVisualInfo vinfo;
4017 strcpy (s, SDATA (value));
4018 dash = index (s, '-');
4019 if (dash)
4021 dpyinfo->n_planes = atoi (dash + 1);
4022 *dash = '\0';
4024 else
4025 /* We won't find a matching visual with depth 0, so that
4026 an error will be printed below. */
4027 dpyinfo->n_planes = 0;
4029 /* Determine the visual class. */
4030 for (i = 0; visual_classes[i].name; ++i)
4031 if (xstrcasecmp (s, visual_classes[i].name) == 0)
4033 class = visual_classes[i].class;
4034 break;
4037 /* Look up a matching visual for the specified class. */
4038 if (class == -1
4039 || !XMatchVisualInfo (dpy, XScreenNumberOfScreen (screen),
4040 dpyinfo->n_planes, class, &vinfo))
4041 fatal ("Invalid visual specification `%s'", SDATA (value));
4043 dpyinfo->visual = vinfo.visual;
4045 else
4047 int n_visuals;
4048 XVisualInfo *vinfo, vinfo_template;
4050 dpyinfo->visual = DefaultVisualOfScreen (screen);
4052 vinfo_template.visualid = XVisualIDFromVisual (dpyinfo->visual);
4053 vinfo_template.screen = XScreenNumberOfScreen (screen);
4054 vinfo = XGetVisualInfo (dpy, VisualIDMask | VisualScreenMask,
4055 &vinfo_template, &n_visuals);
4056 if (n_visuals != 1)
4057 fatal ("Can't get proper X visual info");
4059 dpyinfo->n_planes = vinfo->depth;
4060 XFree ((char *) vinfo);
4065 /* Return the X display structure for the display named NAME.
4066 Open a new connection if necessary. */
4068 struct x_display_info *
4069 x_display_info_for_name (name)
4070 Lisp_Object name;
4072 Lisp_Object names;
4073 struct x_display_info *dpyinfo;
4075 CHECK_STRING (name);
4077 #if 0
4078 if (! EQ (Vinitial_window_system, intern ("x")))
4079 error ("Not using X Windows"); /* That doesn't stop us anymore. */
4080 #endif
4082 for (dpyinfo = x_display_list, names = x_display_name_list;
4083 dpyinfo;
4084 dpyinfo = dpyinfo->next, names = XCDR (names))
4086 Lisp_Object tem;
4087 tem = Fstring_equal (XCAR (XCAR (names)), name);
4088 if (!NILP (tem))
4089 return dpyinfo;
4092 /* Use this general default value to start with. */
4093 Vx_resource_name = Vinvocation_name;
4095 validate_x_resource_name ();
4097 dpyinfo = x_term_init (name, (char *)0,
4098 (char *) SDATA (Vx_resource_name));
4100 if (dpyinfo == 0)
4101 error ("Cannot connect to X server %s", SDATA (name));
4103 x_in_use = 1;
4104 XSETFASTINT (Vwindow_system_version, 11);
4106 return dpyinfo;
4110 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
4111 1, 3, 0,
4112 doc: /* Open a connection to an X server.
4113 DISPLAY is the name of the display to connect to.
4114 Optional second arg XRM-STRING is a string of resources in xrdb format.
4115 If the optional third arg MUST-SUCCEED is non-nil,
4116 terminate Emacs if we can't open the connection. */)
4117 (display, xrm_string, must_succeed)
4118 Lisp_Object display, xrm_string, must_succeed;
4120 unsigned char *xrm_option;
4121 struct x_display_info *dpyinfo;
4123 CHECK_STRING (display);
4124 if (! NILP (xrm_string))
4125 CHECK_STRING (xrm_string);
4127 #if 0
4128 if (! EQ (Vinitial_window_system, intern ("x")))
4129 error ("Not using X Windows"); /* That doesn't stop us anymore. */
4130 #endif
4132 if (! NILP (xrm_string))
4133 xrm_option = (unsigned char *) SDATA (xrm_string);
4134 else
4135 xrm_option = (unsigned char *) 0;
4137 validate_x_resource_name ();
4139 /* This is what opens the connection and sets x_current_display.
4140 This also initializes many symbols, such as those used for input. */
4141 dpyinfo = x_term_init (display, xrm_option,
4142 (char *) SDATA (Vx_resource_name));
4144 if (dpyinfo == 0)
4146 if (!NILP (must_succeed))
4147 fatal ("Cannot connect to X server %s.\n\
4148 Check the DISPLAY environment variable or use `-d'.\n\
4149 Also use the `xauth' program to verify that you have the proper\n\
4150 authorization information needed to connect the X server.\n\
4151 An insecure way to solve the problem may be to use `xhost'.\n",
4152 SDATA (display));
4153 else
4154 error ("Cannot connect to X server %s", SDATA (display));
4157 x_in_use = 1;
4159 XSETFASTINT (Vwindow_system_version, 11);
4160 return Qnil;
4163 DEFUN ("x-close-connection", Fx_close_connection,
4164 Sx_close_connection, 1, 1, 0,
4165 doc: /* Close the connection to TERMINAL's X server.
4166 For TERMINAL, specify a terminal id, a frame or a display name (a
4167 string). If TERMINAL is nil, that stands for the selected frame's
4168 terminal. */)
4169 (terminal)
4170 Lisp_Object terminal;
4172 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4174 if (dpyinfo->reference_count > 0)
4175 error ("Display still has frames on it");
4177 x_delete_terminal (dpyinfo->terminal);
4179 return Qnil;
4182 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
4183 doc: /* Return the list of display names that Emacs has connections to. */)
4186 Lisp_Object tail, result;
4188 result = Qnil;
4189 for (tail = x_display_name_list; CONSP (tail); tail = XCDR (tail))
4190 result = Fcons (XCAR (XCAR (tail)), result);
4192 return result;
4195 DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
4196 doc: /* If ON is non-nil, report X errors as soon as the erring request is made.
4197 If ON is nil, allow buffering of requests.
4198 Turning on synchronization prohibits the Xlib routines from buffering
4199 requests and seriously degrades performance, but makes debugging much
4200 easier.
4201 The optional second argument TERMINAL specifies which display to act on.
4202 TERMINAL should be a terminal id, a frame or a display name (a string).
4203 If TERMINAL is omitted or nil, that stands for the selected frame's display. */)
4204 (on, terminal)
4205 Lisp_Object terminal, on;
4207 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4209 XSynchronize (dpyinfo->display, !EQ (on, Qnil));
4211 return Qnil;
4214 /* Wait for responses to all X commands issued so far for frame F. */
4216 void
4217 x_sync (f)
4218 FRAME_PTR f;
4220 BLOCK_INPUT;
4221 XSync (FRAME_X_DISPLAY (f), False);
4222 UNBLOCK_INPUT;
4226 /***********************************************************************
4227 Window properties
4228 ***********************************************************************/
4230 DEFUN ("x-change-window-property", Fx_change_window_property,
4231 Sx_change_window_property, 2, 6, 0,
4232 doc: /* Change window property PROP to VALUE on the X window of FRAME.
4233 PROP must be a string.
4234 VALUE may be a string or a list of conses, numbers and/or strings.
4235 If an element in the list is a string, it is converted to
4236 an Atom and the value of the Atom is used. If an element is a cons,
4237 it is converted to a 32 bit number where the car is the 16 top bits and the
4238 cdr is the lower 16 bits.
4239 FRAME nil or omitted means use the selected frame.
4240 If TYPE is given and non-nil, it is the name of the type of VALUE.
4241 If TYPE is not given or nil, the type is STRING.
4242 FORMAT gives the size in bits of each element if VALUE is a list.
4243 It must be one of 8, 16 or 32.
4244 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
4245 If OUTER_P is non-nil, the property is changed for the outer X window of
4246 FRAME. Default is to change on the edit X window.
4248 Value is VALUE. */)
4249 (prop, value, frame, type, format, outer_p)
4250 Lisp_Object prop, value, frame, type, format, outer_p;
4252 struct frame *f = check_x_frame (frame);
4253 Atom prop_atom;
4254 Atom target_type = XA_STRING;
4255 int element_format = 8;
4256 unsigned char *data;
4257 int nelements;
4258 Window w;
4260 CHECK_STRING (prop);
4262 if (! NILP (format))
4264 CHECK_NUMBER (format);
4265 element_format = XFASTINT (format);
4267 if (element_format != 8 && element_format != 16
4268 && element_format != 32)
4269 error ("FORMAT must be one of 8, 16 or 32");
4272 if (CONSP (value))
4274 nelements = x_check_property_data (value);
4275 if (nelements == -1)
4276 error ("Bad data in VALUE, must be number, string or cons");
4278 if (element_format == 8)
4279 data = (unsigned char *) xmalloc (nelements);
4280 else if (element_format == 16)
4281 data = (unsigned char *) xmalloc (nelements*2);
4282 else /* format == 32 */
4283 /* The man page for XChangeProperty:
4284 "If the specified format is 32, the property data must be a
4285 long array."
4286 This applies even if long is more than 64 bits. The X library
4287 converts to 32 bits before sending to the X server. */
4288 data = (unsigned char *) xmalloc (nelements * sizeof(long));
4290 x_fill_property_data (FRAME_X_DISPLAY (f), value, data, element_format);
4292 else
4294 CHECK_STRING (value);
4295 data = SDATA (value);
4296 nelements = SCHARS (value);
4299 BLOCK_INPUT;
4300 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4301 if (! NILP (type))
4303 CHECK_STRING (type);
4304 target_type = XInternAtom (FRAME_X_DISPLAY (f), SDATA (type), False);
4307 if (! NILP (outer_p)) w = FRAME_OUTER_WINDOW (f);
4308 else w = FRAME_X_WINDOW (f);
4310 XChangeProperty (FRAME_X_DISPLAY (f), w,
4311 prop_atom, target_type, element_format, PropModeReplace,
4312 data, nelements);
4314 if (CONSP (value)) xfree (data);
4316 /* Make sure the property is set when we return. */
4317 XFlush (FRAME_X_DISPLAY (f));
4318 UNBLOCK_INPUT;
4320 return value;
4324 DEFUN ("x-delete-window-property", Fx_delete_window_property,
4325 Sx_delete_window_property, 1, 2, 0,
4326 doc: /* Remove window property PROP from X window of FRAME.
4327 FRAME nil or omitted means use the selected frame. Value is PROP. */)
4328 (prop, frame)
4329 Lisp_Object prop, frame;
4331 struct frame *f = check_x_frame (frame);
4332 Atom prop_atom;
4334 CHECK_STRING (prop);
4335 BLOCK_INPUT;
4336 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4337 XDeleteProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), prop_atom);
4339 /* Make sure the property is removed when we return. */
4340 XFlush (FRAME_X_DISPLAY (f));
4341 UNBLOCK_INPUT;
4343 return prop;
4347 DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
4348 1, 6, 0,
4349 doc: /* Value is the value of window property PROP on FRAME.
4350 If FRAME is nil or omitted, use the selected frame.
4351 If TYPE is nil or omitted, get the property as a string. Otherwise TYPE
4352 is the name of the Atom that denotes the type expected.
4353 If SOURCE is non-nil, get the property on that window instead of from
4354 FRAME. The number 0 denotes the root window.
4355 If DELETE_P is non-nil, delete the property after retreiving it.
4356 If VECTOR_RET_P is non-nil, don't return a string but a vector of values.
4358 Value is nil if FRAME hasn't a property with name PROP or if PROP has
4359 no value of TYPE. */)
4360 (prop, frame, type, source, delete_p, vector_ret_p)
4361 Lisp_Object prop, frame, type, source, delete_p, vector_ret_p;
4363 struct frame *f = check_x_frame (frame);
4364 Atom prop_atom;
4365 int rc;
4366 Lisp_Object prop_value = Qnil;
4367 unsigned char *tmp_data = NULL;
4368 Atom actual_type;
4369 Atom target_type = XA_STRING;
4370 int actual_format;
4371 unsigned long actual_size, bytes_remaining;
4372 Window target_window = FRAME_X_WINDOW (f);
4373 struct gcpro gcpro1;
4375 GCPRO1 (prop_value);
4376 CHECK_STRING (prop);
4378 if (! NILP (source))
4380 if (NUMBERP (source))
4382 if (FLOATP (source))
4383 target_window = (Window) XFLOAT (source);
4384 else
4385 target_window = XFASTINT (source);
4387 if (target_window == 0)
4388 target_window = FRAME_X_DISPLAY_INFO (f)->root_window;
4390 else if (CONSP (source))
4391 target_window = cons_to_long (source);
4394 BLOCK_INPUT;
4395 if (STRINGP (type))
4397 if (strcmp ("AnyPropertyType", SDATA (type)) == 0)
4398 target_type = AnyPropertyType;
4399 else
4400 target_type = XInternAtom (FRAME_X_DISPLAY (f), SDATA (type), False);
4403 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4404 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4405 prop_atom, 0, 0, False, target_type,
4406 &actual_type, &actual_format, &actual_size,
4407 &bytes_remaining, &tmp_data);
4408 if (rc == Success)
4410 int size = bytes_remaining;
4412 XFree (tmp_data);
4413 tmp_data = NULL;
4415 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4416 prop_atom, 0, bytes_remaining,
4417 ! NILP (delete_p), target_type,
4418 &actual_type, &actual_format,
4419 &actual_size, &bytes_remaining,
4420 &tmp_data);
4421 if (rc == Success && tmp_data)
4423 /* The man page for XGetWindowProperty says:
4424 "If the returned format is 32, the returned data is represented
4425 as a long array and should be cast to that type to obtain the
4426 elements."
4427 This applies even if long is more than 32 bits, the X library
4428 converts from 32 bit elements received from the X server to long
4429 and passes the long array to us. Thus, for that case bcopy can not
4430 be used. We convert to a 32 bit type here, because so much code
4431 assume on that.
4433 The bytes and offsets passed to XGetWindowProperty refers to the
4434 property and those are indeed in 32 bit quantities if format is
4435 32. */
4437 if (actual_format == 32 && actual_format < BITS_PER_LONG)
4439 unsigned long i;
4440 int *idata = (int *) tmp_data;
4441 long *ldata = (long *) tmp_data;
4443 for (i = 0; i < actual_size; ++i)
4444 idata[i] = (int) ldata[i];
4447 if (NILP (vector_ret_p))
4448 prop_value = make_string (tmp_data, size);
4449 else
4450 prop_value = x_property_data_to_lisp (f,
4451 tmp_data,
4452 actual_type,
4453 actual_format,
4454 actual_size);
4457 if (tmp_data) XFree (tmp_data);
4460 UNBLOCK_INPUT;
4461 UNGCPRO;
4462 return prop_value;
4467 /***********************************************************************
4468 Busy cursor
4469 ***********************************************************************/
4471 /* Timer function of hourglass_atimer. TIMER is equal to
4472 hourglass_atimer.
4474 Display an hourglass pointer on all frames by mapping the frames'
4475 hourglass_window. Set the hourglass_p flag in the frames'
4476 output_data.x structure to indicate that an hourglass cursor is
4477 shown on the frames. */
4479 void
4480 show_hourglass (timer)
4481 struct atimer *timer;
4483 /* The timer implementation will cancel this timer automatically
4484 after this function has run. Set hourglass_atimer to null
4485 so that we know the timer doesn't have to be canceled. */
4486 hourglass_atimer = NULL;
4488 if (!hourglass_shown_p)
4490 Lisp_Object rest, frame;
4492 BLOCK_INPUT;
4494 FOR_EACH_FRAME (rest, frame)
4496 struct frame *f = XFRAME (frame);
4498 if (FRAME_LIVE_P (f) && FRAME_X_P (f) && FRAME_X_DISPLAY (f))
4500 Display *dpy = FRAME_X_DISPLAY (f);
4502 #ifdef USE_X_TOOLKIT
4503 if (f->output_data.x->widget)
4504 #else
4505 if (FRAME_OUTER_WINDOW (f))
4506 #endif
4508 f->output_data.x->hourglass_p = 1;
4510 if (!f->output_data.x->hourglass_window)
4512 unsigned long mask = CWCursor;
4513 XSetWindowAttributes attrs;
4514 #ifdef USE_GTK
4515 Window parent = FRAME_X_WINDOW (f);
4516 #else
4517 Window parent = FRAME_OUTER_WINDOW (f);
4518 #endif
4519 attrs.cursor = f->output_data.x->hourglass_cursor;
4521 f->output_data.x->hourglass_window
4522 = XCreateWindow (dpy, parent,
4523 0, 0, 32000, 32000, 0, 0,
4524 InputOnly,
4525 CopyFromParent,
4526 mask, &attrs);
4529 XMapRaised (dpy, f->output_data.x->hourglass_window);
4530 XFlush (dpy);
4535 hourglass_shown_p = 1;
4536 UNBLOCK_INPUT;
4541 /* Hide the hourglass pointer on all frames, if it is currently
4542 shown. */
4544 void
4545 hide_hourglass ()
4547 if (hourglass_shown_p)
4549 Lisp_Object rest, frame;
4551 BLOCK_INPUT;
4552 FOR_EACH_FRAME (rest, frame)
4554 struct frame *f = XFRAME (frame);
4556 if (FRAME_X_P (f)
4557 /* Watch out for newly created frames. */
4558 && f->output_data.x->hourglass_window)
4560 XUnmapWindow (FRAME_X_DISPLAY (f),
4561 f->output_data.x->hourglass_window);
4562 /* Sync here because XTread_socket looks at the
4563 hourglass_p flag that is reset to zero below. */
4564 XSync (FRAME_X_DISPLAY (f), False);
4565 f->output_data.x->hourglass_p = 0;
4569 hourglass_shown_p = 0;
4570 UNBLOCK_INPUT;
4576 /***********************************************************************
4577 Tool tips
4578 ***********************************************************************/
4580 static Lisp_Object x_create_tip_frame P_ ((struct x_display_info *,
4581 Lisp_Object, Lisp_Object));
4582 static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object,
4583 Lisp_Object, int, int, int *, int *));
4585 /* The frame of a currently visible tooltip. */
4587 Lisp_Object tip_frame;
4589 /* If non-nil, a timer started that hides the last tooltip when it
4590 fires. */
4592 Lisp_Object tip_timer;
4593 Window tip_window;
4595 /* If non-nil, a vector of 3 elements containing the last args
4596 with which x-show-tip was called. See there. */
4598 Lisp_Object last_show_tip_args;
4600 /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
4602 Lisp_Object Vx_max_tooltip_size;
4605 static Lisp_Object
4606 unwind_create_tip_frame (frame)
4607 Lisp_Object frame;
4609 Lisp_Object deleted;
4611 deleted = unwind_create_frame (frame);
4612 if (EQ (deleted, Qt))
4614 tip_window = None;
4615 tip_frame = Qnil;
4618 return deleted;
4622 /* Create a frame for a tooltip on the display described by DPYINFO.
4623 PARMS is a list of frame parameters. TEXT is the string to
4624 display in the tip frame. Value is the frame.
4626 Note that functions called here, esp. x_default_parameter can
4627 signal errors, for instance when a specified color name is
4628 undefined. We have to make sure that we're in a consistent state
4629 when this happens. */
4631 static Lisp_Object
4632 x_create_tip_frame (dpyinfo, parms, text)
4633 struct x_display_info *dpyinfo;
4634 Lisp_Object parms, text;
4636 struct frame *f;
4637 Lisp_Object frame, tem;
4638 Lisp_Object name;
4639 long window_prompting = 0;
4640 int width, height;
4641 int count = SPECPDL_INDEX ();
4642 struct gcpro gcpro1, gcpro2, gcpro3;
4643 int face_change_count_before = face_change_count;
4644 Lisp_Object buffer;
4645 struct buffer *old_buffer;
4647 check_x ();
4649 if (!dpyinfo->terminal->name)
4650 error ("Terminal is not live, can't create new frames on it");
4652 parms = Fcopy_alist (parms);
4654 /* Get the name of the frame to use for resource lookup. */
4655 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
4656 if (!STRINGP (name)
4657 && !EQ (name, Qunbound)
4658 && !NILP (name))
4659 error ("Invalid frame name--not a string or nil");
4661 frame = Qnil;
4662 GCPRO3 (parms, name, frame);
4663 f = make_frame (1);
4664 XSETFRAME (frame, f);
4666 buffer = Fget_buffer_create (build_string (" *tip*"));
4667 Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer, Qnil);
4668 old_buffer = current_buffer;
4669 set_buffer_internal_1 (XBUFFER (buffer));
4670 current_buffer->truncate_lines = Qnil;
4671 specbind (Qinhibit_read_only, Qt);
4672 specbind (Qinhibit_modification_hooks, Qt);
4673 Ferase_buffer ();
4674 Finsert (1, &text);
4675 set_buffer_internal_1 (old_buffer);
4677 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
4678 record_unwind_protect (unwind_create_tip_frame, frame);
4680 f->terminal = dpyinfo->terminal;
4681 f->terminal->reference_count++;
4683 /* By setting the output method, we're essentially saying that
4684 the frame is live, as per FRAME_LIVE_P. If we get a signal
4685 from this point on, x_destroy_window might screw up reference
4686 counts etc. */
4687 f->output_method = output_x_window;
4688 f->output_data.x = (struct x_output *) xmalloc (sizeof (struct x_output));
4689 bzero (f->output_data.x, sizeof (struct x_output));
4690 f->output_data.x->icon_bitmap = -1;
4691 FRAME_FONTSET (f) = -1;
4692 f->output_data.x->scroll_bar_foreground_pixel = -1;
4693 f->output_data.x->scroll_bar_background_pixel = -1;
4694 #ifdef USE_TOOLKIT_SCROLL_BARS
4695 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
4696 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
4697 #endif /* USE_TOOLKIT_SCROLL_BARS */
4698 f->icon_name = Qnil;
4699 FRAME_X_DISPLAY_INFO (f) = dpyinfo;
4700 #if GLYPH_DEBUG
4701 image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
4702 dpyinfo_refcount = dpyinfo->reference_count;
4703 #endif /* GLYPH_DEBUG */
4704 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
4705 f->output_data.x->explicit_parent = 0;
4707 /* These colors will be set anyway later, but it's important
4708 to get the color reference counts right, so initialize them! */
4710 Lisp_Object black;
4711 struct gcpro gcpro1;
4713 /* Function x_decode_color can signal an error. Make
4714 sure to initialize color slots so that we won't try
4715 to free colors we haven't allocated. */
4716 FRAME_FOREGROUND_PIXEL (f) = -1;
4717 FRAME_BACKGROUND_PIXEL (f) = -1;
4718 f->output_data.x->cursor_pixel = -1;
4719 f->output_data.x->cursor_foreground_pixel = -1;
4720 f->output_data.x->border_pixel = -1;
4721 f->output_data.x->mouse_pixel = -1;
4723 black = build_string ("black");
4724 GCPRO1 (black);
4725 FRAME_FOREGROUND_PIXEL (f)
4726 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4727 FRAME_BACKGROUND_PIXEL (f)
4728 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4729 f->output_data.x->cursor_pixel
4730 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4731 f->output_data.x->cursor_foreground_pixel
4732 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4733 f->output_data.x->border_pixel
4734 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4735 f->output_data.x->mouse_pixel
4736 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4737 UNGCPRO;
4740 /* Set the name; the functions to which we pass f expect the name to
4741 be set. */
4742 if (EQ (name, Qunbound) || NILP (name))
4744 f->name = build_string (dpyinfo->x_id_name);
4745 f->explicit_name = 0;
4747 else
4749 f->name = name;
4750 f->explicit_name = 1;
4751 /* use the frame's title when getting resources for this frame. */
4752 specbind (Qx_resource_name, name);
4755 f->resx = dpyinfo->resx;
4756 f->resy = dpyinfo->resy;
4758 register_font_driver (&xfont_driver, f);
4759 #ifdef HAVE_FREETYPE
4760 #ifdef HAVE_XFT
4761 register_font_driver (&xftfont_driver, f);
4762 #else /* not HAVE_XFT */
4763 register_font_driver (&ftxfont_driver, f);
4764 #endif /* not HAVE_XFT */
4765 #endif /* HAVE_FREETYPE */
4767 x_default_parameter (f, parms, Qfont_backend, Qnil,
4768 "fontBackend", "FontBackend", RES_TYPE_STRING);
4770 /* Extract the window parameters from the supplied values that are
4771 needed to determine window geometry. */
4772 x_default_font_parameter (f, parms);
4774 x_default_parameter (f, parms, Qborder_width, make_number (2),
4775 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
4777 /* This defaults to 2 in order to match xterm. We recognize either
4778 internalBorderWidth or internalBorder (which is what xterm calls
4779 it). */
4780 if (NILP (Fassq (Qinternal_border_width, parms)))
4782 Lisp_Object value;
4784 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
4785 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
4786 if (! EQ (value, Qunbound))
4787 parms = Fcons (Fcons (Qinternal_border_width, value),
4788 parms);
4791 x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
4792 "internalBorderWidth", "internalBorderWidth",
4793 RES_TYPE_NUMBER);
4795 /* Also do the stuff which must be set before the window exists. */
4796 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
4797 "foreground", "Foreground", RES_TYPE_STRING);
4798 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
4799 "background", "Background", RES_TYPE_STRING);
4800 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
4801 "pointerColor", "Foreground", RES_TYPE_STRING);
4802 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
4803 "cursorColor", "Foreground", RES_TYPE_STRING);
4804 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
4805 "borderColor", "BorderColor", RES_TYPE_STRING);
4807 /* Init faces before x_default_parameter is called for scroll-bar
4808 parameters because that function calls x_set_scroll_bar_width,
4809 which calls change_frame_size, which calls Fset_window_buffer,
4810 which runs hooks, which call Fvertical_motion. At the end, we
4811 end up in init_iterator with a null face cache, which should not
4812 happen. */
4813 init_frame_faces (f);
4815 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
4817 window_prompting = x_figure_window_size (f, parms, 0);
4820 XSetWindowAttributes attrs;
4821 unsigned long mask;
4823 BLOCK_INPUT;
4824 mask = CWBackPixel | CWOverrideRedirect | CWEventMask;
4825 if (DoesSaveUnders (dpyinfo->screen))
4826 mask |= CWSaveUnder;
4828 /* Window managers look at the override-redirect flag to determine
4829 whether or net to give windows a decoration (Xlib spec, chapter
4830 3.2.8). */
4831 attrs.override_redirect = True;
4832 attrs.save_under = True;
4833 attrs.background_pixel = FRAME_BACKGROUND_PIXEL (f);
4834 /* Arrange for getting MapNotify and UnmapNotify events. */
4835 attrs.event_mask = StructureNotifyMask;
4836 tip_window
4837 = FRAME_X_WINDOW (f)
4838 = XCreateWindow (FRAME_X_DISPLAY (f),
4839 FRAME_X_DISPLAY_INFO (f)->root_window,
4840 /* x, y, width, height */
4841 0, 0, 1, 1,
4842 /* Border. */
4844 CopyFromParent, InputOutput, CopyFromParent,
4845 mask, &attrs);
4846 UNBLOCK_INPUT;
4849 x_make_gc (f);
4851 x_default_parameter (f, parms, Qauto_raise, Qnil,
4852 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
4853 x_default_parameter (f, parms, Qauto_lower, Qnil,
4854 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
4855 x_default_parameter (f, parms, Qcursor_type, Qbox,
4856 "cursorType", "CursorType", RES_TYPE_SYMBOL);
4858 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
4859 Change will not be effected unless different from the current
4860 FRAME_LINES (f). */
4861 width = FRAME_COLS (f);
4862 height = FRAME_LINES (f);
4863 SET_FRAME_COLS (f, 0);
4864 FRAME_LINES (f) = 0;
4865 change_frame_size (f, height, width, 1, 0, 0);
4867 /* Add `tooltip' frame parameter's default value. */
4868 if (NILP (Fframe_parameter (frame, intern ("tooltip"))))
4869 Fmodify_frame_parameters (frame, Fcons (Fcons (intern ("tooltip"), Qt),
4870 Qnil));
4872 /* FIXME - can this be done in a similar way to normal frames?
4873 http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
4875 /* Set the `display-type' frame parameter before setting up faces. */
4877 Lisp_Object disptype;
4879 if (FRAME_X_DISPLAY_INFO (f)->n_planes == 1)
4880 disptype = intern ("mono");
4881 else if (FRAME_X_DISPLAY_INFO (f)->visual->class == GrayScale
4882 || FRAME_X_DISPLAY_INFO (f)->visual->class == StaticGray)
4883 disptype = intern ("grayscale");
4884 else
4885 disptype = intern ("color");
4887 if (NILP (Fframe_parameter (frame, Qdisplay_type)))
4888 Fmodify_frame_parameters (frame, Fcons (Fcons (Qdisplay_type, disptype),
4889 Qnil));
4892 /* Set up faces after all frame parameters are known. This call
4893 also merges in face attributes specified for new frames.
4895 Frame parameters may be changed if .Xdefaults contains
4896 specifications for the default font. For example, if there is an
4897 `Emacs.default.attributeBackground: pink', the `background-color'
4898 attribute of the frame get's set, which let's the internal border
4899 of the tooltip frame appear in pink. Prevent this. */
4901 Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
4903 /* Set tip_frame here, so that */
4904 tip_frame = frame;
4905 call2 (Qface_set_after_frame_default, frame, Qnil);
4907 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
4908 Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg),
4909 Qnil));
4912 f->no_split = 1;
4914 UNGCPRO;
4916 /* It is now ok to make the frame official even if we get an error
4917 below. And the frame needs to be on Vframe_list or making it
4918 visible won't work. */
4919 Vframe_list = Fcons (frame, Vframe_list);
4921 /* Now that the frame is official, it counts as a reference to
4922 its display. */
4923 FRAME_X_DISPLAY_INFO (f)->reference_count++;
4925 /* Setting attributes of faces of the tooltip frame from resources
4926 and similar will increment face_change_count, which leads to the
4927 clearing of all current matrices. Since this isn't necessary
4928 here, avoid it by resetting face_change_count to the value it
4929 had before we created the tip frame. */
4930 face_change_count = face_change_count_before;
4932 /* Discard the unwind_protect. */
4933 return unbind_to (count, frame);
4937 /* Compute where to display tip frame F. PARMS is the list of frame
4938 parameters for F. DX and DY are specified offsets from the current
4939 location of the mouse. WIDTH and HEIGHT are the width and height
4940 of the tooltip. Return coordinates relative to the root window of
4941 the display in *ROOT_X, and *ROOT_Y. */
4943 static void
4944 compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
4945 struct frame *f;
4946 Lisp_Object parms, dx, dy;
4947 int width, height;
4948 int *root_x, *root_y;
4950 Lisp_Object left, top;
4951 int win_x, win_y;
4952 Window root, child;
4953 unsigned pmask;
4955 /* User-specified position? */
4956 left = Fcdr (Fassq (Qleft, parms));
4957 top = Fcdr (Fassq (Qtop, parms));
4959 /* Move the tooltip window where the mouse pointer is. Resize and
4960 show it. */
4961 if (!INTEGERP (left) || !INTEGERP (top))
4963 BLOCK_INPUT;
4964 XQueryPointer (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
4965 &root, &child, root_x, root_y, &win_x, &win_y, &pmask);
4966 UNBLOCK_INPUT;
4969 if (INTEGERP (top))
4970 *root_y = XINT (top);
4971 else if (*root_y + XINT (dy) <= 0)
4972 *root_y = 0; /* Can happen for negative dy */
4973 else if (*root_y + XINT (dy) + height <= FRAME_X_DISPLAY_INFO (f)->height)
4974 /* It fits below the pointer */
4975 *root_y += XINT (dy);
4976 else if (height + XINT (dy) <= *root_y)
4977 /* It fits above the pointer. */
4978 *root_y -= height + XINT (dy);
4979 else
4980 /* Put it on the top. */
4981 *root_y = 0;
4983 if (INTEGERP (left))
4984 *root_x = XINT (left);
4985 else if (*root_x + XINT (dx) <= 0)
4986 *root_x = 0; /* Can happen for negative dx */
4987 else if (*root_x + XINT (dx) + width <= FRAME_X_DISPLAY_INFO (f)->width)
4988 /* It fits to the right of the pointer. */
4989 *root_x += XINT (dx);
4990 else if (width + XINT (dx) <= *root_x)
4991 /* It fits to the left of the pointer. */
4992 *root_x -= width + XINT (dx);
4993 else
4994 /* Put it left-justified on the screen--it ought to fit that way. */
4995 *root_x = 0;
4999 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
5000 doc: /* Show STRING in a "tooltip" window on frame FRAME.
5001 A tooltip window is a small X window displaying a string.
5003 This is an internal function; Lisp code should call `tooltip-show'.
5005 FRAME nil or omitted means use the selected frame.
5007 PARMS is an optional list of frame parameters which can be used to
5008 change the tooltip's appearance.
5010 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
5011 means use the default timeout of 5 seconds.
5013 If the list of frame parameters PARAMS contains a `left' parameters,
5014 the tooltip is displayed at that x-position. Otherwise it is
5015 displayed at the mouse position, with offset DX added (default is 5 if
5016 DX isn't specified). Likewise for the y-position; if a `top' frame
5017 parameter is specified, it determines the y-position of the tooltip
5018 window, otherwise it is displayed at the mouse position, with offset
5019 DY added (default is -10).
5021 A tooltip's maximum size is specified by `x-max-tooltip-size'.
5022 Text larger than the specified size is clipped. */)
5023 (string, frame, parms, timeout, dx, dy)
5024 Lisp_Object string, frame, parms, timeout, dx, dy;
5026 struct frame *f;
5027 struct window *w;
5028 int root_x, root_y;
5029 struct buffer *old_buffer;
5030 struct text_pos pos;
5031 int i, width, height;
5032 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
5033 int old_windows_or_buffers_changed = windows_or_buffers_changed;
5034 int count = SPECPDL_INDEX ();
5036 specbind (Qinhibit_redisplay, Qt);
5038 GCPRO4 (string, parms, frame, timeout);
5040 CHECK_STRING (string);
5041 if (SCHARS (string) == 0)
5042 string = make_unibyte_string (" ", 1);
5044 f = check_x_frame (frame);
5045 if (NILP (timeout))
5046 timeout = make_number (5);
5047 else
5048 CHECK_NATNUM (timeout);
5050 if (NILP (dx))
5051 dx = make_number (5);
5052 else
5053 CHECK_NUMBER (dx);
5055 if (NILP (dy))
5056 dy = make_number (-10);
5057 else
5058 CHECK_NUMBER (dy);
5060 if (NILP (last_show_tip_args))
5061 last_show_tip_args = Fmake_vector (make_number (3), Qnil);
5063 if (!NILP (tip_frame))
5065 Lisp_Object last_string = AREF (last_show_tip_args, 0);
5066 Lisp_Object last_frame = AREF (last_show_tip_args, 1);
5067 Lisp_Object last_parms = AREF (last_show_tip_args, 2);
5069 if (EQ (frame, last_frame)
5070 && !NILP (Fequal (last_string, string))
5071 && !NILP (Fequal (last_parms, parms)))
5073 struct frame *f = XFRAME (tip_frame);
5075 /* Only DX and DY have changed. */
5076 if (!NILP (tip_timer))
5078 Lisp_Object timer = tip_timer;
5079 tip_timer = Qnil;
5080 call1 (Qcancel_timer, timer);
5083 BLOCK_INPUT;
5084 compute_tip_xy (f, parms, dx, dy, FRAME_PIXEL_WIDTH (f),
5085 FRAME_PIXEL_HEIGHT (f), &root_x, &root_y);
5086 XMoveWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5087 root_x, root_y);
5088 UNBLOCK_INPUT;
5089 goto start_timer;
5093 /* Hide a previous tip, if any. */
5094 Fx_hide_tip ();
5096 ASET (last_show_tip_args, 0, string);
5097 ASET (last_show_tip_args, 1, frame);
5098 ASET (last_show_tip_args, 2, parms);
5100 /* Add default values to frame parameters. */
5101 if (NILP (Fassq (Qname, parms)))
5102 parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
5103 if (NILP (Fassq (Qinternal_border_width, parms)))
5104 parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
5105 if (NILP (Fassq (Qborder_width, parms)))
5106 parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
5107 if (NILP (Fassq (Qborder_color, parms)))
5108 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
5109 if (NILP (Fassq (Qbackground_color, parms)))
5110 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
5111 parms);
5113 /* Create a frame for the tooltip, and record it in the global
5114 variable tip_frame. */
5115 frame = x_create_tip_frame (FRAME_X_DISPLAY_INFO (f), parms, string);
5116 f = XFRAME (frame);
5118 /* Set up the frame's root window. */
5119 w = XWINDOW (FRAME_ROOT_WINDOW (f));
5120 w->left_col = w->top_line = make_number (0);
5122 if (CONSP (Vx_max_tooltip_size)
5123 && INTEGERP (XCAR (Vx_max_tooltip_size))
5124 && XINT (XCAR (Vx_max_tooltip_size)) > 0
5125 && INTEGERP (XCDR (Vx_max_tooltip_size))
5126 && XINT (XCDR (Vx_max_tooltip_size)) > 0)
5128 w->total_cols = XCAR (Vx_max_tooltip_size);
5129 w->total_lines = XCDR (Vx_max_tooltip_size);
5131 else
5133 w->total_cols = make_number (80);
5134 w->total_lines = make_number (40);
5137 FRAME_TOTAL_COLS (f) = XINT (w->total_cols);
5138 adjust_glyphs (f);
5139 w->pseudo_window_p = 1;
5141 /* Display the tooltip text in a temporary buffer. */
5142 old_buffer = current_buffer;
5143 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer));
5144 current_buffer->truncate_lines = Qnil;
5145 clear_glyph_matrix (w->desired_matrix);
5146 clear_glyph_matrix (w->current_matrix);
5147 SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
5148 try_window (FRAME_ROOT_WINDOW (f), pos, 0);
5150 /* Compute width and height of the tooltip. */
5151 width = height = 0;
5152 for (i = 0; i < w->desired_matrix->nrows; ++i)
5154 struct glyph_row *row = &w->desired_matrix->rows[i];
5155 struct glyph *last;
5156 int row_width;
5158 /* Stop at the first empty row at the end. */
5159 if (!row->enabled_p || !row->displays_text_p)
5160 break;
5162 /* Let the row go over the full width of the frame. */
5163 row->full_width_p = 1;
5165 /* There's a glyph at the end of rows that is used to place
5166 the cursor there. Don't include the width of this glyph. */
5167 if (row->used[TEXT_AREA])
5169 last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
5170 row_width = row->pixel_width - last->pixel_width;
5172 else
5173 row_width = row->pixel_width;
5175 height += row->height;
5176 width = max (width, row_width);
5179 /* Add the frame's internal border to the width and height the X
5180 window should have. */
5181 height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5182 width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5184 /* Move the tooltip window where the mouse pointer is. Resize and
5185 show it. */
5186 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
5188 BLOCK_INPUT;
5189 XMoveResizeWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5190 root_x, root_y, width, height);
5191 XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
5192 UNBLOCK_INPUT;
5194 /* Draw into the window. */
5195 w->must_be_updated_p = 1;
5196 update_single_window (w, 1);
5198 /* Restore original current buffer. */
5199 set_buffer_internal_1 (old_buffer);
5200 windows_or_buffers_changed = old_windows_or_buffers_changed;
5202 start_timer:
5203 /* Let the tip disappear after timeout seconds. */
5204 tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
5205 intern ("x-hide-tip"));
5207 UNGCPRO;
5208 return unbind_to (count, Qnil);
5212 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
5213 doc: /* Hide the current tooltip window, if there is any.
5214 Value is t if tooltip was open, nil otherwise. */)
5217 int count;
5218 Lisp_Object deleted, frame, timer;
5219 struct gcpro gcpro1, gcpro2;
5221 /* Return quickly if nothing to do. */
5222 if (NILP (tip_timer) && NILP (tip_frame))
5223 return Qnil;
5225 frame = tip_frame;
5226 timer = tip_timer;
5227 GCPRO2 (frame, timer);
5228 tip_frame = tip_timer = deleted = Qnil;
5230 count = SPECPDL_INDEX ();
5231 specbind (Qinhibit_redisplay, Qt);
5232 specbind (Qinhibit_quit, Qt);
5234 if (!NILP (timer))
5235 call1 (Qcancel_timer, timer);
5237 if (FRAMEP (frame))
5239 Fdelete_frame (frame, Qnil);
5240 deleted = Qt;
5242 #ifdef USE_LUCID
5243 /* Bloodcurdling hack alert: The Lucid menu bar widget's
5244 redisplay procedure is not called when a tip frame over menu
5245 items is unmapped. Redisplay the menu manually... */
5247 struct frame *f = SELECTED_FRAME ();
5248 Widget w = f->output_data.x->menubar_widget;
5249 extern void xlwmenu_redisplay P_ ((Widget));
5251 if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f)->screen)
5252 && w != NULL)
5254 BLOCK_INPUT;
5255 xlwmenu_redisplay (w);
5256 UNBLOCK_INPUT;
5259 #endif /* USE_LUCID */
5262 UNGCPRO;
5263 return unbind_to (count, deleted);
5268 /***********************************************************************
5269 File selection dialog
5270 ***********************************************************************/
5272 DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog,
5273 Sx_uses_old_gtk_dialog,
5274 0, 0, 0,
5275 doc: /* Return t if the old Gtk+ file selection dialog is used. */)
5278 #ifdef USE_GTK
5279 extern int use_dialog_box;
5280 extern int use_file_dialog;
5282 if (use_dialog_box
5283 && use_file_dialog
5284 && have_menus_p ()
5285 && xg_uses_old_file_dialog ())
5286 return Qt;
5287 #endif
5288 return Qnil;
5292 #ifdef USE_MOTIF
5293 /* Callback for "OK" and "Cancel" on file selection dialog. */
5295 static void
5296 file_dialog_cb (widget, client_data, call_data)
5297 Widget widget;
5298 XtPointer call_data, client_data;
5300 int *result = (int *) client_data;
5301 XmAnyCallbackStruct *cb = (XmAnyCallbackStruct *) call_data;
5302 *result = cb->reason;
5306 /* Callback for unmapping a file selection dialog. This is used to
5307 capture the case where a dialog is closed via a window manager's
5308 closer button, for example. Using a XmNdestroyCallback didn't work
5309 in this case. */
5311 static void
5312 file_dialog_unmap_cb (widget, client_data, call_data)
5313 Widget widget;
5314 XtPointer call_data, client_data;
5316 int *result = (int *) client_data;
5317 *result = XmCR_CANCEL;
5320 static Lisp_Object
5321 clean_up_file_dialog (arg)
5322 Lisp_Object arg;
5324 struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
5325 Widget dialog = (Widget) p->pointer;
5327 /* Clean up. */
5328 BLOCK_INPUT;
5329 XtUnmanageChild (dialog);
5330 XtDestroyWidget (dialog);
5331 x_menu_set_in_use (0);
5332 UNBLOCK_INPUT;
5334 return Qnil;
5338 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5339 doc: /* Read file name, prompting with PROMPT in directory DIR.
5340 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5341 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5342 or directory must exist. ONLY-DIR-P is ignored." */)
5343 (prompt, dir, default_filename, mustmatch, only_dir_p)
5344 Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
5346 int result;
5347 struct frame *f = SELECTED_FRAME ();
5348 Lisp_Object file = Qnil;
5349 Lisp_Object decoded_file;
5350 Widget dialog, text, help;
5351 Arg al[10];
5352 int ac = 0;
5353 extern XtAppContext Xt_app_con;
5354 XmString dir_xmstring, pattern_xmstring;
5355 int count = SPECPDL_INDEX ();
5356 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5358 check_x ();
5360 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5362 if (popup_activated ())
5363 error ("Trying to use a menu from within a menu-entry");
5365 CHECK_STRING (prompt);
5366 CHECK_STRING (dir);
5368 /* Prevent redisplay. */
5369 specbind (Qinhibit_redisplay, Qt);
5371 BLOCK_INPUT;
5373 /* Create the dialog with PROMPT as title, using DIR as initial
5374 directory and using "*" as pattern. */
5375 dir = Fexpand_file_name (dir, Qnil);
5376 dir_xmstring = XmStringCreateLocalized (SDATA (dir));
5377 pattern_xmstring = XmStringCreateLocalized ("*");
5379 XtSetArg (al[ac], XmNtitle, SDATA (prompt)); ++ac;
5380 XtSetArg (al[ac], XmNdirectory, dir_xmstring); ++ac;
5381 XtSetArg (al[ac], XmNpattern, pattern_xmstring); ++ac;
5382 XtSetArg (al[ac], XmNresizePolicy, XmRESIZE_GROW); ++ac;
5383 XtSetArg (al[ac], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); ++ac;
5384 dialog = XmCreateFileSelectionDialog (f->output_data.x->widget,
5385 "fsb", al, ac);
5386 XmStringFree (dir_xmstring);
5387 XmStringFree (pattern_xmstring);
5389 /* Add callbacks for OK and Cancel. */
5390 XtAddCallback (dialog, XmNokCallback, file_dialog_cb,
5391 (XtPointer) &result);
5392 XtAddCallback (dialog, XmNcancelCallback, file_dialog_cb,
5393 (XtPointer) &result);
5394 XtAddCallback (dialog, XmNunmapCallback, file_dialog_unmap_cb,
5395 (XtPointer) &result);
5397 /* Remove the help button since we can't display help. */
5398 help = XmFileSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON);
5399 XtUnmanageChild (help);
5401 /* Mark OK button as default. */
5402 XtVaSetValues (XmFileSelectionBoxGetChild (dialog, XmDIALOG_OK_BUTTON),
5403 XmNshowAsDefault, True, NULL);
5405 /* If MUSTMATCH is non-nil, disable the file entry field of the
5406 dialog, so that the user must select a file from the files list
5407 box. We can't remove it because we wouldn't have a way to get at
5408 the result file name, then. */
5409 text = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5410 if (!NILP (mustmatch))
5412 Widget label;
5413 label = XmFileSelectionBoxGetChild (dialog, XmDIALOG_SELECTION_LABEL);
5414 XtSetSensitive (text, False);
5415 XtSetSensitive (label, False);
5418 /* Manage the dialog, so that list boxes get filled. */
5419 XtManageChild (dialog);
5421 if (STRINGP (default_filename))
5423 XmString default_xmstring;
5424 Widget wtext = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5425 Widget list = XmFileSelectionBoxGetChild (dialog, XmDIALOG_LIST);
5427 XmTextPosition last_pos = XmTextFieldGetLastPosition (wtext);
5428 XmTextFieldReplace (wtext, 0, last_pos,
5429 (SDATA (Ffile_name_nondirectory (default_filename))));
5431 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
5432 must include the path for this to work. */
5434 default_xmstring = XmStringCreateLocalized (SDATA (default_filename));
5436 if (XmListItemExists (list, default_xmstring))
5438 int item_pos = XmListItemPos (list, default_xmstring);
5439 /* Select the item and scroll it into view. */
5440 XmListSelectPos (list, item_pos, True);
5441 XmListSetPos (list, item_pos);
5444 XmStringFree (default_xmstring);
5447 record_unwind_protect (clean_up_file_dialog, make_save_value (dialog, 0));
5449 /* Process events until the user presses Cancel or OK. */
5450 x_menu_set_in_use (1);
5451 result = 0;
5452 while (result == 0)
5454 XEvent event;
5455 x_menu_wait_for_event (0);
5456 XtAppNextEvent (Xt_app_con, &event);
5457 if (event.type == KeyPress
5458 && FRAME_X_DISPLAY (f) == event.xkey.display)
5460 KeySym keysym = XLookupKeysym (&event.xkey, 0);
5462 /* Pop down on C-g. */
5463 if (keysym == XK_g && (event.xkey.state & ControlMask) != 0)
5464 XtUnmanageChild (dialog);
5467 (void) x_dispatch_event (&event, FRAME_X_DISPLAY (f));
5470 /* Get the result. */
5471 if (result == XmCR_OK)
5473 XmString text;
5474 String data;
5476 XtVaGetValues (dialog, XmNtextString, &text, NULL);
5477 XmStringGetLtoR (text, XmFONTLIST_DEFAULT_TAG, &data);
5478 XmStringFree (text);
5479 file = build_string (data);
5480 XtFree (data);
5482 else
5483 file = Qnil;
5485 UNBLOCK_INPUT;
5486 UNGCPRO;
5488 /* Make "Cancel" equivalent to C-g. */
5489 if (NILP (file))
5490 Fsignal (Qquit, Qnil);
5492 decoded_file = DECODE_FILE (file);
5494 return unbind_to (count, decoded_file);
5497 #endif /* USE_MOTIF */
5499 #ifdef USE_GTK
5501 static Lisp_Object
5502 clean_up_dialog (arg)
5503 Lisp_Object arg;
5505 x_menu_set_in_use (0);
5507 return Qnil;
5510 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5511 doc: /* Read file name, prompting with PROMPT in directory DIR.
5512 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5513 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5514 or directory must exist. If ONLY-DIR-P is non-nil, the user can only select
5515 directories. */)
5516 (prompt, dir, default_filename, mustmatch, only_dir_p)
5517 Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
5519 FRAME_PTR f = SELECTED_FRAME ();
5520 char *fn;
5521 Lisp_Object file = Qnil;
5522 Lisp_Object decoded_file;
5523 int count = SPECPDL_INDEX ();
5524 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5525 char *cdef_file;
5527 check_x ();
5529 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5531 if (popup_activated ())
5532 error ("Trying to use a menu from within a menu-entry");
5534 CHECK_STRING (prompt);
5535 CHECK_STRING (dir);
5537 /* Prevent redisplay. */
5538 specbind (Qinhibit_redisplay, Qt);
5539 record_unwind_protect (clean_up_dialog, Qnil);
5541 BLOCK_INPUT;
5543 if (STRINGP (default_filename))
5544 cdef_file = SDATA (default_filename);
5545 else
5546 cdef_file = SDATA (dir);
5548 fn = xg_get_file_name (f, SDATA (prompt), cdef_file,
5549 ! NILP (mustmatch),
5550 ! NILP (only_dir_p));
5552 if (fn)
5554 file = build_string (fn);
5555 xfree (fn);
5558 UNBLOCK_INPUT;
5559 UNGCPRO;
5561 /* Make "Cancel" equivalent to C-g. */
5562 if (NILP (file))
5563 Fsignal (Qquit, Qnil);
5565 decoded_file = DECODE_FILE (file);
5567 return unbind_to (count, decoded_file);
5571 #ifdef HAVE_FREETYPE
5573 DEFUN ("x-select-font", Fx_select_font, Sx_select_font, 0, 2, 0,
5574 doc: /* Read a font name using a GTK font selection dialog.
5575 Return a GTK-style font string corresponding to the selection.
5577 If FRAME is omitted or nil, it defaults to the selected frame. */)
5578 (frame, ignored)
5579 Lisp_Object frame, ignored;
5581 FRAME_PTR f = check_x_frame (frame);
5582 char *name;
5583 Lisp_Object default_font, font = Qnil;
5584 int count = SPECPDL_INDEX ();
5586 check_x ();
5588 if (popup_activated ())
5589 error ("Trying to use a menu from within a menu-entry");
5591 /* Prevent redisplay. */
5592 specbind (Qinhibit_redisplay, Qt);
5593 record_unwind_protect (clean_up_dialog, Qnil);
5595 BLOCK_INPUT;
5597 XSETFONT (default_font, FRAME_FONT (f));
5598 if (FONTP (default_font))
5600 char *default_name = alloca (256);
5601 if (font_unparse_gtkname (default_font, f, default_name, 256) < 0)
5602 default_name = NULL;
5603 name = xg_get_font_name (f, default_name);
5605 else
5606 name = xg_get_font_name (f, NULL);
5608 if (name)
5610 font = build_string (name);
5611 xfree (name);
5614 UNBLOCK_INPUT;
5616 if (NILP (font))
5617 Fsignal (Qquit, Qnil);
5619 return unbind_to (count, font);
5621 #endif /* HAVE_FREETYPE */
5623 #endif /* USE_GTK */
5626 /***********************************************************************
5627 Keyboard
5628 ***********************************************************************/
5630 #ifdef HAVE_XKBGETKEYBOARD
5631 #include <X11/XKBlib.h>
5632 #include <X11/keysym.h>
5633 #endif
5635 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p,
5636 Sx_backspace_delete_keys_p, 0, 1, 0,
5637 doc: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
5638 FRAME nil means use the selected frame.
5639 Value is t if we know that both keys are present, and are mapped to the
5640 usual X keysyms. Value is `lambda' if we cannot determine if both keys are
5641 present and mapped to the usual X keysyms. */)
5642 (frame)
5643 Lisp_Object frame;
5645 #ifdef HAVE_XKBGETKEYBOARD
5646 XkbDescPtr kb;
5647 struct frame *f = check_x_frame (frame);
5648 Display *dpy = FRAME_X_DISPLAY (f);
5649 Lisp_Object have_keys;
5650 int major, minor, op, event, error;
5652 BLOCK_INPUT;
5654 /* Check library version in case we're dynamically linked. */
5655 major = XkbMajorVersion;
5656 minor = XkbMinorVersion;
5657 if (!XkbLibraryVersion (&major, &minor))
5659 UNBLOCK_INPUT;
5660 return Qlambda;
5663 /* Check that the server supports XKB. */
5664 major = XkbMajorVersion;
5665 minor = XkbMinorVersion;
5666 if (!XkbQueryExtension (dpy, &op, &event, &error, &major, &minor))
5668 UNBLOCK_INPUT;
5669 return Qlambda;
5672 /* In this code we check that the keyboard has physical keys with names
5673 that start with BKSP (Backspace) and DELE (Delete), and that they
5674 generate keysym XK_BackSpace and XK_Delete respectively.
5675 This function is used to test if normal-erase-is-backspace should be
5676 turned on.
5677 An alternative approach would be to just check if XK_BackSpace and
5678 XK_Delete are mapped to any key. But if any of those are mapped to
5679 some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the
5680 user doesn't know about it, it is better to return false here.
5681 It is more obvious to the user what to do if she/he has two keys
5682 clearly marked with names/symbols and one key does something not
5683 expected (i.e. she/he then tries the other).
5684 The cases where Backspace/Delete is mapped to some other key combination
5685 are rare, and in those cases, normal-erase-is-backspace can be turned on
5686 manually. */
5688 have_keys = Qnil;
5689 kb = XkbGetMap (dpy, XkbAllMapComponentsMask, XkbUseCoreKbd);
5690 if (kb)
5692 int delete_keycode = 0, backspace_keycode = 0, i;
5694 if (XkbGetNames (dpy, XkbAllNamesMask, kb) == Success)
5696 for (i = kb->min_key_code;
5697 (i < kb->max_key_code
5698 && (delete_keycode == 0 || backspace_keycode == 0));
5699 ++i)
5701 /* The XKB symbolic key names can be seen most easily in
5702 the PS file generated by `xkbprint -label name
5703 $DISPLAY'. */
5704 if (bcmp ("DELE", kb->names->keys[i].name, 4) == 0)
5705 delete_keycode = i;
5706 else if (bcmp ("BKSP", kb->names->keys[i].name, 4) == 0)
5707 backspace_keycode = i;
5710 XkbFreeNames (kb, 0, True);
5713 XkbFreeClientMap (kb, 0, True);
5715 if (delete_keycode
5716 && backspace_keycode
5717 && XKeysymToKeycode (dpy, XK_Delete) == delete_keycode
5718 && XKeysymToKeycode (dpy, XK_BackSpace) == backspace_keycode)
5719 have_keys = Qt;
5721 UNBLOCK_INPUT;
5722 return have_keys;
5723 #else /* not HAVE_XKBGETKEYBOARD */
5724 return Qlambda;
5725 #endif /* not HAVE_XKBGETKEYBOARD */
5730 /***********************************************************************
5731 Initialization
5732 ***********************************************************************/
5734 /* Keep this list in the same order as frame_parms in frame.c.
5735 Use 0 for unsupported frame parameters. */
5737 frame_parm_handler x_frame_parm_handlers[] =
5739 x_set_autoraise,
5740 x_set_autolower,
5741 x_set_background_color,
5742 x_set_border_color,
5743 x_set_border_width,
5744 x_set_cursor_color,
5745 x_set_cursor_type,
5746 x_set_font,
5747 x_set_foreground_color,
5748 x_set_icon_name,
5749 x_set_icon_type,
5750 x_set_internal_border_width,
5751 x_set_menu_bar_lines,
5752 x_set_mouse_color,
5753 x_explicitly_set_name,
5754 x_set_scroll_bar_width,
5755 x_set_title,
5756 x_set_unsplittable,
5757 x_set_vertical_scroll_bars,
5758 x_set_visibility,
5759 x_set_tool_bar_lines,
5760 x_set_scroll_bar_foreground,
5761 x_set_scroll_bar_background,
5762 x_set_screen_gamma,
5763 x_set_line_spacing,
5764 x_set_fringe_width,
5765 x_set_fringe_width,
5766 x_set_wait_for_wm,
5767 x_set_fullscreen,
5768 x_set_font_backend,
5769 x_set_alpha
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 ("none");
5782 staticpro (&Qnone);
5783 Qsuppress_icon = intern ("suppress-icon");
5784 staticpro (&Qsuppress_icon);
5785 Qundefined_color = intern ("undefined-color");
5786 staticpro (&Qundefined_color);
5787 Qcompound_text = intern ("compound-text");
5788 staticpro (&Qcompound_text);
5789 Qcancel_timer = intern ("cancel-timer");
5790 staticpro (&Qcancel_timer);
5791 Qfont_param = intern ("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 Fcons (Qundefined_color, Fcons (Qerror, Qnil)));
5802 Fput (Qundefined_color, Qerror_message,
5803 build_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 ("x"), Qnil);
5902 #ifdef USE_X_TOOLKIT
5903 Fprovide (intern ("x-toolkit"), Qnil);
5904 #ifdef USE_MOTIF
5905 Fprovide (intern ("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 ("x-toolkit"), Qnil);
5919 Fprovide (intern ("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 = build_string (gtk_version);
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_create_frame);
5954 defsubr (&Sx_open_connection);
5955 defsubr (&Sx_close_connection);
5956 defsubr (&Sx_display_list);
5957 defsubr (&Sx_synchronize);
5958 defsubr (&Sx_focus_frame);
5959 defsubr (&Sx_backspace_delete_keys_p);
5961 /* Setting callback functions for fontset handler. */
5962 check_window_system_func = check_x;
5964 defsubr (&Sx_show_tip);
5965 defsubr (&Sx_hide_tip);
5966 tip_timer = Qnil;
5967 staticpro (&tip_timer);
5968 tip_frame = Qnil;
5969 staticpro (&tip_frame);
5971 last_show_tip_args = Qnil;
5972 staticpro (&last_show_tip_args);
5974 defsubr (&Sx_uses_old_gtk_dialog);
5975 #if defined (USE_MOTIF) || defined (USE_GTK)
5976 defsubr (&Sx_file_dialog);
5977 #endif
5979 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
5980 defsubr (&Sx_select_font);
5981 #endif
5984 #endif /* HAVE_X_WINDOWS */
5986 /* arch-tag: 55040d02-5485-4d58-8b22-95a7a05f3288
5987 (do not change this comment) */