1 /* Functions for the X window system.
2 Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
4 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
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"
54 #ifdef USE_FONT_BACKEND
56 #endif /* USE_FONT_BACKEND */
61 #include <sys/types.h>
65 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */
66 #include "bitmaps/gray.xbm"
68 #include <X11/bitmaps/gray>
71 #include "[.bitmaps]gray.xbm"
79 #include <X11/Shell.h>
83 #include <X11/Xaw3d/Paned.h>
84 #include <X11/Xaw3d/Label.h>
85 #else /* !HAVE_XAW3D */
86 #include <X11/Xaw/Paned.h>
87 #include <X11/Xaw/Label.h>
88 #endif /* HAVE_XAW3D */
89 #endif /* USE_MOTIF */
92 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
101 #include "../lwlib/lwlib.h"
105 #include <Xm/DialogS.h>
106 #include <Xm/FileSB.h>
109 /* Do the EDITRES protocol if running X11R5
110 Exception: HP-UX (at least version A.09.05) has X11R5 without EditRes */
112 #if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES)
114 extern void _XEditResCheckMessages ();
115 #endif /* R5 + Athena */
117 /* Unique id counter for widgets created by the Lucid Widget Library. */
119 extern LWLIB_ID widget_id_tick
;
122 /* This is part of a kludge--see lwlib/xlwmenu.c. */
123 extern XFontStruct
*xlwmenu_default_font
;
126 extern void free_frame_menubar ();
127 extern double atof ();
131 /* LessTif/Motif version info. */
133 static Lisp_Object Vmotif_version_string
;
135 #endif /* USE_MOTIF */
137 #endif /* USE_X_TOOLKIT */
141 /* GTK+ version info */
143 static Lisp_Object Vgtk_version_string
;
147 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
149 /* The gray bitmap `bitmaps/gray'. This is done because xterm.c uses
150 it, and including `bitmaps/gray' more than once is a problem when
151 config.h defines `static' as an empty replacement string. */
153 int gray_bitmap_width
= gray_width
;
154 int gray_bitmap_height
= gray_height
;
155 char *gray_bitmap_bits
= gray_bits
;
157 /* Non-zero means we're allowed to display an hourglass cursor. */
159 int display_hourglass_p
;
161 /* Non-zero means prompt with the old GTK file selection dialog. */
163 int x_gtk_use_old_file_dialog
;
165 /* If non-zero, by default show hidden files in the GTK file chooser. */
167 int x_gtk_show_hidden_files
;
169 /* If non-zero, don't show additional help text in the GTK file chooser. */
171 int x_gtk_file_dialog_help_text
;
173 /* If non-zero, don't collapse to tool bar when it is detached. */
175 int x_gtk_whole_detached_tool_bar
;
177 /* The background and shape of the mouse pointer, and shape when not
178 over text or in the modeline. */
180 Lisp_Object Vx_pointer_shape
, Vx_nontext_pointer_shape
, Vx_mode_pointer_shape
;
181 Lisp_Object Vx_hourglass_pointer_shape
;
183 /* The shape when over mouse-sensitive text. */
185 Lisp_Object Vx_sensitive_text_pointer_shape
;
187 /* If non-nil, the pointer shape to indicate that windows can be
188 dragged horizontally. */
190 Lisp_Object Vx_window_horizontal_drag_shape
;
192 /* Color of chars displayed in cursor box. */
194 Lisp_Object Vx_cursor_fore_pixel
;
196 /* Nonzero if using X. */
200 /* Non nil if no window manager is in use. */
202 Lisp_Object Vx_no_window_manager
;
204 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
206 Lisp_Object Vx_pixel_size_width_font_regexp
;
209 Lisp_Object Qsuppress_icon
;
210 Lisp_Object Qundefined_color
;
211 Lisp_Object Qcompound_text
, Qcancel_timer
;
215 extern Lisp_Object Vwindow_system_version
;
217 /* The below are defined in frame.c. */
220 int image_cache_refcount
, dpyinfo_refcount
;
225 /* Error if we are not connected to X. */
231 error ("X windows are not in use or not initialized");
234 /* Nonzero if we can use mouse menus.
235 You should not call this unless HAVE_MENUS is defined. */
243 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
244 and checking validity for X. */
247 check_x_frame (frame
)
253 frame
= selected_frame
;
254 CHECK_LIVE_FRAME (frame
);
257 error ("Non-X frame used");
261 /* Let the user specify an X display with a Lisp object.
262 OBJECT may be nil, a frame or a terminal id.
263 nil stands for the selected frame--or, if that is not an X frame,
264 the first X display on the list. */
266 struct x_display_info
*
267 check_x_display_info (object
)
270 struct x_display_info
*dpyinfo
= NULL
;
274 struct frame
*sf
= XFRAME (selected_frame
);
276 if (FRAME_X_P (sf
) && FRAME_LIVE_P (sf
))
277 dpyinfo
= FRAME_X_DISPLAY_INFO (sf
);
278 else if (x_display_list
!= 0)
279 dpyinfo
= x_display_list
;
281 error ("X windows are not in use or not initialized");
283 else if (INTEGERP (object
))
285 struct terminal
*t
= get_terminal (object
, 1);
287 if (t
->type
!= output_x_window
)
288 error ("Terminal %d is not an X display", XINT (object
));
290 dpyinfo
= t
->display_info
.x
;
292 else if (STRINGP (object
))
293 dpyinfo
= x_display_info_for_name (object
);
296 FRAME_PTR f
= check_x_frame (object
);
297 dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
304 /* Return the Emacs frame-object corresponding to an X window.
305 It could be the frame's main window or an icon window. */
307 /* This function can be called during GC, so use GC_xxx type test macros. */
310 x_window_to_frame (dpyinfo
, wdesc
)
311 struct x_display_info
*dpyinfo
;
314 Lisp_Object tail
, frame
;
317 if (wdesc
== None
) return 0;
319 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
325 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
327 if (f
->output_data
.x
->hourglass_window
== wdesc
)
330 if ((f
->output_data
.x
->edit_widget
331 && XtWindow (f
->output_data
.x
->edit_widget
) == wdesc
)
332 /* A tooltip frame? */
333 || (!f
->output_data
.x
->edit_widget
334 && FRAME_X_WINDOW (f
) == wdesc
)
335 || f
->output_data
.x
->icon_desc
== wdesc
)
337 #else /* not USE_X_TOOLKIT */
339 if (f
->output_data
.x
->edit_widget
)
341 GtkWidget
*gwdesc
= xg_win_to_widget (dpyinfo
->display
, wdesc
);
342 struct x_output
*x
= f
->output_data
.x
;
343 if (gwdesc
!= 0 && gwdesc
== x
->edit_widget
)
347 if (FRAME_X_WINDOW (f
) == wdesc
348 || f
->output_data
.x
->icon_desc
== wdesc
)
350 #endif /* not USE_X_TOOLKIT */
355 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
356 /* Like x_window_to_frame but also compares the window with the widget's
360 x_any_window_to_frame (dpyinfo
, wdesc
)
361 struct x_display_info
*dpyinfo
;
364 Lisp_Object tail
, frame
;
365 struct frame
*f
, *found
;
368 if (wdesc
== None
) return NULL
;
371 for (tail
= Vframe_list
; CONSP (tail
) && !found
; tail
= XCDR (tail
))
378 if (FRAME_X_P (f
) && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
)
380 /* This frame matches if the window is any of its widgets. */
381 x
= f
->output_data
.x
;
382 if (x
->hourglass_window
== wdesc
)
387 GtkWidget
*gwdesc
= xg_win_to_widget (dpyinfo
->display
, wdesc
);
389 && (gwdesc
== x
->widget
390 || gwdesc
== x
->edit_widget
391 || gwdesc
== x
->vbox_widget
392 || gwdesc
== x
->menubar_widget
))
395 if (wdesc
== XtWindow (x
->widget
)
396 || wdesc
== XtWindow (x
->column_widget
)
397 || wdesc
== XtWindow (x
->edit_widget
))
399 /* Match if the window is this frame's menubar. */
400 else if (lw_window_is_in_menubar (wdesc
, x
->menubar_widget
))
404 else if (FRAME_X_WINDOW (f
) == wdesc
)
405 /* A tooltip frame. */
413 /* Likewise, but exclude the menu bar widget. */
416 x_non_menubar_window_to_frame (dpyinfo
, wdesc
)
417 struct x_display_info
*dpyinfo
;
420 Lisp_Object tail
, frame
;
424 if (wdesc
== None
) return 0;
426 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
432 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
434 x
= f
->output_data
.x
;
435 /* This frame matches if the window is any of its widgets. */
436 if (x
->hourglass_window
== wdesc
)
441 GtkWidget
*gwdesc
= xg_win_to_widget (dpyinfo
->display
, wdesc
);
443 && (gwdesc
== x
->widget
444 || gwdesc
== x
->edit_widget
445 || gwdesc
== x
->vbox_widget
))
448 if (wdesc
== XtWindow (x
->widget
)
449 || wdesc
== XtWindow (x
->column_widget
)
450 || wdesc
== XtWindow (x
->edit_widget
))
454 else if (FRAME_X_WINDOW (f
) == wdesc
)
455 /* A tooltip frame. */
461 /* Likewise, but consider only the menu bar widget. */
464 x_menubar_window_to_frame (dpyinfo
, wdesc
)
465 struct x_display_info
*dpyinfo
;
468 Lisp_Object tail
, frame
;
472 if (wdesc
== None
) return 0;
474 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
480 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
482 x
= f
->output_data
.x
;
483 /* Match if the window is this frame's menubar. */
485 if (x
->menubar_widget
)
487 GtkWidget
*gwdesc
= xg_win_to_widget (dpyinfo
->display
, wdesc
);
492 && (gwdesc
== x
->menubar_widget
493 || gtk_widget_get_parent (gwdesc
) == x
->menubar_widget
))
499 if (x
->menubar_widget
500 && lw_window_is_in_menubar (wdesc
, x
->menubar_widget
))
507 /* Return the frame whose principal (outermost) window is WDESC.
508 If WDESC is some other (smaller) window, we return 0. */
511 x_top_window_to_frame (dpyinfo
, wdesc
)
512 struct x_display_info
*dpyinfo
;
515 Lisp_Object tail
, frame
;
519 if (wdesc
== None
) return 0;
521 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
527 if (!FRAME_X_P (f
) || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
529 x
= f
->output_data
.x
;
533 /* This frame matches if the window is its topmost widget. */
535 GtkWidget
*gwdesc
= xg_win_to_widget (dpyinfo
->display
, wdesc
);
536 if (gwdesc
== x
->widget
)
539 if (wdesc
== XtWindow (x
->widget
))
541 #if 0 /* I don't know why it did this,
542 but it seems logically wrong,
543 and it causes trouble for MapNotify events. */
544 /* Match if the window is this frame's menubar. */
545 if (x
->menubar_widget
546 && wdesc
== XtWindow (x
->menubar_widget
))
551 else if (FRAME_X_WINDOW (f
) == wdesc
)
557 #endif /* USE_X_TOOLKIT || USE_GTK */
561 static void x_default_font_parameter
P_ ((struct frame
*, Lisp_Object
));
563 static Lisp_Object unwind_create_frame
P_ ((Lisp_Object
));
564 static Lisp_Object unwind_create_tip_frame
P_ ((Lisp_Object
));
566 void x_set_foreground_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
567 static void x_set_wait_for_wm
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
568 void x_set_background_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
569 void x_set_mouse_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
570 void x_set_cursor_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
571 void x_set_border_color
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
572 void x_set_cursor_type
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
573 void x_set_icon_type
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
574 void x_set_icon_name
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
575 void x_explicitly_set_name
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
576 void x_set_menu_bar_lines
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
577 void x_set_title
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
578 void x_set_tool_bar_lines
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
));
579 void x_set_scroll_bar_foreground
P_ ((struct frame
*, Lisp_Object
,
581 void x_set_scroll_bar_background
P_ ((struct frame
*, Lisp_Object
,
583 static Lisp_Object x_default_scroll_bar_color_parameter
P_ ((struct frame
*,
590 /* Store the screen positions of frame F into XPTR and YPTR.
591 These are the positions of the containing window manager window,
592 not Emacs's own window. */
595 x_real_positions (f
, xptr
, yptr
)
599 int win_x
, win_y
, outer_x
, outer_y
;
600 int real_x
= 0, real_y
= 0;
602 Window win
= f
->output_data
.x
->parent_desc
;
606 x_catch_errors (FRAME_X_DISPLAY (f
));
608 if (win
== FRAME_X_DISPLAY_INFO (f
)->root_window
)
609 win
= FRAME_OUTER_WINDOW (f
);
611 /* This loop traverses up the containment tree until we hit the root
612 window. Window managers may intersect many windows between our window
613 and the root window. The window we find just before the root window
614 should be the outer WM window. */
617 Window wm_window
, rootw
;
618 Window
*tmp_children
;
619 unsigned int tmp_nchildren
;
622 success
= XQueryTree (FRAME_X_DISPLAY (f
), win
, &rootw
,
623 &wm_window
, &tmp_children
, &tmp_nchildren
);
625 had_errors
= x_had_errors_p (FRAME_X_DISPLAY (f
));
627 /* Don't free tmp_children if XQueryTree failed. */
631 XFree ((char *) tmp_children
);
633 if (wm_window
== rootw
|| had_errors
)
644 /* Get the real coordinates for the WM window upper left corner */
645 XGetGeometry (FRAME_X_DISPLAY (f
), win
,
646 &rootw
, &real_x
, &real_y
, &ign
, &ign
, &ign
, &ign
);
648 /* Translate real coordinates to coordinates relative to our
649 window. For our window, the upper left corner is 0, 0.
650 Since the upper left corner of the WM window is outside
651 our window, win_x and win_y will be negative:
653 ------------------ ---> x
655 | ----------------- v y
658 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
660 /* From-window, to-window. */
661 FRAME_X_DISPLAY_INFO (f
)->root_window
,
664 /* From-position, to-position. */
665 real_x
, real_y
, &win_x
, &win_y
,
670 if (FRAME_X_WINDOW (f
) == FRAME_OUTER_WINDOW (f
))
677 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
679 /* From-window, to-window. */
680 FRAME_X_DISPLAY_INFO (f
)->root_window
,
681 FRAME_OUTER_WINDOW (f
),
683 /* From-position, to-position. */
684 real_x
, real_y
, &outer_x
, &outer_y
,
690 had_errors
= x_had_errors_p (FRAME_X_DISPLAY (f
));
697 if (had_errors
) return;
699 f
->x_pixels_diff
= -win_x
;
700 f
->y_pixels_diff
= -win_y
;
702 FRAME_X_OUTPUT (f
)->x_pixels_outer_diff
= -outer_x
;
703 FRAME_X_OUTPUT (f
)->y_pixels_outer_diff
= -outer_y
;
712 /* Gamma-correct COLOR on frame F. */
715 gamma_correct (f
, color
)
721 color
->red
= pow (color
->red
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
722 color
->green
= pow (color
->green
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
723 color
->blue
= pow (color
->blue
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
728 /* Decide if color named COLOR_NAME is valid for use on frame F. If
729 so, return the RGB values in COLOR. If ALLOC_P is non-zero,
730 allocate the color. Value is zero if COLOR_NAME is invalid, or
731 no color could be allocated. */
734 x_defined_color (f
, color_name
, color
, alloc_p
)
741 Display
*dpy
= FRAME_X_DISPLAY (f
);
742 Colormap cmap
= FRAME_X_COLORMAP (f
);
745 success_p
= XParseColor (dpy
, cmap
, color_name
, color
);
746 if (success_p
&& alloc_p
)
747 success_p
= x_alloc_nearest_color (f
, cmap
, color
);
754 /* Return the pixel color value for color COLOR_NAME on frame F. If F
755 is a monochrome frame, return MONO_COLOR regardless of what ARG says.
756 Signal an error if color can't be allocated. */
759 x_decode_color (f
, color_name
, mono_color
)
761 Lisp_Object color_name
;
766 CHECK_STRING (color_name
);
768 #if 0 /* Don't do this. It's wrong when we're not using the default
769 colormap, it makes freeing difficult, and it's probably not
770 an important optimization. */
771 if (strcmp (SDATA (color_name
), "black") == 0)
772 return BLACK_PIX_DEFAULT (f
);
773 else if (strcmp (SDATA (color_name
), "white") == 0)
774 return WHITE_PIX_DEFAULT (f
);
777 /* Return MONO_COLOR for monochrome frames. */
778 if (FRAME_X_DISPLAY_INFO (f
)->n_planes
== 1)
781 /* x_defined_color is responsible for coping with failures
782 by looking for a near-miss. */
783 if (x_defined_color (f
, SDATA (color_name
), &cdef
, 1))
786 signal_error ("Undefined color", color_name
);
791 /* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
792 the previous value of that parameter, NEW_VALUE is the new value.
793 See also the comment of wait_for_wm in struct x_output. */
796 x_set_wait_for_wm (f
, new_value
, old_value
)
798 Lisp_Object new_value
, old_value
;
800 f
->output_data
.x
->wait_for_wm
= !NILP (new_value
);
805 /* Set icon from FILE for frame F. By using GTK functions the icon
806 may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
809 xg_set_icon (f
, file
)
816 found
= x_find_image_file (file
);
822 char *filename
= (char *) SDATA (found
);
825 pixbuf
= gdk_pixbuf_new_from_file (filename
, &err
);
829 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
831 g_object_unref (pixbuf
);
845 xg_set_icon_from_xpm_data (f
, data
)
850 GdkPixbuf
*pixbuf
= gdk_pixbuf_new_from_xpm_data ((const char **) data
);
855 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)), pixbuf
);
856 g_object_unref (pixbuf
);
862 /* Functions called only from `x_set_frame_param'
863 to set individual parameters.
865 If FRAME_X_WINDOW (f) is 0,
866 the frame is being created and its X-window does not exist yet.
867 In that case, just record the parameter's new value
868 in the standard place; do not attempt to change the window. */
871 x_set_foreground_color (f
, arg
, oldval
)
873 Lisp_Object arg
, oldval
;
875 struct x_output
*x
= f
->output_data
.x
;
876 unsigned long fg
, old_fg
;
878 fg
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
879 old_fg
= FRAME_FOREGROUND_PIXEL (f
);
880 FRAME_FOREGROUND_PIXEL (f
) = fg
;
882 if (FRAME_X_WINDOW (f
) != 0)
884 Display
*dpy
= FRAME_X_DISPLAY (f
);
887 XSetForeground (dpy
, x
->normal_gc
, fg
);
888 XSetBackground (dpy
, x
->reverse_gc
, fg
);
890 if (x
->cursor_pixel
== old_fg
)
892 unload_color (f
, x
->cursor_pixel
);
893 x
->cursor_pixel
= x_copy_color (f
, fg
);
894 XSetBackground (dpy
, x
->cursor_gc
, x
->cursor_pixel
);
899 update_face_from_frame_parameter (f
, Qforeground_color
, arg
);
901 if (FRAME_VISIBLE_P (f
))
905 unload_color (f
, old_fg
);
909 x_set_background_color (f
, arg
, oldval
)
911 Lisp_Object arg
, oldval
;
913 struct x_output
*x
= f
->output_data
.x
;
916 bg
= x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
917 unload_color (f
, FRAME_BACKGROUND_PIXEL (f
));
918 FRAME_BACKGROUND_PIXEL (f
) = bg
;
920 if (FRAME_X_WINDOW (f
) != 0)
922 Display
*dpy
= FRAME_X_DISPLAY (f
);
925 XSetBackground (dpy
, x
->normal_gc
, bg
);
926 XSetForeground (dpy
, x
->reverse_gc
, bg
);
927 XSetWindowBackground (dpy
, FRAME_X_WINDOW (f
), bg
);
928 XSetForeground (dpy
, x
->cursor_gc
, bg
);
931 xg_set_background_color (f
, bg
);
934 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
935 toolkit scroll bars. */
938 for (bar
= FRAME_SCROLL_BARS (f
);
940 bar
= XSCROLL_BAR (bar
)->next
)
942 Window window
= XSCROLL_BAR (bar
)->x_window
;
943 XSetWindowBackground (dpy
, window
, bg
);
946 #endif /* USE_TOOLKIT_SCROLL_BARS */
949 update_face_from_frame_parameter (f
, Qbackground_color
, arg
);
951 if (FRAME_VISIBLE_P (f
))
957 x_set_mouse_color (f
, arg
, oldval
)
959 Lisp_Object arg
, oldval
;
961 struct x_output
*x
= f
->output_data
.x
;
962 Display
*dpy
= FRAME_X_DISPLAY (f
);
963 Cursor cursor
, nontext_cursor
, mode_cursor
, hand_cursor
;
964 Cursor hourglass_cursor
, horizontal_drag_cursor
;
965 unsigned long pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
966 unsigned long mask_color
= FRAME_BACKGROUND_PIXEL (f
);
968 /* Don't let pointers be invisible. */
969 if (mask_color
== pixel
)
971 x_free_colors (f
, &pixel
, 1);
972 pixel
= x_copy_color (f
, FRAME_FOREGROUND_PIXEL (f
));
975 unload_color (f
, x
->mouse_pixel
);
976 x
->mouse_pixel
= pixel
;
980 /* It's not okay to crash if the user selects a screwy cursor. */
981 x_catch_errors (dpy
);
983 if (!NILP (Vx_pointer_shape
))
985 CHECK_NUMBER (Vx_pointer_shape
);
986 cursor
= XCreateFontCursor (dpy
, XINT (Vx_pointer_shape
));
989 cursor
= XCreateFontCursor (dpy
, XC_xterm
);
990 x_check_errors (dpy
, "bad text pointer cursor: %s");
992 if (!NILP (Vx_nontext_pointer_shape
))
994 CHECK_NUMBER (Vx_nontext_pointer_shape
);
996 = XCreateFontCursor (dpy
, XINT (Vx_nontext_pointer_shape
));
999 nontext_cursor
= XCreateFontCursor (dpy
, XC_left_ptr
);
1000 x_check_errors (dpy
, "bad nontext pointer cursor: %s");
1002 if (!NILP (Vx_hourglass_pointer_shape
))
1004 CHECK_NUMBER (Vx_hourglass_pointer_shape
);
1006 = XCreateFontCursor (dpy
, XINT (Vx_hourglass_pointer_shape
));
1009 hourglass_cursor
= XCreateFontCursor (dpy
, XC_watch
);
1010 x_check_errors (dpy
, "bad hourglass pointer cursor: %s");
1012 if (!NILP (Vx_mode_pointer_shape
))
1014 CHECK_NUMBER (Vx_mode_pointer_shape
);
1015 mode_cursor
= XCreateFontCursor (dpy
, XINT (Vx_mode_pointer_shape
));
1018 mode_cursor
= XCreateFontCursor (dpy
, XC_xterm
);
1019 x_check_errors (dpy
, "bad modeline pointer cursor: %s");
1021 if (!NILP (Vx_sensitive_text_pointer_shape
))
1023 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
);
1025 = XCreateFontCursor (dpy
, XINT (Vx_sensitive_text_pointer_shape
));
1028 hand_cursor
= XCreateFontCursor (dpy
, XC_hand2
);
1030 if (!NILP (Vx_window_horizontal_drag_shape
))
1032 CHECK_NUMBER (Vx_window_horizontal_drag_shape
);
1033 horizontal_drag_cursor
1034 = XCreateFontCursor (dpy
, XINT (Vx_window_horizontal_drag_shape
));
1037 horizontal_drag_cursor
1038 = XCreateFontCursor (dpy
, XC_sb_h_double_arrow
);
1040 /* Check and report errors with the above calls. */
1041 x_check_errors (dpy
, "can't set cursor shape: %s");
1042 x_uncatch_errors ();
1045 XColor fore_color
, back_color
;
1047 fore_color
.pixel
= x
->mouse_pixel
;
1048 x_query_color (f
, &fore_color
);
1049 back_color
.pixel
= mask_color
;
1050 x_query_color (f
, &back_color
);
1052 XRecolorCursor (dpy
, cursor
, &fore_color
, &back_color
);
1053 XRecolorCursor (dpy
, nontext_cursor
, &fore_color
, &back_color
);
1054 XRecolorCursor (dpy
, mode_cursor
, &fore_color
, &back_color
);
1055 XRecolorCursor (dpy
, hand_cursor
, &fore_color
, &back_color
);
1056 XRecolorCursor (dpy
, hourglass_cursor
, &fore_color
, &back_color
);
1057 XRecolorCursor (dpy
, horizontal_drag_cursor
, &fore_color
, &back_color
);
1060 if (FRAME_X_WINDOW (f
) != 0)
1061 XDefineCursor (dpy
, FRAME_X_WINDOW (f
), cursor
);
1063 if (cursor
!= x
->text_cursor
1064 && x
->text_cursor
!= 0)
1065 XFreeCursor (dpy
, x
->text_cursor
);
1066 x
->text_cursor
= cursor
;
1068 if (nontext_cursor
!= x
->nontext_cursor
1069 && x
->nontext_cursor
!= 0)
1070 XFreeCursor (dpy
, x
->nontext_cursor
);
1071 x
->nontext_cursor
= nontext_cursor
;
1073 if (hourglass_cursor
!= x
->hourglass_cursor
1074 && x
->hourglass_cursor
!= 0)
1075 XFreeCursor (dpy
, x
->hourglass_cursor
);
1076 x
->hourglass_cursor
= hourglass_cursor
;
1078 if (mode_cursor
!= x
->modeline_cursor
1079 && x
->modeline_cursor
!= 0)
1080 XFreeCursor (dpy
, f
->output_data
.x
->modeline_cursor
);
1081 x
->modeline_cursor
= mode_cursor
;
1083 if (hand_cursor
!= x
->hand_cursor
1084 && x
->hand_cursor
!= 0)
1085 XFreeCursor (dpy
, x
->hand_cursor
);
1086 x
->hand_cursor
= hand_cursor
;
1088 if (horizontal_drag_cursor
!= x
->horizontal_drag_cursor
1089 && x
->horizontal_drag_cursor
!= 0)
1090 XFreeCursor (dpy
, x
->horizontal_drag_cursor
);
1091 x
->horizontal_drag_cursor
= horizontal_drag_cursor
;
1096 update_face_from_frame_parameter (f
, Qmouse_color
, arg
);
1100 x_set_cursor_color (f
, arg
, oldval
)
1102 Lisp_Object arg
, oldval
;
1104 unsigned long fore_pixel
, pixel
;
1105 int fore_pixel_allocated_p
= 0, pixel_allocated_p
= 0;
1106 struct x_output
*x
= f
->output_data
.x
;
1108 if (!NILP (Vx_cursor_fore_pixel
))
1110 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
1111 WHITE_PIX_DEFAULT (f
));
1112 fore_pixel_allocated_p
= 1;
1115 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
1117 pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1118 pixel_allocated_p
= 1;
1120 /* Make sure that the cursor color differs from the background color. */
1121 if (pixel
== FRAME_BACKGROUND_PIXEL (f
))
1123 if (pixel_allocated_p
)
1125 x_free_colors (f
, &pixel
, 1);
1126 pixel_allocated_p
= 0;
1129 pixel
= x
->mouse_pixel
;
1130 if (pixel
== fore_pixel
)
1132 if (fore_pixel_allocated_p
)
1134 x_free_colors (f
, &fore_pixel
, 1);
1135 fore_pixel_allocated_p
= 0;
1137 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
1141 unload_color (f
, x
->cursor_foreground_pixel
);
1142 if (!fore_pixel_allocated_p
)
1143 fore_pixel
= x_copy_color (f
, fore_pixel
);
1144 x
->cursor_foreground_pixel
= fore_pixel
;
1146 unload_color (f
, x
->cursor_pixel
);
1147 if (!pixel_allocated_p
)
1148 pixel
= x_copy_color (f
, pixel
);
1149 x
->cursor_pixel
= pixel
;
1151 if (FRAME_X_WINDOW (f
) != 0)
1154 XSetBackground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, x
->cursor_pixel
);
1155 XSetForeground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, fore_pixel
);
1158 if (FRAME_VISIBLE_P (f
))
1160 x_update_cursor (f
, 0);
1161 x_update_cursor (f
, 1);
1165 update_face_from_frame_parameter (f
, Qcursor_color
, arg
);
1168 /* Set the border-color of frame F to pixel value PIX.
1169 Note that this does not fully take effect if done before
1170 F has an x-window. */
1173 x_set_border_pixel (f
, pix
)
1177 unload_color (f
, f
->output_data
.x
->border_pixel
);
1178 f
->output_data
.x
->border_pixel
= pix
;
1180 if (FRAME_X_WINDOW (f
) != 0 && f
->border_width
> 0)
1183 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1184 (unsigned long)pix
);
1187 if (FRAME_VISIBLE_P (f
))
1192 /* Set the border-color of frame F to value described by ARG.
1193 ARG can be a string naming a color.
1194 The border-color is used for the border that is drawn by the X server.
1195 Note that this does not fully take effect if done before
1196 F has an x-window; it must be redone when the window is created.
1198 Note: this is done in two routines because of the way X10 works.
1200 Note: under X11, this is normally the province of the window manager,
1201 and so emacs' border colors may be overridden. */
1204 x_set_border_color (f
, arg
, oldval
)
1206 Lisp_Object arg
, oldval
;
1211 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1212 x_set_border_pixel (f
, pix
);
1213 update_face_from_frame_parameter (f
, Qborder_color
, arg
);
1218 x_set_cursor_type (f
, arg
, oldval
)
1220 Lisp_Object arg
, oldval
;
1222 set_frame_cursor_types (f
, arg
);
1224 /* Make sure the cursor gets redrawn. */
1225 cursor_type_changed
= 1;
1229 x_set_icon_type (f
, arg
, oldval
)
1231 Lisp_Object arg
, oldval
;
1237 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1240 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1245 result
= x_text_icon (f
,
1246 (char *) SDATA ((!NILP (f
->icon_name
)
1250 result
= x_bitmap_icon (f
, arg
);
1255 error ("No icon window available");
1258 XFlush (FRAME_X_DISPLAY (f
));
1263 x_set_icon_name (f
, arg
, oldval
)
1265 Lisp_Object arg
, oldval
;
1271 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1274 else if (!NILP (arg
) || NILP (oldval
))
1279 if (f
->output_data
.x
->icon_bitmap
!= 0)
1284 result
= x_text_icon (f
,
1285 (char *) SDATA ((!NILP (f
->icon_name
)
1294 error ("No icon window available");
1297 XFlush (FRAME_X_DISPLAY (f
));
1303 x_set_menu_bar_lines (f
, value
, oldval
)
1305 Lisp_Object value
, oldval
;
1308 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
1309 int olines
= FRAME_MENU_BAR_LINES (f
);
1312 /* Right now, menu bars don't work properly in minibuf-only frames;
1313 most of the commands try to apply themselves to the minibuffer
1314 frame itself, and get an error because you can't switch buffers
1315 in or split the minibuffer window. */
1316 if (FRAME_MINIBUF_ONLY_P (f
))
1319 if (INTEGERP (value
))
1320 nlines
= XINT (value
);
1324 /* Make sure we redisplay all windows in this frame. */
1325 windows_or_buffers_changed
++;
1327 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1328 FRAME_MENU_BAR_LINES (f
) = 0;
1331 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
1332 if (FRAME_X_P (f
) && f
->output_data
.x
->menubar_widget
== 0)
1333 /* Make sure next redisplay shows the menu bar. */
1334 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= Qt
;
1338 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
1339 free_frame_menubar (f
);
1340 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
1342 f
->output_data
.x
->menubar_widget
= 0;
1344 #else /* not USE_X_TOOLKIT && not USE_GTK */
1345 FRAME_MENU_BAR_LINES (f
) = nlines
;
1346 change_window_heights (f
->root_window
, nlines
- olines
);
1347 #endif /* not USE_X_TOOLKIT */
1352 /* Set the number of lines used for the tool bar of frame F to VALUE.
1353 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1354 is the old number of tool bar lines. This function changes the
1355 height of all windows on frame F to match the new tool bar height.
1356 The frame's height doesn't change. */
1359 x_set_tool_bar_lines (f
, value
, oldval
)
1361 Lisp_Object value
, oldval
;
1363 int delta
, nlines
, root_height
;
1364 Lisp_Object root_window
;
1366 /* Treat tool bars like menu bars. */
1367 if (FRAME_MINIBUF_ONLY_P (f
))
1370 /* Use VALUE only if an integer >= 0. */
1371 if (INTEGERP (value
) && XINT (value
) >= 0)
1372 nlines
= XFASTINT (value
);
1377 FRAME_TOOL_BAR_LINES (f
) = 0;
1380 FRAME_EXTERNAL_TOOL_BAR (f
) = 1;
1381 if (FRAME_X_P (f
) && f
->output_data
.x
->toolbar_widget
== 0)
1382 /* Make sure next redisplay shows the tool bar. */
1383 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= Qt
;
1384 update_frame_tool_bar (f
);
1388 if (FRAME_EXTERNAL_TOOL_BAR (f
))
1389 free_frame_tool_bar (f
);
1390 FRAME_EXTERNAL_TOOL_BAR (f
) = 0;
1396 /* Make sure we redisplay all windows in this frame. */
1397 ++windows_or_buffers_changed
;
1399 delta
= nlines
- FRAME_TOOL_BAR_LINES (f
);
1401 /* Don't resize the tool-bar to more than we have room for. */
1402 root_window
= FRAME_ROOT_WINDOW (f
);
1403 root_height
= WINDOW_TOTAL_LINES (XWINDOW (root_window
));
1404 if (root_height
- delta
< 1)
1406 delta
= root_height
- 1;
1407 nlines
= FRAME_TOOL_BAR_LINES (f
) + delta
;
1410 FRAME_TOOL_BAR_LINES (f
) = nlines
;
1411 change_window_heights (root_window
, delta
);
1414 /* We also have to make sure that the internal border at the top of
1415 the frame, below the menu bar or tool bar, is redrawn when the
1416 tool bar disappears. This is so because the internal border is
1417 below the tool bar if one is displayed, but is below the menu bar
1418 if there isn't a tool bar. The tool bar draws into the area
1419 below the menu bar. */
1420 if (FRAME_X_WINDOW (f
) && FRAME_TOOL_BAR_LINES (f
) == 0)
1423 clear_current_matrices (f
);
1426 /* If the tool bar gets smaller, the internal border below it
1427 has to be cleared. It was formerly part of the display
1428 of the larger tool bar, and updating windows won't clear it. */
1431 int height
= FRAME_INTERNAL_BORDER_WIDTH (f
);
1432 int width
= FRAME_PIXEL_WIDTH (f
);
1433 int y
= nlines
* FRAME_LINE_HEIGHT (f
);
1435 /* height can be zero here. */
1436 if (height
> 0 && width
> 0)
1439 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1440 0, y
, width
, height
, False
);
1444 if (WINDOWP (f
->tool_bar_window
))
1445 clear_glyph_matrix (XWINDOW (f
->tool_bar_window
)->current_matrix
);
1450 /* Set the foreground color for scroll bars on frame F to VALUE.
1451 VALUE should be a string, a color name. If it isn't a string or
1452 isn't a valid color name, do nothing. OLDVAL is the old value of
1453 the frame parameter. */
1456 x_set_scroll_bar_foreground (f
, value
, oldval
)
1458 Lisp_Object value
, oldval
;
1460 unsigned long pixel
;
1462 if (STRINGP (value
))
1463 pixel
= x_decode_color (f
, value
, BLACK_PIX_DEFAULT (f
));
1467 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
1468 unload_color (f
, f
->output_data
.x
->scroll_bar_foreground_pixel
);
1470 f
->output_data
.x
->scroll_bar_foreground_pixel
= pixel
;
1471 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1473 /* Remove all scroll bars because they have wrong colors. */
1474 if (FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
)
1475 (*FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
) (f
);
1476 if (FRAME_TERMINAL (f
)->judge_scroll_bars_hook
)
1477 (*FRAME_TERMINAL (f
)->judge_scroll_bars_hook
) (f
);
1479 update_face_from_frame_parameter (f
, Qscroll_bar_foreground
, value
);
1485 /* Set the background color for scroll bars on frame F to VALUE VALUE
1486 should be a string, a color name. If it isn't a string or isn't a
1487 valid color name, do nothing. OLDVAL is the old value of the frame
1491 x_set_scroll_bar_background (f
, value
, oldval
)
1493 Lisp_Object value
, oldval
;
1495 unsigned long pixel
;
1497 if (STRINGP (value
))
1498 pixel
= x_decode_color (f
, value
, WHITE_PIX_DEFAULT (f
));
1502 if (f
->output_data
.x
->scroll_bar_background_pixel
!= -1)
1503 unload_color (f
, f
->output_data
.x
->scroll_bar_background_pixel
);
1505 #ifdef USE_TOOLKIT_SCROLL_BARS
1506 /* Scrollbar shadow colors. */
1507 if (f
->output_data
.x
->scroll_bar_top_shadow_pixel
!= -1)
1509 unload_color (f
, f
->output_data
.x
->scroll_bar_top_shadow_pixel
);
1510 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
1512 if (f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
!= -1)
1514 unload_color (f
, f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
);
1515 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
1517 #endif /* USE_TOOLKIT_SCROLL_BARS */
1519 f
->output_data
.x
->scroll_bar_background_pixel
= pixel
;
1520 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1522 /* Remove all scroll bars because they have wrong colors. */
1523 if (FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
)
1524 (*FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
) (f
);
1525 if (FRAME_TERMINAL (f
)->judge_scroll_bars_hook
)
1526 (*FRAME_TERMINAL (f
)->judge_scroll_bars_hook
) (f
);
1528 update_face_from_frame_parameter (f
, Qscroll_bar_background
, value
);
1534 /* Encode Lisp string STRING as a text in a format appropriate for
1535 XICCC (X Inter Client Communication Conventions).
1537 This can call Lisp code, so callers must GCPRO.
1539 If STRING contains only ASCII characters, do no conversion and
1540 return the string data of STRING. Otherwise, encode the text by
1541 CODING_SYSTEM, and return a newly allocated memory area which
1542 should be freed by `xfree' by a caller.
1544 SELECTIONP non-zero means the string is being encoded for an X
1545 selection, so it is safe to run pre-write conversions (which
1548 Store the byte length of resulting text in *TEXT_BYTES.
1550 If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
1551 which means that the `encoding' of the result can be `STRING'.
1552 Otherwise store 0 in *STRINGP, which means that the `encoding' of
1553 the result should be `COMPOUND_TEXT'. */
1555 static unsigned char *
1556 x_encode_text (string
, coding_system
, selectionp
, text_bytes
, stringp
, freep
)
1557 Lisp_Object string
, coding_system
;
1558 int *text_bytes
, *stringp
;
1562 int result
= string_xstring_p (string
);
1563 struct coding_system coding
;
1567 /* No multibyte character in OBJ. We need not encode it. */
1568 *text_bytes
= SBYTES (string
);
1571 return SDATA (string
);
1574 setup_coding_system (coding_system
, &coding
);
1575 coding
.mode
|= (CODING_MODE_SAFE_ENCODING
| CODING_MODE_LAST_BLOCK
);
1576 /* We suppress producing escape sequences for composition. */
1577 coding
.common_flags
&= ~CODING_ANNOTATION_MASK
;
1578 coding
.dst_bytes
= SCHARS (string
) * 2;
1579 coding
.destination
= (unsigned char *) xmalloc (coding
.dst_bytes
);
1580 encode_coding_object (&coding
, string
, 0, 0,
1581 SCHARS (string
), SBYTES (string
), Qnil
);
1582 *text_bytes
= coding
.produced
;
1583 *stringp
= (result
== 1 || !EQ (coding_system
, Qcompound_text
));
1585 return coding
.destination
;
1589 /* Set the WM name to NAME for frame F. Also set the icon name.
1590 If the frame already has an icon name, use that, otherwise set the
1591 icon name to NAME. */
1594 x_set_name_internal (f
, name
)
1598 if (FRAME_X_WINDOW (f
))
1602 XTextProperty text
, icon
;
1604 int do_free_icon_value
= 0, do_free_text_value
= 0;
1605 Lisp_Object coding_system
;
1607 Lisp_Object encoded_name
;
1608 struct gcpro gcpro1
;
1610 /* As ENCODE_UTF_8 may cause GC and relocation of string data,
1611 we use it before x_encode_text that may return string data. */
1613 encoded_name
= ENCODE_UTF_8 (name
);
1617 coding_system
= Qcompound_text
;
1618 /* Note: Encoding strategy
1620 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1621 text.encoding. But, there are non-internationalized window
1622 managers which don't support that encoding. So, if NAME
1623 contains only ASCII and 8859-1 characters, encode it by
1624 iso-latin-1, and use "STRING" in text.encoding hoping that
1625 such window managers at least analyze this format correctly,
1626 i.e. treat 8-bit bytes as 8859-1 characters.
1628 We may also be able to use "UTF8_STRING" in text.encoding
1629 in the future which can encode all Unicode characters.
1630 But, for the moment, there's no way to know that the
1631 current window manager supports it or not. */
1632 text
.value
= x_encode_text (name
, coding_system
, 0, &bytes
, &stringp
,
1633 &do_free_text_value
);
1634 text
.encoding
= (stringp
? XA_STRING
1635 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1637 text
.nitems
= bytes
;
1639 if (!STRINGP (f
->icon_name
))
1645 /* See the above comment "Note: Encoding strategy". */
1646 icon
.value
= x_encode_text (f
->icon_name
, coding_system
, 0,
1647 &bytes
, &stringp
, &do_free_icon_value
);
1648 icon
.encoding
= (stringp
? XA_STRING
1649 : FRAME_X_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1651 icon
.nitems
= bytes
;
1655 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
1656 (char *) SDATA (encoded_name
));
1657 #else /* not USE_GTK */
1658 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &text
);
1659 #endif /* not USE_GTK */
1661 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &icon
);
1663 if (do_free_icon_value
)
1665 if (do_free_text_value
)
1672 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1675 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1676 name; if NAME is a string, set F's name to NAME and set
1677 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1679 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1680 suggesting a new name, which lisp code should override; if
1681 F->explicit_name is set, ignore the new name; otherwise, set it. */
1684 x_set_name (f
, name
, explicit)
1689 /* Make sure that requests from lisp code override requests from
1690 Emacs redisplay code. */
1693 /* If we're switching from explicit to implicit, we had better
1694 update the mode lines and thereby update the title. */
1695 if (f
->explicit_name
&& NILP (name
))
1696 update_mode_lines
= 1;
1698 f
->explicit_name
= ! NILP (name
);
1700 else if (f
->explicit_name
)
1703 /* If NAME is nil, set the name to the x_id_name. */
1706 /* Check for no change needed in this very common case
1707 before we do any consing. */
1708 if (!strcmp (FRAME_X_DISPLAY_INFO (f
)->x_id_name
,
1711 name
= build_string (FRAME_X_DISPLAY_INFO (f
)->x_id_name
);
1714 CHECK_STRING (name
);
1716 /* Don't change the name if it's already NAME. */
1717 if (! NILP (Fstring_equal (name
, f
->name
)))
1722 /* For setting the frame title, the title parameter should override
1723 the name parameter. */
1724 if (! NILP (f
->title
))
1727 x_set_name_internal (f
, name
);
1730 /* This function should be called when the user's lisp code has
1731 specified a name for the frame; the name will override any set by the
1734 x_explicitly_set_name (f
, arg
, oldval
)
1736 Lisp_Object arg
, oldval
;
1738 x_set_name (f
, arg
, 1);
1741 /* This function should be called by Emacs redisplay code to set the
1742 name; names set this way will never override names set by the user's
1745 x_implicitly_set_name (f
, arg
, oldval
)
1747 Lisp_Object arg
, oldval
;
1749 x_set_name (f
, arg
, 0);
1752 /* Change the title of frame F to NAME.
1753 If NAME is nil, use the frame name as the title. */
1756 x_set_title (f
, name
, old_name
)
1758 Lisp_Object name
, old_name
;
1760 /* Don't change the title if it's already NAME. */
1761 if (EQ (name
, f
->title
))
1764 update_mode_lines
= 1;
1771 CHECK_STRING (name
);
1773 x_set_name_internal (f
, name
);
1777 x_set_scroll_bar_default_width (f
)
1780 int wid
= FRAME_COLUMN_WIDTH (f
);
1782 #ifdef USE_TOOLKIT_SCROLL_BARS
1783 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
1784 int width
= 16 + 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
1785 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (width
+ wid
- 1) / wid
;
1786 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = width
;
1788 /* Make the actual width at least 14 pixels and a multiple of a
1790 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
1792 /* Use all of that space (aside from required margins) for the
1794 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = 0;
1799 /* Record in frame F the specified or default value according to ALIST
1800 of the parameter named PROP (a Lisp symbol). If no value is
1801 specified for PROP, look for an X default for XPROP on the frame
1802 named NAME. If that is not found either, use the value DEFLT. */
1805 x_default_scroll_bar_color_parameter (f
, alist
, prop
, xprop
, xclass
,
1814 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
1817 tem
= x_get_arg (dpyinfo
, alist
, prop
, xprop
, xclass
, RES_TYPE_STRING
);
1818 if (EQ (tem
, Qunbound
))
1820 #ifdef USE_TOOLKIT_SCROLL_BARS
1822 /* See if an X resource for the scroll bar color has been
1824 tem
= display_x_get_resource (dpyinfo
,
1825 build_string (foreground_p
1828 empty_unibyte_string
,
1829 build_string ("verticalScrollBar"),
1830 empty_unibyte_string
);
1833 /* If nothing has been specified, scroll bars will use a
1834 toolkit-dependent default. Because these defaults are
1835 difficult to get at without actually creating a scroll
1836 bar, use nil to indicate that no color has been
1841 #else /* not USE_TOOLKIT_SCROLL_BARS */
1845 #endif /* not USE_TOOLKIT_SCROLL_BARS */
1848 x_set_frame_parameters (f
, Fcons (Fcons (prop
, tem
), Qnil
));
1855 #ifdef USE_X_TOOLKIT
1857 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
1858 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
1859 already be present because of the toolkit (Motif adds some of them,
1860 for example, but Xt doesn't). */
1863 hack_wm_protocols (f
, widget
)
1867 Display
*dpy
= XtDisplay (widget
);
1868 Window w
= XtWindow (widget
);
1869 int need_delete
= 1;
1876 unsigned char *catoms
;
1878 unsigned long nitems
= 0;
1879 unsigned long bytes_after
;
1881 if ((XGetWindowProperty (dpy
, w
,
1882 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
1883 (long)0, (long)100, False
, XA_ATOM
,
1884 &type
, &format
, &nitems
, &bytes_after
,
1887 && format
== 32 && type
== XA_ATOM
)
1889 Atom
*atoms
= (Atom
*) catoms
;
1894 == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
)
1896 else if (atoms
[nitems
]
1897 == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
)
1899 else if (atoms
[nitems
]
1900 == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
)
1911 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
1913 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
;
1915 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
1917 XChangeProperty (dpy
, w
, FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
1918 XA_ATOM
, 32, PropModeAppend
,
1919 (unsigned char *) props
, count
);
1927 /* Support routines for XIC (X Input Context). */
1931 static XFontSet xic_create_xfontset
P_ ((struct frame
*, char *));
1932 static XFontSet xic_create_xfontset2
P_ ((struct frame
*));
1933 static XIMStyle best_xim_style
P_ ((XIMStyles
*, XIMStyles
*));
1936 /* Supported XIM styles, ordered by preference. */
1938 static XIMStyle supported_xim_styles
[] =
1940 XIMPreeditPosition
| XIMStatusArea
,
1941 XIMPreeditPosition
| XIMStatusNothing
,
1942 XIMPreeditPosition
| XIMStatusNone
,
1943 XIMPreeditNothing
| XIMStatusArea
,
1944 XIMPreeditNothing
| XIMStatusNothing
,
1945 XIMPreeditNothing
| XIMStatusNone
,
1946 XIMPreeditNone
| XIMStatusArea
,
1947 XIMPreeditNone
| XIMStatusNothing
,
1948 XIMPreeditNone
| XIMStatusNone
,
1953 /* Create an X fontset on frame F with base font name BASE_FONTNAME. */
1955 char xic_defaut_fontset
[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
1957 /* Create an Xt fontset spec from the name of a base font.
1958 If `motif' is True use the Motif syntax. */
1960 xic_create_fontsetname (base_fontname
, motif
)
1961 char *base_fontname
;
1964 const char *sep
= motif
? ";" : ",";
1967 /* Make a fontset name from the base font name. */
1968 if (xic_defaut_fontset
== base_fontname
)
1969 { /* There is no base font name, use the default. */
1970 int len
= strlen (base_fontname
) + 2;
1971 fontsetname
= xmalloc (len
);
1972 bzero (fontsetname
, len
);
1973 strcpy (fontsetname
, base_fontname
);
1977 /* Make a fontset name from the base font name.
1978 The font set will be made of the following elements:
1980 - the base font where the charset spec is replaced by -*-*.
1981 - the same but with the family also replaced with -*-*-. */
1982 char *p
= base_fontname
;
1985 for (i
= 0; *p
; p
++)
1988 { /* As the font name doesn't conform to XLFD, we can't
1989 modify it to generalize it to allcs and allfamilies.
1990 Use the specified font plus the default. */
1991 int len
= strlen (base_fontname
) + strlen (xic_defaut_fontset
) + 3;
1992 fontsetname
= xmalloc (len
);
1993 bzero (fontsetname
, len
);
1994 strcpy (fontsetname
, base_fontname
);
1995 strcat (fontsetname
, sep
);
1996 strcat (fontsetname
, xic_defaut_fontset
);
2001 char *p1
= NULL
, *p2
= NULL
, *p3
= NULL
;
2002 char *font_allcs
= NULL
;
2003 char *font_allfamilies
= NULL
;
2004 char *font_all
= NULL
;
2005 char *allcs
= "*-*-*-*-*-*-*";
2006 char *allfamilies
= "-*-*-";
2007 char *all
= "*-*-*-*-";
2010 for (i
= 0, p
= base_fontname
; i
< 8; p
++)
2023 /* If base_fontname specifies ADSTYLE, make it a
2027 int diff
= (p2
- p3
) - 2;
2029 base
= alloca (strlen (base_fontname
) + 1);
2030 bcopy (base_fontname
, base
, p3
- base_fontname
);
2031 base
[p3
- base_fontname
] = '*';
2032 base
[(p3
- base_fontname
) + 1] = '-';
2033 strcpy (base
+ (p3
- base_fontname
) + 2, p2
);
2034 p
= base
+ (p
- base_fontname
) - diff
;
2035 p1
= base
+ (p1
- base_fontname
);
2036 p2
= base
+ (p2
- base_fontname
) - diff
;
2037 base_fontname
= base
;
2040 /* Build the font spec that matches all charsets. */
2041 len
= p
- base_fontname
+ strlen (allcs
) + 1;
2042 font_allcs
= (char *) alloca (len
);
2043 bzero (font_allcs
, len
);
2044 bcopy (base_fontname
, font_allcs
, p
- base_fontname
);
2045 strcat (font_allcs
, allcs
);
2047 /* Build the font spec that matches all families and
2049 len
= p
- p1
+ strlen (allcs
) + strlen (allfamilies
) + 1;
2050 font_allfamilies
= (char *) alloca (len
);
2051 bzero (font_allfamilies
, len
);
2052 strcpy (font_allfamilies
, allfamilies
);
2053 bcopy (p1
, font_allfamilies
+ strlen (allfamilies
), p
- p1
);
2054 strcat (font_allfamilies
, allcs
);
2056 /* Build the font spec that matches all. */
2057 len
= p
- p2
+ strlen (allcs
) + strlen (all
) + strlen (allfamilies
) + 1;
2058 font_all
= (char *) alloca (len
);
2059 bzero (font_all
, len
);
2060 strcpy (font_all
, allfamilies
);
2061 strcat (font_all
, all
);
2062 bcopy (p2
, font_all
+ strlen (all
) + strlen (allfamilies
), p
- p2
);
2063 strcat (font_all
, allcs
);
2065 /* Build the actual font set name. */
2066 len
= strlen (base_fontname
) + strlen (font_allcs
)
2067 + strlen (font_allfamilies
) + strlen (font_all
) + 5;
2068 fontsetname
= xmalloc (len
);
2069 bzero (fontsetname
, len
);
2070 strcpy (fontsetname
, base_fontname
);
2071 strcat (fontsetname
, sep
);
2072 strcat (fontsetname
, font_allcs
);
2073 strcat (fontsetname
, sep
);
2074 strcat (fontsetname
, font_allfamilies
);
2075 strcat (fontsetname
, sep
);
2076 strcat (fontsetname
, font_all
);
2080 strcat (fontsetname
, ":");
2084 #ifdef DEBUG_XIC_FONTSET
2086 print_fontset_result (xfs
, name
, missing_list
, missing_count
)
2089 char **missing_list
;
2093 fprintf (stderr
, "XIC Fontset created: %s\n", name
);
2096 fprintf (stderr
, "XIC Fontset failed: %s\n", name
);
2097 while (missing_count
-- > 0)
2099 fprintf (stderr
, " missing: %s\n", *missing_list
);
2108 xic_create_xfontset (f
, base_fontname
)
2110 char *base_fontname
;
2112 XFontSet xfs
= NULL
;
2113 char **missing_list
= NULL
;
2116 Lisp_Object rest
, frame
;
2119 base_fontname
= xic_defaut_fontset
;
2121 /* See if there is another frame already using same fontset. */
2122 FOR_EACH_FRAME (rest
, frame
)
2124 struct frame
*cf
= XFRAME (frame
);
2125 if (cf
!= f
&& FRAME_LIVE_P (f
) && FRAME_X_P (cf
)
2126 && FRAME_X_DISPLAY_INFO (cf
) == FRAME_X_DISPLAY_INFO (f
)
2127 && FRAME_XIC_BASE_FONTNAME (cf
)
2128 && !strcmp (FRAME_XIC_BASE_FONTNAME (cf
), base_fontname
))
2130 xfs
= FRAME_XIC_FONTSET (cf
);
2137 char *fontsetname
= xic_create_fontsetname (base_fontname
, False
);
2140 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
),
2141 fontsetname
, &missing_list
,
2142 &missing_count
, &def_string
);
2143 #ifdef DEBUG_XIC_FONTSET
2144 print_fontset_result (xfs
, fontsetname
, missing_list
, missing_count
);
2147 XFreeStringList (missing_list
);
2150 /* FONTSETNAME contains a list of font names (specific fonts
2151 first, general fonts last), but giving that to
2152 XCreateFontSet at once occasionally fails (bug of X?).
2153 So, we try to call XCreateFontSet for each fontname. */
2154 char *p0
= fontsetname
, *p1
;
2158 p1
= strchr (p0
, ',');
2161 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
),
2163 &missing_count
, &def_string
);
2164 #ifdef DEBUG_XIC_FONTSET
2165 print_fontset_result (xfs
, p0
, missing_list
, missing_count
);
2168 XFreeStringList (missing_list
);
2171 p0
= p1
? p1
+ 1 : NULL
;
2174 xfree (fontsetname
);
2175 if (! xfs
&& base_fontname
!= xic_defaut_fontset
)
2177 /* Try the default fontset name at a last resort. */
2178 fontsetname
= xic_create_fontsetname (xic_defaut_fontset
, False
);
2179 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
),
2180 fontsetname
, &missing_list
,
2181 &missing_count
, &def_string
);
2182 #ifdef DEBUG_XIC_FONTSET
2183 print_fontset_result (xfs
, fontsetname
, missing_list
, missing_count
);
2186 XFreeStringList (missing_list
);
2187 xfree (fontsetname
);
2191 if (FRAME_XIC_BASE_FONTNAME (f
))
2192 xfree (FRAME_XIC_BASE_FONTNAME (f
));
2193 FRAME_XIC_BASE_FONTNAME (f
) = xstrdup (base_fontname
);
2195 /* No need to free def_string. */
2199 #ifdef USE_FONT_BACKEND
2202 xic_create_xfontset2 (f
)
2205 XFontSet xfs
= NULL
;
2206 struct font
*font
= FRAME_FONT_OBJECT (f
);
2207 int pixel_size
= font
->pixel_size
;
2208 Lisp_Object rest
, frame
;
2210 /* See if there is another frame already using same fontset. */
2211 FOR_EACH_FRAME (rest
, frame
)
2213 struct frame
*cf
= XFRAME (frame
);
2215 if (cf
!= f
&& FRAME_LIVE_P (f
) && FRAME_X_P (cf
)
2216 && FRAME_X_DISPLAY_INFO (cf
) == FRAME_X_DISPLAY_INFO (f
)
2217 && FRAME_FONT_OBJECT (f
)
2218 && FRAME_FONT_OBJECT (f
)->pixel_size
== pixel_size
)
2220 xfs
= FRAME_XIC_FONTSET (cf
);
2228 char **missing_list
;
2231 char *xlfd_format
= "-*-*-medium-r-normal--%d-*-*-*-*-*";
2233 sprintf (buf
, xlfd_format
, pixel_size
);
2234 missing_list
= NULL
;
2235 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
), buf
,
2236 &missing_list
, &missing_count
, &def_string
);
2237 #ifdef DEBUG_XIC_FONTSET
2238 print_fontset_result (xfs
, buf
, missing_list
, missing_count
);
2241 XFreeStringList (missing_list
);
2244 /* List of pixel sizes most likely available. Find one that
2245 is closest to pixel_size. */
2246 int sizes
[] = {0, 8, 10, 11, 12, 14, 17, 18, 20, 24, 26, 34, 0};
2247 int *smaller
, *larger
;
2249 for (smaller
= sizes
; smaller
[1]; smaller
++)
2250 if (smaller
[1] >= pixel_size
)
2252 larger
= smaller
+ 1;
2253 if (*larger
== pixel_size
)
2255 while (*smaller
|| *larger
)
2260 this_size
= *smaller
--;
2261 else if (! *smaller
)
2262 this_size
= *larger
++;
2263 else if (pixel_size
- *smaller
< *larger
- pixel_size
)
2264 this_size
= *smaller
--;
2266 this_size
= *larger
++;
2267 sprintf (buf
, xlfd_format
, this_size
);
2268 missing_list
= NULL
;
2269 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
), buf
,
2270 &missing_list
, &missing_count
, &def_string
);
2271 #ifdef DEBUG_XIC_FONTSET
2272 print_fontset_result (xfs
, buf
, missing_list
, missing_count
);
2275 XFreeStringList (missing_list
);
2282 char *last_resort
= "-*-*-*-r-normal--*-*-*-*-*-*";
2284 missing_list
= NULL
;
2285 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
), last_resort
,
2286 &missing_list
, &missing_count
, &def_string
);
2287 #ifdef DEBUG_XIC_FONTSET
2288 print_fontset_result (xfs
, last_resort
, missing_list
, missing_count
);
2291 XFreeStringList (missing_list
);
2298 #endif /* USE_FONT_BACKEND */
2300 /* Free the X fontset of frame F if it is the last frame using it. */
2303 xic_free_xfontset (f
)
2306 Lisp_Object rest
, frame
;
2309 if (!FRAME_XIC_FONTSET (f
))
2312 /* See if there is another frame sharing the same fontset. */
2313 FOR_EACH_FRAME (rest
, frame
)
2315 struct frame
*cf
= XFRAME (frame
);
2316 if (cf
!= f
&& FRAME_LIVE_P (f
) && FRAME_X_P (cf
)
2317 && FRAME_X_DISPLAY_INFO (cf
) == FRAME_X_DISPLAY_INFO (f
)
2318 && FRAME_XIC_FONTSET (cf
) == FRAME_XIC_FONTSET (f
))
2326 /* The fontset is not used anymore. It is safe to free it. */
2327 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
2329 if (FRAME_XIC_BASE_FONTNAME (f
))
2330 xfree (FRAME_XIC_BASE_FONTNAME (f
));
2331 FRAME_XIC_BASE_FONTNAME (f
) = NULL
;
2332 FRAME_XIC_FONTSET (f
) = NULL
;
2336 /* Value is the best input style, given user preferences USER (already
2337 checked to be supported by Emacs), and styles supported by the
2338 input method XIM. */
2341 best_xim_style (user
, xim
)
2347 for (i
= 0; i
< user
->count_styles
; ++i
)
2348 for (j
= 0; j
< xim
->count_styles
; ++j
)
2349 if (user
->supported_styles
[i
] == xim
->supported_styles
[j
])
2350 return user
->supported_styles
[i
];
2352 /* Return the default style. */
2353 return XIMPreeditNothing
| XIMStatusNothing
;
2356 /* Create XIC for frame F. */
2358 static XIMStyle xic_style
;
2361 create_frame_xic (f
)
2366 XFontSet xfs
= NULL
;
2371 /* Create X fontset. */
2372 #ifdef USE_FONT_BACKEND
2373 if (enable_font_backend
)
2374 xfs
= xic_create_xfontset2 (f
);
2377 xfs
= xic_create_xfontset
2378 (f
, (FRAME_FONTSET (f
) < 0) ? NULL
2379 : (char *) SDATA (fontset_ascii (FRAME_FONTSET (f
))));
2381 xim
= FRAME_X_XIM (f
);
2386 XVaNestedList preedit_attr
;
2387 XVaNestedList status_attr
;
2389 s_area
.x
= 0; s_area
.y
= 0; s_area
.width
= 1; s_area
.height
= 1;
2390 spot
.x
= 0; spot
.y
= 1;
2392 /* Determine XIC style. */
2395 XIMStyles supported_list
;
2396 supported_list
.count_styles
= (sizeof supported_xim_styles
2397 / sizeof supported_xim_styles
[0]);
2398 supported_list
.supported_styles
= supported_xim_styles
;
2399 xic_style
= best_xim_style (&supported_list
,
2400 FRAME_X_XIM_STYLES (f
));
2403 preedit_attr
= XVaCreateNestedList (0,
2406 FRAME_FOREGROUND_PIXEL (f
),
2408 FRAME_BACKGROUND_PIXEL (f
),
2409 (xic_style
& XIMPreeditPosition
2414 status_attr
= XVaCreateNestedList (0,
2420 FRAME_FOREGROUND_PIXEL (f
),
2422 FRAME_BACKGROUND_PIXEL (f
),
2425 xic
= XCreateIC (xim
,
2426 XNInputStyle
, xic_style
,
2427 XNClientWindow
, FRAME_X_WINDOW (f
),
2428 XNFocusWindow
, FRAME_X_WINDOW (f
),
2429 XNStatusAttributes
, status_attr
,
2430 XNPreeditAttributes
, preedit_attr
,
2432 XFree (preedit_attr
);
2433 XFree (status_attr
);
2436 FRAME_XIC (f
) = xic
;
2437 FRAME_XIC_STYLE (f
) = xic_style
;
2438 FRAME_XIC_FONTSET (f
) = xfs
;
2442 /* Destroy XIC and free XIC fontset of frame F, if any. */
2448 if (FRAME_XIC (f
) == NULL
)
2451 XDestroyIC (FRAME_XIC (f
));
2452 xic_free_xfontset (f
);
2454 FRAME_XIC (f
) = NULL
;
2458 /* Place preedit area for XIC of window W's frame to specified
2459 pixel position X/Y. X and Y are relative to window W. */
2462 xic_set_preeditarea (w
, x
, y
)
2466 struct frame
*f
= XFRAME (w
->frame
);
2470 spot
.x
= WINDOW_TO_FRAME_PIXEL_X (w
, x
) + WINDOW_LEFT_FRINGE_WIDTH (w
);
2471 spot
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, y
) + FONT_BASE (FRAME_FONT (f
));
2472 attr
= XVaCreateNestedList (0, XNSpotLocation
, &spot
, NULL
);
2473 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2478 /* Place status area for XIC in bottom right corner of frame F.. */
2481 xic_set_statusarea (f
)
2484 XIC xic
= FRAME_XIC (f
);
2489 /* Negotiate geometry of status area. If input method has existing
2490 status area, use its current size. */
2491 area
.x
= area
.y
= area
.width
= area
.height
= 0;
2492 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &area
, NULL
);
2493 XSetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2496 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &needed
, NULL
);
2497 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2500 if (needed
->width
== 0) /* Use XNArea instead of XNAreaNeeded */
2502 attr
= XVaCreateNestedList (0, XNArea
, &needed
, NULL
);
2503 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2507 area
.width
= needed
->width
;
2508 area
.height
= needed
->height
;
2509 area
.x
= FRAME_PIXEL_WIDTH (f
) - area
.width
- FRAME_INTERNAL_BORDER_WIDTH (f
);
2510 area
.y
= (FRAME_PIXEL_HEIGHT (f
) - area
.height
2511 - FRAME_MENUBAR_HEIGHT (f
)
2512 - FRAME_TOOLBAR_HEIGHT (f
)
2513 - FRAME_INTERNAL_BORDER_WIDTH (f
));
2516 attr
= XVaCreateNestedList (0, XNArea
, &area
, NULL
);
2517 XSetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2522 /* Set X fontset for XIC of frame F, using base font name
2523 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2526 xic_set_xfontset (f
, base_fontname
)
2528 char *base_fontname
;
2533 xic_free_xfontset (f
);
2535 #ifdef USE_FONT_BACKEND
2536 if (enable_font_backend
)
2537 xfs
= xic_create_xfontset2 (f
);
2540 xfs
= xic_create_xfontset (f
, base_fontname
);
2542 attr
= XVaCreateNestedList (0, XNFontSet
, xfs
, NULL
);
2543 if (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
)
2544 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2545 if (FRAME_XIC_STYLE (f
) & XIMStatusArea
)
2546 XSetICValues (FRAME_XIC (f
), XNStatusAttributes
, attr
, NULL
);
2549 FRAME_XIC_FONTSET (f
) = xfs
;
2552 #endif /* HAVE_X_I18N */
2556 #ifdef USE_X_TOOLKIT
2558 /* Create and set up the X widget for frame F. */
2561 x_window (f
, window_prompting
, minibuffer_only
)
2563 long window_prompting
;
2564 int minibuffer_only
;
2566 XClassHint class_hints
;
2567 XSetWindowAttributes attributes
;
2568 unsigned long attribute_mask
;
2569 Widget shell_widget
;
2571 Widget frame_widget
;
2577 /* Use the resource name as the top-level widget name
2578 for looking up resources. Make a non-Lisp copy
2579 for the window manager, so GC relocation won't bother it.
2581 Elsewhere we specify the window name for the window manager. */
2584 char *str
= (char *) SDATA (Vx_resource_name
);
2585 f
->namebuf
= (char *) xmalloc (strlen (str
) + 1);
2586 strcpy (f
->namebuf
, str
);
2590 XtSetArg (al
[ac
], XtNallowShellResize
, 1); ac
++;
2591 XtSetArg (al
[ac
], XtNinput
, 1); ac
++;
2592 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2593 XtSetArg (al
[ac
], XtNborderWidth
, f
->border_width
); ac
++;
2594 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2595 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2596 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2597 shell_widget
= XtAppCreateShell (f
->namebuf
, EMACS_CLASS
,
2598 applicationShellWidgetClass
,
2599 FRAME_X_DISPLAY (f
), al
, ac
);
2601 f
->output_data
.x
->widget
= shell_widget
;
2602 /* maybe_set_screen_title_format (shell_widget); */
2604 pane_widget
= lw_create_widget ("main", "pane", widget_id_tick
++,
2605 (widget_value
*) NULL
,
2606 shell_widget
, False
,
2610 (lw_callback
) NULL
);
2613 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2614 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2615 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2616 XtSetValues (pane_widget
, al
, ac
);
2617 f
->output_data
.x
->column_widget
= pane_widget
;
2619 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2620 the emacs screen when changing menubar. This reduces flickering. */
2623 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2624 XtSetArg (al
[ac
], XtNshowGrip
, 0); ac
++;
2625 XtSetArg (al
[ac
], XtNallowResize
, 1); ac
++;
2626 XtSetArg (al
[ac
], XtNresizeToPreferred
, 1); ac
++;
2627 XtSetArg (al
[ac
], XtNemacsFrame
, f
); ac
++;
2628 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2629 XtSetArg (al
[ac
], XtNdepth
, FRAME_X_DISPLAY_INFO (f
)->n_planes
); ac
++;
2630 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2631 frame_widget
= XtCreateWidget (f
->namebuf
, emacsFrameClass
, pane_widget
,
2634 f
->output_data
.x
->edit_widget
= frame_widget
;
2636 XtManageChild (frame_widget
);
2638 /* Do some needed geometry management. */
2641 char *tem
, shell_position
[32];
2644 int extra_borders
= 0;
2646 = (f
->output_data
.x
->menubar_widget
2647 ? (f
->output_data
.x
->menubar_widget
->core
.height
2648 + f
->output_data
.x
->menubar_widget
->core
.border_width
)
2651 #if 0 /* Experimentally, we now get the right results
2652 for -geometry -0-0 without this. 24 Aug 96, rms. */
2653 if (FRAME_EXTERNAL_MENU_BAR (f
))
2656 XtVaGetValues (pane_widget
, XtNinternalBorderWidth
, &ibw
, NULL
);
2657 menubar_size
+= ibw
;
2661 f
->output_data
.x
->menubar_height
= menubar_size
;
2664 /* Motif seems to need this amount added to the sizes
2665 specified for the shell widget. The Athena/Lucid widgets don't.
2666 Both conclusions reached experimentally. -- rms. */
2667 XtVaGetValues (f
->output_data
.x
->edit_widget
, XtNinternalBorderWidth
,
2668 &extra_borders
, NULL
);
2672 /* Convert our geometry parameters into a geometry string
2674 Note that we do not specify here whether the position
2675 is a user-specified or program-specified one.
2676 We pass that information later, in x_wm_set_size_hints. */
2678 int left
= f
->left_pos
;
2679 int xneg
= window_prompting
& XNegative
;
2680 int top
= f
->top_pos
;
2681 int yneg
= window_prompting
& YNegative
;
2687 if (window_prompting
& USPosition
)
2688 sprintf (shell_position
, "=%dx%d%c%d%c%d",
2689 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2690 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
,
2691 (xneg
? '-' : '+'), left
,
2692 (yneg
? '-' : '+'), top
);
2695 sprintf (shell_position
, "=%dx%d",
2696 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2697 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
);
2699 /* Setting x and y when the position is not specified in
2700 the geometry string will set program position in the WM hints.
2701 If Emacs had just one program position, we could set it in
2702 fallback resources, but since each make-frame call can specify
2703 different program positions, this is easier. */
2704 XtSetArg (al
[ac
], XtNx
, left
); ac
++;
2705 XtSetArg (al
[ac
], XtNy
, top
); ac
++;
2709 len
= strlen (shell_position
) + 1;
2710 /* We don't free this because we don't know whether
2711 it is safe to free it while the frame exists.
2712 It isn't worth the trouble of arranging to free it
2713 when the frame is deleted. */
2714 tem
= (char *) xmalloc (len
);
2715 strncpy (tem
, shell_position
, len
);
2716 XtSetArg (al
[ac
], XtNgeometry
, tem
); ac
++;
2717 XtSetValues (shell_widget
, al
, ac
);
2720 XtManageChild (pane_widget
);
2721 XtRealizeWidget (shell_widget
);
2723 if (FRAME_X_EMBEDDED_P (f
))
2724 XReparentWindow (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
),
2725 f
->output_data
.x
->parent_desc
, 0, 0);
2727 FRAME_X_WINDOW (f
) = XtWindow (frame_widget
);
2729 validate_x_resource_name ();
2731 class_hints
.res_name
= (char *) SDATA (Vx_resource_name
);
2732 class_hints
.res_class
= (char *) SDATA (Vx_resource_class
);
2733 XSetClassHint (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
), &class_hints
);
2736 FRAME_XIC (f
) = NULL
;
2738 create_frame_xic (f
);
2741 f
->output_data
.x
->wm_hints
.input
= True
;
2742 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2743 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2744 &f
->output_data
.x
->wm_hints
);
2746 hack_wm_protocols (f
, shell_widget
);
2749 XtAddEventHandler (shell_widget
, 0, True
, _XEditResCheckMessages
, 0);
2752 /* Do a stupid property change to force the server to generate a
2753 PropertyNotify event so that the event_stream server timestamp will
2754 be initialized to something relevant to the time we created the window.
2756 XChangeProperty (XtDisplay (frame_widget
), XtWindow (frame_widget
),
2757 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2758 XA_ATOM
, 32, PropModeAppend
,
2759 (unsigned char*) NULL
, 0);
2761 /* Make all the standard events reach the Emacs frame. */
2762 attributes
.event_mask
= STANDARD_EVENT_SET
;
2767 /* XIM server might require some X events. */
2768 unsigned long fevent
= NoEventMask
;
2769 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2770 attributes
.event_mask
|= fevent
;
2772 #endif /* HAVE_X_I18N */
2774 attribute_mask
= CWEventMask
;
2775 XChangeWindowAttributes (XtDisplay (shell_widget
), XtWindow (shell_widget
),
2776 attribute_mask
, &attributes
);
2778 XtMapWidget (frame_widget
);
2780 /* x_set_name normally ignores requests to set the name if the
2781 requested name is the same as the current name. This is the one
2782 place where that assumption isn't correct; f->name is set, but
2783 the X server hasn't been told. */
2786 int explicit = f
->explicit_name
;
2788 f
->explicit_name
= 0;
2791 x_set_name (f
, name
, explicit);
2794 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2795 f
->output_data
.x
->text_cursor
);
2799 /* This is a no-op, except under Motif. Make sure main areas are
2800 set to something reasonable, in case we get an error later. */
2801 lw_set_main_areas (pane_widget
, 0, frame_widget
);
2804 #else /* not USE_X_TOOLKIT */
2810 if (! xg_create_frame_widgets (f
))
2811 error ("Unable to create window");
2814 FRAME_XIC (f
) = NULL
;
2818 create_frame_xic (f
);
2821 /* XIM server might require some X events. */
2822 unsigned long fevent
= NoEventMask
;
2823 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2825 if (fevent
!= NoEventMask
)
2827 XSetWindowAttributes attributes
;
2828 XWindowAttributes wattr
;
2829 unsigned long attribute_mask
;
2831 XGetWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2833 attributes
.event_mask
= wattr
.your_event_mask
| fevent
;
2834 attribute_mask
= CWEventMask
;
2835 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2836 attribute_mask
, &attributes
);
2844 #else /*! USE_GTK */
2845 /* Create and set up the X window for frame F. */
2852 XClassHint class_hints
;
2853 XSetWindowAttributes attributes
;
2854 unsigned long attribute_mask
;
2856 attributes
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
2857 attributes
.border_pixel
= f
->output_data
.x
->border_pixel
;
2858 attributes
.bit_gravity
= StaticGravity
;
2859 attributes
.backing_store
= NotUseful
;
2860 attributes
.save_under
= True
;
2861 attributes
.event_mask
= STANDARD_EVENT_SET
;
2862 attributes
.colormap
= FRAME_X_COLORMAP (f
);
2863 attribute_mask
= (CWBackPixel
| CWBorderPixel
| CWBitGravity
| CWEventMask
2868 = XCreateWindow (FRAME_X_DISPLAY (f
),
2869 f
->output_data
.x
->parent_desc
,
2872 FRAME_PIXEL_WIDTH (f
), FRAME_PIXEL_HEIGHT (f
),
2874 CopyFromParent
, /* depth */
2875 InputOutput
, /* class */
2877 attribute_mask
, &attributes
);
2882 create_frame_xic (f
);
2885 /* XIM server might require some X events. */
2886 unsigned long fevent
= NoEventMask
;
2887 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2888 attributes
.event_mask
|= fevent
;
2889 attribute_mask
= CWEventMask
;
2890 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2891 attribute_mask
, &attributes
);
2894 #endif /* HAVE_X_I18N */
2896 validate_x_resource_name ();
2898 class_hints
.res_name
= (char *) SDATA (Vx_resource_name
);
2899 class_hints
.res_class
= (char *) SDATA (Vx_resource_class
);
2900 XSetClassHint (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &class_hints
);
2902 /* The menubar is part of the ordinary display;
2903 it does not count in addition to the height of the window. */
2904 f
->output_data
.x
->menubar_height
= 0;
2906 /* This indicates that we use the "Passive Input" input model.
2907 Unless we do this, we don't get the Focus{In,Out} events that we
2908 need to draw the cursor correctly. Accursed bureaucrats.
2909 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2911 f
->output_data
.x
->wm_hints
.input
= True
;
2912 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2913 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2914 &f
->output_data
.x
->wm_hints
);
2915 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
2917 /* Request "save yourself" and "delete window" commands from wm. */
2920 protocols
[0] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2921 protocols
[1] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2922 XSetWMProtocols (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), protocols
, 2);
2925 /* x_set_name normally ignores requests to set the name if the
2926 requested name is the same as the current name. This is the one
2927 place where that assumption isn't correct; f->name is set, but
2928 the X server hasn't been told. */
2931 int explicit = f
->explicit_name
;
2933 f
->explicit_name
= 0;
2936 x_set_name (f
, name
, explicit);
2939 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2940 f
->output_data
.x
->text_cursor
);
2944 if (FRAME_X_WINDOW (f
) == 0)
2945 error ("Unable to create window");
2948 #endif /* not USE_GTK */
2949 #endif /* not USE_X_TOOLKIT */
2951 /* Verify that the icon position args for this window are valid. */
2954 x_icon_verify (f
, parms
)
2958 Lisp_Object icon_x
, icon_y
;
2960 /* Set the position of the icon. Note that twm groups all
2961 icons in an icon window. */
2962 icon_x
= x_frame_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
2963 icon_y
= x_frame_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
2964 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2966 CHECK_NUMBER (icon_x
);
2967 CHECK_NUMBER (icon_y
);
2969 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2970 error ("Both left and top icon corners of icon must be specified");
2973 /* Handle the icon stuff for this window. Perhaps later we might
2974 want an x_set_icon_position which can be called interactively as
2982 Lisp_Object icon_x
, icon_y
;
2984 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
2987 /* Set the position of the icon. Note that twm groups all
2988 icons in an icon window. */
2989 icon_x
= x_frame_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
2990 icon_y
= x_frame_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
2991 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2993 CHECK_NUMBER (icon_x
);
2994 CHECK_NUMBER (icon_y
);
2996 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2997 error ("Both left and top icon corners of icon must be specified");
3001 if (! EQ (icon_x
, Qunbound
))
3002 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
3004 #if 0 /* x_get_arg removes the visibility parameter as a side effect,
3005 but x_create_frame still needs it. */
3006 /* Start up iconic or window? */
3007 x_wm_set_window_state
3008 (f
, (EQ (x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
),
3014 x_text_icon (f
, (char *) SDATA ((!NILP (f
->icon_name
)
3021 /* Make the GCs needed for this window, setting the
3022 background, border and mouse colors; also create the
3023 mouse cursor and the gray border tile. */
3025 static char cursor_bits
[] =
3027 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3028 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3029 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3030 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3037 XGCValues gc_values
;
3041 /* Create the GCs of this frame.
3042 Note that many default values are used. */
3045 gc_values
.font
= FRAME_FONT (f
)->fid
;
3046 gc_values
.foreground
= FRAME_FOREGROUND_PIXEL (f
);
3047 gc_values
.background
= FRAME_BACKGROUND_PIXEL (f
);
3048 gc_values
.line_width
= 0; /* Means 1 using fast algorithm. */
3049 f
->output_data
.x
->normal_gc
3050 = XCreateGC (FRAME_X_DISPLAY (f
),
3052 GCLineWidth
| GCFont
| GCForeground
| GCBackground
,
3055 /* Reverse video style. */
3056 gc_values
.foreground
= FRAME_BACKGROUND_PIXEL (f
);
3057 gc_values
.background
= FRAME_FOREGROUND_PIXEL (f
);
3058 f
->output_data
.x
->reverse_gc
3059 = XCreateGC (FRAME_X_DISPLAY (f
),
3061 GCFont
| GCForeground
| GCBackground
| GCLineWidth
,
3064 /* Cursor has cursor-color background, background-color foreground. */
3065 gc_values
.foreground
= FRAME_BACKGROUND_PIXEL (f
);
3066 gc_values
.background
= f
->output_data
.x
->cursor_pixel
;
3067 gc_values
.fill_style
= FillOpaqueStippled
;
3069 = XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
3070 FRAME_X_DISPLAY_INFO (f
)->root_window
,
3071 cursor_bits
, 16, 16);
3072 f
->output_data
.x
->cursor_gc
3073 = XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3074 (GCFont
| GCForeground
| GCBackground
3075 | GCFillStyle
/* | GCStipple */ | GCLineWidth
),
3079 f
->output_data
.x
->white_relief
.gc
= 0;
3080 f
->output_data
.x
->black_relief
.gc
= 0;
3082 /* Create the gray border tile used when the pointer is not in
3083 the frame. Since this depends on the frame's pixel values,
3084 this must be done on a per-frame basis. */
3085 f
->output_data
.x
->border_tile
3086 = (XCreatePixmapFromBitmapData
3087 (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
3088 gray_bits
, gray_width
, gray_height
,
3089 FRAME_FOREGROUND_PIXEL (f
),
3090 FRAME_BACKGROUND_PIXEL (f
),
3091 DefaultDepth (FRAME_X_DISPLAY (f
), FRAME_X_SCREEN_NUMBER (f
))));
3097 /* Free what was was allocated in x_make_gc. */
3103 Display
*dpy
= FRAME_X_DISPLAY (f
);
3107 if (f
->output_data
.x
->normal_gc
)
3109 XFreeGC (dpy
, f
->output_data
.x
->normal_gc
);
3110 f
->output_data
.x
->normal_gc
= 0;
3113 if (f
->output_data
.x
->reverse_gc
)
3115 XFreeGC (dpy
, f
->output_data
.x
->reverse_gc
);
3116 f
->output_data
.x
->reverse_gc
= 0;
3119 if (f
->output_data
.x
->cursor_gc
)
3121 XFreeGC (dpy
, f
->output_data
.x
->cursor_gc
);
3122 f
->output_data
.x
->cursor_gc
= 0;
3125 if (f
->output_data
.x
->border_tile
)
3127 XFreePixmap (dpy
, f
->output_data
.x
->border_tile
);
3128 f
->output_data
.x
->border_tile
= 0;
3135 /* Handler for signals raised during x_create_frame and
3136 x_create_top_frame. FRAME is the frame which is partially
3140 unwind_create_frame (frame
)
3143 struct frame
*f
= XFRAME (frame
);
3145 /* If frame is already dead, nothing to do. This can happen if the
3146 display is disconnected after the frame has become official, but
3147 before x_create_frame removes the unwind protect. */
3148 if (!FRAME_LIVE_P (f
))
3151 /* If frame is ``official'', nothing to do. */
3152 if (!CONSP (Vframe_list
) || !EQ (XCAR (Vframe_list
), frame
))
3155 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3158 x_free_frame_resources (f
);
3161 /* Check that reference counts are indeed correct. */
3162 xassert (dpyinfo
->reference_count
== dpyinfo_refcount
);
3163 xassert (dpyinfo
->image_cache
->refcount
== image_cache_refcount
);
3171 #ifdef USE_FONT_BACKEND
3173 x_default_font_parameter (f
, parms
)
3177 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3178 Lisp_Object font
= x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font",
3181 if (! STRINGP (font
))
3184 = { "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
3185 "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3186 "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3187 /* This was formerly the first thing tried, but it finds
3188 too many fonts and takes too long. */
3189 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
3190 /* If those didn't work, look for something which will
3192 "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
3197 for (i
= 0; names
[i
]; i
++)
3199 font
= font_open_by_name (f
, names
[i
]);
3204 error ("No suitable font was found");
3206 x_default_parameter (f
, parms
, Qfont
, font
, "font", "Font", RES_TYPE_STRING
);
3208 #endif /* USE_FONT_BACKEND */
3210 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
3212 doc
: /* Make a new X window, which is called a "frame" in Emacs terms.
3213 Return an Emacs frame object.
3214 ALIST is an alist of frame parameters.
3215 If the parameters specify that the frame should not have a minibuffer,
3216 and do not specify a specific minibuffer window to use,
3217 then `default-minibuffer-frame' must be a frame whose minibuffer can
3218 be shared by the new frame.
3220 This function is an internal primitive--use `make-frame' instead. */)
3225 Lisp_Object frame
, tem
;
3227 int minibuffer_only
= 0;
3228 long window_prompting
= 0;
3230 int count
= SPECPDL_INDEX ();
3231 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
3232 Lisp_Object display
;
3233 struct x_display_info
*dpyinfo
= NULL
;
3237 parms
= Fcopy_alist (parms
);
3239 /* Use this general default value to start with
3240 until we know if this frame has a specified name. */
3241 Vx_resource_name
= Vinvocation_name
;
3243 display
= x_get_arg (dpyinfo
, parms
, Qterminal
, 0, 0, RES_TYPE_NUMBER
);
3244 if (EQ (display
, Qunbound
))
3245 display
= x_get_arg (dpyinfo
, parms
, Qdisplay
, 0, 0, RES_TYPE_STRING
);
3246 if (EQ (display
, Qunbound
))
3248 dpyinfo
= check_x_display_info (display
);
3250 kb
= dpyinfo
->terminal
->kboard
;
3252 kb
= &the_only_kboard
;
3255 if (!dpyinfo
->terminal
->name
)
3256 error ("Terminal is not live, can't create new frames on it");
3258 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
3260 && ! EQ (name
, Qunbound
)
3262 error ("Invalid frame name--not a string or nil");
3265 Vx_resource_name
= name
;
3267 /* See if parent window is specified. */
3268 parent
= x_get_arg (dpyinfo
, parms
, Qparent_id
, NULL
, NULL
, RES_TYPE_NUMBER
);
3269 if (EQ (parent
, Qunbound
))
3271 if (! NILP (parent
))
3272 CHECK_NUMBER (parent
);
3274 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
3275 /* No need to protect DISPLAY because that's not used after passing
3276 it to make_frame_without_minibuffer. */
3278 GCPRO4 (parms
, parent
, name
, frame
);
3279 tem
= x_get_arg (dpyinfo
, parms
, Qminibuffer
, "minibuffer", "Minibuffer",
3281 if (EQ (tem
, Qnone
) || NILP (tem
))
3282 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
3283 else if (EQ (tem
, Qonly
))
3285 f
= make_minibuffer_frame ();
3286 minibuffer_only
= 1;
3288 else if (WINDOWP (tem
))
3289 f
= make_frame_without_minibuffer (tem
, kb
, display
);
3293 XSETFRAME (frame
, f
);
3295 /* Note that X Windows does support scroll bars. */
3296 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
3298 f
->terminal
= dpyinfo
->terminal
;
3299 f
->terminal
->reference_count
++;
3301 f
->output_method
= output_x_window
;
3302 f
->output_data
.x
= (struct x_output
*) xmalloc (sizeof (struct x_output
));
3303 bzero (f
->output_data
.x
, sizeof (struct x_output
));
3304 f
->output_data
.x
->icon_bitmap
= -1;
3305 FRAME_FONTSET (f
) = -1;
3306 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
3307 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
3308 #ifdef USE_TOOLKIT_SCROLL_BARS
3309 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
3310 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
3311 #endif /* USE_TOOLKIT_SCROLL_BARS */
3314 = x_get_arg (dpyinfo
, parms
, Qicon_name
, "iconName", "Title",
3316 if (! STRINGP (f
->icon_name
))
3317 f
->icon_name
= Qnil
;
3319 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
3321 /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe. */
3322 record_unwind_protect (unwind_create_frame
, frame
);
3324 image_cache_refcount
= FRAME_X_IMAGE_CACHE (f
)->refcount
;
3325 dpyinfo_refcount
= dpyinfo
->reference_count
;
3326 #endif /* GLYPH_DEBUG */
3328 /* These colors will be set anyway later, but it's important
3329 to get the color reference counts right, so initialize them! */
3332 struct gcpro gcpro1
;
3334 /* Function x_decode_color can signal an error. Make
3335 sure to initialize color slots so that we won't try
3336 to free colors we haven't allocated. */
3337 FRAME_FOREGROUND_PIXEL (f
) = -1;
3338 FRAME_BACKGROUND_PIXEL (f
) = -1;
3339 f
->output_data
.x
->cursor_pixel
= -1;
3340 f
->output_data
.x
->cursor_foreground_pixel
= -1;
3341 f
->output_data
.x
->border_pixel
= -1;
3342 f
->output_data
.x
->mouse_pixel
= -1;
3344 black
= build_string ("black");
3346 FRAME_FOREGROUND_PIXEL (f
)
3347 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3348 FRAME_BACKGROUND_PIXEL (f
)
3349 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3350 f
->output_data
.x
->cursor_pixel
3351 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3352 f
->output_data
.x
->cursor_foreground_pixel
3353 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3354 f
->output_data
.x
->border_pixel
3355 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3356 f
->output_data
.x
->mouse_pixel
3357 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3361 /* Specify the parent under which to make this X window. */
3365 f
->output_data
.x
->parent_desc
= (Window
) XFASTINT (parent
);
3366 f
->output_data
.x
->explicit_parent
= 1;
3370 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3371 f
->output_data
.x
->explicit_parent
= 0;
3374 /* Set the name; the functions to which we pass f expect the name to
3376 if (EQ (name
, Qunbound
) || NILP (name
))
3378 f
->name
= build_string (dpyinfo
->x_id_name
);
3379 f
->explicit_name
= 0;
3384 f
->explicit_name
= 1;
3385 /* use the frame's title when getting resources for this frame. */
3386 specbind (Qx_resource_name
, name
);
3389 f
->resx
= dpyinfo
->resx
;
3390 f
->resy
= dpyinfo
->resy
;
3392 #ifdef USE_FONT_BACKEND
3393 if (enable_font_backend
)
3395 /* Perhaps, we must allow frame parameter, say `font-backend',
3396 to specify which font backends to use. */
3397 #ifdef HAVE_FREETYPE
3399 register_font_driver (&xftfont_driver
, f
);
3400 #else /* not HAVE_XFT */
3401 register_font_driver (&ftxfont_driver
, f
);
3402 #endif /* not HAVE_XFT */
3403 #endif /* HAVE_FREETYPE */
3404 register_font_driver (&xfont_driver
, f
);
3406 x_default_parameter (f
, parms
, Qfont_backend
, Qnil
,
3407 "fontBackend", "FontBackend", RES_TYPE_STRING
);
3409 #endif /* USE_FONT_BACKEND */
3411 /* Extract the window parameters from the supplied values
3412 that are needed to determine window geometry. */
3413 #ifdef USE_FONT_BACKEND
3414 if (enable_font_backend
)
3415 x_default_font_parameter (f
, parms
);
3417 #endif /* USE_FONT_BACKEND */
3421 font
= x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
3423 /* If the caller has specified no font, try out fonts which we
3424 hope have bold and italic variations. */
3425 if (!STRINGP (font
))
3428 = { "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
3429 "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3430 "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3431 /* This was formerly the first thing tried, but it finds
3432 too many fonts and takes too long. */
3433 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
3434 /* If those didn't work, look for something which will
3436 "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
3441 for (i
= 0; names
[i
]; i
++)
3445 list
= x_list_fonts (f
, build_string (names
[i
]), 0, 1);
3453 if (! STRINGP (font
))
3454 font
= build_string ("fixed");
3456 x_default_parameter (f
, parms
, Qfont
, font
,
3457 "font", "Font", RES_TYPE_STRING
);
3461 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
3462 whereby it fails to get any font. */
3463 xlwmenu_default_font
= FRAME_FONT (f
);
3466 /* Frame contents get displaced if an embedded X window has a border. */
3467 if (! FRAME_X_EMBEDDED_P (f
))
3468 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
3469 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
3471 /* This defaults to 1 in order to match xterm. We recognize either
3472 internalBorderWidth or internalBorder (which is what xterm calls
3474 if (NILP (Fassq (Qinternal_border_width
, parms
)))
3478 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
3479 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
3480 if (! EQ (value
, Qunbound
))
3481 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
3484 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
3485 "internalBorderWidth", "internalBorderWidth",
3487 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qleft
,
3488 "verticalScrollBars", "ScrollBars",
3491 /* Also do the stuff which must be set before the window exists. */
3492 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
3493 "foreground", "Foreground", RES_TYPE_STRING
);
3494 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
3495 "background", "Background", RES_TYPE_STRING
);
3496 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
3497 "pointerColor", "Foreground", RES_TYPE_STRING
);
3498 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
3499 "cursorColor", "Foreground", RES_TYPE_STRING
);
3500 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
3501 "borderColor", "BorderColor", RES_TYPE_STRING
);
3502 x_default_parameter (f
, parms
, Qscreen_gamma
, Qnil
,
3503 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT
);
3504 x_default_parameter (f
, parms
, Qline_spacing
, Qnil
,
3505 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER
);
3506 x_default_parameter (f
, parms
, Qleft_fringe
, Qnil
,
3507 "leftFringe", "LeftFringe", RES_TYPE_NUMBER
);
3508 x_default_parameter (f
, parms
, Qright_fringe
, Qnil
,
3509 "rightFringe", "RightFringe", RES_TYPE_NUMBER
);
3511 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_foreground
,
3512 "scrollBarForeground",
3513 "ScrollBarForeground", 1);
3514 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_background
,
3515 "scrollBarBackground",
3516 "ScrollBarBackground", 0);
3518 /* Init faces before x_default_parameter is called for scroll-bar
3519 parameters because that function calls x_set_scroll_bar_width,
3520 which calls change_frame_size, which calls Fset_window_buffer,
3521 which runs hooks, which call Fvertical_motion. At the end, we
3522 end up in init_iterator with a null face cache, which should not
3524 init_frame_faces (f
);
3526 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
3527 "menuBar", "MenuBar", RES_TYPE_NUMBER
);
3528 x_default_parameter (f
, parms
, Qtool_bar_lines
, make_number (1),
3529 "toolBar", "ToolBar", RES_TYPE_NUMBER
);
3530 x_default_parameter (f
, parms
, Qbuffer_predicate
, Qnil
,
3531 "bufferPredicate", "BufferPredicate",
3533 x_default_parameter (f
, parms
, Qtitle
, Qnil
,
3534 "title", "Title", RES_TYPE_STRING
);
3535 x_default_parameter (f
, parms
, Qwait_for_wm
, Qt
,
3536 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN
);
3537 x_default_parameter (f
, parms
, Qfullscreen
, Qnil
,
3538 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL
);
3540 /* Compute the size of the X window. */
3541 window_prompting
= x_figure_window_size (f
, parms
, 1);
3543 tem
= x_get_arg (dpyinfo
, parms
, Qunsplittable
, 0, 0, RES_TYPE_BOOLEAN
);
3544 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
3546 x_icon_verify (f
, parms
);
3548 /* Create the X widget or window. */
3549 #ifdef USE_X_TOOLKIT
3550 x_window (f
, window_prompting
, minibuffer_only
);
3558 /* Now consider the frame official. */
3559 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
3560 Vframe_list
= Fcons (frame
, Vframe_list
);
3562 /* We need to do this after creating the X window, so that the
3563 icon-creation functions can say whose icon they're describing. */
3564 x_default_parameter (f
, parms
, Qicon_type
, Qt
,
3565 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL
);
3567 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
3568 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3569 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
3570 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3571 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
3572 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
3573 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
3574 "scrollBarWidth", "ScrollBarWidth",
3577 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3578 Change will not be effected unless different from the current
3580 width
= FRAME_COLS (f
);
3581 height
= FRAME_LINES (f
);
3583 SET_FRAME_COLS (f
, 0);
3584 FRAME_LINES (f
) = 0;
3585 change_frame_size (f
, height
, width
, 1, 0, 0);
3587 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3588 /* Create the menu bar. */
3589 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
3591 /* If this signals an error, we haven't set size hints for the
3592 frame and we didn't make it visible. */
3593 initialize_frame_menubar (f
);
3596 /* This is a no-op, except under Motif where it arranges the
3597 main window for the widgets on it. */
3598 lw_set_main_areas (f
->output_data
.x
->column_widget
,
3599 f
->output_data
.x
->menubar_widget
,
3600 f
->output_data
.x
->edit_widget
);
3601 #endif /* not USE_GTK */
3603 #endif /* USE_X_TOOLKIT || USE_GTK */
3605 /* Tell the server what size and position, etc, we want, and how
3606 badly we want them. This should be done after we have the menu
3607 bar so that its size can be taken into account. */
3609 x_wm_set_size_hint (f
, window_prompting
, 0);
3612 /* Make the window appear on the frame and enable display, unless
3613 the caller says not to. However, with explicit parent, Emacs
3614 cannot control visibility, so don't try. */
3615 if (! f
->output_data
.x
->explicit_parent
)
3617 Lisp_Object visibility
;
3619 visibility
= x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0,
3621 if (EQ (visibility
, Qunbound
))
3624 if (EQ (visibility
, Qicon
))
3625 x_iconify_frame (f
);
3626 else if (! NILP (visibility
))
3627 x_make_frame_visible (f
);
3629 /* Must have been Qnil. */
3633 /* Set the WM leader property. GTK does this itself, so this is not
3634 needed when using GTK. */
3635 if (dpyinfo
->client_leader_window
!= 0)
3638 XChangeProperty (FRAME_X_DISPLAY (f
),
3639 FRAME_OUTER_WINDOW (f
),
3640 dpyinfo
->Xatom_wm_client_leader
,
3641 XA_WINDOW
, 32, PropModeReplace
,
3642 (unsigned char *) &dpyinfo
->client_leader_window
, 1);
3646 /* Initialize `default-minibuffer-frame' in case this is the first
3647 frame on this terminal. */
3648 if (FRAME_HAS_MINIBUF_P (f
)
3649 && (!FRAMEP (kb
->Vdefault_minibuffer_frame
)
3650 || !FRAME_LIVE_P (XFRAME (kb
->Vdefault_minibuffer_frame
))))
3651 kb
->Vdefault_minibuffer_frame
= frame
;
3653 /* All remaining specified parameters, which have not been "used"
3654 by x_get_arg and friends, now go in the misc. alist of the frame. */
3655 for (tem
= parms
; CONSP (tem
); tem
= XCDR (tem
))
3656 if (CONSP (XCAR (tem
)) && !NILP (XCAR (XCAR (tem
))))
3657 f
->param_alist
= Fcons (XCAR (tem
), f
->param_alist
);
3661 /* Make sure windows on this frame appear in calls to next-window
3662 and similar functions. */
3663 Vwindow_list
= Qnil
;
3665 return unbind_to (count
, frame
);
3669 /* FRAME is used only to get a handle on the X display. We don't pass the
3670 display info directly because we're called from frame.c, which doesn't
3671 know about that structure. */
3674 x_get_focus_frame (frame
)
3675 struct frame
*frame
;
3677 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (frame
);
3679 if (! dpyinfo
->x_focus_frame
)
3682 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
3687 /* In certain situations, when the window manager follows a
3688 click-to-focus policy, there seems to be no way around calling
3689 XSetInputFocus to give another frame the input focus .
3691 In an ideal world, XSetInputFocus should generally be avoided so
3692 that applications don't interfere with the window manager's focus
3693 policy. But I think it's okay to use when it's clearly done
3694 following a user-command. */
3696 DEFUN ("x-focus-frame", Fx_focus_frame
, Sx_focus_frame
, 1, 1, 0,
3697 doc
: /* Set the input focus to FRAME.
3698 FRAME nil means use the selected frame. */)
3702 struct frame
*f
= check_x_frame (frame
);
3703 Display
*dpy
= FRAME_X_DISPLAY (f
);
3706 x_catch_errors (dpy
);
3707 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3708 RevertToParent
, CurrentTime
);
3709 x_ewmh_activate_frame (f
);
3710 x_uncatch_errors ();
3717 DEFUN ("xw-color-defined-p", Fxw_color_defined_p
, Sxw_color_defined_p
, 1, 2, 0,
3718 doc
: /* Internal function called by `color-defined-p', which see. */)
3720 Lisp_Object color
, frame
;
3723 FRAME_PTR f
= check_x_frame (frame
);
3725 CHECK_STRING (color
);
3727 if (x_defined_color (f
, SDATA (color
), &foo
, 0))
3733 DEFUN ("xw-color-values", Fxw_color_values
, Sxw_color_values
, 1, 2, 0,
3734 doc
: /* Internal function called by `color-values', which see. */)
3736 Lisp_Object color
, frame
;
3739 FRAME_PTR f
= check_x_frame (frame
);
3741 CHECK_STRING (color
);
3743 if (x_defined_color (f
, SDATA (color
), &foo
, 0))
3744 return list3 (make_number (foo
.red
),
3745 make_number (foo
.green
),
3746 make_number (foo
.blue
));
3751 DEFUN ("xw-display-color-p", Fxw_display_color_p
, Sxw_display_color_p
, 0, 1, 0,
3752 doc
: /* Internal function called by `display-color-p', which see. */)
3754 Lisp_Object terminal
;
3756 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3758 if (dpyinfo
->n_planes
<= 2)
3761 switch (dpyinfo
->visual
->class)
3774 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
3776 doc
: /* Return t if the X display supports shades of gray.
3777 Note that color displays do support shades of gray.
3778 The optional argument TERMINAL specifies which display to ask about.
3779 TERMINAL should be a terminal id, 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
);
3786 if (dpyinfo
->n_planes
<= 1)
3789 switch (dpyinfo
->visual
->class)
3804 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
3806 doc
: /* Return the width in pixels of the X display TERMINAL.
3807 The optional argument TERMINAL specifies which display to ask about.
3808 TERMINAL should be a terminal id, a frame or a display name (a string).
3809 If omitted or nil, that stands for the selected frame's display. */)
3811 Lisp_Object terminal
;
3813 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3815 return make_number (dpyinfo
->width
);
3818 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
3819 Sx_display_pixel_height
, 0, 1, 0,
3820 doc
: /* Return the height in pixels of the X display TERMINAL.
3821 The optional argument TERMINAL specifies which display to ask about.
3822 TERMINAL should be a terminal id, a frame or a display name (a string).
3823 If omitted or nil, that stands for the selected frame's display. */)
3825 Lisp_Object terminal
;
3827 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3829 return make_number (dpyinfo
->height
);
3832 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
3834 doc
: /* Return the number of bitplanes of the X display TERMINAL.
3835 The optional argument TERMINAL specifies which display to ask about.
3836 TERMINAL should be a terminal id, a frame or a display name (a string).
3837 If omitted or nil, that stands for the selected frame's display. */)
3839 Lisp_Object terminal
;
3841 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3843 return make_number (dpyinfo
->n_planes
);
3846 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
3848 doc
: /* Return the number of color cells of the X display TERMINAL.
3849 The optional argument TERMINAL specifies which display to ask about.
3850 TERMINAL should be a terminal id, a frame or a display name (a string).
3851 If omitted or nil, that stands for the selected frame's display. */)
3853 Lisp_Object terminal
;
3855 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3857 int nr_planes
= DisplayPlanes (dpyinfo
->display
,
3858 XScreenNumberOfScreen (dpyinfo
->screen
));
3860 /* Truncate nr_planes to 24 to avoid integer overflow.
3861 Some displays says 32, but only 24 bits are actually significant.
3862 There are only very few and rare video cards that have more than
3863 24 significant bits. Also 24 bits is more than 16 million colors,
3864 it "should be enough for everyone". */
3865 if (nr_planes
> 24) nr_planes
= 24;
3867 return make_number (1 << nr_planes
);
3870 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
3871 Sx_server_max_request_size
,
3873 doc
: /* Return the maximum request size of the X server of display TERMINAL.
3874 The optional argument TERMINAL specifies which display to ask about.
3875 TERMINAL should be a terminal id, a frame or a display name (a string).
3876 If omitted or nil, that stands for the selected frame's display. */)
3878 Lisp_Object terminal
;
3880 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3882 return make_number (MAXREQUEST (dpyinfo
->display
));
3885 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
3886 doc
: /* Return the "vendor ID" string of the X server of display TERMINAL.
3887 \(Labelling every distributor as a "vendor" embodies the false assumption
3888 that operating systems cannot be developed and distributed noncommercially.)
3889 The optional argument TERMINAL specifies which display to ask about.
3890 TERMINAL should be a terminal id, a frame or a display name (a string).
3891 If omitted or nil, that stands for the selected frame's display. */)
3893 Lisp_Object terminal
;
3895 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3896 char *vendor
= ServerVendor (dpyinfo
->display
);
3898 if (! vendor
) vendor
= "";
3899 return build_string (vendor
);
3902 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
3903 doc
: /* Return the version numbers of the X server of display TERMINAL.
3904 The value is a list of three integers: the major and minor
3905 version numbers of the X Protocol in use, and the distributor-specific release
3906 number. See also the function `x-server-vendor'.
3908 The optional argument TERMINAL specifies which display to ask about.
3909 TERMINAL should be a terminal id, a frame or a display name (a string).
3910 If omitted or nil, that stands for the selected frame's display. */)
3912 Lisp_Object terminal
;
3914 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3915 Display
*dpy
= dpyinfo
->display
;
3917 return Fcons (make_number (ProtocolVersion (dpy
)),
3918 Fcons (make_number (ProtocolRevision (dpy
)),
3919 Fcons (make_number (VendorRelease (dpy
)), Qnil
)));
3922 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
3923 doc
: /* Return the number of screens on the X server of display TERMINAL.
3924 The optional argument TERMINAL specifies which display to ask about.
3925 TERMINAL should be a terminal id, a frame or a display name (a string).
3926 If omitted or nil, that stands for the selected frame's display. */)
3928 Lisp_Object terminal
;
3930 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3932 return make_number (ScreenCount (dpyinfo
->display
));
3935 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
3936 doc
: /* Return the height in millimeters of the X display TERMINAL.
3937 The optional argument TERMINAL specifies which display to ask about.
3938 TERMINAL should be a terminal id, a frame or a display name (a string).
3939 If omitted or nil, that stands for the selected frame's display. */)
3941 Lisp_Object terminal
;
3943 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3945 return make_number (HeightMMOfScreen (dpyinfo
->screen
));
3948 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
3949 doc
: /* Return the width in millimeters of the X display TERMINAL.
3950 The optional argument TERMINAL specifies which display to ask about.
3951 TERMINAL should be a terminal id, a frame or a display name (a string).
3952 If omitted or nil, that stands for the selected frame's display. */)
3954 Lisp_Object terminal
;
3956 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3958 return make_number (WidthMMOfScreen (dpyinfo
->screen
));
3961 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
3962 Sx_display_backing_store
, 0, 1, 0,
3963 doc
: /* Return an indication of whether X display TERMINAL does backing store.
3964 The value may be `always', `when-mapped', or `not-useful'.
3965 The optional argument TERMINAL specifies which display to ask about.
3966 TERMINAL should be a terminal id, a frame or a display name (a string).
3967 If omitted or nil, that stands for the selected frame's display. */)
3969 Lisp_Object terminal
;
3971 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3974 switch (DoesBackingStore (dpyinfo
->screen
))
3977 result
= intern ("always");
3981 result
= intern ("when-mapped");
3985 result
= intern ("not-useful");
3989 error ("Strange value for BackingStore parameter of screen");
3996 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
3997 Sx_display_visual_class
, 0, 1, 0,
3998 doc
: /* Return the visual class of the X display TERMINAL.
3999 The value is one of the symbols `static-gray', `gray-scale',
4000 `static-color', `pseudo-color', `true-color', or `direct-color'.
4002 The optional argument TERMINAL specifies which display to ask about.
4003 TERMINAL should a terminal id, a frame or a display name (a string).
4004 If omitted or nil, that stands for the selected frame's display. */)
4006 Lisp_Object terminal
;
4008 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4011 switch (dpyinfo
->visual
->class)
4014 result
= intern ("static-gray");
4017 result
= intern ("gray-scale");
4020 result
= intern ("static-color");
4023 result
= intern ("pseudo-color");
4026 result
= intern ("true-color");
4029 result
= intern ("direct-color");
4032 error ("Display has an unknown visual class");
4039 DEFUN ("x-display-save-under", Fx_display_save_under
,
4040 Sx_display_save_under
, 0, 1, 0,
4041 doc
: /* Return t if the X display TERMINAL supports the save-under feature.
4042 The optional argument TERMINAL specifies which display to ask about.
4043 TERMINAL should be a terminal id, a frame or a display name (a string).
4044 If omitted or nil, that stands for the selected frame's display. */)
4046 Lisp_Object terminal
;
4048 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4050 if (DoesSaveUnders (dpyinfo
->screen
) == True
)
4058 register struct frame
*f
;
4060 return FRAME_PIXEL_WIDTH (f
);
4065 register struct frame
*f
;
4067 return FRAME_PIXEL_HEIGHT (f
);
4072 register struct frame
*f
;
4074 return FRAME_COLUMN_WIDTH (f
);
4079 register struct frame
*f
;
4081 return FRAME_LINE_HEIGHT (f
);
4086 register struct frame
*f
;
4088 return FRAME_X_DISPLAY_INFO (f
)->n_planes
;
4093 /************************************************************************
4095 ************************************************************************/
4098 /* Mapping visual names to visuals. */
4100 static struct visual_class
4107 {"StaticGray", StaticGray
},
4108 {"GrayScale", GrayScale
},
4109 {"StaticColor", StaticColor
},
4110 {"PseudoColor", PseudoColor
},
4111 {"TrueColor", TrueColor
},
4112 {"DirectColor", DirectColor
},
4117 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4119 /* Value is the screen number of screen SCR. This is a substitute for
4120 the X function with the same name when that doesn't exist. */
4123 XScreenNumberOfScreen (scr
)
4124 register Screen
*scr
;
4126 Display
*dpy
= scr
->display
;
4129 for (i
= 0; i
< dpy
->nscreens
; ++i
)
4130 if (scr
== dpy
->screens
+ i
)
4136 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4139 /* Select the visual that should be used on display DPYINFO. Set
4140 members of DPYINFO appropriately. Called from x_term_init. */
4143 select_visual (dpyinfo
)
4144 struct x_display_info
*dpyinfo
;
4146 Display
*dpy
= dpyinfo
->display
;
4147 Screen
*screen
= dpyinfo
->screen
;
4150 /* See if a visual is specified. */
4151 value
= display_x_get_resource (dpyinfo
,
4152 build_string ("visualClass"),
4153 build_string ("VisualClass"),
4155 if (STRINGP (value
))
4157 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
4158 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
4159 depth, a decimal number. NAME is compared with case ignored. */
4160 char *s
= (char *) alloca (SBYTES (value
) + 1);
4165 strcpy (s
, SDATA (value
));
4166 dash
= index (s
, '-');
4169 dpyinfo
->n_planes
= atoi (dash
+ 1);
4173 /* We won't find a matching visual with depth 0, so that
4174 an error will be printed below. */
4175 dpyinfo
->n_planes
= 0;
4177 /* Determine the visual class. */
4178 for (i
= 0; visual_classes
[i
].name
; ++i
)
4179 if (xstricmp (s
, visual_classes
[i
].name
) == 0)
4181 class = visual_classes
[i
].class;
4185 /* Look up a matching visual for the specified class. */
4187 || !XMatchVisualInfo (dpy
, XScreenNumberOfScreen (screen
),
4188 dpyinfo
->n_planes
, class, &vinfo
))
4189 fatal ("Invalid visual specification `%s'", SDATA (value
));
4191 dpyinfo
->visual
= vinfo
.visual
;
4196 XVisualInfo
*vinfo
, vinfo_template
;
4198 dpyinfo
->visual
= DefaultVisualOfScreen (screen
);
4200 vinfo_template
.visualid
= XVisualIDFromVisual (dpyinfo
->visual
);
4201 vinfo_template
.screen
= XScreenNumberOfScreen (screen
);
4202 vinfo
= XGetVisualInfo (dpy
, VisualIDMask
| VisualScreenMask
,
4203 &vinfo_template
, &n_visuals
);
4205 fatal ("Can't get proper X visual info");
4207 dpyinfo
->n_planes
= vinfo
->depth
;
4208 XFree ((char *) vinfo
);
4213 /* Return the X display structure for the display named NAME.
4214 Open a new connection if necessary. */
4216 struct x_display_info
*
4217 x_display_info_for_name (name
)
4221 struct x_display_info
*dpyinfo
;
4223 CHECK_STRING (name
);
4226 if (! EQ (Vinitial_window_system
, intern ("x")))
4227 error ("Not using X Windows"); /* That doesn't stop us anymore. */
4230 for (dpyinfo
= x_display_list
, names
= x_display_name_list
;
4232 dpyinfo
= dpyinfo
->next
, names
= XCDR (names
))
4235 tem
= Fstring_equal (XCAR (XCAR (names
)), name
);
4240 /* Use this general default value to start with. */
4241 Vx_resource_name
= Vinvocation_name
;
4243 validate_x_resource_name ();
4245 dpyinfo
= x_term_init (name
, (char *)0,
4246 (char *) SDATA (Vx_resource_name
));
4249 error ("Cannot connect to X server %s", SDATA (name
));
4252 XSETFASTINT (Vwindow_system_version
, 11);
4258 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
4260 doc
: /* Open a connection to an X server.
4261 DISPLAY is the name of the display to connect to.
4262 Optional second arg XRM-STRING is a string of resources in xrdb format.
4263 If the optional third arg MUST-SUCCEED is non-nil,
4264 terminate Emacs if we can't open the connection. */)
4265 (display
, xrm_string
, must_succeed
)
4266 Lisp_Object display
, xrm_string
, must_succeed
;
4268 unsigned char *xrm_option
;
4269 struct x_display_info
*dpyinfo
;
4271 CHECK_STRING (display
);
4272 if (! NILP (xrm_string
))
4273 CHECK_STRING (xrm_string
);
4276 if (! EQ (Vinitial_window_system
, intern ("x")))
4277 error ("Not using X Windows"); /* That doesn't stop us anymore. */
4280 if (! NILP (xrm_string
))
4281 xrm_option
= (unsigned char *) SDATA (xrm_string
);
4283 xrm_option
= (unsigned char *) 0;
4285 validate_x_resource_name ();
4287 /* This is what opens the connection and sets x_current_display.
4288 This also initializes many symbols, such as those used for input. */
4289 dpyinfo
= x_term_init (display
, xrm_option
,
4290 (char *) SDATA (Vx_resource_name
));
4294 if (!NILP (must_succeed
))
4295 fatal ("Cannot connect to X server %s.\n\
4296 Check the DISPLAY environment variable or use `-d'.\n\
4297 Also use the `xauth' program to verify that you have the proper\n\
4298 authorization information needed to connect the X server.\n\
4299 An insecure way to solve the problem may be to use `xhost'.\n",
4302 error ("Cannot connect to X server %s", SDATA (display
));
4307 XSETFASTINT (Vwindow_system_version
, 11);
4311 DEFUN ("x-close-connection", Fx_close_connection
,
4312 Sx_close_connection
, 1, 1, 0,
4313 doc
: /* Close the connection to TERMINAL's X server.
4314 For TERMINAL, specify a terminal id, a frame or a display name (a
4315 string). If TERMINAL is nil, that stands for the selected frame's
4318 Lisp_Object terminal
;
4320 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4322 if (dpyinfo
->reference_count
> 0)
4323 error ("Display still has frames on it");
4325 x_delete_terminal (dpyinfo
->terminal
);
4330 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
4331 doc
: /* Return the list of display names that Emacs has connections to. */)
4334 Lisp_Object tail
, result
;
4337 for (tail
= x_display_name_list
; CONSP (tail
); tail
= XCDR (tail
))
4338 result
= Fcons (XCAR (XCAR (tail
)), result
);
4343 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
4344 doc
: /* If ON is non-nil, report X errors as soon as the erring request is made.
4345 If ON is nil, allow buffering of requests.
4346 Turning on synchronization prohibits the Xlib routines from buffering
4347 requests and seriously degrades performance, but makes debugging much
4349 The optional second argument TERMINAL specifies which display to act on.
4350 TERMINAL should be a terminal id, a frame or a display name (a string).
4351 If TERMINAL is omitted or nil, that stands for the selected frame's display. */)
4353 Lisp_Object terminal
, on
;
4355 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4357 XSynchronize (dpyinfo
->display
, !EQ (on
, Qnil
));
4362 /* Wait for responses to all X commands issued so far for frame F. */
4369 XSync (FRAME_X_DISPLAY (f
), False
);
4374 /***********************************************************************
4376 ***********************************************************************/
4378 DEFUN ("x-change-window-property", Fx_change_window_property
,
4379 Sx_change_window_property
, 2, 6, 0,
4380 doc
: /* Change window property PROP to VALUE on the X window of FRAME.
4381 PROP must be a string.
4382 VALUE may be a string or a list of conses, numbers and/or strings.
4383 If an element in the list is a string, it is converted to
4384 an Atom and the value of the Atom is used. If an element is a cons,
4385 it is converted to a 32 bit number where the car is the 16 top bits and the
4386 cdr is the lower 16 bits.
4387 FRAME nil or omitted means use the selected frame.
4388 If TYPE is given and non-nil, it is the name of the type of VALUE.
4389 If TYPE is not given or nil, the type is STRING.
4390 FORMAT gives the size in bits of each element if VALUE is a list.
4391 It must be one of 8, 16 or 32.
4392 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
4393 If OUTER_P is non-nil, the property is changed for the outer X window of
4394 FRAME. Default is to change on the edit X window.
4397 (prop
, value
, frame
, type
, format
, outer_p
)
4398 Lisp_Object prop
, value
, frame
, type
, format
, outer_p
;
4400 struct frame
*f
= check_x_frame (frame
);
4402 Atom target_type
= XA_STRING
;
4403 int element_format
= 8;
4404 unsigned char *data
;
4408 CHECK_STRING (prop
);
4410 if (! NILP (format
))
4412 CHECK_NUMBER (format
);
4413 element_format
= XFASTINT (format
);
4415 if (element_format
!= 8 && element_format
!= 16
4416 && element_format
!= 32)
4417 error ("FORMAT must be one of 8, 16 or 32");
4422 nelements
= x_check_property_data (value
);
4423 if (nelements
== -1)
4424 error ("Bad data in VALUE, must be number, string or cons");
4426 if (element_format
== 8)
4427 data
= (unsigned char *) xmalloc (nelements
);
4428 else if (element_format
== 16)
4429 data
= (unsigned char *) xmalloc (nelements
*2);
4430 else /* format == 32 */
4431 /* The man page for XChangeProperty:
4432 "If the specified format is 32, the property data must be a
4434 This applies even if long is more than 64 bits. The X library
4435 converts to 32 bits before sending to the X server. */
4436 data
= (unsigned char *) xmalloc (nelements
* sizeof(long));
4438 x_fill_property_data (FRAME_X_DISPLAY (f
), value
, data
, element_format
);
4442 CHECK_STRING (value
);
4443 data
= SDATA (value
);
4444 nelements
= SCHARS (value
);
4448 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
4451 CHECK_STRING (type
);
4452 target_type
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (type
), False
);
4455 if (! NILP (outer_p
)) w
= FRAME_OUTER_WINDOW (f
);
4456 else w
= FRAME_X_WINDOW (f
);
4458 XChangeProperty (FRAME_X_DISPLAY (f
), w
,
4459 prop_atom
, target_type
, element_format
, PropModeReplace
,
4462 if (CONSP (value
)) xfree (data
);
4464 /* Make sure the property is set when we return. */
4465 XFlush (FRAME_X_DISPLAY (f
));
4472 DEFUN ("x-delete-window-property", Fx_delete_window_property
,
4473 Sx_delete_window_property
, 1, 2, 0,
4474 doc
: /* Remove window property PROP from X window of FRAME.
4475 FRAME nil or omitted means use the selected frame. Value is PROP. */)
4477 Lisp_Object prop
, frame
;
4479 struct frame
*f
= check_x_frame (frame
);
4482 CHECK_STRING (prop
);
4484 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
4485 XDeleteProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), prop_atom
);
4487 /* Make sure the property is removed when we return. */
4488 XFlush (FRAME_X_DISPLAY (f
));
4495 DEFUN ("x-window-property", Fx_window_property
, Sx_window_property
,
4497 doc
: /* Value is the value of window property PROP on FRAME.
4498 If FRAME is nil or omitted, use the selected frame.
4499 If TYPE is nil or omitted, get the property as a string. Otherwise TYPE
4500 is the name of the Atom that denotes the type expected.
4501 If SOURCE is non-nil, get the property on that window instead of from
4502 FRAME. The number 0 denotes the root window.
4503 If DELETE_P is non-nil, delete the property after retreiving it.
4504 If VECTOR_RET_P is non-nil, don't return a string but a vector of values.
4506 Value is nil if FRAME hasn't a property with name PROP or if PROP has
4507 no value of TYPE. */)
4508 (prop
, frame
, type
, source
, delete_p
, vector_ret_p
)
4509 Lisp_Object prop
, frame
, type
, source
, delete_p
, vector_ret_p
;
4511 struct frame
*f
= check_x_frame (frame
);
4514 Lisp_Object prop_value
= Qnil
;
4515 unsigned char *tmp_data
= NULL
;
4517 Atom target_type
= XA_STRING
;
4519 unsigned long actual_size
, bytes_remaining
;
4520 Window target_window
= FRAME_X_WINDOW (f
);
4521 struct gcpro gcpro1
;
4523 GCPRO1 (prop_value
);
4524 CHECK_STRING (prop
);
4526 if (! NILP (source
))
4528 if (NUMBERP (source
))
4530 if (FLOATP (source
))
4531 target_window
= (Window
) XFLOAT (source
);
4533 target_window
= XFASTINT (source
);
4535 if (target_window
== 0)
4536 target_window
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
4538 else if (CONSP (source
))
4539 target_window
= cons_to_long (source
);
4545 if (strcmp ("AnyPropertyType", SDATA (type
)) == 0)
4546 target_type
= AnyPropertyType
;
4548 target_type
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (type
), False
);
4551 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SDATA (prop
), False
);
4552 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), target_window
,
4553 prop_atom
, 0, 0, False
, target_type
,
4554 &actual_type
, &actual_format
, &actual_size
,
4555 &bytes_remaining
, &tmp_data
);
4558 int size
= bytes_remaining
;
4563 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), target_window
,
4564 prop_atom
, 0, bytes_remaining
,
4565 ! NILP (delete_p
), target_type
,
4566 &actual_type
, &actual_format
,
4567 &actual_size
, &bytes_remaining
,
4569 if (rc
== Success
&& tmp_data
)
4571 /* The man page for XGetWindowProperty says:
4572 "If the returned format is 32, the returned data is represented
4573 as a long array and should be cast to that type to obtain the
4575 This applies even if long is more than 32 bits, the X library
4576 converts from 32 bit elements received from the X server to long
4577 and passes the long array to us. Thus, for that case bcopy can not
4578 be used. We convert to a 32 bit type here, because so much code
4581 The bytes and offsets passed to XGetWindowProperty refers to the
4582 property and those are indeed in 32 bit quantities if format is
4585 if (actual_format
== 32 && actual_format
< BITS_PER_LONG
)
4588 int *idata
= (int *) tmp_data
;
4589 long *ldata
= (long *) tmp_data
;
4591 for (i
= 0; i
< actual_size
; ++i
)
4592 idata
[i
] = (int) ldata
[i
];
4595 if (NILP (vector_ret_p
))
4596 prop_value
= make_string (tmp_data
, size
);
4598 prop_value
= x_property_data_to_lisp (f
,
4605 if (tmp_data
) XFree (tmp_data
);
4615 /***********************************************************************
4617 ***********************************************************************/
4619 /* If non-null, an asynchronous timer that, when it expires, displays
4620 an hourglass cursor on all frames. */
4622 static struct atimer
*hourglass_atimer
;
4624 /* Non-zero means an hourglass cursor is currently shown. */
4626 static int hourglass_shown_p
;
4628 /* Number of seconds to wait before displaying an hourglass cursor. */
4630 static Lisp_Object Vhourglass_delay
;
4632 /* Default number of seconds to wait before displaying an hourglass
4635 #define DEFAULT_HOURGLASS_DELAY 1
4637 /* Function prototypes. */
4639 static void show_hourglass
P_ ((struct atimer
*));
4640 static void hide_hourglass
P_ ((void));
4642 /* Return non-zero if houglass timer has been started or hourglass is shown. */
4645 hourglass_started ()
4647 return hourglass_shown_p
|| hourglass_atimer
!= NULL
;
4651 /* Cancel a currently active hourglass timer, and start a new one. */
4657 int secs
, usecs
= 0;
4659 cancel_hourglass ();
4661 if (INTEGERP (Vhourglass_delay
)
4662 && XINT (Vhourglass_delay
) > 0)
4663 secs
= XFASTINT (Vhourglass_delay
);
4664 else if (FLOATP (Vhourglass_delay
)
4665 && XFLOAT_DATA (Vhourglass_delay
) > 0)
4668 tem
= Ftruncate (Vhourglass_delay
, Qnil
);
4669 secs
= XFASTINT (tem
);
4670 usecs
= (XFLOAT_DATA (Vhourglass_delay
) - secs
) * 1000000;
4673 secs
= DEFAULT_HOURGLASS_DELAY
;
4675 EMACS_SET_SECS_USECS (delay
, secs
, usecs
);
4676 hourglass_atimer
= start_atimer (ATIMER_RELATIVE
, delay
,
4677 show_hourglass
, NULL
);
4681 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
4687 if (hourglass_atimer
)
4689 cancel_atimer (hourglass_atimer
);
4690 hourglass_atimer
= NULL
;
4693 if (hourglass_shown_p
)
4698 /* Timer function of hourglass_atimer. TIMER is equal to
4701 Display an hourglass pointer on all frames by mapping the frames'
4702 hourglass_window. Set the hourglass_p flag in the frames'
4703 output_data.x structure to indicate that an hourglass cursor is
4704 shown on the frames. */
4707 show_hourglass (timer
)
4708 struct atimer
*timer
;
4710 /* The timer implementation will cancel this timer automatically
4711 after this function has run. Set hourglass_atimer to null
4712 so that we know the timer doesn't have to be canceled. */
4713 hourglass_atimer
= NULL
;
4715 if (!hourglass_shown_p
)
4717 Lisp_Object rest
, frame
;
4721 FOR_EACH_FRAME (rest
, frame
)
4723 struct frame
*f
= XFRAME (frame
);
4725 if (FRAME_LIVE_P (f
) && FRAME_X_P (f
) && FRAME_X_DISPLAY (f
))
4727 Display
*dpy
= FRAME_X_DISPLAY (f
);
4729 #ifdef USE_X_TOOLKIT
4730 if (f
->output_data
.x
->widget
)
4732 if (FRAME_OUTER_WINDOW (f
))
4735 f
->output_data
.x
->hourglass_p
= 1;
4737 if (!f
->output_data
.x
->hourglass_window
)
4739 unsigned long mask
= CWCursor
;
4740 XSetWindowAttributes attrs
;
4742 Window parent
= FRAME_X_WINDOW (f
);
4744 Window parent
= FRAME_OUTER_WINDOW (f
);
4746 attrs
.cursor
= f
->output_data
.x
->hourglass_cursor
;
4748 f
->output_data
.x
->hourglass_window
4749 = XCreateWindow (dpy
, parent
,
4750 0, 0, 32000, 32000, 0, 0,
4756 XMapRaised (dpy
, f
->output_data
.x
->hourglass_window
);
4762 hourglass_shown_p
= 1;
4768 /* Hide the hourglass pointer on all frames, if it is currently
4774 if (hourglass_shown_p
)
4776 Lisp_Object rest
, frame
;
4779 FOR_EACH_FRAME (rest
, frame
)
4781 struct frame
*f
= XFRAME (frame
);
4784 /* Watch out for newly created frames. */
4785 && f
->output_data
.x
->hourglass_window
)
4787 XUnmapWindow (FRAME_X_DISPLAY (f
),
4788 f
->output_data
.x
->hourglass_window
);
4789 /* Sync here because XTread_socket looks at the
4790 hourglass_p flag that is reset to zero below. */
4791 XSync (FRAME_X_DISPLAY (f
), False
);
4792 f
->output_data
.x
->hourglass_p
= 0;
4796 hourglass_shown_p
= 0;
4803 /***********************************************************************
4805 ***********************************************************************/
4807 static Lisp_Object x_create_tip_frame
P_ ((struct x_display_info
*,
4808 Lisp_Object
, Lisp_Object
));
4809 static void compute_tip_xy
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
,
4810 Lisp_Object
, int, int, int *, int *));
4812 /* The frame of a currently visible tooltip. */
4814 Lisp_Object tip_frame
;
4816 /* If non-nil, a timer started that hides the last tooltip when it
4819 Lisp_Object tip_timer
;
4822 /* If non-nil, a vector of 3 elements containing the last args
4823 with which x-show-tip was called. See there. */
4825 Lisp_Object last_show_tip_args
;
4827 /* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
4829 Lisp_Object Vx_max_tooltip_size
;
4833 unwind_create_tip_frame (frame
)
4836 Lisp_Object deleted
;
4838 deleted
= unwind_create_frame (frame
);
4839 if (EQ (deleted
, Qt
))
4849 /* Create a frame for a tooltip on the display described by DPYINFO.
4850 PARMS is a list of frame parameters. TEXT is the string to
4851 display in the tip frame. Value is the frame.
4853 Note that functions called here, esp. x_default_parameter can
4854 signal errors, for instance when a specified color name is
4855 undefined. We have to make sure that we're in a consistent state
4856 when this happens. */
4859 x_create_tip_frame (dpyinfo
, parms
, text
)
4860 struct x_display_info
*dpyinfo
;
4861 Lisp_Object parms
, text
;
4864 Lisp_Object frame
, tem
;
4866 long window_prompting
= 0;
4868 int count
= SPECPDL_INDEX ();
4869 struct gcpro gcpro1
, gcpro2
, gcpro3
;
4870 int face_change_count_before
= face_change_count
;
4872 struct buffer
*old_buffer
;
4876 if (!dpyinfo
->terminal
->name
)
4877 error ("Terminal is not live, can't create new frames on it");
4879 parms
= Fcopy_alist (parms
);
4881 /* Get the name of the frame to use for resource lookup. */
4882 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
4884 && !EQ (name
, Qunbound
)
4886 error ("Invalid frame name--not a string or nil");
4889 GCPRO3 (parms
, name
, frame
);
4891 XSETFRAME (frame
, f
);
4893 buffer
= Fget_buffer_create (build_string (" *tip*"));
4894 Fset_window_buffer (FRAME_ROOT_WINDOW (f
), buffer
, Qnil
);
4895 old_buffer
= current_buffer
;
4896 set_buffer_internal_1 (XBUFFER (buffer
));
4897 current_buffer
->truncate_lines
= Qnil
;
4898 specbind (Qinhibit_read_only
, Qt
);
4899 specbind (Qinhibit_modification_hooks
, Qt
);
4902 set_buffer_internal_1 (old_buffer
);
4904 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
4905 record_unwind_protect (unwind_create_tip_frame
, frame
);
4907 f
->terminal
= dpyinfo
->terminal
;
4908 f
->terminal
->reference_count
++;
4910 /* By setting the output method, we're essentially saying that
4911 the frame is live, as per FRAME_LIVE_P. If we get a signal
4912 from this point on, x_destroy_window might screw up reference
4914 f
->output_method
= output_x_window
;
4915 f
->output_data
.x
= (struct x_output
*) xmalloc (sizeof (struct x_output
));
4916 bzero (f
->output_data
.x
, sizeof (struct x_output
));
4917 f
->output_data
.x
->icon_bitmap
= -1;
4918 FRAME_FONTSET (f
) = -1;
4919 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
4920 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
4921 #ifdef USE_TOOLKIT_SCROLL_BARS
4922 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
4923 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
4924 #endif /* USE_TOOLKIT_SCROLL_BARS */
4925 f
->icon_name
= Qnil
;
4926 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
4928 image_cache_refcount
= FRAME_X_IMAGE_CACHE (f
)->refcount
;
4929 dpyinfo_refcount
= dpyinfo
->reference_count
;
4930 #endif /* GLYPH_DEBUG */
4931 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
4932 f
->output_data
.x
->explicit_parent
= 0;
4934 /* These colors will be set anyway later, but it's important
4935 to get the color reference counts right, so initialize them! */
4938 struct gcpro gcpro1
;
4940 /* Function x_decode_color can signal an error. Make
4941 sure to initialize color slots so that we won't try
4942 to free colors we haven't allocated. */
4943 FRAME_FOREGROUND_PIXEL (f
) = -1;
4944 FRAME_BACKGROUND_PIXEL (f
) = -1;
4945 f
->output_data
.x
->cursor_pixel
= -1;
4946 f
->output_data
.x
->cursor_foreground_pixel
= -1;
4947 f
->output_data
.x
->border_pixel
= -1;
4948 f
->output_data
.x
->mouse_pixel
= -1;
4950 black
= build_string ("black");
4952 FRAME_FOREGROUND_PIXEL (f
)
4953 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
4954 FRAME_BACKGROUND_PIXEL (f
)
4955 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
4956 f
->output_data
.x
->cursor_pixel
4957 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
4958 f
->output_data
.x
->cursor_foreground_pixel
4959 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
4960 f
->output_data
.x
->border_pixel
4961 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
4962 f
->output_data
.x
->mouse_pixel
4963 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
4967 /* Set the name; the functions to which we pass f expect the name to
4969 if (EQ (name
, Qunbound
) || NILP (name
))
4971 f
->name
= build_string (dpyinfo
->x_id_name
);
4972 f
->explicit_name
= 0;
4977 f
->explicit_name
= 1;
4978 /* use the frame's title when getting resources for this frame. */
4979 specbind (Qx_resource_name
, name
);
4982 f
->resx
= dpyinfo
->resx
;
4983 f
->resy
= dpyinfo
->resy
;
4985 #ifdef USE_FONT_BACKEND
4986 if (enable_font_backend
)
4988 /* Perhaps, we must allow frame parameter, say `font-backend',
4989 to specify which font backends to use. */
4990 #ifdef HAVE_FREETYPE
4992 register_font_driver (&xftfont_driver
, f
);
4993 #else /* not HAVE_XFT */
4994 register_font_driver (&ftxfont_driver
, f
);
4995 #endif /* not HAVE_XFT */
4996 #endif /* HAVE_FREETYPE */
4997 register_font_driver (&xfont_driver
, f
);
4999 x_default_parameter (f
, parms
, Qfont_backend
, Qnil
,
5000 "fontBackend", "FontBackend", RES_TYPE_STRING
);
5002 #endif /* USE_FONT_BACKEND */
5004 /* Extract the window parameters from the supplied values that are
5005 needed to determine window geometry. */
5006 #ifdef USE_FONT_BACKEND
5007 if (enable_font_backend
)
5008 x_default_font_parameter (f
, parms
);
5010 #endif /* USE_FONT_BACKEND */
5014 font
= x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
5017 /* First, try whatever font the caller has specified. */
5020 tem
= Fquery_fontset (font
, Qnil
);
5022 font
= x_new_fontset (f
, tem
);
5024 font
= x_new_font (f
, SDATA (font
));
5027 /* Try out a font which we hope has bold and italic variations. */
5028 if (!STRINGP (font
))
5029 font
= x_new_font (f
, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
5030 if (!STRINGP (font
))
5031 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
5032 if (! STRINGP (font
))
5033 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
5034 if (! STRINGP (font
))
5035 /* This was formerly the first thing tried, but it finds too many fonts
5036 and takes too long. */
5037 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
5038 /* If those didn't work, look for something which will at least work. */
5039 if (! STRINGP (font
))
5040 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
5042 if (! STRINGP (font
))
5043 font
= build_string ("fixed");
5045 x_set_frame_parameters (f
, Fcons (Fcons (Qfont
, font
), Qnil
));
5048 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
5049 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
5051 /* This defaults to 2 in order to match xterm. We recognize either
5052 internalBorderWidth or internalBorder (which is what xterm calls
5054 if (NILP (Fassq (Qinternal_border_width
, parms
)))
5058 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
5059 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
5060 if (! EQ (value
, Qunbound
))
5061 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
5065 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
5066 "internalBorderWidth", "internalBorderWidth",
5069 /* Also do the stuff which must be set before the window exists. */
5070 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
5071 "foreground", "Foreground", RES_TYPE_STRING
);
5072 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
5073 "background", "Background", RES_TYPE_STRING
);
5074 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
5075 "pointerColor", "Foreground", RES_TYPE_STRING
);
5076 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
5077 "cursorColor", "Foreground", RES_TYPE_STRING
);
5078 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
5079 "borderColor", "BorderColor", RES_TYPE_STRING
);
5081 /* Init faces before x_default_parameter is called for scroll-bar
5082 parameters because that function calls x_set_scroll_bar_width,
5083 which calls change_frame_size, which calls Fset_window_buffer,
5084 which runs hooks, which call Fvertical_motion. At the end, we
5085 end up in init_iterator with a null face cache, which should not
5087 init_frame_faces (f
);
5089 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
5091 window_prompting
= x_figure_window_size (f
, parms
, 0);
5094 XSetWindowAttributes attrs
;
5098 mask
= CWBackPixel
| CWOverrideRedirect
| CWEventMask
;
5099 if (DoesSaveUnders (dpyinfo
->screen
))
5100 mask
|= CWSaveUnder
;
5102 /* Window managers look at the override-redirect flag to determine
5103 whether or net to give windows a decoration (Xlib spec, chapter
5105 attrs
.override_redirect
= True
;
5106 attrs
.save_under
= True
;
5107 attrs
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
5108 /* Arrange for getting MapNotify and UnmapNotify events. */
5109 attrs
.event_mask
= StructureNotifyMask
;
5111 = FRAME_X_WINDOW (f
)
5112 = XCreateWindow (FRAME_X_DISPLAY (f
),
5113 FRAME_X_DISPLAY_INFO (f
)->root_window
,
5114 /* x, y, width, height */
5118 CopyFromParent
, InputOutput
, CopyFromParent
,
5125 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
5126 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
5127 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
5128 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
5129 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
5130 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
5132 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
5133 Change will not be effected unless different from the current
5135 width
= FRAME_COLS (f
);
5136 height
= FRAME_LINES (f
);
5137 SET_FRAME_COLS (f
, 0);
5138 FRAME_LINES (f
) = 0;
5139 change_frame_size (f
, height
, width
, 1, 0, 0);
5141 /* Add `tooltip' frame parameter's default value. */
5142 if (NILP (Fframe_parameter (frame
, intern ("tooltip"))))
5143 Fmodify_frame_parameters (frame
, Fcons (Fcons (intern ("tooltip"), Qt
),
5146 /* FIXME - can this be done in a similar way to normal frames?
5147 http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
5149 /* Set the `display-type' frame parameter before setting up faces. */
5151 Lisp_Object disptype
;
5153 if (FRAME_X_DISPLAY_INFO (f
)->n_planes
== 1)
5154 disptype
= intern ("mono");
5155 else if (FRAME_X_DISPLAY_INFO (f
)->visual
->class == GrayScale
5156 || FRAME_X_DISPLAY_INFO (f
)->visual
->class == StaticGray
)
5157 disptype
= intern ("grayscale");
5159 disptype
= intern ("color");
5161 if (NILP (Fframe_parameter (frame
, Qdisplay_type
)))
5162 Fmodify_frame_parameters (frame
, Fcons (Fcons (Qdisplay_type
, disptype
),
5166 /* Set up faces after all frame parameters are known. This call
5167 also merges in face attributes specified for new frames.
5169 Frame parameters may be changed if .Xdefaults contains
5170 specifications for the default font. For example, if there is an
5171 `Emacs.default.attributeBackground: pink', the `background-color'
5172 attribute of the frame get's set, which let's the internal border
5173 of the tooltip frame appear in pink. Prevent this. */
5175 Lisp_Object bg
= Fframe_parameter (frame
, Qbackground_color
);
5177 /* Set tip_frame here, so that */
5179 call1 (Qface_set_after_frame_default
, frame
);
5181 if (!EQ (bg
, Fframe_parameter (frame
, Qbackground_color
)))
5182 Fmodify_frame_parameters (frame
, Fcons (Fcons (Qbackground_color
, bg
),
5190 /* It is now ok to make the frame official even if we get an error
5191 below. And the frame needs to be on Vframe_list or making it
5192 visible won't work. */
5193 Vframe_list
= Fcons (frame
, Vframe_list
);
5195 /* Now that the frame is official, it counts as a reference to
5197 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
5199 /* Setting attributes of faces of the tooltip frame from resources
5200 and similar will increment face_change_count, which leads to the
5201 clearing of all current matrices. Since this isn't necessary
5202 here, avoid it by resetting face_change_count to the value it
5203 had before we created the tip frame. */
5204 face_change_count
= face_change_count_before
;
5206 /* Discard the unwind_protect. */
5207 return unbind_to (count
, frame
);
5211 /* Compute where to display tip frame F. PARMS is the list of frame
5212 parameters for F. DX and DY are specified offsets from the current
5213 location of the mouse. WIDTH and HEIGHT are the width and height
5214 of the tooltip. Return coordinates relative to the root window of
5215 the display in *ROOT_X, and *ROOT_Y. */
5218 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, root_x
, root_y
)
5220 Lisp_Object parms
, dx
, dy
;
5222 int *root_x
, *root_y
;
5224 Lisp_Object left
, top
;
5229 /* User-specified position? */
5230 left
= Fcdr (Fassq (Qleft
, parms
));
5231 top
= Fcdr (Fassq (Qtop
, parms
));
5233 /* Move the tooltip window where the mouse pointer is. Resize and
5235 if (!INTEGERP (left
) || !INTEGERP (top
))
5238 XQueryPointer (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
5239 &root
, &child
, root_x
, root_y
, &win_x
, &win_y
, &pmask
);
5244 *root_y
= XINT (top
);
5245 else if (*root_y
+ XINT (dy
) <= 0)
5246 *root_y
= 0; /* Can happen for negative dy */
5247 else if (*root_y
+ XINT (dy
) + height
<= FRAME_X_DISPLAY_INFO (f
)->height
)
5248 /* It fits below the pointer */
5249 *root_y
+= XINT (dy
);
5250 else if (height
+ XINT (dy
) <= *root_y
)
5251 /* It fits above the pointer. */
5252 *root_y
-= height
+ XINT (dy
);
5254 /* Put it on the top. */
5257 if (INTEGERP (left
))
5258 *root_x
= XINT (left
);
5259 else if (*root_x
+ XINT (dx
) <= 0)
5260 *root_x
= 0; /* Can happen for negative dx */
5261 else if (*root_x
+ XINT (dx
) + width
<= FRAME_X_DISPLAY_INFO (f
)->width
)
5262 /* It fits to the right of the pointer. */
5263 *root_x
+= XINT (dx
);
5264 else if (width
+ XINT (dx
) <= *root_x
)
5265 /* It fits to the left of the pointer. */
5266 *root_x
-= width
+ XINT (dx
);
5268 /* Put it left-justified on the screen--it ought to fit that way. */
5273 DEFUN ("x-show-tip", Fx_show_tip
, Sx_show_tip
, 1, 6, 0,
5274 doc
: /* Show STRING in a "tooltip" window on frame FRAME.
5275 A tooltip window is a small X window displaying a string.
5277 This is an internal function; Lisp code should call `tooltip-show'.
5279 FRAME nil or omitted means use the selected frame.
5281 PARMS is an optional list of frame parameters which can be used to
5282 change the tooltip's appearance.
5284 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
5285 means use the default timeout of 5 seconds.
5287 If the list of frame parameters PARAMS contains a `left' parameters,
5288 the tooltip is displayed at that x-position. Otherwise it is
5289 displayed at the mouse position, with offset DX added (default is 5 if
5290 DX isn't specified). Likewise for the y-position; if a `top' frame
5291 parameter is specified, it determines the y-position of the tooltip
5292 window, otherwise it is displayed at the mouse position, with offset
5293 DY added (default is -10).
5295 A tooltip's maximum size is specified by `x-max-tooltip-size'.
5296 Text larger than the specified size is clipped. */)
5297 (string
, frame
, parms
, timeout
, dx
, dy
)
5298 Lisp_Object string
, frame
, parms
, timeout
, dx
, dy
;
5303 struct buffer
*old_buffer
;
5304 struct text_pos pos
;
5305 int i
, width
, height
;
5306 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
5307 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
5308 int count
= SPECPDL_INDEX ();
5310 specbind (Qinhibit_redisplay
, Qt
);
5312 GCPRO4 (string
, parms
, frame
, timeout
);
5314 CHECK_STRING (string
);
5315 f
= check_x_frame (frame
);
5317 timeout
= make_number (5);
5319 CHECK_NATNUM (timeout
);
5322 dx
= make_number (5);
5327 dy
= make_number (-10);
5331 if (NILP (last_show_tip_args
))
5332 last_show_tip_args
= Fmake_vector (make_number (3), Qnil
);
5334 if (!NILP (tip_frame
))
5336 Lisp_Object last_string
= AREF (last_show_tip_args
, 0);
5337 Lisp_Object last_frame
= AREF (last_show_tip_args
, 1);
5338 Lisp_Object last_parms
= AREF (last_show_tip_args
, 2);
5340 if (EQ (frame
, last_frame
)
5341 && !NILP (Fequal (last_string
, string
))
5342 && !NILP (Fequal (last_parms
, parms
)))
5344 struct frame
*f
= XFRAME (tip_frame
);
5346 /* Only DX and DY have changed. */
5347 if (!NILP (tip_timer
))
5349 Lisp_Object timer
= tip_timer
;
5351 call1 (Qcancel_timer
, timer
);
5355 compute_tip_xy (f
, parms
, dx
, dy
, FRAME_PIXEL_WIDTH (f
),
5356 FRAME_PIXEL_HEIGHT (f
), &root_x
, &root_y
);
5357 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5364 /* Hide a previous tip, if any. */
5367 ASET (last_show_tip_args
, 0, string
);
5368 ASET (last_show_tip_args
, 1, frame
);
5369 ASET (last_show_tip_args
, 2, parms
);
5371 /* Add default values to frame parameters. */
5372 if (NILP (Fassq (Qname
, parms
)))
5373 parms
= Fcons (Fcons (Qname
, build_string ("tooltip")), parms
);
5374 if (NILP (Fassq (Qinternal_border_width
, parms
)))
5375 parms
= Fcons (Fcons (Qinternal_border_width
, make_number (3)), parms
);
5376 if (NILP (Fassq (Qborder_width
, parms
)))
5377 parms
= Fcons (Fcons (Qborder_width
, make_number (1)), parms
);
5378 if (NILP (Fassq (Qborder_color
, parms
)))
5379 parms
= Fcons (Fcons (Qborder_color
, build_string ("lightyellow")), parms
);
5380 if (NILP (Fassq (Qbackground_color
, parms
)))
5381 parms
= Fcons (Fcons (Qbackground_color
, build_string ("lightyellow")),
5384 /* Create a frame for the tooltip, and record it in the global
5385 variable tip_frame. */
5386 frame
= x_create_tip_frame (FRAME_X_DISPLAY_INFO (f
), parms
, string
);
5389 /* Set up the frame's root window. */
5390 w
= XWINDOW (FRAME_ROOT_WINDOW (f
));
5391 w
->left_col
= w
->top_line
= make_number (0);
5393 if (CONSP (Vx_max_tooltip_size
)
5394 && INTEGERP (XCAR (Vx_max_tooltip_size
))
5395 && XINT (XCAR (Vx_max_tooltip_size
)) > 0
5396 && INTEGERP (XCDR (Vx_max_tooltip_size
))
5397 && XINT (XCDR (Vx_max_tooltip_size
)) > 0)
5399 w
->total_cols
= XCAR (Vx_max_tooltip_size
);
5400 w
->total_lines
= XCDR (Vx_max_tooltip_size
);
5404 w
->total_cols
= make_number (80);
5405 w
->total_lines
= make_number (40);
5408 FRAME_TOTAL_COLS (f
) = XINT (w
->total_cols
);
5410 w
->pseudo_window_p
= 1;
5412 /* Display the tooltip text in a temporary buffer. */
5413 old_buffer
= current_buffer
;
5414 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f
))->buffer
));
5415 current_buffer
->truncate_lines
= Qnil
;
5416 clear_glyph_matrix (w
->desired_matrix
);
5417 clear_glyph_matrix (w
->current_matrix
);
5418 SET_TEXT_POS (pos
, BEGV
, BEGV_BYTE
);
5419 try_window (FRAME_ROOT_WINDOW (f
), pos
, 0);
5421 /* Compute width and height of the tooltip. */
5423 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
5425 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
5429 /* Stop at the first empty row at the end. */
5430 if (!row
->enabled_p
|| !row
->displays_text_p
)
5433 /* Let the row go over the full width of the frame. */
5434 row
->full_width_p
= 1;
5436 /* There's a glyph at the end of rows that is used to place
5437 the cursor there. Don't include the width of this glyph. */
5438 if (row
->used
[TEXT_AREA
])
5440 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
5441 row_width
= row
->pixel_width
- last
->pixel_width
;
5444 row_width
= row
->pixel_width
;
5446 height
+= row
->height
;
5447 width
= max (width
, row_width
);
5450 /* Add the frame's internal border to the width and height the X
5451 window should have. */
5452 height
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
5453 width
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
5455 /* Move the tooltip window where the mouse pointer is. Resize and
5457 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, &root_x
, &root_y
);
5460 XMoveResizeWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5461 root_x
, root_y
, width
, height
);
5462 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
5465 /* Draw into the window. */
5466 w
->must_be_updated_p
= 1;
5467 update_single_window (w
, 1);
5469 /* Restore original current buffer. */
5470 set_buffer_internal_1 (old_buffer
);
5471 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
5474 /* Let the tip disappear after timeout seconds. */
5475 tip_timer
= call3 (intern ("run-at-time"), timeout
, Qnil
,
5476 intern ("x-hide-tip"));
5479 return unbind_to (count
, Qnil
);
5483 DEFUN ("x-hide-tip", Fx_hide_tip
, Sx_hide_tip
, 0, 0, 0,
5484 doc
: /* Hide the current tooltip window, if there is any.
5485 Value is t if tooltip was open, nil otherwise. */)
5489 Lisp_Object deleted
, frame
, timer
;
5490 struct gcpro gcpro1
, gcpro2
;
5492 /* Return quickly if nothing to do. */
5493 if (NILP (tip_timer
) && NILP (tip_frame
))
5498 GCPRO2 (frame
, timer
);
5499 tip_frame
= tip_timer
= deleted
= Qnil
;
5501 count
= SPECPDL_INDEX ();
5502 specbind (Qinhibit_redisplay
, Qt
);
5503 specbind (Qinhibit_quit
, Qt
);
5506 call1 (Qcancel_timer
, timer
);
5510 Fdelete_frame (frame
, Qnil
);
5514 /* Bloodcurdling hack alert: The Lucid menu bar widget's
5515 redisplay procedure is not called when a tip frame over menu
5516 items is unmapped. Redisplay the menu manually... */
5518 struct frame
*f
= SELECTED_FRAME ();
5519 Widget w
= f
->output_data
.x
->menubar_widget
;
5520 extern void xlwmenu_redisplay
P_ ((Widget
));
5522 if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f
)->screen
)
5526 xlwmenu_redisplay (w
);
5530 #endif /* USE_LUCID */
5534 return unbind_to (count
, deleted
);
5539 /***********************************************************************
5540 File selection dialog
5541 ***********************************************************************/
5543 DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog
,
5544 Sx_uses_old_gtk_dialog
,
5546 doc
: /* Return t if the old Gtk+ file selection dialog is used. */)
5550 extern int use_dialog_box
;
5551 extern int use_file_dialog
;
5556 && xg_uses_old_file_dialog ())
5564 /* Callback for "OK" and "Cancel" on file selection dialog. */
5567 file_dialog_cb (widget
, client_data
, call_data
)
5569 XtPointer call_data
, client_data
;
5571 int *result
= (int *) client_data
;
5572 XmAnyCallbackStruct
*cb
= (XmAnyCallbackStruct
*) call_data
;
5573 *result
= cb
->reason
;
5577 /* Callback for unmapping a file selection dialog. This is used to
5578 capture the case where a dialog is closed via a window manager's
5579 closer button, for example. Using a XmNdestroyCallback didn't work
5583 file_dialog_unmap_cb (widget
, client_data
, call_data
)
5585 XtPointer call_data
, client_data
;
5587 int *result
= (int *) client_data
;
5588 *result
= XmCR_CANCEL
;
5592 clean_up_file_dialog (arg
)
5595 struct Lisp_Save_Value
*p
= XSAVE_VALUE (arg
);
5596 Widget dialog
= (Widget
) p
->pointer
;
5600 XtUnmanageChild (dialog
);
5601 XtDestroyWidget (dialog
);
5602 x_menu_set_in_use (0);
5609 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 5, 0,
5610 doc
: /* Read file name, prompting with PROMPT in directory DIR.
5611 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5612 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5613 or directory must exist. ONLY-DIR-P is ignored." */)
5614 (prompt
, dir
, default_filename
, mustmatch
, only_dir_p
)
5615 Lisp_Object prompt
, dir
, default_filename
, mustmatch
, only_dir_p
;
5618 struct frame
*f
= SELECTED_FRAME ();
5619 Lisp_Object file
= Qnil
;
5620 Lisp_Object decoded_file
;
5621 Widget dialog
, text
, help
;
5624 extern XtAppContext Xt_app_con
;
5625 XmString dir_xmstring
, pattern_xmstring
;
5626 int count
= SPECPDL_INDEX ();
5627 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
, gcpro6
;
5631 GCPRO6 (prompt
, dir
, default_filename
, mustmatch
, only_dir_p
, file
);
5633 if (popup_activated ())
5634 error ("Trying to use a menu from within a menu-entry");
5636 CHECK_STRING (prompt
);
5639 /* Prevent redisplay. */
5640 specbind (Qinhibit_redisplay
, Qt
);
5644 /* Create the dialog with PROMPT as title, using DIR as initial
5645 directory and using "*" as pattern. */
5646 dir
= Fexpand_file_name (dir
, Qnil
);
5647 dir_xmstring
= XmStringCreateLocalized (SDATA (dir
));
5648 pattern_xmstring
= XmStringCreateLocalized ("*");
5650 XtSetArg (al
[ac
], XmNtitle
, SDATA (prompt
)); ++ac
;
5651 XtSetArg (al
[ac
], XmNdirectory
, dir_xmstring
); ++ac
;
5652 XtSetArg (al
[ac
], XmNpattern
, pattern_xmstring
); ++ac
;
5653 XtSetArg (al
[ac
], XmNresizePolicy
, XmRESIZE_GROW
); ++ac
;
5654 XtSetArg (al
[ac
], XmNdialogStyle
, XmDIALOG_APPLICATION_MODAL
); ++ac
;
5655 dialog
= XmCreateFileSelectionDialog (f
->output_data
.x
->widget
,
5657 XmStringFree (dir_xmstring
);
5658 XmStringFree (pattern_xmstring
);
5660 /* Add callbacks for OK and Cancel. */
5661 XtAddCallback (dialog
, XmNokCallback
, file_dialog_cb
,
5662 (XtPointer
) &result
);
5663 XtAddCallback (dialog
, XmNcancelCallback
, file_dialog_cb
,
5664 (XtPointer
) &result
);
5665 XtAddCallback (dialog
, XmNunmapCallback
, file_dialog_unmap_cb
,
5666 (XtPointer
) &result
);
5668 /* Remove the help button since we can't display help. */
5669 help
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_HELP_BUTTON
);
5670 XtUnmanageChild (help
);
5672 /* Mark OK button as default. */
5673 XtVaSetValues (XmFileSelectionBoxGetChild (dialog
, XmDIALOG_OK_BUTTON
),
5674 XmNshowAsDefault
, True
, NULL
);
5676 /* If MUSTMATCH is non-nil, disable the file entry field of the
5677 dialog, so that the user must select a file from the files list
5678 box. We can't remove it because we wouldn't have a way to get at
5679 the result file name, then. */
5680 text
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
5681 if (!NILP (mustmatch
))
5684 label
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_SELECTION_LABEL
);
5685 XtSetSensitive (text
, False
);
5686 XtSetSensitive (label
, False
);
5689 /* Manage the dialog, so that list boxes get filled. */
5690 XtManageChild (dialog
);
5692 if (STRINGP (default_filename
))
5694 XmString default_xmstring
;
5695 Widget wtext
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
5696 Widget list
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_LIST
);
5698 XmTextPosition last_pos
= XmTextFieldGetLastPosition (wtext
);
5699 XmTextFieldReplace (wtext
, 0, last_pos
,
5700 (SDATA (Ffile_name_nondirectory (default_filename
))));
5702 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
5703 must include the path for this to work. */
5705 default_xmstring
= XmStringCreateLocalized (SDATA (default_filename
));
5707 if (XmListItemExists (list
, default_xmstring
))
5709 int item_pos
= XmListItemPos (list
, default_xmstring
);
5710 /* Select the item and scroll it into view. */
5711 XmListSelectPos (list
, item_pos
, True
);
5712 XmListSetPos (list
, item_pos
);
5715 XmStringFree (default_xmstring
);
5718 record_unwind_protect (clean_up_file_dialog
, make_save_value (dialog
, 0));
5720 /* Process events until the user presses Cancel or OK. */
5721 x_menu_set_in_use (1);
5726 x_menu_wait_for_event (0);
5727 XtAppNextEvent (Xt_app_con
, &event
);
5728 if (event
.type
== KeyPress
5729 && FRAME_X_DISPLAY (f
) == event
.xkey
.display
)
5731 KeySym keysym
= XLookupKeysym (&event
.xkey
, 0);
5733 /* Pop down on C-g. */
5734 if (keysym
== XK_g
&& (event
.xkey
.state
& ControlMask
) != 0)
5735 XtUnmanageChild (dialog
);
5738 (void) x_dispatch_event (&event
, FRAME_X_DISPLAY (f
));
5741 /* Get the result. */
5742 if (result
== XmCR_OK
)
5747 XtVaGetValues (dialog
, XmNtextString
, &text
, NULL
);
5748 XmStringGetLtoR (text
, XmFONTLIST_DEFAULT_TAG
, &data
);
5749 XmStringFree (text
);
5750 file
= build_string (data
);
5759 /* Make "Cancel" equivalent to C-g. */
5761 Fsignal (Qquit
, Qnil
);
5763 decoded_file
= DECODE_FILE (file
);
5765 return unbind_to (count
, decoded_file
);
5768 #endif /* USE_MOTIF */
5773 clean_up_dialog (arg
)
5776 x_menu_set_in_use (0);
5781 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 5, 0,
5782 doc
: /* Read file name, prompting with PROMPT in directory DIR.
5783 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5784 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5785 or directory must exist. If ONLY-DIR-P is non-nil, the user can only select
5787 (prompt
, dir
, default_filename
, mustmatch
, only_dir_p
)
5788 Lisp_Object prompt
, dir
, default_filename
, mustmatch
, only_dir_p
;
5790 FRAME_PTR f
= SELECTED_FRAME ();
5792 Lisp_Object file
= Qnil
;
5793 Lisp_Object decoded_file
;
5794 int count
= SPECPDL_INDEX ();
5795 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
, gcpro6
;
5800 GCPRO6 (prompt
, dir
, default_filename
, mustmatch
, only_dir_p
, file
);
5802 if (popup_activated ())
5803 error ("Trying to use a menu from within a menu-entry");
5805 CHECK_STRING (prompt
);
5808 /* Prevent redisplay. */
5809 specbind (Qinhibit_redisplay
, Qt
);
5810 record_unwind_protect (clean_up_dialog
, Qnil
);
5814 if (STRINGP (default_filename
))
5815 cdef_file
= SDATA (default_filename
);
5817 cdef_file
= SDATA (dir
);
5819 fn
= xg_get_file_name (f
, SDATA (prompt
), cdef_file
,
5821 ! NILP (only_dir_p
));
5825 file
= build_string (fn
);
5832 /* Make "Cancel" equivalent to C-g. */
5834 Fsignal (Qquit
, Qnil
);
5836 decoded_file
= DECODE_FILE (file
);
5838 return unbind_to (count
, decoded_file
);
5841 #endif /* USE_GTK */
5844 /***********************************************************************
5846 ***********************************************************************/
5848 #ifdef HAVE_XKBGETKEYBOARD
5849 #include <X11/XKBlib.h>
5850 #include <X11/keysym.h>
5853 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p
,
5854 Sx_backspace_delete_keys_p
, 0, 1, 0,
5855 doc
: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
5856 FRAME nil means use the selected frame.
5857 Value is t if we know that both keys are present, and are mapped to the
5858 usual X keysyms. Value is `lambda' if we cannot determine if both keys are
5859 present and mapped to the usual X keysyms. */)
5863 #ifdef HAVE_XKBGETKEYBOARD
5865 struct frame
*f
= check_x_frame (frame
);
5866 Display
*dpy
= FRAME_X_DISPLAY (f
);
5867 Lisp_Object have_keys
;
5868 int major
, minor
, op
, event
, error
;
5872 /* Check library version in case we're dynamically linked. */
5873 major
= XkbMajorVersion
;
5874 minor
= XkbMinorVersion
;
5875 if (!XkbLibraryVersion (&major
, &minor
))
5881 /* Check that the server supports XKB. */
5882 major
= XkbMajorVersion
;
5883 minor
= XkbMinorVersion
;
5884 if (!XkbQueryExtension (dpy
, &op
, &event
, &error
, &major
, &minor
))
5890 /* In this code we check that the keyboard has physical keys with names
5891 that start with BKSP (Backspace) and DELE (Delete), and that they
5892 generate keysym XK_BackSpace and XK_Delete respectively.
5893 This function is used to test if normal-erase-is-backspace should be
5895 An alternative approach would be to just check if XK_BackSpace and
5896 XK_Delete are mapped to any key. But if any of those are mapped to
5897 some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the
5898 user doesn't know about it, it is better to return false here.
5899 It is more obvious to the user what to do if she/he has two keys
5900 clearly marked with names/symbols and one key does something not
5901 expected (i.e. she/he then tries the other).
5902 The cases where Backspace/Delete is mapped to some other key combination
5903 are rare, and in those cases, normal-erase-is-backspace can be turned on
5907 kb
= XkbGetMap (dpy
, XkbAllMapComponentsMask
, XkbUseCoreKbd
);
5910 int delete_keycode
= 0, backspace_keycode
= 0, i
;
5912 if (XkbGetNames (dpy
, XkbAllNamesMask
, kb
) == Success
)
5914 for (i
= kb
->min_key_code
;
5915 (i
< kb
->max_key_code
5916 && (delete_keycode
== 0 || backspace_keycode
== 0));
5919 /* The XKB symbolic key names can be seen most easily in
5920 the PS file generated by `xkbprint -label name
5922 if (bcmp ("DELE", kb
->names
->keys
[i
].name
, 4) == 0)
5924 else if (bcmp ("BKSP", kb
->names
->keys
[i
].name
, 4) == 0)
5925 backspace_keycode
= i
;
5928 XkbFreeNames (kb
, 0, True
);
5931 XkbFreeClientMap (kb
, 0, True
);
5934 && backspace_keycode
5935 && XKeysymToKeycode (dpy
, XK_Delete
) == delete_keycode
5936 && XKeysymToKeycode (dpy
, XK_BackSpace
) == backspace_keycode
)
5941 #else /* not HAVE_XKBGETKEYBOARD */
5943 #endif /* not HAVE_XKBGETKEYBOARD */
5948 /***********************************************************************
5950 ***********************************************************************/
5952 /* Keep this list in the same order as frame_parms in frame.c.
5953 Use 0 for unsupported frame parameters. */
5955 frame_parm_handler x_frame_parm_handlers
[] =
5959 x_set_background_color
,
5965 x_set_foreground_color
,
5968 x_set_internal_border_width
,
5969 x_set_menu_bar_lines
,
5971 x_explicitly_set_name
,
5972 x_set_scroll_bar_width
,
5975 x_set_vertical_scroll_bars
,
5977 x_set_tool_bar_lines
,
5978 x_set_scroll_bar_foreground
,
5979 x_set_scroll_bar_background
,
5986 #ifdef USE_FONT_BACKEND
5988 #endif /* USE_FONT_BACKEND */
5994 /* This is zero if not using X windows. */
5997 /* The section below is built by the lisp expression at the top of the file,
5998 just above where these variables are declared. */
5999 /*&&& init symbols here &&&*/
6000 Qnone
= intern ("none");
6002 Qsuppress_icon
= intern ("suppress-icon");
6003 staticpro (&Qsuppress_icon
);
6004 Qundefined_color
= intern ("undefined-color");
6005 staticpro (&Qundefined_color
);
6006 Qcompound_text
= intern ("compound-text");
6007 staticpro (&Qcompound_text
);
6008 Qcancel_timer
= intern ("cancel-timer");
6009 staticpro (&Qcancel_timer
);
6010 /* This is the end of symbol initialization. */
6012 /* Text property `display' should be nonsticky by default. */
6013 Vtext_property_default_nonsticky
6014 = Fcons (Fcons (Qdisplay
, Qt
), Vtext_property_default_nonsticky
);
6017 Fput (Qundefined_color
, Qerror_conditions
,
6018 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
6019 Fput (Qundefined_color
, Qerror_message
,
6020 build_string ("Undefined color"));
6022 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
6023 doc
: /* The shape of the pointer when over text.
6024 Changing the value does not affect existing frames
6025 unless you set the mouse color. */);
6026 Vx_pointer_shape
= Qnil
;
6028 #if 0 /* This doesn't really do anything. */
6029 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape
,
6030 doc
: /* The shape of the pointer when not over text.
6031 This variable takes effect when you create a new frame
6032 or when you set the mouse color. */);
6034 Vx_nontext_pointer_shape
= Qnil
;
6036 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape
,
6037 doc
: /* The shape of the pointer when Emacs is busy.
6038 This variable takes effect when you create a new frame
6039 or when you set the mouse color. */);
6040 Vx_hourglass_pointer_shape
= Qnil
;
6042 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p
,
6043 doc
: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
6044 display_hourglass_p
= 1;
6046 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay
,
6047 doc
: /* *Seconds to wait before displaying an hourglass pointer.
6048 Value must be an integer or float. */);
6049 Vhourglass_delay
= make_number (DEFAULT_HOURGLASS_DELAY
);
6051 #if 0 /* This doesn't really do anything. */
6052 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape
,
6053 doc
: /* The shape of the pointer when over the mode line.
6054 This variable takes effect when you create a new frame
6055 or when you set the mouse color. */);
6057 Vx_mode_pointer_shape
= Qnil
;
6059 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
6060 &Vx_sensitive_text_pointer_shape
,
6061 doc
: /* The shape of the pointer when over mouse-sensitive text.
6062 This variable takes effect when you create a new frame
6063 or when you set the mouse color. */);
6064 Vx_sensitive_text_pointer_shape
= Qnil
;
6066 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
6067 &Vx_window_horizontal_drag_shape
,
6068 doc
: /* Pointer shape to use for indicating a window can be dragged horizontally.
6069 This variable takes effect when you create a new frame
6070 or when you set the mouse color. */);
6071 Vx_window_horizontal_drag_shape
= Qnil
;
6073 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
6074 doc
: /* A string indicating the foreground color of the cursor box. */);
6075 Vx_cursor_fore_pixel
= Qnil
;
6077 DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size
,
6078 doc
: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).
6079 Text larger than this is clipped. */);
6080 Vx_max_tooltip_size
= Fcons (make_number (80), make_number (40));
6082 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
6083 doc
: /* Non-nil if no X window manager is in use.
6084 Emacs doesn't try to figure this out; this is always nil
6085 unless you set it to something else. */);
6086 /* We don't have any way to find this out, so set it to nil
6087 and maybe the user would like to set it to t. */
6088 Vx_no_window_manager
= Qnil
;
6090 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
6091 &Vx_pixel_size_width_font_regexp
,
6092 doc
: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
6094 Since Emacs gets width of a font matching with this regexp from
6095 PIXEL_SIZE field of the name, font finding mechanism gets faster for
6096 such a font. This is especially effective for such large fonts as
6097 Chinese, Japanese, and Korean. */);
6098 Vx_pixel_size_width_font_regexp
= Qnil
;
6100 /* This is not ifdef:ed, so other builds than GTK can customize it. */
6101 DEFVAR_BOOL ("x-gtk-use-old-file-dialog", &x_gtk_use_old_file_dialog
,
6102 doc
: /* *Non-nil means prompt with the old GTK file selection dialog.
6103 If nil or if the file selection dialog is not available, the new GTK file
6104 chooser is used instead. To turn off all file dialogs set the
6105 variable `use-file-dialog'. */);
6106 x_gtk_use_old_file_dialog
= 0;
6108 DEFVAR_BOOL ("x-gtk-show-hidden-files", &x_gtk_show_hidden_files
,
6109 doc
: /* *If non-nil, the GTK file chooser will by default show hidden files.
6110 Note that this is just the default, there is a toggle button on the file
6111 chooser to show or not show hidden files on a case by case basis. */);
6112 x_gtk_show_hidden_files
= 0;
6114 DEFVAR_BOOL ("x-gtk-file-dialog-help-text", &x_gtk_file_dialog_help_text
,
6115 doc
: /* *If non-nil, the GTK file chooser will show additional help text.
6116 If more space for files in the file chooser dialog is wanted, set this to nil
6117 to turn the additional text off. */);
6118 x_gtk_file_dialog_help_text
= 1;
6120 DEFVAR_BOOL ("x-gtk-whole-detached-tool-bar", &x_gtk_whole_detached_tool_bar
,
6121 doc
: /* *If non-nil, a detached tool bar is shown in full.
6122 The default is to just show an arrow and pressing on that arrow shows
6123 the tool bar buttons. */);
6124 x_gtk_whole_detached_tool_bar
= 0;
6126 Fprovide (intern ("x"), Qnil
);
6128 #ifdef USE_X_TOOLKIT
6129 Fprovide (intern ("x-toolkit"), Qnil
);
6131 Fprovide (intern ("motif"), Qnil
);
6133 DEFVAR_LISP ("motif-version-string", &Vmotif_version_string
,
6134 doc
: /* Version info for LessTif/Motif. */);
6135 Vmotif_version_string
= build_string (XmVERSION_STRING
);
6136 #endif /* USE_MOTIF */
6137 #endif /* USE_X_TOOLKIT */
6140 /* Provide x-toolkit also for GTK. Internally GTK does not use Xt so it
6141 is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
6142 But for a user it is a toolkit for X, and indeed, configure
6143 accepts --with-x-toolkit=gtk. */
6144 Fprovide (intern ("x-toolkit"), Qnil
);
6145 Fprovide (intern ("gtk"), Qnil
);
6147 DEFVAR_LISP ("gtk-version-string", &Vgtk_version_string
,
6148 doc
: /* Version info for GTK+. */);
6150 char gtk_version
[40];
6151 g_snprintf (gtk_version
, sizeof (gtk_version
), "%u.%u.%u",
6152 GTK_MAJOR_VERSION
, GTK_MINOR_VERSION
, GTK_MICRO_VERSION
);
6153 Vgtk_version_string
= build_string (gtk_version
);
6155 #endif /* USE_GTK */
6157 /* X window properties. */
6158 defsubr (&Sx_change_window_property
);
6159 defsubr (&Sx_delete_window_property
);
6160 defsubr (&Sx_window_property
);
6162 defsubr (&Sxw_display_color_p
);
6163 defsubr (&Sx_display_grayscale_p
);
6164 defsubr (&Sxw_color_defined_p
);
6165 defsubr (&Sxw_color_values
);
6166 defsubr (&Sx_server_max_request_size
);
6167 defsubr (&Sx_server_vendor
);
6168 defsubr (&Sx_server_version
);
6169 defsubr (&Sx_display_pixel_width
);
6170 defsubr (&Sx_display_pixel_height
);
6171 defsubr (&Sx_display_mm_width
);
6172 defsubr (&Sx_display_mm_height
);
6173 defsubr (&Sx_display_screens
);
6174 defsubr (&Sx_display_planes
);
6175 defsubr (&Sx_display_color_cells
);
6176 defsubr (&Sx_display_visual_class
);
6177 defsubr (&Sx_display_backing_store
);
6178 defsubr (&Sx_display_save_under
);
6179 defsubr (&Sx_create_frame
);
6180 defsubr (&Sx_open_connection
);
6181 defsubr (&Sx_close_connection
);
6182 defsubr (&Sx_display_list
);
6183 defsubr (&Sx_synchronize
);
6184 defsubr (&Sx_focus_frame
);
6185 defsubr (&Sx_backspace_delete_keys_p
);
6187 /* Setting callback functions for fontset handler. */
6188 get_font_info_func
= x_get_font_info
;
6190 #if 0 /* This function pointer doesn't seem to be used anywhere.
6191 And the pointer assigned has the wrong type, anyway. */
6192 list_fonts_func
= x_list_fonts
;
6195 load_font_func
= x_load_font
;
6196 find_ccl_program_func
= x_find_ccl_program
;
6197 query_font_func
= x_query_font
;
6198 set_frame_fontset_func
= x_set_font
;
6199 get_font_repertory_func
= x_get_font_repertory
;
6200 check_window_system_func
= check_x
;
6202 hourglass_atimer
= NULL
;
6203 hourglass_shown_p
= 0;
6205 defsubr (&Sx_show_tip
);
6206 defsubr (&Sx_hide_tip
);
6208 staticpro (&tip_timer
);
6210 staticpro (&tip_frame
);
6212 last_show_tip_args
= Qnil
;
6213 staticpro (&last_show_tip_args
);
6215 defsubr (&Sx_uses_old_gtk_dialog
);
6216 #if defined (USE_MOTIF) || defined (USE_GTK)
6217 defsubr (&Sx_file_dialog
);
6221 #endif /* HAVE_X_WINDOWS */
6223 /* arch-tag: 55040d02-5485-4d58-8b22-95a7a05f3288
6224 (do not change this comment) */