(frame-parameter) <defsetf>: Make it return the assigned value.
[emacs.git] / src / xfns.c
blobbfbc6ac02e931e4d4e6044459e0367e825f3d994
1 /* Functions for the X window system.
2 Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
4 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 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; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
23 #include <config.h>
24 #include <stdio.h>
25 #include <math.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"
54 #ifdef USE_FONT_BACKEND
55 #include "font.h"
56 #endif /* USE_FONT_BACKEND */
58 #ifdef HAVE_X_WINDOWS
60 #include <ctype.h>
61 #include <sys/types.h>
62 #include <sys/stat.h>
64 #ifndef VMS
65 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */
66 #include "bitmaps/gray.xbm"
67 #else
68 #include <X11/bitmaps/gray>
69 #endif
70 #else
71 #include "[.bitmaps]gray.xbm"
72 #endif
74 #ifdef USE_GTK
75 #include "gtkutil.h"
76 #endif
78 #ifdef USE_X_TOOLKIT
79 #include <X11/Shell.h>
81 #ifndef USE_MOTIF
82 #ifdef HAVE_XAW3D
83 #include <X11/Xaw3d/Paned.h>
84 #include <X11/Xaw3d/Label.h>
85 #else /* !HAVE_XAW3D */
86 #include <X11/Xaw/Paned.h>
87 #include <X11/Xaw/Label.h>
88 #endif /* HAVE_XAW3D */
89 #endif /* USE_MOTIF */
91 #ifdef USG
92 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
93 #include <X11/Xos.h>
94 #define USG
95 #else
96 #include <X11/Xos.h>
97 #endif
99 #include "widget.h"
101 #include "../lwlib/lwlib.h"
103 #ifdef USE_MOTIF
104 #include <Xm/Xm.h>
105 #include <Xm/DialogS.h>
106 #include <Xm/FileSB.h>
107 #endif
109 /* Do the EDITRES protocol if running X11R5
110 Exception: HP-UX (at least version A.09.05) has X11R5 without EditRes */
112 #if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES)
113 #define HACK_EDITRES
114 extern void _XEditResCheckMessages ();
115 #endif /* R5 + Athena */
117 /* Unique id counter for widgets created by the Lucid Widget Library. */
119 extern LWLIB_ID widget_id_tick;
121 #ifdef USE_LUCID
122 /* This is part of a kludge--see lwlib/xlwmenu.c. */
123 extern XFontStruct *xlwmenu_default_font;
124 #endif
126 extern void free_frame_menubar ();
127 extern double atof ();
129 #ifdef USE_MOTIF
131 /* LessTif/Motif version info. */
133 static Lisp_Object Vmotif_version_string;
135 #endif /* USE_MOTIF */
137 #endif /* USE_X_TOOLKIT */
139 #ifdef USE_GTK
141 /* GTK+ version info */
143 static Lisp_Object Vgtk_version_string;
145 #endif /* USE_GTK */
147 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
149 /* The gray bitmap `bitmaps/gray'. This is done because xterm.c uses
150 it, and including `bitmaps/gray' more than once is a problem when
151 config.h defines `static' as an empty replacement string. */
153 int gray_bitmap_width = gray_width;
154 int gray_bitmap_height = gray_height;
155 char *gray_bitmap_bits = gray_bits;
157 /* Non-zero means we're allowed to display an hourglass cursor. */
159 int display_hourglass_p;
161 /* Non-zero means prompt with the old GTK file selection dialog. */
163 int x_gtk_use_old_file_dialog;
165 /* If non-zero, by default show hidden files in the GTK file chooser. */
167 int x_gtk_show_hidden_files;
169 /* If non-zero, don't show additional help text in the GTK file chooser. */
171 int x_gtk_file_dialog_help_text;
173 /* If non-zero, don't collapse to tool bar when it is detached. */
175 int x_gtk_whole_detached_tool_bar;
177 /* The background and shape of the mouse pointer, and shape when not
178 over text or in the modeline. */
180 Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
181 Lisp_Object Vx_hourglass_pointer_shape;
183 /* The shape when over mouse-sensitive text. */
185 Lisp_Object Vx_sensitive_text_pointer_shape;
187 /* If non-nil, the pointer shape to indicate that windows can be
188 dragged horizontally. */
190 Lisp_Object Vx_window_horizontal_drag_shape;
192 /* Color of chars displayed in cursor box. */
194 Lisp_Object Vx_cursor_fore_pixel;
196 /* Nonzero if using X. */
198 static int x_in_use;
200 /* Non nil if no window manager is in use. */
202 Lisp_Object Vx_no_window_manager;
204 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
206 Lisp_Object Vx_pixel_size_width_font_regexp;
208 Lisp_Object Qnone;
209 Lisp_Object Qsuppress_icon;
210 Lisp_Object Qundefined_color;
211 Lisp_Object Qcompound_text, Qcancel_timer;
213 /* In dispnew.c */
215 extern Lisp_Object Vwindow_system_version;
217 /* The below are defined in frame.c. */
219 #if GLYPH_DEBUG
220 int image_cache_refcount, dpyinfo_refcount;
221 #endif
225 /* Error if we are not connected to X. */
227 void
228 check_x ()
230 if (! x_in_use)
231 error ("X windows are not in use or not initialized");
234 /* Nonzero if we can use mouse menus.
235 You should not call this unless HAVE_MENUS is defined. */
238 have_menus_p ()
240 return x_in_use;
243 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
244 and checking validity for X. */
246 FRAME_PTR
247 check_x_frame (frame)
248 Lisp_Object frame;
250 FRAME_PTR f;
252 if (NILP (frame))
253 frame = selected_frame;
254 CHECK_LIVE_FRAME (frame);
255 f = XFRAME (frame);
256 if (! FRAME_X_P (f))
257 error ("Non-X frame used");
258 return f;
261 /* Let the user specify an X display with a Lisp object.
262 OBJECT may be nil, a frame or a terminal id.
263 nil stands for the selected frame--or, if that is not an X frame,
264 the first X display on the list. */
266 struct x_display_info *
267 check_x_display_info (object)
268 Lisp_Object object;
270 struct x_display_info *dpyinfo = NULL;
272 if (NILP (object))
274 struct frame *sf = XFRAME (selected_frame);
276 if (FRAME_X_P (sf) && FRAME_LIVE_P (sf))
277 dpyinfo = FRAME_X_DISPLAY_INFO (sf);
278 else if (x_display_list != 0)
279 dpyinfo = x_display_list;
280 else
281 error ("X windows are not in use or not initialized");
283 else if (INTEGERP (object))
285 struct terminal *t = get_terminal (object, 1);
287 if (t->type != output_x_window)
288 error ("Terminal %d is not an X display", XINT (object));
290 dpyinfo = t->display_info.x;
292 else if (STRINGP (object))
293 dpyinfo = x_display_info_for_name (object);
294 else
296 FRAME_PTR f = check_x_frame (object);
297 dpyinfo = FRAME_X_DISPLAY_INFO (f);
300 return dpyinfo;
304 /* Return the Emacs frame-object corresponding to an X window.
305 It could be the frame's main window or an icon window. */
307 /* This function can be called during GC, so use GC_xxx type test macros. */
309 struct frame *
310 x_window_to_frame (dpyinfo, wdesc)
311 struct x_display_info *dpyinfo;
312 int wdesc;
314 Lisp_Object tail, frame;
315 struct frame *f;
317 if (wdesc == None) return 0;
319 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
321 frame = XCAR (tail);
322 if (!FRAMEP (frame))
323 continue;
324 f = XFRAME (frame);
325 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
326 continue;
327 if (f->output_data.x->hourglass_window == wdesc)
328 return f;
329 #ifdef USE_X_TOOLKIT
330 if ((f->output_data.x->edit_widget
331 && XtWindow (f->output_data.x->edit_widget) == wdesc)
332 /* A tooltip frame? */
333 || (!f->output_data.x->edit_widget
334 && FRAME_X_WINDOW (f) == wdesc)
335 || f->output_data.x->icon_desc == wdesc)
336 return f;
337 #else /* not USE_X_TOOLKIT */
338 #ifdef USE_GTK
339 if (f->output_data.x->edit_widget)
341 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
342 struct x_output *x = f->output_data.x;
343 if (gwdesc != 0 && gwdesc == x->edit_widget)
344 return f;
346 #endif /* USE_GTK */
347 if (FRAME_X_WINDOW (f) == wdesc
348 || f->output_data.x->icon_desc == wdesc)
349 return f;
350 #endif /* not USE_X_TOOLKIT */
352 return 0;
355 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
356 /* Like x_window_to_frame but also compares the window with the widget's
357 windows. */
359 struct frame *
360 x_any_window_to_frame (dpyinfo, wdesc)
361 struct x_display_info *dpyinfo;
362 int wdesc;
364 Lisp_Object tail, frame;
365 struct frame *f, *found;
366 struct x_output *x;
368 if (wdesc == None) return NULL;
370 found = NULL;
371 for (tail = Vframe_list; CONSP (tail) && !found; tail = XCDR (tail))
373 frame = XCAR (tail);
374 if (!FRAMEP (frame))
375 continue;
377 f = XFRAME (frame);
378 if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) == dpyinfo)
380 /* This frame matches if the window is any of its widgets. */
381 x = f->output_data.x;
382 if (x->hourglass_window == wdesc)
383 found = f;
384 else if (x->widget)
386 #ifdef USE_GTK
387 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
388 if (gwdesc != 0
389 && (gwdesc == x->widget
390 || gwdesc == x->edit_widget
391 || gwdesc == x->vbox_widget
392 || gwdesc == x->menubar_widget))
393 found = f;
394 #else
395 if (wdesc == XtWindow (x->widget)
396 || wdesc == XtWindow (x->column_widget)
397 || wdesc == XtWindow (x->edit_widget))
398 found = f;
399 /* Match if the window is this frame's menubar. */
400 else if (lw_window_is_in_menubar (wdesc, x->menubar_widget))
401 found = f;
402 #endif
404 else if (FRAME_X_WINDOW (f) == wdesc)
405 /* A tooltip frame. */
406 found = f;
410 return found;
413 /* Likewise, but exclude the menu bar widget. */
415 struct frame *
416 x_non_menubar_window_to_frame (dpyinfo, wdesc)
417 struct x_display_info *dpyinfo;
418 int wdesc;
420 Lisp_Object tail, frame;
421 struct frame *f;
422 struct x_output *x;
424 if (wdesc == None) return 0;
426 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
428 frame = XCAR (tail);
429 if (!FRAMEP (frame))
430 continue;
431 f = XFRAME (frame);
432 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
433 continue;
434 x = f->output_data.x;
435 /* This frame matches if the window is any of its widgets. */
436 if (x->hourglass_window == wdesc)
437 return f;
438 else if (x->widget)
440 #ifdef USE_GTK
441 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
442 if (gwdesc != 0
443 && (gwdesc == x->widget
444 || gwdesc == x->edit_widget
445 || gwdesc == x->vbox_widget))
446 return f;
447 #else
448 if (wdesc == XtWindow (x->widget)
449 || wdesc == XtWindow (x->column_widget)
450 || wdesc == XtWindow (x->edit_widget))
451 return f;
452 #endif
454 else if (FRAME_X_WINDOW (f) == wdesc)
455 /* A tooltip frame. */
456 return f;
458 return 0;
461 /* Likewise, but consider only the menu bar widget. */
463 struct frame *
464 x_menubar_window_to_frame (dpyinfo, wdesc)
465 struct x_display_info *dpyinfo;
466 int wdesc;
468 Lisp_Object tail, frame;
469 struct frame *f;
470 struct x_output *x;
472 if (wdesc == None) return 0;
474 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
476 frame = XCAR (tail);
477 if (!FRAMEP (frame))
478 continue;
479 f = XFRAME (frame);
480 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
481 continue;
482 x = f->output_data.x;
483 /* Match if the window is this frame's menubar. */
484 #ifdef USE_GTK
485 if (x->menubar_widget)
487 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
488 int found = 0;
490 BLOCK_INPUT;
491 if (gwdesc != 0
492 && (gwdesc == x->menubar_widget
493 || gtk_widget_get_parent (gwdesc) == x->menubar_widget))
494 found = 1;
495 UNBLOCK_INPUT;
496 if (found) return f;
498 #else
499 if (x->menubar_widget
500 && lw_window_is_in_menubar (wdesc, x->menubar_widget))
501 return f;
502 #endif
504 return 0;
507 /* Return the frame whose principal (outermost) window is WDESC.
508 If WDESC is some other (smaller) window, we return 0. */
510 struct frame *
511 x_top_window_to_frame (dpyinfo, wdesc)
512 struct x_display_info *dpyinfo;
513 int wdesc;
515 Lisp_Object tail, frame;
516 struct frame *f;
517 struct x_output *x;
519 if (wdesc == None) return 0;
521 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
523 frame = XCAR (tail);
524 if (!FRAMEP (frame))
525 continue;
526 f = XFRAME (frame);
527 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
528 continue;
529 x = f->output_data.x;
531 if (x->widget)
533 /* This frame matches if the window is its topmost widget. */
534 #ifdef USE_GTK
535 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
536 if (gwdesc == x->widget)
537 return f;
538 #else
539 if (wdesc == XtWindow (x->widget))
540 return f;
541 #if 0 /* I don't know why it did this,
542 but it seems logically wrong,
543 and it causes trouble for MapNotify events. */
544 /* Match if the window is this frame's menubar. */
545 if (x->menubar_widget
546 && wdesc == XtWindow (x->menubar_widget))
547 return f;
548 #endif
549 #endif
551 else if (FRAME_X_WINDOW (f) == wdesc)
552 /* Tooltip frame. */
553 return f;
555 return 0;
557 #endif /* USE_X_TOOLKIT || USE_GTK */
561 static void x_default_font_parameter P_ ((struct frame *, Lisp_Object));
563 static Lisp_Object unwind_create_frame P_ ((Lisp_Object));
564 static Lisp_Object unwind_create_tip_frame P_ ((Lisp_Object));
566 void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
567 static void x_set_wait_for_wm P_ ((struct frame *, Lisp_Object, Lisp_Object));
568 void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
569 void x_set_mouse_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
570 void x_set_cursor_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
571 void x_set_border_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
572 void x_set_cursor_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
573 void x_set_icon_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
574 void x_set_icon_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
575 void x_explicitly_set_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
576 void x_set_menu_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
577 void x_set_title P_ ((struct frame *, Lisp_Object, Lisp_Object));
578 void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
579 void x_set_scroll_bar_foreground P_ ((struct frame *, Lisp_Object,
580 Lisp_Object));
581 void x_set_scroll_bar_background P_ ((struct frame *, Lisp_Object,
582 Lisp_Object));
583 static Lisp_Object x_default_scroll_bar_color_parameter P_ ((struct frame *,
584 Lisp_Object,
585 Lisp_Object,
586 char *, char *,
587 int));
590 /* Store the screen positions of frame F into XPTR and YPTR.
591 These are the positions of the containing window manager window,
592 not Emacs's own window. */
594 void
595 x_real_positions (f, xptr, yptr)
596 FRAME_PTR f;
597 int *xptr, *yptr;
599 int win_x, win_y, outer_x, outer_y;
600 int real_x = 0, real_y = 0;
601 int had_errors = 0;
602 Window win = f->output_data.x->parent_desc;
604 BLOCK_INPUT;
606 x_catch_errors (FRAME_X_DISPLAY (f));
608 if (win == FRAME_X_DISPLAY_INFO (f)->root_window)
609 win = FRAME_OUTER_WINDOW (f);
611 /* This loop traverses up the containment tree until we hit the root
612 window. Window managers may intersect many windows between our window
613 and the root window. The window we find just before the root window
614 should be the outer WM window. */
615 for (;;)
617 Window wm_window, rootw;
618 Window *tmp_children;
619 unsigned int tmp_nchildren;
620 int success;
622 success = XQueryTree (FRAME_X_DISPLAY (f), win, &rootw,
623 &wm_window, &tmp_children, &tmp_nchildren);
625 had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
627 /* Don't free tmp_children if XQueryTree failed. */
628 if (! success)
629 break;
631 XFree ((char *) tmp_children);
633 if (wm_window == rootw || had_errors)
634 break;
636 win = wm_window;
639 if (! had_errors)
641 unsigned int ign;
642 Window child, rootw;
644 /* Get the real coordinates for the WM window upper left corner */
645 XGetGeometry (FRAME_X_DISPLAY (f), win,
646 &rootw, &real_x, &real_y, &ign, &ign, &ign, &ign);
648 /* Translate real coordinates to coordinates relative to our
649 window. For our window, the upper left corner is 0, 0.
650 Since the upper left corner of the WM window is outside
651 our window, win_x and win_y will be negative:
653 ------------------ ---> x
654 | title |
655 | ----------------- v y
656 | | our window
658 XTranslateCoordinates (FRAME_X_DISPLAY (f),
660 /* From-window, to-window. */
661 FRAME_X_DISPLAY_INFO (f)->root_window,
662 FRAME_X_WINDOW (f),
664 /* From-position, to-position. */
665 real_x, real_y, &win_x, &win_y,
667 /* Child of win. */
668 &child);
670 if (FRAME_X_WINDOW (f) == FRAME_OUTER_WINDOW (f))
672 outer_x = win_x;
673 outer_y = win_y;
675 else
677 XTranslateCoordinates (FRAME_X_DISPLAY (f),
679 /* From-window, to-window. */
680 FRAME_X_DISPLAY_INFO (f)->root_window,
681 FRAME_OUTER_WINDOW (f),
683 /* From-position, to-position. */
684 real_x, real_y, &outer_x, &outer_y,
686 /* Child of win. */
687 &child);
690 had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
693 x_uncatch_errors ();
695 UNBLOCK_INPUT;
697 if (had_errors) return;
699 f->x_pixels_diff = -win_x;
700 f->y_pixels_diff = -win_y;
702 FRAME_X_OUTPUT (f)->x_pixels_outer_diff = -outer_x;
703 FRAME_X_OUTPUT (f)->y_pixels_outer_diff = -outer_y;
705 *xptr = real_x;
706 *yptr = real_y;
712 /* Gamma-correct COLOR on frame F. */
714 void
715 gamma_correct (f, color)
716 struct frame *f;
717 XColor *color;
719 if (f->gamma)
721 color->red = pow (color->red / 65535.0, f->gamma) * 65535.0 + 0.5;
722 color->green = pow (color->green / 65535.0, f->gamma) * 65535.0 + 0.5;
723 color->blue = pow (color->blue / 65535.0, f->gamma) * 65535.0 + 0.5;
728 /* Decide if color named COLOR_NAME is valid for use on frame F. If
729 so, return the RGB values in COLOR. If ALLOC_P is non-zero,
730 allocate the color. Value is zero if COLOR_NAME is invalid, or
731 no color could be allocated. */
734 x_defined_color (f, color_name, color, alloc_p)
735 struct frame *f;
736 char *color_name;
737 XColor *color;
738 int alloc_p;
740 int success_p;
741 Display *dpy = FRAME_X_DISPLAY (f);
742 Colormap cmap = FRAME_X_COLORMAP (f);
744 BLOCK_INPUT;
745 success_p = XParseColor (dpy, cmap, color_name, color);
746 if (success_p && alloc_p)
747 success_p = x_alloc_nearest_color (f, cmap, color);
748 UNBLOCK_INPUT;
750 return success_p;
754 /* Return the pixel color value for color COLOR_NAME on frame F. If F
755 is a monochrome frame, return MONO_COLOR regardless of what ARG says.
756 Signal an error if color can't be allocated. */
759 x_decode_color (f, color_name, mono_color)
760 FRAME_PTR f;
761 Lisp_Object color_name;
762 int mono_color;
764 XColor cdef;
766 CHECK_STRING (color_name);
768 #if 0 /* Don't do this. It's wrong when we're not using the default
769 colormap, it makes freeing difficult, and it's probably not
770 an important optimization. */
771 if (strcmp (SDATA (color_name), "black") == 0)
772 return BLACK_PIX_DEFAULT (f);
773 else if (strcmp (SDATA (color_name), "white") == 0)
774 return WHITE_PIX_DEFAULT (f);
775 #endif
777 /* Return MONO_COLOR for monochrome frames. */
778 if (FRAME_X_DISPLAY_INFO (f)->n_planes == 1)
779 return mono_color;
781 /* x_defined_color is responsible for coping with failures
782 by looking for a near-miss. */
783 if (x_defined_color (f, SDATA (color_name), &cdef, 1))
784 return cdef.pixel;
786 signal_error ("Undefined color", color_name);
791 /* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
792 the previous value of that parameter, NEW_VALUE is the new value.
793 See also the comment of wait_for_wm in struct x_output. */
795 static void
796 x_set_wait_for_wm (f, new_value, old_value)
797 struct frame *f;
798 Lisp_Object new_value, old_value;
800 f->output_data.x->wait_for_wm = !NILP (new_value);
803 #ifdef USE_GTK
805 /* Set icon from FILE for frame F. By using GTK functions the icon
806 may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
809 xg_set_icon (f, file)
810 FRAME_PTR f;
811 Lisp_Object file;
813 int result = 0;
814 Lisp_Object found;
816 found = x_find_image_file (file);
818 if (! NILP (found))
820 GdkPixbuf *pixbuf;
821 GError *err = NULL;
822 char *filename = (char *) SDATA (found);
823 BLOCK_INPUT;
825 pixbuf = gdk_pixbuf_new_from_file (filename, &err);
827 if (pixbuf)
829 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
830 pixbuf);
831 g_object_unref (pixbuf);
833 result = 1;
835 else
836 g_error_free (err);
838 UNBLOCK_INPUT;
841 return result;
845 xg_set_icon_from_xpm_data (f, data)
846 FRAME_PTR f;
847 char **data;
849 int result = 0;
850 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) data);
852 if (!pixbuf)
853 return 0;
855 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), pixbuf);
856 g_object_unref (pixbuf);
857 return 1;
859 #endif /* USE_GTK */
862 /* Functions called only from `x_set_frame_param'
863 to set individual parameters.
865 If FRAME_X_WINDOW (f) is 0,
866 the frame is being created and its X-window does not exist yet.
867 In that case, just record the parameter's new value
868 in the standard place; do not attempt to change the window. */
870 void
871 x_set_foreground_color (f, arg, oldval)
872 struct frame *f;
873 Lisp_Object arg, oldval;
875 struct x_output *x = f->output_data.x;
876 unsigned long fg, old_fg;
878 fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
879 old_fg = FRAME_FOREGROUND_PIXEL (f);
880 FRAME_FOREGROUND_PIXEL (f) = fg;
882 if (FRAME_X_WINDOW (f) != 0)
884 Display *dpy = FRAME_X_DISPLAY (f);
886 BLOCK_INPUT;
887 XSetForeground (dpy, x->normal_gc, fg);
888 XSetBackground (dpy, x->reverse_gc, fg);
890 if (x->cursor_pixel == old_fg)
892 unload_color (f, x->cursor_pixel);
893 x->cursor_pixel = x_copy_color (f, fg);
894 XSetBackground (dpy, x->cursor_gc, x->cursor_pixel);
897 UNBLOCK_INPUT;
899 update_face_from_frame_parameter (f, Qforeground_color, arg);
901 if (FRAME_VISIBLE_P (f))
902 redraw_frame (f);
905 unload_color (f, old_fg);
908 void
909 x_set_background_color (f, arg, oldval)
910 struct frame *f;
911 Lisp_Object arg, oldval;
913 struct x_output *x = f->output_data.x;
914 unsigned long bg;
916 bg = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
917 unload_color (f, FRAME_BACKGROUND_PIXEL (f));
918 FRAME_BACKGROUND_PIXEL (f) = bg;
920 if (FRAME_X_WINDOW (f) != 0)
922 Display *dpy = FRAME_X_DISPLAY (f);
924 BLOCK_INPUT;
925 XSetBackground (dpy, x->normal_gc, bg);
926 XSetForeground (dpy, x->reverse_gc, bg);
927 XSetWindowBackground (dpy, FRAME_X_WINDOW (f), bg);
928 XSetForeground (dpy, x->cursor_gc, bg);
930 #ifdef USE_GTK
931 xg_set_background_color (f, bg);
932 #endif
934 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
935 toolkit scroll bars. */
937 Lisp_Object bar;
938 for (bar = FRAME_SCROLL_BARS (f);
939 !NILP (bar);
940 bar = XSCROLL_BAR (bar)->next)
942 Window window = XSCROLL_BAR (bar)->x_window;
943 XSetWindowBackground (dpy, window, bg);
946 #endif /* USE_TOOLKIT_SCROLL_BARS */
948 UNBLOCK_INPUT;
949 update_face_from_frame_parameter (f, Qbackground_color, arg);
951 if (FRAME_VISIBLE_P (f))
952 redraw_frame (f);
956 void
957 x_set_mouse_color (f, arg, oldval)
958 struct frame *f;
959 Lisp_Object arg, oldval;
961 struct x_output *x = f->output_data.x;
962 Display *dpy = FRAME_X_DISPLAY (f);
963 Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
964 Cursor hourglass_cursor, horizontal_drag_cursor;
965 unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
966 unsigned long mask_color = FRAME_BACKGROUND_PIXEL (f);
968 /* Don't let pointers be invisible. */
969 if (mask_color == pixel)
971 x_free_colors (f, &pixel, 1);
972 pixel = x_copy_color (f, FRAME_FOREGROUND_PIXEL (f));
975 unload_color (f, x->mouse_pixel);
976 x->mouse_pixel = pixel;
978 BLOCK_INPUT;
980 /* It's not okay to crash if the user selects a screwy cursor. */
981 x_catch_errors (dpy);
983 if (!NILP (Vx_pointer_shape))
985 CHECK_NUMBER (Vx_pointer_shape);
986 cursor = XCreateFontCursor (dpy, XINT (Vx_pointer_shape));
988 else
989 cursor = XCreateFontCursor (dpy, XC_xterm);
990 x_check_errors (dpy, "bad text pointer cursor: %s");
992 if (!NILP (Vx_nontext_pointer_shape))
994 CHECK_NUMBER (Vx_nontext_pointer_shape);
995 nontext_cursor
996 = XCreateFontCursor (dpy, XINT (Vx_nontext_pointer_shape));
998 else
999 nontext_cursor = XCreateFontCursor (dpy, XC_left_ptr);
1000 x_check_errors (dpy, "bad nontext pointer cursor: %s");
1002 if (!NILP (Vx_hourglass_pointer_shape))
1004 CHECK_NUMBER (Vx_hourglass_pointer_shape);
1005 hourglass_cursor
1006 = XCreateFontCursor (dpy, XINT (Vx_hourglass_pointer_shape));
1008 else
1009 hourglass_cursor = XCreateFontCursor (dpy, XC_watch);
1010 x_check_errors (dpy, "bad hourglass pointer cursor: %s");
1012 if (!NILP (Vx_mode_pointer_shape))
1014 CHECK_NUMBER (Vx_mode_pointer_shape);
1015 mode_cursor = XCreateFontCursor (dpy, XINT (Vx_mode_pointer_shape));
1017 else
1018 mode_cursor = XCreateFontCursor (dpy, XC_xterm);
1019 x_check_errors (dpy, "bad modeline pointer cursor: %s");
1021 if (!NILP (Vx_sensitive_text_pointer_shape))
1023 CHECK_NUMBER (Vx_sensitive_text_pointer_shape);
1024 hand_cursor
1025 = XCreateFontCursor (dpy, XINT (Vx_sensitive_text_pointer_shape));
1027 else
1028 hand_cursor = XCreateFontCursor (dpy, XC_hand2);
1030 if (!NILP (Vx_window_horizontal_drag_shape))
1032 CHECK_NUMBER (Vx_window_horizontal_drag_shape);
1033 horizontal_drag_cursor
1034 = XCreateFontCursor (dpy, XINT (Vx_window_horizontal_drag_shape));
1036 else
1037 horizontal_drag_cursor
1038 = XCreateFontCursor (dpy, XC_sb_h_double_arrow);
1040 /* Check and report errors with the above calls. */
1041 x_check_errors (dpy, "can't set cursor shape: %s");
1042 x_uncatch_errors ();
1045 XColor fore_color, back_color;
1047 fore_color.pixel = x->mouse_pixel;
1048 x_query_color (f, &fore_color);
1049 back_color.pixel = mask_color;
1050 x_query_color (f, &back_color);
1052 XRecolorCursor (dpy, cursor, &fore_color, &back_color);
1053 XRecolorCursor (dpy, nontext_cursor, &fore_color, &back_color);
1054 XRecolorCursor (dpy, mode_cursor, &fore_color, &back_color);
1055 XRecolorCursor (dpy, hand_cursor, &fore_color, &back_color);
1056 XRecolorCursor (dpy, hourglass_cursor, &fore_color, &back_color);
1057 XRecolorCursor (dpy, horizontal_drag_cursor, &fore_color, &back_color);
1060 if (FRAME_X_WINDOW (f) != 0)
1061 XDefineCursor (dpy, FRAME_X_WINDOW (f), cursor);
1063 if (cursor != x->text_cursor
1064 && x->text_cursor != 0)
1065 XFreeCursor (dpy, x->text_cursor);
1066 x->text_cursor = cursor;
1068 if (nontext_cursor != x->nontext_cursor
1069 && x->nontext_cursor != 0)
1070 XFreeCursor (dpy, x->nontext_cursor);
1071 x->nontext_cursor = nontext_cursor;
1073 if (hourglass_cursor != x->hourglass_cursor
1074 && x->hourglass_cursor != 0)
1075 XFreeCursor (dpy, x->hourglass_cursor);
1076 x->hourglass_cursor = hourglass_cursor;
1078 if (mode_cursor != x->modeline_cursor
1079 && x->modeline_cursor != 0)
1080 XFreeCursor (dpy, f->output_data.x->modeline_cursor);
1081 x->modeline_cursor = mode_cursor;
1083 if (hand_cursor != x->hand_cursor
1084 && x->hand_cursor != 0)
1085 XFreeCursor (dpy, x->hand_cursor);
1086 x->hand_cursor = hand_cursor;
1088 if (horizontal_drag_cursor != x->horizontal_drag_cursor
1089 && x->horizontal_drag_cursor != 0)
1090 XFreeCursor (dpy, x->horizontal_drag_cursor);
1091 x->horizontal_drag_cursor = horizontal_drag_cursor;
1093 XFlush (dpy);
1094 UNBLOCK_INPUT;
1096 update_face_from_frame_parameter (f, Qmouse_color, arg);
1099 void
1100 x_set_cursor_color (f, arg, oldval)
1101 struct frame *f;
1102 Lisp_Object arg, oldval;
1104 unsigned long fore_pixel, pixel;
1105 int fore_pixel_allocated_p = 0, pixel_allocated_p = 0;
1106 struct x_output *x = f->output_data.x;
1108 if (!NILP (Vx_cursor_fore_pixel))
1110 fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
1111 WHITE_PIX_DEFAULT (f));
1112 fore_pixel_allocated_p = 1;
1114 else
1115 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1117 pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1118 pixel_allocated_p = 1;
1120 /* Make sure that the cursor color differs from the background color. */
1121 if (pixel == FRAME_BACKGROUND_PIXEL (f))
1123 if (pixel_allocated_p)
1125 x_free_colors (f, &pixel, 1);
1126 pixel_allocated_p = 0;
1129 pixel = x->mouse_pixel;
1130 if (pixel == fore_pixel)
1132 if (fore_pixel_allocated_p)
1134 x_free_colors (f, &fore_pixel, 1);
1135 fore_pixel_allocated_p = 0;
1137 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1141 unload_color (f, x->cursor_foreground_pixel);
1142 if (!fore_pixel_allocated_p)
1143 fore_pixel = x_copy_color (f, fore_pixel);
1144 x->cursor_foreground_pixel = fore_pixel;
1146 unload_color (f, x->cursor_pixel);
1147 if (!pixel_allocated_p)
1148 pixel = x_copy_color (f, pixel);
1149 x->cursor_pixel = pixel;
1151 if (FRAME_X_WINDOW (f) != 0)
1153 BLOCK_INPUT;
1154 XSetBackground (FRAME_X_DISPLAY (f), x->cursor_gc, x->cursor_pixel);
1155 XSetForeground (FRAME_X_DISPLAY (f), x->cursor_gc, fore_pixel);
1156 UNBLOCK_INPUT;
1158 if (FRAME_VISIBLE_P (f))
1160 x_update_cursor (f, 0);
1161 x_update_cursor (f, 1);
1165 update_face_from_frame_parameter (f, Qcursor_color, arg);
1168 /* Set the border-color of frame F to pixel value PIX.
1169 Note that this does not fully take effect if done before
1170 F has an x-window. */
1172 void
1173 x_set_border_pixel (f, pix)
1174 struct frame *f;
1175 int pix;
1177 unload_color (f, f->output_data.x->border_pixel);
1178 f->output_data.x->border_pixel = pix;
1180 if (FRAME_X_WINDOW (f) != 0 && f->border_width > 0)
1182 BLOCK_INPUT;
1183 XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1184 (unsigned long)pix);
1185 UNBLOCK_INPUT;
1187 if (FRAME_VISIBLE_P (f))
1188 redraw_frame (f);
1192 /* Set the border-color of frame F to value described by ARG.
1193 ARG can be a string naming a color.
1194 The border-color is used for the border that is drawn by the X server.
1195 Note that this does not fully take effect if done before
1196 F has an x-window; it must be redone when the window is created.
1198 Note: this is done in two routines because of the way X10 works.
1200 Note: under X11, this is normally the province of the window manager,
1201 and so emacs' border colors may be overridden. */
1203 void
1204 x_set_border_color (f, arg, oldval)
1205 struct frame *f;
1206 Lisp_Object arg, oldval;
1208 int pix;
1210 CHECK_STRING (arg);
1211 pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1212 x_set_border_pixel (f, pix);
1213 update_face_from_frame_parameter (f, Qborder_color, arg);
1217 void
1218 x_set_cursor_type (f, arg, oldval)
1219 FRAME_PTR f;
1220 Lisp_Object arg, oldval;
1222 set_frame_cursor_types (f, arg);
1224 /* Make sure the cursor gets redrawn. */
1225 cursor_type_changed = 1;
1228 void
1229 x_set_icon_type (f, arg, oldval)
1230 struct frame *f;
1231 Lisp_Object arg, oldval;
1233 int result;
1235 if (STRINGP (arg))
1237 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1238 return;
1240 else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
1241 return;
1243 BLOCK_INPUT;
1244 if (NILP (arg))
1245 result = x_text_icon (f,
1246 (char *) SDATA ((!NILP (f->icon_name)
1247 ? f->icon_name
1248 : f->name)));
1249 else
1250 result = x_bitmap_icon (f, arg);
1252 if (result)
1254 UNBLOCK_INPUT;
1255 error ("No icon window available");
1258 XFlush (FRAME_X_DISPLAY (f));
1259 UNBLOCK_INPUT;
1262 void
1263 x_set_icon_name (f, arg, oldval)
1264 struct frame *f;
1265 Lisp_Object arg, oldval;
1267 int result;
1269 if (STRINGP (arg))
1271 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1272 return;
1274 else if (!NILP (arg) || NILP (oldval))
1275 return;
1277 f->icon_name = arg;
1279 if (f->output_data.x->icon_bitmap != 0)
1280 return;
1282 BLOCK_INPUT;
1284 result = x_text_icon (f,
1285 (char *) SDATA ((!NILP (f->icon_name)
1286 ? f->icon_name
1287 : !NILP (f->title)
1288 ? f->title
1289 : f->name)));
1291 if (result)
1293 UNBLOCK_INPUT;
1294 error ("No icon window available");
1297 XFlush (FRAME_X_DISPLAY (f));
1298 UNBLOCK_INPUT;
1302 void
1303 x_set_menu_bar_lines (f, value, oldval)
1304 struct frame *f;
1305 Lisp_Object value, oldval;
1307 int nlines;
1308 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
1309 int olines = FRAME_MENU_BAR_LINES (f);
1310 #endif
1312 /* Right now, menu bars don't work properly in minibuf-only frames;
1313 most of the commands try to apply themselves to the minibuffer
1314 frame itself, and get an error because you can't switch buffers
1315 in or split the minibuffer window. */
1316 if (FRAME_MINIBUF_ONLY_P (f))
1317 return;
1319 if (INTEGERP (value))
1320 nlines = XINT (value);
1321 else
1322 nlines = 0;
1324 /* Make sure we redisplay all windows in this frame. */
1325 windows_or_buffers_changed++;
1327 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1328 FRAME_MENU_BAR_LINES (f) = 0;
1329 if (nlines)
1331 FRAME_EXTERNAL_MENU_BAR (f) = 1;
1332 if (FRAME_X_P (f) && f->output_data.x->menubar_widget == 0)
1333 /* Make sure next redisplay shows the menu bar. */
1334 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
1336 else
1338 if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
1339 free_frame_menubar (f);
1340 FRAME_EXTERNAL_MENU_BAR (f) = 0;
1341 if (FRAME_X_P (f))
1342 f->output_data.x->menubar_widget = 0;
1344 #else /* not USE_X_TOOLKIT && not USE_GTK */
1345 FRAME_MENU_BAR_LINES (f) = nlines;
1346 change_window_heights (f->root_window, nlines - olines);
1347 #endif /* not USE_X_TOOLKIT */
1348 adjust_glyphs (f);
1352 /* Set the number of lines used for the tool bar of frame F to VALUE.
1353 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1354 is the old number of tool bar lines. This function changes the
1355 height of all windows on frame F to match the new tool bar height.
1356 The frame's height doesn't change. */
1358 void
1359 x_set_tool_bar_lines (f, value, oldval)
1360 struct frame *f;
1361 Lisp_Object value, oldval;
1363 int delta, nlines, root_height;
1364 Lisp_Object root_window;
1366 /* Treat tool bars like menu bars. */
1367 if (FRAME_MINIBUF_ONLY_P (f))
1368 return;
1370 /* Use VALUE only if an integer >= 0. */
1371 if (INTEGERP (value) && XINT (value) >= 0)
1372 nlines = XFASTINT (value);
1373 else
1374 nlines = 0;
1376 #ifdef USE_GTK
1377 FRAME_TOOL_BAR_LINES (f) = 0;
1378 if (nlines)
1380 FRAME_EXTERNAL_TOOL_BAR (f) = 1;
1381 if (FRAME_X_P (f) && f->output_data.x->toolbar_widget == 0)
1382 /* Make sure next redisplay shows the tool bar. */
1383 XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
1384 update_frame_tool_bar (f);
1386 else
1388 if (FRAME_EXTERNAL_TOOL_BAR (f))
1389 free_frame_tool_bar (f);
1390 FRAME_EXTERNAL_TOOL_BAR (f) = 0;
1393 return;
1394 #endif
1396 /* Make sure we redisplay all windows in this frame. */
1397 ++windows_or_buffers_changed;
1399 delta = nlines - FRAME_TOOL_BAR_LINES (f);
1401 /* Don't resize the tool-bar to more than we have room for. */
1402 root_window = FRAME_ROOT_WINDOW (f);
1403 root_height = WINDOW_TOTAL_LINES (XWINDOW (root_window));
1404 if (root_height - delta < 1)
1406 delta = root_height - 1;
1407 nlines = FRAME_TOOL_BAR_LINES (f) + delta;
1410 FRAME_TOOL_BAR_LINES (f) = nlines;
1411 change_window_heights (root_window, delta);
1412 adjust_glyphs (f);
1414 /* We also have to make sure that the internal border at the top of
1415 the frame, below the menu bar or tool bar, is redrawn when the
1416 tool bar disappears. This is so because the internal border is
1417 below the tool bar if one is displayed, but is below the menu bar
1418 if there isn't a tool bar. The tool bar draws into the area
1419 below the menu bar. */
1420 if (FRAME_X_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0)
1422 clear_frame (f);
1423 clear_current_matrices (f);
1426 /* If the tool bar gets smaller, the internal border below it
1427 has to be cleared. It was formerly part of the display
1428 of the larger tool bar, and updating windows won't clear it. */
1429 if (delta < 0)
1431 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1432 int width = FRAME_PIXEL_WIDTH (f);
1433 int y = nlines * FRAME_LINE_HEIGHT (f);
1435 /* height can be zero here. */
1436 if (height > 0 && width > 0)
1438 BLOCK_INPUT;
1439 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1440 0, y, width, height, False);
1441 UNBLOCK_INPUT;
1444 if (WINDOWP (f->tool_bar_window))
1445 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1450 /* Set the foreground color for scroll bars on frame F to VALUE.
1451 VALUE should be a string, a color name. If it isn't a string or
1452 isn't a valid color name, do nothing. OLDVAL is the old value of
1453 the frame parameter. */
1455 void
1456 x_set_scroll_bar_foreground (f, value, oldval)
1457 struct frame *f;
1458 Lisp_Object value, oldval;
1460 unsigned long pixel;
1462 if (STRINGP (value))
1463 pixel = x_decode_color (f, value, BLACK_PIX_DEFAULT (f));
1464 else
1465 pixel = -1;
1467 if (f->output_data.x->scroll_bar_foreground_pixel != -1)
1468 unload_color (f, f->output_data.x->scroll_bar_foreground_pixel);
1470 f->output_data.x->scroll_bar_foreground_pixel = pixel;
1471 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1473 /* Remove all scroll bars because they have wrong colors. */
1474 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1475 (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1476 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1477 (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1479 update_face_from_frame_parameter (f, Qscroll_bar_foreground, value);
1480 redraw_frame (f);
1485 /* Set the background color for scroll bars on frame F to VALUE VALUE
1486 should be a string, a color name. If it isn't a string or isn't a
1487 valid color name, do nothing. OLDVAL is the old value of the frame
1488 parameter. */
1490 void
1491 x_set_scroll_bar_background (f, value, oldval)
1492 struct frame *f;
1493 Lisp_Object value, oldval;
1495 unsigned long pixel;
1497 if (STRINGP (value))
1498 pixel = x_decode_color (f, value, WHITE_PIX_DEFAULT (f));
1499 else
1500 pixel = -1;
1502 if (f->output_data.x->scroll_bar_background_pixel != -1)
1503 unload_color (f, f->output_data.x->scroll_bar_background_pixel);
1505 #ifdef USE_TOOLKIT_SCROLL_BARS
1506 /* Scrollbar shadow colors. */
1507 if (f->output_data.x->scroll_bar_top_shadow_pixel != -1)
1509 unload_color (f, f->output_data.x->scroll_bar_top_shadow_pixel);
1510 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
1512 if (f->output_data.x->scroll_bar_bottom_shadow_pixel != -1)
1514 unload_color (f, f->output_data.x->scroll_bar_bottom_shadow_pixel);
1515 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
1517 #endif /* USE_TOOLKIT_SCROLL_BARS */
1519 f->output_data.x->scroll_bar_background_pixel = pixel;
1520 if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
1522 /* Remove all scroll bars because they have wrong colors. */
1523 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
1524 (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
1525 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
1526 (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
1528 update_face_from_frame_parameter (f, Qscroll_bar_background, value);
1529 redraw_frame (f);
1534 /* Encode Lisp string STRING as a text in a format appropriate for
1535 XICCC (X Inter Client Communication Conventions).
1537 This can call Lisp code, so callers must GCPRO.
1539 If STRING contains only ASCII characters, do no conversion and
1540 return the string data of STRING. Otherwise, encode the text by
1541 CODING_SYSTEM, and return a newly allocated memory area which
1542 should be freed by `xfree' by a caller.
1544 SELECTIONP non-zero means the string is being encoded for an X
1545 selection, so it is safe to run pre-write conversions (which
1546 may run Lisp code).
1548 Store the byte length of resulting text in *TEXT_BYTES.
1550 If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
1551 which means that the `encoding' of the result can be `STRING'.
1552 Otherwise store 0 in *STRINGP, which means that the `encoding' of
1553 the result should be `COMPOUND_TEXT'. */
1555 static unsigned char *
1556 x_encode_text (string, coding_system, selectionp, text_bytes, stringp, freep)
1557 Lisp_Object string, coding_system;
1558 int *text_bytes, *stringp;
1559 int selectionp;
1560 int *freep;
1562 int result = string_xstring_p (string);
1563 struct coding_system coding;
1565 if (result == 0)
1567 /* No multibyte character in OBJ. We need not encode it. */
1568 *text_bytes = SBYTES (string);
1569 *stringp = 1;
1570 *freep = 0;
1571 return SDATA (string);
1574 setup_coding_system (coding_system, &coding);
1575 coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK);
1576 /* We suppress producing escape sequences for composition. */
1577 coding.common_flags &= ~CODING_ANNOTATION_MASK;
1578 coding.dst_bytes = SCHARS (string) * 2;
1579 coding.destination = (unsigned char *) xmalloc (coding.dst_bytes);
1580 encode_coding_object (&coding, string, 0, 0,
1581 SCHARS (string), SBYTES (string), Qnil);
1582 *text_bytes = coding.produced;
1583 *stringp = (result == 1 || !EQ (coding_system, Qcompound_text));
1584 *freep = 1;
1585 return coding.destination;
1589 /* Set the WM name to NAME for frame F. Also set the icon name.
1590 If the frame already has an icon name, use that, otherwise set the
1591 icon name to NAME. */
1593 static void
1594 x_set_name_internal (f, name)
1595 FRAME_PTR f;
1596 Lisp_Object name;
1598 if (FRAME_X_WINDOW (f))
1600 BLOCK_INPUT;
1602 XTextProperty text, icon;
1603 int bytes, stringp;
1604 int do_free_icon_value = 0, do_free_text_value = 0;
1605 Lisp_Object coding_system;
1606 #ifdef USE_GTK
1607 Lisp_Object encoded_name;
1608 struct gcpro gcpro1;
1610 /* As ENCODE_UTF_8 may cause GC and relocation of string data,
1611 we use it before x_encode_text that may return string data. */
1612 GCPRO1 (name);
1613 encoded_name = ENCODE_UTF_8 (name);
1614 UNGCPRO;
1615 #endif
1617 coding_system = Qcompound_text;
1618 /* Note: Encoding strategy
1620 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1621 text.encoding. But, there are non-internationalized window
1622 managers which don't support that encoding. So, if NAME
1623 contains only ASCII and 8859-1 characters, encode it by
1624 iso-latin-1, and use "STRING" in text.encoding hoping that
1625 such window managers at least analyze this format correctly,
1626 i.e. treat 8-bit bytes as 8859-1 characters.
1628 We may also be able to use "UTF8_STRING" in text.encoding
1629 in the future which can encode all Unicode characters.
1630 But, for the moment, there's no way to know that the
1631 current window manager supports it or not. */
1632 text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp,
1633 &do_free_text_value);
1634 text.encoding = (stringp ? XA_STRING
1635 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1636 text.format = 8;
1637 text.nitems = bytes;
1639 if (!STRINGP (f->icon_name))
1641 icon = text;
1643 else
1645 /* See the above comment "Note: Encoding strategy". */
1646 icon.value = x_encode_text (f->icon_name, coding_system, 0,
1647 &bytes, &stringp, &do_free_icon_value);
1648 icon.encoding = (stringp ? XA_STRING
1649 : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
1650 icon.format = 8;
1651 icon.nitems = bytes;
1654 #ifdef USE_GTK
1655 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
1656 (char *) SDATA (encoded_name));
1657 #else /* not USE_GTK */
1658 XSetWMName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &text);
1659 #endif /* not USE_GTK */
1661 XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &icon);
1663 if (do_free_icon_value)
1664 xfree (icon.value);
1665 if (do_free_text_value)
1666 xfree (text.value);
1668 UNBLOCK_INPUT;
1672 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1673 x_id_name.
1675 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1676 name; if NAME is a string, set F's name to NAME and set
1677 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1679 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1680 suggesting a new name, which lisp code should override; if
1681 F->explicit_name is set, ignore the new name; otherwise, set it. */
1683 void
1684 x_set_name (f, name, explicit)
1685 struct frame *f;
1686 Lisp_Object name;
1687 int explicit;
1689 /* Make sure that requests from lisp code override requests from
1690 Emacs redisplay code. */
1691 if (explicit)
1693 /* If we're switching from explicit to implicit, we had better
1694 update the mode lines and thereby update the title. */
1695 if (f->explicit_name && NILP (name))
1696 update_mode_lines = 1;
1698 f->explicit_name = ! NILP (name);
1700 else if (f->explicit_name)
1701 return;
1703 /* If NAME is nil, set the name to the x_id_name. */
1704 if (NILP (name))
1706 /* Check for no change needed in this very common case
1707 before we do any consing. */
1708 if (!strcmp (FRAME_X_DISPLAY_INFO (f)->x_id_name,
1709 SDATA (f->name)))
1710 return;
1711 name = build_string (FRAME_X_DISPLAY_INFO (f)->x_id_name);
1713 else
1714 CHECK_STRING (name);
1716 /* Don't change the name if it's already NAME. */
1717 if (! NILP (Fstring_equal (name, f->name)))
1718 return;
1720 f->name = name;
1722 /* For setting the frame title, the title parameter should override
1723 the name parameter. */
1724 if (! NILP (f->title))
1725 name = f->title;
1727 x_set_name_internal (f, name);
1730 /* This function should be called when the user's lisp code has
1731 specified a name for the frame; the name will override any set by the
1732 redisplay code. */
1733 void
1734 x_explicitly_set_name (f, arg, oldval)
1735 FRAME_PTR f;
1736 Lisp_Object arg, oldval;
1738 x_set_name (f, arg, 1);
1741 /* This function should be called by Emacs redisplay code to set the
1742 name; names set this way will never override names set by the user's
1743 lisp code. */
1744 void
1745 x_implicitly_set_name (f, arg, oldval)
1746 FRAME_PTR f;
1747 Lisp_Object arg, oldval;
1749 x_set_name (f, arg, 0);
1752 /* Change the title of frame F to NAME.
1753 If NAME is nil, use the frame name as the title. */
1755 void
1756 x_set_title (f, name, old_name)
1757 struct frame *f;
1758 Lisp_Object name, old_name;
1760 /* Don't change the title if it's already NAME. */
1761 if (EQ (name, f->title))
1762 return;
1764 update_mode_lines = 1;
1766 f->title = name;
1768 if (NILP (name))
1769 name = f->name;
1770 else
1771 CHECK_STRING (name);
1773 x_set_name_internal (f, name);
1776 void
1777 x_set_scroll_bar_default_width (f)
1778 struct frame *f;
1780 int wid = FRAME_COLUMN_WIDTH (f);
1782 #ifdef USE_TOOLKIT_SCROLL_BARS
1783 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
1784 int width = 16 + 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM;
1785 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (width + wid - 1) / wid;
1786 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = width;
1787 #else
1788 /* Make the actual width at least 14 pixels and a multiple of a
1789 character width. */
1790 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
1792 /* Use all of that space (aside from required margins) for the
1793 scroll bar. */
1794 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 0;
1795 #endif
1799 /* Record in frame F the specified or default value according to ALIST
1800 of the parameter named PROP (a Lisp symbol). If no value is
1801 specified for PROP, look for an X default for XPROP on the frame
1802 named NAME. If that is not found either, use the value DEFLT. */
1804 static Lisp_Object
1805 x_default_scroll_bar_color_parameter (f, alist, prop, xprop, xclass,
1806 foreground_p)
1807 struct frame *f;
1808 Lisp_Object alist;
1809 Lisp_Object prop;
1810 char *xprop;
1811 char *xclass;
1812 int foreground_p;
1814 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
1815 Lisp_Object tem;
1817 tem = x_get_arg (dpyinfo, alist, prop, xprop, xclass, RES_TYPE_STRING);
1818 if (EQ (tem, Qunbound))
1820 #ifdef USE_TOOLKIT_SCROLL_BARS
1822 /* See if an X resource for the scroll bar color has been
1823 specified. */
1824 tem = display_x_get_resource (dpyinfo,
1825 build_string (foreground_p
1826 ? "foreground"
1827 : "background"),
1828 empty_unibyte_string,
1829 build_string ("verticalScrollBar"),
1830 empty_unibyte_string);
1831 if (!STRINGP (tem))
1833 /* If nothing has been specified, scroll bars will use a
1834 toolkit-dependent default. Because these defaults are
1835 difficult to get at without actually creating a scroll
1836 bar, use nil to indicate that no color has been
1837 specified. */
1838 tem = Qnil;
1841 #else /* not USE_TOOLKIT_SCROLL_BARS */
1843 tem = Qnil;
1845 #endif /* not USE_TOOLKIT_SCROLL_BARS */
1848 x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));
1849 return tem;
1855 #ifdef USE_X_TOOLKIT
1857 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
1858 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
1859 already be present because of the toolkit (Motif adds some of them,
1860 for example, but Xt doesn't). */
1862 static void
1863 hack_wm_protocols (f, widget)
1864 FRAME_PTR f;
1865 Widget widget;
1867 Display *dpy = XtDisplay (widget);
1868 Window w = XtWindow (widget);
1869 int need_delete = 1;
1870 int need_focus = 1;
1871 int need_save = 1;
1873 BLOCK_INPUT;
1875 Atom type;
1876 unsigned char *catoms;
1877 int format = 0;
1878 unsigned long nitems = 0;
1879 unsigned long bytes_after;
1881 if ((XGetWindowProperty (dpy, w,
1882 FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
1883 (long)0, (long)100, False, XA_ATOM,
1884 &type, &format, &nitems, &bytes_after,
1885 &catoms)
1886 == Success)
1887 && format == 32 && type == XA_ATOM)
1889 Atom *atoms = (Atom *) catoms;
1890 while (nitems > 0)
1892 nitems--;
1893 if (atoms[nitems]
1894 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window)
1895 need_delete = 0;
1896 else if (atoms[nitems]
1897 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus)
1898 need_focus = 0;
1899 else if (atoms[nitems]
1900 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself)
1901 need_save = 0;
1904 if (catoms)
1905 XFree (catoms);
1908 Atom props [10];
1909 int count = 0;
1910 if (need_delete)
1911 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window;
1912 if (need_focus)
1913 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus;
1914 if (need_save)
1915 props[count++] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
1916 if (count)
1917 XChangeProperty (dpy, w, FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
1918 XA_ATOM, 32, PropModeAppend,
1919 (unsigned char *) props, count);
1921 UNBLOCK_INPUT;
1923 #endif
1927 /* Support routines for XIC (X Input Context). */
1929 #ifdef HAVE_X_I18N
1931 static XFontSet xic_create_xfontset P_ ((struct frame *, char *));
1932 static XFontSet xic_create_xfontset2 P_ ((struct frame *));
1933 static XIMStyle best_xim_style P_ ((XIMStyles *, XIMStyles *));
1936 /* Supported XIM styles, ordered by preference. */
1938 static XIMStyle supported_xim_styles[] =
1940 XIMPreeditPosition | XIMStatusArea,
1941 XIMPreeditPosition | XIMStatusNothing,
1942 XIMPreeditPosition | XIMStatusNone,
1943 XIMPreeditNothing | XIMStatusArea,
1944 XIMPreeditNothing | XIMStatusNothing,
1945 XIMPreeditNothing | XIMStatusNone,
1946 XIMPreeditNone | XIMStatusArea,
1947 XIMPreeditNone | XIMStatusNothing,
1948 XIMPreeditNone | XIMStatusNone,
1953 /* Create an X fontset on frame F with base font name BASE_FONTNAME. */
1955 char xic_defaut_fontset[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
1957 /* Create an Xt fontset spec from the name of a base font.
1958 If `motif' is True use the Motif syntax. */
1959 char *
1960 xic_create_fontsetname (base_fontname, motif)
1961 char *base_fontname;
1962 Bool motif;
1964 const char *sep = motif ? ";" : ",";
1965 char *fontsetname;
1967 /* Make a fontset name from the base font name. */
1968 if (xic_defaut_fontset == base_fontname)
1969 { /* There is no base font name, use the default. */
1970 int len = strlen (base_fontname) + 2;
1971 fontsetname = xmalloc (len);
1972 bzero (fontsetname, len);
1973 strcpy (fontsetname, base_fontname);
1975 else
1977 /* Make a fontset name from the base font name.
1978 The font set will be made of the following elements:
1979 - the base font.
1980 - the base font where the charset spec is replaced by -*-*.
1981 - the same but with the family also replaced with -*-*-. */
1982 char *p = base_fontname;
1983 int i;
1985 for (i = 0; *p; p++)
1986 if (*p == '-') i++;
1987 if (i != 14)
1988 { /* As the font name doesn't conform to XLFD, we can't
1989 modify it to generalize it to allcs and allfamilies.
1990 Use the specified font plus the default. */
1991 int len = strlen (base_fontname) + strlen (xic_defaut_fontset) + 3;
1992 fontsetname = xmalloc (len);
1993 bzero (fontsetname, len);
1994 strcpy (fontsetname, base_fontname);
1995 strcat (fontsetname, sep);
1996 strcat (fontsetname, xic_defaut_fontset);
1998 else
2000 int len;
2001 char *p1 = NULL, *p2 = NULL, *p3 = NULL;
2002 char *font_allcs = NULL;
2003 char *font_allfamilies = NULL;
2004 char *font_all = NULL;
2005 char *allcs = "*-*-*-*-*-*-*";
2006 char *allfamilies = "-*-*-";
2007 char *all = "*-*-*-*-";
2008 char *base;
2010 for (i = 0, p = base_fontname; i < 8; p++)
2012 if (*p == '-')
2014 i++;
2015 if (i == 3)
2016 p1 = p + 1;
2017 else if (i == 7)
2018 p2 = p + 1;
2019 else if (i == 6)
2020 p3 = p + 1;
2023 /* If base_fontname specifies ADSTYLE, make it a
2024 wildcard. */
2025 if (*p3 != '*')
2027 int diff = (p2 - p3) - 2;
2029 base = alloca (strlen (base_fontname) + 1);
2030 bcopy (base_fontname, base, p3 - base_fontname);
2031 base[p3 - base_fontname] = '*';
2032 base[(p3 - base_fontname) + 1] = '-';
2033 strcpy (base + (p3 - base_fontname) + 2, p2);
2034 p = base + (p - base_fontname) - diff;
2035 p1 = base + (p1 - base_fontname);
2036 p2 = base + (p2 - base_fontname) - diff;
2037 base_fontname = base;
2040 /* Build the font spec that matches all charsets. */
2041 len = p - base_fontname + strlen (allcs) + 1;
2042 font_allcs = (char *) alloca (len);
2043 bzero (font_allcs, len);
2044 bcopy (base_fontname, font_allcs, p - base_fontname);
2045 strcat (font_allcs, allcs);
2047 /* Build the font spec that matches all families and
2048 add-styles. */
2049 len = p - p1 + strlen (allcs) + strlen (allfamilies) + 1;
2050 font_allfamilies = (char *) alloca (len);
2051 bzero (font_allfamilies, len);
2052 strcpy (font_allfamilies, allfamilies);
2053 bcopy (p1, font_allfamilies + strlen (allfamilies), p - p1);
2054 strcat (font_allfamilies, allcs);
2056 /* Build the font spec that matches all. */
2057 len = p - p2 + strlen (allcs) + strlen (all) + strlen (allfamilies) + 1;
2058 font_all = (char *) alloca (len);
2059 bzero (font_all, len);
2060 strcpy (font_all, allfamilies);
2061 strcat (font_all, all);
2062 bcopy (p2, font_all + strlen (all) + strlen (allfamilies), p - p2);
2063 strcat (font_all, allcs);
2065 /* Build the actual font set name. */
2066 len = strlen (base_fontname) + strlen (font_allcs)
2067 + strlen (font_allfamilies) + strlen (font_all) + 5;
2068 fontsetname = xmalloc (len);
2069 bzero (fontsetname, len);
2070 strcpy (fontsetname, base_fontname);
2071 strcat (fontsetname, sep);
2072 strcat (fontsetname, font_allcs);
2073 strcat (fontsetname, sep);
2074 strcat (fontsetname, font_allfamilies);
2075 strcat (fontsetname, sep);
2076 strcat (fontsetname, font_all);
2079 if (motif)
2080 strcat (fontsetname, ":");
2081 return fontsetname;
2084 #ifdef DEBUG_XIC_FONTSET
2085 static void
2086 print_fontset_result (xfs, name, missing_list, missing_count)
2087 XFontSet xfs;
2088 char *name;
2089 char **missing_list;
2090 int missing_count;
2092 if (xfs)
2093 fprintf (stderr, "XIC Fontset created: %s\n", name);
2094 else
2096 fprintf (stderr, "XIC Fontset failed: %s\n", name);
2097 while (missing_count-- > 0)
2099 fprintf (stderr, " missing: %s\n", *missing_list);
2100 missing_list++;
2105 #endif
2107 static XFontSet
2108 xic_create_xfontset (f, base_fontname)
2109 struct frame *f;
2110 char *base_fontname;
2112 XFontSet xfs = NULL;
2113 char **missing_list = NULL;
2114 int missing_count;
2115 char *def_string;
2116 Lisp_Object rest, frame;
2118 if (!base_fontname)
2119 base_fontname = xic_defaut_fontset;
2121 /* See if there is another frame already using same fontset. */
2122 FOR_EACH_FRAME (rest, frame)
2124 struct frame *cf = XFRAME (frame);
2125 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
2126 && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f)
2127 && FRAME_XIC_BASE_FONTNAME (cf)
2128 && !strcmp (FRAME_XIC_BASE_FONTNAME (cf), base_fontname))
2130 xfs = FRAME_XIC_FONTSET (cf);
2131 break;
2135 if (!xfs)
2137 char *fontsetname = xic_create_fontsetname (base_fontname, False);
2139 /* New fontset. */
2140 xfs = XCreateFontSet (FRAME_X_DISPLAY (f),
2141 fontsetname, &missing_list,
2142 &missing_count, &def_string);
2143 #ifdef DEBUG_XIC_FONTSET
2144 print_fontset_result (xfs, fontsetname, missing_list, missing_count);
2145 #endif
2146 if (missing_list)
2147 XFreeStringList (missing_list);
2148 if (! xfs)
2150 /* FONTSETNAME contains a list of font names (specific fonts
2151 first, general fonts last), but giving that to
2152 XCreateFontSet at once occasionally fails (bug of X?).
2153 So, we try to call XCreateFontSet for each fontname. */
2154 char *p0 = fontsetname, *p1;
2156 while (p0)
2158 p1 = strchr (p0, ',');
2159 if (p1)
2160 *p1 = '\0';
2161 xfs = XCreateFontSet (FRAME_X_DISPLAY (f),
2162 p0, &missing_list,
2163 &missing_count, &def_string);
2164 #ifdef DEBUG_XIC_FONTSET
2165 print_fontset_result (xfs, p0, missing_list, missing_count);
2166 #endif
2167 if (missing_list)
2168 XFreeStringList (missing_list);
2169 if (xfs)
2170 break;
2171 p0 = p1 ? p1 + 1 : NULL;
2174 xfree (fontsetname);
2175 if (! xfs && base_fontname != xic_defaut_fontset)
2177 /* Try the default fontset name at a last resort. */
2178 fontsetname = xic_create_fontsetname (xic_defaut_fontset, False);
2179 xfs = XCreateFontSet (FRAME_X_DISPLAY (f),
2180 fontsetname, &missing_list,
2181 &missing_count, &def_string);
2182 #ifdef DEBUG_XIC_FONTSET
2183 print_fontset_result (xfs, fontsetname, missing_list, missing_count);
2184 #endif
2185 if (missing_list)
2186 XFreeStringList (missing_list);
2187 xfree (fontsetname);
2191 if (FRAME_XIC_BASE_FONTNAME (f))
2192 xfree (FRAME_XIC_BASE_FONTNAME (f));
2193 FRAME_XIC_BASE_FONTNAME (f) = xstrdup (base_fontname);
2195 /* No need to free def_string. */
2196 return xfs;
2199 #ifdef USE_FONT_BACKEND
2201 static XFontSet
2202 xic_create_xfontset2 (f)
2203 struct frame *f;
2205 XFontSet xfs = NULL;
2206 struct font *font = FRAME_FONT_OBJECT (f);
2207 int pixel_size = font->pixel_size;
2208 Lisp_Object rest, frame;
2210 /* See if there is another frame already using same fontset. */
2211 FOR_EACH_FRAME (rest, frame)
2213 struct frame *cf = XFRAME (frame);
2215 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
2216 && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f)
2217 && FRAME_FONT_OBJECT (f)
2218 && FRAME_FONT_OBJECT (f)->pixel_size == pixel_size)
2220 xfs = FRAME_XIC_FONTSET (cf);
2221 break;
2225 if (! xfs)
2227 char buf[256];
2228 char **missing_list;
2229 int missing_count;
2230 char *def_string;
2231 char *xlfd_format = "-*-*-medium-r-normal--%d-*-*-*-*-*";
2233 sprintf (buf, xlfd_format, pixel_size);
2234 missing_list = NULL;
2235 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
2236 &missing_list, &missing_count, &def_string);
2237 #ifdef DEBUG_XIC_FONTSET
2238 print_fontset_result (xfs, buf, missing_list, missing_count);
2239 #endif
2240 if (missing_list)
2241 XFreeStringList (missing_list);
2242 if (! xfs)
2244 /* List of pixel sizes most likely available. Find one that
2245 is closest to pixel_size. */
2246 int sizes[] = {0, 8, 10, 11, 12, 14, 17, 18, 20, 24, 26, 34, 0};
2247 int *smaller, *larger;
2249 for (smaller = sizes; smaller[1]; smaller++)
2250 if (smaller[1] >= pixel_size)
2251 break;
2252 larger = smaller + 1;
2253 if (*larger == pixel_size)
2254 larger++;
2255 while (*smaller || *larger)
2257 int this_size;
2259 if (! *larger)
2260 this_size = *smaller--;
2261 else if (! *smaller)
2262 this_size = *larger++;
2263 else if (pixel_size - *smaller < *larger - pixel_size)
2264 this_size = *smaller--;
2265 else
2266 this_size = *larger++;
2267 sprintf (buf, xlfd_format, this_size);
2268 missing_list = NULL;
2269 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
2270 &missing_list, &missing_count, &def_string);
2271 #ifdef DEBUG_XIC_FONTSET
2272 print_fontset_result (xfs, buf, missing_list, missing_count);
2273 #endif
2274 if (missing_list)
2275 XFreeStringList (missing_list);
2276 if (xfs)
2277 break;
2280 if (! xfs)
2282 char *last_resort = "-*-*-*-r-normal--*-*-*-*-*-*";
2284 missing_list = NULL;
2285 xfs = XCreateFontSet (FRAME_X_DISPLAY (f), last_resort,
2286 &missing_list, &missing_count, &def_string);
2287 #ifdef DEBUG_XIC_FONTSET
2288 print_fontset_result (xfs, last_resort, missing_list, missing_count);
2289 #endif
2290 if (missing_list)
2291 XFreeStringList (missing_list);
2296 return xfs;
2298 #endif /* USE_FONT_BACKEND */
2300 /* Free the X fontset of frame F if it is the last frame using it. */
2302 void
2303 xic_free_xfontset (f)
2304 struct frame *f;
2306 Lisp_Object rest, frame;
2307 int shared_p = 0;
2309 if (!FRAME_XIC_FONTSET (f))
2310 return;
2312 /* See if there is another frame sharing the same fontset. */
2313 FOR_EACH_FRAME (rest, frame)
2315 struct frame *cf = XFRAME (frame);
2316 if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
2317 && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f)
2318 && FRAME_XIC_FONTSET (cf) == FRAME_XIC_FONTSET (f))
2320 shared_p = 1;
2321 break;
2325 if (!shared_p)
2326 /* The fontset is not used anymore. It is safe to free it. */
2327 XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f));
2329 if (FRAME_XIC_BASE_FONTNAME (f))
2330 xfree (FRAME_XIC_BASE_FONTNAME (f));
2331 FRAME_XIC_BASE_FONTNAME (f) = NULL;
2332 FRAME_XIC_FONTSET (f) = NULL;
2336 /* Value is the best input style, given user preferences USER (already
2337 checked to be supported by Emacs), and styles supported by the
2338 input method XIM. */
2340 static XIMStyle
2341 best_xim_style (user, xim)
2342 XIMStyles *user;
2343 XIMStyles *xim;
2345 int i, j;
2347 for (i = 0; i < user->count_styles; ++i)
2348 for (j = 0; j < xim->count_styles; ++j)
2349 if (user->supported_styles[i] == xim->supported_styles[j])
2350 return user->supported_styles[i];
2352 /* Return the default style. */
2353 return XIMPreeditNothing | XIMStatusNothing;
2356 /* Create XIC for frame F. */
2358 static XIMStyle xic_style;
2360 void
2361 create_frame_xic (f)
2362 struct frame *f;
2364 XIM xim;
2365 XIC xic = NULL;
2366 XFontSet xfs = NULL;
2368 if (FRAME_XIC (f))
2369 return;
2371 /* Create X fontset. */
2372 #ifdef USE_FONT_BACKEND
2373 if (enable_font_backend)
2374 xfs = xic_create_xfontset2 (f);
2375 else
2376 #endif
2377 xfs = xic_create_xfontset
2378 (f, (FRAME_FONTSET (f) < 0) ? NULL
2379 : (char *) SDATA (fontset_ascii (FRAME_FONTSET (f))));
2381 xim = FRAME_X_XIM (f);
2382 if (xim)
2384 XRectangle s_area;
2385 XPoint spot;
2386 XVaNestedList preedit_attr;
2387 XVaNestedList status_attr;
2389 s_area.x = 0; s_area.y = 0; s_area.width = 1; s_area.height = 1;
2390 spot.x = 0; spot.y = 1;
2392 /* Determine XIC style. */
2393 if (xic_style == 0)
2395 XIMStyles supported_list;
2396 supported_list.count_styles = (sizeof supported_xim_styles
2397 / sizeof supported_xim_styles[0]);
2398 supported_list.supported_styles = supported_xim_styles;
2399 xic_style = best_xim_style (&supported_list,
2400 FRAME_X_XIM_STYLES (f));
2403 preedit_attr = XVaCreateNestedList (0,
2404 XNFontSet, xfs,
2405 XNForeground,
2406 FRAME_FOREGROUND_PIXEL (f),
2407 XNBackground,
2408 FRAME_BACKGROUND_PIXEL (f),
2409 (xic_style & XIMPreeditPosition
2410 ? XNSpotLocation
2411 : NULL),
2412 &spot,
2413 NULL);
2414 status_attr = XVaCreateNestedList (0,
2415 XNArea,
2416 &s_area,
2417 XNFontSet,
2418 xfs,
2419 XNForeground,
2420 FRAME_FOREGROUND_PIXEL (f),
2421 XNBackground,
2422 FRAME_BACKGROUND_PIXEL (f),
2423 NULL);
2425 xic = XCreateIC (xim,
2426 XNInputStyle, xic_style,
2427 XNClientWindow, FRAME_X_WINDOW (f),
2428 XNFocusWindow, FRAME_X_WINDOW (f),
2429 XNStatusAttributes, status_attr,
2430 XNPreeditAttributes, preedit_attr,
2431 NULL);
2432 XFree (preedit_attr);
2433 XFree (status_attr);
2436 FRAME_XIC (f) = xic;
2437 FRAME_XIC_STYLE (f) = xic_style;
2438 FRAME_XIC_FONTSET (f) = xfs;
2442 /* Destroy XIC and free XIC fontset of frame F, if any. */
2444 void
2445 free_frame_xic (f)
2446 struct frame *f;
2448 if (FRAME_XIC (f) == NULL)
2449 return;
2451 XDestroyIC (FRAME_XIC (f));
2452 xic_free_xfontset (f);
2454 FRAME_XIC (f) = NULL;
2458 /* Place preedit area for XIC of window W's frame to specified
2459 pixel position X/Y. X and Y are relative to window W. */
2461 void
2462 xic_set_preeditarea (w, x, y)
2463 struct window *w;
2464 int x, y;
2466 struct frame *f = XFRAME (w->frame);
2467 XVaNestedList attr;
2468 XPoint spot;
2470 spot.x = WINDOW_TO_FRAME_PIXEL_X (w, x) + WINDOW_LEFT_FRINGE_WIDTH (w);
2471 spot.y = WINDOW_TO_FRAME_PIXEL_Y (w, y) + FONT_BASE (FRAME_FONT (f));
2472 attr = XVaCreateNestedList (0, XNSpotLocation, &spot, NULL);
2473 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2474 XFree (attr);
2478 /* Place status area for XIC in bottom right corner of frame F.. */
2480 void
2481 xic_set_statusarea (f)
2482 struct frame *f;
2484 XIC xic = FRAME_XIC (f);
2485 XVaNestedList attr;
2486 XRectangle area;
2487 XRectangle *needed;
2489 /* Negotiate geometry of status area. If input method has existing
2490 status area, use its current size. */
2491 area.x = area.y = area.width = area.height = 0;
2492 attr = XVaCreateNestedList (0, XNAreaNeeded, &area, NULL);
2493 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2494 XFree (attr);
2496 attr = XVaCreateNestedList (0, XNAreaNeeded, &needed, NULL);
2497 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2498 XFree (attr);
2500 if (needed->width == 0) /* Use XNArea instead of XNAreaNeeded */
2502 attr = XVaCreateNestedList (0, XNArea, &needed, NULL);
2503 XGetICValues (xic, XNStatusAttributes, attr, NULL);
2504 XFree (attr);
2507 area.width = needed->width;
2508 area.height = needed->height;
2509 area.x = FRAME_PIXEL_WIDTH (f) - area.width - FRAME_INTERNAL_BORDER_WIDTH (f);
2510 area.y = (FRAME_PIXEL_HEIGHT (f) - area.height
2511 - FRAME_MENUBAR_HEIGHT (f)
2512 - FRAME_TOOLBAR_HEIGHT (f)
2513 - FRAME_INTERNAL_BORDER_WIDTH (f));
2514 XFree (needed);
2516 attr = XVaCreateNestedList (0, XNArea, &area, NULL);
2517 XSetICValues (xic, XNStatusAttributes, attr, NULL);
2518 XFree (attr);
2522 /* Set X fontset for XIC of frame F, using base font name
2523 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2525 void
2526 xic_set_xfontset (f, base_fontname)
2527 struct frame *f;
2528 char *base_fontname;
2530 XVaNestedList attr;
2531 XFontSet xfs;
2533 xic_free_xfontset (f);
2535 #ifdef USE_FONT_BACKEND
2536 if (enable_font_backend)
2537 xfs = xic_create_xfontset2 (f);
2538 else
2539 #endif
2540 xfs = xic_create_xfontset (f, base_fontname);
2542 attr = XVaCreateNestedList (0, XNFontSet, xfs, NULL);
2543 if (FRAME_XIC_STYLE (f) & XIMPreeditPosition)
2544 XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
2545 if (FRAME_XIC_STYLE (f) & XIMStatusArea)
2546 XSetICValues (FRAME_XIC (f), XNStatusAttributes, attr, NULL);
2547 XFree (attr);
2549 FRAME_XIC_FONTSET (f) = xfs;
2552 #endif /* HAVE_X_I18N */
2556 #ifdef USE_X_TOOLKIT
2558 /* Create and set up the X widget for frame F. */
2560 static void
2561 x_window (f, window_prompting, minibuffer_only)
2562 struct frame *f;
2563 long window_prompting;
2564 int minibuffer_only;
2566 XClassHint class_hints;
2567 XSetWindowAttributes attributes;
2568 unsigned long attribute_mask;
2569 Widget shell_widget;
2570 Widget pane_widget;
2571 Widget frame_widget;
2572 Arg al [25];
2573 int ac;
2575 BLOCK_INPUT;
2577 /* Use the resource name as the top-level widget name
2578 for looking up resources. Make a non-Lisp copy
2579 for the window manager, so GC relocation won't bother it.
2581 Elsewhere we specify the window name for the window manager. */
2584 char *str = (char *) SDATA (Vx_resource_name);
2585 f->namebuf = (char *) xmalloc (strlen (str) + 1);
2586 strcpy (f->namebuf, str);
2589 ac = 0;
2590 XtSetArg (al[ac], XtNallowShellResize, 1); ac++;
2591 XtSetArg (al[ac], XtNinput, 1); ac++;
2592 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2593 XtSetArg (al[ac], XtNborderWidth, f->border_width); ac++;
2594 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2595 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2596 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2597 shell_widget = XtAppCreateShell (f->namebuf, EMACS_CLASS,
2598 applicationShellWidgetClass,
2599 FRAME_X_DISPLAY (f), al, ac);
2601 f->output_data.x->widget = shell_widget;
2602 /* maybe_set_screen_title_format (shell_widget); */
2604 pane_widget = lw_create_widget ("main", "pane", widget_id_tick++,
2605 (widget_value *) NULL,
2606 shell_widget, False,
2607 (lw_callback) NULL,
2608 (lw_callback) NULL,
2609 (lw_callback) NULL,
2610 (lw_callback) NULL);
2612 ac = 0;
2613 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2614 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2615 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2616 XtSetValues (pane_widget, al, ac);
2617 f->output_data.x->column_widget = pane_widget;
2619 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2620 the emacs screen when changing menubar. This reduces flickering. */
2622 ac = 0;
2623 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
2624 XtSetArg (al[ac], XtNshowGrip, 0); ac++;
2625 XtSetArg (al[ac], XtNallowResize, 1); ac++;
2626 XtSetArg (al[ac], XtNresizeToPreferred, 1); ac++;
2627 XtSetArg (al[ac], XtNemacsFrame, f); ac++;
2628 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
2629 XtSetArg (al[ac], XtNdepth, FRAME_X_DISPLAY_INFO (f)->n_planes); ac++;
2630 XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
2631 frame_widget = XtCreateWidget (f->namebuf, emacsFrameClass, pane_widget,
2632 al, ac);
2634 f->output_data.x->edit_widget = frame_widget;
2636 XtManageChild (frame_widget);
2638 /* Do some needed geometry management. */
2640 int len;
2641 char *tem, shell_position[32];
2642 Arg al[10];
2643 int ac = 0;
2644 int extra_borders = 0;
2645 int menubar_size
2646 = (f->output_data.x->menubar_widget
2647 ? (f->output_data.x->menubar_widget->core.height
2648 + f->output_data.x->menubar_widget->core.border_width)
2649 : 0);
2651 #if 0 /* Experimentally, we now get the right results
2652 for -geometry -0-0 without this. 24 Aug 96, rms. */
2653 if (FRAME_EXTERNAL_MENU_BAR (f))
2655 Dimension ibw = 0;
2656 XtVaGetValues (pane_widget, XtNinternalBorderWidth, &ibw, NULL);
2657 menubar_size += ibw;
2659 #endif
2661 f->output_data.x->menubar_height = menubar_size;
2663 #ifndef USE_LUCID
2664 /* Motif seems to need this amount added to the sizes
2665 specified for the shell widget. The Athena/Lucid widgets don't.
2666 Both conclusions reached experimentally. -- rms. */
2667 XtVaGetValues (f->output_data.x->edit_widget, XtNinternalBorderWidth,
2668 &extra_borders, NULL);
2669 extra_borders *= 2;
2670 #endif
2672 /* Convert our geometry parameters into a geometry string
2673 and specify it.
2674 Note that we do not specify here whether the position
2675 is a user-specified or program-specified one.
2676 We pass that information later, in x_wm_set_size_hints. */
2678 int left = f->left_pos;
2679 int xneg = window_prompting & XNegative;
2680 int top = f->top_pos;
2681 int yneg = window_prompting & YNegative;
2682 if (xneg)
2683 left = -left;
2684 if (yneg)
2685 top = -top;
2687 if (window_prompting & USPosition)
2688 sprintf (shell_position, "=%dx%d%c%d%c%d",
2689 FRAME_PIXEL_WIDTH (f) + extra_borders,
2690 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders,
2691 (xneg ? '-' : '+'), left,
2692 (yneg ? '-' : '+'), top);
2693 else
2695 sprintf (shell_position, "=%dx%d",
2696 FRAME_PIXEL_WIDTH (f) + extra_borders,
2697 FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders);
2699 /* Setting x and y when the position is not specified in
2700 the geometry string will set program position in the WM hints.
2701 If Emacs had just one program position, we could set it in
2702 fallback resources, but since each make-frame call can specify
2703 different program positions, this is easier. */
2704 XtSetArg (al[ac], XtNx, left); ac++;
2705 XtSetArg (al[ac], XtNy, top); ac++;
2709 len = strlen (shell_position) + 1;
2710 /* We don't free this because we don't know whether
2711 it is safe to free it while the frame exists.
2712 It isn't worth the trouble of arranging to free it
2713 when the frame is deleted. */
2714 tem = (char *) xmalloc (len);
2715 strncpy (tem, shell_position, len);
2716 XtSetArg (al[ac], XtNgeometry, tem); ac++;
2717 XtSetValues (shell_widget, al, ac);
2720 XtManageChild (pane_widget);
2721 XtRealizeWidget (shell_widget);
2723 if (FRAME_X_EMBEDDED_P (f))
2724 XReparentWindow (FRAME_X_DISPLAY (f), XtWindow (shell_widget),
2725 f->output_data.x->parent_desc, 0, 0);
2727 FRAME_X_WINDOW (f) = XtWindow (frame_widget);
2729 validate_x_resource_name ();
2731 class_hints.res_name = (char *) SDATA (Vx_resource_name);
2732 class_hints.res_class = (char *) SDATA (Vx_resource_class);
2733 XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints);
2735 #ifdef HAVE_X_I18N
2736 FRAME_XIC (f) = NULL;
2737 if (use_xim)
2738 create_frame_xic (f);
2739 #endif
2741 f->output_data.x->wm_hints.input = True;
2742 f->output_data.x->wm_hints.flags |= InputHint;
2743 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2744 &f->output_data.x->wm_hints);
2746 hack_wm_protocols (f, shell_widget);
2748 #ifdef HACK_EDITRES
2749 XtAddEventHandler (shell_widget, 0, True, _XEditResCheckMessages, 0);
2750 #endif
2752 /* Do a stupid property change to force the server to generate a
2753 PropertyNotify event so that the event_stream server timestamp will
2754 be initialized to something relevant to the time we created the window.
2756 XChangeProperty (XtDisplay (frame_widget), XtWindow (frame_widget),
2757 FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
2758 XA_ATOM, 32, PropModeAppend,
2759 (unsigned char*) NULL, 0);
2761 /* Make all the standard events reach the Emacs frame. */
2762 attributes.event_mask = STANDARD_EVENT_SET;
2764 #ifdef HAVE_X_I18N
2765 if (FRAME_XIC (f))
2767 /* XIM server might require some X events. */
2768 unsigned long fevent = NoEventMask;
2769 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2770 attributes.event_mask |= fevent;
2772 #endif /* HAVE_X_I18N */
2774 attribute_mask = CWEventMask;
2775 XChangeWindowAttributes (XtDisplay (shell_widget), XtWindow (shell_widget),
2776 attribute_mask, &attributes);
2778 XtMapWidget (frame_widget);
2780 /* x_set_name normally ignores requests to set the name if the
2781 requested name is the same as the current name. This is the one
2782 place where that assumption isn't correct; f->name is set, but
2783 the X server hasn't been told. */
2785 Lisp_Object name;
2786 int explicit = f->explicit_name;
2788 f->explicit_name = 0;
2789 name = f->name;
2790 f->name = Qnil;
2791 x_set_name (f, name, explicit);
2794 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2795 f->output_data.x->text_cursor);
2797 UNBLOCK_INPUT;
2799 /* This is a no-op, except under Motif. Make sure main areas are
2800 set to something reasonable, in case we get an error later. */
2801 lw_set_main_areas (pane_widget, 0, frame_widget);
2804 #else /* not USE_X_TOOLKIT */
2805 #ifdef USE_GTK
2806 void
2807 x_window (f)
2808 FRAME_PTR f;
2810 if (! xg_create_frame_widgets (f))
2811 error ("Unable to create window");
2813 #ifdef HAVE_X_I18N
2814 FRAME_XIC (f) = NULL;
2815 if (use_xim)
2817 BLOCK_INPUT;
2818 create_frame_xic (f);
2819 if (FRAME_XIC (f))
2821 /* XIM server might require some X events. */
2822 unsigned long fevent = NoEventMask;
2823 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2825 if (fevent != NoEventMask)
2827 XSetWindowAttributes attributes;
2828 XWindowAttributes wattr;
2829 unsigned long attribute_mask;
2831 XGetWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2832 &wattr);
2833 attributes.event_mask = wattr.your_event_mask | fevent;
2834 attribute_mask = CWEventMask;
2835 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2836 attribute_mask, &attributes);
2839 UNBLOCK_INPUT;
2841 #endif
2844 #else /*! USE_GTK */
2845 /* Create and set up the X window for frame F. */
2847 void
2848 x_window (f)
2849 struct frame *f;
2852 XClassHint class_hints;
2853 XSetWindowAttributes attributes;
2854 unsigned long attribute_mask;
2856 attributes.background_pixel = FRAME_BACKGROUND_PIXEL (f);
2857 attributes.border_pixel = f->output_data.x->border_pixel;
2858 attributes.bit_gravity = StaticGravity;
2859 attributes.backing_store = NotUseful;
2860 attributes.save_under = True;
2861 attributes.event_mask = STANDARD_EVENT_SET;
2862 attributes.colormap = FRAME_X_COLORMAP (f);
2863 attribute_mask = (CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask
2864 | CWColormap);
2866 BLOCK_INPUT;
2867 FRAME_X_WINDOW (f)
2868 = XCreateWindow (FRAME_X_DISPLAY (f),
2869 f->output_data.x->parent_desc,
2870 f->left_pos,
2871 f->top_pos,
2872 FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
2873 f->border_width,
2874 CopyFromParent, /* depth */
2875 InputOutput, /* class */
2876 FRAME_X_VISUAL (f),
2877 attribute_mask, &attributes);
2879 #ifdef HAVE_X_I18N
2880 if (use_xim)
2882 create_frame_xic (f);
2883 if (FRAME_XIC (f))
2885 /* XIM server might require some X events. */
2886 unsigned long fevent = NoEventMask;
2887 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
2888 attributes.event_mask |= fevent;
2889 attribute_mask = CWEventMask;
2890 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2891 attribute_mask, &attributes);
2894 #endif /* HAVE_X_I18N */
2896 validate_x_resource_name ();
2898 class_hints.res_name = (char *) SDATA (Vx_resource_name);
2899 class_hints.res_class = (char *) SDATA (Vx_resource_class);
2900 XSetClassHint (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &class_hints);
2902 /* The menubar is part of the ordinary display;
2903 it does not count in addition to the height of the window. */
2904 f->output_data.x->menubar_height = 0;
2906 /* This indicates that we use the "Passive Input" input model.
2907 Unless we do this, we don't get the Focus{In,Out} events that we
2908 need to draw the cursor correctly. Accursed bureaucrats.
2909 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2911 f->output_data.x->wm_hints.input = True;
2912 f->output_data.x->wm_hints.flags |= InputHint;
2913 XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2914 &f->output_data.x->wm_hints);
2915 f->output_data.x->wm_hints.icon_pixmap = None;
2917 /* Request "save yourself" and "delete window" commands from wm. */
2919 Atom protocols[2];
2920 protocols[0] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window;
2921 protocols[1] = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
2922 XSetWMProtocols (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), protocols, 2);
2925 /* x_set_name normally ignores requests to set the name if the
2926 requested name is the same as the current name. This is the one
2927 place where that assumption isn't correct; f->name is set, but
2928 the X server hasn't been told. */
2930 Lisp_Object name;
2931 int explicit = f->explicit_name;
2933 f->explicit_name = 0;
2934 name = f->name;
2935 f->name = Qnil;
2936 x_set_name (f, name, explicit);
2939 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2940 f->output_data.x->text_cursor);
2942 UNBLOCK_INPUT;
2944 if (FRAME_X_WINDOW (f) == 0)
2945 error ("Unable to create window");
2948 #endif /* not USE_GTK */
2949 #endif /* not USE_X_TOOLKIT */
2951 /* Verify that the icon position args for this window are valid. */
2953 static void
2954 x_icon_verify (f, parms)
2955 struct frame *f;
2956 Lisp_Object parms;
2958 Lisp_Object icon_x, icon_y;
2960 /* Set the position of the icon. Note that twm groups all
2961 icons in an icon window. */
2962 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2963 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2964 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2966 CHECK_NUMBER (icon_x);
2967 CHECK_NUMBER (icon_y);
2969 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2970 error ("Both left and top icon corners of icon must be specified");
2973 /* Handle the icon stuff for this window. Perhaps later we might
2974 want an x_set_icon_position which can be called interactively as
2975 well. */
2977 static void
2978 x_icon (f, parms)
2979 struct frame *f;
2980 Lisp_Object parms;
2982 Lisp_Object icon_x, icon_y;
2983 #if 0
2984 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2985 #endif
2987 /* Set the position of the icon. Note that twm groups all
2988 icons in an icon window. */
2989 icon_x = x_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
2990 icon_y = x_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
2991 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2993 CHECK_NUMBER (icon_x);
2994 CHECK_NUMBER (icon_y);
2996 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2997 error ("Both left and top icon corners of icon must be specified");
2999 BLOCK_INPUT;
3001 if (! EQ (icon_x, Qunbound))
3002 x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
3004 #if 0 /* x_get_arg removes the visibility parameter as a side effect,
3005 but x_create_frame still needs it. */
3006 /* Start up iconic or window? */
3007 x_wm_set_window_state
3008 (f, (EQ (x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL),
3009 Qicon)
3010 ? IconicState
3011 : NormalState));
3012 #endif
3014 x_text_icon (f, (char *) SDATA ((!NILP (f->icon_name)
3015 ? f->icon_name
3016 : f->name)));
3018 UNBLOCK_INPUT;
3021 /* Make the GCs needed for this window, setting the
3022 background, border and mouse colors; also create the
3023 mouse cursor and the gray border tile. */
3025 static char cursor_bits[] =
3027 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3028 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3029 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3030 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3033 static void
3034 x_make_gc (f)
3035 struct frame *f;
3037 XGCValues gc_values;
3039 BLOCK_INPUT;
3041 /* Create the GCs of this frame.
3042 Note that many default values are used. */
3044 /* Normal video */
3045 #ifdef USE_FONT_BACKEND
3046 if (enable_font_backend)
3047 gc_values.font = FRAME_X_DISPLAY_INFO (f)->font->fid;
3048 else
3049 #endif
3050 gc_values.font = FRAME_FONT (f)->fid;
3051 gc_values.foreground = FRAME_FOREGROUND_PIXEL (f);
3052 gc_values.background = FRAME_BACKGROUND_PIXEL (f);
3053 gc_values.line_width = 0; /* Means 1 using fast algorithm. */
3054 f->output_data.x->normal_gc
3055 = XCreateGC (FRAME_X_DISPLAY (f),
3056 FRAME_X_WINDOW (f),
3057 GCLineWidth | GCFont | GCForeground | GCBackground,
3058 &gc_values);
3060 /* Reverse video style. */
3061 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
3062 gc_values.background = FRAME_FOREGROUND_PIXEL (f);
3063 f->output_data.x->reverse_gc
3064 = XCreateGC (FRAME_X_DISPLAY (f),
3065 FRAME_X_WINDOW (f),
3066 GCFont | GCForeground | GCBackground | GCLineWidth,
3067 &gc_values);
3069 /* Cursor has cursor-color background, background-color foreground. */
3070 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
3071 gc_values.background = f->output_data.x->cursor_pixel;
3072 gc_values.fill_style = FillOpaqueStippled;
3073 gc_values.stipple
3074 = XCreateBitmapFromData (FRAME_X_DISPLAY (f),
3075 FRAME_X_DISPLAY_INFO (f)->root_window,
3076 cursor_bits, 16, 16);
3077 f->output_data.x->cursor_gc
3078 = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3079 (GCFont | GCForeground | GCBackground
3080 | GCFillStyle /* | GCStipple */ | GCLineWidth),
3081 &gc_values);
3083 /* Reliefs. */
3084 f->output_data.x->white_relief.gc = 0;
3085 f->output_data.x->black_relief.gc = 0;
3087 /* Create the gray border tile used when the pointer is not in
3088 the frame. Since this depends on the frame's pixel values,
3089 this must be done on a per-frame basis. */
3090 f->output_data.x->border_tile
3091 = (XCreatePixmapFromBitmapData
3092 (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
3093 gray_bits, gray_width, gray_height,
3094 FRAME_FOREGROUND_PIXEL (f),
3095 FRAME_BACKGROUND_PIXEL (f),
3096 DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
3098 UNBLOCK_INPUT;
3102 /* Free what was was allocated in x_make_gc. */
3104 void
3105 x_free_gcs (f)
3106 struct frame *f;
3108 Display *dpy = FRAME_X_DISPLAY (f);
3110 BLOCK_INPUT;
3112 if (f->output_data.x->normal_gc)
3114 XFreeGC (dpy, f->output_data.x->normal_gc);
3115 f->output_data.x->normal_gc = 0;
3118 if (f->output_data.x->reverse_gc)
3120 XFreeGC (dpy, f->output_data.x->reverse_gc);
3121 f->output_data.x->reverse_gc = 0;
3124 if (f->output_data.x->cursor_gc)
3126 XFreeGC (dpy, f->output_data.x->cursor_gc);
3127 f->output_data.x->cursor_gc = 0;
3130 if (f->output_data.x->border_tile)
3132 XFreePixmap (dpy, f->output_data.x->border_tile);
3133 f->output_data.x->border_tile = 0;
3136 UNBLOCK_INPUT;
3140 /* Handler for signals raised during x_create_frame and
3141 x_create_top_frame. FRAME is the frame which is partially
3142 constructed. */
3144 static Lisp_Object
3145 unwind_create_frame (frame)
3146 Lisp_Object frame;
3148 struct frame *f = XFRAME (frame);
3150 /* If frame is already dead, nothing to do. This can happen if the
3151 display is disconnected after the frame has become official, but
3152 before x_create_frame removes the unwind protect. */
3153 if (!FRAME_LIVE_P (f))
3154 return Qnil;
3156 /* If frame is ``official'', nothing to do. */
3157 if (!CONSP (Vframe_list) || !EQ (XCAR (Vframe_list), frame))
3159 #if GLYPH_DEBUG
3160 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3161 #endif
3163 x_free_frame_resources (f);
3165 #if GLYPH_DEBUG
3166 /* Check that reference counts are indeed correct. */
3167 xassert (dpyinfo->reference_count == dpyinfo_refcount);
3168 xassert (dpyinfo->image_cache->refcount == image_cache_refcount);
3169 #endif
3170 return Qt;
3173 return Qnil;
3176 #ifdef USE_FONT_BACKEND
3177 static void
3178 x_default_font_parameter (f, parms)
3179 struct frame *f;
3180 Lisp_Object parms;
3182 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3183 Lisp_Object font = x_get_arg (dpyinfo, parms, Qfont, "font", "Font",
3184 RES_TYPE_STRING);
3186 if (! STRINGP (font))
3188 char *names[]
3189 = { "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
3190 "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3191 "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3192 /* This was formerly the first thing tried, but it finds
3193 too many fonts and takes too long. */
3194 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
3195 /* If those didn't work, look for something which will
3196 at least work. */
3197 "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
3198 "fixed",
3199 NULL };
3200 int i;
3202 for (i = 0; names[i]; i++)
3204 font = font_open_by_name (f, names[i]);
3205 if (! NILP (font))
3206 break;
3208 if (NILP (font))
3209 error ("No suitable font was found");
3211 x_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING);
3213 #endif /* USE_FONT_BACKEND */
3215 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
3216 1, 1, 0,
3217 doc: /* Make a new X window, which is called a "frame" in Emacs terms.
3218 Return an Emacs frame object.
3219 ALIST is an alist of frame parameters.
3220 If the parameters specify that the frame should not have a minibuffer,
3221 and do not specify a specific minibuffer window to use,
3222 then `default-minibuffer-frame' must be a frame whose minibuffer can
3223 be shared by the new frame.
3225 This function is an internal primitive--use `make-frame' instead. */)
3226 (parms)
3227 Lisp_Object parms;
3229 struct frame *f;
3230 Lisp_Object frame, tem;
3231 Lisp_Object name;
3232 int minibuffer_only = 0;
3233 long window_prompting = 0;
3234 int width, height;
3235 int count = SPECPDL_INDEX ();
3236 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
3237 Lisp_Object display;
3238 struct x_display_info *dpyinfo = NULL;
3239 Lisp_Object parent;
3240 struct kboard *kb;
3242 parms = Fcopy_alist (parms);
3244 /* Use this general default value to start with
3245 until we know if this frame has a specified name. */
3246 Vx_resource_name = Vinvocation_name;
3248 display = x_get_arg (dpyinfo, parms, Qterminal, 0, 0, RES_TYPE_NUMBER);
3249 if (EQ (display, Qunbound))
3250 display = x_get_arg (dpyinfo, parms, Qdisplay, 0, 0, RES_TYPE_STRING);
3251 if (EQ (display, Qunbound))
3252 display = Qnil;
3253 dpyinfo = check_x_display_info (display);
3254 #ifdef MULTI_KBOARD
3255 kb = dpyinfo->terminal->kboard;
3256 #else
3257 kb = &the_only_kboard;
3258 #endif
3260 if (!dpyinfo->terminal->name)
3261 error ("Terminal is not live, can't create new frames on it");
3263 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
3264 if (!STRINGP (name)
3265 && ! EQ (name, Qunbound)
3266 && ! NILP (name))
3267 error ("Invalid frame name--not a string or nil");
3269 if (STRINGP (name))
3270 Vx_resource_name = name;
3272 /* See if parent window is specified. */
3273 parent = x_get_arg (dpyinfo, parms, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
3274 if (EQ (parent, Qunbound))
3275 parent = Qnil;
3276 if (! NILP (parent))
3277 CHECK_NUMBER (parent);
3279 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
3280 /* No need to protect DISPLAY because that's not used after passing
3281 it to make_frame_without_minibuffer. */
3282 frame = Qnil;
3283 GCPRO4 (parms, parent, name, frame);
3284 tem = x_get_arg (dpyinfo, parms, Qminibuffer, "minibuffer", "Minibuffer",
3285 RES_TYPE_SYMBOL);
3286 if (EQ (tem, Qnone) || NILP (tem))
3287 f = make_frame_without_minibuffer (Qnil, kb, display);
3288 else if (EQ (tem, Qonly))
3290 f = make_minibuffer_frame ();
3291 minibuffer_only = 1;
3293 else if (WINDOWP (tem))
3294 f = make_frame_without_minibuffer (tem, kb, display);
3295 else
3296 f = make_frame (1);
3298 XSETFRAME (frame, f);
3300 /* Note that X Windows does support scroll bars. */
3301 FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
3303 f->terminal = dpyinfo->terminal;
3304 f->terminal->reference_count++;
3306 f->output_method = output_x_window;
3307 f->output_data.x = (struct x_output *) xmalloc (sizeof (struct x_output));
3308 bzero (f->output_data.x, sizeof (struct x_output));
3309 f->output_data.x->icon_bitmap = -1;
3310 FRAME_FONTSET (f) = -1;
3311 f->output_data.x->scroll_bar_foreground_pixel = -1;
3312 f->output_data.x->scroll_bar_background_pixel = -1;
3313 #ifdef USE_TOOLKIT_SCROLL_BARS
3314 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
3315 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
3316 #endif /* USE_TOOLKIT_SCROLL_BARS */
3318 f->icon_name
3319 = x_get_arg (dpyinfo, parms, Qicon_name, "iconName", "Title",
3320 RES_TYPE_STRING);
3321 if (! STRINGP (f->icon_name))
3322 f->icon_name = Qnil;
3324 FRAME_X_DISPLAY_INFO (f) = dpyinfo;
3326 /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe. */
3327 record_unwind_protect (unwind_create_frame, frame);
3328 #if GLYPH_DEBUG
3329 image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
3330 dpyinfo_refcount = dpyinfo->reference_count;
3331 #endif /* GLYPH_DEBUG */
3333 /* These colors will be set anyway later, but it's important
3334 to get the color reference counts right, so initialize them! */
3336 Lisp_Object black;
3337 struct gcpro gcpro1;
3339 /* Function x_decode_color can signal an error. Make
3340 sure to initialize color slots so that we won't try
3341 to free colors we haven't allocated. */
3342 FRAME_FOREGROUND_PIXEL (f) = -1;
3343 FRAME_BACKGROUND_PIXEL (f) = -1;
3344 f->output_data.x->cursor_pixel = -1;
3345 f->output_data.x->cursor_foreground_pixel = -1;
3346 f->output_data.x->border_pixel = -1;
3347 f->output_data.x->mouse_pixel = -1;
3349 black = build_string ("black");
3350 GCPRO1 (black);
3351 FRAME_FOREGROUND_PIXEL (f)
3352 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3353 FRAME_BACKGROUND_PIXEL (f)
3354 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3355 f->output_data.x->cursor_pixel
3356 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3357 f->output_data.x->cursor_foreground_pixel
3358 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3359 f->output_data.x->border_pixel
3360 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3361 f->output_data.x->mouse_pixel
3362 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
3363 UNGCPRO;
3366 /* Specify the parent under which to make this X window. */
3368 if (!NILP (parent))
3370 f->output_data.x->parent_desc = (Window) XFASTINT (parent);
3371 f->output_data.x->explicit_parent = 1;
3373 else
3375 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
3376 f->output_data.x->explicit_parent = 0;
3379 /* Set the name; the functions to which we pass f expect the name to
3380 be set. */
3381 if (EQ (name, Qunbound) || NILP (name))
3383 f->name = build_string (dpyinfo->x_id_name);
3384 f->explicit_name = 0;
3386 else
3388 f->name = name;
3389 f->explicit_name = 1;
3390 /* use the frame's title when getting resources for this frame. */
3391 specbind (Qx_resource_name, name);
3394 f->resx = dpyinfo->resx;
3395 f->resy = dpyinfo->resy;
3397 #ifdef USE_FONT_BACKEND
3398 if (enable_font_backend)
3400 /* Perhaps, we must allow frame parameter, say `font-backend',
3401 to specify which font backends to use. */
3402 #ifdef HAVE_FREETYPE
3403 #ifdef HAVE_XFT
3404 register_font_driver (&xftfont_driver, f);
3405 #else /* not HAVE_XFT */
3406 register_font_driver (&ftxfont_driver, f);
3407 #endif /* not HAVE_XFT */
3408 #endif /* HAVE_FREETYPE */
3409 register_font_driver (&xfont_driver, f);
3411 x_default_parameter (f, parms, Qfont_backend, Qnil,
3412 "fontBackend", "FontBackend", RES_TYPE_STRING);
3414 #endif /* USE_FONT_BACKEND */
3416 /* Extract the window parameters from the supplied values
3417 that are needed to determine window geometry. */
3418 #ifdef USE_FONT_BACKEND
3419 if (enable_font_backend)
3420 x_default_font_parameter (f, parms);
3421 else
3422 #endif /* USE_FONT_BACKEND */
3424 Lisp_Object font;
3426 font = x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
3428 /* If the caller has specified no font, try out fonts which we
3429 hope have bold and italic variations. */
3430 if (!STRINGP (font))
3432 char *names[]
3433 = { "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
3434 "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3435 "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3436 /* This was formerly the first thing tried, but it finds
3437 too many fonts and takes too long. */
3438 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
3439 /* If those didn't work, look for something which will
3440 at least work. */
3441 "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
3442 NULL };
3443 int i;
3445 BLOCK_INPUT;
3446 for (i = 0; names[i]; i++)
3448 Lisp_Object list;
3450 list = x_list_fonts (f, build_string (names[i]), 0, 1);
3451 if (CONSP (list))
3453 font = XCAR (list);
3454 break;
3457 UNBLOCK_INPUT;
3458 if (! STRINGP (font))
3459 font = build_string ("fixed");
3461 x_default_parameter (f, parms, Qfont, font,
3462 "font", "Font", RES_TYPE_STRING);
3465 #ifdef USE_LUCID
3466 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
3467 whereby it fails to get any font. */
3468 xlwmenu_default_font = FRAME_FONT (f);
3469 #endif
3471 /* Frame contents get displaced if an embedded X window has a border. */
3472 if (! FRAME_X_EMBEDDED_P (f))
3473 x_default_parameter (f, parms, Qborder_width, make_number (2),
3474 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
3476 /* This defaults to 1 in order to match xterm. We recognize either
3477 internalBorderWidth or internalBorder (which is what xterm calls
3478 it). */
3479 if (NILP (Fassq (Qinternal_border_width, parms)))
3481 Lisp_Object value;
3483 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
3484 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
3485 if (! EQ (value, Qunbound))
3486 parms = Fcons (Fcons (Qinternal_border_width, value),
3487 parms);
3489 x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
3490 "internalBorderWidth", "internalBorderWidth",
3491 RES_TYPE_NUMBER);
3492 x_default_parameter (f, parms, Qvertical_scroll_bars, Qleft,
3493 "verticalScrollBars", "ScrollBars",
3494 RES_TYPE_SYMBOL);
3496 /* Also do the stuff which must be set before the window exists. */
3497 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
3498 "foreground", "Foreground", RES_TYPE_STRING);
3499 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
3500 "background", "Background", RES_TYPE_STRING);
3501 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
3502 "pointerColor", "Foreground", RES_TYPE_STRING);
3503 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
3504 "cursorColor", "Foreground", RES_TYPE_STRING);
3505 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
3506 "borderColor", "BorderColor", RES_TYPE_STRING);
3507 x_default_parameter (f, parms, Qscreen_gamma, Qnil,
3508 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
3509 x_default_parameter (f, parms, Qline_spacing, Qnil,
3510 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
3511 x_default_parameter (f, parms, Qleft_fringe, Qnil,
3512 "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
3513 x_default_parameter (f, parms, Qright_fringe, Qnil,
3514 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
3516 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_foreground,
3517 "scrollBarForeground",
3518 "ScrollBarForeground", 1);
3519 x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_background,
3520 "scrollBarBackground",
3521 "ScrollBarBackground", 0);
3523 /* Init faces before x_default_parameter is called for scroll-bar
3524 parameters because that function calls x_set_scroll_bar_width,
3525 which calls change_frame_size, which calls Fset_window_buffer,
3526 which runs hooks, which call Fvertical_motion. At the end, we
3527 end up in init_iterator with a null face cache, which should not
3528 happen. */
3529 init_frame_faces (f);
3531 x_default_parameter (f, parms, Qmenu_bar_lines, make_number (1),
3532 "menuBar", "MenuBar", RES_TYPE_NUMBER);
3533 x_default_parameter (f, parms, Qtool_bar_lines, make_number (1),
3534 "toolBar", "ToolBar", RES_TYPE_NUMBER);
3535 x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
3536 "bufferPredicate", "BufferPredicate",
3537 RES_TYPE_SYMBOL);
3538 x_default_parameter (f, parms, Qtitle, Qnil,
3539 "title", "Title", RES_TYPE_STRING);
3540 x_default_parameter (f, parms, Qwait_for_wm, Qt,
3541 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
3542 x_default_parameter (f, parms, Qfullscreen, Qnil,
3543 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
3545 /* Compute the size of the X window. */
3546 window_prompting = x_figure_window_size (f, parms, 1);
3548 tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
3549 f->no_split = minibuffer_only || EQ (tem, Qt);
3551 x_icon_verify (f, parms);
3553 /* Create the X widget or window. */
3554 #ifdef USE_X_TOOLKIT
3555 x_window (f, window_prompting, minibuffer_only);
3556 #else
3557 x_window (f);
3558 #endif
3560 x_icon (f, parms);
3561 x_make_gc (f);
3563 /* Now consider the frame official. */
3564 FRAME_X_DISPLAY_INFO (f)->reference_count++;
3565 Vframe_list = Fcons (frame, Vframe_list);
3567 /* We need to do this after creating the X window, so that the
3568 icon-creation functions can say whose icon they're describing. */
3569 x_default_parameter (f, parms, Qicon_type, Qt,
3570 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
3572 x_default_parameter (f, parms, Qauto_raise, Qnil,
3573 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3574 x_default_parameter (f, parms, Qauto_lower, Qnil,
3575 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
3576 x_default_parameter (f, parms, Qcursor_type, Qbox,
3577 "cursorType", "CursorType", RES_TYPE_SYMBOL);
3578 x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
3579 "scrollBarWidth", "ScrollBarWidth",
3580 RES_TYPE_NUMBER);
3582 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3583 Change will not be effected unless different from the current
3584 FRAME_LINES (f). */
3585 width = FRAME_COLS (f);
3586 height = FRAME_LINES (f);
3588 SET_FRAME_COLS (f, 0);
3589 FRAME_LINES (f) = 0;
3590 change_frame_size (f, height, width, 1, 0, 0);
3592 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3593 /* Create the menu bar. */
3594 if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
3596 /* If this signals an error, we haven't set size hints for the
3597 frame and we didn't make it visible. */
3598 initialize_frame_menubar (f);
3600 #ifndef USE_GTK
3601 /* This is a no-op, except under Motif where it arranges the
3602 main window for the widgets on it. */
3603 lw_set_main_areas (f->output_data.x->column_widget,
3604 f->output_data.x->menubar_widget,
3605 f->output_data.x->edit_widget);
3606 #endif /* not USE_GTK */
3608 #endif /* USE_X_TOOLKIT || USE_GTK */
3610 /* Tell the server what size and position, etc, we want, and how
3611 badly we want them. This should be done after we have the menu
3612 bar so that its size can be taken into account. */
3613 BLOCK_INPUT;
3614 x_wm_set_size_hint (f, window_prompting, 0);
3615 UNBLOCK_INPUT;
3617 /* Make the window appear on the frame and enable display, unless
3618 the caller says not to. However, with explicit parent, Emacs
3619 cannot control visibility, so don't try. */
3620 if (! f->output_data.x->explicit_parent)
3622 Lisp_Object visibility;
3624 visibility = x_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
3625 RES_TYPE_SYMBOL);
3626 if (EQ (visibility, Qunbound))
3627 visibility = Qt;
3629 if (EQ (visibility, Qicon))
3630 x_iconify_frame (f);
3631 else if (! NILP (visibility))
3632 x_make_frame_visible (f);
3633 else
3634 /* Must have been Qnil. */
3638 /* Set the WM leader property. GTK does this itself, so this is not
3639 needed when using GTK. */
3640 if (dpyinfo->client_leader_window != 0)
3642 BLOCK_INPUT;
3643 XChangeProperty (FRAME_X_DISPLAY (f),
3644 FRAME_OUTER_WINDOW (f),
3645 dpyinfo->Xatom_wm_client_leader,
3646 XA_WINDOW, 32, PropModeReplace,
3647 (unsigned char *) &dpyinfo->client_leader_window, 1);
3648 UNBLOCK_INPUT;
3651 /* Initialize `default-minibuffer-frame' in case this is the first
3652 frame on this terminal. */
3653 if (FRAME_HAS_MINIBUF_P (f)
3654 && (!FRAMEP (kb->Vdefault_minibuffer_frame)
3655 || !FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame))))
3656 kb->Vdefault_minibuffer_frame = frame;
3658 /* All remaining specified parameters, which have not been "used"
3659 by x_get_arg and friends, now go in the misc. alist of the frame. */
3660 for (tem = parms; CONSP (tem); tem = XCDR (tem))
3661 if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
3662 f->param_alist = Fcons (XCAR (tem), f->param_alist);
3664 UNGCPRO;
3666 /* Make sure windows on this frame appear in calls to next-window
3667 and similar functions. */
3668 Vwindow_list = Qnil;
3670 return unbind_to (count, frame);
3674 /* FRAME is used only to get a handle on the X display. We don't pass the
3675 display info directly because we're called from frame.c, which doesn't
3676 know about that structure. */
3678 Lisp_Object
3679 x_get_focus_frame (frame)
3680 struct frame *frame;
3682 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (frame);
3683 Lisp_Object xfocus;
3684 if (! dpyinfo->x_focus_frame)
3685 return Qnil;
3687 XSETFRAME (xfocus, dpyinfo->x_focus_frame);
3688 return xfocus;
3692 /* In certain situations, when the window manager follows a
3693 click-to-focus policy, there seems to be no way around calling
3694 XSetInputFocus to give another frame the input focus .
3696 In an ideal world, XSetInputFocus should generally be avoided so
3697 that applications don't interfere with the window manager's focus
3698 policy. But I think it's okay to use when it's clearly done
3699 following a user-command. */
3701 DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
3702 doc: /* Set the input focus to FRAME.
3703 FRAME nil means use the selected frame. */)
3704 (frame)
3705 Lisp_Object frame;
3707 struct frame *f = check_x_frame (frame);
3708 Display *dpy = FRAME_X_DISPLAY (f);
3710 BLOCK_INPUT;
3711 x_catch_errors (dpy);
3712 XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3713 RevertToParent, CurrentTime);
3714 x_ewmh_activate_frame (f);
3715 x_uncatch_errors ();
3716 UNBLOCK_INPUT;
3718 return Qnil;
3722 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
3723 doc: /* Internal function called by `color-defined-p', which see. */)
3724 (color, frame)
3725 Lisp_Object color, frame;
3727 XColor foo;
3728 FRAME_PTR f = check_x_frame (frame);
3730 CHECK_STRING (color);
3732 if (x_defined_color (f, SDATA (color), &foo, 0))
3733 return Qt;
3734 else
3735 return Qnil;
3738 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
3739 doc: /* Internal function called by `color-values', which see. */)
3740 (color, frame)
3741 Lisp_Object color, frame;
3743 XColor foo;
3744 FRAME_PTR f = check_x_frame (frame);
3746 CHECK_STRING (color);
3748 if (x_defined_color (f, SDATA (color), &foo, 0))
3749 return list3 (make_number (foo.red),
3750 make_number (foo.green),
3751 make_number (foo.blue));
3752 else
3753 return Qnil;
3756 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
3757 doc: /* Internal function called by `display-color-p', which see. */)
3758 (terminal)
3759 Lisp_Object terminal;
3761 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3763 if (dpyinfo->n_planes <= 2)
3764 return Qnil;
3766 switch (dpyinfo->visual->class)
3768 case StaticColor:
3769 case PseudoColor:
3770 case TrueColor:
3771 case DirectColor:
3772 return Qt;
3774 default:
3775 return Qnil;
3779 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
3780 0, 1, 0,
3781 doc: /* Return t if the X display supports shades of gray.
3782 Note that color displays do support shades of gray.
3783 The optional argument TERMINAL specifies which display to ask about.
3784 TERMINAL should be a terminal id, a frame or a display name (a string).
3785 If omitted or nil, that stands for the selected frame's display. */)
3786 (terminal)
3787 Lisp_Object terminal;
3789 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3791 if (dpyinfo->n_planes <= 1)
3792 return Qnil;
3794 switch (dpyinfo->visual->class)
3796 case StaticColor:
3797 case PseudoColor:
3798 case TrueColor:
3799 case DirectColor:
3800 case StaticGray:
3801 case GrayScale:
3802 return Qt;
3804 default:
3805 return Qnil;
3809 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
3810 0, 1, 0,
3811 doc: /* Return the width in pixels of the X display TERMINAL.
3812 The optional argument TERMINAL specifies which display to ask about.
3813 TERMINAL should be a terminal id, a frame or a display name (a string).
3814 If omitted or nil, that stands for the selected frame's display. */)
3815 (terminal)
3816 Lisp_Object terminal;
3818 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3820 return make_number (dpyinfo->width);
3823 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
3824 Sx_display_pixel_height, 0, 1, 0,
3825 doc: /* Return the height in pixels of the X display TERMINAL.
3826 The optional argument TERMINAL specifies which display to ask about.
3827 TERMINAL should be a terminal id, a frame or a display name (a string).
3828 If omitted or nil, that stands for the selected frame's display. */)
3829 (terminal)
3830 Lisp_Object terminal;
3832 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3834 return make_number (dpyinfo->height);
3837 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
3838 0, 1, 0,
3839 doc: /* Return the number of bitplanes of the X display TERMINAL.
3840 The optional argument TERMINAL specifies which display to ask about.
3841 TERMINAL should be a terminal id, a frame or a display name (a string).
3842 If omitted or nil, that stands for the selected frame's display. */)
3843 (terminal)
3844 Lisp_Object terminal;
3846 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3848 return make_number (dpyinfo->n_planes);
3851 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
3852 0, 1, 0,
3853 doc: /* Return the number of color cells of the X display TERMINAL.
3854 The optional argument TERMINAL specifies which display to ask about.
3855 TERMINAL should be a terminal id, a frame or a display name (a string).
3856 If omitted or nil, that stands for the selected frame's display. */)
3857 (terminal)
3858 Lisp_Object terminal;
3860 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3862 int nr_planes = DisplayPlanes (dpyinfo->display,
3863 XScreenNumberOfScreen (dpyinfo->screen));
3865 /* Truncate nr_planes to 24 to avoid integer overflow.
3866 Some displays says 32, but only 24 bits are actually significant.
3867 There are only very few and rare video cards that have more than
3868 24 significant bits. Also 24 bits is more than 16 million colors,
3869 it "should be enough for everyone". */
3870 if (nr_planes > 24) nr_planes = 24;
3872 return make_number (1 << nr_planes);
3875 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
3876 Sx_server_max_request_size,
3877 0, 1, 0,
3878 doc: /* Return the maximum request size of the X server of display TERMINAL.
3879 The optional argument TERMINAL specifies which display to ask about.
3880 TERMINAL should be a terminal id, a frame or a display name (a string).
3881 If omitted or nil, that stands for the selected frame's display. */)
3882 (terminal)
3883 Lisp_Object terminal;
3885 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3887 return make_number (MAXREQUEST (dpyinfo->display));
3890 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
3891 doc: /* Return the "vendor ID" string of the X server of display TERMINAL.
3892 \(Labelling every distributor as a "vendor" embodies the false assumption
3893 that operating systems cannot be developed and distributed noncommercially.)
3894 The optional argument TERMINAL specifies which display to ask about.
3895 TERMINAL should be a terminal id, a frame or a display name (a string).
3896 If omitted or nil, that stands for the selected frame's display. */)
3897 (terminal)
3898 Lisp_Object terminal;
3900 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3901 char *vendor = ServerVendor (dpyinfo->display);
3903 if (! vendor) vendor = "";
3904 return build_string (vendor);
3907 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
3908 doc: /* Return the version numbers of the X server of display TERMINAL.
3909 The value is a list of three integers: the major and minor
3910 version numbers of the X Protocol in use, and the distributor-specific release
3911 number. See also the function `x-server-vendor'.
3913 The optional argument TERMINAL specifies which display to ask about.
3914 TERMINAL should be a terminal id, a frame or a display name (a string).
3915 If omitted or nil, that stands for the selected frame's display. */)
3916 (terminal)
3917 Lisp_Object terminal;
3919 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3920 Display *dpy = dpyinfo->display;
3922 return Fcons (make_number (ProtocolVersion (dpy)),
3923 Fcons (make_number (ProtocolRevision (dpy)),
3924 Fcons (make_number (VendorRelease (dpy)), Qnil)));
3927 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
3928 doc: /* Return the number of screens on the X server of display TERMINAL.
3929 The optional argument TERMINAL specifies which display to ask about.
3930 TERMINAL should be a terminal id, a frame or a display name (a string).
3931 If omitted or nil, that stands for the selected frame's display. */)
3932 (terminal)
3933 Lisp_Object terminal;
3935 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3937 return make_number (ScreenCount (dpyinfo->display));
3940 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
3941 doc: /* Return the height in millimeters of the X display TERMINAL.
3942 The optional argument TERMINAL specifies which display to ask about.
3943 TERMINAL should be a terminal id, a frame or a display name (a string).
3944 If omitted or nil, that stands for the selected frame's display. */)
3945 (terminal)
3946 Lisp_Object terminal;
3948 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3950 return make_number (HeightMMOfScreen (dpyinfo->screen));
3953 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
3954 doc: /* Return the width in millimeters of the X display TERMINAL.
3955 The optional argument TERMINAL specifies which display to ask about.
3956 TERMINAL should be a terminal id, a frame or a display name (a string).
3957 If omitted or nil, that stands for the selected frame's display. */)
3958 (terminal)
3959 Lisp_Object terminal;
3961 struct x_display_info *dpyinfo = check_x_display_info (terminal);
3963 return make_number (WidthMMOfScreen (dpyinfo->screen));
3966 DEFUN ("x-display-backing-store", Fx_display_backing_store,
3967 Sx_display_backing_store, 0, 1, 0,
3968 doc: /* Return an indication of whether X display TERMINAL does backing store.
3969 The value may be `always', `when-mapped', or `not-useful'.
3970 The optional argument TERMINAL specifies which display to ask about.
3971 TERMINAL should be a terminal id, 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);
3977 Lisp_Object result;
3979 switch (DoesBackingStore (dpyinfo->screen))
3981 case Always:
3982 result = intern ("always");
3983 break;
3985 case WhenMapped:
3986 result = intern ("when-mapped");
3987 break;
3989 case NotUseful:
3990 result = intern ("not-useful");
3991 break;
3993 default:
3994 error ("Strange value for BackingStore parameter of screen");
3995 result = Qnil;
3998 return result;
4001 DEFUN ("x-display-visual-class", Fx_display_visual_class,
4002 Sx_display_visual_class, 0, 1, 0,
4003 doc: /* Return the visual class of the X display TERMINAL.
4004 The value is one of the symbols `static-gray', `gray-scale',
4005 `static-color', `pseudo-color', `true-color', or `direct-color'.
4007 The optional argument TERMINAL specifies which display to ask about.
4008 TERMINAL should a terminal id, a frame or a display name (a string).
4009 If omitted or nil, that stands for the selected frame's display. */)
4010 (terminal)
4011 Lisp_Object terminal;
4013 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4014 Lisp_Object result;
4016 switch (dpyinfo->visual->class)
4018 case StaticGray:
4019 result = intern ("static-gray");
4020 break;
4021 case GrayScale:
4022 result = intern ("gray-scale");
4023 break;
4024 case StaticColor:
4025 result = intern ("static-color");
4026 break;
4027 case PseudoColor:
4028 result = intern ("pseudo-color");
4029 break;
4030 case TrueColor:
4031 result = intern ("true-color");
4032 break;
4033 case DirectColor:
4034 result = intern ("direct-color");
4035 break;
4036 default:
4037 error ("Display has an unknown visual class");
4038 result = Qnil;
4041 return result;
4044 DEFUN ("x-display-save-under", Fx_display_save_under,
4045 Sx_display_save_under, 0, 1, 0,
4046 doc: /* Return t if the X display TERMINAL supports the save-under feature.
4047 The optional argument TERMINAL specifies which display to ask about.
4048 TERMINAL should be a terminal id, a frame or a display name (a string).
4049 If omitted or nil, that stands for the selected frame's display. */)
4050 (terminal)
4051 Lisp_Object terminal;
4053 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4055 if (DoesSaveUnders (dpyinfo->screen) == True)
4056 return Qt;
4057 else
4058 return Qnil;
4062 x_pixel_width (f)
4063 register struct frame *f;
4065 return FRAME_PIXEL_WIDTH (f);
4069 x_pixel_height (f)
4070 register struct frame *f;
4072 return FRAME_PIXEL_HEIGHT (f);
4076 x_char_width (f)
4077 register struct frame *f;
4079 return FRAME_COLUMN_WIDTH (f);
4083 x_char_height (f)
4084 register struct frame *f;
4086 return FRAME_LINE_HEIGHT (f);
4090 x_screen_planes (f)
4091 register struct frame *f;
4093 return FRAME_X_DISPLAY_INFO (f)->n_planes;
4098 /************************************************************************
4099 X Displays
4100 ************************************************************************/
4103 /* Mapping visual names to visuals. */
4105 static struct visual_class
4107 char *name;
4108 int class;
4110 visual_classes[] =
4112 {"StaticGray", StaticGray},
4113 {"GrayScale", GrayScale},
4114 {"StaticColor", StaticColor},
4115 {"PseudoColor", PseudoColor},
4116 {"TrueColor", TrueColor},
4117 {"DirectColor", DirectColor},
4118 {NULL, 0}
4122 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4124 /* Value is the screen number of screen SCR. This is a substitute for
4125 the X function with the same name when that doesn't exist. */
4128 XScreenNumberOfScreen (scr)
4129 register Screen *scr;
4131 Display *dpy = scr->display;
4132 int i;
4134 for (i = 0; i < dpy->nscreens; ++i)
4135 if (scr == dpy->screens + i)
4136 break;
4138 return i;
4141 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4144 /* Select the visual that should be used on display DPYINFO. Set
4145 members of DPYINFO appropriately. Called from x_term_init. */
4147 void
4148 select_visual (dpyinfo)
4149 struct x_display_info *dpyinfo;
4151 Display *dpy = dpyinfo->display;
4152 Screen *screen = dpyinfo->screen;
4153 Lisp_Object value;
4155 /* See if a visual is specified. */
4156 value = display_x_get_resource (dpyinfo,
4157 build_string ("visualClass"),
4158 build_string ("VisualClass"),
4159 Qnil, Qnil);
4160 if (STRINGP (value))
4162 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
4163 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
4164 depth, a decimal number. NAME is compared with case ignored. */
4165 char *s = (char *) alloca (SBYTES (value) + 1);
4166 char *dash;
4167 int i, class = -1;
4168 XVisualInfo vinfo;
4170 strcpy (s, SDATA (value));
4171 dash = index (s, '-');
4172 if (dash)
4174 dpyinfo->n_planes = atoi (dash + 1);
4175 *dash = '\0';
4177 else
4178 /* We won't find a matching visual with depth 0, so that
4179 an error will be printed below. */
4180 dpyinfo->n_planes = 0;
4182 /* Determine the visual class. */
4183 for (i = 0; visual_classes[i].name; ++i)
4184 if (xstricmp (s, visual_classes[i].name) == 0)
4186 class = visual_classes[i].class;
4187 break;
4190 /* Look up a matching visual for the specified class. */
4191 if (class == -1
4192 || !XMatchVisualInfo (dpy, XScreenNumberOfScreen (screen),
4193 dpyinfo->n_planes, class, &vinfo))
4194 fatal ("Invalid visual specification `%s'", SDATA (value));
4196 dpyinfo->visual = vinfo.visual;
4198 else
4200 int n_visuals;
4201 XVisualInfo *vinfo, vinfo_template;
4203 dpyinfo->visual = DefaultVisualOfScreen (screen);
4205 vinfo_template.visualid = XVisualIDFromVisual (dpyinfo->visual);
4206 vinfo_template.screen = XScreenNumberOfScreen (screen);
4207 vinfo = XGetVisualInfo (dpy, VisualIDMask | VisualScreenMask,
4208 &vinfo_template, &n_visuals);
4209 if (n_visuals != 1)
4210 fatal ("Can't get proper X visual info");
4212 dpyinfo->n_planes = vinfo->depth;
4213 XFree ((char *) vinfo);
4218 /* Return the X display structure for the display named NAME.
4219 Open a new connection if necessary. */
4221 struct x_display_info *
4222 x_display_info_for_name (name)
4223 Lisp_Object name;
4225 Lisp_Object names;
4226 struct x_display_info *dpyinfo;
4228 CHECK_STRING (name);
4230 #if 0
4231 if (! EQ (Vinitial_window_system, intern ("x")))
4232 error ("Not using X Windows"); /* That doesn't stop us anymore. */
4233 #endif
4235 for (dpyinfo = x_display_list, names = x_display_name_list;
4236 dpyinfo;
4237 dpyinfo = dpyinfo->next, names = XCDR (names))
4239 Lisp_Object tem;
4240 tem = Fstring_equal (XCAR (XCAR (names)), name);
4241 if (!NILP (tem))
4242 return dpyinfo;
4245 /* Use this general default value to start with. */
4246 Vx_resource_name = Vinvocation_name;
4248 validate_x_resource_name ();
4250 dpyinfo = x_term_init (name, (char *)0,
4251 (char *) SDATA (Vx_resource_name));
4253 if (dpyinfo == 0)
4254 error ("Cannot connect to X server %s", SDATA (name));
4256 x_in_use = 1;
4257 XSETFASTINT (Vwindow_system_version, 11);
4259 return dpyinfo;
4263 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
4264 1, 3, 0,
4265 doc: /* Open a connection to an X server.
4266 DISPLAY is the name of the display to connect to.
4267 Optional second arg XRM-STRING is a string of resources in xrdb format.
4268 If the optional third arg MUST-SUCCEED is non-nil,
4269 terminate Emacs if we can't open the connection. */)
4270 (display, xrm_string, must_succeed)
4271 Lisp_Object display, xrm_string, must_succeed;
4273 unsigned char *xrm_option;
4274 struct x_display_info *dpyinfo;
4276 CHECK_STRING (display);
4277 if (! NILP (xrm_string))
4278 CHECK_STRING (xrm_string);
4280 #if 0
4281 if (! EQ (Vinitial_window_system, intern ("x")))
4282 error ("Not using X Windows"); /* That doesn't stop us anymore. */
4283 #endif
4285 if (! NILP (xrm_string))
4286 xrm_option = (unsigned char *) SDATA (xrm_string);
4287 else
4288 xrm_option = (unsigned char *) 0;
4290 validate_x_resource_name ();
4292 /* This is what opens the connection and sets x_current_display.
4293 This also initializes many symbols, such as those used for input. */
4294 dpyinfo = x_term_init (display, xrm_option,
4295 (char *) SDATA (Vx_resource_name));
4297 if (dpyinfo == 0)
4299 if (!NILP (must_succeed))
4300 fatal ("Cannot connect to X server %s.\n\
4301 Check the DISPLAY environment variable or use `-d'.\n\
4302 Also use the `xauth' program to verify that you have the proper\n\
4303 authorization information needed to connect the X server.\n\
4304 An insecure way to solve the problem may be to use `xhost'.\n",
4305 SDATA (display));
4306 else
4307 error ("Cannot connect to X server %s", SDATA (display));
4310 x_in_use = 1;
4312 XSETFASTINT (Vwindow_system_version, 11);
4313 return Qnil;
4316 DEFUN ("x-close-connection", Fx_close_connection,
4317 Sx_close_connection, 1, 1, 0,
4318 doc: /* Close the connection to TERMINAL's X server.
4319 For TERMINAL, specify a terminal id, a frame or a display name (a
4320 string). If TERMINAL is nil, that stands for the selected frame's
4321 terminal. */)
4322 (terminal)
4323 Lisp_Object terminal;
4325 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4327 if (dpyinfo->reference_count > 0)
4328 error ("Display still has frames on it");
4330 x_delete_terminal (dpyinfo->terminal);
4332 return Qnil;
4335 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
4336 doc: /* Return the list of display names that Emacs has connections to. */)
4339 Lisp_Object tail, result;
4341 result = Qnil;
4342 for (tail = x_display_name_list; CONSP (tail); tail = XCDR (tail))
4343 result = Fcons (XCAR (XCAR (tail)), result);
4345 return result;
4348 DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
4349 doc: /* If ON is non-nil, report X errors as soon as the erring request is made.
4350 If ON is nil, allow buffering of requests.
4351 Turning on synchronization prohibits the Xlib routines from buffering
4352 requests and seriously degrades performance, but makes debugging much
4353 easier.
4354 The optional second argument TERMINAL specifies which display to act on.
4355 TERMINAL should be a terminal id, a frame or a display name (a string).
4356 If TERMINAL is omitted or nil, that stands for the selected frame's display. */)
4357 (on, terminal)
4358 Lisp_Object terminal, on;
4360 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4362 XSynchronize (dpyinfo->display, !EQ (on, Qnil));
4364 return Qnil;
4367 /* Wait for responses to all X commands issued so far for frame F. */
4369 void
4370 x_sync (f)
4371 FRAME_PTR f;
4373 BLOCK_INPUT;
4374 XSync (FRAME_X_DISPLAY (f), False);
4375 UNBLOCK_INPUT;
4379 /***********************************************************************
4380 Window properties
4381 ***********************************************************************/
4383 DEFUN ("x-change-window-property", Fx_change_window_property,
4384 Sx_change_window_property, 2, 6, 0,
4385 doc: /* Change window property PROP to VALUE on the X window of FRAME.
4386 PROP must be a string.
4387 VALUE may be a string or a list of conses, numbers and/or strings.
4388 If an element in the list is a string, it is converted to
4389 an Atom and the value of the Atom is used. If an element is a cons,
4390 it is converted to a 32 bit number where the car is the 16 top bits and the
4391 cdr is the lower 16 bits.
4392 FRAME nil or omitted means use the selected frame.
4393 If TYPE is given and non-nil, it is the name of the type of VALUE.
4394 If TYPE is not given or nil, the type is STRING.
4395 FORMAT gives the size in bits of each element if VALUE is a list.
4396 It must be one of 8, 16 or 32.
4397 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
4398 If OUTER_P is non-nil, the property is changed for the outer X window of
4399 FRAME. Default is to change on the edit X window.
4401 Value is VALUE. */)
4402 (prop, value, frame, type, format, outer_p)
4403 Lisp_Object prop, value, frame, type, format, outer_p;
4405 struct frame *f = check_x_frame (frame);
4406 Atom prop_atom;
4407 Atom target_type = XA_STRING;
4408 int element_format = 8;
4409 unsigned char *data;
4410 int nelements;
4411 Window w;
4413 CHECK_STRING (prop);
4415 if (! NILP (format))
4417 CHECK_NUMBER (format);
4418 element_format = XFASTINT (format);
4420 if (element_format != 8 && element_format != 16
4421 && element_format != 32)
4422 error ("FORMAT must be one of 8, 16 or 32");
4425 if (CONSP (value))
4427 nelements = x_check_property_data (value);
4428 if (nelements == -1)
4429 error ("Bad data in VALUE, must be number, string or cons");
4431 if (element_format == 8)
4432 data = (unsigned char *) xmalloc (nelements);
4433 else if (element_format == 16)
4434 data = (unsigned char *) xmalloc (nelements*2);
4435 else /* format == 32 */
4436 /* The man page for XChangeProperty:
4437 "If the specified format is 32, the property data must be a
4438 long array."
4439 This applies even if long is more than 64 bits. The X library
4440 converts to 32 bits before sending to the X server. */
4441 data = (unsigned char *) xmalloc (nelements * sizeof(long));
4443 x_fill_property_data (FRAME_X_DISPLAY (f), value, data, element_format);
4445 else
4447 CHECK_STRING (value);
4448 data = SDATA (value);
4449 nelements = SCHARS (value);
4452 BLOCK_INPUT;
4453 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4454 if (! NILP (type))
4456 CHECK_STRING (type);
4457 target_type = XInternAtom (FRAME_X_DISPLAY (f), SDATA (type), False);
4460 if (! NILP (outer_p)) w = FRAME_OUTER_WINDOW (f);
4461 else w = FRAME_X_WINDOW (f);
4463 XChangeProperty (FRAME_X_DISPLAY (f), w,
4464 prop_atom, target_type, element_format, PropModeReplace,
4465 data, nelements);
4467 if (CONSP (value)) xfree (data);
4469 /* Make sure the property is set when we return. */
4470 XFlush (FRAME_X_DISPLAY (f));
4471 UNBLOCK_INPUT;
4473 return value;
4477 DEFUN ("x-delete-window-property", Fx_delete_window_property,
4478 Sx_delete_window_property, 1, 2, 0,
4479 doc: /* Remove window property PROP from X window of FRAME.
4480 FRAME nil or omitted means use the selected frame. Value is PROP. */)
4481 (prop, frame)
4482 Lisp_Object prop, frame;
4484 struct frame *f = check_x_frame (frame);
4485 Atom prop_atom;
4487 CHECK_STRING (prop);
4488 BLOCK_INPUT;
4489 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4490 XDeleteProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), prop_atom);
4492 /* Make sure the property is removed when we return. */
4493 XFlush (FRAME_X_DISPLAY (f));
4494 UNBLOCK_INPUT;
4496 return prop;
4500 DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
4501 1, 6, 0,
4502 doc: /* Value is the value of window property PROP on FRAME.
4503 If FRAME is nil or omitted, use the selected frame.
4504 If TYPE is nil or omitted, get the property as a string. Otherwise TYPE
4505 is the name of the Atom that denotes the type expected.
4506 If SOURCE is non-nil, get the property on that window instead of from
4507 FRAME. The number 0 denotes the root window.
4508 If DELETE_P is non-nil, delete the property after retreiving it.
4509 If VECTOR_RET_P is non-nil, don't return a string but a vector of values.
4511 Value is nil if FRAME hasn't a property with name PROP or if PROP has
4512 no value of TYPE. */)
4513 (prop, frame, type, source, delete_p, vector_ret_p)
4514 Lisp_Object prop, frame, type, source, delete_p, vector_ret_p;
4516 struct frame *f = check_x_frame (frame);
4517 Atom prop_atom;
4518 int rc;
4519 Lisp_Object prop_value = Qnil;
4520 unsigned char *tmp_data = NULL;
4521 Atom actual_type;
4522 Atom target_type = XA_STRING;
4523 int actual_format;
4524 unsigned long actual_size, bytes_remaining;
4525 Window target_window = FRAME_X_WINDOW (f);
4526 struct gcpro gcpro1;
4528 GCPRO1 (prop_value);
4529 CHECK_STRING (prop);
4531 if (! NILP (source))
4533 if (NUMBERP (source))
4535 if (FLOATP (source))
4536 target_window = (Window) XFLOAT (source);
4537 else
4538 target_window = XFASTINT (source);
4540 if (target_window == 0)
4541 target_window = FRAME_X_DISPLAY_INFO (f)->root_window;
4543 else if (CONSP (source))
4544 target_window = cons_to_long (source);
4547 BLOCK_INPUT;
4548 if (STRINGP (type))
4550 if (strcmp ("AnyPropertyType", SDATA (type)) == 0)
4551 target_type = AnyPropertyType;
4552 else
4553 target_type = XInternAtom (FRAME_X_DISPLAY (f), SDATA (type), False);
4556 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
4557 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4558 prop_atom, 0, 0, False, target_type,
4559 &actual_type, &actual_format, &actual_size,
4560 &bytes_remaining, &tmp_data);
4561 if (rc == Success)
4563 int size = bytes_remaining;
4565 XFree (tmp_data);
4566 tmp_data = NULL;
4568 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4569 prop_atom, 0, bytes_remaining,
4570 ! NILP (delete_p), target_type,
4571 &actual_type, &actual_format,
4572 &actual_size, &bytes_remaining,
4573 &tmp_data);
4574 if (rc == Success && tmp_data)
4576 /* The man page for XGetWindowProperty says:
4577 "If the returned format is 32, the returned data is represented
4578 as a long array and should be cast to that type to obtain the
4579 elements."
4580 This applies even if long is more than 32 bits, the X library
4581 converts from 32 bit elements received from the X server to long
4582 and passes the long array to us. Thus, for that case bcopy can not
4583 be used. We convert to a 32 bit type here, because so much code
4584 assume on that.
4586 The bytes and offsets passed to XGetWindowProperty refers to the
4587 property and those are indeed in 32 bit quantities if format is
4588 32. */
4590 if (actual_format == 32 && actual_format < BITS_PER_LONG)
4592 unsigned long i;
4593 int *idata = (int *) tmp_data;
4594 long *ldata = (long *) tmp_data;
4596 for (i = 0; i < actual_size; ++i)
4597 idata[i] = (int) ldata[i];
4600 if (NILP (vector_ret_p))
4601 prop_value = make_string (tmp_data, size);
4602 else
4603 prop_value = x_property_data_to_lisp (f,
4604 tmp_data,
4605 actual_type,
4606 actual_format,
4607 actual_size);
4610 if (tmp_data) XFree (tmp_data);
4613 UNBLOCK_INPUT;
4614 UNGCPRO;
4615 return prop_value;
4620 /***********************************************************************
4621 Busy cursor
4622 ***********************************************************************/
4624 /* If non-null, an asynchronous timer that, when it expires, displays
4625 an hourglass cursor on all frames. */
4627 static struct atimer *hourglass_atimer;
4629 /* Non-zero means an hourglass cursor is currently shown. */
4631 static int hourglass_shown_p;
4633 /* Number of seconds to wait before displaying an hourglass cursor. */
4635 static Lisp_Object Vhourglass_delay;
4637 /* Default number of seconds to wait before displaying an hourglass
4638 cursor. */
4640 #define DEFAULT_HOURGLASS_DELAY 1
4642 /* Function prototypes. */
4644 static void show_hourglass P_ ((struct atimer *));
4645 static void hide_hourglass P_ ((void));
4647 /* Return non-zero if houglass timer has been started or hourglass is shown. */
4650 hourglass_started ()
4652 return hourglass_shown_p || hourglass_atimer != NULL;
4656 /* Cancel a currently active hourglass timer, and start a new one. */
4658 void
4659 start_hourglass ()
4661 EMACS_TIME delay;
4662 int secs, usecs = 0;
4664 cancel_hourglass ();
4666 if (INTEGERP (Vhourglass_delay)
4667 && XINT (Vhourglass_delay) > 0)
4668 secs = XFASTINT (Vhourglass_delay);
4669 else if (FLOATP (Vhourglass_delay)
4670 && XFLOAT_DATA (Vhourglass_delay) > 0)
4672 Lisp_Object tem;
4673 tem = Ftruncate (Vhourglass_delay, Qnil);
4674 secs = XFASTINT (tem);
4675 usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000;
4677 else
4678 secs = DEFAULT_HOURGLASS_DELAY;
4680 EMACS_SET_SECS_USECS (delay, secs, usecs);
4681 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
4682 show_hourglass, NULL);
4686 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
4687 shown. */
4689 void
4690 cancel_hourglass ()
4692 if (hourglass_atimer)
4694 cancel_atimer (hourglass_atimer);
4695 hourglass_atimer = NULL;
4698 if (hourglass_shown_p)
4699 hide_hourglass ();
4703 /* Timer function of hourglass_atimer. TIMER is equal to
4704 hourglass_atimer.
4706 Display an hourglass pointer on all frames by mapping the frames'
4707 hourglass_window. Set the hourglass_p flag in the frames'
4708 output_data.x structure to indicate that an hourglass cursor is
4709 shown on the frames. */
4711 static void
4712 show_hourglass (timer)
4713 struct atimer *timer;
4715 /* The timer implementation will cancel this timer automatically
4716 after this function has run. Set hourglass_atimer to null
4717 so that we know the timer doesn't have to be canceled. */
4718 hourglass_atimer = NULL;
4720 if (!hourglass_shown_p)
4722 Lisp_Object rest, frame;
4724 BLOCK_INPUT;
4726 FOR_EACH_FRAME (rest, frame)
4728 struct frame *f = XFRAME (frame);
4730 if (FRAME_LIVE_P (f) && FRAME_X_P (f) && FRAME_X_DISPLAY (f))
4732 Display *dpy = FRAME_X_DISPLAY (f);
4734 #ifdef USE_X_TOOLKIT
4735 if (f->output_data.x->widget)
4736 #else
4737 if (FRAME_OUTER_WINDOW (f))
4738 #endif
4740 f->output_data.x->hourglass_p = 1;
4742 if (!f->output_data.x->hourglass_window)
4744 unsigned long mask = CWCursor;
4745 XSetWindowAttributes attrs;
4746 #ifdef USE_GTK
4747 Window parent = FRAME_X_WINDOW (f);
4748 #else
4749 Window parent = FRAME_OUTER_WINDOW (f);
4750 #endif
4751 attrs.cursor = f->output_data.x->hourglass_cursor;
4753 f->output_data.x->hourglass_window
4754 = XCreateWindow (dpy, parent,
4755 0, 0, 32000, 32000, 0, 0,
4756 InputOnly,
4757 CopyFromParent,
4758 mask, &attrs);
4761 XMapRaised (dpy, f->output_data.x->hourglass_window);
4762 XFlush (dpy);
4767 hourglass_shown_p = 1;
4768 UNBLOCK_INPUT;
4773 /* Hide the hourglass pointer on all frames, if it is currently
4774 shown. */
4776 static void
4777 hide_hourglass ()
4779 if (hourglass_shown_p)
4781 Lisp_Object rest, frame;
4783 BLOCK_INPUT;
4784 FOR_EACH_FRAME (rest, frame)
4786 struct frame *f = XFRAME (frame);
4788 if (FRAME_X_P (f)
4789 /* Watch out for newly created frames. */
4790 && f->output_data.x->hourglass_window)
4792 XUnmapWindow (FRAME_X_DISPLAY (f),
4793 f->output_data.x->hourglass_window);
4794 /* Sync here because XTread_socket looks at the
4795 hourglass_p flag that is reset to zero below. */
4796 XSync (FRAME_X_DISPLAY (f), False);
4797 f->output_data.x->hourglass_p = 0;
4801 hourglass_shown_p = 0;
4802 UNBLOCK_INPUT;
4808 /***********************************************************************
4809 Tool tips
4810 ***********************************************************************/
4812 static Lisp_Object x_create_tip_frame P_ ((struct x_display_info *,
4813 Lisp_Object, Lisp_Object));
4814 static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object,
4815 Lisp_Object, int, int, int *, int *));
4817 /* The frame of a currently visible tooltip. */
4819 Lisp_Object tip_frame;
4821 /* If non-nil, a timer started that hides the last tooltip when it
4822 fires. */
4824 Lisp_Object tip_timer;
4825 Window tip_window;
4827 /* If non-nil, a vector of 3 elements containing the last args
4828 with which x-show-tip was called. See there. */
4830 Lisp_Object last_show_tip_args;
4832 /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
4834 Lisp_Object Vx_max_tooltip_size;
4837 static Lisp_Object
4838 unwind_create_tip_frame (frame)
4839 Lisp_Object frame;
4841 Lisp_Object deleted;
4843 deleted = unwind_create_frame (frame);
4844 if (EQ (deleted, Qt))
4846 tip_window = None;
4847 tip_frame = Qnil;
4850 return deleted;
4854 /* Create a frame for a tooltip on the display described by DPYINFO.
4855 PARMS is a list of frame parameters. TEXT is the string to
4856 display in the tip frame. Value is the frame.
4858 Note that functions called here, esp. x_default_parameter can
4859 signal errors, for instance when a specified color name is
4860 undefined. We have to make sure that we're in a consistent state
4861 when this happens. */
4863 static Lisp_Object
4864 x_create_tip_frame (dpyinfo, parms, text)
4865 struct x_display_info *dpyinfo;
4866 Lisp_Object parms, text;
4868 struct frame *f;
4869 Lisp_Object frame, tem;
4870 Lisp_Object name;
4871 long window_prompting = 0;
4872 int width, height;
4873 int count = SPECPDL_INDEX ();
4874 struct gcpro gcpro1, gcpro2, gcpro3;
4875 int face_change_count_before = face_change_count;
4876 Lisp_Object buffer;
4877 struct buffer *old_buffer;
4879 check_x ();
4881 if (!dpyinfo->terminal->name)
4882 error ("Terminal is not live, can't create new frames on it");
4884 parms = Fcopy_alist (parms);
4886 /* Get the name of the frame to use for resource lookup. */
4887 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
4888 if (!STRINGP (name)
4889 && !EQ (name, Qunbound)
4890 && !NILP (name))
4891 error ("Invalid frame name--not a string or nil");
4893 frame = Qnil;
4894 GCPRO3 (parms, name, frame);
4895 f = make_frame (1);
4896 XSETFRAME (frame, f);
4898 buffer = Fget_buffer_create (build_string (" *tip*"));
4899 Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer, Qnil);
4900 old_buffer = current_buffer;
4901 set_buffer_internal_1 (XBUFFER (buffer));
4902 current_buffer->truncate_lines = Qnil;
4903 specbind (Qinhibit_read_only, Qt);
4904 specbind (Qinhibit_modification_hooks, Qt);
4905 Ferase_buffer ();
4906 Finsert (1, &text);
4907 set_buffer_internal_1 (old_buffer);
4909 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
4910 record_unwind_protect (unwind_create_tip_frame, frame);
4912 f->terminal = dpyinfo->terminal;
4913 f->terminal->reference_count++;
4915 /* By setting the output method, we're essentially saying that
4916 the frame is live, as per FRAME_LIVE_P. If we get a signal
4917 from this point on, x_destroy_window might screw up reference
4918 counts etc. */
4919 f->output_method = output_x_window;
4920 f->output_data.x = (struct x_output *) xmalloc (sizeof (struct x_output));
4921 bzero (f->output_data.x, sizeof (struct x_output));
4922 f->output_data.x->icon_bitmap = -1;
4923 FRAME_FONTSET (f) = -1;
4924 f->output_data.x->scroll_bar_foreground_pixel = -1;
4925 f->output_data.x->scroll_bar_background_pixel = -1;
4926 #ifdef USE_TOOLKIT_SCROLL_BARS
4927 f->output_data.x->scroll_bar_top_shadow_pixel = -1;
4928 f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
4929 #endif /* USE_TOOLKIT_SCROLL_BARS */
4930 f->icon_name = Qnil;
4931 FRAME_X_DISPLAY_INFO (f) = dpyinfo;
4932 #if GLYPH_DEBUG
4933 image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
4934 dpyinfo_refcount = dpyinfo->reference_count;
4935 #endif /* GLYPH_DEBUG */
4936 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
4937 f->output_data.x->explicit_parent = 0;
4939 /* These colors will be set anyway later, but it's important
4940 to get the color reference counts right, so initialize them! */
4942 Lisp_Object black;
4943 struct gcpro gcpro1;
4945 /* Function x_decode_color can signal an error. Make
4946 sure to initialize color slots so that we won't try
4947 to free colors we haven't allocated. */
4948 FRAME_FOREGROUND_PIXEL (f) = -1;
4949 FRAME_BACKGROUND_PIXEL (f) = -1;
4950 f->output_data.x->cursor_pixel = -1;
4951 f->output_data.x->cursor_foreground_pixel = -1;
4952 f->output_data.x->border_pixel = -1;
4953 f->output_data.x->mouse_pixel = -1;
4955 black = build_string ("black");
4956 GCPRO1 (black);
4957 FRAME_FOREGROUND_PIXEL (f)
4958 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4959 FRAME_BACKGROUND_PIXEL (f)
4960 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4961 f->output_data.x->cursor_pixel
4962 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4963 f->output_data.x->cursor_foreground_pixel
4964 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4965 f->output_data.x->border_pixel
4966 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4967 f->output_data.x->mouse_pixel
4968 = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
4969 UNGCPRO;
4972 /* Set the name; the functions to which we pass f expect the name to
4973 be set. */
4974 if (EQ (name, Qunbound) || NILP (name))
4976 f->name = build_string (dpyinfo->x_id_name);
4977 f->explicit_name = 0;
4979 else
4981 f->name = name;
4982 f->explicit_name = 1;
4983 /* use the frame's title when getting resources for this frame. */
4984 specbind (Qx_resource_name, name);
4987 f->resx = dpyinfo->resx;
4988 f->resy = dpyinfo->resy;
4990 #ifdef USE_FONT_BACKEND
4991 if (enable_font_backend)
4993 /* Perhaps, we must allow frame parameter, say `font-backend',
4994 to specify which font backends to use. */
4995 #ifdef HAVE_FREETYPE
4996 #ifdef HAVE_XFT
4997 register_font_driver (&xftfont_driver, f);
4998 #else /* not HAVE_XFT */
4999 register_font_driver (&ftxfont_driver, f);
5000 #endif /* not HAVE_XFT */
5001 #endif /* HAVE_FREETYPE */
5002 register_font_driver (&xfont_driver, f);
5004 x_default_parameter (f, parms, Qfont_backend, Qnil,
5005 "fontBackend", "FontBackend", RES_TYPE_STRING);
5007 #endif /* USE_FONT_BACKEND */
5009 /* Extract the window parameters from the supplied values that are
5010 needed to determine window geometry. */
5011 #ifdef USE_FONT_BACKEND
5012 if (enable_font_backend)
5013 x_default_font_parameter (f, parms);
5014 else
5015 #endif /* USE_FONT_BACKEND */
5017 Lisp_Object font;
5019 font = x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
5021 BLOCK_INPUT;
5022 /* First, try whatever font the caller has specified. */
5023 if (STRINGP (font))
5025 tem = Fquery_fontset (font, Qnil);
5026 if (STRINGP (tem))
5027 font = x_new_fontset (f, tem);
5028 else
5029 font = x_new_font (f, SDATA (font));
5032 /* Try out a font which we hope has bold and italic variations. */
5033 if (!STRINGP (font))
5034 font = x_new_font (f, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
5035 if (!STRINGP (font))
5036 font = x_new_font (f, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
5037 if (! STRINGP (font))
5038 font = x_new_font (f, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
5039 if (! STRINGP (font))
5040 /* This was formerly the first thing tried, but it finds too many fonts
5041 and takes too long. */
5042 font = x_new_font (f, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
5043 /* If those didn't work, look for something which will at least work. */
5044 if (! STRINGP (font))
5045 font = x_new_font (f, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
5046 UNBLOCK_INPUT;
5047 if (! STRINGP (font))
5048 font = build_string ("fixed");
5050 x_set_frame_parameters (f, Fcons (Fcons (Qfont, font), Qnil));
5053 x_default_parameter (f, parms, Qborder_width, make_number (2),
5054 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
5056 /* This defaults to 2 in order to match xterm. We recognize either
5057 internalBorderWidth or internalBorder (which is what xterm calls
5058 it). */
5059 if (NILP (Fassq (Qinternal_border_width, parms)))
5061 Lisp_Object value;
5063 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
5064 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
5065 if (! EQ (value, Qunbound))
5066 parms = Fcons (Fcons (Qinternal_border_width, value),
5067 parms);
5070 x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
5071 "internalBorderWidth", "internalBorderWidth",
5072 RES_TYPE_NUMBER);
5074 /* Also do the stuff which must be set before the window exists. */
5075 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
5076 "foreground", "Foreground", RES_TYPE_STRING);
5077 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
5078 "background", "Background", RES_TYPE_STRING);
5079 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
5080 "pointerColor", "Foreground", RES_TYPE_STRING);
5081 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
5082 "cursorColor", "Foreground", RES_TYPE_STRING);
5083 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
5084 "borderColor", "BorderColor", RES_TYPE_STRING);
5086 /* Init faces before x_default_parameter is called for scroll-bar
5087 parameters because that function calls x_set_scroll_bar_width,
5088 which calls change_frame_size, which calls Fset_window_buffer,
5089 which runs hooks, which call Fvertical_motion. At the end, we
5090 end up in init_iterator with a null face cache, which should not
5091 happen. */
5092 init_frame_faces (f);
5094 f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
5096 window_prompting = x_figure_window_size (f, parms, 0);
5099 XSetWindowAttributes attrs;
5100 unsigned long mask;
5102 BLOCK_INPUT;
5103 mask = CWBackPixel | CWOverrideRedirect | CWEventMask;
5104 if (DoesSaveUnders (dpyinfo->screen))
5105 mask |= CWSaveUnder;
5107 /* Window managers look at the override-redirect flag to determine
5108 whether or net to give windows a decoration (Xlib spec, chapter
5109 3.2.8). */
5110 attrs.override_redirect = True;
5111 attrs.save_under = True;
5112 attrs.background_pixel = FRAME_BACKGROUND_PIXEL (f);
5113 /* Arrange for getting MapNotify and UnmapNotify events. */
5114 attrs.event_mask = StructureNotifyMask;
5115 tip_window
5116 = FRAME_X_WINDOW (f)
5117 = XCreateWindow (FRAME_X_DISPLAY (f),
5118 FRAME_X_DISPLAY_INFO (f)->root_window,
5119 /* x, y, width, height */
5120 0, 0, 1, 1,
5121 /* Border. */
5123 CopyFromParent, InputOutput, CopyFromParent,
5124 mask, &attrs);
5125 UNBLOCK_INPUT;
5128 x_make_gc (f);
5130 x_default_parameter (f, parms, Qauto_raise, Qnil,
5131 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
5132 x_default_parameter (f, parms, Qauto_lower, Qnil,
5133 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
5134 x_default_parameter (f, parms, Qcursor_type, Qbox,
5135 "cursorType", "CursorType", RES_TYPE_SYMBOL);
5137 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
5138 Change will not be effected unless different from the current
5139 FRAME_LINES (f). */
5140 width = FRAME_COLS (f);
5141 height = FRAME_LINES (f);
5142 SET_FRAME_COLS (f, 0);
5143 FRAME_LINES (f) = 0;
5144 change_frame_size (f, height, width, 1, 0, 0);
5146 /* Add `tooltip' frame parameter's default value. */
5147 if (NILP (Fframe_parameter (frame, intern ("tooltip"))))
5148 Fmodify_frame_parameters (frame, Fcons (Fcons (intern ("tooltip"), Qt),
5149 Qnil));
5151 /* FIXME - can this be done in a similar way to normal frames?
5152 http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
5154 /* Set the `display-type' frame parameter before setting up faces. */
5156 Lisp_Object disptype;
5158 if (FRAME_X_DISPLAY_INFO (f)->n_planes == 1)
5159 disptype = intern ("mono");
5160 else if (FRAME_X_DISPLAY_INFO (f)->visual->class == GrayScale
5161 || FRAME_X_DISPLAY_INFO (f)->visual->class == StaticGray)
5162 disptype = intern ("grayscale");
5163 else
5164 disptype = intern ("color");
5166 if (NILP (Fframe_parameter (frame, Qdisplay_type)))
5167 Fmodify_frame_parameters (frame, Fcons (Fcons (Qdisplay_type, disptype),
5168 Qnil));
5171 /* Set up faces after all frame parameters are known. This call
5172 also merges in face attributes specified for new frames.
5174 Frame parameters may be changed if .Xdefaults contains
5175 specifications for the default font. For example, if there is an
5176 `Emacs.default.attributeBackground: pink', the `background-color'
5177 attribute of the frame get's set, which let's the internal border
5178 of the tooltip frame appear in pink. Prevent this. */
5180 Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
5182 /* Set tip_frame here, so that */
5183 tip_frame = frame;
5184 call1 (Qface_set_after_frame_default, frame);
5186 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
5187 Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg),
5188 Qnil));
5191 f->no_split = 1;
5193 UNGCPRO;
5195 /* It is now ok to make the frame official even if we get an error
5196 below. And the frame needs to be on Vframe_list or making it
5197 visible won't work. */
5198 Vframe_list = Fcons (frame, Vframe_list);
5200 /* Now that the frame is official, it counts as a reference to
5201 its display. */
5202 FRAME_X_DISPLAY_INFO (f)->reference_count++;
5204 /* Setting attributes of faces of the tooltip frame from resources
5205 and similar will increment face_change_count, which leads to the
5206 clearing of all current matrices. Since this isn't necessary
5207 here, avoid it by resetting face_change_count to the value it
5208 had before we created the tip frame. */
5209 face_change_count = face_change_count_before;
5211 /* Discard the unwind_protect. */
5212 return unbind_to (count, frame);
5216 /* Compute where to display tip frame F. PARMS is the list of frame
5217 parameters for F. DX and DY are specified offsets from the current
5218 location of the mouse. WIDTH and HEIGHT are the width and height
5219 of the tooltip. Return coordinates relative to the root window of
5220 the display in *ROOT_X, and *ROOT_Y. */
5222 static void
5223 compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
5224 struct frame *f;
5225 Lisp_Object parms, dx, dy;
5226 int width, height;
5227 int *root_x, *root_y;
5229 Lisp_Object left, top;
5230 int win_x, win_y;
5231 Window root, child;
5232 unsigned pmask;
5234 /* User-specified position? */
5235 left = Fcdr (Fassq (Qleft, parms));
5236 top = Fcdr (Fassq (Qtop, parms));
5238 /* Move the tooltip window where the mouse pointer is. Resize and
5239 show it. */
5240 if (!INTEGERP (left) || !INTEGERP (top))
5242 BLOCK_INPUT;
5243 XQueryPointer (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
5244 &root, &child, root_x, root_y, &win_x, &win_y, &pmask);
5245 UNBLOCK_INPUT;
5248 if (INTEGERP (top))
5249 *root_y = XINT (top);
5250 else if (*root_y + XINT (dy) <= 0)
5251 *root_y = 0; /* Can happen for negative dy */
5252 else if (*root_y + XINT (dy) + height <= FRAME_X_DISPLAY_INFO (f)->height)
5253 /* It fits below the pointer */
5254 *root_y += XINT (dy);
5255 else if (height + XINT (dy) <= *root_y)
5256 /* It fits above the pointer. */
5257 *root_y -= height + XINT (dy);
5258 else
5259 /* Put it on the top. */
5260 *root_y = 0;
5262 if (INTEGERP (left))
5263 *root_x = XINT (left);
5264 else if (*root_x + XINT (dx) <= 0)
5265 *root_x = 0; /* Can happen for negative dx */
5266 else if (*root_x + XINT (dx) + width <= FRAME_X_DISPLAY_INFO (f)->width)
5267 /* It fits to the right of the pointer. */
5268 *root_x += XINT (dx);
5269 else if (width + XINT (dx) <= *root_x)
5270 /* It fits to the left of the pointer. */
5271 *root_x -= width + XINT (dx);
5272 else
5273 /* Put it left-justified on the screen--it ought to fit that way. */
5274 *root_x = 0;
5278 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
5279 doc: /* Show STRING in a "tooltip" window on frame FRAME.
5280 A tooltip window is a small X window displaying a string.
5282 This is an internal function; Lisp code should call `tooltip-show'.
5284 FRAME nil or omitted means use the selected frame.
5286 PARMS is an optional list of frame parameters which can be used to
5287 change the tooltip's appearance.
5289 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
5290 means use the default timeout of 5 seconds.
5292 If the list of frame parameters PARAMS contains a `left' parameters,
5293 the tooltip is displayed at that x-position. Otherwise it is
5294 displayed at the mouse position, with offset DX added (default is 5 if
5295 DX isn't specified). Likewise for the y-position; if a `top' frame
5296 parameter is specified, it determines the y-position of the tooltip
5297 window, otherwise it is displayed at the mouse position, with offset
5298 DY added (default is -10).
5300 A tooltip's maximum size is specified by `x-max-tooltip-size'.
5301 Text larger than the specified size is clipped. */)
5302 (string, frame, parms, timeout, dx, dy)
5303 Lisp_Object string, frame, parms, timeout, dx, dy;
5305 struct frame *f;
5306 struct window *w;
5307 int root_x, root_y;
5308 struct buffer *old_buffer;
5309 struct text_pos pos;
5310 int i, width, height;
5311 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
5312 int old_windows_or_buffers_changed = windows_or_buffers_changed;
5313 int count = SPECPDL_INDEX ();
5315 specbind (Qinhibit_redisplay, Qt);
5317 GCPRO4 (string, parms, frame, timeout);
5319 CHECK_STRING (string);
5320 if (SCHARS (string) == 0)
5321 string = make_unibyte_string (" ", 1);
5323 f = check_x_frame (frame);
5324 if (NILP (timeout))
5325 timeout = make_number (5);
5326 else
5327 CHECK_NATNUM (timeout);
5329 if (NILP (dx))
5330 dx = make_number (5);
5331 else
5332 CHECK_NUMBER (dx);
5334 if (NILP (dy))
5335 dy = make_number (-10);
5336 else
5337 CHECK_NUMBER (dy);
5339 if (NILP (last_show_tip_args))
5340 last_show_tip_args = Fmake_vector (make_number (3), Qnil);
5342 if (!NILP (tip_frame))
5344 Lisp_Object last_string = AREF (last_show_tip_args, 0);
5345 Lisp_Object last_frame = AREF (last_show_tip_args, 1);
5346 Lisp_Object last_parms = AREF (last_show_tip_args, 2);
5348 if (EQ (frame, last_frame)
5349 && !NILP (Fequal (last_string, string))
5350 && !NILP (Fequal (last_parms, parms)))
5352 struct frame *f = XFRAME (tip_frame);
5354 /* Only DX and DY have changed. */
5355 if (!NILP (tip_timer))
5357 Lisp_Object timer = tip_timer;
5358 tip_timer = Qnil;
5359 call1 (Qcancel_timer, timer);
5362 BLOCK_INPUT;
5363 compute_tip_xy (f, parms, dx, dy, FRAME_PIXEL_WIDTH (f),
5364 FRAME_PIXEL_HEIGHT (f), &root_x, &root_y);
5365 XMoveWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5366 root_x, root_y);
5367 UNBLOCK_INPUT;
5368 goto start_timer;
5372 /* Hide a previous tip, if any. */
5373 Fx_hide_tip ();
5375 ASET (last_show_tip_args, 0, string);
5376 ASET (last_show_tip_args, 1, frame);
5377 ASET (last_show_tip_args, 2, parms);
5379 /* Add default values to frame parameters. */
5380 if (NILP (Fassq (Qname, parms)))
5381 parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
5382 if (NILP (Fassq (Qinternal_border_width, parms)))
5383 parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
5384 if (NILP (Fassq (Qborder_width, parms)))
5385 parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
5386 if (NILP (Fassq (Qborder_color, parms)))
5387 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
5388 if (NILP (Fassq (Qbackground_color, parms)))
5389 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
5390 parms);
5392 /* Create a frame for the tooltip, and record it in the global
5393 variable tip_frame. */
5394 frame = x_create_tip_frame (FRAME_X_DISPLAY_INFO (f), parms, string);
5395 f = XFRAME (frame);
5397 /* Set up the frame's root window. */
5398 w = XWINDOW (FRAME_ROOT_WINDOW (f));
5399 w->left_col = w->top_line = make_number (0);
5401 if (CONSP (Vx_max_tooltip_size)
5402 && INTEGERP (XCAR (Vx_max_tooltip_size))
5403 && XINT (XCAR (Vx_max_tooltip_size)) > 0
5404 && INTEGERP (XCDR (Vx_max_tooltip_size))
5405 && XINT (XCDR (Vx_max_tooltip_size)) > 0)
5407 w->total_cols = XCAR (Vx_max_tooltip_size);
5408 w->total_lines = XCDR (Vx_max_tooltip_size);
5410 else
5412 w->total_cols = make_number (80);
5413 w->total_lines = make_number (40);
5416 FRAME_TOTAL_COLS (f) = XINT (w->total_cols);
5417 adjust_glyphs (f);
5418 w->pseudo_window_p = 1;
5420 /* Display the tooltip text in a temporary buffer. */
5421 old_buffer = current_buffer;
5422 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer));
5423 current_buffer->truncate_lines = Qnil;
5424 clear_glyph_matrix (w->desired_matrix);
5425 clear_glyph_matrix (w->current_matrix);
5426 SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
5427 try_window (FRAME_ROOT_WINDOW (f), pos, 0);
5429 /* Compute width and height of the tooltip. */
5430 width = height = 0;
5431 for (i = 0; i < w->desired_matrix->nrows; ++i)
5433 struct glyph_row *row = &w->desired_matrix->rows[i];
5434 struct glyph *last;
5435 int row_width;
5437 /* Stop at the first empty row at the end. */
5438 if (!row->enabled_p || !row->displays_text_p)
5439 break;
5441 /* Let the row go over the full width of the frame. */
5442 row->full_width_p = 1;
5444 /* There's a glyph at the end of rows that is used to place
5445 the cursor there. Don't include the width of this glyph. */
5446 if (row->used[TEXT_AREA])
5448 last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
5449 row_width = row->pixel_width - last->pixel_width;
5451 else
5452 row_width = row->pixel_width;
5454 height += row->height;
5455 width = max (width, row_width);
5458 /* Add the frame's internal border to the width and height the X
5459 window should have. */
5460 height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5461 width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5463 /* Move the tooltip window where the mouse pointer is. Resize and
5464 show it. */
5465 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
5467 BLOCK_INPUT;
5468 XMoveResizeWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5469 root_x, root_y, width, height);
5470 XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
5471 UNBLOCK_INPUT;
5473 /* Draw into the window. */
5474 w->must_be_updated_p = 1;
5475 update_single_window (w, 1);
5477 /* Restore original current buffer. */
5478 set_buffer_internal_1 (old_buffer);
5479 windows_or_buffers_changed = old_windows_or_buffers_changed;
5481 start_timer:
5482 /* Let the tip disappear after timeout seconds. */
5483 tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
5484 intern ("x-hide-tip"));
5486 UNGCPRO;
5487 return unbind_to (count, Qnil);
5491 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
5492 doc: /* Hide the current tooltip window, if there is any.
5493 Value is t if tooltip was open, nil otherwise. */)
5496 int count;
5497 Lisp_Object deleted, frame, timer;
5498 struct gcpro gcpro1, gcpro2;
5500 /* Return quickly if nothing to do. */
5501 if (NILP (tip_timer) && NILP (tip_frame))
5502 return Qnil;
5504 frame = tip_frame;
5505 timer = tip_timer;
5506 GCPRO2 (frame, timer);
5507 tip_frame = tip_timer = deleted = Qnil;
5509 count = SPECPDL_INDEX ();
5510 specbind (Qinhibit_redisplay, Qt);
5511 specbind (Qinhibit_quit, Qt);
5513 if (!NILP (timer))
5514 call1 (Qcancel_timer, timer);
5516 if (FRAMEP (frame))
5518 Fdelete_frame (frame, Qnil);
5519 deleted = Qt;
5521 #ifdef USE_LUCID
5522 /* Bloodcurdling hack alert: The Lucid menu bar widget's
5523 redisplay procedure is not called when a tip frame over menu
5524 items is unmapped. Redisplay the menu manually... */
5526 struct frame *f = SELECTED_FRAME ();
5527 Widget w = f->output_data.x->menubar_widget;
5528 extern void xlwmenu_redisplay P_ ((Widget));
5530 if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f)->screen)
5531 && w != NULL)
5533 BLOCK_INPUT;
5534 xlwmenu_redisplay (w);
5535 UNBLOCK_INPUT;
5538 #endif /* USE_LUCID */
5541 UNGCPRO;
5542 return unbind_to (count, deleted);
5547 /***********************************************************************
5548 File selection dialog
5549 ***********************************************************************/
5551 DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog,
5552 Sx_uses_old_gtk_dialog,
5553 0, 0, 0,
5554 doc: /* Return t if the old Gtk+ file selection dialog is used. */)
5557 #ifdef USE_GTK
5558 extern int use_dialog_box;
5559 extern int use_file_dialog;
5561 if (use_dialog_box
5562 && use_file_dialog
5563 && have_menus_p ()
5564 && xg_uses_old_file_dialog ())
5565 return Qt;
5566 #endif
5567 return Qnil;
5571 #ifdef USE_MOTIF
5572 /* Callback for "OK" and "Cancel" on file selection dialog. */
5574 static void
5575 file_dialog_cb (widget, client_data, call_data)
5576 Widget widget;
5577 XtPointer call_data, client_data;
5579 int *result = (int *) client_data;
5580 XmAnyCallbackStruct *cb = (XmAnyCallbackStruct *) call_data;
5581 *result = cb->reason;
5585 /* Callback for unmapping a file selection dialog. This is used to
5586 capture the case where a dialog is closed via a window manager's
5587 closer button, for example. Using a XmNdestroyCallback didn't work
5588 in this case. */
5590 static void
5591 file_dialog_unmap_cb (widget, client_data, call_data)
5592 Widget widget;
5593 XtPointer call_data, client_data;
5595 int *result = (int *) client_data;
5596 *result = XmCR_CANCEL;
5599 static Lisp_Object
5600 clean_up_file_dialog (arg)
5601 Lisp_Object arg;
5603 struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
5604 Widget dialog = (Widget) p->pointer;
5606 /* Clean up. */
5607 BLOCK_INPUT;
5608 XtUnmanageChild (dialog);
5609 XtDestroyWidget (dialog);
5610 x_menu_set_in_use (0);
5611 UNBLOCK_INPUT;
5613 return Qnil;
5617 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5618 doc: /* Read file name, prompting with PROMPT in directory DIR.
5619 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5620 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5621 or directory must exist. ONLY-DIR-P is ignored." */)
5622 (prompt, dir, default_filename, mustmatch, only_dir_p)
5623 Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
5625 int result;
5626 struct frame *f = SELECTED_FRAME ();
5627 Lisp_Object file = Qnil;
5628 Lisp_Object decoded_file;
5629 Widget dialog, text, help;
5630 Arg al[10];
5631 int ac = 0;
5632 extern XtAppContext Xt_app_con;
5633 XmString dir_xmstring, pattern_xmstring;
5634 int count = SPECPDL_INDEX ();
5635 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5637 check_x ();
5639 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5641 if (popup_activated ())
5642 error ("Trying to use a menu from within a menu-entry");
5644 CHECK_STRING (prompt);
5645 CHECK_STRING (dir);
5647 /* Prevent redisplay. */
5648 specbind (Qinhibit_redisplay, Qt);
5650 BLOCK_INPUT;
5652 /* Create the dialog with PROMPT as title, using DIR as initial
5653 directory and using "*" as pattern. */
5654 dir = Fexpand_file_name (dir, Qnil);
5655 dir_xmstring = XmStringCreateLocalized (SDATA (dir));
5656 pattern_xmstring = XmStringCreateLocalized ("*");
5658 XtSetArg (al[ac], XmNtitle, SDATA (prompt)); ++ac;
5659 XtSetArg (al[ac], XmNdirectory, dir_xmstring); ++ac;
5660 XtSetArg (al[ac], XmNpattern, pattern_xmstring); ++ac;
5661 XtSetArg (al[ac], XmNresizePolicy, XmRESIZE_GROW); ++ac;
5662 XtSetArg (al[ac], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); ++ac;
5663 dialog = XmCreateFileSelectionDialog (f->output_data.x->widget,
5664 "fsb", al, ac);
5665 XmStringFree (dir_xmstring);
5666 XmStringFree (pattern_xmstring);
5668 /* Add callbacks for OK and Cancel. */
5669 XtAddCallback (dialog, XmNokCallback, file_dialog_cb,
5670 (XtPointer) &result);
5671 XtAddCallback (dialog, XmNcancelCallback, file_dialog_cb,
5672 (XtPointer) &result);
5673 XtAddCallback (dialog, XmNunmapCallback, file_dialog_unmap_cb,
5674 (XtPointer) &result);
5676 /* Remove the help button since we can't display help. */
5677 help = XmFileSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON);
5678 XtUnmanageChild (help);
5680 /* Mark OK button as default. */
5681 XtVaSetValues (XmFileSelectionBoxGetChild (dialog, XmDIALOG_OK_BUTTON),
5682 XmNshowAsDefault, True, NULL);
5684 /* If MUSTMATCH is non-nil, disable the file entry field of the
5685 dialog, so that the user must select a file from the files list
5686 box. We can't remove it because we wouldn't have a way to get at
5687 the result file name, then. */
5688 text = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5689 if (!NILP (mustmatch))
5691 Widget label;
5692 label = XmFileSelectionBoxGetChild (dialog, XmDIALOG_SELECTION_LABEL);
5693 XtSetSensitive (text, False);
5694 XtSetSensitive (label, False);
5697 /* Manage the dialog, so that list boxes get filled. */
5698 XtManageChild (dialog);
5700 if (STRINGP (default_filename))
5702 XmString default_xmstring;
5703 Widget wtext = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5704 Widget list = XmFileSelectionBoxGetChild (dialog, XmDIALOG_LIST);
5706 XmTextPosition last_pos = XmTextFieldGetLastPosition (wtext);
5707 XmTextFieldReplace (wtext, 0, last_pos,
5708 (SDATA (Ffile_name_nondirectory (default_filename))));
5710 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
5711 must include the path for this to work. */
5713 default_xmstring = XmStringCreateLocalized (SDATA (default_filename));
5715 if (XmListItemExists (list, default_xmstring))
5717 int item_pos = XmListItemPos (list, default_xmstring);
5718 /* Select the item and scroll it into view. */
5719 XmListSelectPos (list, item_pos, True);
5720 XmListSetPos (list, item_pos);
5723 XmStringFree (default_xmstring);
5726 record_unwind_protect (clean_up_file_dialog, make_save_value (dialog, 0));
5728 /* Process events until the user presses Cancel or OK. */
5729 x_menu_set_in_use (1);
5730 result = 0;
5731 while (result == 0)
5733 XEvent event;
5734 x_menu_wait_for_event (0);
5735 XtAppNextEvent (Xt_app_con, &event);
5736 if (event.type == KeyPress
5737 && FRAME_X_DISPLAY (f) == event.xkey.display)
5739 KeySym keysym = XLookupKeysym (&event.xkey, 0);
5741 /* Pop down on C-g. */
5742 if (keysym == XK_g && (event.xkey.state & ControlMask) != 0)
5743 XtUnmanageChild (dialog);
5746 (void) x_dispatch_event (&event, FRAME_X_DISPLAY (f));
5749 /* Get the result. */
5750 if (result == XmCR_OK)
5752 XmString text;
5753 String data;
5755 XtVaGetValues (dialog, XmNtextString, &text, NULL);
5756 XmStringGetLtoR (text, XmFONTLIST_DEFAULT_TAG, &data);
5757 XmStringFree (text);
5758 file = build_string (data);
5759 XtFree (data);
5761 else
5762 file = Qnil;
5764 UNBLOCK_INPUT;
5765 UNGCPRO;
5767 /* Make "Cancel" equivalent to C-g. */
5768 if (NILP (file))
5769 Fsignal (Qquit, Qnil);
5771 decoded_file = DECODE_FILE (file);
5773 return unbind_to (count, decoded_file);
5776 #endif /* USE_MOTIF */
5778 #ifdef USE_GTK
5780 static Lisp_Object
5781 clean_up_dialog (arg)
5782 Lisp_Object arg;
5784 x_menu_set_in_use (0);
5786 return Qnil;
5789 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5790 doc: /* Read file name, prompting with PROMPT in directory DIR.
5791 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5792 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5793 or directory must exist. If ONLY-DIR-P is non-nil, the user can only select
5794 directories. */)
5795 (prompt, dir, default_filename, mustmatch, only_dir_p)
5796 Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
5798 FRAME_PTR f = SELECTED_FRAME ();
5799 char *fn;
5800 Lisp_Object file = Qnil;
5801 Lisp_Object decoded_file;
5802 int count = SPECPDL_INDEX ();
5803 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5804 char *cdef_file;
5806 check_x ();
5808 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5810 if (popup_activated ())
5811 error ("Trying to use a menu from within a menu-entry");
5813 CHECK_STRING (prompt);
5814 CHECK_STRING (dir);
5816 /* Prevent redisplay. */
5817 specbind (Qinhibit_redisplay, Qt);
5818 record_unwind_protect (clean_up_dialog, Qnil);
5820 BLOCK_INPUT;
5822 if (STRINGP (default_filename))
5823 cdef_file = SDATA (default_filename);
5824 else
5825 cdef_file = SDATA (dir);
5827 fn = xg_get_file_name (f, SDATA (prompt), cdef_file,
5828 ! NILP (mustmatch),
5829 ! NILP (only_dir_p));
5831 if (fn)
5833 file = build_string (fn);
5834 xfree (fn);
5837 UNBLOCK_INPUT;
5838 UNGCPRO;
5840 /* Make "Cancel" equivalent to C-g. */
5841 if (NILP (file))
5842 Fsignal (Qquit, Qnil);
5844 decoded_file = DECODE_FILE (file);
5846 return unbind_to (count, decoded_file);
5849 #endif /* USE_GTK */
5852 /***********************************************************************
5853 Keyboard
5854 ***********************************************************************/
5856 #ifdef HAVE_XKBGETKEYBOARD
5857 #include <X11/XKBlib.h>
5858 #include <X11/keysym.h>
5859 #endif
5861 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p,
5862 Sx_backspace_delete_keys_p, 0, 1, 0,
5863 doc: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
5864 FRAME nil means use the selected frame.
5865 Value is t if we know that both keys are present, and are mapped to the
5866 usual X keysyms. Value is `lambda' if we cannot determine if both keys are
5867 present and mapped to the usual X keysyms. */)
5868 (frame)
5869 Lisp_Object frame;
5871 #ifdef HAVE_XKBGETKEYBOARD
5872 XkbDescPtr kb;
5873 struct frame *f = check_x_frame (frame);
5874 Display *dpy = FRAME_X_DISPLAY (f);
5875 Lisp_Object have_keys;
5876 int major, minor, op, event, error;
5878 BLOCK_INPUT;
5880 /* Check library version in case we're dynamically linked. */
5881 major = XkbMajorVersion;
5882 minor = XkbMinorVersion;
5883 if (!XkbLibraryVersion (&major, &minor))
5885 UNBLOCK_INPUT;
5886 return Qlambda;
5889 /* Check that the server supports XKB. */
5890 major = XkbMajorVersion;
5891 minor = XkbMinorVersion;
5892 if (!XkbQueryExtension (dpy, &op, &event, &error, &major, &minor))
5894 UNBLOCK_INPUT;
5895 return Qlambda;
5898 /* In this code we check that the keyboard has physical keys with names
5899 that start with BKSP (Backspace) and DELE (Delete), and that they
5900 generate keysym XK_BackSpace and XK_Delete respectively.
5901 This function is used to test if normal-erase-is-backspace should be
5902 turned on.
5903 An alternative approach would be to just check if XK_BackSpace and
5904 XK_Delete are mapped to any key. But if any of those are mapped to
5905 some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the
5906 user doesn't know about it, it is better to return false here.
5907 It is more obvious to the user what to do if she/he has two keys
5908 clearly marked with names/symbols and one key does something not
5909 expected (i.e. she/he then tries the other).
5910 The cases where Backspace/Delete is mapped to some other key combination
5911 are rare, and in those cases, normal-erase-is-backspace can be turned on
5912 manually. */
5914 have_keys = Qnil;
5915 kb = XkbGetMap (dpy, XkbAllMapComponentsMask, XkbUseCoreKbd);
5916 if (kb)
5918 int delete_keycode = 0, backspace_keycode = 0, i;
5920 if (XkbGetNames (dpy, XkbAllNamesMask, kb) == Success)
5922 for (i = kb->min_key_code;
5923 (i < kb->max_key_code
5924 && (delete_keycode == 0 || backspace_keycode == 0));
5925 ++i)
5927 /* The XKB symbolic key names can be seen most easily in
5928 the PS file generated by `xkbprint -label name
5929 $DISPLAY'. */
5930 if (bcmp ("DELE", kb->names->keys[i].name, 4) == 0)
5931 delete_keycode = i;
5932 else if (bcmp ("BKSP", kb->names->keys[i].name, 4) == 0)
5933 backspace_keycode = i;
5936 XkbFreeNames (kb, 0, True);
5939 XkbFreeClientMap (kb, 0, True);
5941 if (delete_keycode
5942 && backspace_keycode
5943 && XKeysymToKeycode (dpy, XK_Delete) == delete_keycode
5944 && XKeysymToKeycode (dpy, XK_BackSpace) == backspace_keycode)
5945 have_keys = Qt;
5947 UNBLOCK_INPUT;
5948 return have_keys;
5949 #else /* not HAVE_XKBGETKEYBOARD */
5950 return Qlambda;
5951 #endif /* not HAVE_XKBGETKEYBOARD */
5956 /***********************************************************************
5957 Initialization
5958 ***********************************************************************/
5960 /* Keep this list in the same order as frame_parms in frame.c.
5961 Use 0 for unsupported frame parameters. */
5963 frame_parm_handler x_frame_parm_handlers[] =
5965 x_set_autoraise,
5966 x_set_autolower,
5967 x_set_background_color,
5968 x_set_border_color,
5969 x_set_border_width,
5970 x_set_cursor_color,
5971 x_set_cursor_type,
5972 x_set_font,
5973 x_set_foreground_color,
5974 x_set_icon_name,
5975 x_set_icon_type,
5976 x_set_internal_border_width,
5977 x_set_menu_bar_lines,
5978 x_set_mouse_color,
5979 x_explicitly_set_name,
5980 x_set_scroll_bar_width,
5981 x_set_title,
5982 x_set_unsplittable,
5983 x_set_vertical_scroll_bars,
5984 x_set_visibility,
5985 x_set_tool_bar_lines,
5986 x_set_scroll_bar_foreground,
5987 x_set_scroll_bar_background,
5988 x_set_screen_gamma,
5989 x_set_line_spacing,
5990 x_set_fringe_width,
5991 x_set_fringe_width,
5992 x_set_wait_for_wm,
5993 x_set_fullscreen,
5994 #ifdef USE_FONT_BACKEND
5995 x_set_font_backend
5996 #endif /* USE_FONT_BACKEND */
5999 void
6000 syms_of_xfns ()
6002 /* This is zero if not using X windows. */
6003 x_in_use = 0;
6005 /* The section below is built by the lisp expression at the top of the file,
6006 just above where these variables are declared. */
6007 /*&&& init symbols here &&&*/
6008 Qnone = intern ("none");
6009 staticpro (&Qnone);
6010 Qsuppress_icon = intern ("suppress-icon");
6011 staticpro (&Qsuppress_icon);
6012 Qundefined_color = intern ("undefined-color");
6013 staticpro (&Qundefined_color);
6014 Qcompound_text = intern ("compound-text");
6015 staticpro (&Qcompound_text);
6016 Qcancel_timer = intern ("cancel-timer");
6017 staticpro (&Qcancel_timer);
6018 /* This is the end of symbol initialization. */
6020 /* Text property `display' should be nonsticky by default. */
6021 Vtext_property_default_nonsticky
6022 = Fcons (Fcons (Qdisplay, Qt), Vtext_property_default_nonsticky);
6025 Fput (Qundefined_color, Qerror_conditions,
6026 Fcons (Qundefined_color, Fcons (Qerror, Qnil)));
6027 Fput (Qundefined_color, Qerror_message,
6028 build_string ("Undefined color"));
6030 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
6031 doc: /* The shape of the pointer when over text.
6032 Changing the value does not affect existing frames
6033 unless you set the mouse color. */);
6034 Vx_pointer_shape = Qnil;
6036 #if 0 /* This doesn't really do anything. */
6037 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape,
6038 doc: /* The shape of the pointer when not over text.
6039 This variable takes effect when you create a new frame
6040 or when you set the mouse color. */);
6041 #endif
6042 Vx_nontext_pointer_shape = Qnil;
6044 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape,
6045 doc: /* The shape of the pointer when Emacs is busy.
6046 This variable takes effect when you create a new frame
6047 or when you set the mouse color. */);
6048 Vx_hourglass_pointer_shape = Qnil;
6050 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p,
6051 doc: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
6052 display_hourglass_p = 1;
6054 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay,
6055 doc: /* *Seconds to wait before displaying an hourglass pointer.
6056 Value must be an integer or float. */);
6057 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
6059 #if 0 /* This doesn't really do anything. */
6060 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape,
6061 doc: /* The shape of the pointer when over the mode line.
6062 This variable takes effect when you create a new frame
6063 or when you set the mouse color. */);
6064 #endif
6065 Vx_mode_pointer_shape = Qnil;
6067 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
6068 &Vx_sensitive_text_pointer_shape,
6069 doc: /* The shape of the pointer when over mouse-sensitive text.
6070 This variable takes effect when you create a new frame
6071 or when you set the mouse color. */);
6072 Vx_sensitive_text_pointer_shape = Qnil;
6074 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
6075 &Vx_window_horizontal_drag_shape,
6076 doc: /* Pointer shape to use for indicating a window can be dragged horizontally.
6077 This variable takes effect when you create a new frame
6078 or when you set the mouse color. */);
6079 Vx_window_horizontal_drag_shape = Qnil;
6081 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel,
6082 doc: /* A string indicating the foreground color of the cursor box. */);
6083 Vx_cursor_fore_pixel = Qnil;
6085 DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size,
6086 doc: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).
6087 Text larger than this is clipped. */);
6088 Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
6090 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
6091 doc: /* Non-nil if no X window manager is in use.
6092 Emacs doesn't try to figure this out; this is always nil
6093 unless you set it to something else. */);
6094 /* We don't have any way to find this out, so set it to nil
6095 and maybe the user would like to set it to t. */
6096 Vx_no_window_manager = Qnil;
6098 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
6099 &Vx_pixel_size_width_font_regexp,
6100 doc: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
6102 Since Emacs gets width of a font matching with this regexp from
6103 PIXEL_SIZE field of the name, font finding mechanism gets faster for
6104 such a font. This is especially effective for such large fonts as
6105 Chinese, Japanese, and Korean. */);
6106 Vx_pixel_size_width_font_regexp = Qnil;
6108 /* This is not ifdef:ed, so other builds than GTK can customize it. */
6109 DEFVAR_BOOL ("x-gtk-use-old-file-dialog", &x_gtk_use_old_file_dialog,
6110 doc: /* *Non-nil means prompt with the old GTK file selection dialog.
6111 If nil or if the file selection dialog is not available, the new GTK file
6112 chooser is used instead. To turn off all file dialogs set the
6113 variable `use-file-dialog'. */);
6114 x_gtk_use_old_file_dialog = 0;
6116 DEFVAR_BOOL ("x-gtk-show-hidden-files", &x_gtk_show_hidden_files,
6117 doc: /* *If non-nil, the GTK file chooser will by default show hidden files.
6118 Note that this is just the default, there is a toggle button on the file
6119 chooser to show or not show hidden files on a case by case basis. */);
6120 x_gtk_show_hidden_files = 0;
6122 DEFVAR_BOOL ("x-gtk-file-dialog-help-text", &x_gtk_file_dialog_help_text,
6123 doc: /* *If non-nil, the GTK file chooser will show additional help text.
6124 If more space for files in the file chooser dialog is wanted, set this to nil
6125 to turn the additional text off. */);
6126 x_gtk_file_dialog_help_text = 1;
6128 DEFVAR_BOOL ("x-gtk-whole-detached-tool-bar", &x_gtk_whole_detached_tool_bar,
6129 doc: /* *If non-nil, a detached tool bar is shown in full.
6130 The default is to just show an arrow and pressing on that arrow shows
6131 the tool bar buttons. */);
6132 x_gtk_whole_detached_tool_bar = 0;
6134 Fprovide (intern ("x"), Qnil);
6136 #ifdef USE_X_TOOLKIT
6137 Fprovide (intern ("x-toolkit"), Qnil);
6138 #ifdef USE_MOTIF
6139 Fprovide (intern ("motif"), Qnil);
6141 DEFVAR_LISP ("motif-version-string", &Vmotif_version_string,
6142 doc: /* Version info for LessTif/Motif. */);
6143 Vmotif_version_string = build_string (XmVERSION_STRING);
6144 #endif /* USE_MOTIF */
6145 #endif /* USE_X_TOOLKIT */
6147 #ifdef USE_GTK
6148 /* Provide x-toolkit also for GTK. Internally GTK does not use Xt so it
6149 is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
6150 But for a user it is a toolkit for X, and indeed, configure
6151 accepts --with-x-toolkit=gtk. */
6152 Fprovide (intern ("x-toolkit"), Qnil);
6153 Fprovide (intern ("gtk"), Qnil);
6155 DEFVAR_LISP ("gtk-version-string", &Vgtk_version_string,
6156 doc: /* Version info for GTK+. */);
6158 char gtk_version[40];
6159 g_snprintf (gtk_version, sizeof (gtk_version), "%u.%u.%u",
6160 GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
6161 Vgtk_version_string = build_string (gtk_version);
6163 #endif /* USE_GTK */
6165 /* X window properties. */
6166 defsubr (&Sx_change_window_property);
6167 defsubr (&Sx_delete_window_property);
6168 defsubr (&Sx_window_property);
6170 defsubr (&Sxw_display_color_p);
6171 defsubr (&Sx_display_grayscale_p);
6172 defsubr (&Sxw_color_defined_p);
6173 defsubr (&Sxw_color_values);
6174 defsubr (&Sx_server_max_request_size);
6175 defsubr (&Sx_server_vendor);
6176 defsubr (&Sx_server_version);
6177 defsubr (&Sx_display_pixel_width);
6178 defsubr (&Sx_display_pixel_height);
6179 defsubr (&Sx_display_mm_width);
6180 defsubr (&Sx_display_mm_height);
6181 defsubr (&Sx_display_screens);
6182 defsubr (&Sx_display_planes);
6183 defsubr (&Sx_display_color_cells);
6184 defsubr (&Sx_display_visual_class);
6185 defsubr (&Sx_display_backing_store);
6186 defsubr (&Sx_display_save_under);
6187 defsubr (&Sx_create_frame);
6188 defsubr (&Sx_open_connection);
6189 defsubr (&Sx_close_connection);
6190 defsubr (&Sx_display_list);
6191 defsubr (&Sx_synchronize);
6192 defsubr (&Sx_focus_frame);
6193 defsubr (&Sx_backspace_delete_keys_p);
6195 /* Setting callback functions for fontset handler. */
6196 get_font_info_func = x_get_font_info;
6198 #if 0 /* This function pointer doesn't seem to be used anywhere.
6199 And the pointer assigned has the wrong type, anyway. */
6200 list_fonts_func = x_list_fonts;
6201 #endif
6203 load_font_func = x_load_font;
6204 find_ccl_program_func = x_find_ccl_program;
6205 query_font_func = x_query_font;
6206 set_frame_fontset_func = x_set_font;
6207 get_font_repertory_func = x_get_font_repertory;
6208 check_window_system_func = check_x;
6210 hourglass_atimer = NULL;
6211 hourglass_shown_p = 0;
6213 defsubr (&Sx_show_tip);
6214 defsubr (&Sx_hide_tip);
6215 tip_timer = Qnil;
6216 staticpro (&tip_timer);
6217 tip_frame = Qnil;
6218 staticpro (&tip_frame);
6220 last_show_tip_args = Qnil;
6221 staticpro (&last_show_tip_args);
6223 defsubr (&Sx_uses_old_gtk_dialog);
6224 #if defined (USE_MOTIF) || defined (USE_GTK)
6225 defsubr (&Sx_file_dialog);
6226 #endif
6229 #endif /* HAVE_X_WINDOWS */
6231 /* arch-tag: 55040d02-5485-4d58-8b22-95a7a05f3288
6232 (do not change this comment) */