Mention multi-planes text-properties
[emacs.git] / src / xfns.c
blobd19914e8dec94d977f7cac8035d331a0c474cdaf
1 /* Functions for the X window system.
2 Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 #include <config.h>
22 #include <stdio.h>
23 #include <math.h>
24 #include <setjmp.h>
25 #include <ctype.h>
27 #ifdef HAVE_UNISTD_H
28 #include <unistd.h>
29 #endif
31 /* This makes the fields of a Display accessible, in Xlib header files. */
33 #define XLIB_ILLEGAL_ACCESS
35 #include "lisp.h"
36 #include "xterm.h"
37 #include "frame.h"
38 #include "window.h"
39 #include "buffer.h"
40 #include "intervals.h"
41 #include "dispextern.h"
42 #include "keyboard.h"
43 #include "blockinput.h"
44 #include <epaths.h>
45 #include "character.h"
46 #include "charset.h"
47 #include "coding.h"
48 #include "fontset.h"
49 #include "systime.h"
50 #include "termhooks.h"
51 #include "atimer.h"
52 #include "termchar.h"
53 #include "font.h"
55 #ifdef HAVE_X_WINDOWS
57 #include <ctype.h>
58 #include <sys/types.h>
59 #include <sys/stat.h>
61 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */
62 #include "bitmaps/gray.xbm"
63 #else
64 #include <X11/bitmaps/gray>
65 #endif
67 #include "xsettings.h"
69 #ifdef USE_GTK
70 #include "gtkutil.h"
71 #endif
73 #ifdef USE_X_TOOLKIT
74 #include <X11/Shell.h>
76 #ifndef USE_MOTIF
77 #ifdef HAVE_XAW3D
78 #include <X11/Xaw3d/Paned.h>
79 #include <X11/Xaw3d/Label.h>
80 #else /* !HAVE_XAW3D */
81 #include <X11/Xaw/Paned.h>
82 #include <X11/Xaw/Label.h>
83 #endif /* HAVE_XAW3D */
84 #endif /* USE_MOTIF */
86 #ifdef USG
87 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
88 #include <X11/Xos.h>
89 #define USG
90 #else
91 #include <X11/Xos.h>
92 #endif
94 #include "widget.h"
96 #include "../lwlib/lwlib.h"
98 #ifdef USE_MOTIF
99 #include <Xm/Xm.h>
100 #include <Xm/DialogS.h>
101 #include <Xm/FileSB.h>
102 #endif
104 #if !defined(NO_EDITRES)
105 #define HACK_EDITRES
106 extern void _XEditResCheckMessages ();
107 #endif /* not defined NO_EDITRES */
109 /* Unique id counter for widgets created by the Lucid Widget Library. */
111 extern LWLIB_ID widget_id_tick;
113 extern void free_frame_menubar ();
114 extern double atof ();
116 #ifdef USE_MOTIF
118 /* LessTif/Motif version info. */
120 static Lisp_Object Vmotif_version_string;
122 #endif /* USE_MOTIF */
124 #endif /* USE_X_TOOLKIT */
126 #ifdef USE_GTK
128 /* GTK+ version info */
130 static Lisp_Object Vgtk_version_string;
132 #endif /* USE_GTK */
134 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
136 /* The gray bitmap `bitmaps/gray'. This is done because xterm.c uses
137 it, and including `bitmaps/gray' more than once is a problem when
138 config.h defines `static' as an empty replacement string. */
140 int gray_bitmap_width = gray_width;
141 int gray_bitmap_height = gray_height;
142 char *gray_bitmap_bits = gray_bits;
144 /* Non-zero means prompt with the old GTK file selection dialog. */
146 int x_gtk_use_old_file_dialog;
148 /* If non-zero, by default show hidden files in the GTK file chooser. */
150 int x_gtk_show_hidden_files;
152 /* If non-zero, don't show additional help text in the GTK file chooser. */
154 int x_gtk_file_dialog_help_text;
156 /* If non-zero, don't collapse to tool bar when it is detached. */
158 int x_gtk_whole_detached_tool_bar;
160 /* The background and shape of the mouse pointer, and shape when not
161 over text or in the modeline. */
163 Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
164 Lisp_Object Vx_hourglass_pointer_shape;
166 /* The shape when over mouse-sensitive text. */
168 Lisp_Object Vx_sensitive_text_pointer_shape;
170 /* If non-nil, the pointer shape to indicate that windows can be
171 dragged horizontally. */
173 Lisp_Object Vx_window_horizontal_drag_shape;
175 /* Color of chars displayed in cursor box. */
177 Lisp_Object Vx_cursor_fore_pixel;
179 /* Nonzero if using X. */
181 static int x_in_use;
183 /* Non nil if no window manager is in use. */
185 Lisp_Object Vx_no_window_manager;
187 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
189 Lisp_Object Vx_pixel_size_width_font_regexp;
191 Lisp_Object Qnone;
192 Lisp_Object Qsuppress_icon;
193 Lisp_Object Qundefined_color;
194 Lisp_Object Qcompound_text, Qcancel_timer;
195 Lisp_Object Qfont_param;
197 /* In dispnew.c */
199 extern Lisp_Object Vwindow_system_version;
201 /* In editfns.c */
203 extern Lisp_Object Vsystem_name;
205 /* The below are defined in frame.c. */
207 #if GLYPH_DEBUG
208 int image_cache_refcount, dpyinfo_refcount;
209 #endif
211 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
212 char *x_last_font_name;
213 #endif
216 /* Error if we are not connected to X. */
218 void
219 check_x ()
221 if (! x_in_use)
222 error ("X windows are not in use or not initialized");
225 /* Nonzero if we can use mouse menus.
226 You should not call this unless HAVE_MENUS is defined. */
229 have_menus_p ()
231 return x_in_use;
234 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
235 and checking validity for X. */
237 FRAME_PTR
238 check_x_frame (frame)
239 Lisp_Object frame;
241 FRAME_PTR f;
243 if (NILP (frame))
244 frame = selected_frame;
245 CHECK_LIVE_FRAME (frame);
246 f = XFRAME (frame);
247 if (! FRAME_X_P (f))
248 error ("Non-X frame used");
249 return f;
252 /* Let the user specify an X display with a Lisp object.
253 OBJECT may be nil, a frame or a terminal object.
254 nil stands for the selected frame--or, if that is not an X frame,
255 the first X display on the list. */
257 struct x_display_info *
258 check_x_display_info (object)
259 Lisp_Object object;
261 struct x_display_info *dpyinfo = NULL;
263 if (NILP (object))
265 struct frame *sf = XFRAME (selected_frame);
267 if (FRAME_X_P (sf) && FRAME_LIVE_P (sf))
268 dpyinfo = FRAME_X_DISPLAY_INFO (sf);
269 else if (x_display_list != 0)
270 dpyinfo = x_display_list;
271 else
272 error ("X windows are not in use or not initialized");
274 else if (TERMINALP (object))
276 struct terminal *t = get_terminal (object, 1);
278 if (t->type != output_x_window)
279 error ("Terminal %d is not an X display", XINT (object));
281 dpyinfo = t->display_info.x;
283 else if (STRINGP (object))
284 dpyinfo = x_display_info_for_name (object);
285 else
287 FRAME_PTR f = check_x_frame (object);
288 dpyinfo = FRAME_X_DISPLAY_INFO (f);
291 return dpyinfo;
295 /* Return the Emacs frame-object corresponding to an X window.
296 It could be the frame's main window or an icon window. */
298 /* This function can be called during GC, so use GC_xxx type test macros. */
300 struct frame *
301 x_window_to_frame (dpyinfo, wdesc)
302 struct x_display_info *dpyinfo;
303 int wdesc;
305 Lisp_Object tail, frame;
306 struct frame *f;
308 if (wdesc == None) return 0;
310 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
312 frame = XCAR (tail);
313 if (!FRAMEP (frame))
314 continue;
315 f = XFRAME (frame);
316 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
317 continue;
318 if (f->output_data.x->hourglass_window == wdesc)
319 return f;
320 #ifdef USE_X_TOOLKIT
321 if ((f->output_data.x->edit_widget
322 && XtWindow (f->output_data.x->edit_widget) == wdesc)
323 /* A tooltip frame? */
324 || (!f->output_data.x->edit_widget
325 && FRAME_X_WINDOW (f) == wdesc)
326 || f->output_data.x->icon_desc == wdesc)
327 return f;
328 #else /* not USE_X_TOOLKIT */
329 #ifdef USE_GTK
330 if (f->output_data.x->edit_widget)
332 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
333 struct x_output *x = f->output_data.x;
334 if (gwdesc != 0 && gwdesc == x->edit_widget)
335 return f;
337 #endif /* USE_GTK */
338 if (FRAME_X_WINDOW (f) == wdesc
339 || f->output_data.x->icon_desc == wdesc)
340 return f;
341 #endif /* not USE_X_TOOLKIT */
343 return 0;
346 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
347 /* Like x_window_to_frame but also compares the window with the widget's
348 windows. */
350 struct frame *
351 x_any_window_to_frame (dpyinfo, wdesc)
352 struct x_display_info *dpyinfo;
353 int wdesc;
355 Lisp_Object tail, frame;
356 struct frame *f, *found;
357 struct x_output *x;
359 if (wdesc == None) return NULL;
361 found = NULL;
362 for (tail = Vframe_list; CONSP (tail) && !found; tail = XCDR (tail))
364 frame = XCAR (tail);
365 if (!FRAMEP (frame))
366 continue;
368 f = XFRAME (frame);
369 if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) == dpyinfo)
371 /* This frame matches if the window is any of its widgets. */
372 x = f->output_data.x;
373 if (x->hourglass_window == wdesc)
374 found = f;
375 else if (x->widget)
377 #ifdef USE_GTK
378 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
379 if (gwdesc != 0
380 && gtk_widget_get_toplevel (gwdesc) == x->widget)
381 found = f;
382 #else
383 if (wdesc == XtWindow (x->widget)
384 || wdesc == XtWindow (x->column_widget)
385 || wdesc == XtWindow (x->edit_widget))
386 found = f;
387 /* Match if the window is this frame's menubar. */
388 else if (lw_window_is_in_menubar (wdesc, x->menubar_widget))
389 found = f;
390 #endif
392 else if (FRAME_X_WINDOW (f) == wdesc)
393 /* A tooltip frame. */
394 found = f;
398 return found;
401 /* Likewise, but consider only the menu bar widget. */
403 struct frame *
404 x_menubar_window_to_frame (dpyinfo, wdesc)
405 struct x_display_info *dpyinfo;
406 int wdesc;
408 Lisp_Object tail, frame;
409 struct frame *f;
410 struct x_output *x;
412 if (wdesc == None) return 0;
414 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
416 frame = XCAR (tail);
417 if (!FRAMEP (frame))
418 continue;
419 f = XFRAME (frame);
420 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
421 continue;
422 x = f->output_data.x;
423 /* Match if the window is this frame's menubar. */
424 #ifdef USE_GTK
425 if (x->menubar_widget)
427 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
429 /* This gives false positives, but the rectangle check in xterm.c
430 where this is called takes care of that. */
431 if (gwdesc != 0
432 && (gwdesc == x->menubar_widget
433 || gtk_widget_is_ancestor (x->menubar_widget, gwdesc)
434 || gtk_widget_is_ancestor (gwdesc, x->menubar_widget)))
435 return f;
437 #else
438 if (x->menubar_widget
439 && lw_window_is_in_menubar (wdesc, x->menubar_widget))
440 return f;
441 #endif
443 return 0;
446 /* Return the frame whose principal (outermost) window is WDESC.
447 If WDESC is some other (smaller) window, we return 0. */
449 struct frame *
450 x_top_window_to_frame (dpyinfo, wdesc)
451 struct x_display_info *dpyinfo;
452 int wdesc;
454 Lisp_Object tail, frame;
455 struct frame *f;
456 struct x_output *x;
458 if (wdesc == None) return 0;
460 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
462 frame = XCAR (tail);
463 if (!FRAMEP (frame))
464 continue;
465 f = XFRAME (frame);
466 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
467 continue;
468 x = f->output_data.x;
470 if (x->widget)
472 /* This frame matches if the window is its topmost widget. */
473 #ifdef USE_GTK
474 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
475 if (gwdesc == x->widget)
476 return f;
477 #else
478 if (wdesc == XtWindow (x->widget))
479 return f;
480 #if 0 /* I don't know why it did this,
481 but it seems logically wrong,
482 and it causes trouble for MapNotify events. */
483 /* Match if the window is this frame's menubar. */
484 if (x->menubar_widget
485 && wdesc == XtWindow (x->menubar_widget))
486 return f;
487 #endif
488 #endif
490 else if (FRAME_X_WINDOW (f) == wdesc)
491 /* Tooltip frame. */
492 return f;
494 return 0;
496 #endif /* USE_X_TOOLKIT || USE_GTK */
500 static void x_default_font_parameter P_ ((struct frame *, Lisp_Object));
502 static Lisp_Object unwind_create_frame P_ ((Lisp_Object));
503 static Lisp_Object unwind_create_tip_frame P_ ((Lisp_Object));
505 void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
506 static void x_set_wait_for_wm P_ ((struct frame *, Lisp_Object, Lisp_Object));
507 void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
508 void x_set_mouse_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
509 void x_set_cursor_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
510 void x_set_border_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
511 void x_set_cursor_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
512 void x_set_icon_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
513 void x_set_icon_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
514 void x_explicitly_set_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
515 void x_set_menu_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
516 void x_set_title P_ ((struct frame *, Lisp_Object, Lisp_Object));
517 void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
518 void x_set_scroll_bar_foreground P_ ((struct frame *, Lisp_Object,
519 Lisp_Object));
520 void x_set_scroll_bar_background P_ ((struct frame *, Lisp_Object,
521 Lisp_Object));
522 static Lisp_Object x_default_scroll_bar_color_parameter P_ ((struct frame *,
523 Lisp_Object,
524 Lisp_Object,
525 char *, char *,
526 int));
529 /* Store the screen positions of frame F into XPTR and YPTR.
530 These are the positions of the containing window manager window,
531 not Emacs's own window. */
533 void
534 x_real_positions (f, xptr, yptr)
535 FRAME_PTR f;
536 int *xptr, *yptr;
538 int win_x, win_y, outer_x, outer_y;
539 int real_x = 0, real_y = 0;
540 int had_errors = 0;
541 Window win = f->output_data.x->parent_desc;
543 BLOCK_INPUT;
545 x_catch_errors (FRAME_X_DISPLAY (f));
547 if (win == FRAME_X_DISPLAY_INFO (f)->root_window)
548 win = FRAME_OUTER_WINDOW (f);
550 /* This loop traverses up the containment tree until we hit the root
551 window. Window managers may intersect many windows between our window
552 and the root window. The window we find just before the root window
553 should be the outer WM window. */
554 for (;;)
556 Window wm_window, rootw;
557 Window *tmp_children;
558 unsigned int tmp_nchildren;
559 int success;
561 success = XQueryTree (FRAME_X_DISPLAY (f), win, &rootw,
562 &wm_window, &tmp_children, &tmp_nchildren);
564 had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
566 /* Don't free tmp_children if XQueryTree failed. */
567 if (! success)
568 break;
570 XFree ((char *) tmp_children);
572 if (wm_window == rootw || had_errors)
573 break;
575 win = wm_window;
578 if (! had_errors)
580 unsigned int ign;
581 Window child, rootw;
583 /* Get the real coordinates for the WM window upper left corner */
584 XGetGeometry (FRAME_X_DISPLAY (f), win,
585 &rootw, &real_x, &real_y, &ign, &ign, &ign, &ign);
587 /* Translate real coordinates to coordinates relative to our
588 window. For our window, the upper left corner is 0, 0.
589 Since the upper left corner of the WM window is outside
590 our window, win_x and win_y will be negative:
592 ------------------ ---> x
593 | title |
594 | ----------------- v y
595 | | our window
597 XTranslateCoordinates (FRAME_X_DISPLAY (f),
599 /* From-window, to-window. */
600 FRAME_X_DISPLAY_INFO (f)->root_window,
601 FRAME_X_WINDOW (f),
603 /* From-position, to-position. */
604 real_x, real_y, &win_x, &win_y,
606 /* Child of win. */
607 &child);
609 if (FRAME_X_WINDOW (f) == FRAME_OUTER_WINDOW (f))
611 outer_x = win_x;
612 outer_y = win_y;
614 else
616 XTranslateCoordinates (FRAME_X_DISPLAY (f),
618 /* From-window, to-window. */
619 FRAME_X_DISPLAY_INFO (f)->root_window,
620 FRAME_OUTER_WINDOW (f),
622 /* From-position, to-position. */
623 real_x, real_y, &outer_x, &outer_y,
625 /* Child of win. */
626 &child);
629 had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
632 x_uncatch_errors ();
634 UNBLOCK_INPUT;
636 if (had_errors) return;
638 f->x_pixels_diff = -win_x;
639 f->y_pixels_diff = -win_y;
641 FRAME_X_OUTPUT (f)->x_pixels_outer_diff = -outer_x;
642 FRAME_X_OUTPUT (f)->y_pixels_outer_diff = -outer_y;
644 *xptr = real_x;
645 *yptr = real_y;
651 /* Gamma-correct COLOR on frame F. */
653 void
654 gamma_correct (f, color)
655 struct frame *f;
656 XColor *color;
658 if (f->gamma)
660 color->red = pow (color->red / 65535.0, f->gamma) * 65535.0 + 0.5;
661 color->green = pow (color->green / 65535.0, f->gamma) * 65535.0 + 0.5;
662 color->blue = pow (color->blue / 65535.0, f->gamma) * 65535.0 + 0.5;
667 /* Decide if color named COLOR_NAME is valid for use on frame F. If
668 so, return the RGB values in COLOR. If ALLOC_P is non-zero,
669 allocate the color. Value is zero if COLOR_NAME is invalid, or
670 no color could be allocated. */
673 x_defined_color (f, color_name, color, alloc_p)
674 struct frame *f;
675 char *color_name;
676 XColor *color;
677 int alloc_p;
679 int success_p;
680 Display *dpy = FRAME_X_DISPLAY (f);
681 Colormap cmap = FRAME_X_COLORMAP (f);
683 BLOCK_INPUT;
684 success_p = XParseColor (dpy, cmap, color_name, color);
685 if (success_p && alloc_p)
686 success_p = x_alloc_nearest_color (f, cmap, color);
687 UNBLOCK_INPUT;
689 return success_p;
693 /* Return the pixel color value for color COLOR_NAME on frame F. If F
694 is a monochrome frame, return MONO_COLOR regardless of what ARG says.
695 Signal an error if color can't be allocated. */
698 x_decode_color (f, color_name, mono_color)
699 FRAME_PTR f;
700 Lisp_Object color_name;
701 int mono_color;
703 XColor cdef;
705 CHECK_STRING (color_name);
707 #if 0 /* Don't do this. It's wrong when we're not using the default
708 colormap, it makes freeing difficult, and it's probably not
709 an important optimization. */
710 if (strcmp (SDATA (color_name), "black") == 0)
711 return BLACK_PIX_DEFAULT (f);
712 else if (strcmp (SDATA (color_name), "white") == 0)
713 return WHITE_PIX_DEFAULT (f);
714 #endif
716 /* Return MONO_COLOR for monochrome frames. */
717 if (FRAME_X_DISPLAY_INFO (f)->n_planes == 1)
718 return mono_color;
720 /* x_defined_color is responsible for coping with failures
721 by looking for a near-miss. */
722 if (x_defined_color (f, SDATA (color_name), &cdef, 1))
723 return cdef.pixel;
725 signal_error ("Undefined color", color_name);
730 /* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
731 the previous value of that parameter, NEW_VALUE is the new value.
732 See also the comment of wait_for_wm in struct x_output. */
734 static void
735 x_set_wait_for_wm (f, new_value, old_value)
736 struct frame *f;
737 Lisp_Object new_value, old_value;
739 f->output_data.x->wait_for_wm = !NILP (new_value);
742 #ifdef USE_GTK
744 /* Set icon from FILE for frame F. By using GTK functions the icon
745 may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
748 xg_set_icon (f, file)
749 FRAME_PTR f;
750 Lisp_Object file;
752 int result = 0;
753 Lisp_Object found;
755 found = x_find_image_file (file);
757 if (! NILP (found))
759 GdkPixbuf *pixbuf;
760 GError *err = NULL;
761 char *filename = (char *) SDATA (found);
762 BLOCK_INPUT;
764 pixbuf = gdk_pixbuf_new_from_file (filename, &err);
766 if (pixbuf)
768 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
769 pixbuf);
770 g_object_unref (pixbuf);
772 result = 1;
774 else
775 g_error_free (err);
777 UNBLOCK_INPUT;
780 return result;
784 xg_set_icon_from_xpm_data (f, data)
785 FRAME_PTR f;
786 char **data;
788 int result = 0;
789 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) data);
791 if (!pixbuf)
792 return 0;
794 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), pixbuf);
795 g_object_unref (pixbuf);
796 return 1;
798 #endif /* USE_GTK */
801 /* Functions called only from `x_set_frame_param'
802 to set individual parameters.
804 If FRAME_X_WINDOW (f) is 0,
805 the frame is being created and its X-window does not exist yet.
806 In that case, just record the parameter's new value
807 in the standard place; do not attempt to change the window. */
809 void
810 x_set_foreground_color (f, arg, oldval)
811 struct frame *f;
812 Lisp_Object arg, oldval;
814 struct x_output *x = f->output_data.x;
815 unsigned long fg, old_fg;
817 fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
818 old_fg = FRAME_FOREGROUND_PIXEL (f);
819 FRAME_FOREGROUND_PIXEL (f) = fg;
821 if (FRAME_X_WINDOW (f) != 0)
823 Display *dpy = FRAME_X_DISPLAY (f);
825 BLOCK_INPUT;
826 XSetForeground (dpy, x->normal_gc, fg);
827 XSetBackground (dpy, x->reverse_gc, fg);
829 if (x->cursor_pixel == old_fg)
831 unload_color (f, x->cursor_pixel);
832 x->cursor_pixel = x_copy_color (f, fg);
833 XSetBackground (dpy, x->cursor_gc, x->cursor_pixel);
836 UNBLOCK_INPUT;
838 update_face_from_frame_parameter (f, Qforeground_color, arg);
840 if (FRAME_VISIBLE_P (f))
841 redraw_frame (f);
844 unload_color (f, old_fg);
847 void
848 x_set_background_color (f, arg, oldval)
849 struct frame *f;
850 Lisp_Object arg, oldval;
852 struct x_output *x = f->output_data.x;
853 unsigned long bg;
855 bg = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
856 unload_color (f, FRAME_BACKGROUND_PIXEL (f));
857 FRAME_BACKGROUND_PIXEL (f) = bg;
859 if (FRAME_X_WINDOW (f) != 0)
861 Display *dpy = FRAME_X_DISPLAY (f);
863 BLOCK_INPUT;
864 XSetBackground (dpy, x->normal_gc, bg);
865 XSetForeground (dpy, x->reverse_gc, bg);
866 XSetWindowBackground (dpy, FRAME_X_WINDOW (f), bg);
867 XSetForeground (dpy, x->cursor_gc, bg);
869 #ifdef USE_GTK
870 xg_set_background_color (f, bg);
871 #endif
873 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
874 toolkit scroll bars. */
876 Lisp_Object bar;
877 for (bar = FRAME_SCROLL_BARS (f);
878 !NILP (bar);
879 bar = XSCROLL_BAR (bar)->next)
881 Window window = XSCROLL_BAR (bar)->x_window;
882 XSetWindowBackground (dpy, window, bg);
885 #endif /* USE_TOOLKIT_SCROLL_BARS */
887 UNBLOCK_INPUT;
888 update_face_from_frame_parameter (f, Qbackground_color, arg);
890 if (FRAME_VISIBLE_P (f))
891 redraw_frame (f);
895 static Cursor
896 make_invisible_cursor (f)
897 struct frame *f;
899 Display *dpy = FRAME_X_DISPLAY (f);
900 static char const no_data[] = { 0 };
901 Pixmap pix;
902 XColor col;
903 Cursor c;
905 x_catch_errors (dpy);
906 pix = XCreateBitmapFromData (dpy, FRAME_X_DISPLAY_INFO (f)->root_window,
907 no_data, 1, 1);
908 if (! x_had_errors_p (dpy) && pix != None)
910 col.pixel = 0;
911 col.red = col.green = col.blue = 0;
912 col.flags = DoRed | DoGreen | DoBlue;
913 c = XCreatePixmapCursor (dpy, pix, pix, &col, &col, 0, 0);
914 if (x_had_errors_p (dpy) || c == None)
915 c = 0;
916 XFreePixmap (dpy, pix);
919 x_uncatch_errors ();
921 return c;
924 void
925 x_set_mouse_color (f, arg, oldval)
926 struct frame *f;
927 Lisp_Object arg, oldval;
929 struct x_output *x = f->output_data.x;
930 Display *dpy = FRAME_X_DISPLAY (f);
931 Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
932 Cursor hourglass_cursor, horizontal_drag_cursor;
933 unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
934 unsigned long mask_color = FRAME_BACKGROUND_PIXEL (f);
936 /* Don't let pointers be invisible. */
937 if (mask_color == pixel)
939 x_free_colors (f, &pixel, 1);
940 pixel = x_copy_color (f, FRAME_FOREGROUND_PIXEL (f));
943 unload_color (f, x->mouse_pixel);
944 x->mouse_pixel = pixel;
946 BLOCK_INPUT;
948 /* It's not okay to crash if the user selects a screwy cursor. */
949 x_catch_errors (dpy);
951 if (!NILP (Vx_pointer_shape))
953 CHECK_NUMBER (Vx_pointer_shape);
954 cursor = XCreateFontCursor (dpy, XINT (Vx_pointer_shape));
956 else
957 cursor = XCreateFontCursor (dpy, XC_xterm);
958 x_check_errors (dpy, "bad text pointer cursor: %s");
960 if (!NILP (Vx_nontext_pointer_shape))
962 CHECK_NUMBER (Vx_nontext_pointer_shape);
963 nontext_cursor
964 = XCreateFontCursor (dpy, XINT (Vx_nontext_pointer_shape));
966 else
967 nontext_cursor = XCreateFontCursor (dpy, XC_left_ptr);
968 x_check_errors (dpy, "bad nontext pointer cursor: %s");
970 if (!NILP (Vx_hourglass_pointer_shape))
972 CHECK_NUMBER (Vx_hourglass_pointer_shape);
973 hourglass_cursor
974 = XCreateFontCursor (dpy, XINT (Vx_hourglass_pointer_shape));
976 else
977 hourglass_cursor = XCreateFontCursor (dpy, XC_watch);
978 x_check_errors (dpy, "bad hourglass pointer cursor: %s");
980 if (!NILP (Vx_mode_pointer_shape))
982 CHECK_NUMBER (Vx_mode_pointer_shape);
983 mode_cursor = XCreateFontCursor (dpy, XINT (Vx_mode_pointer_shape));
985 else
986 mode_cursor = XCreateFontCursor (dpy, XC_xterm);
987 x_check_errors (dpy, "bad modeline pointer cursor: %s");
989 if (!NILP (Vx_sensitive_text_pointer_shape))
991 CHECK_NUMBER (Vx_sensitive_text_pointer_shape);
992 hand_cursor
993 = XCreateFontCursor (dpy, XINT (Vx_sensitive_text_pointer_shape));
995 else
996 hand_cursor = XCreateFontCursor (dpy, XC_hand2);
998 if (!NILP (Vx_window_horizontal_drag_shape))
1000 CHECK_NUMBER (Vx_window_horizontal_drag_shape);
1001 horizontal_drag_cursor
1002 = XCreateFontCursor (dpy, XINT (Vx_window_horizontal_drag_shape));
1004 else
1005 horizontal_drag_cursor
1006 = XCreateFontCursor (dpy, XC_sb_h_double_arrow);
1008 /* Check and report errors with the above calls. */
1009 x_check_errors (dpy, "can't set cursor shape: %s");
1010 x_uncatch_errors ();
1013 XColor fore_color, back_color;
1015 fore_color.pixel = x->mouse_pixel;
1016 x_query_color (f, &fore_color);
1017 back_color.pixel = mask_color;
1018 x_query_color (f, &back_color);
1020 XRecolorCursor (dpy, cursor, &fore_color, &back_color);
1021 XRecolorCursor (dpy, nontext_cursor, &fore_color, &back_color);
1022 XRecolorCursor (dpy, mode_cursor, &fore_color, &back_color);
1023 XRecolorCursor (dpy, hand_cursor, &fore_color, &back_color);
1024 XRecolorCursor (dpy, hourglass_cursor, &fore_color, &back_color);
1025 XRecolorCursor (dpy, horizontal_drag_cursor, &fore_color, &back_color);
1028 if (FRAME_X_WINDOW (f) != 0)
1029 XDefineCursor (dpy, FRAME_X_WINDOW (f),
1030 f->output_data.x->current_cursor = cursor);
1032 if (FRAME_X_DISPLAY_INFO (f)->invisible_cursor == 0)
1033 FRAME_X_DISPLAY_INFO (f)->invisible_cursor = make_invisible_cursor (f);
1035 if (cursor != x->text_cursor
1036 && x->text_cursor != 0)
1037 XFreeCursor (dpy, x->text_cursor);
1038 x->text_cursor = cursor;
1040 if (nontext_cursor != x->nontext_cursor
1041 && x->nontext_cursor != 0)
1042 XFreeCursor (dpy, x->nontext_cursor);
1043 x->nontext_cursor = nontext_cursor;
1045 if (hourglass_cursor != x->hourglass_cursor
1046 && x->hourglass_cursor != 0)
1047 XFreeCursor (dpy, x->hourglass_cursor);
1048 x->hourglass_cursor = hourglass_cursor;
1050 if (mode_cursor != x->modeline_cursor
1051 && x->modeline_cursor != 0)
1052 XFreeCursor (dpy, f->output_data.x->modeline_cursor);
1053 x->modeline_cursor = mode_cursor;
1055 if (hand_cursor != x->hand_cursor
1056 && x->hand_cursor != 0)
1057 XFreeCursor (dpy, x->hand_cursor);
1058 x->hand_cursor = hand_cursor;
1060 if (horizontal_drag_cursor != x->horizontal_drag_cursor
1061 && x->horizontal_drag_cursor != 0)
1062 XFreeCursor (dpy, x->horizontal_drag_cursor);
1063 x->horizontal_drag_cursor = horizontal_drag_cursor;
1065 XFlush (dpy);
1066 UNBLOCK_INPUT;
1068 update_face_from_frame_parameter (f, Qmouse_color, arg);
1071 void
1072 x_set_cursor_color (f, arg, oldval)
1073 struct frame *f;
1074 Lisp_Object arg, oldval;
1076 unsigned long fore_pixel, pixel;
1077 int fore_pixel_allocated_p = 0, pixel_allocated_p = 0;
1078 struct x_output *x = f->output_data.x;
1080 if (!NILP (Vx_cursor_fore_pixel))
1082 fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
1083 WHITE_PIX_DEFAULT (f));
1084 fore_pixel_allocated_p = 1;
1086 else
1087 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1089 pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1090 pixel_allocated_p = 1;
1092 /* Make sure that the cursor color differs from the background color. */
1093 if (pixel == FRAME_BACKGROUND_PIXEL (f))
1095 if (pixel_allocated_p)
1097 x_free_colors (f, &pixel, 1);
1098 pixel_allocated_p = 0;
1101 pixel = x->mouse_pixel;
1102 if (pixel == fore_pixel)
1104 if (fore_pixel_allocated_p)
1106 x_free_colors (f, &fore_pixel, 1);
1107 fore_pixel_allocated_p = 0;
1109 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1113 unload_color (f, x->cursor_foreground_pixel);
1114 if (!fore_pixel_allocated_p)
1115 fore_pixel = x_copy_color (f, fore_pixel);
1116 x->cursor_foreground_pixel = fore_pixel;
1118 unload_color (f, x->cursor_pixel);
1119 if (!pixel_allocated_p)
1120 pixel = x_copy_color (f, pixel);
1121 x->cursor_pixel = pixel;
1123 if (FRAME_X_WINDOW (f) != 0)
1125 BLOCK_INPUT;
1126 XSetBackground (FRAME_X_DISPLAY (f), x->cursor_gc, x->cursor_pixel);
1127 XSetForeground (FRAME_X_DISPLAY (f), x->cursor_gc, fore_pixel);
1128 UNBLOCK_INPUT;
1130 if (FRAME_VISIBLE_P (f))
1132 x_update_cursor (f, 0);
1133 x_update_cursor (f, 1);
1137 update_face_from_frame_parameter (f, Qcursor_color, arg);
1140 /* Set the border-color of frame F to pixel value PIX.
1141 Note that this does not fully take effect if done before
1142 F has an x-window. */
1144 void
1145 x_set_border_pixel (f, pix)
1146 struct frame *f;
1147 int pix;
1149 unload_color (f, f->output_data.x->border_pixel);
1150 f->output_data.x->border_pixel = pix;
1152 if (FRAME_X_WINDOW (f) != 0 && f->border_width > 0)
1154 BLOCK_INPUT;
1155 XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1156 (unsigned long)pix);
1157 UNBLOCK_INPUT;
1159 if (FRAME_VISIBLE_P (f))
1160 redraw_frame (f);
1164 /* Set the border-color of frame F to value described by ARG.
1165 ARG can be a string naming a color.
1166 The border-color is used for the border that is drawn by the X server.
1167 Note that this does not fully take effect if done before
1168 F has an x-window; it must be redone when the window is created.
1170 Note: this is done in two routines because of the way X10 works.
1172 Note: under X11, this is normally the province of the window manager,
1173 and so emacs' border colors may be overridden. */
1175 void
1176 x_set_border_color (f, arg, oldval)
1177 struct frame *f;
1178 Lisp_Object arg, oldval;
1180 int pix;
1182 CHECK_STRING (arg);
1183 pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1184 x_set_border_pixel (f, pix);
1185 update_face_from_frame_parameter (f, Qborder_color, arg);
1189 void
1190 x_set_cursor_type (f, arg, oldval)
1191 FRAME_PTR f;
1192 Lisp_Object arg, oldval;
1194 set_frame_cursor_types (f, arg);
1196 /* Make sure the cursor gets redrawn. */
1197 cursor_type_changed = 1;
1200 void
1201 x_set_icon_type (f, arg, oldval)
1202 struct frame *f;
1203 Lisp_Object arg, oldval;
1205 int result;
1207 if (STRINGP (arg))
1209 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1210 return;
1212 else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
1213 return;
1215 BLOCK_INPUT;
1216 if (NILP (arg))
1217 result = x_text_icon (f,
1218 (char *) SDATA ((!NILP (f->icon_name)
1219 ? f->icon_name
1220 : f->name)));
1221 else
1222 result = x_bitmap_icon (f, arg);
1224 if (result)
1226 UNBLOCK_INPUT;
1227 error ("No icon window available");
1230 XFlush (FRAME_X_DISPLAY (f));
1231 UNBLOCK_INPUT;
1234 void
1235 x_set_icon_name (f, arg, oldval)
1236 struct frame *f;
1237 Lisp_Object arg, oldval;
1239 int result;
1241 if (STRINGP (arg))
1243 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1244 return;
1246 else if (!NILP (arg) || NILP (oldval))
1247 return;
1249 f->icon_name = arg;
1251 if (f->output_data.x->icon_bitmap != 0)
1252 return;
1254 BLOCK_INPUT;
1256 result = x_text_icon (f,
1257 (char *) SDATA ((!NILP (f->icon_name)
1258 ? f->icon_name
1259 : !NILP (f->title)
1260 ? f->title
1261 : f->name)));
1263 if (result)
1265 UNBLOCK_INPUT;
1266 error ("No icon window available");
1269 XFlush (FRAME_X_DISPLAY (f));
1270 UNBLOCK_INPUT;
1274 void
1275 x_set_menu_bar_lines (f, value, oldval)
1276 struct frame *f;
1277 Lisp_Object value, oldval;
1279 int nlines;
1280 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
1281 int olines = FRAME_MENU_BAR_LINES (f);
1282 #endif
1284 /* Right now, menu bars don't work properly in minibuf-only frames;
1285 most of the commands try to apply themselves to the minibuffer
1286 frame itself, and get an error because you can't switch buffers
1287 in or split the minibuffer window. */
1288 if (FRAME_MINIBUF_ONLY_P (f))
1289 return;
1291 if (INTEGERP (value))
1292 nlines = XINT (value);
1293 else
1294 nlines = 0;
1296 /* Make sure we redisplay all windows in this frame. */
1297 windows_or_buffers_changed++;
1299 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1300 FRAME_MENU_BAR_LINES (f) = 0;
1301 if (nlines)
1303 FRAME_EXTERNAL_MENU_BAR (f) = 1;
1304 if (FRAME_X_P (f) && f->output_data.x->menubar_widget == 0)
1305 /* Make sure next redisplay shows the menu bar. */
1306 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
1308 else
1310 if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
1311 free_frame_menubar (f);
1312 FRAME_EXTERNAL_MENU_BAR (f) = 0;
1313 if (FRAME_X_P (f))
1314 f->output_data.x->menubar_widget = 0;
1316 #else /* not USE_X_TOOLKIT && not USE_GTK */
1317 FRAME_MENU_BAR_LINES (f) = nlines;
1318 change_window_heights (f->root_window, nlines - olines);
1320 /* If the menu bar height gets changed, the internal border below
1321 the top margin has to be cleared. Also, if the menu bar gets
1322 larger, the area for the added lines has to be cleared except for
1323 the first menu bar line that is to be drawn later. */
1324 if (nlines != olines)
1326 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1327 int width = FRAME_PIXEL_WIDTH (f);
1328 int y;
1330 /* height can be zero here. */
1331 if (height > 0 && width > 0)
1333 y = FRAME_TOP_MARGIN_HEIGHT (f);
1335 BLOCK_INPUT;
1336 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1337 0, y, width, height, False);
1338 UNBLOCK_INPUT;
1341 if (nlines > 1 && nlines > olines)
1343 y = (olines == 0 ? 1 : olines) * FRAME_LINE_HEIGHT (f);
1344 height = nlines * FRAME_LINE_HEIGHT (f) - y;
1346 BLOCK_INPUT;
1347 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1348 0, y, width, height, False);
1349 UNBLOCK_INPUT;
1352 if (nlines == 0 && WINDOWP (f->menu_bar_window))
1353 clear_glyph_matrix (XWINDOW (f->menu_bar_window)->current_matrix);
1355 #endif /* not USE_X_TOOLKIT && not USE_GTK */
1356 adjust_glyphs (f);
1360 /* Set the number of lines used for the tool bar of frame F to VALUE.
1361 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1362 is the old number of tool bar lines. This function changes the
1363 height of all windows on frame F to match the new tool bar height.
1364 The frame's height doesn't change. */
1366 void
1367 x_set_tool_bar_lines (f, value, oldval)
1368 struct frame *f;
1369 Lisp_Object value, oldval;
1371 int delta, nlines, root_height;
1372 Lisp_Object root_window;
1374 /* Treat tool bars like menu bars. */
1375 if (FRAME_MINIBUF_ONLY_P (f))
1376 return;
1378 /* Use VALUE only if an integer >= 0. */
1379 if (INTEGERP (value) && XINT (value) >= 0)
1380 nlines = XFASTINT (value);
1381 else
1382 nlines = 0;
1384 #ifdef USE_GTK
1385 FRAME_TOOL_BAR_LINES (f) = 0;
1386 if (nlines)
1388 FRAME_EXTERNAL_TOOL_BAR (f) = 1;
1389 if (FRAME_X_P (f) && f->output_data.x->toolbar_widget == 0)
1390 /* Make sure next redisplay shows the tool bar. */
1391 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
1392 update_frame_tool_bar (f);
1394 else
1396 if (FRAME_EXTERNAL_TOOL_BAR (f))
1397 free_frame_tool_bar (f);
1398 FRAME_EXTERNAL_TOOL_BAR (f) = 0;
1401 return;
1402 #endif
1404 /* Make sure we redisplay all windows in this frame. */
1405 ++windows_or_buffers_changed;
1407 delta = nlines - FRAME_TOOL_BAR_LINES (f);
1409 /* Don't resize the tool-bar to more than we have room for. */
1410 root_window = FRAME_ROOT_WINDOW (f);
1411 root_height = WINDOW_TOTAL_LINES (XWINDOW (root_window));
1412 if (root_height - delta < 1)
1414 delta = root_height - 1;
1415 nlines = FRAME_TOOL_BAR_LINES (f) + delta;
1418 FRAME_TOOL_BAR_LINES (f) = nlines;
1419 change_window_heights (root_window, delta);
1420 adjust_glyphs (f);
1422 /* We also have to make sure that the internal border at the top of
1423 the frame, below the menu bar or tool bar, is redrawn when the
1424 tool bar disappears. This is so because the internal border is
1425 below the tool bar if one is displayed, but is below the menu bar
1426 if there isn't a tool bar. The tool bar draws into the area
1427 below the menu bar. */
1428 if (FRAME_X_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0)
1430 clear_frame (f);
1431 clear_current_matrices (f);
1434 /* If the tool bar gets smaller, the internal border below it
1435 has to be cleared. It was formerly part of the display
1436 of the larger tool bar, and updating windows won't clear it. */
1437 if (delta < 0)
1439 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1440 int width = FRAME_PIXEL_WIDTH (f);
1441 int y = (FRAME_MENU_BAR_LINES (f) + nlines) * FRAME_LINE_HEIGHT (f);
1443 /* height can be zero here. */
1444 if (height > 0 && width > 0)
1446 BLOCK_INPUT;
1447 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1448 0, y, width, height, False);
1449 UNBLOCK_INPUT;
1452 if (WINDOWP (f->tool_bar_window))
1453 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1458 /* Set the foreground color for scroll bars on frame F to VALUE.
1459 VALUE should be a string, a color name. If it isn't a string or
1460 isn't a valid color name, do nothing. OLDVAL is the old value of
1461 the frame parameter. */
1463 void
1464 x_set_scroll_bar_foreground (f, value, oldval)
1465 struct frame *f;
1466 Lisp_Object value, oldval;
1468 unsigned long pixel;
1470 if (STRINGP (value))
1471 pixel = x_decode_color (f, value, BLACK_PIX_DEFAULT (f));
1472 else
1473 pixel = -1;
1475 if (f->output_data.x->scroll_bar_foreground_pixel != -1)
1476 unload_color (f, f->output_data.x->scroll_bar_foreground_pixel);
1478 f->output_data.x->scroll_bar_foreground_pixel = pixel;
1479 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1481 /* Remove all scroll bars because they have wrong colors. */
1482 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1483 (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1484 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1485 (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1487 update_face_from_frame_parameter (f, Qscroll_bar_foreground, value);
1488 redraw_frame (f);
1493 /* Set the background color for scroll bars on frame F to VALUE VALUE
1494 should be a string, a color name. If it isn't a string or isn't a
1495 valid color name, do nothing. OLDVAL is the old value of the frame
1496 parameter. */
1498 void
1499 x_set_scroll_bar_background (f, value, oldval)
1500 struct frame *f;
1501 Lisp_Object value, oldval;
1503 unsigned long pixel;
1505 if (STRINGP (value))
1506 pixel = x_decode_color (f, value, WHITE_PIX_DEFAULT (f));
1507 else
1508 pixel = -1;
1510 if (f->output_data.x->scroll_bar_background_pixel != -1)
1511 unload_color (f, f->output_data.x->scroll_bar_background_pixel);
1513 #ifdef USE_TOOLKIT_SCROLL_BARS
1514 /* Scrollbar shadow colors. */
1515 if (f->output_data.x->scroll_bar_top_shadow_pixel != -1)
1517 unload_color (f, f->output_data.x->scroll_bar_top_shadow_pixel);
1518 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
1520 if (f->output_data.x->scroll_bar_bottom_shadow_pixel != -1)
1522 unload_color (f, f->output_data.x->scroll_bar_bottom_shadow_pixel);
1523 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
1525 #endif /* USE_TOOLKIT_SCROLL_BARS */
1527 f->output_data.x->scroll_bar_background_pixel = pixel;
1528 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1530 /* Remove all scroll bars because they have wrong colors. */
1531 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1532 (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1533 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1534 (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1536 update_face_from_frame_parameter (f, Qscroll_bar_background, value);
1537 redraw_frame (f);
1542 /* Encode Lisp string STRING as a text in a format appropriate for
1543 XICCC (X Inter Client Communication Conventions).
1545 This can call Lisp code, so callers must GCPRO.
1547 If STRING contains only ASCII characters, do no conversion and
1548 return the string data of STRING. Otherwise, encode the text by
1549 CODING_SYSTEM, and return a newly allocated memory area which
1550 should be freed by `xfree' by a caller.
1552 SELECTIONP non-zero means the string is being encoded for an X
1553 selection, so it is safe to run pre-write conversions (which
1554 may run Lisp code).
1556 Store the byte length of resulting text in *TEXT_BYTES.
1558 If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
1559 which means that the `encoding' of the result can be `STRING'.
1560 Otherwise store 0 in *STRINGP, which means that the `encoding' of
1561 the result should be `COMPOUND_TEXT'. */
1563 static unsigned char *
1564 x_encode_text (string, coding_system, selectionp, text_bytes, stringp, freep)
1565 Lisp_Object string, coding_system;
1566 int *text_bytes, *stringp;
1567 int selectionp;
1568 int *freep;
1570 int result = string_xstring_p (string);
1571 struct coding_system coding;
1573 if (result == 0)
1575 /* No multibyte character in OBJ. We need not encode it. */
1576 *text_bytes = SBYTES (string);
1577 *stringp = 1;
1578 *freep = 0;
1579 return SDATA (string);
1582 setup_coding_system (coding_system, &coding);
1583 coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK);
1584 /* We suppress producing escape sequences for composition. */
1585 coding.common_flags &= ~CODING_ANNOTATION_MASK;
1586 coding.dst_bytes = SCHARS (string) * 2;
1587 coding.destination = (unsigned char *) xmalloc (coding.dst_bytes);
1588 encode_coding_object (&coding, string, 0, 0,
1589 SCHARS (string), SBYTES (string), Qnil);
1590 *text_bytes = coding.produced;
1591 *stringp = (result == 1 || !EQ (coding_system, Qcompound_text));
1592 *freep = 1;
1593 return coding.destination;
1597 /* Set the WM name to NAME for frame F. Also set the icon name.
1598 If the frame already has an icon name, use that, otherwise set the
1599 icon name to NAME. */
1601 static void
1602 x_set_name_internal (f, name)
1603 FRAME_PTR f;
1604 Lisp_Object name;
1606 if (FRAME_X_WINDOW (f))
1608 BLOCK_INPUT;
1610 XTextProperty text, icon;
1611 int bytes, stringp;
1612 int do_free_icon_value = 0, do_free_text_value = 0;
1613 Lisp_Object coding_system;
1614 #ifdef USE_GTK
1615 Lisp_Object encoded_name;
1616 struct gcpro gcpro1;
1618 /* As ENCODE_UTF_8 may cause GC and relocation of string data,
1619 we use it before x_encode_text that may return string data. */
1620 GCPRO1 (name);
1621 encoded_name = ENCODE_UTF_8 (name);
1622 UNGCPRO;
1623 #endif
1625 coding_system = Qcompound_text;
1626 /* Note: Encoding strategy
1628 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1629 text.encoding. But, there are non-internationalized window
1630 managers which don't support that encoding. So, if NAME
1631 contains only ASCII and 8859-1 characters, encode it by
1632 iso-latin-1, and use "STRING" in text.encoding hoping that
1633 such window managers at least analyze this format correctly,
1634 i.e. treat 8-bit bytes as 8859-1 characters.
1636 We may also be able to use "UTF8_STRING" in text.encoding
1637 in the future which can encode all Unicode characters.
1638 But, for the moment, there's no way to know that the
1639 current window manager supports it or not. */
1640 text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp,
1641 &do_free_text_value);
1642 text.encoding = (stringp ? XA_STRING
1643 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1644 text.format = 8;
1645 text.nitems = bytes;
1647 if (!STRINGP (f->icon_name))
1649 icon = text;
1651 else
1653 /* See the above comment "Note: Encoding strategy". */
1654 icon.value = x_encode_text (f->icon_name, coding_system, 0,
1655 &bytes, &stringp, &do_free_icon_value);
1656 icon.encoding = (stringp ? XA_STRING
1657 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1658 icon.format = 8;
1659 icon.nitems = bytes;
1662 #ifdef USE_GTK
1663 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
1664 (char *) SDATA (encoded_name));
1665 #else /* not USE_GTK */
1666 XSetWMName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &text);
1667 #endif /* not USE_GTK */
1669 XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &icon);
1671 if (do_free_icon_value)
1672 xfree (icon.value);
1673 if (do_free_text_value)
1674 xfree (text.value);
1676 UNBLOCK_INPUT;
1680 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1681 x_id_name.
1683 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1684 name; if NAME is a string, set F's name to NAME and set
1685 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1687 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1688 suggesting a new name, which lisp code should override; if
1689 F->explicit_name is set, ignore the new name; otherwise, set it. */
1691 void
1692 x_set_name (f, name, explicit)
1693 struct frame *f;
1694 Lisp_Object name;
1695 int explicit;
1697 /* Make sure that requests from lisp code override requests from
1698 Emacs redisplay code. */
1699 if (explicit)
1701 /* If we're switching from explicit to implicit, we had better
1702 update the mode lines and thereby update the title. */
1703 if (f->explicit_name && NILP (name))
1704 update_mode_lines = 1;
1706 f->explicit_name = ! NILP (name);
1708 else if (f->explicit_name)
1709 return;
1711 /* If NAME is nil, set the name to the x_id_name. */
1712 if (NILP (name))
1714 /* Check for no change needed in this very common case
1715 before we do any consing. */
1716 if (!strcmp (FRAME_X_DISPLAY_INFO (f)->x_id_name,
1717 SDATA (f->name)))
1718 return;
1719 name = build_string (FRAME_X_DISPLAY_INFO (f)->x_id_name);
1721 else
1722 CHECK_STRING (name);
1724 /* Don't change the name if it's already NAME. */
1725 if (! NILP (Fstring_equal (name, f->name)))
1726 return;
1728 f->name = name;
1730 /* For setting the frame title, the title parameter should override
1731 the name parameter. */
1732 if (! NILP (f->title))
1733 name = f->title;
1735 x_set_name_internal (f, name);
1738 /* This function should be called when the user's lisp code has
1739 specified a name for the frame; the name will override any set by the
1740 redisplay code. */
1741 void
1742 x_explicitly_set_name (f, arg, oldval)
1743 FRAME_PTR f;
1744 Lisp_Object arg, oldval;
1746 x_set_name (f, arg, 1);
1749 /* This function should be called by Emacs redisplay code to set the
1750 name; names set this way will never override names set by the user's
1751 lisp code. */
1752 void
1753 x_implicitly_set_name (f, arg, oldval)
1754 FRAME_PTR f;
1755 Lisp_Object arg, oldval;
1757 x_set_name (f, arg, 0);
1760 /* Change the title of frame F to NAME.
1761 If NAME is nil, use the frame name as the title. */
1763 void
1764 x_set_title (f, name, old_name)
1765 struct frame *f;
1766 Lisp_Object name, old_name;
1768 /* Don't change the title if it's already NAME. */
1769 if (EQ (name, f->title))
1770 return;
1772 update_mode_lines = 1;
1774 f->title = name;
1776 if (NILP (name))
1777 name = f->name;
1778 else
1779 CHECK_STRING (name);
1781 x_set_name_internal (f, name);
1784 void
1785 x_set_scroll_bar_default_width (f)
1786 struct frame *f;
1788 int wid = FRAME_COLUMN_WIDTH (f);
1790 #ifdef USE_TOOLKIT_SCROLL_BARS
1791 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
1792 int width = 16 + 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM;
1793 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (width + wid - 1) / wid;
1794 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = width;
1795 #else
1796 /* Make the actual width at least 14 pixels and a multiple of a
1797 character width. */
1798 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
1800 /* Use all of that space (aside from required margins) for the
1801 scroll bar. */
1802 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 0;
1803 #endif
1807 /* Record in frame F the specified or default value according to ALIST
1808 of the parameter named PROP (a Lisp symbol). If no value is
1809 specified for PROP, look for an X default for XPROP on the frame
1810 named NAME. If that is not found either, use the value DEFLT. */
1812 static Lisp_Object
1813 x_default_scroll_bar_color_parameter (f, alist, prop, xprop, xclass,
1814 foreground_p)
1815 struct frame *f;
1816 Lisp_Object alist;
1817 Lisp_Object prop;
1818 char *xprop;
1819 char *xclass;
1820 int foreground_p;
1822 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
1823 Lisp_Object tem;
1825 tem = x_get_arg (dpyinfo, alist, prop, xprop, xclass, RES_TYPE_STRING);
1826 if (EQ (tem, Qunbound))
1828 #ifdef USE_TOOLKIT_SCROLL_BARS
1830 /* See if an X resource for the scroll bar color has been
1831 specified. */
1832 tem = display_x_get_resource (dpyinfo,
1833 build_string (foreground_p
1834 ? "foreground"
1835 : "background"),
1836 empty_unibyte_string,
1837 build_string ("verticalScrollBar"),
1838 empty_unibyte_string);
1839 if (!STRINGP (tem))
1841 /* If nothing has been specified, scroll bars will use a
1842 toolkit-dependent default. Because these defaults are
1843 difficult to get at without actually creating a scroll
1844 bar, use nil to indicate that no color has been
1845 specified. */
1846 tem = Qnil;
1849 #else /* not USE_TOOLKIT_SCROLL_BARS */
1851 tem = Qnil;
1853 #endif /* not USE_TOOLKIT_SCROLL_BARS */
1856 x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));
1857 return tem;
1863 #ifdef USE_X_TOOLKIT
1865 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
1866 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
1867 already be present because of the toolkit (Motif adds some of them,
1868 for example, but Xt doesn't). */
1870 static void
1871 hack_wm_protocols (f, widget)
1872 FRAME_PTR f;
1873 Widget widget;
1875 Display *dpy = XtDisplay (widget);
1876 Window w = XtWindow (widget);
1877 int need_delete = 1;
1878 int need_focus = 1;
1879 int need_save = 1;
1881 BLOCK_INPUT;
1883 Atom type;
1884 unsigned char *catoms;
1885 int format = 0;
1886 unsigned long nitems = 0;
1887 unsigned long bytes_after;
1889 if ((XGetWindowProperty (dpy, w,
1890 FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
1891 (long)0, (long)100, False, XA_ATOM,
1892 &type, &format, &nitems, &bytes_after,
1893 &catoms)
1894 == Success)
1895 && format == 32 && type == XA_ATOM)
1897 Atom *atoms = (Atom *) catoms;
1898 while (nitems > 0)
1900 nitems--;
1901 if (atoms[nitems]
1902 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window)
1903 need_delete = 0;
1904 else if (atoms[nitems]
1905 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus)
1906 need_focus = 0;
1907 else if (atoms[nitems]
1908 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself)
1909 need_save = 0;
1912 if (catoms)
1913 XFree (catoms);
1916 Atom props [10];
1917 int count = 0;
1918 if (need_delete)
1919 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window;
1920 if (need_focus)
1921 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus;
1922 if (need_save)
1923 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
1924 if (count)
1925 XChangeProperty (dpy, w, FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
1926 XA_ATOM, 32, PropModeAppend,
1927 (unsigned char *) props, count);
1929 UNBLOCK_INPUT;
1931 #endif
1935 /* Support routines for XIC (X Input Context). */
1937 #ifdef HAVE_X_I18N
1939 static XFontSet xic_create_xfontset P_ ((struct frame *));
1940 static XIMStyle best_xim_style P_ ((XIMStyles *, XIMStyles *));
1943 /* Supported XIM styles, ordered by preference. */
1945 static XIMStyle supported_xim_styles[] =
1947 XIMPreeditPosition | XIMStatusArea,
1948 XIMPreeditPosition | XIMStatusNothing,
1949 XIMPreeditPosition | XIMStatusNone,
1950 XIMPreeditNothing | XIMStatusArea,
1951 XIMPreeditNothing | XIMStatusNothing,
1952 XIMPreeditNothing | XIMStatusNone,
1953 XIMPreeditNone | XIMStatusArea,
1954 XIMPreeditNone | XIMStatusNothing,
1955 XIMPreeditNone | XIMStatusNone,
1960 /* Create an X fontset on frame F with base font name BASE_FONTNAME. */
1962 char xic_defaut_fontset[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
1964 /* Create an Xt fontset spec from the name of a base font.
1965 If `motif' is True use the Motif syntax. */
1966 char *
1967 xic_create_fontsetname (base_fontname, motif)
1968 char *base_fontname;
1969 Bool motif;
1971 const char *sep = motif ? ";" : ",";
1972 char *fontsetname;
1974 /* Make a fontset name from the base font name. */
1975 if (xic_defaut_fontset == base_fontname)
1976 { /* There is no base font name, use the default. */
1977 int len = strlen (base_fontname) + 2;
1978 fontsetname = xmalloc (len);
1979 bzero (fontsetname, len);
1980 strcpy (fontsetname, base_fontname);
1982 else
1984 /* Make a fontset name from the base font name.
1985 The font set will be made of the following elements:
1986 - the base font.
1987 - the base font where the charset spec is replaced by -*-*.
1988 - the same but with the family also replaced with -*-*-. */
1989 char *p = base_fontname;
1990 int i;
1992 for (i = 0; *p; p++)
1993 if (*p == '-') i++;
1994 if (i != 14)
1995 { /* As the font name doesn't conform to XLFD, we can't
1996 modify it to generalize it to allcs and allfamilies.
1997 Use the specified font plus the default. */
1998 int len = strlen (base_fontname) + strlen (xic_defaut_fontset) + 3;
1999 fontsetname = xmalloc (len);
2000 bzero (fontsetname, len);
2001 strcpy (fontsetname, base_fontname);
2002 strcat (fontsetname, sep);
2003 strcat (fontsetname, xic_defaut_fontset);
2005 else
2007 int len;
2008 char *p1 = NULL, *p2 = NULL, *p3 = NULL;
2009 char *font_allcs = NULL;
2010 char *font_allfamilies = NULL;
2011 char *font_all = NULL;
2012 char *allcs = "*-*-*-*-*-*-*";
2013 char *allfamilies = "-*-*-";
2014 char *all = "*-*-*-*-";
2015 char *base;
2017 for (i = 0, p = base_fontname; i < 8; p++)
2019 if (*p == '-')
2021 i++;
2022 if (i == 3)
2023 p1 = p + 1;
2024 else if (i == 7)
2025 p2 = p + 1;
2026 else if (i == 6)
2027 p3 = p + 1;
2030 /* If base_fontname specifies ADSTYLE, make it a
2031 wildcard. */
2032 if (*p3 != '*')
2034 int diff = (p2 - p3) - 2;
2036 base = alloca (strlen (base_fontname) + 1);
2037 bcopy (base_fontname, base, p3 - base_fontname);
2038 base[p3 - base_fontname] = '*';
2039 base[(p3 - base_fontname) + 1] = '-';
2040 strcpy (base + (p3 - base_fontname) + 2, p2);
2041 p = base + (p - base_fontname) - diff;
2042 p1 = base + (p1 - base_fontname);
2043 p2 = base + (p2 - base_fontname) - diff;
2044 base_fontname = base;
2047 /* Build the font spec that matches all charsets. */
2048 len = p - base_fontname + strlen (allcs) + 1;
2049 font_allcs = (char *) alloca (len);
2050 bzero (font_allcs, len);
2051 bcopy (base_fontname, font_allcs, p - base_fontname);
2052 strcat (font_allcs, allcs);
2054 /* Build the font spec that matches all families and
2055 add-styles. */
2056 len = p - p1 + strlen (allcs) + strlen (allfamilies) + 1;
2057 font_allfamilies = (char *) alloca (len);
2058 bzero (font_allfamilies, len);
2059 strcpy (font_allfamilies, allfamilies);
2060 bcopy (p1, font_allfamilies + strlen (allfamilies), p - p1);
2061 strcat (font_allfamilies, allcs);
2063 /* Build the font spec that matches all. */
2064 len = p - p2 + strlen (allcs) + strlen (all) + strlen (allfamilies) + 1;
2065 font_all = (char *) alloca (len);
2066 bzero (font_all, len);
2067 strcpy (font_all, allfamilies);
2068 strcat (font_all, all);
2069 bcopy (p2, font_all + strlen (all) + strlen (allfamilies), p - p2);
2070 strcat (font_all, allcs);
2072 /* Build the actual font set name. */
2073 len = strlen (base_fontname) + strlen (font_allcs)
2074 + strlen (font_allfamilies) + strlen (font_all) + 5;
2075 fontsetname = xmalloc (len);
2076 bzero (fontsetname, len);
2077 strcpy (fontsetname, base_fontname);
2078 strcat (fontsetname, sep);
2079 strcat (fontsetname, font_allcs);
2080 strcat (fontsetname, sep);
2081 strcat (fontsetname, font_allfamilies);
2082 strcat (fontsetname, sep);
2083 strcat (fontsetname, font_all);
2086 if (motif)
2087 strcat (fontsetname, ":");
2088 return fontsetname;
2091 #ifdef DEBUG_XIC_FONTSET
2092 static void
2093 print_fontset_result (xfs, name, missing_list, missing_count)
2094 XFontSet xfs;
2095 char *name;
2096 char **missing_list;
2097 int missing_count;
2099 if (xfs)
2100 fprintf (stderr, "XIC Fontset created: %s\n", name);
2101 else
2103 fprintf (stderr, "XIC Fontset failed: %s\n", name);
2104 while (missing_count-- > 0)
2106 fprintf (stderr, " missing: %s\n", *missing_list);
2107 missing_list++;
2112 #endif
2114 static XFontSet
2115 xic_create_xfontset (f)
2116 struct frame *f;
2118 XFontSet xfs = NULL;
2119 struct font *font = FRAME_FONT (f);
2120 int pixel_size = font->pixel_size;
2121 Lisp_Object rest, frame;
2123 /* See if there is another frame already using same fontset. */
2124 FOR_EACH_FRAME (rest, frame)
2126 struct frame *cf = XFRAME (frame);
2128 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
2129 && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f)
2130 && FRAME_FONT (f)
2131 && FRAME_FONT (f)->pixel_size == pixel_size)
2133 xfs = FRAME_XIC_FONTSET (cf);
2134 break;
2138 if (! xfs)
2140 char buf[256];
2141 char **missing_list;
2142 int missing_count;
2143 char *def_string;
2144 char *xlfd_format = "-*-*-medium-r-normal--%d-*-*-*-*-*";
2146 sprintf (buf, xlfd_format, pixel_size);
2147 missing_list = NULL;
2148 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
2149 &missing_list, &missing_count, &def_string);
2150 #ifdef DEBUG_XIC_FONTSET
2151 print_fontset_result (xfs, buf, missing_list, missing_count);
2152 #endif
2153 if (missing_list)
2154 XFreeStringList (missing_list);
2155 if (! xfs)
2157 /* List of pixel sizes most likely available. Find one that
2158 is closest to pixel_size. */
2159 int sizes[] = {0, 8, 10, 11, 12, 14, 17, 18, 20, 24, 26, 34, 0};
2160 int *smaller, *larger;
2162 for (smaller = sizes; smaller[1]; smaller++)
2163 if (smaller[1] >= pixel_size)
2164 break;
2165 larger = smaller + 1;
2166 if (*larger == pixel_size)
2167 larger++;
2168 while (*smaller || *larger)
2170 int this_size;
2172 if (! *larger)
2173 this_size = *smaller--;
2174 else if (! *smaller)
2175 this_size = *larger++;
2176 else if (pixel_size - *smaller < *larger - pixel_size)
2177 this_size = *smaller--;
2178 else
2179 this_size = *larger++;
2180 sprintf (buf, xlfd_format, this_size);
2181 missing_list = NULL;
2182 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
2183 &missing_list, &missing_count, &def_string);
2184 #ifdef DEBUG_XIC_FONTSET
2185 print_fontset_result (xfs, buf, missing_list, missing_count);
2186 #endif
2187 if (missing_list)
2188 XFreeStringList (missing_list);
2189 if (xfs)
2190 break;
2193 if (! xfs)
2195 char *last_resort = "-*-*-*-r-normal--*-*-*-*-*-*";
2197 missing_list = NULL;
2198 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), last_resort,
2199 &missing_list, &missing_count, &def_string);
2200 #ifdef DEBUG_XIC_FONTSET
2201 print_fontset_result (xfs, last_resort, missing_list, missing_count);
2202 #endif
2203 if (missing_list)
2204 XFreeStringList (missing_list);
2209 return xfs;
2212 /* Free the X fontset of frame F if it is the last frame using it. */
2214 void
2215 xic_free_xfontset (f)
2216 struct frame *f;
2218 Lisp_Object rest, frame;
2219 int shared_p = 0;
2221 if (!FRAME_XIC_FONTSET (f))
2222 return;
2224 /* See if there is another frame sharing the same fontset. */
2225 FOR_EACH_FRAME (rest, frame)
2227 struct frame *cf = XFRAME (frame);
2228 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
2229 && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f)
2230 && FRAME_XIC_FONTSET (cf) == FRAME_XIC_FONTSET (f))
2232 shared_p = 1;
2233 break;
2237 if (!shared_p)
2238 /* The fontset is not used anymore. It is safe to free it. */
2239 XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f));
2241 if (FRAME_XIC_BASE_FONTNAME (f))
2242 xfree (FRAME_XIC_BASE_FONTNAME (f));
2243 FRAME_XIC_BASE_FONTNAME (f) = NULL;
2244 FRAME_XIC_FONTSET (f) = NULL;
2248 /* Value is the best input style, given user preferences USER (already
2249 checked to be supported by Emacs), and styles supported by the
2250 input method XIM. */
2252 static XIMStyle
2253 best_xim_style (user, xim)
2254 XIMStyles *user;
2255 XIMStyles *xim;
2257 int i, j;
2259 for (i = 0; i < user->count_styles; ++i)
2260 for (j = 0; j < xim->count_styles; ++j)
2261 if (user->supported_styles[i] == xim->supported_styles[j])
2262 return user->supported_styles[i];
2264 /* Return the default style. */
2265 return XIMPreeditNothing | XIMStatusNothing;
2268 /* Create XIC for frame F. */
2270 static XIMStyle xic_style;
2272 void
2273 create_frame_xic (f)
2274 struct frame *f;
2276 XIM xim;
2277 XIC xic = NULL;
2278 XFontSet xfs = NULL;
2280 if (FRAME_XIC (f))
2281 return;
2283 /* Create X fontset. */
2284 xfs = xic_create_xfontset (f);
2285 xim = FRAME_X_XIM (f);
2286 if (xim)
2288 XRectangle s_area;
2289 XPoint spot;
2290 XVaNestedList preedit_attr;
2291 XVaNestedList status_attr;
2293 s_area.x = 0; s_area.y = 0; s_area.width = 1; s_area.height = 1;
2294 spot.x = 0; spot.y = 1;
2296 /* Determine XIC style. */
2297 if (xic_style == 0)
2299 XIMStyles supported_list;
2300 supported_list.count_styles = (sizeof supported_xim_styles
2301 / sizeof supported_xim_styles[0]);
2302 supported_list.supported_styles = supported_xim_styles;
2303 xic_style = best_xim_style (&supported_list,
2304 FRAME_X_XIM_STYLES (f));
2307 preedit_attr = XVaCreateNestedList (0,
2308 XNFontSet, xfs,
2309 XNForeground,
2310 FRAME_FOREGROUND_PIXEL (f),
2311 XNBackground,
2312 FRAME_BACKGROUND_PIXEL (f),
2313 (xic_style & XIMPreeditPosition
2314 ? XNSpotLocation
2315 : NULL),
2316 &spot,
2317 NULL);
2318 status_attr = XVaCreateNestedList (0,
2319 XNArea,
2320 &s_area,
2321 XNFontSet,
2322 xfs,
2323 XNForeground,
2324 FRAME_FOREGROUND_PIXEL (f),
2325 XNBackground,
2326 FRAME_BACKGROUND_PIXEL (f),
2327 NULL);
2329 xic = XCreateIC (xim,
2330 XNInputStyle, xic_style,
2331 XNClientWindow, FRAME_X_WINDOW (f),
2332 XNFocusWindow, FRAME_X_WINDOW (f),
2333 XNStatusAttributes, status_attr,
2334 XNPreeditAttributes, preedit_attr,
2335 NULL);
2336 XFree (preedit_attr);
2337 XFree (status_attr);
2340 FRAME_XIC (f) = xic;
2341 FRAME_XIC_STYLE (f) = xic_style;
2342 FRAME_XIC_FONTSET (f) = xfs;
2346 /* Destroy XIC and free XIC fontset of frame F, if any. */
2348 void
2349 free_frame_xic (f)
2350 struct frame *f;
2352 if (FRAME_XIC (f) == NULL)
2353 return;
2355 XDestroyIC (FRAME_XIC (f));
2356 xic_free_xfontset (f);
2358 FRAME_XIC (f) = NULL;
2362 /* Place preedit area for XIC of window W's frame to specified
2363 pixel position X/Y. X and Y are relative to window W. */
2365 void
2366 xic_set_preeditarea (w, x, y)
2367 struct window *w;
2368 int x, y;
2370 struct frame *f = XFRAME (w->frame);
2371 XVaNestedList attr;
2372 XPoint spot;
2374 spot.x = WINDOW_TO_FRAME_PIXEL_X (w, x) + WINDOW_LEFT_FRINGE_WIDTH (w);
2375 spot.y = WINDOW_TO_FRAME_PIXEL_Y (w, y) + FONT_BASE (FRAME_FONT (f));
2376 attr = XVaCreateNestedList (0, XNSpotLocation, &spot, NULL);
2377 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2378 XFree (attr);
2382 /* Place status area for XIC in bottom right corner of frame F.. */
2384 void
2385 xic_set_statusarea (f)
2386 struct frame *f;
2388 XIC xic = FRAME_XIC (f);
2389 XVaNestedList attr;
2390 XRectangle area;
2391 XRectangle *needed;
2393 /* Negotiate geometry of status area. If input method has existing
2394 status area, use its current size. */
2395 area.x = area.y = area.width = area.height = 0;
2396 attr = XVaCreateNestedList (0, XNAreaNeeded, &area, NULL);
2397 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2398 XFree (attr);
2400 attr = XVaCreateNestedList (0, XNAreaNeeded, &needed, NULL);
2401 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2402 XFree (attr);
2404 if (needed->width == 0) /* Use XNArea instead of XNAreaNeeded */
2406 attr = XVaCreateNestedList (0, XNArea, &needed, NULL);
2407 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2408 XFree (attr);
2411 area.width = needed->width;
2412 area.height = needed->height;
2413 area.x = FRAME_PIXEL_WIDTH (f) - area.width - FRAME_INTERNAL_BORDER_WIDTH (f);
2414 area.y = (FRAME_PIXEL_HEIGHT (f) - area.height
2415 - FRAME_MENUBAR_HEIGHT (f)
2416 - FRAME_TOOLBAR_HEIGHT (f)
2417 - FRAME_INTERNAL_BORDER_WIDTH (f));
2418 XFree (needed);
2420 attr = XVaCreateNestedList (0, XNArea, &area, NULL);
2421 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2422 XFree (attr);
2426 /* Set X fontset for XIC of frame F, using base font name
2427 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2429 void
2430 xic_set_xfontset (f, base_fontname)
2431 struct frame *f;
2432 char *base_fontname;
2434 XVaNestedList attr;
2435 XFontSet xfs;
2437 xic_free_xfontset (f);
2439 xfs = xic_create_xfontset (f);
2441 attr = XVaCreateNestedList (0, XNFontSet, xfs, NULL);
2442 if (FRAME_XIC_STYLE (f) & XIMPreeditPosition)
2443 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2444 if (FRAME_XIC_STYLE (f) & XIMStatusArea)
2445 XSetICValues (FRAME_XIC (f), XNStatusAttributes, attr, NULL);
2446 XFree (attr);
2448 FRAME_XIC_FONTSET (f) = xfs;
2451 #endif /* HAVE_X_I18N */
2455 #ifdef USE_X_TOOLKIT
2457 /* Create and set up the X widget for frame F. */
2459 static void
2460 x_window (f, window_prompting, minibuffer_only)
2461 struct frame *f;
2462 long window_prompting;
2463 int minibuffer_only;
2465 XClassHint class_hints;
2466 XSetWindowAttributes attributes;
2467 unsigned long attribute_mask;
2468 Widget shell_widget;
2469 Widget pane_widget;
2470 Widget frame_widget;
2471 Arg al [25];
2472 int ac;
2474 BLOCK_INPUT;
2476 /* Use the resource name as the top-level widget name
2477 for looking up resources. Make a non-Lisp copy
2478 for the window manager, so GC relocation won't bother it.
2480 Elsewhere we specify the window name for the window manager. */
2483 char *str = (char *) SDATA (Vx_resource_name);
2484 f->namebuf = (char *) xmalloc (strlen (str) + 1);
2485 strcpy (f->namebuf, str);
2488 ac = 0;
2489 XtSetArg (al[ac], XtNallowShellResize, 1); ac++;
2490 XtSetArg (al[ac], XtNinput, 1); ac++;
2491 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2492 XtSetArg (al[ac], XtNborderWidth, f->border_width); ac++;
2493 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2494 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2495 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2496 shell_widget = XtAppCreateShell (f->namebuf, EMACS_CLASS,
2497 applicationShellWidgetClass,
2498 FRAME_X_DISPLAY (f), al, ac);
2500 f->output_data.x->widget = shell_widget;
2501 /* maybe_set_screen_title_format (shell_widget); */
2503 pane_widget = lw_create_widget ("main", "pane", widget_id_tick++,
2504 (widget_value *) NULL,
2505 shell_widget, False,
2506 (lw_callback) NULL,
2507 (lw_callback) NULL,
2508 (lw_callback) NULL,
2509 (lw_callback) NULL);
2511 ac = 0;
2512 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2513 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2514 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2515 XtSetValues (pane_widget, al, ac);
2516 f->output_data.x->column_widget = pane_widget;
2518 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2519 the emacs screen when changing menubar. This reduces flickering. */
2521 ac = 0;
2522 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2523 XtSetArg (al[ac], XtNshowGrip, 0); ac++;
2524 XtSetArg (al[ac], XtNallowResize, 1); ac++;
2525 XtSetArg (al[ac], XtNresizeToPreferred, 1); ac++;
2526 XtSetArg (al[ac], XtNemacsFrame, f); ac++;
2527 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2528 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2529 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2530 frame_widget = XtCreateWidget (f->namebuf, emacsFrameClass, pane_widget,
2531 al, ac);
2533 f->output_data.x->edit_widget = frame_widget;
2535 XtManageChild (frame_widget);
2537 /* Do some needed geometry management. */
2539 int len;
2540 char *tem, shell_position[32];
2541 Arg al[10];
2542 int ac = 0;
2543 int extra_borders = 0;
2544 int menubar_size
2545 = (f->output_data.x->menubar_widget
2546 ? (f->output_data.x->menubar_widget->core.height
2547 + f->output_data.x->menubar_widget->core.border_width)
2548 : 0);
2550 #if 0 /* Experimentally, we now get the right results
2551 for -geometry -0-0 without this. 24 Aug 96, rms. */
2552 if (FRAME_EXTERNAL_MENU_BAR (f))
2554 Dimension ibw = 0;
2555 XtVaGetValues (pane_widget, XtNinternalBorderWidth, &ibw, NULL);
2556 menubar_size += ibw;
2558 #endif
2560 f->output_data.x->menubar_height = menubar_size;
2562 #ifndef USE_LUCID
2563 /* Motif seems to need this amount added to the sizes
2564 specified for the shell widget. The Athena/Lucid widgets don't.
2565 Both conclusions reached experimentally. -- rms. */
2566 XtVaGetValues (f->output_data.x->edit_widget, XtNinternalBorderWidth,
2567 &extra_borders, NULL);
2568 extra_borders *= 2;
2569 #endif
2571 /* Convert our geometry parameters into a geometry string
2572 and specify it.
2573 Note that we do not specify here whether the position
2574 is a user-specified or program-specified one.
2575 We pass that information later, in x_wm_set_size_hints. */
2577 int left = f->left_pos;
2578 int xneg = window_prompting & XNegative;
2579 int top = f->top_pos;
2580 int yneg = window_prompting & YNegative;
2581 if (xneg)
2582 left = -left;
2583 if (yneg)
2584 top = -top;
2586 if (window_prompting & USPosition)
2587 sprintf (shell_position, "=%dx%d%c%d%c%d",
2588 FRAME_PIXEL_WIDTH (f) + extra_borders,
2589 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders,
2590 (xneg ? '-' : '+'), left,
2591 (yneg ? '-' : '+'), top);
2592 else
2594 sprintf (shell_position, "=%dx%d",
2595 FRAME_PIXEL_WIDTH (f) + extra_borders,
2596 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders);
2598 /* Setting x and y when the position is not specified in
2599 the geometry string will set program position in the WM hints.
2600 If Emacs had just one program position, we could set it in
2601 fallback resources, but since each make-frame call can specify
2602 different program positions, this is easier. */
2603 XtSetArg (al[ac], XtNx, left); ac++;
2604 XtSetArg (al[ac], XtNy, top); ac++;
2608 len = strlen (shell_position) + 1;
2609 /* We don't free this because we don't know whether
2610 it is safe to free it while the frame exists.
2611 It isn't worth the trouble of arranging to free it
2612 when the frame is deleted. */
2613 tem = (char *) xmalloc (len);
2614 strncpy (tem, shell_position, len);
2615 XtSetArg (al[ac], XtNgeometry, tem); ac++;
2616 XtSetValues (shell_widget, al, ac);
2619 XtManageChild (pane_widget);
2620 XtRealizeWidget (shell_widget);
2622 if (FRAME_X_EMBEDDED_P (f))
2623 XReparentWindow (FRAME_X_DISPLAY (f), XtWindow (shell_widget),
2624 f->output_data.x->parent_desc, 0, 0);
2626 FRAME_X_WINDOW (f) = XtWindow (frame_widget);
2628 validate_x_resource_name ();
2630 class_hints.res_name = (char *) SDATA (Vx_resource_name);
2631 class_hints.res_class = (char *) SDATA (Vx_resource_class);
2632 XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints);
2634 #ifdef HAVE_X_I18N
2635 FRAME_XIC (f) = NULL;
2636 if (use_xim)
2637 create_frame_xic (f);
2638 #endif
2640 f->output_data.x->wm_hints.input = True;
2641 f->output_data.x->wm_hints.flags |= InputHint;
2642 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2643 &f->output_data.x->wm_hints);
2645 hack_wm_protocols (f, shell_widget);
2647 #ifdef HACK_EDITRES
2648 XtAddEventHandler (shell_widget, 0, True, _XEditResCheckMessages, 0);
2649 #endif
2651 /* Do a stupid property change to force the server to generate a
2652 PropertyNotify event so that the event_stream server timestamp will
2653 be initialized to something relevant to the time we created the window.
2655 XChangeProperty (XtDisplay (frame_widget), XtWindow (frame_widget),
2656 FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
2657 XA_ATOM, 32, PropModeAppend,
2658 (unsigned char*) NULL, 0);
2660 /* Make all the standard events reach the Emacs frame. */
2661 attributes.event_mask = STANDARD_EVENT_SET;
2663 #ifdef HAVE_X_I18N
2664 if (FRAME_XIC (f))
2666 /* XIM server might require some X events. */
2667 unsigned long fevent = NoEventMask;
2668 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2669 attributes.event_mask |= fevent;
2671 #endif /* HAVE_X_I18N */
2673 attribute_mask = CWEventMask;
2674 XChangeWindowAttributes (XtDisplay (shell_widget), XtWindow (shell_widget),
2675 attribute_mask, &attributes);
2677 XtMapWidget (frame_widget);
2679 /* x_set_name normally ignores requests to set the name if the
2680 requested name is the same as the current name. This is the one
2681 place where that assumption isn't correct; f->name is set, but
2682 the X server hasn't been told. */
2684 Lisp_Object name;
2685 int explicit = f->explicit_name;
2687 f->explicit_name = 0;
2688 name = f->name;
2689 f->name = Qnil;
2690 x_set_name (f, name, explicit);
2693 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2694 f->output_data.x->current_cursor
2695 = f->output_data.x->text_cursor);
2697 UNBLOCK_INPUT;
2699 /* This is a no-op, except under Motif. Make sure main areas are
2700 set to something reasonable, in case we get an error later. */
2701 lw_set_main_areas (pane_widget, 0, frame_widget);
2704 #else /* not USE_X_TOOLKIT */
2705 #ifdef USE_GTK
2706 void
2707 x_window (f)
2708 FRAME_PTR f;
2710 if (! xg_create_frame_widgets (f))
2711 error ("Unable to create window");
2713 #ifdef HAVE_X_I18N
2714 FRAME_XIC (f) = NULL;
2715 if (use_xim)
2717 BLOCK_INPUT;
2718 create_frame_xic (f);
2719 if (FRAME_XIC (f))
2721 /* XIM server might require some X events. */
2722 unsigned long fevent = NoEventMask;
2723 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2725 if (fevent != NoEventMask)
2727 XSetWindowAttributes attributes;
2728 XWindowAttributes wattr;
2729 unsigned long attribute_mask;
2731 XGetWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2732 &wattr);
2733 attributes.event_mask = wattr.your_event_mask | fevent;
2734 attribute_mask = CWEventMask;
2735 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2736 attribute_mask, &attributes);
2739 UNBLOCK_INPUT;
2741 #endif
2744 #else /*! USE_GTK */
2745 /* Create and set up the X window for frame F. */
2747 void
2748 x_window (f)
2749 struct frame *f;
2752 XClassHint class_hints;
2753 XSetWindowAttributes attributes;
2754 unsigned long attribute_mask;
2756 attributes.background_pixel = FRAME_BACKGROUND_PIXEL (f);
2757 attributes.border_pixel = f->output_data.x->border_pixel;
2758 attributes.bit_gravity = StaticGravity;
2759 attributes.backing_store = NotUseful;
2760 attributes.save_under = True;
2761 attributes.event_mask = STANDARD_EVENT_SET;
2762 attributes.colormap = FRAME_X_COLORMAP (f);
2763 attribute_mask = (CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask
2764 | CWColormap);
2766 BLOCK_INPUT;
2767 FRAME_X_WINDOW (f)
2768 = XCreateWindow (FRAME_X_DISPLAY (f),
2769 f->output_data.x->parent_desc,
2770 f->left_pos,
2771 f->top_pos,
2772 FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
2773 f->border_width,
2774 CopyFromParent, /* depth */
2775 InputOutput, /* class */
2776 FRAME_X_VISUAL (f),
2777 attribute_mask, &attributes);
2779 #ifdef HAVE_X_I18N
2780 if (use_xim)
2782 create_frame_xic (f);
2783 if (FRAME_XIC (f))
2785 /* XIM server might require some X events. */
2786 unsigned long fevent = NoEventMask;
2787 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2788 attributes.event_mask |= fevent;
2789 attribute_mask = CWEventMask;
2790 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2791 attribute_mask, &attributes);
2794 #endif /* HAVE_X_I18N */
2796 validate_x_resource_name ();
2798 class_hints.res_name = (char *) SDATA (Vx_resource_name);
2799 class_hints.res_class = (char *) SDATA (Vx_resource_class);
2800 XSetClassHint (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &class_hints);
2802 /* The menubar is part of the ordinary display;
2803 it does not count in addition to the height of the window. */
2804 f->output_data.x->menubar_height = 0;
2806 /* This indicates that we use the "Passive Input" input model.
2807 Unless we do this, we don't get the Focus{In,Out} events that we
2808 need to draw the cursor correctly. Accursed bureaucrats.
2809 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2811 f->output_data.x->wm_hints.input = True;
2812 f->output_data.x->wm_hints.flags |= InputHint;
2813 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2814 &f->output_data.x->wm_hints);
2815 f->output_data.x->wm_hints.icon_pixmap = None;
2817 /* Request "save yourself" and "delete window" commands from wm. */
2819 Atom protocols[2];
2820 protocols[0] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window;
2821 protocols[1] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
2822 XSetWMProtocols (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), protocols, 2);
2825 /* x_set_name normally ignores requests to set the name if the
2826 requested name is the same as the current name. This is the one
2827 place where that assumption isn't correct; f->name is set, but
2828 the X server hasn't been told. */
2830 Lisp_Object name;
2831 int explicit = f->explicit_name;
2833 f->explicit_name = 0;
2834 name = f->name;
2835 f->name = Qnil;
2836 x_set_name (f, name, explicit);
2839 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2840 f->output_data.x->current_cursor
2841 = f->output_data.x->text_cursor);
2843 UNBLOCK_INPUT;
2845 if (FRAME_X_WINDOW (f) == 0)
2846 error ("Unable to create window");
2849 #endif /* not USE_GTK */
2850 #endif /* not USE_X_TOOLKIT */
2852 /* Verify that the icon position args for this window are valid. */
2854 static void
2855 x_icon_verify (f, parms)
2856 struct frame *f;
2857 Lisp_Object parms;
2859 Lisp_Object icon_x, icon_y;
2861 /* Set the position of the icon. Note that twm groups all
2862 icons in an icon window. */
2863 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2864 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2865 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2867 CHECK_NUMBER (icon_x);
2868 CHECK_NUMBER (icon_y);
2870 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2871 error ("Both left and top icon corners of icon must be specified");
2874 /* Handle the icon stuff for this window. Perhaps later we might
2875 want an x_set_icon_position which can be called interactively as
2876 well. */
2878 static void
2879 x_icon (f, parms)
2880 struct frame *f;
2881 Lisp_Object parms;
2883 Lisp_Object icon_x, icon_y;
2884 #if 0
2885 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2886 #endif
2888 /* Set the position of the icon. Note that twm groups all
2889 icons in an icon window. */
2890 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2891 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2892 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2894 CHECK_NUMBER (icon_x);
2895 CHECK_NUMBER (icon_y);
2897 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2898 error ("Both left and top icon corners of icon must be specified");
2900 BLOCK_INPUT;
2902 if (! EQ (icon_x, Qunbound))
2903 x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
2905 #if 0 /* x_get_arg removes the visibility parameter as a side effect,
2906 but x_create_frame still needs it. */
2907 /* Start up iconic or window? */
2908 x_wm_set_window_state
2909 (f, (EQ (x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL),
2910 Qicon)
2911 ? IconicState
2912 : NormalState));
2913 #endif
2915 x_text_icon (f, (char *) SDATA ((!NILP (f->icon_name)
2916 ? f->icon_name
2917 : f->name)));
2919 UNBLOCK_INPUT;
2922 /* Make the GCs needed for this window, setting the
2923 background, border and mouse colors; also create the
2924 mouse cursor and the gray border tile. */
2926 static void
2927 x_make_gc (f)
2928 struct frame *f;
2930 XGCValues gc_values;
2932 BLOCK_INPUT;
2934 /* Create the GCs of this frame.
2935 Note that many default values are used. */
2937 gc_values.foreground = FRAME_FOREGROUND_PIXEL (f);
2938 gc_values.background = FRAME_BACKGROUND_PIXEL (f);
2939 gc_values.line_width = 0; /* Means 1 using fast algorithm. */
2940 f->output_data.x->normal_gc
2941 = XCreateGC (FRAME_X_DISPLAY (f),
2942 FRAME_X_WINDOW (f),
2943 GCLineWidth | GCForeground | GCBackground,
2944 &gc_values);
2946 /* Reverse video style. */
2947 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2948 gc_values.background = FRAME_FOREGROUND_PIXEL (f);
2949 f->output_data.x->reverse_gc
2950 = XCreateGC (FRAME_X_DISPLAY (f),
2951 FRAME_X_WINDOW (f),
2952 GCForeground | GCBackground | GCLineWidth,
2953 &gc_values);
2955 /* Cursor has cursor-color background, background-color foreground. */
2956 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
2957 gc_values.background = f->output_data.x->cursor_pixel;
2958 gc_values.fill_style = FillOpaqueStippled;
2959 f->output_data.x->cursor_gc
2960 = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2961 (GCForeground | GCBackground
2962 | GCFillStyle | GCLineWidth),
2963 &gc_values);
2965 /* Reliefs. */
2966 f->output_data.x->white_relief.gc = 0;
2967 f->output_data.x->black_relief.gc = 0;
2969 /* Create the gray border tile used when the pointer is not in
2970 the frame. Since this depends on the frame's pixel values,
2971 this must be done on a per-frame basis. */
2972 f->output_data.x->border_tile
2973 = (XCreatePixmapFromBitmapData
2974 (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
2975 gray_bits, gray_width, gray_height,
2976 FRAME_FOREGROUND_PIXEL (f),
2977 FRAME_BACKGROUND_PIXEL (f),
2978 DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
2980 UNBLOCK_INPUT;
2984 /* Free what was allocated in x_make_gc. */
2986 void
2987 x_free_gcs (f)
2988 struct frame *f;
2990 Display *dpy = FRAME_X_DISPLAY (f);
2992 BLOCK_INPUT;
2994 if (f->output_data.x->normal_gc)
2996 XFreeGC (dpy, f->output_data.x->normal_gc);
2997 f->output_data.x->normal_gc = 0;
3000 if (f->output_data.x->reverse_gc)
3002 XFreeGC (dpy, f->output_data.x->reverse_gc);
3003 f->output_data.x->reverse_gc = 0;
3006 if (f->output_data.x->cursor_gc)
3008 XFreeGC (dpy, f->output_data.x->cursor_gc);
3009 f->output_data.x->cursor_gc = 0;
3012 if (f->output_data.x->border_tile)
3014 XFreePixmap (dpy, f->output_data.x->border_tile);
3015 f->output_data.x->border_tile = 0;
3018 UNBLOCK_INPUT;
3022 /* Handler for signals raised during x_create_frame and
3023 x_create_top_frame. FRAME is the frame which is partially
3024 constructed. */
3026 static Lisp_Object
3027 unwind_create_frame (frame)
3028 Lisp_Object frame;
3030 struct frame *f = XFRAME (frame);
3032 /* If frame is already dead, nothing to do. This can happen if the
3033 display is disconnected after the frame has become official, but
3034 before x_create_frame removes the unwind protect. */
3035 if (!FRAME_LIVE_P (f))
3036 return Qnil;
3038 /* If frame is ``official'', nothing to do. */
3039 if (!CONSP (Vframe_list) || !EQ (XCAR (Vframe_list), frame))
3041 #if GLYPH_DEBUG
3042 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3043 #endif
3045 x_free_frame_resources (f);
3047 #if GLYPH_DEBUG
3048 /* Check that reference counts are indeed correct. */
3049 xassert (dpyinfo->reference_count == dpyinfo_refcount);
3050 xassert (dpyinfo->image_cache->refcount == image_cache_refcount);
3051 #endif
3052 return Qt;
3055 return Qnil;
3059 static void
3060 x_default_font_parameter (f, parms)
3061 struct frame *f;
3062 Lisp_Object parms;
3064 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3065 Lisp_Object font_param = x_get_arg (dpyinfo, parms, Qfont, NULL, NULL,
3066 RES_TYPE_STRING);
3067 Lisp_Object font;
3068 int got_from_gconf = 0;
3069 if (EQ (font_param, Qunbound))
3070 font_param = Qnil;
3072 if (NILP (font_param))
3074 /* System font takes precedendce over X resources. We must suggest this
3075 regardless of font-use-system-font because .emacs may not have been
3076 read yet. */
3077 const char *system_font = xsettings_get_system_font ();
3078 if (system_font) font_param = make_string (system_font,
3079 strlen (system_font));
3082 font = !NILP (font_param) ? font_param
3083 : x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
3085 if (! STRINGP (font))
3087 char *names[]
3089 #ifdef HAVE_XFT
3090 /* This will find the normal Xft font. */
3091 "monospace-10",
3092 #endif
3093 "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
3094 "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3095 "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3096 /* This was formerly the first thing tried, but it finds
3097 too many fonts and takes too long. */
3098 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
3099 /* If those didn't work, look for something which will
3100 at least work. */
3101 "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
3102 "fixed",
3103 NULL };
3104 int i;
3106 for (i = 0; names[i]; i++)
3108 font = font_open_by_name (f, names[i]);
3109 if (! NILP (font))
3110 break;
3112 if (NILP (font))
3113 error ("No suitable font was found");
3115 else if (!NILP (font_param))
3117 /* Remember the explicit font parameter, so we can re-apply it after
3118 we've applied the `default' face settings. */
3119 x_set_frame_parameters (f, Fcons (Fcons (Qfont_param, font_param), Qnil));
3122 x_default_parameter (f, parms, Qfont, font,
3123 got_from_gconf ? NULL : "font",
3124 got_from_gconf ? NULL : "Font",
3125 RES_TYPE_STRING);
3129 DEFUN ("x-wm-set-size-hint", Fx_wm_set_size_hint, Sx_wm_set_size_hint,
3130 0, 1, 0,
3131 doc: /* Send the size hints for frame FRAME to the window manager.
3132 If FRAME is nil, use the selected frame. */)
3133 (frame)
3134 Lisp_Object frame;
3136 struct frame *f;
3137 if (NILP (frame))
3138 frame = selected_frame;
3139 f = XFRAME (frame);
3140 BLOCK_INPUT;
3141 if (FRAME_X_P (f))
3142 x_wm_set_size_hint (f, 0, 0);
3143 UNBLOCK_INPUT;
3144 return Qnil;
3147 static void
3148 set_machine_and_pid_properties (struct frame *f)
3150 /* See the above comment "Note: Encoding strategy". */
3151 XTextProperty text;
3152 int bytes, stringp;
3153 int do_free_text_value = 0;
3154 long pid = (long) getpid ();
3156 text.value = x_encode_text (Vsystem_name,
3157 Qcompound_text, 0, &bytes, &stringp,
3158 &do_free_text_value);
3159 text.encoding = (stringp ? XA_STRING
3160 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
3161 text.format = 8;
3162 text.nitems = bytes;
3163 XSetWMClientMachine (FRAME_X_DISPLAY (f),
3164 FRAME_OUTER_WINDOW (f),
3165 &text);
3166 if (do_free_text_value)
3167 xfree (text.value);
3169 XChangeProperty (FRAME_X_DISPLAY (f),
3170 FRAME_OUTER_WINDOW (f),
3171 XInternAtom (FRAME_X_DISPLAY (f),
3172 "_NET_WM_PID",
3173 False),
3174 XA_CARDINAL, 32, PropModeReplace,
3175 (unsigned char *) &pid, 1);
3178 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
3179 1, 1, 0,
3180 doc: /* Make a new X window, which is called a "frame" in Emacs terms.
3181 Return an Emacs frame object.
3182 PARMS is an alist of frame parameters.
3183 If the parameters specify that the frame should not have a minibuffer,
3184 and do not specify a specific minibuffer window to use,
3185 then `default-minibuffer-frame' must be a frame whose minibuffer can
3186 be shared by the new frame.
3188 This function is an internal primitive--use `make-frame' instead. */)
3189 (parms)
3190 Lisp_Object parms;
3192 struct frame *f;
3193 Lisp_Object frame, tem;
3194 Lisp_Object name;
3195 int minibuffer_only = 0;
3196 long window_prompting = 0;
3197 int width, height;
3198 int count = SPECPDL_INDEX ();
3199 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
3200 Lisp_Object display;
3201 struct x_display_info *dpyinfo = NULL;
3202 Lisp_Object parent;
3203 struct kboard *kb;
3205 parms = Fcopy_alist (parms);
3207 /* Use this general default value to start with
3208 until we know if this frame has a specified name. */
3209 Vx_resource_name = Vinvocation_name;
3211 display = x_get_arg (dpyinfo, parms, Qterminal, 0, 0, RES_TYPE_NUMBER);
3212 if (EQ (display, Qunbound))
3213 display = x_get_arg (dpyinfo, parms, Qdisplay, 0, 0, RES_TYPE_STRING);
3214 if (EQ (display, Qunbound))
3215 display = Qnil;
3216 dpyinfo = check_x_display_info (display);
3217 kb = dpyinfo->terminal->kboard;
3219 if (!dpyinfo->terminal->name)
3220 error ("Terminal is not live, can't create new frames on it");
3222 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
3223 if (!STRINGP (name)
3224 && ! EQ (name, Qunbound)
3225 && ! NILP (name))
3226 error ("Invalid frame name--not a string or nil");
3228 if (STRINGP (name))
3229 Vx_resource_name = name;
3231 /* See if parent window is specified. */
3232 parent = x_get_arg (dpyinfo, parms, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
3233 if (EQ (parent, Qunbound))
3234 parent = Qnil;
3235 if (! NILP (parent))
3236 CHECK_NUMBER (parent);
3238 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
3239 /* No need to protect DISPLAY because that's not used after passing
3240 it to make_frame_without_minibuffer. */
3241 frame = Qnil;
3242 GCPRO4 (parms, parent, name, frame);
3243 tem = x_get_arg (dpyinfo, parms, Qminibuffer, "minibuffer", "Minibuffer",
3244 RES_TYPE_SYMBOL);
3245 if (EQ (tem, Qnone) || NILP (tem))
3246 f = make_frame_without_minibuffer (Qnil, kb, display);
3247 else if (EQ (tem, Qonly))
3249 f = make_minibuffer_frame ();
3250 minibuffer_only = 1;
3252 else if (WINDOWP (tem))
3253 f = make_frame_without_minibuffer (tem, kb, display);
3254 else
3255 f = make_frame (1);
3257 XSETFRAME (frame, f);
3259 /* Note that X Windows does support scroll bars. */
3260 FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
3262 f->terminal = dpyinfo->terminal;
3263 f->terminal->reference_count++;
3265 f->output_method = output_x_window;
3266 f->output_data.x = (struct x_output *) xmalloc (sizeof (struct x_output));
3267 bzero (f->output_data.x, sizeof (struct x_output));
3268 f->output_data.x->icon_bitmap = -1;
3269 FRAME_FONTSET (f) = -1;
3270 f->output_data.x->scroll_bar_foreground_pixel = -1;
3271 f->output_data.x->scroll_bar_background_pixel = -1;
3272 #ifdef USE_TOOLKIT_SCROLL_BARS
3273 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
3274 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
3275 #endif /* USE_TOOLKIT_SCROLL_BARS */
3277 f->icon_name
3278 = x_get_arg (dpyinfo, parms, Qicon_name, "iconName", "Title",
3279 RES_TYPE_STRING);
3280 if (! STRINGP (f->icon_name))
3281 f->icon_name = Qnil;
3283 FRAME_X_DISPLAY_INFO (f) = dpyinfo;
3285 /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe. */
3286 record_unwind_protect (unwind_create_frame, frame);
3287 #if GLYPH_DEBUG
3288 image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
3289 dpyinfo_refcount = dpyinfo->reference_count;
3290 #endif /* GLYPH_DEBUG */
3292 /* These colors will be set anyway later, but it's important
3293 to get the color reference counts right, so initialize them! */
3295 Lisp_Object black;
3296 struct gcpro gcpro1;
3298 /* Function x_decode_color can signal an error. Make
3299 sure to initialize color slots so that we won't try
3300 to free colors we haven't allocated. */
3301 FRAME_FOREGROUND_PIXEL (f) = -1;
3302 FRAME_BACKGROUND_PIXEL (f) = -1;
3303 f->output_data.x->cursor_pixel = -1;
3304 f->output_data.x->cursor_foreground_pixel = -1;
3305 f->output_data.x->border_pixel = -1;
3306 f->output_data.x->mouse_pixel = -1;
3308 black = build_string ("black");
3309 GCPRO1 (black);
3310 FRAME_FOREGROUND_PIXEL (f)
3311 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3312 FRAME_BACKGROUND_PIXEL (f)
3313 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3314 f->output_data.x->cursor_pixel
3315 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3316 f->output_data.x->cursor_foreground_pixel
3317 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3318 f->output_data.x->border_pixel
3319 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3320 f->output_data.x->mouse_pixel
3321 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3322 UNGCPRO;
3325 /* Specify the parent under which to make this X window. */
3327 if (!NILP (parent))
3329 f->output_data.x->parent_desc = (Window) XFASTINT (parent);
3330 f->output_data.x->explicit_parent = 1;
3332 else
3334 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
3335 f->output_data.x->explicit_parent = 0;
3338 /* Set the name; the functions to which we pass f expect the name to
3339 be set. */
3340 if (EQ (name, Qunbound) || NILP (name))
3342 f->name = build_string (dpyinfo->x_id_name);
3343 f->explicit_name = 0;
3345 else
3347 f->name = name;
3348 f->explicit_name = 1;
3349 /* use the frame's title when getting resources for this frame. */
3350 specbind (Qx_resource_name, name);
3353 f->resx = dpyinfo->resx;
3354 f->resy = dpyinfo->resy;
3356 #ifdef HAVE_FREETYPE
3357 #ifdef HAVE_XFT
3358 register_font_driver (&xftfont_driver, f);
3359 #else /* not HAVE_XFT */
3360 register_font_driver (&ftxfont_driver, f);
3361 #endif /* not HAVE_XFT */
3362 #endif /* HAVE_FREETYPE */
3363 register_font_driver (&xfont_driver, f);
3365 x_default_parameter (f, parms, Qfont_backend, Qnil,
3366 "fontBackend", "FontBackend", RES_TYPE_STRING);
3368 /* Extract the window parameters from the supplied values
3369 that are needed to determine window geometry. */
3370 x_default_font_parameter (f, parms);
3371 if (!FRAME_FONT (f))
3373 delete_frame (frame, Qnoelisp);
3374 error ("Invalid frame font");
3377 /* Frame contents get displaced if an embedded X window has a border. */
3378 if (! FRAME_X_EMBEDDED_P (f))
3379 x_default_parameter (f, parms, Qborder_width, make_number (0),
3380 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
3382 /* This defaults to 1 in order to match xterm. We recognize either
3383 internalBorderWidth or internalBorder (which is what xterm calls
3384 it). */
3385 if (NILP (Fassq (Qinternal_border_width, parms)))
3387 Lisp_Object value;
3389 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
3390 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
3391 if (! EQ (value, Qunbound))
3392 parms = Fcons (Fcons (Qinternal_border_width, value),
3393 parms);
3395 x_default_parameter (f, parms, Qinternal_border_width,
3396 #ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */
3397 make_number (0),
3398 #else
3399 make_number (1),
3400 #endif
3401 "internalBorderWidth", "internalBorderWidth",
3402 RES_TYPE_NUMBER);
3403 x_default_parameter (f, parms, Qvertical_scroll_bars,
3404 #if defined(USE_GTK) && defined(USE_TOOLKIT_SCROLL_BARS)
3405 Qright,
3406 #else
3407 Qleft,
3408 #endif
3409 "verticalScrollBars", "ScrollBars",
3410 RES_TYPE_SYMBOL);
3412 /* Also do the stuff which must be set before the window exists. */
3413 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
3414 "foreground", "Foreground", RES_TYPE_STRING);
3415 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
3416 "background", "Background", RES_TYPE_STRING);
3417 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
3418 "pointerColor", "Foreground", RES_TYPE_STRING);
3419 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
3420 "cursorColor", "Foreground", RES_TYPE_STRING);
3421 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
3422 "borderColor", "BorderColor", RES_TYPE_STRING);
3423 x_default_parameter (f, parms, Qscreen_gamma, Qnil,
3424 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
3425 x_default_parameter (f, parms, Qline_spacing, Qnil,
3426 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
3427 x_default_parameter (f, parms, Qleft_fringe, Qnil,
3428 "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
3429 x_default_parameter (f, parms, Qright_fringe, Qnil,
3430 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
3432 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_foreground,
3433 "scrollBarForeground",
3434 "ScrollBarForeground", 1);
3435 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_background,
3436 "scrollBarBackground",
3437 "ScrollBarBackground", 0);
3439 /* Init faces before x_default_parameter is called for scroll-bar
3440 parameters because that function calls x_set_scroll_bar_width,
3441 which calls change_frame_size, which calls Fset_window_buffer,
3442 which runs hooks, which call Fvertical_motion. At the end, we
3443 end up in init_iterator with a null face cache, which should not
3444 happen. */
3445 init_frame_faces (f);
3447 x_default_parameter (f, parms, Qmenu_bar_lines, make_number (1),
3448 "menuBar", "MenuBar", RES_TYPE_BOOLEAN_NUMBER);
3449 x_default_parameter (f, parms, Qtool_bar_lines, make_number (1),
3450 "toolBar", "ToolBar", RES_TYPE_NUMBER);
3451 x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
3452 "bufferPredicate", "BufferPredicate",
3453 RES_TYPE_SYMBOL);
3454 x_default_parameter (f, parms, Qtitle, Qnil,
3455 "title", "Title", RES_TYPE_STRING);
3456 x_default_parameter (f, parms, Qwait_for_wm, Qt,
3457 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
3458 x_default_parameter (f, parms, Qfullscreen, Qnil,
3459 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
3461 /* Compute the size of the X window. */
3462 window_prompting = x_figure_window_size (f, parms, 1);
3464 tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
3465 f->no_split = minibuffer_only || EQ (tem, Qt);
3467 x_icon_verify (f, parms);
3469 /* Create the X widget or window. */
3470 #ifdef USE_X_TOOLKIT
3471 x_window (f, window_prompting, minibuffer_only);
3472 #else
3473 x_window (f);
3474 #endif
3476 x_icon (f, parms);
3477 x_make_gc (f);
3479 /* Now consider the frame official. */
3480 FRAME_X_DISPLAY_INFO (f)->reference_count++;
3481 Vframe_list = Fcons (frame, Vframe_list);
3483 /* We need to do this after creating the X window, so that the
3484 icon-creation functions can say whose icon they're describing. */
3485 x_default_parameter (f, parms, Qicon_type, Qt,
3486 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
3488 x_default_parameter (f, parms, Qauto_raise, Qnil,
3489 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3490 x_default_parameter (f, parms, Qauto_lower, Qnil,
3491 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3492 x_default_parameter (f, parms, Qcursor_type, Qbox,
3493 "cursorType", "CursorType", RES_TYPE_SYMBOL);
3494 x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
3495 "scrollBarWidth", "ScrollBarWidth",
3496 RES_TYPE_NUMBER);
3497 x_default_parameter (f, parms, Qalpha, Qnil,
3498 "alpha", "Alpha", RES_TYPE_NUMBER);
3500 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3501 Change will not be effected unless different from the current
3502 FRAME_LINES (f). */
3503 width = FRAME_COLS (f);
3504 height = FRAME_LINES (f);
3506 SET_FRAME_COLS (f, 0);
3507 FRAME_LINES (f) = 0;
3508 change_frame_size (f, height, width, 1, 0, 0);
3510 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3511 /* Create the menu bar. */
3512 if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
3514 /* If this signals an error, we haven't set size hints for the
3515 frame and we didn't make it visible. */
3516 initialize_frame_menubar (f);
3518 #ifndef USE_GTK
3519 /* This is a no-op, except under Motif where it arranges the
3520 main window for the widgets on it. */
3521 lw_set_main_areas (f->output_data.x->column_widget,
3522 f->output_data.x->menubar_widget,
3523 f->output_data.x->edit_widget);
3524 #endif /* not USE_GTK */
3526 #endif /* USE_X_TOOLKIT || USE_GTK */
3528 /* Tell the server what size and position, etc, we want, and how
3529 badly we want them. This should be done after we have the menu
3530 bar so that its size can be taken into account. */
3531 BLOCK_INPUT;
3532 x_wm_set_size_hint (f, window_prompting, 0);
3533 UNBLOCK_INPUT;
3535 /* Make the window appear on the frame and enable display, unless
3536 the caller says not to. However, with explicit parent, Emacs
3537 cannot control visibility, so don't try. */
3538 if (! f->output_data.x->explicit_parent)
3540 Lisp_Object visibility;
3542 visibility = x_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
3543 RES_TYPE_SYMBOL);
3544 if (EQ (visibility, Qunbound))
3545 visibility = Qt;
3547 if (EQ (visibility, Qicon))
3548 x_iconify_frame (f);
3549 else if (! NILP (visibility))
3550 x_make_frame_visible (f);
3551 else
3552 /* Must have been Qnil. */
3556 BLOCK_INPUT;
3558 /* Set machine name and pid for the purpose of window managers. */
3559 set_machine_and_pid_properties(f);
3561 /* Set the WM leader property. GTK does this itself, so this is not
3562 needed when using GTK. */
3563 if (dpyinfo->client_leader_window != 0)
3565 XChangeProperty (FRAME_X_DISPLAY (f),
3566 FRAME_OUTER_WINDOW (f),
3567 dpyinfo->Xatom_wm_client_leader,
3568 XA_WINDOW, 32, PropModeReplace,
3569 (unsigned char *) &dpyinfo->client_leader_window, 1);
3572 UNBLOCK_INPUT;
3574 /* Initialize `default-minibuffer-frame' in case this is the first
3575 frame on this terminal. */
3576 if (FRAME_HAS_MINIBUF_P (f)
3577 && (!FRAMEP (kb->Vdefault_minibuffer_frame)
3578 || !FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame))))
3579 kb->Vdefault_minibuffer_frame = frame;
3581 /* All remaining specified parameters, which have not been "used"
3582 by x_get_arg and friends, now go in the misc. alist of the frame. */
3583 for (tem = parms; CONSP (tem); tem = XCDR (tem))
3584 if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
3585 f->param_alist = Fcons (XCAR (tem), f->param_alist);
3587 UNGCPRO;
3589 /* Make sure windows on this frame appear in calls to next-window
3590 and similar functions. */
3591 Vwindow_list = Qnil;
3593 return unbind_to (count, frame);
3597 /* FRAME is used only to get a handle on the X display. We don't pass the
3598 display info directly because we're called from frame.c, which doesn't
3599 know about that structure. */
3601 Lisp_Object
3602 x_get_focus_frame (frame)
3603 struct frame *frame;
3605 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (frame);
3606 Lisp_Object xfocus;
3607 if (! dpyinfo->x_focus_frame)
3608 return Qnil;
3610 XSETFRAME (xfocus, dpyinfo->x_focus_frame);
3611 return xfocus;
3615 /* In certain situations, when the window manager follows a
3616 click-to-focus policy, there seems to be no way around calling
3617 XSetInputFocus to give another frame the input focus .
3619 In an ideal world, XSetInputFocus should generally be avoided so
3620 that applications don't interfere with the window manager's focus
3621 policy. But I think it's okay to use when it's clearly done
3622 following a user-command. */
3624 DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
3625 doc: /* Set the input focus to FRAME.
3626 FRAME nil means use the selected frame. */)
3627 (frame)
3628 Lisp_Object frame;
3630 struct frame *f = check_x_frame (frame);
3631 Display *dpy = FRAME_X_DISPLAY (f);
3633 BLOCK_INPUT;
3634 x_catch_errors (dpy);
3635 XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3636 RevertToParent, CurrentTime);
3637 x_ewmh_activate_frame (f);
3638 x_uncatch_errors ();
3639 UNBLOCK_INPUT;
3641 return Qnil;
3645 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
3646 doc: /* Internal function called by `color-defined-p', which see. */)
3647 (color, frame)
3648 Lisp_Object color, frame;
3650 XColor foo;
3651 FRAME_PTR f = check_x_frame (frame);
3653 CHECK_STRING (color);
3655 if (x_defined_color (f, SDATA (color), &foo, 0))
3656 return Qt;
3657 else
3658 return Qnil;
3661 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
3662 doc: /* Internal function called by `color-values', which see. */)
3663 (color, frame)
3664 Lisp_Object color, frame;
3666 XColor foo;
3667 FRAME_PTR f = check_x_frame (frame);
3669 CHECK_STRING (color);
3671 if (x_defined_color (f, SDATA (color), &foo, 0))
3672 return list3 (make_number (foo.red),
3673 make_number (foo.green),
3674 make_number (foo.blue));
3675 else
3676 return Qnil;
3679 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
3680 doc: /* Internal function called by `display-color-p', which see. */)
3681 (terminal)
3682 Lisp_Object terminal;
3684 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3686 if (dpyinfo->n_planes <= 2)
3687 return Qnil;
3689 switch (dpyinfo->visual->class)
3691 case StaticColor:
3692 case PseudoColor:
3693 case TrueColor:
3694 case DirectColor:
3695 return Qt;
3697 default:
3698 return Qnil;
3702 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
3703 0, 1, 0,
3704 doc: /* Return t if the X display supports shades of gray.
3705 Note that color displays do support shades of gray.
3706 The optional argument TERMINAL specifies which display to ask about.
3707 TERMINAL should be a terminal object, a frame or a display name (a string).
3708 If omitted or nil, that stands for the selected frame's display. */)
3709 (terminal)
3710 Lisp_Object terminal;
3712 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3714 if (dpyinfo->n_planes <= 1)
3715 return Qnil;
3717 switch (dpyinfo->visual->class)
3719 case StaticColor:
3720 case PseudoColor:
3721 case TrueColor:
3722 case DirectColor:
3723 case StaticGray:
3724 case GrayScale:
3725 return Qt;
3727 default:
3728 return Qnil;
3732 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
3733 0, 1, 0,
3734 doc: /* Return the width in pixels of the X display TERMINAL.
3735 The optional argument TERMINAL specifies which display to ask about.
3736 TERMINAL should be a terminal object, a frame or a display name (a string).
3737 If omitted or nil, that stands for the selected frame's display. */)
3738 (terminal)
3739 Lisp_Object terminal;
3741 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3743 return make_number (x_display_pixel_width (dpyinfo));
3746 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
3747 Sx_display_pixel_height, 0, 1, 0,
3748 doc: /* Return the height in pixels of the X display TERMINAL.
3749 The optional argument TERMINAL specifies which display to ask about.
3750 TERMINAL should be a terminal object, a frame or a display name (a string).
3751 If omitted or nil, that stands for the selected frame's display. */)
3752 (terminal)
3753 Lisp_Object terminal;
3755 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3757 return make_number (x_display_pixel_height (dpyinfo));
3760 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
3761 0, 1, 0,
3762 doc: /* Return the number of bitplanes of the X display TERMINAL.
3763 The optional argument TERMINAL specifies which display to ask about.
3764 TERMINAL should be a terminal object, a frame or a display name (a string).
3765 If omitted or nil, that stands for the selected frame's display. */)
3766 (terminal)
3767 Lisp_Object terminal;
3769 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3771 return make_number (dpyinfo->n_planes);
3774 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
3775 0, 1, 0,
3776 doc: /* Return the number of color cells of the X display TERMINAL.
3777 The optional argument TERMINAL specifies which display to ask about.
3778 TERMINAL should be a terminal object, a frame or a display name (a string).
3779 If omitted or nil, that stands for the selected frame's display. */)
3780 (terminal)
3781 Lisp_Object terminal;
3783 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3785 int nr_planes = DisplayPlanes (dpyinfo->display,
3786 XScreenNumberOfScreen (dpyinfo->screen));
3788 /* Truncate nr_planes to 24 to avoid integer overflow.
3789 Some displays says 32, but only 24 bits are actually significant.
3790 There are only very few and rare video cards that have more than
3791 24 significant bits. Also 24 bits is more than 16 million colors,
3792 it "should be enough for everyone". */
3793 if (nr_planes > 24) nr_planes = 24;
3795 return make_number (1 << nr_planes);
3798 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
3799 Sx_server_max_request_size,
3800 0, 1, 0,
3801 doc: /* Return the maximum request size of the X server of display TERMINAL.
3802 The optional argument TERMINAL specifies which display to ask about.
3803 TERMINAL should be a terminal object, 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 (MAXREQUEST (dpyinfo->display));
3813 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
3814 doc: /* Return the "vendor ID" string of the X server of display TERMINAL.
3815 \(Labelling every distributor as a "vendor" embodies the false assumption
3816 that operating systems cannot be developed and distributed noncommercially.)
3817 The optional argument TERMINAL specifies which display to ask about.
3818 TERMINAL should be a terminal object, 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 char *vendor = ServerVendor (dpyinfo->display);
3826 if (! vendor) vendor = "";
3827 return build_string (vendor);
3830 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
3831 doc: /* Return the version numbers of the X server of display TERMINAL.
3832 The value is a list of three integers: the major and minor
3833 version numbers of the X Protocol in use, and the distributor-specific release
3834 number. See also the function `x-server-vendor'.
3836 The optional argument TERMINAL specifies which display to ask about.
3837 TERMINAL should be a terminal object, a frame or a display name (a string).
3838 If omitted or nil, that stands for the selected frame's display. */)
3839 (terminal)
3840 Lisp_Object terminal;
3842 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3843 Display *dpy = dpyinfo->display;
3845 return Fcons (make_number (ProtocolVersion (dpy)),
3846 Fcons (make_number (ProtocolRevision (dpy)),
3847 Fcons (make_number (VendorRelease (dpy)), Qnil)));
3850 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
3851 doc: /* Return the number of screens on the X server of display TERMINAL.
3852 The optional argument TERMINAL specifies which display to ask about.
3853 TERMINAL should be a terminal object, a frame or a display name (a string).
3854 If omitted or nil, that stands for the selected frame's display. */)
3855 (terminal)
3856 Lisp_Object terminal;
3858 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3860 return make_number (ScreenCount (dpyinfo->display));
3863 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
3864 doc: /* Return the height in millimeters of the X display TERMINAL.
3865 The optional argument TERMINAL specifies which display to ask about.
3866 TERMINAL should be a terminal object, a frame or a display name (a string).
3867 If omitted or nil, that stands for the selected frame's display. */)
3868 (terminal)
3869 Lisp_Object terminal;
3871 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3873 return make_number (HeightMMOfScreen (dpyinfo->screen));
3876 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
3877 doc: /* Return the width in millimeters of the X display TERMINAL.
3878 The optional argument TERMINAL specifies which display to ask about.
3879 TERMINAL should be a terminal object, a frame or a display name (a string).
3880 If omitted or nil, that stands for the selected frame's display. */)
3881 (terminal)
3882 Lisp_Object terminal;
3884 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3886 return make_number (WidthMMOfScreen (dpyinfo->screen));
3889 DEFUN ("x-display-backing-store", Fx_display_backing_store,
3890 Sx_display_backing_store, 0, 1, 0,
3891 doc: /* Return an indication of whether X display TERMINAL does backing store.
3892 The value may be `always', `when-mapped', or `not-useful'.
3893 The optional argument TERMINAL specifies which display to ask about.
3894 TERMINAL should be a terminal object, a frame or a display name (a string).
3895 If omitted or nil, that stands for the selected frame's display. */)
3896 (terminal)
3897 Lisp_Object terminal;
3899 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3900 Lisp_Object result;
3902 switch (DoesBackingStore (dpyinfo->screen))
3904 case Always:
3905 result = intern ("always");
3906 break;
3908 case WhenMapped:
3909 result = intern ("when-mapped");
3910 break;
3912 case NotUseful:
3913 result = intern ("not-useful");
3914 break;
3916 default:
3917 error ("Strange value for BackingStore parameter of screen");
3918 result = Qnil;
3921 return result;
3924 DEFUN ("x-display-visual-class", Fx_display_visual_class,
3925 Sx_display_visual_class, 0, 1, 0,
3926 doc: /* Return the visual class of the X display TERMINAL.
3927 The value is one of the symbols `static-gray', `gray-scale',
3928 `static-color', `pseudo-color', `true-color', or `direct-color'.
3930 The optional argument TERMINAL specifies which display to ask about.
3931 TERMINAL should a terminal object, a frame or a display name (a string).
3932 If omitted or nil, that stands for the selected frame's display. */)
3933 (terminal)
3934 Lisp_Object terminal;
3936 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3937 Lisp_Object result;
3939 switch (dpyinfo->visual->class)
3941 case StaticGray:
3942 result = intern ("static-gray");
3943 break;
3944 case GrayScale:
3945 result = intern ("gray-scale");
3946 break;
3947 case StaticColor:
3948 result = intern ("static-color");
3949 break;
3950 case PseudoColor:
3951 result = intern ("pseudo-color");
3952 break;
3953 case TrueColor:
3954 result = intern ("true-color");
3955 break;
3956 case DirectColor:
3957 result = intern ("direct-color");
3958 break;
3959 default:
3960 error ("Display has an unknown visual class");
3961 result = Qnil;
3964 return result;
3967 DEFUN ("x-display-save-under", Fx_display_save_under,
3968 Sx_display_save_under, 0, 1, 0,
3969 doc: /* Return t if the X display TERMINAL supports the save-under feature.
3970 The optional argument TERMINAL specifies which display to ask about.
3971 TERMINAL should be a terminal object, a frame or a display name (a string).
3972 If omitted or nil, that stands for the selected frame's display. */)
3973 (terminal)
3974 Lisp_Object terminal;
3976 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3978 if (DoesSaveUnders (dpyinfo->screen) == True)
3979 return Qt;
3980 else
3981 return Qnil;
3985 x_pixel_width (f)
3986 register struct frame *f;
3988 return FRAME_PIXEL_WIDTH (f);
3992 x_pixel_height (f)
3993 register struct frame *f;
3995 return FRAME_PIXEL_HEIGHT (f);
3999 x_char_width (f)
4000 register struct frame *f;
4002 return FRAME_COLUMN_WIDTH (f);
4006 x_char_height (f)
4007 register struct frame *f;
4009 return FRAME_LINE_HEIGHT (f);
4013 x_screen_planes (f)
4014 register struct frame *f;
4016 return FRAME_X_DISPLAY_INFO (f)->n_planes;
4021 /************************************************************************
4022 X Displays
4023 ************************************************************************/
4026 /* Mapping visual names to visuals. */
4028 static struct visual_class
4030 char *name;
4031 int class;
4033 visual_classes[] =
4035 {"StaticGray", StaticGray},
4036 {"GrayScale", GrayScale},
4037 {"StaticColor", StaticColor},
4038 {"PseudoColor", PseudoColor},
4039 {"TrueColor", TrueColor},
4040 {"DirectColor", DirectColor},
4041 {NULL, 0}
4045 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4047 /* Value is the screen number of screen SCR. This is a substitute for
4048 the X function with the same name when that doesn't exist. */
4051 XScreenNumberOfScreen (scr)
4052 register Screen *scr;
4054 Display *dpy = scr->display;
4055 int i;
4057 for (i = 0; i < dpy->nscreens; ++i)
4058 if (scr == dpy->screens + i)
4059 break;
4061 return i;
4064 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4067 /* Select the visual that should be used on display DPYINFO. Set
4068 members of DPYINFO appropriately. Called from x_term_init. */
4070 void
4071 select_visual (dpyinfo)
4072 struct x_display_info *dpyinfo;
4074 Display *dpy = dpyinfo->display;
4075 Screen *screen = dpyinfo->screen;
4076 Lisp_Object value;
4078 /* See if a visual is specified. */
4079 value = display_x_get_resource (dpyinfo,
4080 build_string ("visualClass"),
4081 build_string ("VisualClass"),
4082 Qnil, Qnil);
4083 if (STRINGP (value))
4085 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
4086 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
4087 depth, a decimal number. NAME is compared with case ignored. */
4088 char *s = (char *) alloca (SBYTES (value) + 1);
4089 char *dash;
4090 int i, class = -1;
4091 XVisualInfo vinfo;
4093 strcpy (s, SDATA (value));
4094 dash = index (s, '-');
4095 if (dash)
4097 dpyinfo->n_planes = atoi (dash + 1);
4098 *dash = '\0';
4100 else
4101 /* We won't find a matching visual with depth 0, so that
4102 an error will be printed below. */
4103 dpyinfo->n_planes = 0;
4105 /* Determine the visual class. */
4106 for (i = 0; visual_classes[i].name; ++i)
4107 if (xstrcasecmp (s, visual_classes[i].name) == 0)
4109 class = visual_classes[i].class;
4110 break;
4113 /* Look up a matching visual for the specified class. */
4114 if (class == -1
4115 || !XMatchVisualInfo (dpy, XScreenNumberOfScreen (screen),
4116 dpyinfo->n_planes, class, &vinfo))
4117 fatal ("Invalid visual specification `%s'", SDATA (value));
4119 dpyinfo->visual = vinfo.visual;
4121 else
4123 int n_visuals;
4124 XVisualInfo *vinfo, vinfo_template;
4126 dpyinfo->visual = DefaultVisualOfScreen (screen);
4128 vinfo_template.visualid = XVisualIDFromVisual (dpyinfo->visual);
4129 vinfo_template.screen = XScreenNumberOfScreen (screen);
4130 vinfo = XGetVisualInfo (dpy, VisualIDMask | VisualScreenMask,
4131 &vinfo_template, &n_visuals);
4132 if (n_visuals <= 0)
4133 fatal ("Can't get proper X visual info");
4135 dpyinfo->n_planes = vinfo->depth;
4136 XFree ((char *) vinfo);
4141 /* Return the X display structure for the display named NAME.
4142 Open a new connection if necessary. */
4144 struct x_display_info *
4145 x_display_info_for_name (name)
4146 Lisp_Object name;
4148 Lisp_Object names;
4149 struct x_display_info *dpyinfo;
4151 CHECK_STRING (name);
4153 #if 0
4154 if (! EQ (Vinitial_window_system, intern ("x")))
4155 error ("Not using X Windows"); /* That doesn't stop us anymore. */
4156 #endif
4158 for (dpyinfo = x_display_list, names = x_display_name_list;
4159 dpyinfo;
4160 dpyinfo = dpyinfo->next, names = XCDR (names))
4162 Lisp_Object tem;
4163 tem = Fstring_equal (XCAR (XCAR (names)), name);
4164 if (!NILP (tem))
4165 return dpyinfo;
4168 /* Use this general default value to start with. */
4169 Vx_resource_name = Vinvocation_name;
4171 validate_x_resource_name ();
4173 dpyinfo = x_term_init (name, (char *)0,
4174 (char *) SDATA (Vx_resource_name));
4176 if (dpyinfo == 0)
4177 error ("Cannot connect to X server %s", SDATA (name));
4179 x_in_use = 1;
4180 XSETFASTINT (Vwindow_system_version, 11);
4182 return dpyinfo;
4186 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
4187 1, 3, 0,
4188 doc: /* Open a connection to an X server.
4189 DISPLAY is the name of the display to connect to.
4190 Optional second arg XRM-STRING is a string of resources in xrdb format.
4191 If the optional third arg MUST-SUCCEED is non-nil,
4192 terminate Emacs if we can't open the connection. */)
4193 (display, xrm_string, must_succeed)
4194 Lisp_Object display, xrm_string, must_succeed;
4196 unsigned char *xrm_option;
4197 struct x_display_info *dpyinfo;
4199 CHECK_STRING (display);
4200 if (! NILP (xrm_string))
4201 CHECK_STRING (xrm_string);
4203 #if 0
4204 if (! EQ (Vinitial_window_system, intern ("x")))
4205 error ("Not using X Windows"); /* That doesn't stop us anymore. */
4206 #endif
4208 if (! NILP (xrm_string))
4209 xrm_option = (unsigned char *) SDATA (xrm_string);
4210 else
4211 xrm_option = (unsigned char *) 0;
4213 validate_x_resource_name ();
4215 /* This is what opens the connection and sets x_current_display.
4216 This also initializes many symbols, such as those used for input. */
4217 dpyinfo = x_term_init (display, xrm_option,
4218 (char *) SDATA (Vx_resource_name));
4220 if (dpyinfo == 0)
4222 if (!NILP (must_succeed))
4223 fatal ("Cannot connect to X server %s.\n\
4224 Check the DISPLAY environment variable or use `-d'.\n\
4225 Also use the `xauth' program to verify that you have the proper\n\
4226 authorization information needed to connect the X server.\n\
4227 An insecure way to solve the problem may be to use `xhost'.\n",
4228 SDATA (display));
4229 else
4230 error ("Cannot connect to X server %s", SDATA (display));
4233 x_in_use = 1;
4235 XSETFASTINT (Vwindow_system_version, 11);
4236 return Qnil;
4239 DEFUN ("x-close-connection", Fx_close_connection,
4240 Sx_close_connection, 1, 1, 0,
4241 doc: /* Close the connection to TERMINAL's X server.
4242 For TERMINAL, specify a terminal object, a frame or a display name (a
4243 string). If TERMINAL is nil, that stands for the selected frame's
4244 terminal. */)
4245 (terminal)
4246 Lisp_Object terminal;
4248 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4250 if (dpyinfo->reference_count > 0)
4251 error ("Display still has frames on it");
4253 x_delete_terminal (dpyinfo->terminal);
4255 return Qnil;
4258 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
4259 doc: /* Return the list of display names that Emacs has connections to. */)
4262 Lisp_Object tail, result;
4264 result = Qnil;
4265 for (tail = x_display_name_list; CONSP (tail); tail = XCDR (tail))
4266 result = Fcons (XCAR (XCAR (tail)), result);
4268 return result;
4271 DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
4272 doc: /* If ON is non-nil, report X errors as soon as the erring request is made.
4273 If ON is nil, allow buffering of requests.
4274 Turning on synchronization prohibits the Xlib routines from buffering
4275 requests and seriously degrades performance, but makes debugging much
4276 easier.
4277 The optional second argument TERMINAL specifies which display to act on.
4278 TERMINAL should be a terminal object, a frame or a display name (a string).
4279 If TERMINAL is omitted or nil, that stands for the selected frame's display. */)
4280 (on, terminal)
4281 Lisp_Object terminal, on;
4283 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4285 XSynchronize (dpyinfo->display, !EQ (on, Qnil));
4287 return Qnil;
4290 /* Wait for responses to all X commands issued so far for frame F. */
4292 void
4293 x_sync (f)
4294 FRAME_PTR f;
4296 BLOCK_INPUT;
4297 XSync (FRAME_X_DISPLAY (f), False);
4298 UNBLOCK_INPUT;
4302 /***********************************************************************
4303 Window properties
4304 ***********************************************************************/
4306 DEFUN ("x-change-window-property", Fx_change_window_property,
4307 Sx_change_window_property, 2, 6, 0,
4308 doc: /* Change window property PROP to VALUE on the X window of FRAME.
4309 PROP must be a string.
4310 VALUE may be a string or a list of conses, numbers and/or strings.
4311 If an element in the list is a string, it is converted to
4312 an Atom and the value of the Atom is used. If an element is a cons,
4313 it is converted to a 32 bit number where the car is the 16 top bits and the
4314 cdr is the lower 16 bits.
4315 FRAME nil or omitted means use the selected frame.
4316 If TYPE is given and non-nil, it is the name of the type of VALUE.
4317 If TYPE is not given or nil, the type is STRING.
4318 FORMAT gives the size in bits of each element if VALUE is a list.
4319 It must be one of 8, 16 or 32.
4320 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
4321 If OUTER_P is non-nil, the property is changed for the outer X window of
4322 FRAME. Default is to change on the edit X window.
4324 Value is VALUE. */)
4325 (prop, value, frame, type, format, outer_p)
4326 Lisp_Object prop, value, frame, type, format, outer_p;
4328 struct frame *f = check_x_frame (frame);
4329 Atom prop_atom;
4330 Atom target_type = XA_STRING;
4331 int element_format = 8;
4332 unsigned char *data;
4333 int nelements;
4334 Window w;
4336 CHECK_STRING (prop);
4338 if (! NILP (format))
4340 CHECK_NUMBER (format);
4341 element_format = XFASTINT (format);
4343 if (element_format != 8 && element_format != 16
4344 && element_format != 32)
4345 error ("FORMAT must be one of 8, 16 or 32");
4348 if (CONSP (value))
4350 nelements = x_check_property_data (value);
4351 if (nelements == -1)
4352 error ("Bad data in VALUE, must be number, string or cons");
4354 if (element_format == 8)
4355 data = (unsigned char *) xmalloc (nelements);
4356 else if (element_format == 16)
4357 data = (unsigned char *) xmalloc (nelements*2);
4358 else /* format == 32 */
4359 /* The man page for XChangeProperty:
4360 "If the specified format is 32, the property data must be a
4361 long array."
4362 This applies even if long is more than 64 bits. The X library
4363 converts to 32 bits before sending to the X server. */
4364 data = (unsigned char *) xmalloc (nelements * sizeof(long));
4366 x_fill_property_data (FRAME_X_DISPLAY (f), value, data, element_format);
4368 else
4370 CHECK_STRING (value);
4371 data = SDATA (value);
4372 nelements = SCHARS (value);
4375 BLOCK_INPUT;
4376 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4377 if (! NILP (type))
4379 CHECK_STRING (type);
4380 target_type = XInternAtom (FRAME_X_DISPLAY (f), SDATA (type), False);
4383 if (! NILP (outer_p)) w = FRAME_OUTER_WINDOW (f);
4384 else w = FRAME_X_WINDOW (f);
4386 XChangeProperty (FRAME_X_DISPLAY (f), w,
4387 prop_atom, target_type, element_format, PropModeReplace,
4388 data, nelements);
4390 if (CONSP (value)) xfree (data);
4392 /* Make sure the property is set when we return. */
4393 XFlush (FRAME_X_DISPLAY (f));
4394 UNBLOCK_INPUT;
4396 return value;
4400 DEFUN ("x-delete-window-property", Fx_delete_window_property,
4401 Sx_delete_window_property, 1, 2, 0,
4402 doc: /* Remove window property PROP from X window of FRAME.
4403 FRAME nil or omitted means use the selected frame. Value is PROP. */)
4404 (prop, frame)
4405 Lisp_Object prop, frame;
4407 struct frame *f = check_x_frame (frame);
4408 Atom prop_atom;
4410 CHECK_STRING (prop);
4411 BLOCK_INPUT;
4412 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4413 XDeleteProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), prop_atom);
4415 /* Make sure the property is removed when we return. */
4416 XFlush (FRAME_X_DISPLAY (f));
4417 UNBLOCK_INPUT;
4419 return prop;
4423 DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
4424 1, 6, 0,
4425 doc: /* Value is the value of window property PROP on FRAME.
4426 If FRAME is nil or omitted, use the selected frame.
4427 If TYPE is nil or omitted, get the property as a string. Otherwise TYPE
4428 is the name of the Atom that denotes the type expected.
4429 If SOURCE is non-nil, get the property on that window instead of from
4430 FRAME. The number 0 denotes the root window.
4431 If DELETE_P is non-nil, delete the property after retreiving it.
4432 If VECTOR_RET_P is non-nil, don't return a string but a vector of values.
4434 Value is nil if FRAME hasn't a property with name PROP or if PROP has
4435 no value of TYPE. */)
4436 (prop, frame, type, source, delete_p, vector_ret_p)
4437 Lisp_Object prop, frame, type, source, delete_p, vector_ret_p;
4439 struct frame *f = check_x_frame (frame);
4440 Atom prop_atom;
4441 int rc;
4442 Lisp_Object prop_value = Qnil;
4443 unsigned char *tmp_data = NULL;
4444 Atom actual_type;
4445 Atom target_type = XA_STRING;
4446 int actual_format;
4447 unsigned long actual_size, bytes_remaining;
4448 Window target_window = FRAME_X_WINDOW (f);
4449 struct gcpro gcpro1;
4451 GCPRO1 (prop_value);
4452 CHECK_STRING (prop);
4454 if (! NILP (source))
4456 if (NUMBERP (source))
4458 if (FLOATP (source))
4459 target_window = (Window) XFLOAT (source);
4460 else
4461 target_window = XFASTINT (source);
4463 if (target_window == 0)
4464 target_window = FRAME_X_DISPLAY_INFO (f)->root_window;
4466 else if (CONSP (source))
4467 target_window = cons_to_long (source);
4470 BLOCK_INPUT;
4471 if (STRINGP (type))
4473 if (strcmp ("AnyPropertyType", SDATA (type)) == 0)
4474 target_type = AnyPropertyType;
4475 else
4476 target_type = XInternAtom (FRAME_X_DISPLAY (f), SDATA (type), False);
4479 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4480 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4481 prop_atom, 0, 0, False, target_type,
4482 &actual_type, &actual_format, &actual_size,
4483 &bytes_remaining, &tmp_data);
4484 if (rc == Success)
4486 int size = bytes_remaining;
4488 XFree (tmp_data);
4489 tmp_data = NULL;
4491 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4492 prop_atom, 0, bytes_remaining,
4493 ! NILP (delete_p), target_type,
4494 &actual_type, &actual_format,
4495 &actual_size, &bytes_remaining,
4496 &tmp_data);
4497 if (rc == Success && tmp_data)
4499 /* The man page for XGetWindowProperty says:
4500 "If the returned format is 32, the returned data is represented
4501 as a long array and should be cast to that type to obtain the
4502 elements."
4503 This applies even if long is more than 32 bits, the X library
4504 converts from 32 bit elements received from the X server to long
4505 and passes the long array to us. Thus, for that case bcopy can not
4506 be used. We convert to a 32 bit type here, because so much code
4507 assume on that.
4509 The bytes and offsets passed to XGetWindowProperty refers to the
4510 property and those are indeed in 32 bit quantities if format is
4511 32. */
4513 if (actual_format == 32 && actual_format < BITS_PER_LONG)
4515 unsigned long i;
4516 int *idata = (int *) tmp_data;
4517 long *ldata = (long *) tmp_data;
4519 for (i = 0; i < actual_size; ++i)
4520 idata[i] = (int) ldata[i];
4523 if (NILP (vector_ret_p))
4524 prop_value = make_string (tmp_data, size);
4525 else
4526 prop_value = x_property_data_to_lisp (f,
4527 tmp_data,
4528 actual_type,
4529 actual_format,
4530 actual_size);
4533 if (tmp_data) XFree (tmp_data);
4536 UNBLOCK_INPUT;
4537 UNGCPRO;
4538 return prop_value;
4543 /***********************************************************************
4544 Busy cursor
4545 ***********************************************************************/
4547 /* Timer function of hourglass_atimer. TIMER is equal to
4548 hourglass_atimer.
4550 Display an hourglass pointer on all frames by mapping the frames'
4551 hourglass_window. Set the hourglass_p flag in the frames'
4552 output_data.x structure to indicate that an hourglass cursor is
4553 shown on the frames. */
4555 void
4556 show_hourglass (timer)
4557 struct atimer *timer;
4559 /* The timer implementation will cancel this timer automatically
4560 after this function has run. Set hourglass_atimer to null
4561 so that we know the timer doesn't have to be canceled. */
4562 hourglass_atimer = NULL;
4564 if (!hourglass_shown_p)
4566 Lisp_Object rest, frame;
4568 BLOCK_INPUT;
4570 FOR_EACH_FRAME (rest, frame)
4572 struct frame *f = XFRAME (frame);
4574 if (FRAME_LIVE_P (f) && FRAME_X_P (f) && FRAME_X_DISPLAY (f))
4576 Display *dpy = FRAME_X_DISPLAY (f);
4578 #ifdef USE_X_TOOLKIT
4579 if (f->output_data.x->widget)
4580 #else
4581 if (FRAME_OUTER_WINDOW (f))
4582 #endif
4584 f->output_data.x->hourglass_p = 1;
4586 if (!f->output_data.x->hourglass_window)
4588 unsigned long mask = CWCursor;
4589 XSetWindowAttributes attrs;
4590 #ifdef USE_GTK
4591 Window parent = FRAME_X_WINDOW (f);
4592 #else
4593 Window parent = FRAME_OUTER_WINDOW (f);
4594 #endif
4595 attrs.cursor = f->output_data.x->hourglass_cursor;
4597 f->output_data.x->hourglass_window
4598 = XCreateWindow (dpy, parent,
4599 0, 0, 32000, 32000, 0, 0,
4600 InputOnly,
4601 CopyFromParent,
4602 mask, &attrs);
4605 XMapRaised (dpy, f->output_data.x->hourglass_window);
4606 XFlush (dpy);
4611 hourglass_shown_p = 1;
4612 UNBLOCK_INPUT;
4617 /* Hide the hourglass pointer on all frames, if it is currently
4618 shown. */
4620 void
4621 hide_hourglass ()
4623 if (hourglass_shown_p)
4625 Lisp_Object rest, frame;
4627 BLOCK_INPUT;
4628 FOR_EACH_FRAME (rest, frame)
4630 struct frame *f = XFRAME (frame);
4632 if (FRAME_X_P (f)
4633 /* Watch out for newly created frames. */
4634 && f->output_data.x->hourglass_window)
4636 XUnmapWindow (FRAME_X_DISPLAY (f),
4637 f->output_data.x->hourglass_window);
4638 /* Sync here because XTread_socket looks at the
4639 hourglass_p flag that is reset to zero below. */
4640 XSync (FRAME_X_DISPLAY (f), False);
4641 f->output_data.x->hourglass_p = 0;
4645 hourglass_shown_p = 0;
4646 UNBLOCK_INPUT;
4652 /***********************************************************************
4653 Tool tips
4654 ***********************************************************************/
4656 static Lisp_Object x_create_tip_frame P_ ((struct x_display_info *,
4657 Lisp_Object, Lisp_Object));
4658 static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object,
4659 Lisp_Object, int, int, int *, int *));
4661 /* The frame of a currently visible tooltip. */
4663 Lisp_Object tip_frame;
4665 /* If non-nil, a timer started that hides the last tooltip when it
4666 fires. */
4668 Lisp_Object tip_timer;
4669 Window tip_window;
4671 /* If non-nil, a vector of 3 elements containing the last args
4672 with which x-show-tip was called. See there. */
4674 Lisp_Object last_show_tip_args;
4676 /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
4678 Lisp_Object Vx_max_tooltip_size;
4681 static Lisp_Object
4682 unwind_create_tip_frame (frame)
4683 Lisp_Object frame;
4685 Lisp_Object deleted;
4687 deleted = unwind_create_frame (frame);
4688 if (EQ (deleted, Qt))
4690 tip_window = None;
4691 tip_frame = Qnil;
4694 return deleted;
4698 /* Create a frame for a tooltip on the display described by DPYINFO.
4699 PARMS is a list of frame parameters. TEXT is the string to
4700 display in the tip frame. Value is the frame.
4702 Note that functions called here, esp. x_default_parameter can
4703 signal errors, for instance when a specified color name is
4704 undefined. We have to make sure that we're in a consistent state
4705 when this happens. */
4707 static Lisp_Object
4708 x_create_tip_frame (dpyinfo, parms, text)
4709 struct x_display_info *dpyinfo;
4710 Lisp_Object parms, text;
4712 struct frame *f;
4713 Lisp_Object frame, tem;
4714 Lisp_Object name;
4715 long window_prompting = 0;
4716 int width, height;
4717 int count = SPECPDL_INDEX ();
4718 struct gcpro gcpro1, gcpro2, gcpro3;
4719 int face_change_count_before = face_change_count;
4720 Lisp_Object buffer;
4721 struct buffer *old_buffer;
4723 check_x ();
4725 if (!dpyinfo->terminal->name)
4726 error ("Terminal is not live, can't create new frames on it");
4728 parms = Fcopy_alist (parms);
4730 /* Get the name of the frame to use for resource lookup. */
4731 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
4732 if (!STRINGP (name)
4733 && !EQ (name, Qunbound)
4734 && !NILP (name))
4735 error ("Invalid frame name--not a string or nil");
4737 frame = Qnil;
4738 GCPRO3 (parms, name, frame);
4739 f = make_frame (1);
4740 XSETFRAME (frame, f);
4742 buffer = Fget_buffer_create (build_string (" *tip*"));
4743 Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer, Qnil);
4744 old_buffer = current_buffer;
4745 set_buffer_internal_1 (XBUFFER (buffer));
4746 current_buffer->truncate_lines = Qnil;
4747 specbind (Qinhibit_read_only, Qt);
4748 specbind (Qinhibit_modification_hooks, Qt);
4749 Ferase_buffer ();
4750 Finsert (1, &text);
4751 set_buffer_internal_1 (old_buffer);
4753 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
4754 record_unwind_protect (unwind_create_tip_frame, frame);
4756 f->terminal = dpyinfo->terminal;
4757 f->terminal->reference_count++;
4759 /* By setting the output method, we're essentially saying that
4760 the frame is live, as per FRAME_LIVE_P. If we get a signal
4761 from this point on, x_destroy_window might screw up reference
4762 counts etc. */
4763 f->output_method = output_x_window;
4764 f->output_data.x = (struct x_output *) xmalloc (sizeof (struct x_output));
4765 bzero (f->output_data.x, sizeof (struct x_output));
4766 f->output_data.x->icon_bitmap = -1;
4767 FRAME_FONTSET (f) = -1;
4768 f->output_data.x->scroll_bar_foreground_pixel = -1;
4769 f->output_data.x->scroll_bar_background_pixel = -1;
4770 #ifdef USE_TOOLKIT_SCROLL_BARS
4771 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
4772 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
4773 #endif /* USE_TOOLKIT_SCROLL_BARS */
4774 f->icon_name = Qnil;
4775 FRAME_X_DISPLAY_INFO (f) = dpyinfo;
4776 #if GLYPH_DEBUG
4777 image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
4778 dpyinfo_refcount = dpyinfo->reference_count;
4779 #endif /* GLYPH_DEBUG */
4780 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
4781 f->output_data.x->explicit_parent = 0;
4783 /* These colors will be set anyway later, but it's important
4784 to get the color reference counts right, so initialize them! */
4786 Lisp_Object black;
4787 struct gcpro gcpro1;
4789 /* Function x_decode_color can signal an error. Make
4790 sure to initialize color slots so that we won't try
4791 to free colors we haven't allocated. */
4792 FRAME_FOREGROUND_PIXEL (f) = -1;
4793 FRAME_BACKGROUND_PIXEL (f) = -1;
4794 f->output_data.x->cursor_pixel = -1;
4795 f->output_data.x->cursor_foreground_pixel = -1;
4796 f->output_data.x->border_pixel = -1;
4797 f->output_data.x->mouse_pixel = -1;
4799 black = build_string ("black");
4800 GCPRO1 (black);
4801 FRAME_FOREGROUND_PIXEL (f)
4802 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4803 FRAME_BACKGROUND_PIXEL (f)
4804 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4805 f->output_data.x->cursor_pixel
4806 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4807 f->output_data.x->cursor_foreground_pixel
4808 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4809 f->output_data.x->border_pixel
4810 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4811 f->output_data.x->mouse_pixel
4812 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4813 UNGCPRO;
4816 /* Set the name; the functions to which we pass f expect the name to
4817 be set. */
4818 if (EQ (name, Qunbound) || NILP (name))
4820 f->name = build_string (dpyinfo->x_id_name);
4821 f->explicit_name = 0;
4823 else
4825 f->name = name;
4826 f->explicit_name = 1;
4827 /* use the frame's title when getting resources for this frame. */
4828 specbind (Qx_resource_name, name);
4831 f->resx = dpyinfo->resx;
4832 f->resy = dpyinfo->resy;
4834 register_font_driver (&xfont_driver, f);
4835 #ifdef HAVE_FREETYPE
4836 #ifdef HAVE_XFT
4837 register_font_driver (&xftfont_driver, f);
4838 #else /* not HAVE_XFT */
4839 register_font_driver (&ftxfont_driver, f);
4840 #endif /* not HAVE_XFT */
4841 #endif /* HAVE_FREETYPE */
4843 x_default_parameter (f, parms, Qfont_backend, Qnil,
4844 "fontBackend", "FontBackend", RES_TYPE_STRING);
4846 /* Extract the window parameters from the supplied values that are
4847 needed to determine window geometry. */
4848 x_default_font_parameter (f, parms);
4850 x_default_parameter (f, parms, Qborder_width, make_number (0),
4851 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
4853 /* This defaults to 2 in order to match xterm. We recognize either
4854 internalBorderWidth or internalBorder (which is what xterm calls
4855 it). */
4856 if (NILP (Fassq (Qinternal_border_width, parms)))
4858 Lisp_Object value;
4860 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
4861 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
4862 if (! EQ (value, Qunbound))
4863 parms = Fcons (Fcons (Qinternal_border_width, value),
4864 parms);
4867 x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
4868 "internalBorderWidth", "internalBorderWidth",
4869 RES_TYPE_NUMBER);
4871 /* Also do the stuff which must be set before the window exists. */
4872 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
4873 "foreground", "Foreground", RES_TYPE_STRING);
4874 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
4875 "background", "Background", RES_TYPE_STRING);
4876 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
4877 "pointerColor", "Foreground", RES_TYPE_STRING);
4878 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
4879 "cursorColor", "Foreground", RES_TYPE_STRING);
4880 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
4881 "borderColor", "BorderColor", RES_TYPE_STRING);
4883 /* Init faces before x_default_parameter is called for scroll-bar
4884 parameters because that function calls x_set_scroll_bar_width,
4885 which calls change_frame_size, which calls Fset_window_buffer,
4886 which runs hooks, which call Fvertical_motion. At the end, we
4887 end up in init_iterator with a null face cache, which should not
4888 happen. */
4889 init_frame_faces (f);
4891 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
4893 window_prompting = x_figure_window_size (f, parms, 0);
4896 XSetWindowAttributes attrs;
4897 unsigned long mask;
4898 Atom type = FRAME_X_DISPLAY_INFO (f)->Xatom_net_window_type_tooltip;
4900 BLOCK_INPUT;
4901 mask = CWBackPixel | CWOverrideRedirect | CWEventMask;
4902 if (DoesSaveUnders (dpyinfo->screen))
4903 mask |= CWSaveUnder;
4905 /* Window managers look at the override-redirect flag to determine
4906 whether or net to give windows a decoration (Xlib spec, chapter
4907 3.2.8). */
4908 attrs.override_redirect = True;
4909 attrs.save_under = True;
4910 attrs.background_pixel = FRAME_BACKGROUND_PIXEL (f);
4911 /* Arrange for getting MapNotify and UnmapNotify events. */
4912 attrs.event_mask = StructureNotifyMask;
4913 tip_window
4914 = FRAME_X_WINDOW (f)
4915 = XCreateWindow (FRAME_X_DISPLAY (f),
4916 FRAME_X_DISPLAY_INFO (f)->root_window,
4917 /* x, y, width, height */
4918 0, 0, 1, 1,
4919 /* Border. */
4920 f->border_width,
4921 CopyFromParent, InputOutput, CopyFromParent,
4922 mask, &attrs);
4923 XChangeProperty (FRAME_X_DISPLAY (f), tip_window,
4924 FRAME_X_DISPLAY_INFO (f)->Xatom_net_window_type,
4925 XA_ATOM, 32, PropModeReplace,
4926 (unsigned char *)&type, 1);
4927 UNBLOCK_INPUT;
4930 x_make_gc (f);
4932 x_default_parameter (f, parms, Qauto_raise, Qnil,
4933 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
4934 x_default_parameter (f, parms, Qauto_lower, Qnil,
4935 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
4936 x_default_parameter (f, parms, Qcursor_type, Qbox,
4937 "cursorType", "CursorType", RES_TYPE_SYMBOL);
4939 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
4940 Change will not be effected unless different from the current
4941 FRAME_LINES (f). */
4942 width = FRAME_COLS (f);
4943 height = FRAME_LINES (f);
4944 SET_FRAME_COLS (f, 0);
4945 FRAME_LINES (f) = 0;
4946 change_frame_size (f, height, width, 1, 0, 0);
4948 /* Add `tooltip' frame parameter's default value. */
4949 if (NILP (Fframe_parameter (frame, intern ("tooltip"))))
4950 Fmodify_frame_parameters (frame, Fcons (Fcons (intern ("tooltip"), Qt),
4951 Qnil));
4953 /* FIXME - can this be done in a similar way to normal frames?
4954 http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
4956 /* Set the `display-type' frame parameter before setting up faces. */
4958 Lisp_Object disptype;
4960 if (FRAME_X_DISPLAY_INFO (f)->n_planes == 1)
4961 disptype = intern ("mono");
4962 else if (FRAME_X_DISPLAY_INFO (f)->visual->class == GrayScale
4963 || FRAME_X_DISPLAY_INFO (f)->visual->class == StaticGray)
4964 disptype = intern ("grayscale");
4965 else
4966 disptype = intern ("color");
4968 if (NILP (Fframe_parameter (frame, Qdisplay_type)))
4969 Fmodify_frame_parameters (frame, Fcons (Fcons (Qdisplay_type, disptype),
4970 Qnil));
4973 /* Set up faces after all frame parameters are known. This call
4974 also merges in face attributes specified for new frames.
4976 Frame parameters may be changed if .Xdefaults contains
4977 specifications for the default font. For example, if there is an
4978 `Emacs.default.attributeBackground: pink', the `background-color'
4979 attribute of the frame get's set, which let's the internal border
4980 of the tooltip frame appear in pink. Prevent this. */
4982 Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
4984 /* Set tip_frame here, so that */
4985 tip_frame = frame;
4986 call2 (Qface_set_after_frame_default, frame, Qnil);
4988 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
4989 Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg),
4990 Qnil));
4993 f->no_split = 1;
4995 UNGCPRO;
4997 /* It is now ok to make the frame official even if we get an error
4998 below. And the frame needs to be on Vframe_list or making it
4999 visible won't work. */
5000 Vframe_list = Fcons (frame, Vframe_list);
5002 /* Now that the frame is official, it counts as a reference to
5003 its display. */
5004 FRAME_X_DISPLAY_INFO (f)->reference_count++;
5006 /* Setting attributes of faces of the tooltip frame from resources
5007 and similar will increment face_change_count, which leads to the
5008 clearing of all current matrices. Since this isn't necessary
5009 here, avoid it by resetting face_change_count to the value it
5010 had before we created the tip frame. */
5011 face_change_count = face_change_count_before;
5013 /* Discard the unwind_protect. */
5014 return unbind_to (count, frame);
5018 /* Compute where to display tip frame F. PARMS is the list of frame
5019 parameters for F. DX and DY are specified offsets from the current
5020 location of the mouse. WIDTH and HEIGHT are the width and height
5021 of the tooltip. Return coordinates relative to the root window of
5022 the display in *ROOT_X, and *ROOT_Y. */
5024 static void
5025 compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
5026 struct frame *f;
5027 Lisp_Object parms, dx, dy;
5028 int width, height;
5029 int *root_x, *root_y;
5031 Lisp_Object left, top;
5032 int win_x, win_y;
5033 Window root, child;
5034 unsigned pmask;
5036 /* User-specified position? */
5037 left = Fcdr (Fassq (Qleft, parms));
5038 top = Fcdr (Fassq (Qtop, parms));
5040 /* Move the tooltip window where the mouse pointer is. Resize and
5041 show it. */
5042 if (!INTEGERP (left) || !INTEGERP (top))
5044 BLOCK_INPUT;
5045 XQueryPointer (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
5046 &root, &child, root_x, root_y, &win_x, &win_y, &pmask);
5047 UNBLOCK_INPUT;
5050 if (INTEGERP (top))
5051 *root_y = XINT (top);
5052 else if (*root_y + XINT (dy) <= 0)
5053 *root_y = 0; /* Can happen for negative dy */
5054 else if (*root_y + XINT (dy) + height
5055 <= x_display_pixel_height (FRAME_X_DISPLAY_INFO (f)))
5056 /* It fits below the pointer */
5057 *root_y += XINT (dy);
5058 else if (height + XINT (dy) <= *root_y)
5059 /* It fits above the pointer. */
5060 *root_y -= height + XINT (dy);
5061 else
5062 /* Put it on the top. */
5063 *root_y = 0;
5065 if (INTEGERP (left))
5066 *root_x = XINT (left);
5067 else if (*root_x + XINT (dx) <= 0)
5068 *root_x = 0; /* Can happen for negative dx */
5069 else if (*root_x + XINT (dx) + width
5070 <= x_display_pixel_width (FRAME_X_DISPLAY_INFO (f)))
5071 /* It fits to the right of the pointer. */
5072 *root_x += XINT (dx);
5073 else if (width + XINT (dx) <= *root_x)
5074 /* It fits to the left of the pointer. */
5075 *root_x -= width + XINT (dx);
5076 else
5077 /* Put it left-justified on the screen--it ought to fit that way. */
5078 *root_x = 0;
5082 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
5083 doc: /* Show STRING in a "tooltip" window on frame FRAME.
5084 A tooltip window is a small X window displaying a string.
5086 This is an internal function; Lisp code should call `tooltip-show'.
5088 FRAME nil or omitted means use the selected frame.
5090 PARMS is an optional list of frame parameters which can be used to
5091 change the tooltip's appearance.
5093 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
5094 means use the default timeout of 5 seconds.
5096 If the list of frame parameters PARAMS contains a `left' parameters,
5097 the tooltip is displayed at that x-position. Otherwise it is
5098 displayed at the mouse position, with offset DX added (default is 5 if
5099 DX isn't specified). Likewise for the y-position; if a `top' frame
5100 parameter is specified, it determines the y-position of the tooltip
5101 window, otherwise it is displayed at the mouse position, with offset
5102 DY added (default is -10).
5104 A tooltip's maximum size is specified by `x-max-tooltip-size'.
5105 Text larger than the specified size is clipped. */)
5106 (string, frame, parms, timeout, dx, dy)
5107 Lisp_Object string, frame, parms, timeout, dx, dy;
5109 struct frame *f;
5110 struct window *w;
5111 int root_x, root_y;
5112 struct buffer *old_buffer;
5113 struct text_pos pos;
5114 int i, width, height;
5115 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
5116 int old_windows_or_buffers_changed = windows_or_buffers_changed;
5117 int count = SPECPDL_INDEX ();
5119 specbind (Qinhibit_redisplay, Qt);
5121 GCPRO4 (string, parms, frame, timeout);
5123 CHECK_STRING (string);
5124 if (SCHARS (string) == 0)
5125 string = make_unibyte_string (" ", 1);
5127 f = check_x_frame (frame);
5128 if (NILP (timeout))
5129 timeout = make_number (5);
5130 else
5131 CHECK_NATNUM (timeout);
5133 if (NILP (dx))
5134 dx = make_number (5);
5135 else
5136 CHECK_NUMBER (dx);
5138 if (NILP (dy))
5139 dy = make_number (-10);
5140 else
5141 CHECK_NUMBER (dy);
5143 if (NILP (last_show_tip_args))
5144 last_show_tip_args = Fmake_vector (make_number (3), Qnil);
5146 if (!NILP (tip_frame))
5148 Lisp_Object last_string = AREF (last_show_tip_args, 0);
5149 Lisp_Object last_frame = AREF (last_show_tip_args, 1);
5150 Lisp_Object last_parms = AREF (last_show_tip_args, 2);
5152 if (EQ (frame, last_frame)
5153 && !NILP (Fequal (last_string, string))
5154 && !NILP (Fequal (last_parms, parms)))
5156 struct frame *f = XFRAME (tip_frame);
5158 /* Only DX and DY have changed. */
5159 if (!NILP (tip_timer))
5161 Lisp_Object timer = tip_timer;
5162 tip_timer = Qnil;
5163 call1 (Qcancel_timer, timer);
5166 BLOCK_INPUT;
5167 compute_tip_xy (f, parms, dx, dy, FRAME_PIXEL_WIDTH (f),
5168 FRAME_PIXEL_HEIGHT (f), &root_x, &root_y);
5169 XMoveWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5170 root_x, root_y);
5171 UNBLOCK_INPUT;
5172 goto start_timer;
5176 /* Hide a previous tip, if any. */
5177 Fx_hide_tip ();
5179 ASET (last_show_tip_args, 0, string);
5180 ASET (last_show_tip_args, 1, frame);
5181 ASET (last_show_tip_args, 2, parms);
5183 /* Add default values to frame parameters. */
5184 if (NILP (Fassq (Qname, parms)))
5185 parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
5186 if (NILP (Fassq (Qinternal_border_width, parms)))
5187 parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
5188 if (NILP (Fassq (Qborder_width, parms)))
5189 parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
5190 if (NILP (Fassq (Qborder_color, parms)))
5191 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
5192 if (NILP (Fassq (Qbackground_color, parms)))
5193 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
5194 parms);
5196 /* Create a frame for the tooltip, and record it in the global
5197 variable tip_frame. */
5198 frame = x_create_tip_frame (FRAME_X_DISPLAY_INFO (f), parms, string);
5199 f = XFRAME (frame);
5201 /* Set up the frame's root window. */
5202 w = XWINDOW (FRAME_ROOT_WINDOW (f));
5203 w->left_col = w->top_line = make_number (0);
5205 if (CONSP (Vx_max_tooltip_size)
5206 && INTEGERP (XCAR (Vx_max_tooltip_size))
5207 && XINT (XCAR (Vx_max_tooltip_size)) > 0
5208 && INTEGERP (XCDR (Vx_max_tooltip_size))
5209 && XINT (XCDR (Vx_max_tooltip_size)) > 0)
5211 w->total_cols = XCAR (Vx_max_tooltip_size);
5212 w->total_lines = XCDR (Vx_max_tooltip_size);
5214 else
5216 w->total_cols = make_number (80);
5217 w->total_lines = make_number (40);
5220 FRAME_TOTAL_COLS (f) = XINT (w->total_cols);
5221 adjust_glyphs (f);
5222 w->pseudo_window_p = 1;
5224 /* Display the tooltip text in a temporary buffer. */
5225 old_buffer = current_buffer;
5226 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer));
5227 current_buffer->truncate_lines = Qnil;
5228 clear_glyph_matrix (w->desired_matrix);
5229 clear_glyph_matrix (w->current_matrix);
5230 SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
5231 try_window (FRAME_ROOT_WINDOW (f), pos, TRY_WINDOW_IGNORE_FONTS_CHANGE);
5233 /* Compute width and height of the tooltip. */
5234 width = height = 0;
5235 for (i = 0; i < w->desired_matrix->nrows; ++i)
5237 struct glyph_row *row = &w->desired_matrix->rows[i];
5238 struct glyph *last;
5239 int row_width;
5241 /* Stop at the first empty row at the end. */
5242 if (!row->enabled_p || !row->displays_text_p)
5243 break;
5245 /* Let the row go over the full width of the frame. */
5246 row->full_width_p = 1;
5248 row_width = row->pixel_width;
5249 /* There's a glyph at the end of rows that is used to place
5250 the cursor there. Don't include the width of this glyph. */
5251 if (row->used[TEXT_AREA])
5253 last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
5254 if (INTEGERP (last->object))
5255 row_width -= last->pixel_width;
5258 height += row->height;
5259 width = max (width, row_width);
5262 /* Add the frame's internal border to the width and height the X
5263 window should have. */
5264 height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5265 width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5267 /* Move the tooltip window where the mouse pointer is. Resize and
5268 show it. */
5269 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
5271 BLOCK_INPUT;
5272 XMoveResizeWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5273 root_x, root_y, width, height);
5274 XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
5275 UNBLOCK_INPUT;
5277 /* Draw into the window. */
5278 w->must_be_updated_p = 1;
5279 update_single_window (w, 1);
5281 /* Restore original current buffer. */
5282 set_buffer_internal_1 (old_buffer);
5283 windows_or_buffers_changed = old_windows_or_buffers_changed;
5285 start_timer:
5286 /* Let the tip disappear after timeout seconds. */
5287 tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
5288 intern ("x-hide-tip"));
5290 UNGCPRO;
5291 return unbind_to (count, Qnil);
5295 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
5296 doc: /* Hide the current tooltip window, if there is any.
5297 Value is t if tooltip was open, nil otherwise. */)
5300 int count;
5301 Lisp_Object deleted, frame, timer;
5302 struct gcpro gcpro1, gcpro2;
5304 /* Return quickly if nothing to do. */
5305 if (NILP (tip_timer) && NILP (tip_frame))
5306 return Qnil;
5308 frame = tip_frame;
5309 timer = tip_timer;
5310 GCPRO2 (frame, timer);
5311 tip_frame = tip_timer = deleted = Qnil;
5313 count = SPECPDL_INDEX ();
5314 specbind (Qinhibit_redisplay, Qt);
5315 specbind (Qinhibit_quit, Qt);
5317 if (!NILP (timer))
5318 call1 (Qcancel_timer, timer);
5320 if (FRAMEP (frame))
5322 delete_frame (frame, Qnil);
5323 deleted = Qt;
5325 #ifdef USE_LUCID
5326 /* Bloodcurdling hack alert: The Lucid menu bar widget's
5327 redisplay procedure is not called when a tip frame over menu
5328 items is unmapped. Redisplay the menu manually... */
5330 struct frame *f = SELECTED_FRAME ();
5331 Widget w = f->output_data.x->menubar_widget;
5332 extern void xlwmenu_redisplay P_ ((Widget));
5334 if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f)->screen)
5335 && w != NULL)
5337 BLOCK_INPUT;
5338 xlwmenu_redisplay (w);
5339 UNBLOCK_INPUT;
5342 #endif /* USE_LUCID */
5345 UNGCPRO;
5346 return unbind_to (count, deleted);
5351 /***********************************************************************
5352 File selection dialog
5353 ***********************************************************************/
5355 DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog,
5356 Sx_uses_old_gtk_dialog,
5357 0, 0, 0,
5358 doc: /* Return t if the old Gtk+ file selection dialog is used. */)
5361 #ifdef USE_GTK
5362 extern int use_dialog_box;
5363 extern int use_file_dialog;
5365 if (use_dialog_box
5366 && use_file_dialog
5367 && have_menus_p ()
5368 && xg_uses_old_file_dialog ())
5369 return Qt;
5370 #endif
5371 return Qnil;
5375 #ifdef USE_MOTIF
5376 /* Callback for "OK" and "Cancel" on file selection dialog. */
5378 static void
5379 file_dialog_cb (widget, client_data, call_data)
5380 Widget widget;
5381 XtPointer call_data, client_data;
5383 int *result = (int *) client_data;
5384 XmAnyCallbackStruct *cb = (XmAnyCallbackStruct *) call_data;
5385 *result = cb->reason;
5389 /* Callback for unmapping a file selection dialog. This is used to
5390 capture the case where a dialog is closed via a window manager's
5391 closer button, for example. Using a XmNdestroyCallback didn't work
5392 in this case. */
5394 static void
5395 file_dialog_unmap_cb (widget, client_data, call_data)
5396 Widget widget;
5397 XtPointer call_data, client_data;
5399 int *result = (int *) client_data;
5400 *result = XmCR_CANCEL;
5403 static Lisp_Object
5404 clean_up_file_dialog (arg)
5405 Lisp_Object arg;
5407 struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
5408 Widget dialog = (Widget) p->pointer;
5410 /* Clean up. */
5411 BLOCK_INPUT;
5412 XtUnmanageChild (dialog);
5413 XtDestroyWidget (dialog);
5414 x_menu_set_in_use (0);
5415 UNBLOCK_INPUT;
5417 return Qnil;
5421 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5422 doc: /* Read file name, prompting with PROMPT in directory DIR.
5423 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5424 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5425 or directory must exist. ONLY-DIR-P is ignored." */)
5426 (prompt, dir, default_filename, mustmatch, only_dir_p)
5427 Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
5429 int result;
5430 struct frame *f = SELECTED_FRAME ();
5431 Lisp_Object file = Qnil;
5432 Lisp_Object decoded_file;
5433 Widget dialog, text, help;
5434 Arg al[10];
5435 int ac = 0;
5436 extern XtAppContext Xt_app_con;
5437 XmString dir_xmstring, pattern_xmstring;
5438 int count = SPECPDL_INDEX ();
5439 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5441 check_x ();
5443 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5445 if (popup_activated ())
5446 error ("Trying to use a menu from within a menu-entry");
5448 CHECK_STRING (prompt);
5449 CHECK_STRING (dir);
5451 /* Prevent redisplay. */
5452 specbind (Qinhibit_redisplay, Qt);
5454 BLOCK_INPUT;
5456 /* Create the dialog with PROMPT as title, using DIR as initial
5457 directory and using "*" as pattern. */
5458 dir = Fexpand_file_name (dir, Qnil);
5459 dir_xmstring = XmStringCreateLocalized (SDATA (dir));
5460 pattern_xmstring = XmStringCreateLocalized ("*");
5462 XtSetArg (al[ac], XmNtitle, SDATA (prompt)); ++ac;
5463 XtSetArg (al[ac], XmNdirectory, dir_xmstring); ++ac;
5464 XtSetArg (al[ac], XmNpattern, pattern_xmstring); ++ac;
5465 XtSetArg (al[ac], XmNresizePolicy, XmRESIZE_GROW); ++ac;
5466 XtSetArg (al[ac], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); ++ac;
5467 dialog = XmCreateFileSelectionDialog (f->output_data.x->widget,
5468 "fsb", al, ac);
5469 XmStringFree (dir_xmstring);
5470 XmStringFree (pattern_xmstring);
5472 /* Add callbacks for OK and Cancel. */
5473 XtAddCallback (dialog, XmNokCallback, file_dialog_cb,
5474 (XtPointer) &result);
5475 XtAddCallback (dialog, XmNcancelCallback, file_dialog_cb,
5476 (XtPointer) &result);
5477 XtAddCallback (dialog, XmNunmapCallback, file_dialog_unmap_cb,
5478 (XtPointer) &result);
5480 /* Remove the help button since we can't display help. */
5481 help = XmFileSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON);
5482 XtUnmanageChild (help);
5484 /* Mark OK button as default. */
5485 XtVaSetValues (XmFileSelectionBoxGetChild (dialog, XmDIALOG_OK_BUTTON),
5486 XmNshowAsDefault, True, NULL);
5488 /* If MUSTMATCH is non-nil, disable the file entry field of the
5489 dialog, so that the user must select a file from the files list
5490 box. We can't remove it because we wouldn't have a way to get at
5491 the result file name, then. */
5492 text = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5493 if (!NILP (mustmatch))
5495 Widget label;
5496 label = XmFileSelectionBoxGetChild (dialog, XmDIALOG_SELECTION_LABEL);
5497 XtSetSensitive (text, False);
5498 XtSetSensitive (label, False);
5501 /* Manage the dialog, so that list boxes get filled. */
5502 XtManageChild (dialog);
5504 if (STRINGP (default_filename))
5506 XmString default_xmstring;
5507 Widget wtext = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5508 Widget list = XmFileSelectionBoxGetChild (dialog, XmDIALOG_LIST);
5510 XmTextPosition last_pos = XmTextFieldGetLastPosition (wtext);
5511 XmTextFieldReplace (wtext, 0, last_pos,
5512 (SDATA (Ffile_name_nondirectory (default_filename))));
5514 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
5515 must include the path for this to work. */
5517 default_xmstring = XmStringCreateLocalized (SDATA (default_filename));
5519 if (XmListItemExists (list, default_xmstring))
5521 int item_pos = XmListItemPos (list, default_xmstring);
5522 /* Select the item and scroll it into view. */
5523 XmListSelectPos (list, item_pos, True);
5524 XmListSetPos (list, item_pos);
5527 XmStringFree (default_xmstring);
5530 record_unwind_protect (clean_up_file_dialog, make_save_value (dialog, 0));
5532 /* Process events until the user presses Cancel or OK. */
5533 x_menu_set_in_use (1);
5534 result = 0;
5535 while (result == 0)
5537 XEvent event;
5538 x_menu_wait_for_event (0);
5539 XtAppNextEvent (Xt_app_con, &event);
5540 if (event.type == KeyPress
5541 && FRAME_X_DISPLAY (f) == event.xkey.display)
5543 KeySym keysym = XLookupKeysym (&event.xkey, 0);
5545 /* Pop down on C-g. */
5546 if (keysym == XK_g && (event.xkey.state & ControlMask) != 0)
5547 XtUnmanageChild (dialog);
5550 (void) x_dispatch_event (&event, FRAME_X_DISPLAY (f));
5553 /* Get the result. */
5554 if (result == XmCR_OK)
5556 XmString text;
5557 String data;
5559 XtVaGetValues (dialog, XmNtextString, &text, NULL);
5560 XmStringGetLtoR (text, XmFONTLIST_DEFAULT_TAG, &data);
5561 XmStringFree (text);
5562 file = build_string (data);
5563 XtFree (data);
5565 else
5566 file = Qnil;
5568 UNBLOCK_INPUT;
5569 UNGCPRO;
5571 /* Make "Cancel" equivalent to C-g. */
5572 if (NILP (file))
5573 Fsignal (Qquit, Qnil);
5575 decoded_file = DECODE_FILE (file);
5577 return unbind_to (count, decoded_file);
5580 #endif /* USE_MOTIF */
5582 #ifdef USE_GTK
5584 static Lisp_Object
5585 clean_up_dialog (arg)
5586 Lisp_Object arg;
5588 x_menu_set_in_use (0);
5590 return Qnil;
5593 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5594 doc: /* Read file name, prompting with PROMPT in directory DIR.
5595 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5596 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5597 or directory must exist. If ONLY-DIR-P is non-nil, the user can only select
5598 directories. */)
5599 (prompt, dir, default_filename, mustmatch, only_dir_p)
5600 Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
5602 FRAME_PTR f = SELECTED_FRAME ();
5603 char *fn;
5604 Lisp_Object file = Qnil;
5605 Lisp_Object decoded_file;
5606 int count = SPECPDL_INDEX ();
5607 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5608 char *cdef_file;
5610 check_x ();
5612 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5614 if (popup_activated ())
5615 error ("Trying to use a menu from within a menu-entry");
5617 CHECK_STRING (prompt);
5618 CHECK_STRING (dir);
5620 /* Prevent redisplay. */
5621 specbind (Qinhibit_redisplay, Qt);
5622 record_unwind_protect (clean_up_dialog, Qnil);
5624 BLOCK_INPUT;
5626 if (STRINGP (default_filename))
5627 cdef_file = SDATA (default_filename);
5628 else
5629 cdef_file = SDATA (dir);
5631 fn = xg_get_file_name (f, SDATA (prompt), cdef_file,
5632 ! NILP (mustmatch),
5633 ! NILP (only_dir_p));
5635 if (fn)
5637 file = build_string (fn);
5638 xfree (fn);
5641 UNBLOCK_INPUT;
5642 UNGCPRO;
5644 /* Make "Cancel" equivalent to C-g. */
5645 if (NILP (file))
5646 Fsignal (Qquit, Qnil);
5648 decoded_file = DECODE_FILE (file);
5650 return unbind_to (count, decoded_file);
5654 #ifdef HAVE_FREETYPE
5656 DEFUN ("x-select-font", Fx_select_font, Sx_select_font, 0, 2, 0,
5657 doc: /* Read a font name using a GTK font selection dialog.
5658 Return a GTK-style font string corresponding to the selection.
5660 If FRAME is omitted or nil, it defaults to the selected frame. */)
5661 (frame, ignored)
5662 Lisp_Object frame, ignored;
5664 FRAME_PTR f = check_x_frame (frame);
5665 char *name;
5666 Lisp_Object font;
5667 Lisp_Object font_param;
5668 char *default_name = NULL;
5669 struct gcpro gcpro1, gcpro2;
5670 int count = SPECPDL_INDEX ();
5672 check_x ();
5674 if (popup_activated ())
5675 error ("Trying to use a menu from within a menu-entry");
5677 /* Prevent redisplay. */
5678 specbind (Qinhibit_redisplay, Qt);
5679 record_unwind_protect (clean_up_dialog, Qnil);
5681 BLOCK_INPUT;
5683 GCPRO2(font_param, font);
5685 XSETFONT (font, FRAME_FONT (f));
5686 font_param = Ffont_get (font, intern (":name"));
5687 if (STRINGP (font_param))
5688 default_name = xstrdup (SDATA (font_param));
5689 else
5691 font_param = Fframe_parameter (frame, Qfont_param);
5692 if (STRINGP (font_param))
5693 default_name = xstrdup (SDATA (font_param));
5696 if (default_name == NULL && x_last_font_name != NULL)
5697 default_name = xstrdup (x_last_font_name);
5699 /* Convert fontconfig names to Gtk names, i.e. remove - before number */
5700 if (default_name)
5702 char *p = strrchr (default_name, '-');
5703 if (p)
5705 char *ep = p+1;
5706 while (isdigit (*ep))
5707 ++ep;
5708 if (*ep == '\0') *p = ' ';
5712 name = xg_get_font_name (f, default_name);
5713 xfree (default_name);
5715 if (name)
5717 font = build_string (name);
5718 g_free (x_last_font_name);
5719 x_last_font_name = name;
5722 UNBLOCK_INPUT;
5724 if (NILP (font))
5725 Fsignal (Qquit, Qnil);
5727 return unbind_to (count, font);
5729 #endif /* HAVE_FREETYPE */
5731 #endif /* USE_GTK */
5734 /***********************************************************************
5735 Keyboard
5736 ***********************************************************************/
5738 #ifdef HAVE_XKBGETKEYBOARD
5739 #include <X11/XKBlib.h>
5740 #include <X11/keysym.h>
5741 #endif
5743 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p,
5744 Sx_backspace_delete_keys_p, 0, 1, 0,
5745 doc: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
5746 FRAME nil means use the selected frame.
5747 Value is t if we know that both keys are present, and are mapped to the
5748 usual X keysyms. Value is `lambda' if we cannot determine if both keys are
5749 present and mapped to the usual X keysyms. */)
5750 (frame)
5751 Lisp_Object frame;
5753 #ifdef HAVE_XKBGETKEYBOARD
5754 XkbDescPtr kb;
5755 struct frame *f = check_x_frame (frame);
5756 Display *dpy = FRAME_X_DISPLAY (f);
5757 Lisp_Object have_keys;
5758 int major, minor, op, event, error;
5760 BLOCK_INPUT;
5762 /* Check library version in case we're dynamically linked. */
5763 major = XkbMajorVersion;
5764 minor = XkbMinorVersion;
5765 if (!XkbLibraryVersion (&major, &minor))
5767 UNBLOCK_INPUT;
5768 return Qlambda;
5771 /* Check that the server supports XKB. */
5772 major = XkbMajorVersion;
5773 minor = XkbMinorVersion;
5774 if (!XkbQueryExtension (dpy, &op, &event, &error, &major, &minor))
5776 UNBLOCK_INPUT;
5777 return Qlambda;
5780 /* In this code we check that the keyboard has physical keys with names
5781 that start with BKSP (Backspace) and DELE (Delete), and that they
5782 generate keysym XK_BackSpace and XK_Delete respectively.
5783 This function is used to test if normal-erase-is-backspace should be
5784 turned on.
5785 An alternative approach would be to just check if XK_BackSpace and
5786 XK_Delete are mapped to any key. But if any of those are mapped to
5787 some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the
5788 user doesn't know about it, it is better to return false here.
5789 It is more obvious to the user what to do if she/he has two keys
5790 clearly marked with names/symbols and one key does something not
5791 expected (i.e. she/he then tries the other).
5792 The cases where Backspace/Delete is mapped to some other key combination
5793 are rare, and in those cases, normal-erase-is-backspace can be turned on
5794 manually. */
5796 have_keys = Qnil;
5797 kb = XkbGetMap (dpy, XkbAllMapComponentsMask, XkbUseCoreKbd);
5798 if (kb)
5800 int delete_keycode = 0, backspace_keycode = 0, i;
5802 if (XkbGetNames (dpy, XkbAllNamesMask, kb) == Success)
5804 for (i = kb->min_key_code;
5805 (i < kb->max_key_code
5806 && (delete_keycode == 0 || backspace_keycode == 0));
5807 ++i)
5809 /* The XKB symbolic key names can be seen most easily in
5810 the PS file generated by `xkbprint -label name
5811 $DISPLAY'. */
5812 if (bcmp ("DELE", kb->names->keys[i].name, 4) == 0)
5813 delete_keycode = i;
5814 else if (bcmp ("BKSP", kb->names->keys[i].name, 4) == 0)
5815 backspace_keycode = i;
5818 XkbFreeNames (kb, 0, True);
5821 XkbFreeClientMap (kb, 0, True);
5823 if (delete_keycode
5824 && backspace_keycode
5825 && XKeysymToKeycode (dpy, XK_Delete) == delete_keycode
5826 && XKeysymToKeycode (dpy, XK_BackSpace) == backspace_keycode)
5827 have_keys = Qt;
5829 UNBLOCK_INPUT;
5830 return have_keys;
5831 #else /* not HAVE_XKBGETKEYBOARD */
5832 return Qlambda;
5833 #endif /* not HAVE_XKBGETKEYBOARD */
5838 /***********************************************************************
5839 Initialization
5840 ***********************************************************************/
5842 /* Keep this list in the same order as frame_parms in frame.c.
5843 Use 0 for unsupported frame parameters. */
5845 frame_parm_handler x_frame_parm_handlers[] =
5847 x_set_autoraise,
5848 x_set_autolower,
5849 x_set_background_color,
5850 x_set_border_color,
5851 x_set_border_width,
5852 x_set_cursor_color,
5853 x_set_cursor_type,
5854 x_set_font,
5855 x_set_foreground_color,
5856 x_set_icon_name,
5857 x_set_icon_type,
5858 x_set_internal_border_width,
5859 x_set_menu_bar_lines,
5860 x_set_mouse_color,
5861 x_explicitly_set_name,
5862 x_set_scroll_bar_width,
5863 x_set_title,
5864 x_set_unsplittable,
5865 x_set_vertical_scroll_bars,
5866 x_set_visibility,
5867 x_set_tool_bar_lines,
5868 x_set_scroll_bar_foreground,
5869 x_set_scroll_bar_background,
5870 x_set_screen_gamma,
5871 x_set_line_spacing,
5872 x_set_fringe_width,
5873 x_set_fringe_width,
5874 x_set_wait_for_wm,
5875 x_set_fullscreen,
5876 x_set_font_backend,
5877 x_set_alpha,
5878 x_set_sticky,
5881 void
5882 syms_of_xfns ()
5884 /* This is zero if not using X windows. */
5885 x_in_use = 0;
5887 /* The section below is built by the lisp expression at the top of the file,
5888 just above where these variables are declared. */
5889 /*&&& init symbols here &&&*/
5890 Qnone = intern_c_string ("none");
5891 staticpro (&Qnone);
5892 Qsuppress_icon = intern_c_string ("suppress-icon");
5893 staticpro (&Qsuppress_icon);
5894 Qundefined_color = intern_c_string ("undefined-color");
5895 staticpro (&Qundefined_color);
5896 Qcompound_text = intern_c_string ("compound-text");
5897 staticpro (&Qcompound_text);
5898 Qcancel_timer = intern_c_string ("cancel-timer");
5899 staticpro (&Qcancel_timer);
5900 Qfont_param = intern_c_string ("font-parameter");
5901 staticpro (&Qfont_param);
5902 /* This is the end of symbol initialization. */
5904 /* Text property `display' should be nonsticky by default. */
5905 Vtext_property_default_nonsticky
5906 = Fcons (Fcons (Qdisplay, Qt), Vtext_property_default_nonsticky);
5909 Fput (Qundefined_color, Qerror_conditions,
5910 pure_cons (Qundefined_color, pure_cons (Qerror, Qnil)));
5911 Fput (Qundefined_color, Qerror_message,
5912 make_pure_c_string ("Undefined color"));
5914 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
5915 doc: /* The shape of the pointer when over text.
5916 Changing the value does not affect existing frames
5917 unless you set the mouse color. */);
5918 Vx_pointer_shape = Qnil;
5920 #if 0 /* This doesn't really do anything. */
5921 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape,
5922 doc: /* The shape of the pointer when not over text.
5923 This variable takes effect when you create a new frame
5924 or when you set the mouse color. */);
5925 #endif
5926 Vx_nontext_pointer_shape = Qnil;
5928 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape,
5929 doc: /* The shape of the pointer when Emacs is busy.
5930 This variable takes effect when you create a new frame
5931 or when you set the mouse color. */);
5932 Vx_hourglass_pointer_shape = Qnil;
5934 #if 0 /* This doesn't really do anything. */
5935 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape,
5936 doc: /* The shape of the pointer when over the mode line.
5937 This variable takes effect when you create a new frame
5938 or when you set the mouse color. */);
5939 #endif
5940 Vx_mode_pointer_shape = Qnil;
5942 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
5943 &Vx_sensitive_text_pointer_shape,
5944 doc: /* The shape of the pointer when over mouse-sensitive text.
5945 This variable takes effect when you create a new frame
5946 or when you set the mouse color. */);
5947 Vx_sensitive_text_pointer_shape = Qnil;
5949 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
5950 &Vx_window_horizontal_drag_shape,
5951 doc: /* Pointer shape to use for indicating a window can be dragged horizontally.
5952 This variable takes effect when you create a new frame
5953 or when you set the mouse color. */);
5954 Vx_window_horizontal_drag_shape = Qnil;
5956 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel,
5957 doc: /* A string indicating the foreground color of the cursor box. */);
5958 Vx_cursor_fore_pixel = Qnil;
5960 DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size,
5961 doc: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).
5962 Text larger than this is clipped. */);
5963 Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
5965 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
5966 doc: /* Non-nil if no X window manager is in use.
5967 Emacs doesn't try to figure this out; this is always nil
5968 unless you set it to something else. */);
5969 /* We don't have any way to find this out, so set it to nil
5970 and maybe the user would like to set it to t. */
5971 Vx_no_window_manager = Qnil;
5973 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
5974 &Vx_pixel_size_width_font_regexp,
5975 doc: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
5977 Since Emacs gets width of a font matching with this regexp from
5978 PIXEL_SIZE field of the name, font finding mechanism gets faster for
5979 such a font. This is especially effective for such large fonts as
5980 Chinese, Japanese, and Korean. */);
5981 Vx_pixel_size_width_font_regexp = Qnil;
5983 /* This is not ifdef:ed, so other builds than GTK can customize it. */
5984 DEFVAR_BOOL ("x-gtk-use-old-file-dialog", &x_gtk_use_old_file_dialog,
5985 doc: /* *Non-nil means prompt with the old GTK file selection dialog.
5986 If nil or if the file selection dialog is not available, the new GTK file
5987 chooser is used instead. To turn off all file dialogs set the
5988 variable `use-file-dialog'. */);
5989 x_gtk_use_old_file_dialog = 0;
5991 DEFVAR_BOOL ("x-gtk-show-hidden-files", &x_gtk_show_hidden_files,
5992 doc: /* *If non-nil, the GTK file chooser will by default show hidden files.
5993 Note that this is just the default, there is a toggle button on the file
5994 chooser to show or not show hidden files on a case by case basis. */);
5995 x_gtk_show_hidden_files = 0;
5997 DEFVAR_BOOL ("x-gtk-file-dialog-help-text", &x_gtk_file_dialog_help_text,
5998 doc: /* *If non-nil, the GTK file chooser will show additional help text.
5999 If more space for files in the file chooser dialog is wanted, set this to nil
6000 to turn the additional text off. */);
6001 x_gtk_file_dialog_help_text = 1;
6003 DEFVAR_BOOL ("x-gtk-whole-detached-tool-bar", &x_gtk_whole_detached_tool_bar,
6004 doc: /* *If non-nil, a detached tool bar is shown in full.
6005 The default is to just show an arrow and pressing on that arrow shows
6006 the tool bar buttons. */);
6007 x_gtk_whole_detached_tool_bar = 0;
6009 Fprovide (intern_c_string ("x"), Qnil);
6011 #ifdef USE_X_TOOLKIT
6012 Fprovide (intern_c_string ("x-toolkit"), Qnil);
6013 #ifdef USE_MOTIF
6014 Fprovide (intern_c_string ("motif"), Qnil);
6016 DEFVAR_LISP ("motif-version-string", &Vmotif_version_string,
6017 doc: /* Version info for LessTif/Motif. */);
6018 Vmotif_version_string = build_string (XmVERSION_STRING);
6019 #endif /* USE_MOTIF */
6020 #endif /* USE_X_TOOLKIT */
6022 #ifdef USE_GTK
6023 /* Provide x-toolkit also for GTK. Internally GTK does not use Xt so it
6024 is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
6025 But for a user it is a toolkit for X, and indeed, configure
6026 accepts --with-x-toolkit=gtk. */
6027 Fprovide (intern_c_string ("x-toolkit"), Qnil);
6028 Fprovide (intern_c_string ("gtk"), Qnil);
6030 DEFVAR_LISP ("gtk-version-string", &Vgtk_version_string,
6031 doc: /* Version info for GTK+. */);
6033 char gtk_version[40];
6034 g_snprintf (gtk_version, sizeof (gtk_version), "%u.%u.%u",
6035 GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
6036 Vgtk_version_string = make_pure_string (gtk_version, strlen (gtk_version), strlen (gtk_version), 0);
6038 #endif /* USE_GTK */
6040 /* X window properties. */
6041 defsubr (&Sx_change_window_property);
6042 defsubr (&Sx_delete_window_property);
6043 defsubr (&Sx_window_property);
6045 defsubr (&Sxw_display_color_p);
6046 defsubr (&Sx_display_grayscale_p);
6047 defsubr (&Sxw_color_defined_p);
6048 defsubr (&Sxw_color_values);
6049 defsubr (&Sx_server_max_request_size);
6050 defsubr (&Sx_server_vendor);
6051 defsubr (&Sx_server_version);
6052 defsubr (&Sx_display_pixel_width);
6053 defsubr (&Sx_display_pixel_height);
6054 defsubr (&Sx_display_mm_width);
6055 defsubr (&Sx_display_mm_height);
6056 defsubr (&Sx_display_screens);
6057 defsubr (&Sx_display_planes);
6058 defsubr (&Sx_display_color_cells);
6059 defsubr (&Sx_display_visual_class);
6060 defsubr (&Sx_display_backing_store);
6061 defsubr (&Sx_display_save_under);
6062 defsubr (&Sx_wm_set_size_hint);
6063 defsubr (&Sx_create_frame);
6064 defsubr (&Sx_open_connection);
6065 defsubr (&Sx_close_connection);
6066 defsubr (&Sx_display_list);
6067 defsubr (&Sx_synchronize);
6068 defsubr (&Sx_focus_frame);
6069 defsubr (&Sx_backspace_delete_keys_p);
6071 /* Setting callback functions for fontset handler. */
6072 check_window_system_func = check_x;
6074 defsubr (&Sx_show_tip);
6075 defsubr (&Sx_hide_tip);
6076 tip_timer = Qnil;
6077 staticpro (&tip_timer);
6078 tip_frame = Qnil;
6079 staticpro (&tip_frame);
6081 last_show_tip_args = Qnil;
6082 staticpro (&last_show_tip_args);
6084 defsubr (&Sx_uses_old_gtk_dialog);
6085 #if defined (USE_MOTIF) || defined (USE_GTK)
6086 defsubr (&Sx_file_dialog);
6087 #endif
6089 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
6090 defsubr (&Sx_select_font);
6091 x_last_font_name = NULL;
6092 #endif
6095 #endif /* HAVE_X_WINDOWS */
6097 /* arch-tag: 55040d02-5485-4d58-8b22-95a7a05f3288
6098 (do not change this comment) */