1 /* Functions for the X window system.
2 Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
31 /* This makes the fields of a Display accessible, in Xlib header files. */
33 #define XLIB_ILLEGAL_ACCESS
40 #include "intervals.h"
41 #include "dispextern.h"
43 #include "blockinput.h"
45 #include "character.h"
50 #include "termhooks.h"
58 #include <sys/types.h>
61 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */
62 #include "bitmaps/gray.xbm"
64 #include <X11/bitmaps/gray>
67 #include "xsettings.h"
74 #include <X11/Shell.h>
78 #include <X11/Xaw3d/Paned.h>
79 #include <X11/Xaw3d/Label.h>
80 #else /* !HAVE_XAW3D */
81 #include <X11/Xaw/Paned.h>
82 #include <X11/Xaw/Label.h>
83 #endif /* HAVE_XAW3D */
84 #endif /* USE_MOTIF */
87 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
96 #include "../lwlib/lwlib.h"
100 #include <Xm/DialogS.h>
101 #include <Xm/FileSB.h>
104 #if !defined(NO_EDITRES)
106 extern void _XEditResCheckMessages ();
107 #endif /* not defined NO_EDITRES */
109 /* Unique id counter for widgets created by the Lucid Widget Library. */
111 extern LWLIB_ID widget_id_tick
;
114 /* This is part of a kludge--see lwlib/xlwmenu.c. */
115 extern XFontStruct
*xlwmenu_default_font
;
118 extern void free_frame_menubar ();
119 extern double atof ();
123 /* LessTif/Motif version info. */
125 static Lisp_Object Vmotif_version_string
;
127 #endif /* USE_MOTIF */
129 #endif /* USE_X_TOOLKIT */
133 /* GTK+ version info */
135 static Lisp_Object Vgtk_version_string
;
139 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
141 /* The gray bitmap `bitmaps/gray'. This is done because xterm.c uses
142 it, and including `bitmaps/gray' more than once is a problem when
143 config.h defines `static' as an empty replacement string. */
145 int gray_bitmap_width
= gray_width
;
146 int gray_bitmap_height
= gray_height
;
147 char *gray_bitmap_bits
= gray_bits
;
149 /* Non-zero means prompt with the old GTK file selection dialog. */
151 int x_gtk_use_old_file_dialog
;
153 /* If non-zero, by default show hidden files in the GTK file chooser. */
155 int x_gtk_show_hidden_files
;
157 /* If non-zero, don't show additional help text in the GTK file chooser. */
159 int x_gtk_file_dialog_help_text
;
161 /* If non-zero, don't collapse to tool bar when it is detached. */
163 int x_gtk_whole_detached_tool_bar
;
165 /* The background and shape of the mouse pointer, and shape when not
166 over text or in the modeline. */
168 Lisp_Object Vx_pointer_shape
, Vx_nontext_pointer_shape
, Vx_mode_pointer_shape
;
169 Lisp_Object Vx_hourglass_pointer_shape
;
171 /* The shape when over mouse-sensitive text. */
173 Lisp_Object Vx_sensitive_text_pointer_shape
;
175 /* If non-nil, the pointer shape to indicate that windows can be
176 dragged horizontally. */
178 Lisp_Object Vx_window_horizontal_drag_shape
;
180 /* Color of chars displayed in cursor box. */
182 Lisp_Object Vx_cursor_fore_pixel
;
184 /* Nonzero if using X. */
188 /* Non nil if no window manager is in use. */
190 Lisp_Object Vx_no_window_manager
;
192 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
194 Lisp_Object Vx_pixel_size_width_font_regexp
;
197 Lisp_Object Qsuppress_icon
;
198 Lisp_Object Qundefined_color
;
199 Lisp_Object Qcompound_text
, Qcancel_timer
;
200 Lisp_Object Qfont_param
;
204 extern Lisp_Object Vwindow_system_version
;
206 /* The below are defined in frame.c. */
208 extern Lisp_Object Qtooltip
;
211 int image_cache_refcount
, dpyinfo_refcount
;
214 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
215 char *x_last_font_name
;
219 /* Error if we are not connected to X. */
225 error ("X windows are not in use or not initialized");
228 /* Nonzero if we can use mouse menus.
229 You should not call this unless HAVE_MENUS is defined. */
237 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
238 and checking validity for X. */
241 check_x_frame (frame
)
247 frame
= selected_frame
;
248 CHECK_LIVE_FRAME (frame
);
251 error ("Non-X frame used");
255 /* Let the user specify an X display with a Lisp object.
256 OBJECT may be nil, a frame or a terminal object.
257 nil stands for the selected frame--or, if that is not an X frame,
258 the first X display on the list. */
260 struct x_display_info
*
261 check_x_display_info (object
)
264 struct x_display_info
*dpyinfo
= NULL
;
268 struct frame
*sf
= XFRAME (selected_frame
);
270 if (FRAME_X_P (sf
) && FRAME_LIVE_P (sf
))
271 dpyinfo
= FRAME_X_DISPLAY_INFO (sf
);
272 else if (x_display_list
!= 0)
273 dpyinfo
= x_display_list
;
275 error ("X windows are not in use or not initialized");
277 else if (TERMINALP (object
))
279 struct terminal
*t
= get_terminal (object
, 1);
281 if (t
->type
!= output_x_window
)
282 error ("Terminal %d is not an X display", XINT (object
));
284 dpyinfo
= t
->display_info
.x
;
286 else if (STRINGP (object
))
287 dpyinfo
= x_display_info_for_name (object
);
290 FRAME_PTR f
= check_x_frame (object
);
291 dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
298 /* Return the Emacs frame-object corresponding to an X window.
299 It could be the frame's main window or an icon window. */
301 /* This function can be called during GC, so use GC_xxx type test macros. */
304 x_window_to_frame (dpyinfo
, wdesc
)
305 struct x_display_info
*dpyinfo
;
308 Lisp_Object tail
, frame
;
311 if (wdesc
== None
) return 0;
313 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
319 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
321 if (f
->output_data
.x
->hourglass_window
== wdesc
)
324 if ((f
->output_data
.x
->edit_widget
325 && XtWindow (f
->output_data
.x
->edit_widget
) == wdesc
)
326 /* A tooltip frame? */
327 || (!f
->output_data
.x
->edit_widget
328 && FRAME_X_WINDOW (f
) == wdesc
)
329 || f
->output_data
.x
->icon_desc
== wdesc
)
331 #else /* not USE_X_TOOLKIT */
333 if (f
->output_data
.x
->edit_widget
)
335 GtkWidget
*gwdesc
= xg_win_to_widget (dpyinfo
->display
, wdesc
);
336 struct x_output
*x
= f
->output_data
.x
;
337 if (gwdesc
!= 0 && gwdesc
== x
->edit_widget
)
341 if (FRAME_X_WINDOW (f
) == wdesc
342 || f
->output_data
.x
->icon_desc
== wdesc
)
344 #endif /* not USE_X_TOOLKIT */
349 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
350 /* Like x_window_to_frame but also compares the window with the widget's
354 x_any_window_to_frame (dpyinfo
, wdesc
)
355 struct x_display_info
*dpyinfo
;
358 Lisp_Object tail
, frame
;
359 struct frame
*f
, *found
;
362 if (wdesc
== None
) return NULL
;
365 for (tail
= Vframe_list
; CONSP (tail
) && !found
; tail
= XCDR (tail
))
372 if (FRAME_X_P (f
) && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
)
374 /* This frame matches if the window is any of its widgets. */
375 x
= f
->output_data
.x
;
376 if (x
->hourglass_window
== wdesc
)
381 GtkWidget
*gwdesc
= xg_win_to_widget (dpyinfo
->display
, wdesc
);
383 && gtk_widget_get_toplevel (gwdesc
) == x
->widget
)
386 if (wdesc
== XtWindow (x
->widget
)
387 || wdesc
== XtWindow (x
->column_widget
)
388 || wdesc
== XtWindow (x
->edit_widget
))
390 /* Match if the window is this frame's menubar. */
391 else if (lw_window_is_in_menubar (wdesc
, x
->menubar_widget
))
395 else if (FRAME_X_WINDOW (f
) == wdesc
)
396 /* A tooltip frame. */
404 /* Likewise, but consider only the menu bar widget. */
407 x_menubar_window_to_frame (dpyinfo
, event
)
408 struct x_display_info
*dpyinfo
;
411 Window wdesc
= event
->xany
.window
;
412 Lisp_Object tail
, frame
;
416 if (wdesc
== None
) return 0;
418 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
424 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
426 x
= f
->output_data
.x
;
428 if (x
->menubar_widget
&& xg_event_is_for_menubar (f
, event
))
431 /* Match if the window is this frame's menubar. */
432 if (x
->menubar_widget
433 && lw_window_is_in_menubar (wdesc
, x
->menubar_widget
))
440 /* Return the frame whose principal (outermost) window is WDESC.
441 If WDESC is some other (smaller) window, we return 0. */
444 x_top_window_to_frame (dpyinfo
, wdesc
)
445 struct x_display_info
*dpyinfo
;
448 Lisp_Object tail
, frame
;
452 if (wdesc
== None
) return 0;
454 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
460 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
462 x
= f
->output_data
.x
;
466 /* This frame matches if the window is its topmost widget. */
468 GtkWidget
*gwdesc
= xg_win_to_widget (dpyinfo
->display
, wdesc
);
469 if (gwdesc
== x
->widget
)
472 if (wdesc
== XtWindow (x
->widget
))
474 #if 0 /* I don't know why it did this,
475 but it seems logically wrong,
476 and it causes trouble for MapNotify events. */
477 /* Match if the window is this frame's menubar. */
478 if (x
->menubar_widget
479 && wdesc
== XtWindow (x
->menubar_widget
))
484 else if (FRAME_X_WINDOW (f
) == wdesc
)
490 #endif /* USE_X_TOOLKIT || USE_GTK */
494 static void x_default_font_parameter
P_ ((struct frame
*, Lisp_Object
));
496 static Lisp_Object unwind_create_frame
P_ ((Lisp_Object
));
497 static Lisp_Object unwind_create_tip_frame
P_ ((Lisp_Object
));
499 void x_set_foreground_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
500 static void x_set_wait_for_wm
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
501 void x_set_background_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
502 void x_set_mouse_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
503 void x_set_cursor_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
504 void x_set_border_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
505 void x_set_cursor_type
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
506 void x_set_icon_type
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
507 void x_set_icon_name
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
508 void x_explicitly_set_name
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
509 void x_set_menu_bar_lines
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
510 void x_set_title
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
511 void x_set_tool_bar_lines
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
512 void x_set_scroll_bar_foreground
P_ ((struct frame
*, Lisp_Object
,
514 void x_set_scroll_bar_background
P_ ((struct frame
*, Lisp_Object
,
516 static Lisp_Object x_default_scroll_bar_color_parameter
P_ ((struct frame
*,
523 /* Store the screen positions of frame F into XPTR and YPTR.
524 These are the positions of the containing window manager window,
525 not Emacs's own window. */
528 x_real_positions (f
, xptr
, yptr
)
532 int win_x
, win_y
, outer_x
, outer_y
;
533 int real_x
= 0, real_y
= 0;
535 Window win
= f
->output_data
.x
->parent_desc
;
539 x_catch_errors (FRAME_X_DISPLAY (f
));
541 if (win
== FRAME_X_DISPLAY_INFO (f
)->root_window
)
542 win
= FRAME_OUTER_WINDOW (f
);
544 /* This loop traverses up the containment tree until we hit the root
545 window. Window managers may intersect many windows between our window
546 and the root window. The window we find just before the root window
547 should be the outer WM window. */
550 Window wm_window
, rootw
;
551 Window
*tmp_children
;
552 unsigned int tmp_nchildren
;
555 success
= XQueryTree (FRAME_X_DISPLAY (f
), win
, &rootw
,
556 &wm_window
, &tmp_children
, &tmp_nchildren
);
558 had_errors
= x_had_errors_p (FRAME_X_DISPLAY (f
));
560 /* Don't free tmp_children if XQueryTree failed. */
564 XFree ((char *) tmp_children
);
566 if (wm_window
== rootw
|| had_errors
)
577 /* Get the real coordinates for the WM window upper left corner */
578 XGetGeometry (FRAME_X_DISPLAY (f
), win
,
579 &rootw
, &real_x
, &real_y
, &ign
, &ign
, &ign
, &ign
);
581 /* Translate real coordinates to coordinates relative to our
582 window. For our window, the upper left corner is 0, 0.
583 Since the upper left corner of the WM window is outside
584 our window, win_x and win_y will be negative:
586 ------------------ ---> x
588 | ----------------- v y
591 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
593 /* From-window, to-window. */
594 FRAME_X_DISPLAY_INFO (f
)->root_window
,
597 /* From-position, to-position. */
598 real_x
, real_y
, &win_x
, &win_y
,
603 if (FRAME_X_WINDOW (f
) == FRAME_OUTER_WINDOW (f
))
610 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
612 /* From-window, to-window. */
613 FRAME_X_DISPLAY_INFO (f
)->root_window
,
614 FRAME_OUTER_WINDOW (f
),
616 /* From-position, to-position. */
617 real_x
, real_y
, &outer_x
, &outer_y
,
623 had_errors
= x_had_errors_p (FRAME_X_DISPLAY (f
));
630 if (had_errors
) return;
632 f
->x_pixels_diff
= -win_x
;
633 f
->y_pixels_diff
= -win_y
;
635 FRAME_X_OUTPUT (f
)->x_pixels_outer_diff
= -outer_x
;
636 FRAME_X_OUTPUT (f
)->y_pixels_outer_diff
= -outer_y
;
645 /* Gamma-correct COLOR on frame F. */
648 gamma_correct (f
, color
)
654 color
->red
= pow (color
->red
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
655 color
->green
= pow (color
->green
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
656 color
->blue
= pow (color
->blue
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
661 /* Decide if color named COLOR_NAME is valid for use on frame F. If
662 so, return the RGB values in COLOR. If ALLOC_P is non-zero,
663 allocate the color. Value is zero if COLOR_NAME is invalid, or
664 no color could be allocated. */
667 x_defined_color (f
, color_name
, color
, alloc_p
)
674 Display
*dpy
= FRAME_X_DISPLAY (f
);
675 Colormap cmap
= FRAME_X_COLORMAP (f
);
678 success_p
= XParseColor (dpy
, cmap
, color_name
, color
);
679 if (success_p
&& alloc_p
)
680 success_p
= x_alloc_nearest_color (f
, cmap
, color
);
687 /* Return the pixel color value for color COLOR_NAME on frame F. If F
688 is a monochrome frame, return MONO_COLOR regardless of what ARG says.
689 Signal an error if color can't be allocated. */
692 x_decode_color (f
, color_name
, mono_color
)
694 Lisp_Object color_name
;
699 CHECK_STRING (color_name
);
701 #if 0 /* Don't do this. It's wrong when we're not using the default
702 colormap, it makes freeing difficult, and it's probably not
703 an important optimization. */
704 if (strcmp (SDATA (color_name
), "black") == 0)
705 return BLACK_PIX_DEFAULT (f
);
706 else if (strcmp (SDATA (color_name
), "white") == 0)
707 return WHITE_PIX_DEFAULT (f
);
710 /* Return MONO_COLOR for monochrome frames. */
711 if (FRAME_X_DISPLAY_INFO (f
)->n_planes
== 1)
714 /* x_defined_color is responsible for coping with failures
715 by looking for a near-miss. */
716 if (x_defined_color (f
, SDATA (color_name
), &cdef
, 1))
719 signal_error ("Undefined color", color_name
);
724 /* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
725 the previous value of that parameter, NEW_VALUE is the new value.
726 See also the comment of wait_for_wm in struct x_output. */
729 x_set_wait_for_wm (f
, new_value
, old_value
)
731 Lisp_Object new_value
, old_value
;
733 f
->output_data
.x
->wait_for_wm
= !NILP (new_value
);
738 /* Set icon from FILE for frame F. By using GTK functions the icon
739 may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
742 xg_set_icon (f
, file
)
749 found
= x_find_image_file (file
);
755 char *filename
= (char *) SDATA (found
);
758 pixbuf
= gdk_pixbuf_new_from_file (filename
, &err
);
762 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
764 g_object_unref (pixbuf
);
778 xg_set_icon_from_xpm_data (f
, data
)
783 GdkPixbuf
*pixbuf
= gdk_pixbuf_new_from_xpm_data ((const char **) data
);
788 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)), pixbuf
);
789 g_object_unref (pixbuf
);
795 /* Functions called only from `x_set_frame_param'
796 to set individual parameters.
798 If FRAME_X_WINDOW (f) is 0,
799 the frame is being created and its X-window does not exist yet.
800 In that case, just record the parameter's new value
801 in the standard place; do not attempt to change the window. */
804 x_set_foreground_color (f
, arg
, oldval
)
806 Lisp_Object arg
, oldval
;
808 struct x_output
*x
= f
->output_data
.x
;
809 unsigned long fg
, old_fg
;
811 fg
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
812 old_fg
= FRAME_FOREGROUND_PIXEL (f
);
813 FRAME_FOREGROUND_PIXEL (f
) = fg
;
815 if (FRAME_X_WINDOW (f
) != 0)
817 Display
*dpy
= FRAME_X_DISPLAY (f
);
820 XSetForeground (dpy
, x
->normal_gc
, fg
);
821 XSetBackground (dpy
, x
->reverse_gc
, fg
);
823 if (x
->cursor_pixel
== old_fg
)
825 unload_color (f
, x
->cursor_pixel
);
826 x
->cursor_pixel
= x_copy_color (f
, fg
);
827 XSetBackground (dpy
, x
->cursor_gc
, x
->cursor_pixel
);
832 update_face_from_frame_parameter (f
, Qforeground_color
, arg
);
834 if (FRAME_VISIBLE_P (f
))
838 unload_color (f
, old_fg
);
842 x_set_background_color (f
, arg
, oldval
)
844 Lisp_Object arg
, oldval
;
846 struct x_output
*x
= f
->output_data
.x
;
849 bg
= x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
850 unload_color (f
, FRAME_BACKGROUND_PIXEL (f
));
851 FRAME_BACKGROUND_PIXEL (f
) = bg
;
853 if (FRAME_X_WINDOW (f
) != 0)
855 Display
*dpy
= FRAME_X_DISPLAY (f
);
858 XSetBackground (dpy
, x
->normal_gc
, bg
);
859 XSetForeground (dpy
, x
->reverse_gc
, bg
);
860 XSetWindowBackground (dpy
, FRAME_X_WINDOW (f
), bg
);
861 XSetForeground (dpy
, x
->cursor_gc
, bg
);
864 xg_set_background_color (f
, bg
);
867 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
868 toolkit scroll bars. */
871 for (bar
= FRAME_SCROLL_BARS (f
);
873 bar
= XSCROLL_BAR (bar
)->next
)
875 Window window
= XSCROLL_BAR (bar
)->x_window
;
876 XSetWindowBackground (dpy
, window
, bg
);
879 #endif /* USE_TOOLKIT_SCROLL_BARS */
882 update_face_from_frame_parameter (f
, Qbackground_color
, arg
);
884 if (FRAME_VISIBLE_P (f
))
890 make_invisible_cursor (f
)
893 Display
*dpy
= FRAME_X_DISPLAY (f
);
894 static char const no_data
[] = { 0 };
899 x_catch_errors (dpy
);
900 pix
= XCreateBitmapFromData (dpy
, FRAME_X_DISPLAY_INFO (f
)->root_window
,
902 if (! x_had_errors_p (dpy
) && pix
!= None
)
905 col
.red
= col
.green
= col
.blue
= 0;
906 col
.flags
= DoRed
| DoGreen
| DoBlue
;
907 c
= XCreatePixmapCursor (dpy
, pix
, pix
, &col
, &col
, 0, 0);
908 if (x_had_errors_p (dpy
) || c
== None
)
910 XFreePixmap (dpy
, pix
);
919 x_set_mouse_color (f
, arg
, oldval
)
921 Lisp_Object arg
, oldval
;
923 struct x_output
*x
= f
->output_data
.x
;
924 Display
*dpy
= FRAME_X_DISPLAY (f
);
925 Cursor cursor
, nontext_cursor
, mode_cursor
, hand_cursor
;
926 Cursor hourglass_cursor
, horizontal_drag_cursor
;
927 unsigned long pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
928 unsigned long mask_color
= FRAME_BACKGROUND_PIXEL (f
);
930 /* Don't let pointers be invisible. */
931 if (mask_color
== pixel
)
933 x_free_colors (f
, &pixel
, 1);
934 pixel
= x_copy_color (f
, FRAME_FOREGROUND_PIXEL (f
));
937 unload_color (f
, x
->mouse_pixel
);
938 x
->mouse_pixel
= pixel
;
942 /* It's not okay to crash if the user selects a screwy cursor. */
943 x_catch_errors (dpy
);
945 if (!NILP (Vx_pointer_shape
))
947 CHECK_NUMBER (Vx_pointer_shape
);
948 cursor
= XCreateFontCursor (dpy
, XINT (Vx_pointer_shape
));
951 cursor
= XCreateFontCursor (dpy
, XC_xterm
);
952 x_check_errors (dpy
, "bad text pointer cursor: %s");
954 if (!NILP (Vx_nontext_pointer_shape
))
956 CHECK_NUMBER (Vx_nontext_pointer_shape
);
958 = XCreateFontCursor (dpy
, XINT (Vx_nontext_pointer_shape
));
961 nontext_cursor
= XCreateFontCursor (dpy
, XC_left_ptr
);
962 x_check_errors (dpy
, "bad nontext pointer cursor: %s");
964 if (!NILP (Vx_hourglass_pointer_shape
))
966 CHECK_NUMBER (Vx_hourglass_pointer_shape
);
968 = XCreateFontCursor (dpy
, XINT (Vx_hourglass_pointer_shape
));
971 hourglass_cursor
= XCreateFontCursor (dpy
, XC_watch
);
972 x_check_errors (dpy
, "bad hourglass pointer cursor: %s");
974 if (!NILP (Vx_mode_pointer_shape
))
976 CHECK_NUMBER (Vx_mode_pointer_shape
);
977 mode_cursor
= XCreateFontCursor (dpy
, XINT (Vx_mode_pointer_shape
));
980 mode_cursor
= XCreateFontCursor (dpy
, XC_xterm
);
981 x_check_errors (dpy
, "bad modeline pointer cursor: %s");
983 if (!NILP (Vx_sensitive_text_pointer_shape
))
985 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
);
987 = XCreateFontCursor (dpy
, XINT (Vx_sensitive_text_pointer_shape
));
990 hand_cursor
= XCreateFontCursor (dpy
, XC_hand2
);
992 if (!NILP (Vx_window_horizontal_drag_shape
))
994 CHECK_NUMBER (Vx_window_horizontal_drag_shape
);
995 horizontal_drag_cursor
996 = XCreateFontCursor (dpy
, XINT (Vx_window_horizontal_drag_shape
));
999 horizontal_drag_cursor
1000 = XCreateFontCursor (dpy
, XC_sb_h_double_arrow
);
1002 /* Check and report errors with the above calls. */
1003 x_check_errors (dpy
, "can't set cursor shape: %s");
1004 x_uncatch_errors ();
1007 XColor fore_color
, back_color
;
1009 fore_color
.pixel
= x
->mouse_pixel
;
1010 x_query_color (f
, &fore_color
);
1011 back_color
.pixel
= mask_color
;
1012 x_query_color (f
, &back_color
);
1014 XRecolorCursor (dpy
, cursor
, &fore_color
, &back_color
);
1015 XRecolorCursor (dpy
, nontext_cursor
, &fore_color
, &back_color
);
1016 XRecolorCursor (dpy
, mode_cursor
, &fore_color
, &back_color
);
1017 XRecolorCursor (dpy
, hand_cursor
, &fore_color
, &back_color
);
1018 XRecolorCursor (dpy
, hourglass_cursor
, &fore_color
, &back_color
);
1019 XRecolorCursor (dpy
, horizontal_drag_cursor
, &fore_color
, &back_color
);
1022 if (FRAME_X_WINDOW (f
) != 0)
1023 XDefineCursor (dpy
, FRAME_X_WINDOW (f
),
1024 f
->output_data
.x
->current_cursor
= cursor
);
1026 if (FRAME_X_DISPLAY_INFO (f
)->invisible_cursor
== 0)
1027 FRAME_X_DISPLAY_INFO (f
)->invisible_cursor
= make_invisible_cursor (f
);
1029 if (cursor
!= x
->text_cursor
1030 && x
->text_cursor
!= 0)
1031 XFreeCursor (dpy
, x
->text_cursor
);
1032 x
->text_cursor
= cursor
;
1034 if (nontext_cursor
!= x
->nontext_cursor
1035 && x
->nontext_cursor
!= 0)
1036 XFreeCursor (dpy
, x
->nontext_cursor
);
1037 x
->nontext_cursor
= nontext_cursor
;
1039 if (hourglass_cursor
!= x
->hourglass_cursor
1040 && x
->hourglass_cursor
!= 0)
1041 XFreeCursor (dpy
, x
->hourglass_cursor
);
1042 x
->hourglass_cursor
= hourglass_cursor
;
1044 if (mode_cursor
!= x
->modeline_cursor
1045 && x
->modeline_cursor
!= 0)
1046 XFreeCursor (dpy
, f
->output_data
.x
->modeline_cursor
);
1047 x
->modeline_cursor
= mode_cursor
;
1049 if (hand_cursor
!= x
->hand_cursor
1050 && x
->hand_cursor
!= 0)
1051 XFreeCursor (dpy
, x
->hand_cursor
);
1052 x
->hand_cursor
= hand_cursor
;
1054 if (horizontal_drag_cursor
!= x
->horizontal_drag_cursor
1055 && x
->horizontal_drag_cursor
!= 0)
1056 XFreeCursor (dpy
, x
->horizontal_drag_cursor
);
1057 x
->horizontal_drag_cursor
= horizontal_drag_cursor
;
1062 update_face_from_frame_parameter (f
, Qmouse_color
, arg
);
1066 x_set_cursor_color (f
, arg
, oldval
)
1068 Lisp_Object arg
, oldval
;
1070 unsigned long fore_pixel
, pixel
;
1071 int fore_pixel_allocated_p
= 0, pixel_allocated_p
= 0;
1072 struct x_output
*x
= f
->output_data
.x
;
1074 if (!NILP (Vx_cursor_fore_pixel
))
1076 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
1077 WHITE_PIX_DEFAULT (f
));
1078 fore_pixel_allocated_p
= 1;
1081 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
1083 pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1084 pixel_allocated_p
= 1;
1086 /* Make sure that the cursor color differs from the background color. */
1087 if (pixel
== FRAME_BACKGROUND_PIXEL (f
))
1089 if (pixel_allocated_p
)
1091 x_free_colors (f
, &pixel
, 1);
1092 pixel_allocated_p
= 0;
1095 pixel
= x
->mouse_pixel
;
1096 if (pixel
== fore_pixel
)
1098 if (fore_pixel_allocated_p
)
1100 x_free_colors (f
, &fore_pixel
, 1);
1101 fore_pixel_allocated_p
= 0;
1103 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
1107 unload_color (f
, x
->cursor_foreground_pixel
);
1108 if (!fore_pixel_allocated_p
)
1109 fore_pixel
= x_copy_color (f
, fore_pixel
);
1110 x
->cursor_foreground_pixel
= fore_pixel
;
1112 unload_color (f
, x
->cursor_pixel
);
1113 if (!pixel_allocated_p
)
1114 pixel
= x_copy_color (f
, pixel
);
1115 x
->cursor_pixel
= pixel
;
1117 if (FRAME_X_WINDOW (f
) != 0)
1120 XSetBackground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, x
->cursor_pixel
);
1121 XSetForeground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, fore_pixel
);
1124 if (FRAME_VISIBLE_P (f
))
1126 x_update_cursor (f
, 0);
1127 x_update_cursor (f
, 1);
1131 update_face_from_frame_parameter (f
, Qcursor_color
, arg
);
1134 /* Set the border-color of frame F to pixel value PIX.
1135 Note that this does not fully take effect if done before
1136 F has an x-window. */
1139 x_set_border_pixel (f
, pix
)
1143 unload_color (f
, f
->output_data
.x
->border_pixel
);
1144 f
->output_data
.x
->border_pixel
= pix
;
1146 if (FRAME_X_WINDOW (f
) != 0 && f
->border_width
> 0)
1149 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1150 (unsigned long)pix
);
1153 if (FRAME_VISIBLE_P (f
))
1158 /* Set the border-color of frame F to value described by ARG.
1159 ARG can be a string naming a color.
1160 The border-color is used for the border that is drawn by the X server.
1161 Note that this does not fully take effect if done before
1162 F has an x-window; it must be redone when the window is created.
1164 Note: this is done in two routines because of the way X10 works.
1166 Note: under X11, this is normally the province of the window manager,
1167 and so emacs' border colors may be overridden. */
1170 x_set_border_color (f
, arg
, oldval
)
1172 Lisp_Object arg
, oldval
;
1177 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1178 x_set_border_pixel (f
, pix
);
1179 update_face_from_frame_parameter (f
, Qborder_color
, arg
);
1184 x_set_cursor_type (f
, arg
, oldval
)
1186 Lisp_Object arg
, oldval
;
1188 set_frame_cursor_types (f
, arg
);
1190 /* Make sure the cursor gets redrawn. */
1191 cursor_type_changed
= 1;
1195 x_set_icon_type (f
, arg
, oldval
)
1197 Lisp_Object arg
, oldval
;
1203 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1206 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1211 result
= x_text_icon (f
,
1212 (char *) SDATA ((!NILP (f
->icon_name
)
1216 result
= x_bitmap_icon (f
, arg
);
1221 error ("No icon window available");
1224 XFlush (FRAME_X_DISPLAY (f
));
1229 x_set_icon_name (f
, arg
, oldval
)
1231 Lisp_Object arg
, oldval
;
1237 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1240 else if (!NILP (arg
) || NILP (oldval
))
1245 if (f
->output_data
.x
->icon_bitmap
!= 0)
1250 result
= x_text_icon (f
,
1251 (char *) SDATA ((!NILP (f
->icon_name
)
1260 error ("No icon window available");
1263 XFlush (FRAME_X_DISPLAY (f
));
1269 x_set_menu_bar_lines (f
, value
, oldval
)
1271 Lisp_Object value
, oldval
;
1274 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
1275 int olines
= FRAME_MENU_BAR_LINES (f
);
1278 /* Right now, menu bars don't work properly in minibuf-only frames;
1279 most of the commands try to apply themselves to the minibuffer
1280 frame itself, and get an error because you can't switch buffers
1281 in or split the minibuffer window. */
1282 if (FRAME_MINIBUF_ONLY_P (f
))
1285 if (INTEGERP (value
))
1286 nlines
= XINT (value
);
1290 /* Make sure we redisplay all windows in this frame. */
1291 windows_or_buffers_changed
++;
1293 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1294 FRAME_MENU_BAR_LINES (f
) = 0;
1297 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
1298 if (FRAME_X_P (f
) && f
->output_data
.x
->menubar_widget
== 0)
1299 /* Make sure next redisplay shows the menu bar. */
1300 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= Qt
;
1304 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
1305 free_frame_menubar (f
);
1306 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
1308 f
->output_data
.x
->menubar_widget
= 0;
1310 #else /* not USE_X_TOOLKIT && not USE_GTK */
1311 FRAME_MENU_BAR_LINES (f
) = nlines
;
1312 change_window_heights (f
->root_window
, nlines
- olines
);
1314 /* If the menu bar height gets changed, the internal border below
1315 the top margin has to be cleared. Also, if the menu bar gets
1316 larger, the area for the added lines has to be cleared except for
1317 the first menu bar line that is to be drawn later. */
1318 if (nlines
!= olines
)
1320 int height
= FRAME_INTERNAL_BORDER_WIDTH (f
);
1321 int width
= FRAME_PIXEL_WIDTH (f
);
1324 /* height can be zero here. */
1325 if (height
> 0 && width
> 0)
1327 y
= FRAME_TOP_MARGIN_HEIGHT (f
);
1330 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1331 0, y
, width
, height
, False
);
1335 if (nlines
> 1 && nlines
> olines
)
1337 y
= (olines
== 0 ? 1 : olines
) * FRAME_LINE_HEIGHT (f
);
1338 height
= nlines
* FRAME_LINE_HEIGHT (f
) - y
;
1341 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1342 0, y
, width
, height
, False
);
1346 if (nlines
== 0 && WINDOWP (f
->menu_bar_window
))
1347 clear_glyph_matrix (XWINDOW (f
->menu_bar_window
)->current_matrix
);
1349 #endif /* not USE_X_TOOLKIT && not USE_GTK */
1354 /* Set the number of lines used for the tool bar of frame F to VALUE.
1355 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1356 is the old number of tool bar lines. This function changes the
1357 height of all windows on frame F to match the new tool bar height.
1358 The frame's height doesn't change. */
1361 x_set_tool_bar_lines (f
, value
, oldval
)
1363 Lisp_Object value
, oldval
;
1365 int delta
, nlines
, root_height
;
1366 Lisp_Object root_window
;
1368 /* Treat tool bars like menu bars. */
1369 if (FRAME_MINIBUF_ONLY_P (f
))
1372 /* Use VALUE only if an integer >= 0. */
1373 if (INTEGERP (value
) && XINT (value
) >= 0)
1374 nlines
= XFASTINT (value
);
1379 FRAME_TOOL_BAR_LINES (f
) = 0;
1382 FRAME_EXTERNAL_TOOL_BAR (f
) = 1;
1383 if (FRAME_X_P (f
) && f
->output_data
.x
->toolbar_widget
== 0)
1384 /* Make sure next redisplay shows the tool bar. */
1385 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= Qt
;
1386 update_frame_tool_bar (f
);
1390 if (FRAME_EXTERNAL_TOOL_BAR (f
))
1391 free_frame_tool_bar (f
);
1392 FRAME_EXTERNAL_TOOL_BAR (f
) = 0;
1398 /* Make sure we redisplay all windows in this frame. */
1399 ++windows_or_buffers_changed
;
1401 delta
= nlines
- FRAME_TOOL_BAR_LINES (f
);
1403 /* Don't resize the tool-bar to more than we have room for. */
1404 root_window
= FRAME_ROOT_WINDOW (f
);
1405 root_height
= WINDOW_TOTAL_LINES (XWINDOW (root_window
));
1406 if (root_height
- delta
< 1)
1408 delta
= root_height
- 1;
1409 nlines
= FRAME_TOOL_BAR_LINES (f
) + delta
;
1412 FRAME_TOOL_BAR_LINES (f
) = nlines
;
1413 change_window_heights (root_window
, delta
);
1416 /* We also have to make sure that the internal border at the top of
1417 the frame, below the menu bar or tool bar, is redrawn when the
1418 tool bar disappears. This is so because the internal border is
1419 below the tool bar if one is displayed, but is below the menu bar
1420 if there isn't a tool bar. The tool bar draws into the area
1421 below the menu bar. */
1422 if (FRAME_X_WINDOW (f
) && FRAME_TOOL_BAR_LINES (f
) == 0)
1425 clear_current_matrices (f
);
1428 /* If the tool bar gets smaller, the internal border below it
1429 has to be cleared. It was formerly part of the display
1430 of the larger tool bar, and updating windows won't clear it. */
1433 int height
= FRAME_INTERNAL_BORDER_WIDTH (f
);
1434 int width
= FRAME_PIXEL_WIDTH (f
);
1435 int y
= (FRAME_MENU_BAR_LINES (f
) + nlines
) * FRAME_LINE_HEIGHT (f
);
1437 /* height can be zero here. */
1438 if (height
> 0 && width
> 0)
1441 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1442 0, y
, width
, height
, False
);
1446 if (WINDOWP (f
->tool_bar_window
))
1447 clear_glyph_matrix (XWINDOW (f
->tool_bar_window
)->current_matrix
);
1452 /* Set the foreground color for scroll bars on frame F to VALUE.
1453 VALUE should be a string, a color name. If it isn't a string or
1454 isn't a valid color name, do nothing. OLDVAL is the old value of
1455 the frame parameter. */
1458 x_set_scroll_bar_foreground (f
, value
, oldval
)
1460 Lisp_Object value
, oldval
;
1462 unsigned long pixel
;
1464 if (STRINGP (value
))
1465 pixel
= x_decode_color (f
, value
, BLACK_PIX_DEFAULT (f
));
1469 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
1470 unload_color (f
, f
->output_data
.x
->scroll_bar_foreground_pixel
);
1472 f
->output_data
.x
->scroll_bar_foreground_pixel
= pixel
;
1473 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1475 /* Remove all scroll bars because they have wrong colors. */
1476 if (FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
)
1477 (*FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
) (f
);
1478 if (FRAME_TERMINAL (f
)->judge_scroll_bars_hook
)
1479 (*FRAME_TERMINAL (f
)->judge_scroll_bars_hook
) (f
);
1481 update_face_from_frame_parameter (f
, Qscroll_bar_foreground
, value
);
1487 /* Set the background color for scroll bars on frame F to VALUE VALUE
1488 should be a string, a color name. If it isn't a string or isn't a
1489 valid color name, do nothing. OLDVAL is the old value of the frame
1493 x_set_scroll_bar_background (f
, value
, oldval
)
1495 Lisp_Object value
, oldval
;
1497 unsigned long pixel
;
1499 if (STRINGP (value
))
1500 pixel
= x_decode_color (f
, value
, WHITE_PIX_DEFAULT (f
));
1504 if (f
->output_data
.x
->scroll_bar_background_pixel
!= -1)
1505 unload_color (f
, f
->output_data
.x
->scroll_bar_background_pixel
);
1507 #ifdef USE_TOOLKIT_SCROLL_BARS
1508 /* Scrollbar shadow colors. */
1509 if (f
->output_data
.x
->scroll_bar_top_shadow_pixel
!= -1)
1511 unload_color (f
, f
->output_data
.x
->scroll_bar_top_shadow_pixel
);
1512 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
1514 if (f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
!= -1)
1516 unload_color (f
, f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
);
1517 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
1519 #endif /* USE_TOOLKIT_SCROLL_BARS */
1521 f
->output_data
.x
->scroll_bar_background_pixel
= pixel
;
1522 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1524 /* Remove all scroll bars because they have wrong colors. */
1525 if (FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
)
1526 (*FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
) (f
);
1527 if (FRAME_TERMINAL (f
)->judge_scroll_bars_hook
)
1528 (*FRAME_TERMINAL (f
)->judge_scroll_bars_hook
) (f
);
1530 update_face_from_frame_parameter (f
, Qscroll_bar_background
, value
);
1536 /* Encode Lisp string STRING as a text in a format appropriate for
1537 XICCC (X Inter Client Communication Conventions).
1539 This can call Lisp code, so callers must GCPRO.
1541 If STRING contains only ASCII characters, do no conversion and
1542 return the string data of STRING. Otherwise, encode the text by
1543 CODING_SYSTEM, and return a newly allocated memory area which
1544 should be freed by `xfree' by a caller.
1546 SELECTIONP non-zero means the string is being encoded for an X
1547 selection, so it is safe to run pre-write conversions (which
1550 Store the byte length of resulting text in *TEXT_BYTES.
1552 If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
1553 which means that the `encoding' of the result can be `STRING'.
1554 Otherwise store 0 in *STRINGP, which means that the `encoding' of
1555 the result should be `COMPOUND_TEXT'. */
1557 static unsigned char *
1558 x_encode_text (string
, coding_system
, selectionp
, text_bytes
, stringp
, freep
)
1559 Lisp_Object string
, coding_system
;
1560 int *text_bytes
, *stringp
;
1564 int result
= string_xstring_p (string
);
1565 struct coding_system coding
;
1569 /* No multibyte character in OBJ. We need not encode it. */
1570 *text_bytes
= SBYTES (string
);
1573 return SDATA (string
);
1576 setup_coding_system (coding_system
, &coding
);
1577 coding
.mode
|= (CODING_MODE_SAFE_ENCODING
| CODING_MODE_LAST_BLOCK
);
1578 /* We suppress producing escape sequences for composition. */
1579 coding
.common_flags
&= ~CODING_ANNOTATION_MASK
;
1580 coding
.dst_bytes
= SCHARS (string
) * 2;
1581 coding
.destination
= (unsigned char *) xmalloc (coding
.dst_bytes
);
1582 encode_coding_object (&coding
, string
, 0, 0,
1583 SCHARS (string
), SBYTES (string
), Qnil
);
1584 *text_bytes
= coding
.produced
;
1585 *stringp
= (result
== 1 || !EQ (coding_system
, Qcompound_text
));
1587 return coding
.destination
;
1591 /* Set the WM name to NAME for frame F. Also set the icon name.
1592 If the frame already has an icon name, use that, otherwise set the
1593 icon name to NAME. */
1596 x_set_name_internal (f
, name
)
1600 if (FRAME_X_WINDOW (f
))
1604 XTextProperty text
, icon
;
1606 int do_free_icon_value
= 0, do_free_text_value
= 0;
1607 Lisp_Object coding_system
;
1609 Lisp_Object encoded_name
;
1610 struct gcpro gcpro1
;
1612 /* As ENCODE_UTF_8 may cause GC and relocation of string data,
1613 we use it before x_encode_text that may return string data. */
1615 encoded_name
= ENCODE_UTF_8 (name
);
1619 coding_system
= Qcompound_text
;
1620 /* Note: Encoding strategy
1622 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1623 text.encoding. But, there are non-internationalized window
1624 managers which don't support that encoding. So, if NAME
1625 contains only ASCII and 8859-1 characters, encode it by
1626 iso-latin-1, and use "STRING" in text.encoding hoping that
1627 such window managers at least analyze this format correctly,
1628 i.e. treat 8-bit bytes as 8859-1 characters.
1630 We may also be able to use "UTF8_STRING" in text.encoding
1631 in the future which can encode all Unicode characters.
1632 But, for the moment, there's no way to know that the
1633 current window manager supports it or not. */
1634 text
.value
= x_encode_text (name
, coding_system
, 0, &bytes
, &stringp
,
1635 &do_free_text_value
);
1636 text
.encoding
= (stringp
? XA_STRING
1637 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1639 text
.nitems
= bytes
;
1641 if (!STRINGP (f
->icon_name
))
1647 /* See the above comment "Note: Encoding strategy". */
1648 icon
.value
= x_encode_text (f
->icon_name
, coding_system
, 0,
1649 &bytes
, &stringp
, &do_free_icon_value
);
1650 icon
.encoding
= (stringp
? XA_STRING
1651 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1653 icon
.nitems
= bytes
;
1657 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
1658 (char *) SDATA (encoded_name
));
1659 #else /* not USE_GTK */
1660 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &text
);
1661 #endif /* not USE_GTK */
1663 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &icon
);
1665 if (do_free_icon_value
)
1667 if (do_free_text_value
)
1674 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1677 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1678 name; if NAME is a string, set F's name to NAME and set
1679 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1681 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1682 suggesting a new name, which lisp code should override; if
1683 F->explicit_name is set, ignore the new name; otherwise, set it. */
1686 x_set_name (f
, name
, explicit)
1691 /* Make sure that requests from lisp code override requests from
1692 Emacs redisplay code. */
1695 /* If we're switching from explicit to implicit, we had better
1696 update the mode lines and thereby update the title. */
1697 if (f
->explicit_name
&& NILP (name
))
1698 update_mode_lines
= 1;
1700 f
->explicit_name
= ! NILP (name
);
1702 else if (f
->explicit_name
)
1705 /* If NAME is nil, set the name to the x_id_name. */
1708 /* Check for no change needed in this very common case
1709 before we do any consing. */
1710 if (!strcmp (FRAME_X_DISPLAY_INFO (f
)->x_id_name
,
1713 name
= build_string (FRAME_X_DISPLAY_INFO (f
)->x_id_name
);
1716 CHECK_STRING (name
);
1718 /* Don't change the name if it's already NAME. */
1719 if (! NILP (Fstring_equal (name
, f
->name
)))
1724 /* For setting the frame title, the title parameter should override
1725 the name parameter. */
1726 if (! NILP (f
->title
))
1729 x_set_name_internal (f
, name
);
1732 /* This function should be called when the user's lisp code has
1733 specified a name for the frame; the name will override any set by the
1736 x_explicitly_set_name (f
, arg
, oldval
)
1738 Lisp_Object arg
, oldval
;
1740 x_set_name (f
, arg
, 1);
1743 /* This function should be called by Emacs redisplay code to set the
1744 name; names set this way will never override names set by the user's
1747 x_implicitly_set_name (f
, arg
, oldval
)
1749 Lisp_Object arg
, oldval
;
1751 x_set_name (f
, arg
, 0);
1754 /* Change the title of frame F to NAME.
1755 If NAME is nil, use the frame name as the title. */
1758 x_set_title (f
, name
, old_name
)
1760 Lisp_Object name
, old_name
;
1762 /* Don't change the title if it's already NAME. */
1763 if (EQ (name
, f
->title
))
1766 update_mode_lines
= 1;
1773 CHECK_STRING (name
);
1775 x_set_name_internal (f
, name
);
1779 x_set_scroll_bar_default_width (f
)
1782 int wid
= FRAME_COLUMN_WIDTH (f
);
1784 #ifdef USE_TOOLKIT_SCROLL_BARS
1785 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
1786 int width
= 16 + 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
1787 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (width
+ wid
- 1) / wid
;
1788 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = width
;
1790 /* Make the actual width at least 14 pixels and a multiple of a
1792 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
1794 /* Use all of that space (aside from required margins) for the
1796 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = 0;
1801 /* Record in frame F the specified or default value according to ALIST
1802 of the parameter named PROP (a Lisp symbol). If no value is
1803 specified for PROP, look for an X default for XPROP on the frame
1804 named NAME. If that is not found either, use the value DEFLT. */
1807 x_default_scroll_bar_color_parameter (f
, alist
, prop
, xprop
, xclass
,
1816 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
1819 tem
= x_get_arg (dpyinfo
, alist
, prop
, xprop
, xclass
, RES_TYPE_STRING
);
1820 if (EQ (tem
, Qunbound
))
1822 #ifdef USE_TOOLKIT_SCROLL_BARS
1824 /* See if an X resource for the scroll bar color has been
1826 tem
= display_x_get_resource (dpyinfo
,
1827 build_string (foreground_p
1830 empty_unibyte_string
,
1831 build_string ("verticalScrollBar"),
1832 empty_unibyte_string
);
1835 /* If nothing has been specified, scroll bars will use a
1836 toolkit-dependent default. Because these defaults are
1837 difficult to get at without actually creating a scroll
1838 bar, use nil to indicate that no color has been
1843 #else /* not USE_TOOLKIT_SCROLL_BARS */
1847 #endif /* not USE_TOOLKIT_SCROLL_BARS */
1850 x_set_frame_parameters (f
, Fcons (Fcons (prop
, tem
), Qnil
));
1857 #ifdef USE_X_TOOLKIT
1859 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
1860 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
1861 already be present because of the toolkit (Motif adds some of them,
1862 for example, but Xt doesn't). */
1865 hack_wm_protocols (f
, widget
)
1869 Display
*dpy
= XtDisplay (widget
);
1870 Window w
= XtWindow (widget
);
1871 int need_delete
= 1;
1878 unsigned char *catoms
;
1880 unsigned long nitems
= 0;
1881 unsigned long bytes_after
;
1883 if ((XGetWindowProperty (dpy
, w
,
1884 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
1885 (long)0, (long)100, False
, XA_ATOM
,
1886 &type
, &format
, &nitems
, &bytes_after
,
1889 && format
== 32 && type
== XA_ATOM
)
1891 Atom
*atoms
= (Atom
*) catoms
;
1896 == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
)
1898 else if (atoms
[nitems
]
1899 == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
)
1901 else if (atoms
[nitems
]
1902 == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
)
1913 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
1915 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
;
1917 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
1919 XChangeProperty (dpy
, w
, FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
1920 XA_ATOM
, 32, PropModeAppend
,
1921 (unsigned char *) props
, count
);
1929 /* Support routines for XIC (X Input Context). */
1933 static XFontSet xic_create_xfontset
P_ ((struct frame
*));
1934 static XIMStyle best_xim_style
P_ ((XIMStyles
*, XIMStyles
*));
1937 /* Supported XIM styles, ordered by preference. */
1939 static XIMStyle supported_xim_styles
[] =
1941 XIMPreeditPosition
| XIMStatusArea
,
1942 XIMPreeditPosition
| XIMStatusNothing
,
1943 XIMPreeditPosition
| XIMStatusNone
,
1944 XIMPreeditNothing
| XIMStatusArea
,
1945 XIMPreeditNothing
| XIMStatusNothing
,
1946 XIMPreeditNothing
| XIMStatusNone
,
1947 XIMPreeditNone
| XIMStatusArea
,
1948 XIMPreeditNone
| XIMStatusNothing
,
1949 XIMPreeditNone
| XIMStatusNone
,
1954 /* Create an X fontset on frame F with base font name BASE_FONTNAME. */
1956 char xic_defaut_fontset
[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
1958 /* Create an Xt fontset spec from the name of a base font.
1959 If `motif' is True use the Motif syntax. */
1961 xic_create_fontsetname (base_fontname
, motif
)
1962 char *base_fontname
;
1965 const char *sep
= motif
? ";" : ",";
1968 /* Make a fontset name from the base font name. */
1969 if (xic_defaut_fontset
== base_fontname
)
1970 { /* There is no base font name, use the default. */
1971 int len
= strlen (base_fontname
) + 2;
1972 fontsetname
= xmalloc (len
);
1973 bzero (fontsetname
, len
);
1974 strcpy (fontsetname
, base_fontname
);
1978 /* Make a fontset name from the base font name.
1979 The font set will be made of the following elements:
1981 - the base font where the charset spec is replaced by -*-*.
1982 - the same but with the family also replaced with -*-*-. */
1983 char *p
= base_fontname
;
1986 for (i
= 0; *p
; p
++)
1989 { /* As the font name doesn't conform to XLFD, we can't
1990 modify it to generalize it to allcs and allfamilies.
1991 Use the specified font plus the default. */
1992 int len
= strlen (base_fontname
) + strlen (xic_defaut_fontset
) + 3;
1993 fontsetname
= xmalloc (len
);
1994 bzero (fontsetname
, len
);
1995 strcpy (fontsetname
, base_fontname
);
1996 strcat (fontsetname
, sep
);
1997 strcat (fontsetname
, xic_defaut_fontset
);
2002 char *p1
= NULL
, *p2
= NULL
, *p3
= NULL
;
2003 char *font_allcs
= NULL
;
2004 char *font_allfamilies
= NULL
;
2005 char *font_all
= NULL
;
2006 char *allcs
= "*-*-*-*-*-*-*";
2007 char *allfamilies
= "-*-*-";
2008 char *all
= "*-*-*-*-";
2011 for (i
= 0, p
= base_fontname
; i
< 8; p
++)
2024 /* If base_fontname specifies ADSTYLE, make it a
2028 int diff
= (p2
- p3
) - 2;
2030 base
= alloca (strlen (base_fontname
) + 1);
2031 bcopy (base_fontname
, base
, p3
- base_fontname
);
2032 base
[p3
- base_fontname
] = '*';
2033 base
[(p3
- base_fontname
) + 1] = '-';
2034 strcpy (base
+ (p3
- base_fontname
) + 2, p2
);
2035 p
= base
+ (p
- base_fontname
) - diff
;
2036 p1
= base
+ (p1
- base_fontname
);
2037 p2
= base
+ (p2
- base_fontname
) - diff
;
2038 base_fontname
= base
;
2041 /* Build the font spec that matches all charsets. */
2042 len
= p
- base_fontname
+ strlen (allcs
) + 1;
2043 font_allcs
= (char *) alloca (len
);
2044 bzero (font_allcs
, len
);
2045 bcopy (base_fontname
, font_allcs
, p
- base_fontname
);
2046 strcat (font_allcs
, allcs
);
2048 /* Build the font spec that matches all families and
2050 len
= p
- p1
+ strlen (allcs
) + strlen (allfamilies
) + 1;
2051 font_allfamilies
= (char *) alloca (len
);
2052 bzero (font_allfamilies
, len
);
2053 strcpy (font_allfamilies
, allfamilies
);
2054 bcopy (p1
, font_allfamilies
+ strlen (allfamilies
), p
- p1
);
2055 strcat (font_allfamilies
, allcs
);
2057 /* Build the font spec that matches all. */
2058 len
= p
- p2
+ strlen (allcs
) + strlen (all
) + strlen (allfamilies
) + 1;
2059 font_all
= (char *) alloca (len
);
2060 bzero (font_all
, len
);
2061 strcpy (font_all
, allfamilies
);
2062 strcat (font_all
, all
);
2063 bcopy (p2
, font_all
+ strlen (all
) + strlen (allfamilies
), p
- p2
);
2064 strcat (font_all
, allcs
);
2066 /* Build the actual font set name. */
2067 len
= strlen (base_fontname
) + strlen (font_allcs
)
2068 + strlen (font_allfamilies
) + strlen (font_all
) + 5;
2069 fontsetname
= xmalloc (len
);
2070 bzero (fontsetname
, len
);
2071 strcpy (fontsetname
, base_fontname
);
2072 strcat (fontsetname
, sep
);
2073 strcat (fontsetname
, font_allcs
);
2074 strcat (fontsetname
, sep
);
2075 strcat (fontsetname
, font_allfamilies
);
2076 strcat (fontsetname
, sep
);
2077 strcat (fontsetname
, font_all
);
2081 strcat (fontsetname
, ":");
2085 #ifdef DEBUG_XIC_FONTSET
2087 print_fontset_result (xfs
, name
, missing_list
, missing_count
)
2090 char **missing_list
;
2094 fprintf (stderr
, "XIC Fontset created: %s\n", name
);
2097 fprintf (stderr
, "XIC Fontset failed: %s\n", name
);
2098 while (missing_count
-- > 0)
2100 fprintf (stderr
, " missing: %s\n", *missing_list
);
2109 xic_create_xfontset (f
)
2112 XFontSet xfs
= NULL
;
2113 struct font
*font
= FRAME_FONT (f
);
2114 int pixel_size
= font
->pixel_size
;
2115 Lisp_Object rest
, frame
;
2117 /* See if there is another frame already using same fontset. */
2118 FOR_EACH_FRAME (rest
, frame
)
2120 struct frame
*cf
= XFRAME (frame
);
2122 if (cf
!= f
&& FRAME_LIVE_P (f
) && FRAME_X_P (cf
)
2123 && FRAME_X_DISPLAY_INFO (cf
) == FRAME_X_DISPLAY_INFO (f
)
2125 && FRAME_FONT (f
)->pixel_size
== pixel_size
)
2127 xfs
= FRAME_XIC_FONTSET (cf
);
2135 char **missing_list
;
2138 char *xlfd_format
= "-*-*-medium-r-normal--%d-*-*-*-*-*";
2140 sprintf (buf
, xlfd_format
, pixel_size
);
2141 missing_list
= NULL
;
2142 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
), buf
,
2143 &missing_list
, &missing_count
, &def_string
);
2144 #ifdef DEBUG_XIC_FONTSET
2145 print_fontset_result (xfs
, buf
, missing_list
, missing_count
);
2148 XFreeStringList (missing_list
);
2151 /* List of pixel sizes most likely available. Find one that
2152 is closest to pixel_size. */
2153 int sizes
[] = {0, 8, 10, 11, 12, 14, 17, 18, 20, 24, 26, 34, 0};
2154 int *smaller
, *larger
;
2156 for (smaller
= sizes
; smaller
[1]; smaller
++)
2157 if (smaller
[1] >= pixel_size
)
2159 larger
= smaller
+ 1;
2160 if (*larger
== pixel_size
)
2162 while (*smaller
|| *larger
)
2167 this_size
= *smaller
--;
2168 else if (! *smaller
)
2169 this_size
= *larger
++;
2170 else if (pixel_size
- *smaller
< *larger
- pixel_size
)
2171 this_size
= *smaller
--;
2173 this_size
= *larger
++;
2174 sprintf (buf
, xlfd_format
, this_size
);
2175 missing_list
= NULL
;
2176 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
), buf
,
2177 &missing_list
, &missing_count
, &def_string
);
2178 #ifdef DEBUG_XIC_FONTSET
2179 print_fontset_result (xfs
, buf
, missing_list
, missing_count
);
2182 XFreeStringList (missing_list
);
2189 char *last_resort
= "-*-*-*-r-normal--*-*-*-*-*-*";
2191 missing_list
= NULL
;
2192 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
), last_resort
,
2193 &missing_list
, &missing_count
, &def_string
);
2194 #ifdef DEBUG_XIC_FONTSET
2195 print_fontset_result (xfs
, last_resort
, missing_list
, missing_count
);
2198 XFreeStringList (missing_list
);
2206 /* Free the X fontset of frame F if it is the last frame using it. */
2209 xic_free_xfontset (f
)
2212 Lisp_Object rest
, frame
;
2215 if (!FRAME_XIC_FONTSET (f
))
2218 /* See if there is another frame sharing the same fontset. */
2219 FOR_EACH_FRAME (rest
, frame
)
2221 struct frame
*cf
= XFRAME (frame
);
2222 if (cf
!= f
&& FRAME_LIVE_P (f
) && FRAME_X_P (cf
)
2223 && FRAME_X_DISPLAY_INFO (cf
) == FRAME_X_DISPLAY_INFO (f
)
2224 && FRAME_XIC_FONTSET (cf
) == FRAME_XIC_FONTSET (f
))
2232 /* The fontset is not used anymore. It is safe to free it. */
2233 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
2235 if (FRAME_XIC_BASE_FONTNAME (f
))
2236 xfree (FRAME_XIC_BASE_FONTNAME (f
));
2237 FRAME_XIC_BASE_FONTNAME (f
) = NULL
;
2238 FRAME_XIC_FONTSET (f
) = NULL
;
2242 /* Value is the best input style, given user preferences USER (already
2243 checked to be supported by Emacs), and styles supported by the
2244 input method XIM. */
2247 best_xim_style (user
, xim
)
2253 for (i
= 0; i
< user
->count_styles
; ++i
)
2254 for (j
= 0; j
< xim
->count_styles
; ++j
)
2255 if (user
->supported_styles
[i
] == xim
->supported_styles
[j
])
2256 return user
->supported_styles
[i
];
2258 /* Return the default style. */
2259 return XIMPreeditNothing
| XIMStatusNothing
;
2262 /* Create XIC for frame F. */
2264 static XIMStyle xic_style
;
2267 create_frame_xic (f
)
2272 XFontSet xfs
= NULL
;
2277 /* Create X fontset. */
2278 xfs
= xic_create_xfontset (f
);
2279 xim
= FRAME_X_XIM (f
);
2284 XVaNestedList preedit_attr
;
2285 XVaNestedList status_attr
;
2287 s_area
.x
= 0; s_area
.y
= 0; s_area
.width
= 1; s_area
.height
= 1;
2288 spot
.x
= 0; spot
.y
= 1;
2290 /* Determine XIC style. */
2293 XIMStyles supported_list
;
2294 supported_list
.count_styles
= (sizeof supported_xim_styles
2295 / sizeof supported_xim_styles
[0]);
2296 supported_list
.supported_styles
= supported_xim_styles
;
2297 xic_style
= best_xim_style (&supported_list
,
2298 FRAME_X_XIM_STYLES (f
));
2301 preedit_attr
= XVaCreateNestedList (0,
2304 FRAME_FOREGROUND_PIXEL (f
),
2306 FRAME_BACKGROUND_PIXEL (f
),
2307 (xic_style
& XIMPreeditPosition
2312 status_attr
= XVaCreateNestedList (0,
2318 FRAME_FOREGROUND_PIXEL (f
),
2320 FRAME_BACKGROUND_PIXEL (f
),
2323 xic
= XCreateIC (xim
,
2324 XNInputStyle
, xic_style
,
2325 XNClientWindow
, FRAME_X_WINDOW (f
),
2326 XNFocusWindow
, FRAME_X_WINDOW (f
),
2327 XNStatusAttributes
, status_attr
,
2328 XNPreeditAttributes
, preedit_attr
,
2330 XFree (preedit_attr
);
2331 XFree (status_attr
);
2334 FRAME_XIC (f
) = xic
;
2335 FRAME_XIC_STYLE (f
) = xic_style
;
2336 FRAME_XIC_FONTSET (f
) = xfs
;
2340 /* Destroy XIC and free XIC fontset of frame F, if any. */
2346 if (FRAME_XIC (f
) == NULL
)
2349 XDestroyIC (FRAME_XIC (f
));
2350 xic_free_xfontset (f
);
2352 FRAME_XIC (f
) = NULL
;
2356 /* Place preedit area for XIC of window W's frame to specified
2357 pixel position X/Y. X and Y are relative to window W. */
2360 xic_set_preeditarea (w
, x
, y
)
2364 struct frame
*f
= XFRAME (w
->frame
);
2368 spot
.x
= WINDOW_TO_FRAME_PIXEL_X (w
, x
) + WINDOW_LEFT_FRINGE_WIDTH (w
);
2369 spot
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, y
) + FONT_BASE (FRAME_FONT (f
));
2370 attr
= XVaCreateNestedList (0, XNSpotLocation
, &spot
, NULL
);
2371 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2376 /* Place status area for XIC in bottom right corner of frame F.. */
2379 xic_set_statusarea (f
)
2382 XIC xic
= FRAME_XIC (f
);
2387 /* Negotiate geometry of status area. If input method has existing
2388 status area, use its current size. */
2389 area
.x
= area
.y
= area
.width
= area
.height
= 0;
2390 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &area
, NULL
);
2391 XSetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2394 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &needed
, NULL
);
2395 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2398 if (needed
->width
== 0) /* Use XNArea instead of XNAreaNeeded */
2400 attr
= XVaCreateNestedList (0, XNArea
, &needed
, NULL
);
2401 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2405 area
.width
= needed
->width
;
2406 area
.height
= needed
->height
;
2407 area
.x
= FRAME_PIXEL_WIDTH (f
) - area
.width
- FRAME_INTERNAL_BORDER_WIDTH (f
);
2408 area
.y
= (FRAME_PIXEL_HEIGHT (f
) - area
.height
2409 - FRAME_MENUBAR_HEIGHT (f
)
2410 - FRAME_TOOLBAR_HEIGHT (f
)
2411 - FRAME_INTERNAL_BORDER_WIDTH (f
));
2414 attr
= XVaCreateNestedList (0, XNArea
, &area
, NULL
);
2415 XSetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2420 /* Set X fontset for XIC of frame F, using base font name
2421 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2424 xic_set_xfontset (f
, base_fontname
)
2426 char *base_fontname
;
2431 xic_free_xfontset (f
);
2433 xfs
= xic_create_xfontset (f
);
2435 attr
= XVaCreateNestedList (0, XNFontSet
, xfs
, NULL
);
2436 if (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
)
2437 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2438 if (FRAME_XIC_STYLE (f
) & XIMStatusArea
)
2439 XSetICValues (FRAME_XIC (f
), XNStatusAttributes
, attr
, NULL
);
2442 FRAME_XIC_FONTSET (f
) = xfs
;
2445 #endif /* HAVE_X_I18N */
2449 #ifdef USE_X_TOOLKIT
2451 /* Create and set up the X widget for frame F. */
2454 x_window (f
, window_prompting
, minibuffer_only
)
2456 long window_prompting
;
2457 int minibuffer_only
;
2459 XClassHint class_hints
;
2460 XSetWindowAttributes attributes
;
2461 unsigned long attribute_mask
;
2462 Widget shell_widget
;
2464 Widget frame_widget
;
2470 /* Use the resource name as the top-level widget name
2471 for looking up resources. Make a non-Lisp copy
2472 for the window manager, so GC relocation won't bother it.
2474 Elsewhere we specify the window name for the window manager. */
2477 char *str
= (char *) SDATA (Vx_resource_name
);
2478 f
->namebuf
= (char *) xmalloc (strlen (str
) + 1);
2479 strcpy (f
->namebuf
, str
);
2483 XtSetArg (al
[ac
], XtNallowShellResize
, 1); ac
++;
2484 XtSetArg (al
[ac
], XtNinput
, 1); ac
++;
2485 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2486 XtSetArg (al
[ac
], XtNborderWidth
, f
->border_width
); ac
++;
2487 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2488 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2489 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2490 shell_widget
= XtAppCreateShell (f
->namebuf
, EMACS_CLASS
,
2491 applicationShellWidgetClass
,
2492 FRAME_X_DISPLAY (f
), al
, ac
);
2494 f
->output_data
.x
->widget
= shell_widget
;
2495 /* maybe_set_screen_title_format (shell_widget); */
2497 pane_widget
= lw_create_widget ("main", "pane", widget_id_tick
++,
2498 (widget_value
*) NULL
,
2499 shell_widget
, False
,
2503 (lw_callback
) NULL
);
2506 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2507 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2508 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2509 XtSetValues (pane_widget
, al
, ac
);
2510 f
->output_data
.x
->column_widget
= pane_widget
;
2512 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2513 the emacs screen when changing menubar. This reduces flickering. */
2516 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2517 XtSetArg (al
[ac
], XtNshowGrip
, 0); ac
++;
2518 XtSetArg (al
[ac
], XtNallowResize
, 1); ac
++;
2519 XtSetArg (al
[ac
], XtNresizeToPreferred
, 1); ac
++;
2520 XtSetArg (al
[ac
], XtNemacsFrame
, f
); ac
++;
2521 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2522 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2523 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2524 frame_widget
= XtCreateWidget (f
->namebuf
, emacsFrameClass
, pane_widget
,
2527 f
->output_data
.x
->edit_widget
= frame_widget
;
2529 XtManageChild (frame_widget
);
2531 /* Do some needed geometry management. */
2534 char *tem
, shell_position
[32];
2537 int extra_borders
= 0;
2539 = (f
->output_data
.x
->menubar_widget
2540 ? (f
->output_data
.x
->menubar_widget
->core
.height
2541 + f
->output_data
.x
->menubar_widget
->core
.border_width
)
2544 #if 0 /* Experimentally, we now get the right results
2545 for -geometry -0-0 without this. 24 Aug 96, rms. */
2546 if (FRAME_EXTERNAL_MENU_BAR (f
))
2549 XtVaGetValues (pane_widget
, XtNinternalBorderWidth
, &ibw
, NULL
);
2550 menubar_size
+= ibw
;
2554 f
->output_data
.x
->menubar_height
= menubar_size
;
2557 /* Motif seems to need this amount added to the sizes
2558 specified for the shell widget. The Athena/Lucid widgets don't.
2559 Both conclusions reached experimentally. -- rms. */
2560 XtVaGetValues (f
->output_data
.x
->edit_widget
, XtNinternalBorderWidth
,
2561 &extra_borders
, NULL
);
2565 /* Convert our geometry parameters into a geometry string
2567 Note that we do not specify here whether the position
2568 is a user-specified or program-specified one.
2569 We pass that information later, in x_wm_set_size_hints. */
2571 int left
= f
->left_pos
;
2572 int xneg
= window_prompting
& XNegative
;
2573 int top
= f
->top_pos
;
2574 int yneg
= window_prompting
& YNegative
;
2580 if (window_prompting
& USPosition
)
2581 sprintf (shell_position
, "=%dx%d%c%d%c%d",
2582 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2583 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
,
2584 (xneg
? '-' : '+'), left
,
2585 (yneg
? '-' : '+'), top
);
2588 sprintf (shell_position
, "=%dx%d",
2589 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2590 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
);
2592 /* Setting x and y when the position is not specified in
2593 the geometry string will set program position in the WM hints.
2594 If Emacs had just one program position, we could set it in
2595 fallback resources, but since each make-frame call can specify
2596 different program positions, this is easier. */
2597 XtSetArg (al
[ac
], XtNx
, left
); ac
++;
2598 XtSetArg (al
[ac
], XtNy
, top
); ac
++;
2602 len
= strlen (shell_position
) + 1;
2603 /* We don't free this because we don't know whether
2604 it is safe to free it while the frame exists.
2605 It isn't worth the trouble of arranging to free it
2606 when the frame is deleted. */
2607 tem
= (char *) xmalloc (len
);
2608 strncpy (tem
, shell_position
, len
);
2609 XtSetArg (al
[ac
], XtNgeometry
, tem
); ac
++;
2610 XtSetValues (shell_widget
, al
, ac
);
2613 XtManageChild (pane_widget
);
2614 XtRealizeWidget (shell_widget
);
2616 if (FRAME_X_EMBEDDED_P (f
))
2617 XReparentWindow (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
),
2618 f
->output_data
.x
->parent_desc
, 0, 0);
2620 FRAME_X_WINDOW (f
) = XtWindow (frame_widget
);
2622 validate_x_resource_name ();
2624 class_hints
.res_name
= (char *) SDATA (Vx_resource_name
);
2625 class_hints
.res_class
= (char *) SDATA (Vx_resource_class
);
2626 XSetClassHint (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
), &class_hints
);
2629 FRAME_XIC (f
) = NULL
;
2631 create_frame_xic (f
);
2634 f
->output_data
.x
->wm_hints
.input
= True
;
2635 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2636 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2637 &f
->output_data
.x
->wm_hints
);
2639 hack_wm_protocols (f
, shell_widget
);
2642 XtAddEventHandler (shell_widget
, 0, True
, _XEditResCheckMessages
, 0);
2645 /* Do a stupid property change to force the server to generate a
2646 PropertyNotify event so that the event_stream server timestamp will
2647 be initialized to something relevant to the time we created the window.
2649 XChangeProperty (XtDisplay (frame_widget
), XtWindow (frame_widget
),
2650 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2651 XA_ATOM
, 32, PropModeAppend
,
2652 (unsigned char*) NULL
, 0);
2654 /* Make all the standard events reach the Emacs frame. */
2655 attributes
.event_mask
= STANDARD_EVENT_SET
;
2660 /* XIM server might require some X events. */
2661 unsigned long fevent
= NoEventMask
;
2662 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2663 attributes
.event_mask
|= fevent
;
2665 #endif /* HAVE_X_I18N */
2667 attribute_mask
= CWEventMask
;
2668 XChangeWindowAttributes (XtDisplay (shell_widget
), XtWindow (shell_widget
),
2669 attribute_mask
, &attributes
);
2671 XtMapWidget (frame_widget
);
2673 /* x_set_name normally ignores requests to set the name if the
2674 requested name is the same as the current name. This is the one
2675 place where that assumption isn't correct; f->name is set, but
2676 the X server hasn't been told. */
2679 int explicit = f
->explicit_name
;
2681 f
->explicit_name
= 0;
2684 x_set_name (f
, name
, explicit);
2687 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2688 f
->output_data
.x
->current_cursor
2689 = f
->output_data
.x
->text_cursor
);
2693 /* This is a no-op, except under Motif. Make sure main areas are
2694 set to something reasonable, in case we get an error later. */
2695 lw_set_main_areas (pane_widget
, 0, frame_widget
);
2698 #else /* not USE_X_TOOLKIT */
2704 if (! xg_create_frame_widgets (f
))
2705 error ("Unable to create window");
2708 FRAME_XIC (f
) = NULL
;
2712 create_frame_xic (f
);
2715 /* XIM server might require some X events. */
2716 unsigned long fevent
= NoEventMask
;
2717 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2719 if (fevent
!= NoEventMask
)
2721 XSetWindowAttributes attributes
;
2722 XWindowAttributes wattr
;
2723 unsigned long attribute_mask
;
2725 XGetWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2727 attributes
.event_mask
= wattr
.your_event_mask
| fevent
;
2728 attribute_mask
= CWEventMask
;
2729 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2730 attribute_mask
, &attributes
);
2738 #else /*! USE_GTK */
2739 /* Create and set up the X window for frame F. */
2746 XClassHint class_hints
;
2747 XSetWindowAttributes attributes
;
2748 unsigned long attribute_mask
;
2750 attributes
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
2751 attributes
.border_pixel
= f
->output_data
.x
->border_pixel
;
2752 attributes
.bit_gravity
= StaticGravity
;
2753 attributes
.backing_store
= NotUseful
;
2754 attributes
.save_under
= True
;
2755 attributes
.event_mask
= STANDARD_EVENT_SET
;
2756 attributes
.colormap
= FRAME_X_COLORMAP (f
);
2757 attribute_mask
= (CWBackPixel
| CWBorderPixel
| CWBitGravity
| CWEventMask
2762 = XCreateWindow (FRAME_X_DISPLAY (f
),
2763 f
->output_data
.x
->parent_desc
,
2766 FRAME_PIXEL_WIDTH (f
), FRAME_PIXEL_HEIGHT (f
),
2768 CopyFromParent
, /* depth */
2769 InputOutput
, /* class */
2771 attribute_mask
, &attributes
);
2776 create_frame_xic (f
);
2779 /* XIM server might require some X events. */
2780 unsigned long fevent
= NoEventMask
;
2781 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2782 attributes
.event_mask
|= fevent
;
2783 attribute_mask
= CWEventMask
;
2784 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2785 attribute_mask
, &attributes
);
2788 #endif /* HAVE_X_I18N */
2790 validate_x_resource_name ();
2792 class_hints
.res_name
= (char *) SDATA (Vx_resource_name
);
2793 class_hints
.res_class
= (char *) SDATA (Vx_resource_class
);
2794 XSetClassHint (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &class_hints
);
2796 /* The menubar is part of the ordinary display;
2797 it does not count in addition to the height of the window. */
2798 f
->output_data
.x
->menubar_height
= 0;
2800 /* This indicates that we use the "Passive Input" input model.
2801 Unless we do this, we don't get the Focus{In,Out} events that we
2802 need to draw the cursor correctly. Accursed bureaucrats.
2803 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2805 f
->output_data
.x
->wm_hints
.input
= True
;
2806 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2807 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2808 &f
->output_data
.x
->wm_hints
);
2809 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
2811 /* Request "save yourself" and "delete window" commands from wm. */
2814 protocols
[0] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2815 protocols
[1] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2816 XSetWMProtocols (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), protocols
, 2);
2819 /* x_set_name normally ignores requests to set the name if the
2820 requested name is the same as the current name. This is the one
2821 place where that assumption isn't correct; f->name is set, but
2822 the X server hasn't been told. */
2825 int explicit = f
->explicit_name
;
2827 f
->explicit_name
= 0;
2830 x_set_name (f
, name
, explicit);
2833 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2834 f
->output_data
.x
->current_cursor
2835 = f
->output_data
.x
->text_cursor
);
2839 if (FRAME_X_WINDOW (f
) == 0)
2840 error ("Unable to create window");
2843 #endif /* not USE_GTK */
2844 #endif /* not USE_X_TOOLKIT */
2846 /* Verify that the icon position args for this window are valid. */
2849 x_icon_verify (f
, parms
)
2853 Lisp_Object icon_x
, icon_y
;
2855 /* Set the position of the icon. Note that twm groups all
2856 icons in an icon window. */
2857 icon_x
= x_frame_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
2858 icon_y
= x_frame_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
2859 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2861 CHECK_NUMBER (icon_x
);
2862 CHECK_NUMBER (icon_y
);
2864 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2865 error ("Both left and top icon corners of icon must be specified");
2868 /* Handle the icon stuff for this window. Perhaps later we might
2869 want an x_set_icon_position which can be called interactively as
2877 Lisp_Object icon_x
, icon_y
;
2879 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
2882 /* Set the position of the icon. Note that twm groups all
2883 icons in an icon window. */
2884 icon_x
= x_frame_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
2885 icon_y
= x_frame_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
2886 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2888 CHECK_NUMBER (icon_x
);
2889 CHECK_NUMBER (icon_y
);
2891 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2892 error ("Both left and top icon corners of icon must be specified");
2896 if (! EQ (icon_x
, Qunbound
))
2897 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
2899 #if 0 /* x_get_arg removes the visibility parameter as a side effect,
2900 but x_create_frame still needs it. */
2901 /* Start up iconic or window? */
2902 x_wm_set_window_state
2903 (f
, (EQ (x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
),
2909 x_text_icon (f
, (char *) SDATA ((!NILP (f
->icon_name
)
2916 /* Make the GCs needed for this window, setting the
2917 background, border and mouse colors; also create the
2918 mouse cursor and the gray border tile. */
2924 XGCValues gc_values
;
2928 /* Create the GCs of this frame.
2929 Note that many default values are used. */
2931 gc_values
.foreground
= FRAME_FOREGROUND_PIXEL (f
);
2932 gc_values
.background
= FRAME_BACKGROUND_PIXEL (f
);
2933 gc_values
.line_width
= 0; /* Means 1 using fast algorithm. */
2934 f
->output_data
.x
->normal_gc
2935 = XCreateGC (FRAME_X_DISPLAY (f
),
2937 GCLineWidth
| GCForeground
| GCBackground
,
2940 /* Reverse video style. */
2941 gc_values
.foreground
= FRAME_BACKGROUND_PIXEL (f
);
2942 gc_values
.background
= FRAME_FOREGROUND_PIXEL (f
);
2943 f
->output_data
.x
->reverse_gc
2944 = XCreateGC (FRAME_X_DISPLAY (f
),
2946 GCForeground
| GCBackground
| GCLineWidth
,
2949 /* Cursor has cursor-color background, background-color foreground. */
2950 gc_values
.foreground
= FRAME_BACKGROUND_PIXEL (f
);
2951 gc_values
.background
= f
->output_data
.x
->cursor_pixel
;
2952 gc_values
.fill_style
= FillOpaqueStippled
;
2953 f
->output_data
.x
->cursor_gc
2954 = XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2955 (GCForeground
| GCBackground
2956 | GCFillStyle
| GCLineWidth
),
2960 f
->output_data
.x
->white_relief
.gc
= 0;
2961 f
->output_data
.x
->black_relief
.gc
= 0;
2963 /* Create the gray border tile used when the pointer is not in
2964 the frame. Since this depends on the frame's pixel values,
2965 this must be done on a per-frame basis. */
2966 f
->output_data
.x
->border_tile
2967 = (XCreatePixmapFromBitmapData
2968 (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
2969 gray_bits
, gray_width
, gray_height
,
2970 FRAME_FOREGROUND_PIXEL (f
),
2971 FRAME_BACKGROUND_PIXEL (f
),
2972 DefaultDepth (FRAME_X_DISPLAY (f
), FRAME_X_SCREEN_NUMBER (f
))));
2978 /* Free what was allocated in x_make_gc. */
2984 Display
*dpy
= FRAME_X_DISPLAY (f
);
2988 if (f
->output_data
.x
->normal_gc
)
2990 XFreeGC (dpy
, f
->output_data
.x
->normal_gc
);
2991 f
->output_data
.x
->normal_gc
= 0;
2994 if (f
->output_data
.x
->reverse_gc
)
2996 XFreeGC (dpy
, f
->output_data
.x
->reverse_gc
);
2997 f
->output_data
.x
->reverse_gc
= 0;
3000 if (f
->output_data
.x
->cursor_gc
)
3002 XFreeGC (dpy
, f
->output_data
.x
->cursor_gc
);
3003 f
->output_data
.x
->cursor_gc
= 0;
3006 if (f
->output_data
.x
->border_tile
)
3008 XFreePixmap (dpy
, f
->output_data
.x
->border_tile
);
3009 f
->output_data
.x
->border_tile
= 0;
3016 /* Handler for signals raised during x_create_frame and
3017 x_create_top_frame. FRAME is the frame which is partially
3021 unwind_create_frame (frame
)
3024 struct frame
*f
= XFRAME (frame
);
3026 /* If frame is already dead, nothing to do. This can happen if the
3027 display is disconnected after the frame has become official, but
3028 before x_create_frame removes the unwind protect. */
3029 if (!FRAME_LIVE_P (f
))
3032 /* If frame is ``official'', nothing to do. */
3033 if (!CONSP (Vframe_list
) || !EQ (XCAR (Vframe_list
), frame
))
3036 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3039 x_free_frame_resources (f
);
3042 /* Check that reference counts are indeed correct. */
3043 xassert (dpyinfo
->reference_count
== dpyinfo_refcount
);
3044 xassert (dpyinfo
->image_cache
->refcount
== image_cache_refcount
);
3054 x_default_font_parameter (f
, parms
)
3058 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3059 Lisp_Object font_param
= x_get_arg (dpyinfo
, parms
, Qfont
, NULL
, NULL
,
3062 int got_from_gconf
= 0;
3063 if (EQ (font_param
, Qunbound
))
3066 if (NILP (font_param
))
3068 /* System font takes precedendce over X resources. We must suggest this
3069 regardless of font-use-system-font because .emacs may not have been
3071 const char *system_font
= xsettings_get_system_font ();
3072 if (system_font
) font_param
= make_string (system_font
,
3073 strlen (system_font
));
3076 font
= !NILP (font_param
) ? font_param
3077 : x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
3079 if (! STRINGP (font
))
3084 /* This will find the normal Xft font. */
3087 "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
3088 "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3089 "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3090 /* This was formerly the first thing tried, but it finds
3091 too many fonts and takes too long. */
3092 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
3093 /* If those didn't work, look for something which will
3095 "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
3100 for (i
= 0; names
[i
]; i
++)
3102 font
= font_open_by_name (f
, names
[i
]);
3107 error ("No suitable font was found");
3109 else if (!NILP (font_param
))
3111 /* Remember the explicit font parameter, so we can re-apply it after
3112 we've applied the `default' face settings. */
3113 x_set_frame_parameters (f
, Fcons (Fcons (Qfont_param
, font_param
), Qnil
));
3116 x_default_parameter (f
, parms
, Qfont
, font
,
3117 got_from_gconf
? NULL
: "font",
3118 got_from_gconf
? NULL
: "Font",
3123 DEFUN ("x-wm-set-size-hint", Fx_wm_set_size_hint
, Sx_wm_set_size_hint
,
3125 doc
: /* Send the size hints for frame FRAME to the window manager.
3126 If FRAME is nil, use the selected frame. */)
3132 frame
= selected_frame
;
3136 x_wm_set_size_hint (f
, 0, 0);
3141 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
3143 doc
: /* Make a new X window, which is called a "frame" in Emacs terms.
3144 Return an Emacs frame object.
3145 PARMS is an alist of frame parameters.
3146 If the parameters specify that the frame should not have a minibuffer,
3147 and do not specify a specific minibuffer window to use,
3148 then `default-minibuffer-frame' must be a frame whose minibuffer can
3149 be shared by the new frame.
3151 This function is an internal primitive--use `make-frame' instead. */)
3156 Lisp_Object frame
, tem
;
3158 int minibuffer_only
= 0;
3159 long window_prompting
= 0;
3161 int count
= SPECPDL_INDEX ();
3162 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
3163 Lisp_Object display
;
3164 struct x_display_info
*dpyinfo
= NULL
;
3168 parms
= Fcopy_alist (parms
);
3170 /* Use this general default value to start with
3171 until we know if this frame has a specified name. */
3172 Vx_resource_name
= Vinvocation_name
;
3174 display
= x_get_arg (dpyinfo
, parms
, Qterminal
, 0, 0, RES_TYPE_NUMBER
);
3175 if (EQ (display
, Qunbound
))
3176 display
= x_get_arg (dpyinfo
, parms
, Qdisplay
, 0, 0, RES_TYPE_STRING
);
3177 if (EQ (display
, Qunbound
))
3179 dpyinfo
= check_x_display_info (display
);
3180 kb
= dpyinfo
->terminal
->kboard
;
3182 if (!dpyinfo
->terminal
->name
)
3183 error ("Terminal is not live, can't create new frames on it");
3185 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
3187 && ! EQ (name
, Qunbound
)
3189 error ("Invalid frame name--not a string or nil");
3192 Vx_resource_name
= name
;
3194 /* See if parent window is specified. */
3195 parent
= x_get_arg (dpyinfo
, parms
, Qparent_id
, NULL
, NULL
, RES_TYPE_NUMBER
);
3196 if (EQ (parent
, Qunbound
))
3198 if (! NILP (parent
))
3199 CHECK_NUMBER (parent
);
3201 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
3202 /* No need to protect DISPLAY because that's not used after passing
3203 it to make_frame_without_minibuffer. */
3205 GCPRO4 (parms
, parent
, name
, frame
);
3206 tem
= x_get_arg (dpyinfo
, parms
, Qminibuffer
, "minibuffer", "Minibuffer",
3208 if (EQ (tem
, Qnone
) || NILP (tem
))
3209 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
3210 else if (EQ (tem
, Qonly
))
3212 f
= make_minibuffer_frame ();
3213 minibuffer_only
= 1;
3215 else if (WINDOWP (tem
))
3216 f
= make_frame_without_minibuffer (tem
, kb
, display
);
3220 XSETFRAME (frame
, f
);
3222 /* Note that X Windows does support scroll bars. */
3223 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
3225 f
->terminal
= dpyinfo
->terminal
;
3226 f
->terminal
->reference_count
++;
3228 f
->output_method
= output_x_window
;
3229 f
->output_data
.x
= (struct x_output
*) xmalloc (sizeof (struct x_output
));
3230 bzero (f
->output_data
.x
, sizeof (struct x_output
));
3231 f
->output_data
.x
->icon_bitmap
= -1;
3232 FRAME_FONTSET (f
) = -1;
3233 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
3234 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
3235 #ifdef USE_TOOLKIT_SCROLL_BARS
3236 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
3237 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
3238 #endif /* USE_TOOLKIT_SCROLL_BARS */
3241 = x_get_arg (dpyinfo
, parms
, Qicon_name
, "iconName", "Title",
3243 if (! STRINGP (f
->icon_name
))
3244 f
->icon_name
= Qnil
;
3246 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
3248 /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe. */
3249 record_unwind_protect (unwind_create_frame
, frame
);
3251 image_cache_refcount
= FRAME_IMAGE_CACHE (f
)->refcount
;
3252 dpyinfo_refcount
= dpyinfo
->reference_count
;
3253 #endif /* GLYPH_DEBUG */
3255 /* These colors will be set anyway later, but it's important
3256 to get the color reference counts right, so initialize them! */
3259 struct gcpro gcpro1
;
3261 /* Function x_decode_color can signal an error. Make
3262 sure to initialize color slots so that we won't try
3263 to free colors we haven't allocated. */
3264 FRAME_FOREGROUND_PIXEL (f
) = -1;
3265 FRAME_BACKGROUND_PIXEL (f
) = -1;
3266 f
->output_data
.x
->cursor_pixel
= -1;
3267 f
->output_data
.x
->cursor_foreground_pixel
= -1;
3268 f
->output_data
.x
->border_pixel
= -1;
3269 f
->output_data
.x
->mouse_pixel
= -1;
3271 black
= build_string ("black");
3273 FRAME_FOREGROUND_PIXEL (f
)
3274 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3275 FRAME_BACKGROUND_PIXEL (f
)
3276 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3277 f
->output_data
.x
->cursor_pixel
3278 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3279 f
->output_data
.x
->cursor_foreground_pixel
3280 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3281 f
->output_data
.x
->border_pixel
3282 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3283 f
->output_data
.x
->mouse_pixel
3284 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3288 /* Specify the parent under which to make this X window. */
3292 f
->output_data
.x
->parent_desc
= (Window
) XFASTINT (parent
);
3293 f
->output_data
.x
->explicit_parent
= 1;
3297 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3298 f
->output_data
.x
->explicit_parent
= 0;
3301 /* Set the name; the functions to which we pass f expect the name to
3303 if (EQ (name
, Qunbound
) || NILP (name
))
3305 f
->name
= build_string (dpyinfo
->x_id_name
);
3306 f
->explicit_name
= 0;
3311 f
->explicit_name
= 1;
3312 /* use the frame's title when getting resources for this frame. */
3313 specbind (Qx_resource_name
, name
);
3316 f
->resx
= dpyinfo
->resx
;
3317 f
->resy
= dpyinfo
->resy
;
3319 #ifdef HAVE_FREETYPE
3321 register_font_driver (&xftfont_driver
, f
);
3322 #else /* not HAVE_XFT */
3323 register_font_driver (&ftxfont_driver
, f
);
3324 #endif /* not HAVE_XFT */
3325 #endif /* HAVE_FREETYPE */
3326 register_font_driver (&xfont_driver
, f
);
3328 x_default_parameter (f
, parms
, Qfont_backend
, Qnil
,
3329 "fontBackend", "FontBackend", RES_TYPE_STRING
);
3331 /* Extract the window parameters from the supplied values
3332 that are needed to determine window geometry. */
3333 x_default_font_parameter (f
, parms
);
3334 if (!FRAME_FONT (f
))
3336 delete_frame (frame
, Qnoelisp
);
3337 error ("Invalid frame font");
3341 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
3342 whereby it fails to get any font. */
3344 xlwmenu_default_font
= XLoadQueryFont (FRAME_X_DISPLAY (f
), "fixed");
3348 /* Frame contents get displaced if an embedded X window has a border. */
3349 if (! FRAME_X_EMBEDDED_P (f
))
3350 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
3351 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
3353 /* This defaults to 1 in order to match xterm. We recognize either
3354 internalBorderWidth or internalBorder (which is what xterm calls
3356 if (NILP (Fassq (Qinternal_border_width
, parms
)))
3360 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
3361 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
3362 if (! EQ (value
, Qunbound
))
3363 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
3366 x_default_parameter (f
, parms
, Qinternal_border_width
,
3367 #ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */
3372 "internalBorderWidth", "internalBorderWidth",
3374 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qleft
,
3375 "verticalScrollBars", "ScrollBars",
3378 /* Also do the stuff which must be set before the window exists. */
3379 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
3380 "foreground", "Foreground", RES_TYPE_STRING
);
3381 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
3382 "background", "Background", RES_TYPE_STRING
);
3383 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
3384 "pointerColor", "Foreground", RES_TYPE_STRING
);
3385 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
3386 "cursorColor", "Foreground", RES_TYPE_STRING
);
3387 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
3388 "borderColor", "BorderColor", RES_TYPE_STRING
);
3389 x_default_parameter (f
, parms
, Qscreen_gamma
, Qnil
,
3390 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT
);
3391 x_default_parameter (f
, parms
, Qline_spacing
, Qnil
,
3392 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER
);
3393 x_default_parameter (f
, parms
, Qleft_fringe
, Qnil
,
3394 "leftFringe", "LeftFringe", RES_TYPE_NUMBER
);
3395 x_default_parameter (f
, parms
, Qright_fringe
, Qnil
,
3396 "rightFringe", "RightFringe", RES_TYPE_NUMBER
);
3398 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_foreground
,
3399 "scrollBarForeground",
3400 "ScrollBarForeground", 1);
3401 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_background
,
3402 "scrollBarBackground",
3403 "ScrollBarBackground", 0);
3405 /* Init faces before x_default_parameter is called for scroll-bar
3406 parameters because that function calls x_set_scroll_bar_width,
3407 which calls change_frame_size, which calls Fset_window_buffer,
3408 which runs hooks, which call Fvertical_motion. At the end, we
3409 end up in init_iterator with a null face cache, which should not
3411 init_frame_faces (f
);
3413 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
3414 "menuBar", "MenuBar", RES_TYPE_BOOLEAN_NUMBER
);
3415 x_default_parameter (f
, parms
, Qtool_bar_lines
, make_number (1),
3416 "toolBar", "ToolBar", RES_TYPE_NUMBER
);
3417 x_default_parameter (f
, parms
, Qbuffer_predicate
, Qnil
,
3418 "bufferPredicate", "BufferPredicate",
3420 x_default_parameter (f
, parms
, Qtitle
, Qnil
,
3421 "title", "Title", RES_TYPE_STRING
);
3422 x_default_parameter (f
, parms
, Qwait_for_wm
, Qt
,
3423 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN
);
3424 x_default_parameter (f
, parms
, Qfullscreen
, Qnil
,
3425 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL
);
3427 /* Compute the size of the X window. */
3428 window_prompting
= x_figure_window_size (f
, parms
, 1);
3430 tem
= x_get_arg (dpyinfo
, parms
, Qunsplittable
, 0, 0, RES_TYPE_BOOLEAN
);
3431 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
3433 x_icon_verify (f
, parms
);
3435 /* Create the X widget or window. */
3436 #ifdef USE_X_TOOLKIT
3437 x_window (f
, window_prompting
, minibuffer_only
);
3445 /* Now consider the frame official. */
3446 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
3447 Vframe_list
= Fcons (frame
, Vframe_list
);
3449 /* We need to do this after creating the X window, so that the
3450 icon-creation functions can say whose icon they're describing. */
3451 x_default_parameter (f
, parms
, Qicon_type
, Qt
,
3452 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL
);
3454 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
3455 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3456 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
3457 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3458 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
3459 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
3460 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
3461 "scrollBarWidth", "ScrollBarWidth",
3463 x_default_parameter (f
, parms
, Qalpha
, Qnil
,
3464 "alpha", "Alpha", RES_TYPE_NUMBER
);
3466 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3467 Change will not be effected unless different from the current
3469 width
= FRAME_COLS (f
);
3470 height
= FRAME_LINES (f
);
3472 SET_FRAME_COLS (f
, 0);
3473 FRAME_LINES (f
) = 0;
3474 change_frame_size (f
, height
, width
, 1, 0, 0);
3476 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3477 /* Create the menu bar. */
3478 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
3480 /* If this signals an error, we haven't set size hints for the
3481 frame and we didn't make it visible. */
3482 initialize_frame_menubar (f
);
3485 /* This is a no-op, except under Motif where it arranges the
3486 main window for the widgets on it. */
3487 lw_set_main_areas (f
->output_data
.x
->column_widget
,
3488 f
->output_data
.x
->menubar_widget
,
3489 f
->output_data
.x
->edit_widget
);
3490 #endif /* not USE_GTK */
3492 #endif /* USE_X_TOOLKIT || USE_GTK */
3494 /* Tell the server what size and position, etc, we want, and how
3495 badly we want them. This should be done after we have the menu
3496 bar so that its size can be taken into account. */
3498 x_wm_set_size_hint (f
, window_prompting
, 0);
3501 /* Make the window appear on the frame and enable display, unless
3502 the caller says not to. However, with explicit parent, Emacs
3503 cannot control visibility, so don't try. */
3504 if (! f
->output_data
.x
->explicit_parent
)
3506 Lisp_Object visibility
;
3508 visibility
= x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0,
3510 if (EQ (visibility
, Qunbound
))
3513 if (EQ (visibility
, Qicon
))
3514 x_iconify_frame (f
);
3515 else if (! NILP (visibility
))
3516 x_make_frame_visible (f
);
3518 /* Must have been Qnil. */
3522 /* Set the WM leader property. GTK does this itself, so this is not
3523 needed when using GTK. */
3524 if (dpyinfo
->client_leader_window
!= 0)
3527 XChangeProperty (FRAME_X_DISPLAY (f
),
3528 FRAME_OUTER_WINDOW (f
),
3529 dpyinfo
->Xatom_wm_client_leader
,
3530 XA_WINDOW
, 32, PropModeReplace
,
3531 (unsigned char *) &dpyinfo
->client_leader_window
, 1);
3535 /* Initialize `default-minibuffer-frame' in case this is the first
3536 frame on this terminal. */
3537 if (FRAME_HAS_MINIBUF_P (f
)
3538 && (!FRAMEP (kb
->Vdefault_minibuffer_frame
)
3539 || !FRAME_LIVE_P (XFRAME (kb
->Vdefault_minibuffer_frame
))))
3540 kb
->Vdefault_minibuffer_frame
= frame
;
3542 /* All remaining specified parameters, which have not been "used"
3543 by x_get_arg and friends, now go in the misc. alist of the frame. */
3544 for (tem
= parms
; CONSP (tem
); tem
= XCDR (tem
))
3545 if (CONSP (XCAR (tem
)) && !NILP (XCAR (XCAR (tem
))))
3546 f
->param_alist
= Fcons (XCAR (tem
), f
->param_alist
);
3550 /* Make sure windows on this frame appear in calls to next-window
3551 and similar functions. */
3552 Vwindow_list
= Qnil
;
3554 return unbind_to (count
, frame
);
3558 /* FRAME is used only to get a handle on the X display. We don't pass the
3559 display info directly because we're called from frame.c, which doesn't
3560 know about that structure. */
3563 x_get_focus_frame (frame
)
3564 struct frame
*frame
;
3566 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (frame
);
3568 if (! dpyinfo
->x_focus_frame
)
3571 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
3576 /* In certain situations, when the window manager follows a
3577 click-to-focus policy, there seems to be no way around calling
3578 XSetInputFocus to give another frame the input focus .
3580 In an ideal world, XSetInputFocus should generally be avoided so
3581 that applications don't interfere with the window manager's focus
3582 policy. But I think it's okay to use when it's clearly done
3583 following a user-command. */
3585 DEFUN ("x-focus-frame", Fx_focus_frame
, Sx_focus_frame
, 1, 1, 0,
3586 doc
: /* Set the input focus to FRAME.
3587 FRAME nil means use the selected frame. */)
3591 struct frame
*f
= check_x_frame (frame
);
3592 Display
*dpy
= FRAME_X_DISPLAY (f
);
3595 x_catch_errors (dpy
);
3596 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3597 RevertToParent
, CurrentTime
);
3598 x_ewmh_activate_frame (f
);
3599 x_uncatch_errors ();
3606 DEFUN ("xw-color-defined-p", Fxw_color_defined_p
, Sxw_color_defined_p
, 1, 2, 0,
3607 doc
: /* Internal function called by `color-defined-p', which see. */)
3609 Lisp_Object color
, frame
;
3612 FRAME_PTR f
= check_x_frame (frame
);
3614 CHECK_STRING (color
);
3616 if (x_defined_color (f
, SDATA (color
), &foo
, 0))
3622 DEFUN ("xw-color-values", Fxw_color_values
, Sxw_color_values
, 1, 2, 0,
3623 doc
: /* Internal function called by `color-values', which see. */)
3625 Lisp_Object color
, frame
;
3628 FRAME_PTR f
= check_x_frame (frame
);
3630 CHECK_STRING (color
);
3632 if (x_defined_color (f
, SDATA (color
), &foo
, 0))
3633 return list3 (make_number (foo
.red
),
3634 make_number (foo
.green
),
3635 make_number (foo
.blue
));
3640 DEFUN ("xw-display-color-p", Fxw_display_color_p
, Sxw_display_color_p
, 0, 1, 0,
3641 doc
: /* Internal function called by `display-color-p', which see. */)
3643 Lisp_Object terminal
;
3645 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3647 if (dpyinfo
->n_planes
<= 2)
3650 switch (dpyinfo
->visual
->class)
3663 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
3665 doc
: /* Return t if the X display supports shades of gray.
3666 Note that color displays do support shades of gray.
3667 The optional argument TERMINAL specifies which display to ask about.
3668 TERMINAL should be a terminal object, a frame or a display name (a string).
3669 If omitted or nil, that stands for the selected frame's display. */)
3671 Lisp_Object terminal
;
3673 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3675 if (dpyinfo
->n_planes
<= 1)
3678 switch (dpyinfo
->visual
->class)
3693 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
3695 doc
: /* Return the width in pixels of the X display TERMINAL.
3696 The optional argument TERMINAL specifies which display to ask about.
3697 TERMINAL should be a terminal object, a frame or a display name (a string).
3698 If omitted or nil, that stands for the selected frame's display. */)
3700 Lisp_Object terminal
;
3702 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3704 return make_number (x_display_pixel_width (dpyinfo
));
3707 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
3708 Sx_display_pixel_height
, 0, 1, 0,
3709 doc
: /* Return the height in pixels of the X display TERMINAL.
3710 The optional argument TERMINAL specifies which display to ask about.
3711 TERMINAL should be a terminal object, a frame or a display name (a string).
3712 If omitted or nil, that stands for the selected frame's display. */)
3714 Lisp_Object terminal
;
3716 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3718 return make_number (x_display_pixel_height (dpyinfo
));
3721 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
3723 doc
: /* Return the number of bitplanes of the X display TERMINAL.
3724 The optional argument TERMINAL specifies which display to ask about.
3725 TERMINAL should be a terminal object, a frame or a display name (a string).
3726 If omitted or nil, that stands for the selected frame's display. */)
3728 Lisp_Object terminal
;
3730 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3732 return make_number (dpyinfo
->n_planes
);
3735 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
3737 doc
: /* Return the number of color cells of the X display TERMINAL.
3738 The optional argument TERMINAL specifies which display to ask about.
3739 TERMINAL should be a terminal object, a frame or a display name (a string).
3740 If omitted or nil, that stands for the selected frame's display. */)
3742 Lisp_Object terminal
;
3744 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3746 int nr_planes
= DisplayPlanes (dpyinfo
->display
,
3747 XScreenNumberOfScreen (dpyinfo
->screen
));
3749 /* Truncate nr_planes to 24 to avoid integer overflow.
3750 Some displays says 32, but only 24 bits are actually significant.
3751 There are only very few and rare video cards that have more than
3752 24 significant bits. Also 24 bits is more than 16 million colors,
3753 it "should be enough for everyone". */
3754 if (nr_planes
> 24) nr_planes
= 24;
3756 return make_number (1 << nr_planes
);
3759 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
3760 Sx_server_max_request_size
,
3762 doc
: /* Return the maximum request size of the X server of display TERMINAL.
3763 The optional argument TERMINAL specifies which display to ask about.
3764 TERMINAL should be a terminal object, a frame or a display name (a string).
3765 If omitted or nil, that stands for the selected frame's display. */)
3767 Lisp_Object terminal
;
3769 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3771 return make_number (MAXREQUEST (dpyinfo
->display
));
3774 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
3775 doc
: /* Return the "vendor ID" string of the X server of display TERMINAL.
3776 \(Labelling every distributor as a "vendor" embodies the false assumption
3777 that operating systems cannot be developed and distributed noncommercially.)
3778 The optional argument TERMINAL specifies which display to ask about.
3779 TERMINAL should be a terminal object, a frame or a display name (a string).
3780 If omitted or nil, that stands for the selected frame's display. */)
3782 Lisp_Object terminal
;
3784 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3785 char *vendor
= ServerVendor (dpyinfo
->display
);
3787 if (! vendor
) vendor
= "";
3788 return build_string (vendor
);
3791 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
3792 doc
: /* Return the version numbers of the X server of display TERMINAL.
3793 The value is a list of three integers: the major and minor
3794 version numbers of the X Protocol in use, and the distributor-specific release
3795 number. See also the function `x-server-vendor'.
3797 The optional argument TERMINAL specifies which display to ask about.
3798 TERMINAL should be a terminal object, a frame or a display name (a string).
3799 If omitted or nil, that stands for the selected frame's display. */)
3801 Lisp_Object terminal
;
3803 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3804 Display
*dpy
= dpyinfo
->display
;
3806 return Fcons (make_number (ProtocolVersion (dpy
)),
3807 Fcons (make_number (ProtocolRevision (dpy
)),
3808 Fcons (make_number (VendorRelease (dpy
)), Qnil
)));
3811 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
3812 doc
: /* Return the number of screens on the X server of display TERMINAL.
3813 The optional argument TERMINAL specifies which display to ask about.
3814 TERMINAL should be a terminal object, a frame or a display name (a string).
3815 If omitted or nil, that stands for the selected frame's display. */)
3817 Lisp_Object terminal
;
3819 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3821 return make_number (ScreenCount (dpyinfo
->display
));
3824 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
3825 doc
: /* Return the height in millimeters of the X display TERMINAL.
3826 The optional argument TERMINAL specifies which display to ask about.
3827 TERMINAL should be a terminal object, a frame or a display name (a string).
3828 If omitted or nil, that stands for the selected frame's display. */)
3830 Lisp_Object terminal
;
3832 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3834 return make_number (HeightMMOfScreen (dpyinfo
->screen
));
3837 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
3838 doc
: /* Return the width in millimeters of the X display TERMINAL.
3839 The optional argument TERMINAL specifies which display to ask about.
3840 TERMINAL should be a terminal object, a frame or a display name (a string).
3841 If omitted or nil, that stands for the selected frame's display. */)
3843 Lisp_Object terminal
;
3845 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3847 return make_number (WidthMMOfScreen (dpyinfo
->screen
));
3850 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
3851 Sx_display_backing_store
, 0, 1, 0,
3852 doc
: /* Return an indication of whether X display TERMINAL does backing store.
3853 The value may be `always', `when-mapped', or `not-useful'.
3854 The optional argument TERMINAL specifies which display to ask about.
3855 TERMINAL should be a terminal object, a frame or a display name (a string).
3856 If omitted or nil, that stands for the selected frame's display. */)
3858 Lisp_Object terminal
;
3860 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3863 switch (DoesBackingStore (dpyinfo
->screen
))
3866 result
= intern ("always");
3870 result
= intern ("when-mapped");
3874 result
= intern ("not-useful");
3878 error ("Strange value for BackingStore parameter of screen");
3885 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
3886 Sx_display_visual_class
, 0, 1, 0,
3887 doc
: /* Return the visual class of the X display TERMINAL.
3888 The value is one of the symbols `static-gray', `gray-scale',
3889 `static-color', `pseudo-color', `true-color', or `direct-color'.
3891 The optional argument TERMINAL specifies which display to ask about.
3892 TERMINAL should a terminal object, a frame or a display name (a string).
3893 If omitted or nil, that stands for the selected frame's display. */)
3895 Lisp_Object terminal
;
3897 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3900 switch (dpyinfo
->visual
->class)
3903 result
= intern ("static-gray");
3906 result
= intern ("gray-scale");
3909 result
= intern ("static-color");
3912 result
= intern ("pseudo-color");
3915 result
= intern ("true-color");
3918 result
= intern ("direct-color");
3921 error ("Display has an unknown visual class");
3928 DEFUN ("x-display-save-under", Fx_display_save_under
,
3929 Sx_display_save_under
, 0, 1, 0,
3930 doc
: /* Return t if the X display TERMINAL supports the save-under feature.
3931 The optional argument TERMINAL specifies which display to ask about.
3932 TERMINAL should be a terminal object, a frame or a display name (a string).
3933 If omitted or nil, that stands for the selected frame's display. */)
3935 Lisp_Object terminal
;
3937 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3939 if (DoesSaveUnders (dpyinfo
->screen
) == True
)
3947 register struct frame
*f
;
3949 return FRAME_PIXEL_WIDTH (f
);
3954 register struct frame
*f
;
3956 return FRAME_PIXEL_HEIGHT (f
);
3961 register struct frame
*f
;
3963 return FRAME_COLUMN_WIDTH (f
);
3968 register struct frame
*f
;
3970 return FRAME_LINE_HEIGHT (f
);
3975 register struct frame
*f
;
3977 return FRAME_X_DISPLAY_INFO (f
)->n_planes
;
3982 /************************************************************************
3984 ************************************************************************/
3987 /* Mapping visual names to visuals. */
3989 static struct visual_class
3996 {"StaticGray", StaticGray
},
3997 {"GrayScale", GrayScale
},
3998 {"StaticColor", StaticColor
},
3999 {"PseudoColor", PseudoColor
},
4000 {"TrueColor", TrueColor
},
4001 {"DirectColor", DirectColor
},
4006 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4008 /* Value is the screen number of screen SCR. This is a substitute for
4009 the X function with the same name when that doesn't exist. */
4012 XScreenNumberOfScreen (scr
)
4013 register Screen
*scr
;
4015 Display
*dpy
= scr
->display
;
4018 for (i
= 0; i
< dpy
->nscreens
; ++i
)
4019 if (scr
== dpy
->screens
+ i
)
4025 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4028 /* Select the visual that should be used on display DPYINFO. Set
4029 members of DPYINFO appropriately. Called from x_term_init. */
4032 select_visual (dpyinfo
)
4033 struct x_display_info
*dpyinfo
;
4035 Display
*dpy
= dpyinfo
->display
;
4036 Screen
*screen
= dpyinfo
->screen
;
4039 /* See if a visual is specified. */
4040 value
= display_x_get_resource (dpyinfo
,
4041 build_string ("visualClass"),
4042 build_string ("VisualClass"),
4044 if (STRINGP (value
))
4046 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
4047 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
4048 depth, a decimal number. NAME is compared with case ignored. */
4049 char *s
= (char *) alloca (SBYTES (value
) + 1);
4054 strcpy (s
, SDATA (value
));
4055 dash
= index (s
, '-');
4058 dpyinfo
->n_planes
= atoi (dash
+ 1);
4062 /* We won't find a matching visual with depth 0, so that
4063 an error will be printed below. */
4064 dpyinfo
->n_planes
= 0;
4066 /* Determine the visual class. */
4067 for (i
= 0; visual_classes
[i
].name
; ++i
)
4068 if (xstrcasecmp (s
, visual_classes
[i
].name
) == 0)
4070 class = visual_classes
[i
].class;
4074 /* Look up a matching visual for the specified class. */
4076 || !XMatchVisualInfo (dpy
, XScreenNumberOfScreen (screen
),
4077 dpyinfo
->n_planes
, class, &vinfo
))
4078 fatal ("Invalid visual specification `%s'", SDATA (value
));
4080 dpyinfo
->visual
= vinfo
.visual
;
4085 XVisualInfo
*vinfo
, vinfo_template
;
4087 dpyinfo
->visual
= DefaultVisualOfScreen (screen
);
4089 vinfo_template
.visualid
= XVisualIDFromVisual (dpyinfo
->visual
);
4090 vinfo_template
.screen
= XScreenNumberOfScreen (screen
);
4091 vinfo
= XGetVisualInfo (dpy
, VisualIDMask
| VisualScreenMask
,
4092 &vinfo_template
, &n_visuals
);
4094 fatal ("Can't get proper X visual info");
4096 dpyinfo
->n_planes
= vinfo
->depth
;
4097 XFree ((char *) vinfo
);
4102 /* Return the X display structure for the display named NAME.
4103 Open a new connection if necessary. */
4105 struct x_display_info
*
4106 x_display_info_for_name (name
)
4110 struct x_display_info
*dpyinfo
;
4112 CHECK_STRING (name
);
4115 if (! EQ (Vinitial_window_system
, intern ("x")))
4116 error ("Not using X Windows"); /* That doesn't stop us anymore. */
4119 for (dpyinfo
= x_display_list
, names
= x_display_name_list
;
4121 dpyinfo
= dpyinfo
->next
, names
= XCDR (names
))
4124 tem
= Fstring_equal (XCAR (XCAR (names
)), name
);
4129 /* Use this general default value to start with. */
4130 Vx_resource_name
= Vinvocation_name
;
4132 validate_x_resource_name ();
4134 dpyinfo
= x_term_init (name
, (char *)0,
4135 (char *) SDATA (Vx_resource_name
));
4138 error ("Cannot connect to X server %s", SDATA (name
));
4141 XSETFASTINT (Vwindow_system_version
, 11);
4147 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
4149 doc
: /* Open a connection to an X server.
4150 DISPLAY is the name of the display to connect to.
4151 Optional second arg XRM-STRING is a string of resources in xrdb format.
4152 If the optional third arg MUST-SUCCEED is non-nil,
4153 terminate Emacs if we can't open the connection. */)
4154 (display
, xrm_string
, must_succeed
)
4155 Lisp_Object display
, xrm_string
, must_succeed
;
4157 unsigned char *xrm_option
;
4158 struct x_display_info
*dpyinfo
;
4160 CHECK_STRING (display
);
4161 if (! NILP (xrm_string
))
4162 CHECK_STRING (xrm_string
);
4165 if (! EQ (Vinitial_window_system
, intern ("x")))
4166 error ("Not using X Windows"); /* That doesn't stop us anymore. */
4169 if (! NILP (xrm_string
))
4170 xrm_option
= (unsigned char *) SDATA (xrm_string
);
4172 xrm_option
= (unsigned char *) 0;
4174 validate_x_resource_name ();
4176 /* This is what opens the connection and sets x_current_display.
4177 This also initializes many symbols, such as those used for input. */
4178 dpyinfo
= x_term_init (display
, xrm_option
,
4179 (char *) SDATA (Vx_resource_name
));
4183 if (!NILP (must_succeed
))
4184 fatal ("Cannot connect to X server %s.\n\
4185 Check the DISPLAY environment variable or use `-d'.\n\
4186 Also use the `xauth' program to verify that you have the proper\n\
4187 authorization information needed to connect the X server.\n\
4188 An insecure way to solve the problem may be to use `xhost'.\n",
4191 error ("Cannot connect to X server %s", SDATA (display
));
4196 XSETFASTINT (Vwindow_system_version
, 11);
4200 DEFUN ("x-close-connection", Fx_close_connection
,
4201 Sx_close_connection
, 1, 1, 0,
4202 doc
: /* Close the connection to TERMINAL's X server.
4203 For TERMINAL, specify a terminal object, a frame or a display name (a
4204 string). If TERMINAL is nil, that stands for the selected frame's
4207 Lisp_Object terminal
;
4209 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4211 if (dpyinfo
->reference_count
> 0)
4212 error ("Display still has frames on it");
4214 x_delete_terminal (dpyinfo
->terminal
);
4219 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
4220 doc
: /* Return the list of display names that Emacs has connections to. */)
4223 Lisp_Object tail
, result
;
4226 for (tail
= x_display_name_list
; CONSP (tail
); tail
= XCDR (tail
))
4227 result
= Fcons (XCAR (XCAR (tail
)), result
);
4232 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
4233 doc
: /* If ON is non-nil, report X errors as soon as the erring request is made.
4234 If ON is nil, allow buffering of requests.
4235 Turning on synchronization prohibits the Xlib routines from buffering
4236 requests and seriously degrades performance, but makes debugging much
4238 The optional second argument TERMINAL specifies which display to act on.
4239 TERMINAL should be a terminal object, a frame or a display name (a string).
4240 If TERMINAL is omitted or nil, that stands for the selected frame's display. */)
4242 Lisp_Object terminal
, on
;
4244 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4246 XSynchronize (dpyinfo
->display
, !EQ (on
, Qnil
));
4251 /* Wait for responses to all X commands issued so far for frame F. */
4258 XSync (FRAME_X_DISPLAY (f
), False
);
4263 /***********************************************************************
4265 ***********************************************************************/
4267 DEFUN ("x-change-window-property", Fx_change_window_property
,
4268 Sx_change_window_property
, 2, 6, 0,
4269 doc
: /* Change window property PROP to VALUE on the X window of FRAME.
4270 PROP must be a string.
4271 VALUE may be a string or a list of conses, numbers and/or strings.
4272 If an element in the list is a string, it is converted to
4273 an Atom and the value of the Atom is used. If an element is a cons,
4274 it is converted to a 32 bit number where the car is the 16 top bits and the
4275 cdr is the lower 16 bits.
4276 FRAME nil or omitted means use the selected frame.
4277 If TYPE is given and non-nil, it is the name of the type of VALUE.
4278 If TYPE is not given or nil, the type is STRING.
4279 FORMAT gives the size in bits of each element if VALUE is a list.
4280 It must be one of 8, 16 or 32.
4281 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
4282 If OUTER_P is non-nil, the property is changed for the outer X window of
4283 FRAME. Default is to change on the edit X window.
4286 (prop
, value
, frame
, type
, format
, outer_p
)
4287 Lisp_Object prop
, value
, frame
, type
, format
, outer_p
;
4289 struct frame
*f
= check_x_frame (frame
);
4291 Atom target_type
= XA_STRING
;
4292 int element_format
= 8;
4293 unsigned char *data
;
4297 CHECK_STRING (prop
);
4299 if (! NILP (format
))
4301 CHECK_NUMBER (format
);
4302 element_format
= XFASTINT (format
);
4304 if (element_format
!= 8 && element_format
!= 16
4305 && element_format
!= 32)
4306 error ("FORMAT must be one of 8, 16 or 32");
4311 nelements
= x_check_property_data (value
);
4312 if (nelements
== -1)
4313 error ("Bad data in VALUE, must be number, string or cons");
4315 if (element_format
== 8)
4316 data
= (unsigned char *) xmalloc (nelements
);
4317 else if (element_format
== 16)
4318 data
= (unsigned char *) xmalloc (nelements
*2);
4319 else /* format == 32 */
4320 /* The man page for XChangeProperty:
4321 "If the specified format is 32, the property data must be a
4323 This applies even if long is more than 64 bits. The X library
4324 converts to 32 bits before sending to the X server. */
4325 data
= (unsigned char *) xmalloc (nelements
* sizeof(long));
4327 x_fill_property_data (FRAME_X_DISPLAY (f
), value
, data
, element_format
);
4331 CHECK_STRING (value
);
4332 data
= SDATA (value
);
4333 nelements
= SCHARS (value
);
4337 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
4340 CHECK_STRING (type
);
4341 target_type
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (type
), False
);
4344 if (! NILP (outer_p
)) w
= FRAME_OUTER_WINDOW (f
);
4345 else w
= FRAME_X_WINDOW (f
);
4347 XChangeProperty (FRAME_X_DISPLAY (f
), w
,
4348 prop_atom
, target_type
, element_format
, PropModeReplace
,
4351 if (CONSP (value
)) xfree (data
);
4353 /* Make sure the property is set when we return. */
4354 XFlush (FRAME_X_DISPLAY (f
));
4361 DEFUN ("x-delete-window-property", Fx_delete_window_property
,
4362 Sx_delete_window_property
, 1, 2, 0,
4363 doc
: /* Remove window property PROP from X window of FRAME.
4364 FRAME nil or omitted means use the selected frame. Value is PROP. */)
4366 Lisp_Object prop
, frame
;
4368 struct frame
*f
= check_x_frame (frame
);
4371 CHECK_STRING (prop
);
4373 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
4374 XDeleteProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), prop_atom
);
4376 /* Make sure the property is removed when we return. */
4377 XFlush (FRAME_X_DISPLAY (f
));
4384 DEFUN ("x-window-property", Fx_window_property
, Sx_window_property
,
4386 doc
: /* Value is the value of window property PROP on FRAME.
4387 If FRAME is nil or omitted, use the selected frame.
4388 If TYPE is nil or omitted, get the property as a string. Otherwise TYPE
4389 is the name of the Atom that denotes the type expected.
4390 If SOURCE is non-nil, get the property on that window instead of from
4391 FRAME. The number 0 denotes the root window.
4392 If DELETE_P is non-nil, delete the property after retreiving it.
4393 If VECTOR_RET_P is non-nil, don't return a string but a vector of values.
4395 Value is nil if FRAME hasn't a property with name PROP or if PROP has
4396 no value of TYPE. */)
4397 (prop
, frame
, type
, source
, delete_p
, vector_ret_p
)
4398 Lisp_Object prop
, frame
, type
, source
, delete_p
, vector_ret_p
;
4400 struct frame
*f
= check_x_frame (frame
);
4403 Lisp_Object prop_value
= Qnil
;
4404 unsigned char *tmp_data
= NULL
;
4406 Atom target_type
= XA_STRING
;
4408 unsigned long actual_size
, bytes_remaining
;
4409 Window target_window
= FRAME_X_WINDOW (f
);
4410 struct gcpro gcpro1
;
4412 GCPRO1 (prop_value
);
4413 CHECK_STRING (prop
);
4415 if (! NILP (source
))
4417 if (NUMBERP (source
))
4419 if (FLOATP (source
))
4420 target_window
= (Window
) XFLOAT (source
);
4422 target_window
= XFASTINT (source
);
4424 if (target_window
== 0)
4425 target_window
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
4427 else if (CONSP (source
))
4428 target_window
= cons_to_long (source
);
4434 if (strcmp ("AnyPropertyType", SDATA (type
)) == 0)
4435 target_type
= AnyPropertyType
;
4437 target_type
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (type
), False
);
4440 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
4441 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), target_window
,
4442 prop_atom
, 0, 0, False
, target_type
,
4443 &actual_type
, &actual_format
, &actual_size
,
4444 &bytes_remaining
, &tmp_data
);
4447 int size
= bytes_remaining
;
4452 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), target_window
,
4453 prop_atom
, 0, bytes_remaining
,
4454 ! NILP (delete_p
), target_type
,
4455 &actual_type
, &actual_format
,
4456 &actual_size
, &bytes_remaining
,
4458 if (rc
== Success
&& tmp_data
)
4460 /* The man page for XGetWindowProperty says:
4461 "If the returned format is 32, the returned data is represented
4462 as a long array and should be cast to that type to obtain the
4464 This applies even if long is more than 32 bits, the X library
4465 converts from 32 bit elements received from the X server to long
4466 and passes the long array to us. Thus, for that case bcopy can not
4467 be used. We convert to a 32 bit type here, because so much code
4470 The bytes and offsets passed to XGetWindowProperty refers to the
4471 property and those are indeed in 32 bit quantities if format is
4474 if (actual_format
== 32 && actual_format
< BITS_PER_LONG
)
4477 int *idata
= (int *) tmp_data
;
4478 long *ldata
= (long *) tmp_data
;
4480 for (i
= 0; i
< actual_size
; ++i
)
4481 idata
[i
] = (int) ldata
[i
];
4484 if (NILP (vector_ret_p
))
4485 prop_value
= make_string (tmp_data
, size
);
4487 prop_value
= x_property_data_to_lisp (f
,
4494 if (tmp_data
) XFree (tmp_data
);
4504 /***********************************************************************
4506 ***********************************************************************/
4508 /* Timer function of hourglass_atimer. TIMER is equal to
4511 Display an hourglass pointer on all frames by mapping the frames'
4512 hourglass_window. Set the hourglass_p flag in the frames'
4513 output_data.x structure to indicate that an hourglass cursor is
4514 shown on the frames. */
4517 show_hourglass (timer
)
4518 struct atimer
*timer
;
4520 /* The timer implementation will cancel this timer automatically
4521 after this function has run. Set hourglass_atimer to null
4522 so that we know the timer doesn't have to be canceled. */
4523 hourglass_atimer
= NULL
;
4525 if (!hourglass_shown_p
)
4527 Lisp_Object rest
, frame
;
4531 FOR_EACH_FRAME (rest
, frame
)
4533 struct frame
*f
= XFRAME (frame
);
4535 if (FRAME_LIVE_P (f
) && FRAME_X_P (f
) && FRAME_X_DISPLAY (f
))
4537 Display
*dpy
= FRAME_X_DISPLAY (f
);
4539 #ifdef USE_X_TOOLKIT
4540 if (f
->output_data
.x
->widget
)
4542 if (FRAME_OUTER_WINDOW (f
))
4545 f
->output_data
.x
->hourglass_p
= 1;
4547 if (!f
->output_data
.x
->hourglass_window
)
4549 unsigned long mask
= CWCursor
;
4550 XSetWindowAttributes attrs
;
4552 Window parent
= FRAME_X_WINDOW (f
);
4554 Window parent
= FRAME_OUTER_WINDOW (f
);
4556 attrs
.cursor
= f
->output_data
.x
->hourglass_cursor
;
4558 f
->output_data
.x
->hourglass_window
4559 = XCreateWindow (dpy
, parent
,
4560 0, 0, 32000, 32000, 0, 0,
4566 XMapRaised (dpy
, f
->output_data
.x
->hourglass_window
);
4572 hourglass_shown_p
= 1;
4578 /* Hide the hourglass pointer on all frames, if it is currently
4584 if (hourglass_shown_p
)
4586 Lisp_Object rest
, frame
;
4589 FOR_EACH_FRAME (rest
, frame
)
4591 struct frame
*f
= XFRAME (frame
);
4594 /* Watch out for newly created frames. */
4595 && f
->output_data
.x
->hourglass_window
)
4597 XUnmapWindow (FRAME_X_DISPLAY (f
),
4598 f
->output_data
.x
->hourglass_window
);
4599 /* Sync here because XTread_socket looks at the
4600 hourglass_p flag that is reset to zero below. */
4601 XSync (FRAME_X_DISPLAY (f
), False
);
4602 f
->output_data
.x
->hourglass_p
= 0;
4606 hourglass_shown_p
= 0;
4613 /***********************************************************************
4615 ***********************************************************************/
4617 static Lisp_Object x_create_tip_frame
P_ ((struct x_display_info
*,
4618 Lisp_Object
, Lisp_Object
));
4619 static void compute_tip_xy
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
,
4620 Lisp_Object
, int, int, int *, int *));
4622 /* The frame of a currently visible tooltip. */
4624 Lisp_Object tip_frame
;
4626 /* If non-nil, a timer started that hides the last tooltip when it
4629 Lisp_Object tip_timer
;
4632 /* If non-nil, a vector of 3 elements containing the last args
4633 with which x-show-tip was called. See there. */
4635 Lisp_Object last_show_tip_args
;
4637 /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
4639 Lisp_Object Vx_max_tooltip_size
;
4643 unwind_create_tip_frame (frame
)
4646 Lisp_Object deleted
;
4648 deleted
= unwind_create_frame (frame
);
4649 if (EQ (deleted
, Qt
))
4659 /* Create a frame for a tooltip on the display described by DPYINFO.
4660 PARMS is a list of frame parameters. TEXT is the string to
4661 display in the tip frame. Value is the frame.
4663 Note that functions called here, esp. x_default_parameter can
4664 signal errors, for instance when a specified color name is
4665 undefined. We have to make sure that we're in a consistent state
4666 when this happens. */
4669 x_create_tip_frame (dpyinfo
, parms
, text
)
4670 struct x_display_info
*dpyinfo
;
4671 Lisp_Object parms
, text
;
4674 Lisp_Object frame
, tem
;
4676 long window_prompting
= 0;
4678 int count
= SPECPDL_INDEX ();
4679 struct gcpro gcpro1
, gcpro2
, gcpro3
;
4680 int face_change_count_before
= face_change_count
;
4682 struct buffer
*old_buffer
;
4686 if (!dpyinfo
->terminal
->name
)
4687 error ("Terminal is not live, can't create new frames on it");
4689 parms
= Fcopy_alist (parms
);
4691 /* Get the name of the frame to use for resource lookup. */
4692 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
4694 && !EQ (name
, Qunbound
)
4696 error ("Invalid frame name--not a string or nil");
4699 GCPRO3 (parms
, name
, frame
);
4701 XSETFRAME (frame
, f
);
4703 buffer
= Fget_buffer_create (build_string (" *tip*"));
4704 Fset_window_buffer (FRAME_ROOT_WINDOW (f
), buffer
, Qnil
);
4705 old_buffer
= current_buffer
;
4706 set_buffer_internal_1 (XBUFFER (buffer
));
4707 current_buffer
->truncate_lines
= Qnil
;
4708 specbind (Qinhibit_read_only
, Qt
);
4709 specbind (Qinhibit_modification_hooks
, Qt
);
4712 set_buffer_internal_1 (old_buffer
);
4714 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
4715 record_unwind_protect (unwind_create_tip_frame
, frame
);
4717 f
->terminal
= dpyinfo
->terminal
;
4718 f
->terminal
->reference_count
++;
4720 /* By setting the output method, we're essentially saying that
4721 the frame is live, as per FRAME_LIVE_P. If we get a signal
4722 from this point on, x_destroy_window might screw up reference
4724 f
->output_method
= output_x_window
;
4725 f
->output_data
.x
= (struct x_output
*) xmalloc (sizeof (struct x_output
));
4726 bzero (f
->output_data
.x
, sizeof (struct x_output
));
4727 f
->output_data
.x
->icon_bitmap
= -1;
4728 FRAME_FONTSET (f
) = -1;
4729 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
4730 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
4731 #ifdef USE_TOOLKIT_SCROLL_BARS
4732 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
4733 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
4734 #endif /* USE_TOOLKIT_SCROLL_BARS */
4735 f
->icon_name
= Qnil
;
4736 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
4738 image_cache_refcount
= FRAME_IMAGE_CACHE (f
)->refcount
;
4739 dpyinfo_refcount
= dpyinfo
->reference_count
;
4740 #endif /* GLYPH_DEBUG */
4741 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
4742 f
->output_data
.x
->explicit_parent
= 0;
4744 /* These colors will be set anyway later, but it's important
4745 to get the color reference counts right, so initialize them! */
4748 struct gcpro gcpro1
;
4750 /* Function x_decode_color can signal an error. Make
4751 sure to initialize color slots so that we won't try
4752 to free colors we haven't allocated. */
4753 FRAME_FOREGROUND_PIXEL (f
) = -1;
4754 FRAME_BACKGROUND_PIXEL (f
) = -1;
4755 f
->output_data
.x
->cursor_pixel
= -1;
4756 f
->output_data
.x
->cursor_foreground_pixel
= -1;
4757 f
->output_data
.x
->border_pixel
= -1;
4758 f
->output_data
.x
->mouse_pixel
= -1;
4760 black
= build_string ("black");
4762 FRAME_FOREGROUND_PIXEL (f
)
4763 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
4764 FRAME_BACKGROUND_PIXEL (f
)
4765 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
4766 f
->output_data
.x
->cursor_pixel
4767 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
4768 f
->output_data
.x
->cursor_foreground_pixel
4769 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
4770 f
->output_data
.x
->border_pixel
4771 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
4772 f
->output_data
.x
->mouse_pixel
4773 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
4777 /* Set the name; the functions to which we pass f expect the name to
4779 if (EQ (name
, Qunbound
) || NILP (name
))
4781 f
->name
= build_string (dpyinfo
->x_id_name
);
4782 f
->explicit_name
= 0;
4787 f
->explicit_name
= 1;
4788 /* use the frame's title when getting resources for this frame. */
4789 specbind (Qx_resource_name
, name
);
4792 f
->resx
= dpyinfo
->resx
;
4793 f
->resy
= dpyinfo
->resy
;
4795 register_font_driver (&xfont_driver
, f
);
4796 #ifdef HAVE_FREETYPE
4798 register_font_driver (&xftfont_driver
, f
);
4799 #else /* not HAVE_XFT */
4800 register_font_driver (&ftxfont_driver
, f
);
4801 #endif /* not HAVE_XFT */
4802 #endif /* HAVE_FREETYPE */
4804 x_default_parameter (f
, parms
, Qfont_backend
, Qnil
,
4805 "fontBackend", "FontBackend", RES_TYPE_STRING
);
4807 /* Extract the window parameters from the supplied values that are
4808 needed to determine window geometry. */
4809 x_default_font_parameter (f
, parms
);
4811 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
4812 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
4814 /* This defaults to 2 in order to match xterm. We recognize either
4815 internalBorderWidth or internalBorder (which is what xterm calls
4817 if (NILP (Fassq (Qinternal_border_width
, parms
)))
4821 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
4822 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
4823 if (! EQ (value
, Qunbound
))
4824 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
4828 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
4829 "internalBorderWidth", "internalBorderWidth",
4832 /* Also do the stuff which must be set before the window exists. */
4833 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
4834 "foreground", "Foreground", RES_TYPE_STRING
);
4835 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
4836 "background", "Background", RES_TYPE_STRING
);
4837 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
4838 "pointerColor", "Foreground", RES_TYPE_STRING
);
4839 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
4840 "cursorColor", "Foreground", RES_TYPE_STRING
);
4841 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
4842 "borderColor", "BorderColor", RES_TYPE_STRING
);
4844 /* Init faces before x_default_parameter is called for scroll-bar
4845 parameters because that function calls x_set_scroll_bar_width,
4846 which calls change_frame_size, which calls Fset_window_buffer,
4847 which runs hooks, which call Fvertical_motion. At the end, we
4848 end up in init_iterator with a null face cache, which should not
4850 init_frame_faces (f
);
4852 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
4854 window_prompting
= x_figure_window_size (f
, parms
, 0);
4857 XSetWindowAttributes attrs
;
4859 Atom type
= FRAME_X_DISPLAY_INFO (f
)->Xatom_net_window_type_tooltip
;
4862 mask
= CWBackPixel
| CWOverrideRedirect
| CWEventMask
;
4863 if (DoesSaveUnders (dpyinfo
->screen
))
4864 mask
|= CWSaveUnder
;
4866 /* Window managers look at the override-redirect flag to determine
4867 whether or net to give windows a decoration (Xlib spec, chapter
4869 attrs
.override_redirect
= True
;
4870 attrs
.save_under
= True
;
4871 attrs
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
4872 /* Arrange for getting MapNotify and UnmapNotify events. */
4873 attrs
.event_mask
= StructureNotifyMask
;
4875 = FRAME_X_WINDOW (f
)
4876 = XCreateWindow (FRAME_X_DISPLAY (f
),
4877 FRAME_X_DISPLAY_INFO (f
)->root_window
,
4878 /* x, y, width, height */
4882 CopyFromParent
, InputOutput
, CopyFromParent
,
4884 XChangeProperty (FRAME_X_DISPLAY (f
), tip_window
,
4885 FRAME_X_DISPLAY_INFO (f
)->Xatom_net_window_type
,
4886 XA_ATOM
, 32, PropModeReplace
,
4887 (unsigned char *)&type
, 1);
4893 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
4894 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
4895 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
4896 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
4897 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
4898 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
4900 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
4901 Change will not be effected unless different from the current
4903 width
= FRAME_COLS (f
);
4904 height
= FRAME_LINES (f
);
4905 SET_FRAME_COLS (f
, 0);
4906 FRAME_LINES (f
) = 0;
4907 change_frame_size (f
, height
, width
, 1, 0, 0);
4909 /* Add `tooltip' frame parameter's default value. */
4910 if (NILP (Fframe_parameter (frame
, Qtooltip
)))
4911 Fmodify_frame_parameters (frame
, Fcons (Fcons (Qtooltip
, Qt
), Qnil
));
4913 /* FIXME - can this be done in a similar way to normal frames?
4914 http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
4916 /* Set the `display-type' frame parameter before setting up faces. */
4918 Lisp_Object disptype
;
4920 if (FRAME_X_DISPLAY_INFO (f
)->n_planes
== 1)
4921 disptype
= intern ("mono");
4922 else if (FRAME_X_DISPLAY_INFO (f
)->visual
->class == GrayScale
4923 || FRAME_X_DISPLAY_INFO (f
)->visual
->class == StaticGray
)
4924 disptype
= intern ("grayscale");
4926 disptype
= intern ("color");
4928 if (NILP (Fframe_parameter (frame
, Qdisplay_type
)))
4929 Fmodify_frame_parameters (frame
, Fcons (Fcons (Qdisplay_type
, disptype
),
4933 /* Set up faces after all frame parameters are known. This call
4934 also merges in face attributes specified for new frames.
4936 Frame parameters may be changed if .Xdefaults contains
4937 specifications for the default font. For example, if there is an
4938 `Emacs.default.attributeBackground: pink', the `background-color'
4939 attribute of the frame get's set, which let's the internal border
4940 of the tooltip frame appear in pink. Prevent this. */
4942 Lisp_Object bg
= Fframe_parameter (frame
, Qbackground_color
);
4944 /* Set tip_frame here, so that */
4946 call2 (Qface_set_after_frame_default
, frame
, Qnil
);
4948 if (!EQ (bg
, Fframe_parameter (frame
, Qbackground_color
)))
4949 Fmodify_frame_parameters (frame
, Fcons (Fcons (Qbackground_color
, bg
),
4957 /* It is now ok to make the frame official even if we get an error
4958 below. And the frame needs to be on Vframe_list or making it
4959 visible won't work. */
4960 Vframe_list
= Fcons (frame
, Vframe_list
);
4962 /* Now that the frame is official, it counts as a reference to
4964 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
4966 /* Setting attributes of faces of the tooltip frame from resources
4967 and similar will increment face_change_count, which leads to the
4968 clearing of all current matrices. Since this isn't necessary
4969 here, avoid it by resetting face_change_count to the value it
4970 had before we created the tip frame. */
4971 face_change_count
= face_change_count_before
;
4973 /* Discard the unwind_protect. */
4974 return unbind_to (count
, frame
);
4978 /* Compute where to display tip frame F. PARMS is the list of frame
4979 parameters for F. DX and DY are specified offsets from the current
4980 location of the mouse. WIDTH and HEIGHT are the width and height
4981 of the tooltip. Return coordinates relative to the root window of
4982 the display in *ROOT_X, and *ROOT_Y. */
4985 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, root_x
, root_y
)
4987 Lisp_Object parms
, dx
, dy
;
4989 int *root_x
, *root_y
;
4991 Lisp_Object left
, top
;
4996 /* User-specified position? */
4997 left
= Fcdr (Fassq (Qleft
, parms
));
4998 top
= Fcdr (Fassq (Qtop
, parms
));
5000 /* Move the tooltip window where the mouse pointer is. Resize and
5002 if (!INTEGERP (left
) || !INTEGERP (top
))
5005 XQueryPointer (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
5006 &root
, &child
, root_x
, root_y
, &win_x
, &win_y
, &pmask
);
5011 *root_y
= XINT (top
);
5012 else if (*root_y
+ XINT (dy
) <= 0)
5013 *root_y
= 0; /* Can happen for negative dy */
5014 else if (*root_y
+ XINT (dy
) + height
5015 <= x_display_pixel_height (FRAME_X_DISPLAY_INFO (f
)))
5016 /* It fits below the pointer */
5017 *root_y
+= XINT (dy
);
5018 else if (height
+ XINT (dy
) <= *root_y
)
5019 /* It fits above the pointer. */
5020 *root_y
-= height
+ XINT (dy
);
5022 /* Put it on the top. */
5025 if (INTEGERP (left
))
5026 *root_x
= XINT (left
);
5027 else if (*root_x
+ XINT (dx
) <= 0)
5028 *root_x
= 0; /* Can happen for negative dx */
5029 else if (*root_x
+ XINT (dx
) + width
5030 <= x_display_pixel_width (FRAME_X_DISPLAY_INFO (f
)))
5031 /* It fits to the right of the pointer. */
5032 *root_x
+= XINT (dx
);
5033 else if (width
+ XINT (dx
) <= *root_x
)
5034 /* It fits to the left of the pointer. */
5035 *root_x
-= width
+ XINT (dx
);
5037 /* Put it left-justified on the screen--it ought to fit that way. */
5042 DEFUN ("x-show-tip", Fx_show_tip
, Sx_show_tip
, 1, 6, 0,
5043 doc
: /* Show STRING in a "tooltip" window on frame FRAME.
5044 A tooltip window is a small X window displaying a string.
5046 This is an internal function; Lisp code should call `tooltip-show'.
5048 FRAME nil or omitted means use the selected frame.
5050 PARMS is an optional list of frame parameters which can be used to
5051 change the tooltip's appearance.
5053 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
5054 means use the default timeout of 5 seconds.
5056 If the list of frame parameters PARAMS contains a `left' parameters,
5057 the tooltip is displayed at that x-position. Otherwise it is
5058 displayed at the mouse position, with offset DX added (default is 5 if
5059 DX isn't specified). Likewise for the y-position; if a `top' frame
5060 parameter is specified, it determines the y-position of the tooltip
5061 window, otherwise it is displayed at the mouse position, with offset
5062 DY added (default is -10).
5064 A tooltip's maximum size is specified by `x-max-tooltip-size'.
5065 Text larger than the specified size is clipped. */)
5066 (string
, frame
, parms
, timeout
, dx
, dy
)
5067 Lisp_Object string
, frame
, parms
, timeout
, dx
, dy
;
5072 struct buffer
*old_buffer
;
5073 struct text_pos pos
;
5074 int i
, width
, height
;
5075 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
5076 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
5077 int count
= SPECPDL_INDEX ();
5079 specbind (Qinhibit_redisplay
, Qt
);
5081 GCPRO4 (string
, parms
, frame
, timeout
);
5083 CHECK_STRING (string
);
5084 if (SCHARS (string
) == 0)
5085 string
= make_unibyte_string (" ", 1);
5087 f
= check_x_frame (frame
);
5089 timeout
= make_number (5);
5091 CHECK_NATNUM (timeout
);
5094 dx
= make_number (5);
5099 dy
= make_number (-10);
5103 if (NILP (last_show_tip_args
))
5104 last_show_tip_args
= Fmake_vector (make_number (3), Qnil
);
5106 if (!NILP (tip_frame
))
5108 Lisp_Object last_string
= AREF (last_show_tip_args
, 0);
5109 Lisp_Object last_frame
= AREF (last_show_tip_args
, 1);
5110 Lisp_Object last_parms
= AREF (last_show_tip_args
, 2);
5112 if (EQ (frame
, last_frame
)
5113 && !NILP (Fequal (last_string
, string
))
5114 && !NILP (Fequal (last_parms
, parms
)))
5116 struct frame
*f
= XFRAME (tip_frame
);
5118 /* Only DX and DY have changed. */
5119 if (!NILP (tip_timer
))
5121 Lisp_Object timer
= tip_timer
;
5123 call1 (Qcancel_timer
, timer
);
5127 compute_tip_xy (f
, parms
, dx
, dy
, FRAME_PIXEL_WIDTH (f
),
5128 FRAME_PIXEL_HEIGHT (f
), &root_x
, &root_y
);
5129 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5136 /* Hide a previous tip, if any. */
5139 ASET (last_show_tip_args
, 0, string
);
5140 ASET (last_show_tip_args
, 1, frame
);
5141 ASET (last_show_tip_args
, 2, parms
);
5143 /* Add default values to frame parameters. */
5144 if (NILP (Fassq (Qname
, parms
)))
5145 parms
= Fcons (Fcons (Qname
, build_string ("tooltip")), parms
);
5146 if (NILP (Fassq (Qinternal_border_width
, parms
)))
5147 parms
= Fcons (Fcons (Qinternal_border_width
, make_number (3)), parms
);
5148 if (NILP (Fassq (Qborder_width
, parms
)))
5149 parms
= Fcons (Fcons (Qborder_width
, make_number (1)), parms
);
5150 if (NILP (Fassq (Qborder_color
, parms
)))
5151 parms
= Fcons (Fcons (Qborder_color
, build_string ("lightyellow")), parms
);
5152 if (NILP (Fassq (Qbackground_color
, parms
)))
5153 parms
= Fcons (Fcons (Qbackground_color
, build_string ("lightyellow")),
5156 /* Create a frame for the tooltip, and record it in the global
5157 variable tip_frame. */
5158 frame
= x_create_tip_frame (FRAME_X_DISPLAY_INFO (f
), parms
, string
);
5161 /* Set up the frame's root window. */
5162 w
= XWINDOW (FRAME_ROOT_WINDOW (f
));
5163 w
->left_col
= w
->top_line
= make_number (0);
5165 if (CONSP (Vx_max_tooltip_size
)
5166 && INTEGERP (XCAR (Vx_max_tooltip_size
))
5167 && XINT (XCAR (Vx_max_tooltip_size
)) > 0
5168 && INTEGERP (XCDR (Vx_max_tooltip_size
))
5169 && XINT (XCDR (Vx_max_tooltip_size
)) > 0)
5171 w
->total_cols
= XCAR (Vx_max_tooltip_size
);
5172 w
->total_lines
= XCDR (Vx_max_tooltip_size
);
5176 w
->total_cols
= make_number (80);
5177 w
->total_lines
= make_number (40);
5180 FRAME_TOTAL_COLS (f
) = XINT (w
->total_cols
);
5182 w
->pseudo_window_p
= 1;
5184 /* Display the tooltip text in a temporary buffer. */
5185 old_buffer
= current_buffer
;
5186 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f
))->buffer
));
5187 current_buffer
->truncate_lines
= Qnil
;
5188 clear_glyph_matrix (w
->desired_matrix
);
5189 clear_glyph_matrix (w
->current_matrix
);
5190 SET_TEXT_POS (pos
, BEGV
, BEGV_BYTE
);
5191 try_window (FRAME_ROOT_WINDOW (f
), pos
, 0);
5193 /* Compute width and height of the tooltip. */
5195 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
5197 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
5201 /* Stop at the first empty row at the end. */
5202 if (!row
->enabled_p
|| !row
->displays_text_p
)
5205 /* Let the row go over the full width of the frame. */
5206 row
->full_width_p
= 1;
5208 /* There's a glyph at the end of rows that is used to place
5209 the cursor there. Don't include the width of this glyph. */
5210 if (row
->used
[TEXT_AREA
])
5212 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
5213 row_width
= row
->pixel_width
- last
->pixel_width
;
5216 row_width
= row
->pixel_width
;
5218 height
+= row
->height
;
5219 width
= max (width
, row_width
);
5222 /* Add the frame's internal border to the width and height the X
5223 window should have. */
5224 height
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
5225 width
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
5227 /* Move the tooltip window where the mouse pointer is. Resize and
5229 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, &root_x
, &root_y
);
5232 XMoveResizeWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5233 root_x
, root_y
, width
, height
);
5234 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
5237 /* Draw into the window. */
5238 w
->must_be_updated_p
= 1;
5239 update_single_window (w
, 1);
5241 /* Restore original current buffer. */
5242 set_buffer_internal_1 (old_buffer
);
5243 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
5246 /* Let the tip disappear after timeout seconds. */
5247 tip_timer
= call3 (intern ("run-at-time"), timeout
, Qnil
,
5248 intern ("x-hide-tip"));
5251 return unbind_to (count
, Qnil
);
5255 DEFUN ("x-hide-tip", Fx_hide_tip
, Sx_hide_tip
, 0, 0, 0,
5256 doc
: /* Hide the current tooltip window, if there is any.
5257 Value is t if tooltip was open, nil otherwise. */)
5261 Lisp_Object deleted
, frame
, timer
;
5262 struct gcpro gcpro1
, gcpro2
;
5264 /* Return quickly if nothing to do. */
5265 if (NILP (tip_timer
) && NILP (tip_frame
))
5270 GCPRO2 (frame
, timer
);
5271 tip_frame
= tip_timer
= deleted
= Qnil
;
5273 count
= SPECPDL_INDEX ();
5274 specbind (Qinhibit_redisplay
, Qt
);
5275 specbind (Qinhibit_quit
, Qt
);
5278 call1 (Qcancel_timer
, timer
);
5282 delete_frame (frame
, Qnil
);
5286 /* Bloodcurdling hack alert: The Lucid menu bar widget's
5287 redisplay procedure is not called when a tip frame over menu
5288 items is unmapped. Redisplay the menu manually... */
5290 struct frame
*f
= SELECTED_FRAME ();
5291 Widget w
= f
->output_data
.x
->menubar_widget
;
5292 extern void xlwmenu_redisplay
P_ ((Widget
));
5294 if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f
)->screen
)
5298 xlwmenu_redisplay (w
);
5302 #endif /* USE_LUCID */
5306 return unbind_to (count
, deleted
);
5311 /***********************************************************************
5312 File selection dialog
5313 ***********************************************************************/
5315 DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog
,
5316 Sx_uses_old_gtk_dialog
,
5318 doc
: /* Return t if the old Gtk+ file selection dialog is used. */)
5322 extern int use_dialog_box
;
5323 extern int use_file_dialog
;
5328 && xg_uses_old_file_dialog ())
5336 /* Callback for "OK" and "Cancel" on file selection dialog. */
5339 file_dialog_cb (widget
, client_data
, call_data
)
5341 XtPointer call_data
, client_data
;
5343 int *result
= (int *) client_data
;
5344 XmAnyCallbackStruct
*cb
= (XmAnyCallbackStruct
*) call_data
;
5345 *result
= cb
->reason
;
5349 /* Callback for unmapping a file selection dialog. This is used to
5350 capture the case where a dialog is closed via a window manager's
5351 closer button, for example. Using a XmNdestroyCallback didn't work
5355 file_dialog_unmap_cb (widget
, client_data
, call_data
)
5357 XtPointer call_data
, client_data
;
5359 int *result
= (int *) client_data
;
5360 *result
= XmCR_CANCEL
;
5364 clean_up_file_dialog (arg
)
5367 struct Lisp_Save_Value
*p
= XSAVE_VALUE (arg
);
5368 Widget dialog
= (Widget
) p
->pointer
;
5372 XtUnmanageChild (dialog
);
5373 XtDestroyWidget (dialog
);
5374 x_menu_set_in_use (0);
5381 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 5, 0,
5382 doc
: /* Read file name, prompting with PROMPT in directory DIR.
5383 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5384 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5385 or directory must exist. ONLY-DIR-P is ignored." */)
5386 (prompt
, dir
, default_filename
, mustmatch
, only_dir_p
)
5387 Lisp_Object prompt
, dir
, default_filename
, mustmatch
, only_dir_p
;
5390 struct frame
*f
= SELECTED_FRAME ();
5391 Lisp_Object file
= Qnil
;
5392 Lisp_Object decoded_file
;
5393 Widget dialog
, text
, help
;
5396 extern XtAppContext Xt_app_con
;
5397 XmString dir_xmstring
, pattern_xmstring
;
5398 int count
= SPECPDL_INDEX ();
5399 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
, gcpro6
;
5403 GCPRO6 (prompt
, dir
, default_filename
, mustmatch
, only_dir_p
, file
);
5405 if (popup_activated ())
5406 error ("Trying to use a menu from within a menu-entry");
5408 CHECK_STRING (prompt
);
5411 /* Prevent redisplay. */
5412 specbind (Qinhibit_redisplay
, Qt
);
5416 /* Create the dialog with PROMPT as title, using DIR as initial
5417 directory and using "*" as pattern. */
5418 dir
= Fexpand_file_name (dir
, Qnil
);
5419 dir_xmstring
= XmStringCreateLocalized (SDATA (dir
));
5420 pattern_xmstring
= XmStringCreateLocalized ("*");
5422 XtSetArg (al
[ac
], XmNtitle
, SDATA (prompt
)); ++ac
;
5423 XtSetArg (al
[ac
], XmNdirectory
, dir_xmstring
); ++ac
;
5424 XtSetArg (al
[ac
], XmNpattern
, pattern_xmstring
); ++ac
;
5425 XtSetArg (al
[ac
], XmNresizePolicy
, XmRESIZE_GROW
); ++ac
;
5426 XtSetArg (al
[ac
], XmNdialogStyle
, XmDIALOG_APPLICATION_MODAL
); ++ac
;
5427 dialog
= XmCreateFileSelectionDialog (f
->output_data
.x
->widget
,
5429 XmStringFree (dir_xmstring
);
5430 XmStringFree (pattern_xmstring
);
5432 /* Add callbacks for OK and Cancel. */
5433 XtAddCallback (dialog
, XmNokCallback
, file_dialog_cb
,
5434 (XtPointer
) &result
);
5435 XtAddCallback (dialog
, XmNcancelCallback
, file_dialog_cb
,
5436 (XtPointer
) &result
);
5437 XtAddCallback (dialog
, XmNunmapCallback
, file_dialog_unmap_cb
,
5438 (XtPointer
) &result
);
5440 /* Remove the help button since we can't display help. */
5441 help
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_HELP_BUTTON
);
5442 XtUnmanageChild (help
);
5444 /* Mark OK button as default. */
5445 XtVaSetValues (XmFileSelectionBoxGetChild (dialog
, XmDIALOG_OK_BUTTON
),
5446 XmNshowAsDefault
, True
, NULL
);
5448 /* If MUSTMATCH is non-nil, disable the file entry field of the
5449 dialog, so that the user must select a file from the files list
5450 box. We can't remove it because we wouldn't have a way to get at
5451 the result file name, then. */
5452 text
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
5453 if (!NILP (mustmatch
))
5456 label
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_SELECTION_LABEL
);
5457 XtSetSensitive (text
, False
);
5458 XtSetSensitive (label
, False
);
5461 /* Manage the dialog, so that list boxes get filled. */
5462 XtManageChild (dialog
);
5464 if (STRINGP (default_filename
))
5466 XmString default_xmstring
;
5467 Widget wtext
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
5468 Widget list
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_LIST
);
5470 XmTextPosition last_pos
= XmTextFieldGetLastPosition (wtext
);
5471 XmTextFieldReplace (wtext
, 0, last_pos
,
5472 (SDATA (Ffile_name_nondirectory (default_filename
))));
5474 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
5475 must include the path for this to work. */
5477 default_xmstring
= XmStringCreateLocalized (SDATA (default_filename
));
5479 if (XmListItemExists (list
, default_xmstring
))
5481 int item_pos
= XmListItemPos (list
, default_xmstring
);
5482 /* Select the item and scroll it into view. */
5483 XmListSelectPos (list
, item_pos
, True
);
5484 XmListSetPos (list
, item_pos
);
5487 XmStringFree (default_xmstring
);
5490 record_unwind_protect (clean_up_file_dialog
, make_save_value (dialog
, 0));
5492 /* Process events until the user presses Cancel or OK. */
5493 x_menu_set_in_use (1);
5498 x_menu_wait_for_event (0);
5499 XtAppNextEvent (Xt_app_con
, &event
);
5500 if (event
.type
== KeyPress
5501 && FRAME_X_DISPLAY (f
) == event
.xkey
.display
)
5503 KeySym keysym
= XLookupKeysym (&event
.xkey
, 0);
5505 /* Pop down on C-g. */
5506 if (keysym
== XK_g
&& (event
.xkey
.state
& ControlMask
) != 0)
5507 XtUnmanageChild (dialog
);
5510 (void) x_dispatch_event (&event
, FRAME_X_DISPLAY (f
));
5513 /* Get the result. */
5514 if (result
== XmCR_OK
)
5519 XtVaGetValues (dialog
, XmNtextString
, &text
, NULL
);
5520 XmStringGetLtoR (text
, XmFONTLIST_DEFAULT_TAG
, &data
);
5521 XmStringFree (text
);
5522 file
= build_string (data
);
5531 /* Make "Cancel" equivalent to C-g. */
5533 Fsignal (Qquit
, Qnil
);
5535 decoded_file
= DECODE_FILE (file
);
5537 return unbind_to (count
, decoded_file
);
5540 #endif /* USE_MOTIF */
5545 clean_up_dialog (arg
)
5548 x_menu_set_in_use (0);
5553 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 5, 0,
5554 doc
: /* Read file name, prompting with PROMPT in directory DIR.
5555 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5556 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5557 or directory must exist. If ONLY-DIR-P is non-nil, the user can only select
5559 (prompt
, dir
, default_filename
, mustmatch
, only_dir_p
)
5560 Lisp_Object prompt
, dir
, default_filename
, mustmatch
, only_dir_p
;
5562 FRAME_PTR f
= SELECTED_FRAME ();
5564 Lisp_Object file
= Qnil
;
5565 Lisp_Object decoded_file
;
5566 int count
= SPECPDL_INDEX ();
5567 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
, gcpro6
;
5572 GCPRO6 (prompt
, dir
, default_filename
, mustmatch
, only_dir_p
, file
);
5574 if (popup_activated ())
5575 error ("Trying to use a menu from within a menu-entry");
5577 CHECK_STRING (prompt
);
5580 /* Prevent redisplay. */
5581 specbind (Qinhibit_redisplay
, Qt
);
5582 record_unwind_protect (clean_up_dialog
, Qnil
);
5586 if (STRINGP (default_filename
))
5587 cdef_file
= SDATA (default_filename
);
5589 cdef_file
= SDATA (dir
);
5591 fn
= xg_get_file_name (f
, SDATA (prompt
), cdef_file
,
5593 ! NILP (only_dir_p
));
5597 file
= build_string (fn
);
5604 /* Make "Cancel" equivalent to C-g. */
5606 Fsignal (Qquit
, Qnil
);
5608 decoded_file
= DECODE_FILE (file
);
5610 return unbind_to (count
, decoded_file
);
5614 #ifdef HAVE_FREETYPE
5616 DEFUN ("x-select-font", Fx_select_font
, Sx_select_font
, 0, 2, 0,
5617 doc
: /* Read a font name using a GTK font selection dialog.
5618 Return a GTK-style font string corresponding to the selection.
5620 If FRAME is omitted or nil, it defaults to the selected frame. */)
5622 Lisp_Object frame
, ignored
;
5624 FRAME_PTR f
= check_x_frame (frame
);
5627 Lisp_Object font_param
;
5628 char *default_name
= NULL
;
5629 struct gcpro gcpro1
, gcpro2
;
5630 int count
= SPECPDL_INDEX ();
5634 if (popup_activated ())
5635 error ("Trying to use a menu from within a menu-entry");
5637 /* Prevent redisplay. */
5638 specbind (Qinhibit_redisplay
, Qt
);
5639 record_unwind_protect (clean_up_dialog
, Qnil
);
5643 GCPRO2(font_param
, font
);
5645 XSETFONT (font
, FRAME_FONT (f
));
5646 font_param
= Ffont_get (font
, intern (":name"));
5647 if (STRINGP (font_param
))
5648 default_name
= xstrdup (SDATA (font_param
));
5651 font_param
= Fframe_parameter (frame
, Qfont_param
);
5652 if (STRINGP (font_param
))
5653 default_name
= xstrdup (SDATA (font_param
));
5656 if (default_name
== NULL
&& x_last_font_name
!= NULL
)
5657 default_name
= xstrdup (x_last_font_name
);
5659 /* Convert fontconfig names to Gtk names, i.e. remove - before number */
5662 char *p
= strrchr (default_name
, '-');
5666 while (isdigit (*ep
))
5668 if (*ep
== '\0') *p
= ' ';
5672 name
= xg_get_font_name (f
, default_name
);
5673 xfree (default_name
);
5677 font
= build_string (name
);
5678 g_free (x_last_font_name
);
5679 x_last_font_name
= name
;
5685 Fsignal (Qquit
, Qnil
);
5687 return unbind_to (count
, font
);
5689 #endif /* HAVE_FREETYPE */
5691 #endif /* USE_GTK */
5694 /***********************************************************************
5696 ***********************************************************************/
5698 #ifdef HAVE_XKBGETKEYBOARD
5699 #include <X11/XKBlib.h>
5700 #include <X11/keysym.h>
5703 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p
,
5704 Sx_backspace_delete_keys_p
, 0, 1, 0,
5705 doc
: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
5706 FRAME nil means use the selected frame.
5707 Value is t if we know that both keys are present, and are mapped to the
5708 usual X keysyms. Value is `lambda' if we cannot determine if both keys are
5709 present and mapped to the usual X keysyms. */)
5713 #ifdef HAVE_XKBGETKEYBOARD
5715 struct frame
*f
= check_x_frame (frame
);
5716 Display
*dpy
= FRAME_X_DISPLAY (f
);
5717 Lisp_Object have_keys
;
5718 int major
, minor
, op
, event
, error
;
5722 /* Check library version in case we're dynamically linked. */
5723 major
= XkbMajorVersion
;
5724 minor
= XkbMinorVersion
;
5725 if (!XkbLibraryVersion (&major
, &minor
))
5731 /* Check that the server supports XKB. */
5732 major
= XkbMajorVersion
;
5733 minor
= XkbMinorVersion
;
5734 if (!XkbQueryExtension (dpy
, &op
, &event
, &error
, &major
, &minor
))
5740 /* In this code we check that the keyboard has physical keys with names
5741 that start with BKSP (Backspace) and DELE (Delete), and that they
5742 generate keysym XK_BackSpace and XK_Delete respectively.
5743 This function is used to test if normal-erase-is-backspace should be
5745 An alternative approach would be to just check if XK_BackSpace and
5746 XK_Delete are mapped to any key. But if any of those are mapped to
5747 some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the
5748 user doesn't know about it, it is better to return false here.
5749 It is more obvious to the user what to do if she/he has two keys
5750 clearly marked with names/symbols and one key does something not
5751 expected (i.e. she/he then tries the other).
5752 The cases where Backspace/Delete is mapped to some other key combination
5753 are rare, and in those cases, normal-erase-is-backspace can be turned on
5757 kb
= XkbGetMap (dpy
, XkbAllMapComponentsMask
, XkbUseCoreKbd
);
5760 int delete_keycode
= 0, backspace_keycode
= 0, i
;
5762 if (XkbGetNames (dpy
, XkbAllNamesMask
, kb
) == Success
)
5764 for (i
= kb
->min_key_code
;
5765 (i
< kb
->max_key_code
5766 && (delete_keycode
== 0 || backspace_keycode
== 0));
5769 /* The XKB symbolic key names can be seen most easily in
5770 the PS file generated by `xkbprint -label name
5772 if (bcmp ("DELE", kb
->names
->keys
[i
].name
, 4) == 0)
5774 else if (bcmp ("BKSP", kb
->names
->keys
[i
].name
, 4) == 0)
5775 backspace_keycode
= i
;
5778 XkbFreeNames (kb
, 0, True
);
5781 XkbFreeClientMap (kb
, 0, True
);
5784 && backspace_keycode
5785 && XKeysymToKeycode (dpy
, XK_Delete
) == delete_keycode
5786 && XKeysymToKeycode (dpy
, XK_BackSpace
) == backspace_keycode
)
5791 #else /* not HAVE_XKBGETKEYBOARD */
5793 #endif /* not HAVE_XKBGETKEYBOARD */
5798 /***********************************************************************
5800 ***********************************************************************/
5802 /* Keep this list in the same order as frame_parms in frame.c.
5803 Use 0 for unsupported frame parameters. */
5805 frame_parm_handler x_frame_parm_handlers
[] =
5809 x_set_background_color
,
5815 x_set_foreground_color
,
5818 x_set_internal_border_width
,
5819 x_set_menu_bar_lines
,
5821 x_explicitly_set_name
,
5822 x_set_scroll_bar_width
,
5825 x_set_vertical_scroll_bars
,
5827 x_set_tool_bar_lines
,
5828 x_set_scroll_bar_foreground
,
5829 x_set_scroll_bar_background
,
5844 /* This is zero if not using X windows. */
5847 /* The section below is built by the lisp expression at the top of the file,
5848 just above where these variables are declared. */
5849 /*&&& init symbols here &&&*/
5850 Qnone
= intern_c_string ("none");
5852 Qsuppress_icon
= intern_c_string ("suppress-icon");
5853 staticpro (&Qsuppress_icon
);
5854 Qundefined_color
= intern_c_string ("undefined-color");
5855 staticpro (&Qundefined_color
);
5856 Qcompound_text
= intern_c_string ("compound-text");
5857 staticpro (&Qcompound_text
);
5858 Qcancel_timer
= intern_c_string ("cancel-timer");
5859 staticpro (&Qcancel_timer
);
5860 Qfont_param
= intern_c_string ("font-parameter");
5861 staticpro (&Qfont_param
);
5862 /* This is the end of symbol initialization. */
5864 /* Text property `display' should be nonsticky by default. */
5865 Vtext_property_default_nonsticky
5866 = Fcons (Fcons (Qdisplay
, Qt
), Vtext_property_default_nonsticky
);
5869 Fput (Qundefined_color
, Qerror_conditions
,
5870 pure_cons (Qundefined_color
, pure_cons (Qerror
, Qnil
)));
5871 Fput (Qundefined_color
, Qerror_message
,
5872 make_pure_c_string ("Undefined color"));
5874 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
5875 doc
: /* The shape of the pointer when over text.
5876 Changing the value does not affect existing frames
5877 unless you set the mouse color. */);
5878 Vx_pointer_shape
= Qnil
;
5880 #if 0 /* This doesn't really do anything. */
5881 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape
,
5882 doc
: /* The shape of the pointer when not over text.
5883 This variable takes effect when you create a new frame
5884 or when you set the mouse color. */);
5886 Vx_nontext_pointer_shape
= Qnil
;
5888 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape
,
5889 doc
: /* The shape of the pointer when Emacs is busy.
5890 This variable takes effect when you create a new frame
5891 or when you set the mouse color. */);
5892 Vx_hourglass_pointer_shape
= Qnil
;
5894 #if 0 /* This doesn't really do anything. */
5895 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape
,
5896 doc
: /* The shape of the pointer when over the mode line.
5897 This variable takes effect when you create a new frame
5898 or when you set the mouse color. */);
5900 Vx_mode_pointer_shape
= Qnil
;
5902 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
5903 &Vx_sensitive_text_pointer_shape
,
5904 doc
: /* The shape of the pointer when over mouse-sensitive text.
5905 This variable takes effect when you create a new frame
5906 or when you set the mouse color. */);
5907 Vx_sensitive_text_pointer_shape
= Qnil
;
5909 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
5910 &Vx_window_horizontal_drag_shape
,
5911 doc
: /* Pointer shape to use for indicating a window can be dragged horizontally.
5912 This variable takes effect when you create a new frame
5913 or when you set the mouse color. */);
5914 Vx_window_horizontal_drag_shape
= Qnil
;
5916 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
5917 doc
: /* A string indicating the foreground color of the cursor box. */);
5918 Vx_cursor_fore_pixel
= Qnil
;
5920 DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size
,
5921 doc
: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).
5922 Text larger than this is clipped. */);
5923 Vx_max_tooltip_size
= Fcons (make_number (80), make_number (40));
5925 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
5926 doc
: /* Non-nil if no X window manager is in use.
5927 Emacs doesn't try to figure this out; this is always nil
5928 unless you set it to something else. */);
5929 /* We don't have any way to find this out, so set it to nil
5930 and maybe the user would like to set it to t. */
5931 Vx_no_window_manager
= Qnil
;
5933 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
5934 &Vx_pixel_size_width_font_regexp
,
5935 doc
: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
5937 Since Emacs gets width of a font matching with this regexp from
5938 PIXEL_SIZE field of the name, font finding mechanism gets faster for
5939 such a font. This is especially effective for such large fonts as
5940 Chinese, Japanese, and Korean. */);
5941 Vx_pixel_size_width_font_regexp
= Qnil
;
5943 /* This is not ifdef:ed, so other builds than GTK can customize it. */
5944 DEFVAR_BOOL ("x-gtk-use-old-file-dialog", &x_gtk_use_old_file_dialog
,
5945 doc
: /* *Non-nil means prompt with the old GTK file selection dialog.
5946 If nil or if the file selection dialog is not available, the new GTK file
5947 chooser is used instead. To turn off all file dialogs set the
5948 variable `use-file-dialog'. */);
5949 x_gtk_use_old_file_dialog
= 0;
5951 DEFVAR_BOOL ("x-gtk-show-hidden-files", &x_gtk_show_hidden_files
,
5952 doc
: /* *If non-nil, the GTK file chooser will by default show hidden files.
5953 Note that this is just the default, there is a toggle button on the file
5954 chooser to show or not show hidden files on a case by case basis. */);
5955 x_gtk_show_hidden_files
= 0;
5957 DEFVAR_BOOL ("x-gtk-file-dialog-help-text", &x_gtk_file_dialog_help_text
,
5958 doc
: /* *If non-nil, the GTK file chooser will show additional help text.
5959 If more space for files in the file chooser dialog is wanted, set this to nil
5960 to turn the additional text off. */);
5961 x_gtk_file_dialog_help_text
= 1;
5963 DEFVAR_BOOL ("x-gtk-whole-detached-tool-bar", &x_gtk_whole_detached_tool_bar
,
5964 doc
: /* *If non-nil, a detached tool bar is shown in full.
5965 The default is to just show an arrow and pressing on that arrow shows
5966 the tool bar buttons. */);
5967 x_gtk_whole_detached_tool_bar
= 0;
5969 Fprovide (intern_c_string ("x"), Qnil
);
5971 #ifdef USE_X_TOOLKIT
5972 Fprovide (intern_c_string ("x-toolkit"), Qnil
);
5974 Fprovide (intern_c_string ("motif"), Qnil
);
5976 DEFVAR_LISP ("motif-version-string", &Vmotif_version_string
,
5977 doc
: /* Version info for LessTif/Motif. */);
5978 Vmotif_version_string
= build_string (XmVERSION_STRING
);
5979 #endif /* USE_MOTIF */
5980 #endif /* USE_X_TOOLKIT */
5983 /* Provide x-toolkit also for GTK. Internally GTK does not use Xt so it
5984 is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
5985 But for a user it is a toolkit for X, and indeed, configure
5986 accepts --with-x-toolkit=gtk. */
5987 Fprovide (intern_c_string ("x-toolkit"), Qnil
);
5988 Fprovide (intern_c_string ("gtk"), Qnil
);
5990 DEFVAR_LISP ("gtk-version-string", &Vgtk_version_string
,
5991 doc
: /* Version info for GTK+. */);
5993 char gtk_version
[40];
5994 g_snprintf (gtk_version
, sizeof (gtk_version
), "%u.%u.%u",
5995 GTK_MAJOR_VERSION
, GTK_MINOR_VERSION
, GTK_MICRO_VERSION
);
5996 Vgtk_version_string
= make_pure_string (gtk_version
, strlen (gtk_version
), strlen (gtk_version
), 0);
5998 #endif /* USE_GTK */
6000 /* X window properties. */
6001 defsubr (&Sx_change_window_property
);
6002 defsubr (&Sx_delete_window_property
);
6003 defsubr (&Sx_window_property
);
6005 defsubr (&Sxw_display_color_p
);
6006 defsubr (&Sx_display_grayscale_p
);
6007 defsubr (&Sxw_color_defined_p
);
6008 defsubr (&Sxw_color_values
);
6009 defsubr (&Sx_server_max_request_size
);
6010 defsubr (&Sx_server_vendor
);
6011 defsubr (&Sx_server_version
);
6012 defsubr (&Sx_display_pixel_width
);
6013 defsubr (&Sx_display_pixel_height
);
6014 defsubr (&Sx_display_mm_width
);
6015 defsubr (&Sx_display_mm_height
);
6016 defsubr (&Sx_display_screens
);
6017 defsubr (&Sx_display_planes
);
6018 defsubr (&Sx_display_color_cells
);
6019 defsubr (&Sx_display_visual_class
);
6020 defsubr (&Sx_display_backing_store
);
6021 defsubr (&Sx_display_save_under
);
6022 defsubr (&Sx_wm_set_size_hint
);
6023 defsubr (&Sx_create_frame
);
6024 defsubr (&Sx_open_connection
);
6025 defsubr (&Sx_close_connection
);
6026 defsubr (&Sx_display_list
);
6027 defsubr (&Sx_synchronize
);
6028 defsubr (&Sx_focus_frame
);
6029 defsubr (&Sx_backspace_delete_keys_p
);
6031 /* Setting callback functions for fontset handler. */
6032 check_window_system_func
= check_x
;
6034 defsubr (&Sx_show_tip
);
6035 defsubr (&Sx_hide_tip
);
6037 staticpro (&tip_timer
);
6039 staticpro (&tip_frame
);
6041 last_show_tip_args
= Qnil
;
6042 staticpro (&last_show_tip_args
);
6044 defsubr (&Sx_uses_old_gtk_dialog
);
6045 #if defined (USE_MOTIF) || defined (USE_GTK)
6046 defsubr (&Sx_file_dialog
);
6049 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
6050 defsubr (&Sx_select_font
);
6051 x_last_font_name
= NULL
;
6055 #endif /* HAVE_X_WINDOWS */
6057 /* arch-tag: 55040d02-5485-4d58-8b22-95a7a05f3288
6058 (do not change this comment) */