1 /* Functions for the X window system.
3 Copyright (C) 1989, 1992-2014 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
30 #include "character.h"
32 #include "intervals.h"
33 #include "dispextern.h"
35 #include "blockinput.h"
41 #include "termhooks.h"
46 #include <sys/types.h>
49 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */
50 #include "bitmaps/gray.xbm"
52 #include <X11/bitmaps/gray>
55 #include "xsettings.h"
58 #include <X11/extensions/Xrandr.h>
61 #include <X11/extensions/Xinerama.h>
69 #include <X11/Shell.h>
73 #include <X11/Xaw3d/Paned.h>
74 #include <X11/Xaw3d/Label.h>
75 #else /* !HAVE_XAW3D */
76 #include <X11/Xaw/Paned.h>
77 #include <X11/Xaw/Label.h>
78 #endif /* HAVE_XAW3D */
79 #endif /* USE_MOTIF */
82 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
85 #ifdef USG /* Pacify gcc -Wunused-macros. */
93 #include "../lwlib/lwlib.h"
97 #include <Xm/DialogS.h>
98 #include <Xm/FileSB.h>
100 #include <Xm/TextF.h>
104 #include "../lwlib/xlwmenu.h"
107 #if !defined (NO_EDITRES)
109 extern void _XEditResCheckMessages (Widget
, XtPointer
, XEvent
*, Boolean
*);
110 #endif /* not defined NO_EDITRES */
112 /* Unique id counter for widgets created by the Lucid Widget Library. */
114 extern LWLIB_ID widget_id_tick
;
118 #endif /* USE_MOTIF */
120 #endif /* USE_X_TOOLKIT */
126 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
128 static Lisp_Object Qundefined_color
;
129 static Lisp_Object Qcompound_text
, Qcancel_timer
;
130 Lisp_Object Qfont_param
;
133 static ptrdiff_t image_cache_refcount
;
134 static int dpyinfo_refcount
;
137 static struct x_display_info
*x_display_info_for_name (Lisp_Object
);
139 /* Let the user specify an X display with a Lisp object.
140 OBJECT may be nil, a frame or a terminal object.
141 nil stands for the selected frame--or, if that is not an X frame,
142 the first X display on the list. */
144 struct x_display_info
*
145 check_x_display_info (Lisp_Object object
)
147 struct x_display_info
*dpyinfo
= NULL
;
151 struct frame
*sf
= XFRAME (selected_frame
);
153 if (FRAME_X_P (sf
) && FRAME_LIVE_P (sf
))
154 dpyinfo
= FRAME_DISPLAY_INFO (sf
);
155 else if (x_display_list
!= 0)
156 dpyinfo
= x_display_list
;
158 error ("X windows are not in use or not initialized");
160 else if (TERMINALP (object
))
162 struct terminal
*t
= decode_live_terminal (object
);
164 if (t
->type
!= output_x_window
)
165 error ("Terminal %d is not an X display", t
->id
);
167 dpyinfo
= t
->display_info
.x
;
169 else if (STRINGP (object
))
170 dpyinfo
= x_display_info_for_name (object
);
173 struct frame
*f
= decode_window_system_frame (object
);
174 dpyinfo
= FRAME_DISPLAY_INFO (f
);
180 /* Store the screen positions of frame F into XPTR and YPTR.
181 These are the positions of the containing window manager window,
182 not Emacs's own window. */
185 x_real_positions (struct frame
*f
, int *xptr
, int *yptr
)
187 int win_x
, win_y
, outer_x
IF_LINT (= 0), outer_y
IF_LINT (= 0);
188 int real_x
= 0, real_y
= 0;
190 Window win
= f
->output_data
.x
->parent_desc
;
192 unsigned long actual_size
, bytes_remaining
;
193 int rc
, actual_format
;
194 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
196 Display
*dpy
= FRAME_X_DISPLAY (f
);
197 unsigned char *tmp_data
= NULL
;
198 Atom target_type
= XA_CARDINAL
;
202 x_catch_errors (dpy
);
204 if (win
== dpyinfo
->root_window
)
205 win
= FRAME_OUTER_WINDOW (f
);
207 /* This loop traverses up the containment tree until we hit the root
208 window. Window managers may intersect many windows between our window
209 and the root window. The window we find just before the root window
210 should be the outer WM window. */
213 Window wm_window
, rootw
;
214 Window
*tmp_children
;
215 unsigned int tmp_nchildren
;
218 success
= XQueryTree (FRAME_X_DISPLAY (f
), win
, &rootw
,
219 &wm_window
, &tmp_children
, &tmp_nchildren
);
221 had_errors
= x_had_errors_p (FRAME_X_DISPLAY (f
));
223 /* Don't free tmp_children if XQueryTree failed. */
227 XFree (tmp_children
);
229 if (wm_window
== rootw
|| had_errors
)
240 /* Get the real coordinates for the WM window upper left corner */
241 XGetGeometry (FRAME_X_DISPLAY (f
), win
,
242 &rootw
, &real_x
, &real_y
, &ign
, &ign
, &ign
, &ign
);
244 /* Translate real coordinates to coordinates relative to our
245 window. For our window, the upper left corner is 0, 0.
246 Since the upper left corner of the WM window is outside
247 our window, win_x and win_y will be negative:
249 ------------------ ---> x
251 | ----------------- v y
254 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
256 /* From-window, to-window. */
257 FRAME_DISPLAY_INFO (f
)->root_window
,
260 /* From-position, to-position. */
261 real_x
, real_y
, &win_x
, &win_y
,
266 if (FRAME_X_WINDOW (f
) == FRAME_OUTER_WINDOW (f
))
273 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
275 /* From-window, to-window. */
276 FRAME_DISPLAY_INFO (f
)->root_window
,
277 FRAME_OUTER_WINDOW (f
),
279 /* From-position, to-position. */
280 real_x
, real_y
, &outer_x
, &outer_y
,
286 had_errors
= x_had_errors_p (FRAME_X_DISPLAY (f
));
290 if (dpyinfo
->root_window
== f
->output_data
.x
->parent_desc
)
292 /* Try _NET_FRAME_EXTENTS if our parent is the root window. */
293 rc
= XGetWindowProperty (dpy
, win
, dpyinfo
->Xatom_net_frame_extents
,
294 0, max_len
, False
, target_type
,
295 &actual_type
, &actual_format
, &actual_size
,
296 &bytes_remaining
, &tmp_data
);
298 if (rc
== Success
&& actual_type
== target_type
&& !x_had_errors_p (dpy
)
299 && actual_size
== 4 && actual_format
== 32)
303 long *fe
= (long *)tmp_data
;
305 XGetGeometry (FRAME_X_DISPLAY (f
), win
,
306 &rootw
, &real_x
, &real_y
, &ign
, &ign
, &ign
, &ign
);
314 if (tmp_data
) XFree (tmp_data
);
320 if (had_errors
) return;
322 f
->x_pixels_diff
= -win_x
;
323 f
->y_pixels_diff
= -win_y
;
325 FRAME_X_OUTPUT (f
)->x_pixels_outer_diff
= -outer_x
;
326 FRAME_X_OUTPUT (f
)->y_pixels_outer_diff
= -outer_y
;
332 /* Get the mouse position in frame relative coordinates. */
335 x_relative_mouse_position (struct frame
*f
, int *x
, int *y
)
337 Window root
, dummy_window
;
340 eassert (FRAME_X_P (f
));
344 XQueryPointer (FRAME_X_DISPLAY (f
),
345 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
347 /* The root window which contains the pointer. */
350 /* Window pointer is on, not used */
353 /* The position on that root window. */
356 /* x/y in dummy_window coordinates, not used. */
359 /* Modifier keys and pointer buttons, about which
361 (unsigned int *) &dummy
);
365 /* Translate root window coordinates to window coordinates. */
366 *x
-= f
->left_pos
+ FRAME_OUTER_TO_INNER_DIFF_X (f
);
367 *y
-= f
->top_pos
+ FRAME_OUTER_TO_INNER_DIFF_Y (f
);
370 /* Gamma-correct COLOR on frame F. */
373 gamma_correct (struct frame
*f
, XColor
*color
)
377 color
->red
= pow (color
->red
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
378 color
->green
= pow (color
->green
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
379 color
->blue
= pow (color
->blue
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
384 /* Decide if color named COLOR_NAME is valid for use on frame F. If
385 so, return the RGB values in COLOR. If ALLOC_P,
386 allocate the color. Value is false if COLOR_NAME is invalid, or
387 no color could be allocated. */
390 x_defined_color (struct frame
*f
, const char *color_name
,
391 XColor
*color
, bool alloc_p
)
394 Display
*dpy
= FRAME_X_DISPLAY (f
);
395 Colormap cmap
= FRAME_X_COLORMAP (f
);
399 success_p
= xg_check_special_colors (f
, color_name
, color
);
402 success_p
= XParseColor (dpy
, cmap
, color_name
, color
) != 0;
403 if (success_p
&& alloc_p
)
404 success_p
= x_alloc_nearest_color (f
, cmap
, color
);
411 /* Return the pixel color value for color COLOR_NAME on frame F. If F
412 is a monochrome frame, return MONO_COLOR regardless of what ARG says.
413 Signal an error if color can't be allocated. */
416 x_decode_color (struct frame
*f
, Lisp_Object color_name
, int mono_color
)
420 CHECK_STRING (color_name
);
422 #if 0 /* Don't do this. It's wrong when we're not using the default
423 colormap, it makes freeing difficult, and it's probably not
424 an important optimization. */
425 if (strcmp (SDATA (color_name
), "black") == 0)
426 return BLACK_PIX_DEFAULT (f
);
427 else if (strcmp (SDATA (color_name
), "white") == 0)
428 return WHITE_PIX_DEFAULT (f
);
431 /* Return MONO_COLOR for monochrome frames. */
432 if (FRAME_DISPLAY_INFO (f
)->n_planes
== 1)
435 /* x_defined_color is responsible for coping with failures
436 by looking for a near-miss. */
437 if (x_defined_color (f
, SSDATA (color_name
), &cdef
, 1))
440 signal_error ("Undefined color", color_name
);
445 /* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
446 the previous value of that parameter, NEW_VALUE is the new value.
447 See also the comment of wait_for_wm in struct x_output. */
450 x_set_wait_for_wm (struct frame
*f
, Lisp_Object new_value
, Lisp_Object old_value
)
452 f
->output_data
.x
->wait_for_wm
= !NILP (new_value
);
456 x_set_tool_bar_position (struct frame
*f
,
457 Lisp_Object new_value
,
458 Lisp_Object old_value
)
460 Lisp_Object choice
= list4 (Qleft
, Qright
, Qtop
, Qbottom
);
462 if (!NILP (Fmemq (new_value
, choice
)))
465 if (!EQ (new_value
, old_value
))
467 xg_change_toolbar_position (f
, new_value
);
468 fset_tool_bar_position (f
, new_value
);
471 if (!EQ (new_value
, Qtop
))
472 error ("The only supported tool bar position is top");
476 wrong_choice (choice
, new_value
);
481 /* Set icon from FILE for frame F. By using GTK functions the icon
482 may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
485 xg_set_icon (struct frame
*f
, Lisp_Object file
)
490 found
= x_find_image_file (file
);
496 char *filename
= SSDATA (found
);
499 pixbuf
= gdk_pixbuf_new_from_file (filename
, &err
);
503 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
505 g_object_unref (pixbuf
);
519 xg_set_icon_from_xpm_data (struct frame
*f
, const char **data
)
521 GdkPixbuf
*pixbuf
= gdk_pixbuf_new_from_xpm_data (data
);
526 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)), pixbuf
);
527 g_object_unref (pixbuf
);
533 /* Functions called only from `x_set_frame_param'
534 to set individual parameters.
536 If FRAME_X_WINDOW (f) is 0,
537 the frame is being created and its X-window does not exist yet.
538 In that case, just record the parameter's new value
539 in the standard place; do not attempt to change the window. */
542 x_set_foreground_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
544 struct x_output
*x
= f
->output_data
.x
;
545 unsigned long fg
, old_fg
;
547 fg
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
548 old_fg
= FRAME_FOREGROUND_PIXEL (f
);
549 FRAME_FOREGROUND_PIXEL (f
) = fg
;
551 if (FRAME_X_WINDOW (f
) != 0)
553 Display
*dpy
= FRAME_X_DISPLAY (f
);
556 XSetForeground (dpy
, x
->normal_gc
, fg
);
557 XSetBackground (dpy
, x
->reverse_gc
, fg
);
559 if (x
->cursor_pixel
== old_fg
)
561 unload_color (f
, x
->cursor_pixel
);
562 x
->cursor_pixel
= x_copy_color (f
, fg
);
563 XSetBackground (dpy
, x
->cursor_gc
, x
->cursor_pixel
);
568 update_face_from_frame_parameter (f
, Qforeground_color
, arg
);
570 if (FRAME_VISIBLE_P (f
))
574 unload_color (f
, old_fg
);
578 x_set_background_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
580 struct x_output
*x
= f
->output_data
.x
;
583 bg
= x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
584 unload_color (f
, FRAME_BACKGROUND_PIXEL (f
));
585 FRAME_BACKGROUND_PIXEL (f
) = bg
;
587 if (FRAME_X_WINDOW (f
) != 0)
589 Display
*dpy
= FRAME_X_DISPLAY (f
);
592 XSetBackground (dpy
, x
->normal_gc
, bg
);
593 XSetForeground (dpy
, x
->reverse_gc
, bg
);
594 XSetWindowBackground (dpy
, FRAME_X_WINDOW (f
), bg
);
595 XSetForeground (dpy
, x
->cursor_gc
, bg
);
598 xg_set_background_color (f
, bg
);
601 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
602 toolkit scroll bars. */
605 for (bar
= FRAME_SCROLL_BARS (f
);
607 bar
= XSCROLL_BAR (bar
)->next
)
609 Window window
= XSCROLL_BAR (bar
)->x_window
;
610 XSetWindowBackground (dpy
, window
, bg
);
613 #endif /* USE_TOOLKIT_SCROLL_BARS */
616 update_face_from_frame_parameter (f
, Qbackground_color
, arg
);
618 if (FRAME_VISIBLE_P (f
))
624 x_set_mouse_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
626 struct x_output
*x
= f
->output_data
.x
;
627 Display
*dpy
= FRAME_X_DISPLAY (f
);
628 Cursor cursor
, nontext_cursor
, mode_cursor
, hand_cursor
;
629 Cursor hourglass_cursor
, horizontal_drag_cursor
, vertical_drag_cursor
;
630 unsigned long pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
631 unsigned long mask_color
= FRAME_BACKGROUND_PIXEL (f
);
633 /* Don't let pointers be invisible. */
634 if (mask_color
== pixel
)
636 x_free_colors (f
, &pixel
, 1);
637 pixel
= x_copy_color (f
, FRAME_FOREGROUND_PIXEL (f
));
640 unload_color (f
, x
->mouse_pixel
);
641 x
->mouse_pixel
= pixel
;
645 /* It's not okay to crash if the user selects a screwy cursor. */
646 x_catch_errors (dpy
);
648 if (!NILP (Vx_pointer_shape
))
650 CHECK_NUMBER (Vx_pointer_shape
);
651 cursor
= XCreateFontCursor (dpy
, XINT (Vx_pointer_shape
));
654 cursor
= XCreateFontCursor (dpy
, XC_xterm
);
655 x_check_errors (dpy
, "bad text pointer cursor: %s");
657 if (!NILP (Vx_nontext_pointer_shape
))
659 CHECK_NUMBER (Vx_nontext_pointer_shape
);
661 = XCreateFontCursor (dpy
, XINT (Vx_nontext_pointer_shape
));
664 nontext_cursor
= XCreateFontCursor (dpy
, XC_left_ptr
);
665 x_check_errors (dpy
, "bad nontext pointer cursor: %s");
667 if (!NILP (Vx_hourglass_pointer_shape
))
669 CHECK_NUMBER (Vx_hourglass_pointer_shape
);
671 = XCreateFontCursor (dpy
, XINT (Vx_hourglass_pointer_shape
));
674 hourglass_cursor
= XCreateFontCursor (dpy
, XC_watch
);
675 x_check_errors (dpy
, "bad hourglass pointer cursor: %s");
677 if (!NILP (Vx_mode_pointer_shape
))
679 CHECK_NUMBER (Vx_mode_pointer_shape
);
680 mode_cursor
= XCreateFontCursor (dpy
, XINT (Vx_mode_pointer_shape
));
683 mode_cursor
= XCreateFontCursor (dpy
, XC_xterm
);
684 x_check_errors (dpy
, "bad modeline pointer cursor: %s");
686 if (!NILP (Vx_sensitive_text_pointer_shape
))
688 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
);
690 = XCreateFontCursor (dpy
, XINT (Vx_sensitive_text_pointer_shape
));
693 hand_cursor
= XCreateFontCursor (dpy
, XC_hand2
);
695 if (!NILP (Vx_window_horizontal_drag_shape
))
697 CHECK_TYPE_RANGED_INTEGER (unsigned, Vx_window_horizontal_drag_shape
);
698 horizontal_drag_cursor
699 = XCreateFontCursor (dpy
, XINT (Vx_window_horizontal_drag_shape
));
702 horizontal_drag_cursor
703 = XCreateFontCursor (dpy
, XC_sb_h_double_arrow
);
705 if (!NILP (Vx_window_vertical_drag_shape
))
707 CHECK_NUMBER (Vx_window_vertical_drag_shape
);
709 = XCreateFontCursor (dpy
, XINT (Vx_window_vertical_drag_shape
));
713 = XCreateFontCursor (dpy
, XC_sb_v_double_arrow
);
715 /* Check and report errors with the above calls. */
716 x_check_errors (dpy
, "can't set cursor shape: %s");
720 XColor fore_color
, back_color
;
722 fore_color
.pixel
= x
->mouse_pixel
;
723 x_query_color (f
, &fore_color
);
724 back_color
.pixel
= mask_color
;
725 x_query_color (f
, &back_color
);
727 XRecolorCursor (dpy
, cursor
, &fore_color
, &back_color
);
728 XRecolorCursor (dpy
, nontext_cursor
, &fore_color
, &back_color
);
729 XRecolorCursor (dpy
, mode_cursor
, &fore_color
, &back_color
);
730 XRecolorCursor (dpy
, hand_cursor
, &fore_color
, &back_color
);
731 XRecolorCursor (dpy
, hourglass_cursor
, &fore_color
, &back_color
);
732 XRecolorCursor (dpy
, horizontal_drag_cursor
, &fore_color
, &back_color
);
733 XRecolorCursor (dpy
, vertical_drag_cursor
, &fore_color
, &back_color
);
736 if (FRAME_X_WINDOW (f
) != 0)
737 XDefineCursor (dpy
, FRAME_X_WINDOW (f
),
738 f
->output_data
.x
->current_cursor
= cursor
);
740 if (cursor
!= x
->text_cursor
741 && x
->text_cursor
!= 0)
742 XFreeCursor (dpy
, x
->text_cursor
);
743 x
->text_cursor
= cursor
;
745 if (nontext_cursor
!= x
->nontext_cursor
746 && x
->nontext_cursor
!= 0)
747 XFreeCursor (dpy
, x
->nontext_cursor
);
748 x
->nontext_cursor
= nontext_cursor
;
750 if (hourglass_cursor
!= x
->hourglass_cursor
751 && x
->hourglass_cursor
!= 0)
752 XFreeCursor (dpy
, x
->hourglass_cursor
);
753 x
->hourglass_cursor
= hourglass_cursor
;
755 if (mode_cursor
!= x
->modeline_cursor
756 && x
->modeline_cursor
!= 0)
757 XFreeCursor (dpy
, f
->output_data
.x
->modeline_cursor
);
758 x
->modeline_cursor
= mode_cursor
;
760 if (hand_cursor
!= x
->hand_cursor
761 && x
->hand_cursor
!= 0)
762 XFreeCursor (dpy
, x
->hand_cursor
);
763 x
->hand_cursor
= hand_cursor
;
765 if (horizontal_drag_cursor
!= x
->horizontal_drag_cursor
766 && x
->horizontal_drag_cursor
!= 0)
767 XFreeCursor (dpy
, x
->horizontal_drag_cursor
);
768 x
->horizontal_drag_cursor
= horizontal_drag_cursor
;
770 if (vertical_drag_cursor
!= x
->vertical_drag_cursor
771 && x
->vertical_drag_cursor
!= 0)
772 XFreeCursor (dpy
, x
->vertical_drag_cursor
);
773 x
->vertical_drag_cursor
= vertical_drag_cursor
;
778 update_face_from_frame_parameter (f
, Qmouse_color
, arg
);
782 x_set_cursor_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
784 unsigned long fore_pixel
, pixel
;
785 bool fore_pixel_allocated_p
= 0, pixel_allocated_p
= 0;
786 struct x_output
*x
= f
->output_data
.x
;
788 if (!NILP (Vx_cursor_fore_pixel
))
790 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
791 WHITE_PIX_DEFAULT (f
));
792 fore_pixel_allocated_p
= 1;
795 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
797 pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
798 pixel_allocated_p
= 1;
800 /* Make sure that the cursor color differs from the background color. */
801 if (pixel
== FRAME_BACKGROUND_PIXEL (f
))
803 if (pixel_allocated_p
)
805 x_free_colors (f
, &pixel
, 1);
806 pixel_allocated_p
= 0;
809 pixel
= x
->mouse_pixel
;
810 if (pixel
== fore_pixel
)
812 if (fore_pixel_allocated_p
)
814 x_free_colors (f
, &fore_pixel
, 1);
815 fore_pixel_allocated_p
= 0;
817 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
821 unload_color (f
, x
->cursor_foreground_pixel
);
822 if (!fore_pixel_allocated_p
)
823 fore_pixel
= x_copy_color (f
, fore_pixel
);
824 x
->cursor_foreground_pixel
= fore_pixel
;
826 unload_color (f
, x
->cursor_pixel
);
827 if (!pixel_allocated_p
)
828 pixel
= x_copy_color (f
, pixel
);
829 x
->cursor_pixel
= pixel
;
831 if (FRAME_X_WINDOW (f
) != 0)
834 XSetBackground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, x
->cursor_pixel
);
835 XSetForeground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, fore_pixel
);
838 if (FRAME_VISIBLE_P (f
))
840 x_update_cursor (f
, 0);
841 x_update_cursor (f
, 1);
845 update_face_from_frame_parameter (f
, Qcursor_color
, arg
);
848 /* Set the border-color of frame F to pixel value PIX.
849 Note that this does not fully take effect if done before
850 F has an x-window. */
853 x_set_border_pixel (struct frame
*f
, int pix
)
855 unload_color (f
, f
->output_data
.x
->border_pixel
);
856 f
->output_data
.x
->border_pixel
= pix
;
858 if (FRAME_X_WINDOW (f
) != 0 && f
->border_width
> 0)
861 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), pix
);
864 if (FRAME_VISIBLE_P (f
))
869 /* Set the border-color of frame F to value described by ARG.
870 ARG can be a string naming a color.
871 The border-color is used for the border that is drawn by the X server.
872 Note that this does not fully take effect if done before
873 F has an x-window; it must be redone when the window is created.
875 Note: this is done in two routines because of the way X10 works.
877 Note: under X11, this is normally the province of the window manager,
878 and so emacs's border colors may be overridden. */
881 x_set_border_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
886 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
887 x_set_border_pixel (f
, pix
);
888 update_face_from_frame_parameter (f
, Qborder_color
, arg
);
893 x_set_cursor_type (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
895 set_frame_cursor_types (f
, arg
);
899 x_set_icon_type (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
905 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
908 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
913 result
= x_text_icon (f
,
914 SSDATA ((!NILP (f
->icon_name
)
918 result
= x_bitmap_icon (f
, arg
);
923 error ("No icon window available");
926 XFlush (FRAME_X_DISPLAY (f
));
931 x_set_icon_name (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
937 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
940 else if (!NILP (arg
) || NILP (oldval
))
943 fset_icon_name (f
, arg
);
945 if (f
->output_data
.x
->icon_bitmap
!= 0)
950 result
= x_text_icon (f
,
951 SSDATA ((!NILP (f
->icon_name
)
960 error ("No icon window available");
963 XFlush (FRAME_X_DISPLAY (f
));
969 x_set_menu_bar_lines (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
972 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
973 int olines
= FRAME_MENU_BAR_LINES (f
);
976 /* Right now, menu bars don't work properly in minibuf-only frames;
977 most of the commands try to apply themselves to the minibuffer
978 frame itself, and get an error because you can't switch buffers
979 in or split the minibuffer window. */
980 if (FRAME_MINIBUF_ONLY_P (f
))
983 if (TYPE_RANGED_INTEGERP (int, value
))
984 nlines
= XINT (value
);
988 /* Make sure we redisplay all windows in this frame. */
989 windows_or_buffers_changed
= 59;
991 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
992 FRAME_MENU_BAR_LINES (f
) = 0;
993 FRAME_MENU_BAR_HEIGHT (f
) = 0;
996 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
997 if (FRAME_X_P (f
) && f
->output_data
.x
->menubar_widget
== 0)
998 /* Make sure next redisplay shows the menu bar. */
999 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= 1;
1003 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
1004 free_frame_menubar (f
);
1005 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
1007 f
->output_data
.x
->menubar_widget
= 0;
1009 #else /* not USE_X_TOOLKIT && not USE_GTK */
1010 FRAME_MENU_BAR_LINES (f
) = nlines
;
1011 FRAME_MENU_BAR_HEIGHT (f
) = nlines
* FRAME_LINE_HEIGHT (f
);
1012 adjust_frame_size (f
, -1, -1, 2, 1, Qmenu_bar_lines
);
1013 if (FRAME_X_WINDOW (f
))
1014 x_clear_under_internal_border (f
);
1016 /* If the menu bar height gets changed, the internal border below
1017 the top margin has to be cleared. Also, if the menu bar gets
1018 larger, the area for the added lines has to be cleared except for
1019 the first menu bar line that is to be drawn later. */
1020 if (nlines
!= olines
)
1022 int height
= FRAME_INTERNAL_BORDER_WIDTH (f
);
1023 int width
= FRAME_PIXEL_WIDTH (f
);
1026 /* height can be zero here. */
1027 if (FRAME_X_WINDOW (f
) && height
> 0 && width
> 0)
1029 y
= FRAME_TOP_MARGIN_HEIGHT (f
);
1032 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1033 0, y
, width
, height
);
1037 if (nlines
> 1 && nlines
> olines
)
1039 y
= (olines
== 0 ? 1 : olines
) * FRAME_LINE_HEIGHT (f
);
1040 height
= nlines
* FRAME_LINE_HEIGHT (f
) - y
;
1043 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1044 0, y
, width
, height
);
1048 if (nlines
== 0 && WINDOWP (f
->menu_bar_window
))
1049 clear_glyph_matrix (XWINDOW (f
->menu_bar_window
)->current_matrix
);
1051 #endif /* not USE_X_TOOLKIT && not USE_GTK */
1052 adjust_frame_glyphs (f
);
1053 run_window_configuration_change_hook (f
);
1057 /* Set the number of lines used for the tool bar of frame F to VALUE.
1058 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1059 is the old number of tool bar lines. This function changes the
1060 height of all windows on frame F to match the new tool bar height.
1061 The frame's height doesn't change. */
1064 x_set_tool_bar_lines (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
1068 /* Treat tool bars like menu bars. */
1069 if (FRAME_MINIBUF_ONLY_P (f
))
1072 /* Use VALUE only if an int >= 0. */
1073 if (RANGED_INTEGERP (0, value
, INT_MAX
))
1074 nlines
= XFASTINT (value
);
1079 x_change_tool_bar_height (f
, nlines
* FRAME_LINE_HEIGHT (f
));
1080 #else /* !USE_GTK */
1082 x_change_tool_bar_height (f
, nlines
* FRAME_LINE_HEIGHT (f
));
1085 f
->n_tool_bar_rows
= 0;
1086 FRAME_TOOL_BAR_LINES (f
) = nlines
;
1087 adjust_frame_glyphs (f
);
1088 SET_FRAME_GARBAGED (f
);
1090 #endif /* USE_GTK */
1094 /* Set the pixel height of the tool bar of frame F to HEIGHT. */
1096 x_change_tool_bar_height (struct frame
*f
, int height
)
1099 FRAME_TOOL_BAR_LINES (f
) = 0;
1100 FRAME_TOOL_BAR_HEIGHT (f
) = 0;
1103 FRAME_EXTERNAL_TOOL_BAR (f
) = 1;
1104 if (FRAME_X_P (f
) && f
->output_data
.x
->toolbar_widget
== 0)
1105 /* Make sure next redisplay shows the tool bar. */
1106 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= 1;
1107 update_frame_tool_bar (f
);
1111 if (FRAME_EXTERNAL_TOOL_BAR (f
))
1112 free_frame_tool_bar (f
);
1113 FRAME_EXTERNAL_TOOL_BAR (f
) = 0;
1115 #else /* !USE_GTK */
1116 int unit
= FRAME_LINE_HEIGHT (f
);
1117 int old_height
= FRAME_TOOL_BAR_HEIGHT (f
);
1118 int lines
= (height
+ unit
- 1) / unit
;
1120 /* Make sure we redisplay all windows in this frame. */
1121 windows_or_buffers_changed
= 60;
1124 /* Recalculate tool bar and frame text sizes. */
1125 FRAME_TOOL_BAR_HEIGHT (f
) = height
;
1126 FRAME_TOOL_BAR_LINES (f
) = lines
;
1127 /** FRAME_TEXT_HEIGHT (f) **/
1128 /** = FRAME_PIXEL_TO_TEXT_HEIGHT (f, FRAME_PIXEL_HEIGHT (f)); **/
1129 /** FRAME_LINES (f) **/
1130 /** = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, FRAME_PIXEL_HEIGHT (f)); **/
1131 /* Store the `tool-bar-lines' and `height' frame parameters. */
1132 store_frame_param (f
, Qtool_bar_lines
, make_number (lines
));
1133 store_frame_param (f
, Qheight
, make_number (FRAME_LINES (f
)));
1135 /* We also have to make sure that the internal border at the top of
1136 the frame, below the menu bar or tool bar, is redrawn when the
1137 tool bar disappears. This is so because the internal border is
1138 below the tool bar if one is displayed, but is below the menu bar
1139 if there isn't a tool bar. The tool bar draws into the area
1140 below the menu bar. */
1141 if (FRAME_X_WINDOW (f
) && FRAME_TOOL_BAR_HEIGHT (f
) == 0)
1144 clear_current_matrices (f
);
1147 if ((height
< old_height
) && WINDOWP (f
->tool_bar_window
))
1148 clear_glyph_matrix (XWINDOW (f
->tool_bar_window
)->current_matrix
);
1150 /* Recalculate toolbar height. */
1151 f
->n_tool_bar_rows
= 0;
1153 adjust_frame_size (f
, -1, -1, (old_height
== 0 || height
== 0) ? 2 : 4, 0,
1156 if (FRAME_X_WINDOW (f
))
1157 x_clear_under_internal_border (f
);
1159 #endif /* USE_GTK */
1164 x_set_internal_border_width (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1168 CHECK_TYPE_RANGED_INTEGER (int, arg
);
1169 border
= max (XINT (arg
), 0);
1171 if (border
!= FRAME_INTERNAL_BORDER_WIDTH (f
))
1173 FRAME_INTERNAL_BORDER_WIDTH (f
) = border
;
1175 #ifdef USE_X_TOOLKIT
1176 if (FRAME_X_OUTPUT (f
)->edit_widget
)
1177 widget_store_internal_border (FRAME_X_OUTPUT (f
)->edit_widget
);
1180 if (FRAME_X_WINDOW (f
) != 0)
1182 adjust_frame_size (f
, -1, -1, 3, 0, Qinternal_border_width
);
1185 xg_clear_under_internal_border (f
);
1187 x_clear_under_internal_border (f
);
1195 /* Set the foreground color for scroll bars on frame F to VALUE.
1196 VALUE should be a string, a color name. If it isn't a string or
1197 isn't a valid color name, do nothing. OLDVAL is the old value of
1198 the frame parameter. */
1201 x_set_scroll_bar_foreground (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
1203 unsigned long pixel
;
1205 if (STRINGP (value
))
1206 pixel
= x_decode_color (f
, value
, BLACK_PIX_DEFAULT (f
));
1210 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
1211 unload_color (f
, f
->output_data
.x
->scroll_bar_foreground_pixel
);
1213 f
->output_data
.x
->scroll_bar_foreground_pixel
= pixel
;
1214 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1216 /* Remove all scroll bars because they have wrong colors. */
1217 if (FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
)
1218 (*FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
) (f
);
1219 if (FRAME_TERMINAL (f
)->judge_scroll_bars_hook
)
1220 (*FRAME_TERMINAL (f
)->judge_scroll_bars_hook
) (f
);
1222 update_face_from_frame_parameter (f
, Qscroll_bar_foreground
, value
);
1228 /* Set the background color for scroll bars on frame F to VALUE VALUE
1229 should be a string, a color name. If it isn't a string or isn't a
1230 valid color name, do nothing. OLDVAL is the old value of the frame
1234 x_set_scroll_bar_background (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
1236 unsigned long pixel
;
1238 if (STRINGP (value
))
1239 pixel
= x_decode_color (f
, value
, WHITE_PIX_DEFAULT (f
));
1243 if (f
->output_data
.x
->scroll_bar_background_pixel
!= -1)
1244 unload_color (f
, f
->output_data
.x
->scroll_bar_background_pixel
);
1246 #if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
1247 /* Scrollbar shadow colors. */
1248 if (f
->output_data
.x
->scroll_bar_top_shadow_pixel
!= -1)
1250 unload_color (f
, f
->output_data
.x
->scroll_bar_top_shadow_pixel
);
1251 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
1253 if (f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
!= -1)
1255 unload_color (f
, f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
);
1256 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
1258 #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
1260 f
->output_data
.x
->scroll_bar_background_pixel
= pixel
;
1261 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1263 /* Remove all scroll bars because they have wrong colors. */
1264 if (FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
)
1265 (*FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
) (f
);
1266 if (FRAME_TERMINAL (f
)->judge_scroll_bars_hook
)
1267 (*FRAME_TERMINAL (f
)->judge_scroll_bars_hook
) (f
);
1269 update_face_from_frame_parameter (f
, Qscroll_bar_background
, value
);
1275 /* Encode Lisp string STRING as a text in a format appropriate for
1276 XICCC (X Inter Client Communication Conventions).
1278 This can call Lisp code, so callers must GCPRO.
1280 If STRING contains only ASCII characters, do no conversion and
1281 return the string data of STRING. Otherwise, encode the text by
1282 CODING_SYSTEM, and return a newly allocated memory area which
1283 should be freed by `xfree' by a caller.
1285 Store the byte length of resulting text in *TEXT_BYTES.
1287 If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
1288 which means that the `encoding' of the result can be `STRING'.
1289 Otherwise store 0 in *STRINGP, which means that the `encoding' of
1290 the result should be `COMPOUND_TEXT'. */
1292 static unsigned char *
1293 x_encode_text (Lisp_Object string
, Lisp_Object coding_system
,
1294 ptrdiff_t *text_bytes
, int *stringp
, bool *freep
)
1296 int result
= string_xstring_p (string
);
1297 struct coding_system coding
;
1301 /* No multibyte character in OBJ. We need not encode it. */
1302 *text_bytes
= SBYTES (string
);
1305 return SDATA (string
);
1308 setup_coding_system (coding_system
, &coding
);
1309 coding
.mode
|= (CODING_MODE_SAFE_ENCODING
| CODING_MODE_LAST_BLOCK
);
1310 /* We suppress producing escape sequences for composition. */
1311 coding
.common_flags
&= ~CODING_ANNOTATION_MASK
;
1312 coding
.destination
= xnmalloc (SCHARS (string
), 2);
1313 coding
.dst_bytes
= SCHARS (string
) * 2;
1314 encode_coding_object (&coding
, string
, 0, 0,
1315 SCHARS (string
), SBYTES (string
), Qnil
);
1316 *text_bytes
= coding
.produced
;
1317 *stringp
= (result
== 1 || !EQ (coding_system
, Qcompound_text
));
1319 return coding
.destination
;
1323 /* Set the WM name to NAME for frame F. Also set the icon name.
1324 If the frame already has an icon name, use that, otherwise set the
1325 icon name to NAME. */
1328 x_set_name_internal (struct frame
*f
, Lisp_Object name
)
1330 if (FRAME_X_WINDOW (f
))
1334 XTextProperty text
, icon
;
1337 bool do_free_icon_value
= 0, do_free_text_value
= 0;
1338 Lisp_Object coding_system
;
1339 Lisp_Object encoded_name
;
1340 Lisp_Object encoded_icon_name
;
1341 struct gcpro gcpro1
;
1343 /* As ENCODE_UTF_8 may cause GC and relocation of string data,
1344 we use it before x_encode_text that may return string data. */
1346 encoded_name
= ENCODE_UTF_8 (name
);
1349 coding_system
= Qcompound_text
;
1350 /* Note: Encoding strategy
1352 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1353 text.encoding. But, there are non-internationalized window
1354 managers which don't support that encoding. So, if NAME
1355 contains only ASCII and 8859-1 characters, encode it by
1356 iso-latin-1, and use "STRING" in text.encoding hoping that
1357 such window managers at least analyze this format correctly,
1358 i.e. treat 8-bit bytes as 8859-1 characters.
1360 We may also be able to use "UTF8_STRING" in text.encoding
1361 in the future which can encode all Unicode characters.
1362 But, for the moment, there's no way to know that the
1363 current window manager supports it or not.
1365 Either way, we also set the _NET_WM_NAME and _NET_WM_ICON_NAME
1366 properties. Per the EWMH specification, those two properties
1367 are always UTF8_STRING. This matches what gtk_window_set_title()
1368 does in the USE_GTK case. */
1369 text
.value
= x_encode_text (name
, coding_system
, &bytes
,
1370 &stringp
, &do_free_text_value
);
1371 text
.encoding
= (stringp
? XA_STRING
1372 : FRAME_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1374 text
.nitems
= bytes
;
1376 if (!STRINGP (f
->icon_name
))
1379 encoded_icon_name
= encoded_name
;
1383 /* See the above comment "Note: Encoding strategy". */
1384 icon
.value
= x_encode_text (f
->icon_name
, coding_system
, &bytes
,
1385 &stringp
, &do_free_icon_value
);
1386 icon
.encoding
= (stringp
? XA_STRING
1387 : FRAME_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1389 icon
.nitems
= bytes
;
1391 encoded_icon_name
= ENCODE_UTF_8 (f
->icon_name
);
1395 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
1396 SSDATA (encoded_name
));
1397 #else /* not USE_GTK */
1398 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &text
);
1399 XChangeProperty (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
1400 FRAME_DISPLAY_INFO (f
)->Xatom_net_wm_name
,
1401 FRAME_DISPLAY_INFO (f
)->Xatom_UTF8_STRING
,
1403 SDATA (encoded_name
),
1404 SBYTES (encoded_name
));
1405 #endif /* not USE_GTK */
1407 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &icon
);
1408 XChangeProperty (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
1409 FRAME_DISPLAY_INFO (f
)->Xatom_net_wm_icon_name
,
1410 FRAME_DISPLAY_INFO (f
)->Xatom_UTF8_STRING
,
1412 SDATA (encoded_icon_name
),
1413 SBYTES (encoded_icon_name
));
1415 if (do_free_icon_value
)
1417 if (do_free_text_value
)
1424 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1427 If EXPLICIT is true, that indicates that lisp code is setting the
1428 name; if NAME is a string, set F's name to NAME and set
1429 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1431 If EXPLICIT is false, that indicates that Emacs redisplay code is
1432 suggesting a new name, which lisp code should override; if
1433 F->explicit_name is set, ignore the new name; otherwise, set it. */
1436 x_set_name (struct frame
*f
, Lisp_Object name
, bool explicit)
1438 /* Make sure that requests from lisp code override requests from
1439 Emacs redisplay code. */
1442 /* If we're switching from explicit to implicit, we had better
1443 update the mode lines and thereby update the title. */
1444 if (f
->explicit_name
&& NILP (name
))
1445 update_mode_lines
= 37;
1447 f
->explicit_name
= ! NILP (name
);
1449 else if (f
->explicit_name
)
1452 /* If NAME is nil, set the name to the x_id_name. */
1455 /* Check for no change needed in this very common case
1456 before we do any consing. */
1457 if (!strcmp (FRAME_DISPLAY_INFO (f
)->x_id_name
,
1460 name
= build_string (FRAME_DISPLAY_INFO (f
)->x_id_name
);
1463 CHECK_STRING (name
);
1465 /* Don't change the name if it's already NAME. */
1466 if (! NILP (Fstring_equal (name
, f
->name
)))
1469 fset_name (f
, name
);
1471 /* For setting the frame title, the title parameter should override
1472 the name parameter. */
1473 if (! NILP (f
->title
))
1476 x_set_name_internal (f
, name
);
1479 /* This function should be called when the user's lisp code has
1480 specified a name for the frame; the name will override any set by the
1483 x_explicitly_set_name (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1485 x_set_name (f
, arg
, 1);
1488 /* This function should be called by Emacs redisplay code to set the
1489 name; names set this way will never override names set by the user's
1492 x_implicitly_set_name (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1494 x_set_name (f
, arg
, 0);
1497 /* Change the title of frame F to NAME.
1498 If NAME is nil, use the frame name as the title. */
1501 x_set_title (struct frame
*f
, Lisp_Object name
, Lisp_Object old_name
)
1503 /* Don't change the title if it's already NAME. */
1504 if (EQ (name
, f
->title
))
1507 update_mode_lines
= 38;
1509 fset_title (f
, name
);
1514 CHECK_STRING (name
);
1516 x_set_name_internal (f
, name
);
1520 x_set_scroll_bar_default_width (struct frame
*f
)
1522 int unit
= FRAME_COLUMN_WIDTH (f
);
1523 #ifdef USE_TOOLKIT_SCROLL_BARS
1525 int minw
= xg_get_default_scrollbar_width ();
1529 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
1530 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (minw
+ unit
- 1) / unit
;
1531 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = minw
;
1533 /* The width of a non-toolkit scrollbar is 14 pixels. */
1534 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + unit
- 1) / unit
;
1535 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
)
1536 = FRAME_CONFIG_SCROLL_BAR_COLS (f
) * unit
;
1541 x_set_scroll_bar_default_height (struct frame
*f
)
1543 int height
= FRAME_LINE_HEIGHT (f
);
1544 #ifdef USE_TOOLKIT_SCROLL_BARS
1546 int min_height
= xg_get_default_scrollbar_height ();
1548 int min_height
= 16;
1550 /* A minimum height of 14 doesn't look good for toolkit scroll bars. */
1551 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f
) = min_height
;
1552 FRAME_CONFIG_SCROLL_BAR_LINES (f
) = (min_height
+ height
- 1) / height
;
1554 /* The height of a non-toolkit scrollbar is 14 pixels. */
1555 FRAME_CONFIG_SCROLL_BAR_LINES (f
) = (14 + height
- 1) / height
;
1557 /* Use all of that space (aside from required margins) for the
1559 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f
) = 14;
1564 /* Record in frame F the specified or default value according to ALIST
1565 of the parameter named PROP (a Lisp symbol). If no value is
1566 specified for PROP, look for an X default for XPROP on the frame
1567 named NAME. If that is not found either, use the value DEFLT. */
1570 x_default_scroll_bar_color_parameter (struct frame
*f
,
1571 Lisp_Object alist
, Lisp_Object prop
,
1572 const char *xprop
, const char *xclass
,
1575 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
1578 tem
= x_get_arg (dpyinfo
, alist
, prop
, xprop
, xclass
, RES_TYPE_STRING
);
1579 if (EQ (tem
, Qunbound
))
1581 #ifdef USE_TOOLKIT_SCROLL_BARS
1583 /* See if an X resource for the scroll bar color has been
1585 AUTO_STRING (foreground
, "foreground");
1586 AUTO_STRING (background
, "foreground");
1587 AUTO_STRING (verticalScrollBar
, "verticalScrollBar");
1588 tem
= (display_x_get_resource
1589 (dpyinfo
, foreground_p
? foreground
: background
,
1590 empty_unibyte_string
,
1592 empty_unibyte_string
));
1595 /* If nothing has been specified, scroll bars will use a
1596 toolkit-dependent default. Because these defaults are
1597 difficult to get at without actually creating a scroll
1598 bar, use nil to indicate that no color has been
1603 #else /* not USE_TOOLKIT_SCROLL_BARS */
1607 #endif /* not USE_TOOLKIT_SCROLL_BARS */
1610 AUTO_FRAME_ARG (arg
, prop
, tem
);
1611 x_set_frame_parameters (f
, arg
);
1618 #ifdef USE_X_TOOLKIT
1620 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
1621 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
1622 already be present because of the toolkit (Motif adds some of them,
1623 for example, but Xt doesn't). */
1626 hack_wm_protocols (struct frame
*f
, Widget widget
)
1628 Display
*dpy
= XtDisplay (widget
);
1629 Window w
= XtWindow (widget
);
1630 int need_delete
= 1;
1637 unsigned char *catoms
;
1639 unsigned long nitems
= 0;
1640 unsigned long bytes_after
;
1642 if ((XGetWindowProperty (dpy
, w
,
1643 FRAME_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
1644 0, 100, False
, XA_ATOM
,
1645 &type
, &format
, &nitems
, &bytes_after
,
1648 && format
== 32 && type
== XA_ATOM
)
1650 Atom
*atoms
= (Atom
*) catoms
;
1655 == FRAME_DISPLAY_INFO (f
)->Xatom_wm_delete_window
)
1657 else if (atoms
[nitems
]
1658 == FRAME_DISPLAY_INFO (f
)->Xatom_wm_take_focus
)
1660 else if (atoms
[nitems
]
1661 == FRAME_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
)
1672 props
[count
++] = FRAME_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
1674 props
[count
++] = FRAME_DISPLAY_INFO (f
)->Xatom_wm_take_focus
;
1676 props
[count
++] = FRAME_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
1678 XChangeProperty (dpy
, w
, FRAME_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
1679 XA_ATOM
, 32, PropModeAppend
,
1680 (unsigned char *) props
, count
);
1688 /* Support routines for XIC (X Input Context). */
1692 static XFontSet
xic_create_xfontset (struct frame
*);
1693 static XIMStyle
best_xim_style (XIMStyles
*);
1696 /* Supported XIM styles, ordered by preference. */
1698 static const XIMStyle supported_xim_styles
[] =
1700 XIMPreeditPosition
| XIMStatusArea
,
1701 XIMPreeditPosition
| XIMStatusNothing
,
1702 XIMPreeditPosition
| XIMStatusNone
,
1703 XIMPreeditNothing
| XIMStatusArea
,
1704 XIMPreeditNothing
| XIMStatusNothing
,
1705 XIMPreeditNothing
| XIMStatusNone
,
1706 XIMPreeditNone
| XIMStatusArea
,
1707 XIMPreeditNone
| XIMStatusNothing
,
1708 XIMPreeditNone
| XIMStatusNone
,
1713 #if defined HAVE_X_WINDOWS && defined USE_X_TOOLKIT
1714 /* Create an X fontset on frame F with base font name BASE_FONTNAME. */
1716 static const char xic_default_fontset
[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
1718 /* Create an Xt fontset spec from the name of a base font.
1719 If `motif' is True use the Motif syntax. */
1721 xic_create_fontsetname (const char *base_fontname
, int motif
)
1723 const char *sep
= motif
? ";" : ",";
1726 /* Make a fontset name from the base font name. */
1727 if (xic_default_fontset
== base_fontname
)
1729 /* There is no base font name, use the default. */
1730 fontsetname
= xmalloc (strlen (base_fontname
) + 2);
1731 strcpy (fontsetname
, base_fontname
);
1735 /* Make a fontset name from the base font name.
1736 The font set will be made of the following elements:
1738 - the base font where the charset spec is replaced by -*-*.
1739 - the same but with the family also replaced with -*-*-. */
1740 const char *p
= base_fontname
;
1743 for (i
= 0; *p
; p
++)
1747 /* As the font name doesn't conform to XLFD, we can't
1748 modify it to generalize it to allcs and allfamilies.
1749 Use the specified font plus the default. */
1750 fontsetname
= xmalloc (strlen (base_fontname
)
1751 + strlen (xic_default_fontset
) + 3);
1752 strcpy (fontsetname
, base_fontname
);
1753 strcat (fontsetname
, sep
);
1754 strcat (fontsetname
, xic_default_fontset
);
1759 const char *p1
= NULL
, *p2
= NULL
, *p3
= NULL
;
1760 char *font_allcs
= NULL
;
1761 char *font_allfamilies
= NULL
;
1762 char *font_all
= NULL
;
1763 const char *allcs
= "*-*-*-*-*-*-*";
1764 const char *allfamilies
= "-*-*-";
1765 const char *all
= "*-*-*-*-";
1768 for (i
= 0, p
= base_fontname
; i
< 8; p
++)
1781 /* If base_fontname specifies ADSTYLE, make it a
1785 ptrdiff_t diff
= (p2
- p3
) - 2;
1787 base
= alloca (strlen (base_fontname
) + 1);
1788 memcpy (base
, base_fontname
, p3
- base_fontname
);
1789 base
[p3
- base_fontname
] = '*';
1790 base
[(p3
- base_fontname
) + 1] = '-';
1791 strcpy (base
+ (p3
- base_fontname
) + 2, p2
);
1792 p
= base
+ (p
- base_fontname
) - diff
;
1793 p1
= base
+ (p1
- base_fontname
);
1794 p2
= base
+ (p2
- base_fontname
) - diff
;
1795 base_fontname
= base
;
1798 /* Build the font spec that matches all charsets. */
1799 len
= p
- base_fontname
+ strlen (allcs
) + 1;
1800 font_allcs
= alloca (len
);
1801 memcpy (font_allcs
, base_fontname
, p
- base_fontname
);
1802 strcpy (font_allcs
+ (p
- base_fontname
), allcs
);
1804 /* Build the font spec that matches all families and
1806 len
= p
- p1
+ strlen (allcs
) + strlen (allfamilies
) + 1;
1807 font_allfamilies
= alloca (len
);
1808 strcpy (font_allfamilies
, allfamilies
);
1809 memcpy (font_allfamilies
+ strlen (allfamilies
), p1
, p
- p1
);
1810 strcpy (font_allfamilies
+ strlen (allfamilies
) + (p
- p1
), allcs
);
1812 /* Build the font spec that matches all. */
1813 len
= p
- p2
+ strlen (allcs
) + strlen (all
) + strlen (allfamilies
) + 1;
1814 font_all
= alloca (len
);
1815 strcpy (font_all
, allfamilies
);
1816 strcat (font_all
, all
);
1817 memcpy (font_all
+ strlen (all
) + strlen (allfamilies
), p2
, p
- p2
);
1818 strcpy (font_all
+ strlen (all
) + strlen (allfamilies
) + (p
- p2
),
1821 /* Build the actual font set name. */
1822 len
= strlen (base_fontname
) + strlen (font_allcs
)
1823 + strlen (font_allfamilies
) + strlen (font_all
) + 5;
1824 fontsetname
= xmalloc (len
);
1825 strcpy (fontsetname
, base_fontname
);
1826 strcat (fontsetname
, sep
);
1827 strcat (fontsetname
, font_allcs
);
1828 strcat (fontsetname
, sep
);
1829 strcat (fontsetname
, font_allfamilies
);
1830 strcat (fontsetname
, sep
);
1831 strcat (fontsetname
, font_all
);
1835 return strcat (fontsetname
, ":");
1838 #endif /* HAVE_X_WINDOWS && USE_X_TOOLKIT */
1840 #ifdef DEBUG_XIC_FONTSET
1842 print_fontset_result (XFontSet xfs
, char *name
, char **missing_list
,
1846 fprintf (stderr
, "XIC Fontset created: %s\n", name
);
1849 fprintf (stderr
, "XIC Fontset failed: %s\n", name
);
1850 while (missing_count
-- > 0)
1852 fprintf (stderr
, " missing: %s\n", *missing_list
);
1861 xic_create_xfontset (struct frame
*f
)
1863 XFontSet xfs
= NULL
;
1864 struct font
*font
= FRAME_FONT (f
);
1865 int pixel_size
= font
->pixel_size
;
1866 Lisp_Object rest
, frame
;
1868 /* See if there is another frame already using same fontset. */
1869 FOR_EACH_FRAME (rest
, frame
)
1871 struct frame
*cf
= XFRAME (frame
);
1873 if (cf
!= f
&& FRAME_LIVE_P (f
) && FRAME_X_P (cf
)
1874 && FRAME_DISPLAY_INFO (cf
) == FRAME_DISPLAY_INFO (f
)
1876 && FRAME_FONT (f
)->pixel_size
== pixel_size
)
1878 xfs
= FRAME_XIC_FONTSET (cf
);
1886 char **missing_list
;
1889 const char *xlfd_format
= "-*-*-medium-r-normal--%d-*-*-*-*-*";
1891 sprintf (buf
, xlfd_format
, pixel_size
);
1892 missing_list
= NULL
;
1893 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
), buf
,
1894 &missing_list
, &missing_count
, &def_string
);
1895 #ifdef DEBUG_XIC_FONTSET
1896 print_fontset_result (xfs
, buf
, missing_list
, missing_count
);
1899 XFreeStringList (missing_list
);
1902 /* List of pixel sizes most likely available. Find one that
1903 is closest to pixel_size. */
1904 int sizes
[] = {0, 8, 10, 11, 12, 14, 17, 18, 20, 24, 26, 34, 0};
1905 int *smaller
, *larger
;
1907 for (smaller
= sizes
; smaller
[1]; smaller
++)
1908 if (smaller
[1] >= pixel_size
)
1910 larger
= smaller
+ 1;
1911 if (*larger
== pixel_size
)
1913 while (*smaller
|| *larger
)
1918 this_size
= *smaller
--;
1919 else if (! *smaller
)
1920 this_size
= *larger
++;
1921 else if (pixel_size
- *smaller
< *larger
- pixel_size
)
1922 this_size
= *smaller
--;
1924 this_size
= *larger
++;
1925 sprintf (buf
, xlfd_format
, this_size
);
1926 missing_list
= NULL
;
1927 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
), buf
,
1928 &missing_list
, &missing_count
, &def_string
);
1929 #ifdef DEBUG_XIC_FONTSET
1930 print_fontset_result (xfs
, buf
, missing_list
, missing_count
);
1933 XFreeStringList (missing_list
);
1940 const char *last_resort
= "-*-*-*-r-normal--*-*-*-*-*-*";
1942 missing_list
= NULL
;
1943 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
), last_resort
,
1944 &missing_list
, &missing_count
, &def_string
);
1945 #ifdef DEBUG_XIC_FONTSET
1946 print_fontset_result (xfs
, last_resort
, missing_list
, missing_count
);
1949 XFreeStringList (missing_list
);
1957 /* Free the X fontset of frame F if it is the last frame using it. */
1960 xic_free_xfontset (struct frame
*f
)
1962 Lisp_Object rest
, frame
;
1965 if (!FRAME_XIC_FONTSET (f
))
1968 /* See if there is another frame sharing the same fontset. */
1969 FOR_EACH_FRAME (rest
, frame
)
1971 struct frame
*cf
= XFRAME (frame
);
1972 if (cf
!= f
&& FRAME_LIVE_P (f
) && FRAME_X_P (cf
)
1973 && FRAME_DISPLAY_INFO (cf
) == FRAME_DISPLAY_INFO (f
)
1974 && FRAME_XIC_FONTSET (cf
) == FRAME_XIC_FONTSET (f
))
1982 /* The fontset is not used anymore. It is safe to free it. */
1983 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
1985 FRAME_XIC_FONTSET (f
) = NULL
;
1989 /* Value is the best input style, given user preferences USER (already
1990 checked to be supported by Emacs), and styles supported by the
1991 input method XIM. */
1994 best_xim_style (XIMStyles
*xim
)
1997 int nr_supported
= ARRAYELTS (supported_xim_styles
);
1999 for (i
= 0; i
< nr_supported
; ++i
)
2000 for (j
= 0; j
< xim
->count_styles
; ++j
)
2001 if (supported_xim_styles
[i
] == xim
->supported_styles
[j
])
2002 return supported_xim_styles
[i
];
2004 /* Return the default style. */
2005 return XIMPreeditNothing
| XIMStatusNothing
;
2008 /* Create XIC for frame F. */
2011 create_frame_xic (struct frame
*f
)
2015 XFontSet xfs
= NULL
;
2016 XVaNestedList status_attr
= NULL
;
2017 XVaNestedList preedit_attr
= NULL
;
2025 xim
= FRAME_X_XIM (f
);
2029 /* Determine XIC style. */
2030 xic_style
= best_xim_style (FRAME_X_XIM_STYLES (f
));
2032 /* Create X fontset. */
2033 if (xic_style
& (XIMPreeditPosition
| XIMStatusArea
))
2035 xfs
= xic_create_xfontset (f
);
2039 FRAME_XIC_FONTSET (f
) = xfs
;
2042 if (xic_style
& XIMPreeditPosition
)
2044 spot
.x
= 0; spot
.y
= 1;
2045 preedit_attr
= XVaCreateNestedList (0,
2048 FRAME_FOREGROUND_PIXEL (f
),
2050 FRAME_BACKGROUND_PIXEL (f
),
2051 (xic_style
& XIMPreeditPosition
2061 if (xic_style
& XIMStatusArea
)
2063 s_area
.x
= 0; s_area
.y
= 0; s_area
.width
= 1; s_area
.height
= 1;
2064 status_attr
= XVaCreateNestedList (0,
2070 FRAME_FOREGROUND_PIXEL (f
),
2072 FRAME_BACKGROUND_PIXEL (f
),
2079 if (preedit_attr
&& status_attr
)
2080 xic
= XCreateIC (xim
,
2081 XNInputStyle
, xic_style
,
2082 XNClientWindow
, FRAME_X_WINDOW (f
),
2083 XNFocusWindow
, FRAME_X_WINDOW (f
),
2084 XNStatusAttributes
, status_attr
,
2085 XNPreeditAttributes
, preedit_attr
,
2087 else if (preedit_attr
)
2088 xic
= XCreateIC (xim
,
2089 XNInputStyle
, xic_style
,
2090 XNClientWindow
, FRAME_X_WINDOW (f
),
2091 XNFocusWindow
, FRAME_X_WINDOW (f
),
2092 XNPreeditAttributes
, preedit_attr
,
2094 else if (status_attr
)
2095 xic
= XCreateIC (xim
,
2096 XNInputStyle
, xic_style
,
2097 XNClientWindow
, FRAME_X_WINDOW (f
),
2098 XNFocusWindow
, FRAME_X_WINDOW (f
),
2099 XNStatusAttributes
, status_attr
,
2102 xic
= XCreateIC (xim
,
2103 XNInputStyle
, xic_style
,
2104 XNClientWindow
, FRAME_X_WINDOW (f
),
2105 XNFocusWindow
, FRAME_X_WINDOW (f
),
2111 FRAME_XIC (f
) = xic
;
2112 FRAME_XIC_STYLE (f
) = xic_style
;
2113 xfs
= NULL
; /* Don't free below. */
2121 XFree (preedit_attr
);
2124 XFree (status_attr
);
2128 /* Destroy XIC and free XIC fontset of frame F, if any. */
2131 free_frame_xic (struct frame
*f
)
2133 if (FRAME_XIC (f
) == NULL
)
2136 XDestroyIC (FRAME_XIC (f
));
2137 xic_free_xfontset (f
);
2139 FRAME_XIC (f
) = NULL
;
2143 /* Place preedit area for XIC of window W's frame to specified
2144 pixel position X/Y. X and Y are relative to window W. */
2147 xic_set_preeditarea (struct window
*w
, int x
, int y
)
2149 struct frame
*f
= XFRAME (w
->frame
);
2153 spot
.x
= WINDOW_TO_FRAME_PIXEL_X (w
, x
) + WINDOW_LEFT_FRINGE_WIDTH (w
);
2154 spot
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, y
) + FONT_BASE (FRAME_FONT (f
));
2155 attr
= XVaCreateNestedList (0, XNSpotLocation
, &spot
, NULL
);
2156 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2161 /* Place status area for XIC in bottom right corner of frame F.. */
2164 xic_set_statusarea (struct frame
*f
)
2166 XIC xic
= FRAME_XIC (f
);
2171 /* Negotiate geometry of status area. If input method has existing
2172 status area, use its current size. */
2173 area
.x
= area
.y
= area
.width
= area
.height
= 0;
2174 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &area
, NULL
);
2175 XSetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2178 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &needed
, NULL
);
2179 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2182 if (needed
->width
== 0) /* Use XNArea instead of XNAreaNeeded */
2184 attr
= XVaCreateNestedList (0, XNArea
, &needed
, NULL
);
2185 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2189 area
.width
= needed
->width
;
2190 area
.height
= needed
->height
;
2191 area
.x
= FRAME_PIXEL_WIDTH (f
) - area
.width
- FRAME_INTERNAL_BORDER_WIDTH (f
);
2192 area
.y
= (FRAME_PIXEL_HEIGHT (f
) - area
.height
2193 - FRAME_MENUBAR_HEIGHT (f
)
2194 - FRAME_TOOLBAR_TOP_HEIGHT (f
)
2195 - FRAME_INTERNAL_BORDER_WIDTH (f
));
2198 attr
= XVaCreateNestedList (0, XNArea
, &area
, NULL
);
2199 XSetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2204 /* Set X fontset for XIC of frame F, using base font name
2205 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2208 xic_set_xfontset (struct frame
*f
, const char *base_fontname
)
2213 xic_free_xfontset (f
);
2215 xfs
= xic_create_xfontset (f
);
2217 attr
= XVaCreateNestedList (0, XNFontSet
, xfs
, NULL
);
2218 if (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
)
2219 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2220 if (FRAME_XIC_STYLE (f
) & XIMStatusArea
)
2221 XSetICValues (FRAME_XIC (f
), XNStatusAttributes
, attr
, NULL
);
2224 FRAME_XIC_FONTSET (f
) = xfs
;
2227 #endif /* HAVE_X_I18N */
2231 #ifdef USE_X_TOOLKIT
2233 /* Create and set up the X widget for frame F. */
2236 x_window (struct frame
*f
, long window_prompting
, int minibuffer_only
)
2238 XClassHint class_hints
;
2239 XSetWindowAttributes attributes
;
2240 unsigned long attribute_mask
;
2241 Widget shell_widget
;
2243 Widget frame_widget
;
2249 /* Use the resource name as the top-level widget name
2250 for looking up resources. Make a non-Lisp copy
2251 for the window manager, so GC relocation won't bother it.
2253 Elsewhere we specify the window name for the window manager. */
2254 f
->namebuf
= xstrdup (SSDATA (Vx_resource_name
));
2257 XtSetArg (al
[ac
], XtNallowShellResize
, 1); ac
++;
2258 XtSetArg (al
[ac
], XtNinput
, 1); ac
++;
2259 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2260 XtSetArg (al
[ac
], XtNborderWidth
, f
->border_width
); ac
++;
2261 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2262 XtSetArg (al
[ac
], XtNdepth
, FRAME_DISPLAY_INFO (f
)->n_planes
); ac
++;
2263 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2264 shell_widget
= XtAppCreateShell (f
->namebuf
, EMACS_CLASS
,
2265 applicationShellWidgetClass
,
2266 FRAME_X_DISPLAY (f
), al
, ac
);
2268 f
->output_data
.x
->widget
= shell_widget
;
2269 /* maybe_set_screen_title_format (shell_widget); */
2271 pane_widget
= lw_create_widget ("main", "pane", widget_id_tick
++,
2272 NULL
, shell_widget
, False
,
2273 NULL
, NULL
, NULL
, NULL
);
2276 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2277 XtSetArg (al
[ac
], XtNdepth
, FRAME_DISPLAY_INFO (f
)->n_planes
); ac
++;
2278 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2279 XtSetArg (al
[ac
], XtNborderWidth
, 0); ac
++;
2280 XtSetValues (pane_widget
, al
, ac
);
2281 f
->output_data
.x
->column_widget
= pane_widget
;
2283 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2284 the emacs screen when changing menubar. This reduces flickering. */
2287 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2288 XtSetArg (al
[ac
], XtNshowGrip
, 0); ac
++;
2289 XtSetArg (al
[ac
], XtNallowResize
, 1); ac
++;
2290 XtSetArg (al
[ac
], XtNresizeToPreferred
, 1); ac
++;
2291 XtSetArg (al
[ac
], XtNemacsFrame
, f
); ac
++;
2292 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2293 XtSetArg (al
[ac
], XtNdepth
, FRAME_DISPLAY_INFO (f
)->n_planes
); ac
++;
2294 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2295 XtSetArg (al
[ac
], XtNborderWidth
, 0); ac
++;
2296 frame_widget
= XtCreateWidget (f
->namebuf
, emacsFrameClass
, pane_widget
,
2299 f
->output_data
.x
->edit_widget
= frame_widget
;
2301 XtManageChild (frame_widget
);
2303 /* Do some needed geometry management. */
2307 int extra_borders
= 0;
2309 = (f
->output_data
.x
->menubar_widget
2310 ? (f
->output_data
.x
->menubar_widget
->core
.height
2311 + f
->output_data
.x
->menubar_widget
->core
.border_width
)
2314 #if 0 /* Experimentally, we now get the right results
2315 for -geometry -0-0 without this. 24 Aug 96, rms. */
2316 if (FRAME_EXTERNAL_MENU_BAR (f
))
2319 XtVaGetValues (pane_widget
, XtNinternalBorderWidth
, &ibw
, NULL
);
2320 menubar_size
+= ibw
;
2324 FRAME_MENUBAR_HEIGHT (f
) = menubar_size
;
2327 /* Motif seems to need this amount added to the sizes
2328 specified for the shell widget. The Athena/Lucid widgets don't.
2329 Both conclusions reached experimentally. -- rms. */
2330 XtVaGetValues (f
->output_data
.x
->edit_widget
, XtNinternalBorderWidth
,
2331 &extra_borders
, NULL
);
2335 f
->shell_position
= xmalloc (sizeof "=x++" + 4 * INT_STRLEN_BOUND (int));
2337 /* Convert our geometry parameters into a geometry string
2339 Note that we do not specify here whether the position
2340 is a user-specified or program-specified one.
2341 We pass that information later, in x_wm_set_size_hints. */
2343 int left
= f
->left_pos
;
2344 int xneg
= window_prompting
& XNegative
;
2345 int top
= f
->top_pos
;
2346 int yneg
= window_prompting
& YNegative
;
2352 if (window_prompting
& USPosition
)
2353 sprintf (f
->shell_position
, "=%dx%d%c%d%c%d",
2354 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2355 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
,
2356 (xneg
? '-' : '+'), left
,
2357 (yneg
? '-' : '+'), top
);
2360 sprintf (f
->shell_position
, "=%dx%d",
2361 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2362 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
);
2364 /* Setting x and y when the position is not specified in
2365 the geometry string will set program position in the WM hints.
2366 If Emacs had just one program position, we could set it in
2367 fallback resources, but since each make-frame call can specify
2368 different program positions, this is easier. */
2369 XtSetArg (gal
[gac
], XtNx
, left
); gac
++;
2370 XtSetArg (gal
[gac
], XtNy
, top
); gac
++;
2374 XtSetArg (gal
[gac
], XtNgeometry
, f
->shell_position
); gac
++;
2375 XtSetValues (shell_widget
, gal
, gac
);
2378 XtManageChild (pane_widget
);
2379 XtRealizeWidget (shell_widget
);
2381 if (FRAME_X_EMBEDDED_P (f
))
2382 XReparentWindow (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
),
2383 f
->output_data
.x
->parent_desc
, 0, 0);
2385 FRAME_X_WINDOW (f
) = XtWindow (frame_widget
);
2387 validate_x_resource_name ();
2389 class_hints
.res_name
= SSDATA (Vx_resource_name
);
2390 class_hints
.res_class
= SSDATA (Vx_resource_class
);
2391 XSetClassHint (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
), &class_hints
);
2394 FRAME_XIC (f
) = NULL
;
2396 create_frame_xic (f
);
2399 f
->output_data
.x
->wm_hints
.input
= True
;
2400 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2401 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2402 &f
->output_data
.x
->wm_hints
);
2404 hack_wm_protocols (f
, shell_widget
);
2407 XtAddEventHandler (shell_widget
, 0, True
, _XEditResCheckMessages
, 0);
2410 /* Do a stupid property change to force the server to generate a
2411 PropertyNotify event so that the event_stream server timestamp will
2412 be initialized to something relevant to the time we created the window.
2414 XChangeProperty (XtDisplay (frame_widget
), XtWindow (frame_widget
),
2415 FRAME_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2416 XA_ATOM
, 32, PropModeAppend
, NULL
, 0);
2418 /* Make all the standard events reach the Emacs frame. */
2419 attributes
.event_mask
= STANDARD_EVENT_SET
;
2424 /* XIM server might require some X events. */
2425 unsigned long fevent
= NoEventMask
;
2426 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2427 attributes
.event_mask
|= fevent
;
2429 #endif /* HAVE_X_I18N */
2431 attribute_mask
= CWEventMask
;
2432 XChangeWindowAttributes (XtDisplay (shell_widget
), XtWindow (shell_widget
),
2433 attribute_mask
, &attributes
);
2435 XtMapWidget (frame_widget
);
2437 /* x_set_name normally ignores requests to set the name if the
2438 requested name is the same as the current name. This is the one
2439 place where that assumption isn't correct; f->name is set, but
2440 the X server hasn't been told. */
2443 bool explicit = f
->explicit_name
;
2445 f
->explicit_name
= 0;
2447 fset_name (f
, Qnil
);
2448 x_set_name (f
, name
, explicit);
2451 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2452 f
->output_data
.x
->current_cursor
2453 = f
->output_data
.x
->text_cursor
);
2457 /* This is a no-op, except under Motif. Make sure main areas are
2458 set to something reasonable, in case we get an error later. */
2459 lw_set_main_areas (pane_widget
, 0, frame_widget
);
2462 #else /* not USE_X_TOOLKIT */
2465 x_window (struct frame
*f
)
2467 if (! xg_create_frame_widgets (f
))
2468 error ("Unable to create window");
2471 FRAME_XIC (f
) = NULL
;
2475 create_frame_xic (f
);
2478 /* XIM server might require some X events. */
2479 unsigned long fevent
= NoEventMask
;
2480 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2482 if (fevent
!= NoEventMask
)
2484 XSetWindowAttributes attributes
;
2485 XWindowAttributes wattr
;
2486 unsigned long attribute_mask
;
2488 XGetWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2490 attributes
.event_mask
= wattr
.your_event_mask
| fevent
;
2491 attribute_mask
= CWEventMask
;
2492 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2493 attribute_mask
, &attributes
);
2501 #else /*! USE_GTK */
2502 /* Create and set up the X window for frame F. */
2505 x_window (struct frame
*f
)
2507 XClassHint class_hints
;
2508 XSetWindowAttributes attributes
;
2509 unsigned long attribute_mask
;
2511 attributes
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
2512 attributes
.border_pixel
= f
->output_data
.x
->border_pixel
;
2513 attributes
.bit_gravity
= StaticGravity
;
2514 attributes
.backing_store
= NotUseful
;
2515 attributes
.save_under
= True
;
2516 attributes
.event_mask
= STANDARD_EVENT_SET
;
2517 attributes
.colormap
= FRAME_X_COLORMAP (f
);
2518 attribute_mask
= (CWBackPixel
| CWBorderPixel
| CWBitGravity
| CWEventMask
2523 = XCreateWindow (FRAME_X_DISPLAY (f
),
2524 f
->output_data
.x
->parent_desc
,
2527 FRAME_PIXEL_WIDTH (f
), FRAME_PIXEL_HEIGHT (f
),
2529 CopyFromParent
, /* depth */
2530 InputOutput
, /* class */
2532 attribute_mask
, &attributes
);
2537 create_frame_xic (f
);
2540 /* XIM server might require some X events. */
2541 unsigned long fevent
= NoEventMask
;
2542 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2543 attributes
.event_mask
|= fevent
;
2544 attribute_mask
= CWEventMask
;
2545 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2546 attribute_mask
, &attributes
);
2549 #endif /* HAVE_X_I18N */
2551 validate_x_resource_name ();
2553 class_hints
.res_name
= SSDATA (Vx_resource_name
);
2554 class_hints
.res_class
= SSDATA (Vx_resource_class
);
2555 XSetClassHint (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &class_hints
);
2557 /* This indicates that we use the "Passive Input" input model.
2558 Unless we do this, we don't get the Focus{In,Out} events that we
2559 need to draw the cursor correctly. Accursed bureaucrats.
2560 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2562 f
->output_data
.x
->wm_hints
.input
= True
;
2563 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2564 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2565 &f
->output_data
.x
->wm_hints
);
2566 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
2568 /* Request "save yourself" and "delete window" commands from wm. */
2571 protocols
[0] = FRAME_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2572 protocols
[1] = FRAME_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2573 XSetWMProtocols (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), protocols
, 2);
2576 /* x_set_name normally ignores requests to set the name if the
2577 requested name is the same as the current name. This is the one
2578 place where that assumption isn't correct; f->name is set, but
2579 the X server hasn't been told. */
2582 bool explicit = f
->explicit_name
;
2584 f
->explicit_name
= 0;
2586 fset_name (f
, Qnil
);
2587 x_set_name (f
, name
, explicit);
2590 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2591 f
->output_data
.x
->current_cursor
2592 = f
->output_data
.x
->text_cursor
);
2596 if (FRAME_X_WINDOW (f
) == 0)
2597 error ("Unable to create window");
2600 #endif /* not USE_GTK */
2601 #endif /* not USE_X_TOOLKIT */
2603 /* Verify that the icon position args for this window are valid. */
2606 x_icon_verify (struct frame
*f
, Lisp_Object parms
)
2608 Lisp_Object icon_x
, icon_y
;
2610 /* Set the position of the icon. Note that twm groups all
2611 icons in an icon window. */
2612 icon_x
= x_frame_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
2613 icon_y
= x_frame_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
2614 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2616 CHECK_NUMBER (icon_x
);
2617 CHECK_NUMBER (icon_y
);
2619 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2620 error ("Both left and top icon corners of icon must be specified");
2623 /* Handle the icon stuff for this window. Perhaps later we might
2624 want an x_set_icon_position which can be called interactively as
2628 x_icon (struct frame
*f
, Lisp_Object parms
)
2630 Lisp_Object icon_x
, icon_y
;
2632 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
2635 /* Set the position of the icon. Note that twm groups all
2636 icons in an icon window. */
2637 icon_x
= x_frame_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
2638 icon_y
= x_frame_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
2639 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2641 CHECK_TYPE_RANGED_INTEGER (int, icon_x
);
2642 CHECK_TYPE_RANGED_INTEGER (int, icon_y
);
2644 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2645 error ("Both left and top icon corners of icon must be specified");
2649 if (! EQ (icon_x
, Qunbound
))
2650 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
2652 #if 0 /* x_get_arg removes the visibility parameter as a side effect,
2653 but x_create_frame still needs it. */
2654 /* Start up iconic or window? */
2655 x_wm_set_window_state
2656 (f
, (EQ (x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
),
2662 x_text_icon (f
, SSDATA ((!NILP (f
->icon_name
)
2669 /* Make the GCs needed for this window, setting the
2670 background, border and mouse colors; also create the
2671 mouse cursor and the gray border tile. */
2674 x_make_gc (struct frame
*f
)
2676 XGCValues gc_values
;
2680 /* Create the GCs of this frame.
2681 Note that many default values are used. */
2683 gc_values
.foreground
= FRAME_FOREGROUND_PIXEL (f
);
2684 gc_values
.background
= FRAME_BACKGROUND_PIXEL (f
);
2685 gc_values
.line_width
= 0; /* Means 1 using fast algorithm. */
2686 f
->output_data
.x
->normal_gc
2687 = XCreateGC (FRAME_X_DISPLAY (f
),
2689 GCLineWidth
| GCForeground
| GCBackground
,
2692 /* Reverse video style. */
2693 gc_values
.foreground
= FRAME_BACKGROUND_PIXEL (f
);
2694 gc_values
.background
= FRAME_FOREGROUND_PIXEL (f
);
2695 f
->output_data
.x
->reverse_gc
2696 = XCreateGC (FRAME_X_DISPLAY (f
),
2698 GCForeground
| GCBackground
| GCLineWidth
,
2701 /* Cursor has cursor-color background, background-color foreground. */
2702 gc_values
.foreground
= FRAME_BACKGROUND_PIXEL (f
);
2703 gc_values
.background
= f
->output_data
.x
->cursor_pixel
;
2704 gc_values
.fill_style
= FillOpaqueStippled
;
2705 f
->output_data
.x
->cursor_gc
2706 = XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2707 (GCForeground
| GCBackground
2708 | GCFillStyle
| GCLineWidth
),
2711 /* Create the gray border tile used when the pointer is not in
2712 the frame. Since this depends on the frame's pixel values,
2713 this must be done on a per-frame basis. */
2714 f
->output_data
.x
->border_tile
2715 = (XCreatePixmapFromBitmapData
2716 (FRAME_X_DISPLAY (f
), FRAME_DISPLAY_INFO (f
)->root_window
,
2717 gray_bits
, gray_width
, gray_height
,
2718 FRAME_FOREGROUND_PIXEL (f
),
2719 FRAME_BACKGROUND_PIXEL (f
),
2720 DefaultDepth (FRAME_X_DISPLAY (f
), FRAME_X_SCREEN_NUMBER (f
))));
2726 /* Free what was allocated in x_make_gc. */
2729 x_free_gcs (struct frame
*f
)
2731 Display
*dpy
= FRAME_X_DISPLAY (f
);
2735 if (f
->output_data
.x
->normal_gc
)
2737 XFreeGC (dpy
, f
->output_data
.x
->normal_gc
);
2738 f
->output_data
.x
->normal_gc
= 0;
2741 if (f
->output_data
.x
->reverse_gc
)
2743 XFreeGC (dpy
, f
->output_data
.x
->reverse_gc
);
2744 f
->output_data
.x
->reverse_gc
= 0;
2747 if (f
->output_data
.x
->cursor_gc
)
2749 XFreeGC (dpy
, f
->output_data
.x
->cursor_gc
);
2750 f
->output_data
.x
->cursor_gc
= 0;
2753 if (f
->output_data
.x
->border_tile
)
2755 XFreePixmap (dpy
, f
->output_data
.x
->border_tile
);
2756 f
->output_data
.x
->border_tile
= 0;
2763 /* Handler for signals raised during x_create_frame and
2764 x_create_tip_frame. FRAME is the frame which is partially
2768 unwind_create_frame (Lisp_Object frame
)
2770 struct frame
*f
= XFRAME (frame
);
2772 /* If frame is already dead, nothing to do. This can happen if the
2773 display is disconnected after the frame has become official, but
2774 before x_create_frame removes the unwind protect. */
2775 if (!FRAME_LIVE_P (f
))
2778 /* If frame is ``official'', nothing to do. */
2779 if (NILP (Fmemq (frame
, Vframe_list
)))
2781 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2782 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
2785 x_free_frame_resources (f
);
2788 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2789 /* Check that reference counts are indeed correct. */
2790 eassert (dpyinfo
->reference_count
== dpyinfo_refcount
);
2791 eassert (dpyinfo
->terminal
->image_cache
->refcount
== image_cache_refcount
);
2800 do_unwind_create_frame (Lisp_Object frame
)
2802 unwind_create_frame (frame
);
2806 x_default_font_parameter (struct frame
*f
, Lisp_Object parms
)
2808 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
2809 Lisp_Object font_param
= x_get_arg (dpyinfo
, parms
, Qfont
, NULL
, NULL
,
2811 Lisp_Object font
= Qnil
;
2812 if (EQ (font_param
, Qunbound
))
2815 if (NILP (font_param
))
2817 /* System font should take precedence over X resources. We suggest this
2818 regardless of font-use-system-font because .emacs may not have been
2820 const char *system_font
= xsettings_get_system_font ();
2822 font
= font_open_by_name (f
, build_unibyte_string (system_font
));
2826 font
= !NILP (font_param
) ? font_param
2827 : x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
2829 if (! FONTP (font
) && ! STRINGP (font
))
2834 /* This will find the normal Xft font. */
2837 "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
2838 "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
2839 "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
2840 /* This was formerly the first thing tried, but it finds
2841 too many fonts and takes too long. */
2842 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
2843 /* If those didn't work, look for something which will
2845 "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
2850 for (i
= 0; names
[i
]; i
++)
2852 font
= font_open_by_name (f
, build_unibyte_string (names
[i
]));
2857 error ("No suitable font was found");
2859 else if (!NILP (font_param
))
2861 /* Remember the explicit font parameter, so we can re-apply it after
2862 we've applied the `default' face settings. */
2863 AUTO_FRAME_ARG (arg
, Qfont_param
, font_param
);
2864 x_set_frame_parameters (f
, arg
);
2867 /* This call will make X resources override any system font setting. */
2868 x_default_parameter (f
, parms
, Qfont
, font
, "font", "Font", RES_TYPE_STRING
);
2872 DEFUN ("x-wm-set-size-hint", Fx_wm_set_size_hint
, Sx_wm_set_size_hint
,
2874 doc
: /* Send the size hints for frame FRAME to the window manager.
2875 If FRAME is omitted or nil, use the selected frame.
2876 Signal error if FRAME is not an X frame. */)
2879 struct frame
*f
= decode_window_system_frame (frame
);
2882 x_wm_set_size_hint (f
, 0, 0);
2888 set_machine_and_pid_properties (struct frame
*f
)
2890 /* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME. */
2891 XSetWMProperties (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), NULL
, NULL
,
2892 NULL
, 0, NULL
, NULL
, NULL
);
2893 pid_t pid
= getpid ();
2894 if (pid
<= 0xffffffffu
)
2896 unsigned long xpid
= pid
;
2897 XChangeProperty (FRAME_X_DISPLAY (f
),
2898 FRAME_OUTER_WINDOW (f
),
2899 XInternAtom (FRAME_X_DISPLAY (f
),
2902 XA_CARDINAL
, 32, PropModeReplace
,
2903 (unsigned char *) &xpid
, 1);
2907 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
2909 doc
: /* Make a new X window, which is called a "frame" in Emacs terms.
2910 Return an Emacs frame object. PARMS is an alist of frame parameters.
2911 If the parameters specify that the frame should not have a minibuffer,
2912 and do not specify a specific minibuffer window to use, then
2913 `default-minibuffer-frame' must be a frame whose minibuffer can be
2914 shared by the new frame.
2916 This function is an internal primitive--use `make-frame' instead. */)
2920 Lisp_Object frame
, tem
;
2922 int minibuffer_only
= 0;
2923 long window_prompting
= 0;
2924 ptrdiff_t count
= SPECPDL_INDEX ();
2925 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
2926 Lisp_Object display
;
2927 struct x_display_info
*dpyinfo
= NULL
;
2931 parms
= Fcopy_alist (parms
);
2933 /* Use this general default value to start with
2934 until we know if this frame has a specified name. */
2935 Vx_resource_name
= Vinvocation_name
;
2937 display
= x_get_arg (dpyinfo
, parms
, Qterminal
, 0, 0, RES_TYPE_NUMBER
);
2938 if (EQ (display
, Qunbound
))
2939 display
= x_get_arg (dpyinfo
, parms
, Qdisplay
, 0, 0, RES_TYPE_STRING
);
2940 if (EQ (display
, Qunbound
))
2942 dpyinfo
= check_x_display_info (display
);
2943 kb
= dpyinfo
->terminal
->kboard
;
2945 if (!dpyinfo
->terminal
->name
)
2946 error ("Terminal is not live, can't create new frames on it");
2948 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
2950 && ! EQ (name
, Qunbound
)
2952 error ("Invalid frame name--not a string or nil");
2955 Vx_resource_name
= name
;
2957 /* See if parent window is specified. */
2958 parent
= x_get_arg (dpyinfo
, parms
, Qparent_id
, NULL
, NULL
, RES_TYPE_NUMBER
);
2959 if (EQ (parent
, Qunbound
))
2961 if (! NILP (parent
))
2962 CHECK_NUMBER (parent
);
2964 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
2965 /* No need to protect DISPLAY because that's not used after passing
2966 it to make_frame_without_minibuffer. */
2968 GCPRO4 (parms
, parent
, name
, frame
);
2969 tem
= x_get_arg (dpyinfo
, parms
, Qminibuffer
, "minibuffer", "Minibuffer",
2971 if (EQ (tem
, Qnone
) || NILP (tem
))
2972 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
2973 else if (EQ (tem
, Qonly
))
2975 f
= make_minibuffer_frame ();
2976 minibuffer_only
= 1;
2978 else if (WINDOWP (tem
))
2979 f
= make_frame_without_minibuffer (tem
, kb
, display
);
2983 XSETFRAME (frame
, f
);
2985 f
->terminal
= dpyinfo
->terminal
;
2987 f
->output_method
= output_x_window
;
2988 f
->output_data
.x
= xzalloc (sizeof *f
->output_data
.x
);
2989 f
->output_data
.x
->icon_bitmap
= -1;
2990 FRAME_FONTSET (f
) = -1;
2991 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
2992 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
2993 #if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
2994 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
2995 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
2996 #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
2997 f
->output_data
.x
->white_relief
.pixel
= -1;
2998 f
->output_data
.x
->black_relief
.pixel
= -1;
3001 x_get_arg (dpyinfo
, parms
, Qicon_name
, "iconName", "Title",
3003 if (! STRINGP (f
->icon_name
))
3004 fset_icon_name (f
, Qnil
);
3006 FRAME_DISPLAY_INFO (f
) = dpyinfo
;
3008 /* With FRAME_DISPLAY_INFO set up, this unwind-protect is safe. */
3009 record_unwind_protect (do_unwind_create_frame
, frame
);
3011 /* These colors will be set anyway later, but it's important
3012 to get the color reference counts right, so initialize them! */
3015 struct gcpro gcpro1
;
3017 /* Function x_decode_color can signal an error. Make
3018 sure to initialize color slots so that we won't try
3019 to free colors we haven't allocated. */
3020 FRAME_FOREGROUND_PIXEL (f
) = -1;
3021 FRAME_BACKGROUND_PIXEL (f
) = -1;
3022 f
->output_data
.x
->cursor_pixel
= -1;
3023 f
->output_data
.x
->cursor_foreground_pixel
= -1;
3024 f
->output_data
.x
->border_pixel
= -1;
3025 f
->output_data
.x
->mouse_pixel
= -1;
3027 black
= build_string ("black");
3029 FRAME_FOREGROUND_PIXEL (f
)
3030 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3031 FRAME_BACKGROUND_PIXEL (f
)
3032 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3033 f
->output_data
.x
->cursor_pixel
3034 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3035 f
->output_data
.x
->cursor_foreground_pixel
3036 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3037 f
->output_data
.x
->border_pixel
3038 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3039 f
->output_data
.x
->mouse_pixel
3040 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3044 /* Specify the parent under which to make this X window. */
3047 f
->output_data
.x
->parent_desc
= (Window
) XFASTINT (parent
);
3048 f
->output_data
.x
->explicit_parent
= 1;
3052 f
->output_data
.x
->parent_desc
= FRAME_DISPLAY_INFO (f
)->root_window
;
3053 f
->output_data
.x
->explicit_parent
= 0;
3056 /* Set the name; the functions to which we pass f expect the name to
3058 if (EQ (name
, Qunbound
) || NILP (name
))
3060 fset_name (f
, build_string (dpyinfo
->x_id_name
));
3061 f
->explicit_name
= 0;
3065 fset_name (f
, name
);
3066 f
->explicit_name
= 1;
3067 /* Use the frame's title when getting resources for this frame. */
3068 specbind (Qx_resource_name
, name
);
3071 #ifdef HAVE_FREETYPE
3073 register_font_driver (&xftfont_driver
, f
);
3074 #else /* not HAVE_XFT */
3075 register_font_driver (&ftxfont_driver
, f
);
3076 #endif /* not HAVE_XFT */
3077 #endif /* HAVE_FREETYPE */
3078 register_font_driver (&xfont_driver
, f
);
3080 x_default_parameter (f
, parms
, Qfont_backend
, Qnil
,
3081 "fontBackend", "FontBackend", RES_TYPE_STRING
);
3083 /* Extract the window parameters from the supplied values
3084 that are needed to determine window geometry. */
3085 x_default_font_parameter (f
, parms
);
3086 if (!FRAME_FONT (f
))
3088 delete_frame (frame
, Qnoelisp
);
3089 error ("Invalid frame font");
3092 /* Frame contents get displaced if an embedded X window has a border. */
3093 if (! FRAME_X_EMBEDDED_P (f
))
3094 x_default_parameter (f
, parms
, Qborder_width
, make_number (0),
3095 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
3097 /* This defaults to 1 in order to match xterm. We recognize either
3098 internalBorderWidth or internalBorder (which is what xterm calls
3100 if (NILP (Fassq (Qinternal_border_width
, parms
)))
3104 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
3105 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
3106 if (! EQ (value
, Qunbound
))
3107 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
3110 x_default_parameter (f
, parms
, Qinternal_border_width
,
3111 #ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */
3116 "internalBorderWidth", "internalBorderWidth",
3118 x_default_parameter (f
, parms
, Qright_divider_width
, make_number (0),
3119 NULL
, NULL
, RES_TYPE_NUMBER
);
3120 x_default_parameter (f
, parms
, Qbottom_divider_width
, make_number (0),
3121 NULL
, NULL
, RES_TYPE_NUMBER
);
3122 x_default_parameter (f
, parms
, Qvertical_scroll_bars
,
3123 #if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
3128 "verticalScrollBars", "ScrollBars",
3130 x_default_parameter (f
, parms
, Qhorizontal_scroll_bars
, Qnil
,
3131 "horizontalScrollBars", "ScrollBars",
3133 /* Also do the stuff which must be set before the window exists. */
3134 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
3135 "foreground", "Foreground", RES_TYPE_STRING
);
3136 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
3137 "background", "Background", RES_TYPE_STRING
);
3138 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
3139 "pointerColor", "Foreground", RES_TYPE_STRING
);
3140 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
3141 "borderColor", "BorderColor", RES_TYPE_STRING
);
3142 x_default_parameter (f
, parms
, Qscreen_gamma
, Qnil
,
3143 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT
);
3144 x_default_parameter (f
, parms
, Qline_spacing
, Qnil
,
3145 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER
);
3146 x_default_parameter (f
, parms
, Qleft_fringe
, Qnil
,
3147 "leftFringe", "LeftFringe", RES_TYPE_NUMBER
);
3148 x_default_parameter (f
, parms
, Qright_fringe
, Qnil
,
3149 "rightFringe", "RightFringe", RES_TYPE_NUMBER
);
3151 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_foreground
,
3152 "scrollBarForeground",
3153 "ScrollBarForeground", 1);
3154 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_background
,
3155 "scrollBarBackground",
3156 "ScrollBarBackground", 0);
3159 image_cache_refcount
=
3160 FRAME_IMAGE_CACHE (f
) ? FRAME_IMAGE_CACHE (f
)->refcount
: 0;
3161 dpyinfo_refcount
= dpyinfo
->reference_count
;
3162 #endif /* GLYPH_DEBUG */
3164 /* Init faces before x_default_parameter is called for the
3165 scroll-bar-width parameter because otherwise we end up in
3166 init_iterator with a null face cache, which should not happen. */
3167 init_frame_faces (f
);
3169 /* The following call of change_frame_size is needed since otherwise
3170 x_set_tool_bar_lines will already work with the character sizes
3171 installed by init_frame_faces while the frame's pixel size is
3172 still calculated from a character size of 1 and we subsequently
3173 hit the (height >= 0) assertion in window_box_height.
3175 The non-pixelwise code apparently worked around this because it
3176 had one frame line vs one toolbar line which left us with a zero
3177 root window height which was obviously wrong as well ... */
3178 adjust_frame_size (f
, FRAME_COLS (f
) * FRAME_COLUMN_WIDTH (f
),
3179 FRAME_LINES (f
) * FRAME_LINE_HEIGHT (f
), 5, 1, Qnil
);
3181 /* Set the menu-bar-lines and tool-bar-lines parameters. We don't
3182 look up the X resources controlling the menu-bar and tool-bar
3183 here; they are processed specially at startup, and reflected in
3184 the values of the mode variables. */
3186 x_default_parameter (f
, parms
, Qmenu_bar_lines
,
3187 NILP (Vmenu_bar_mode
)
3188 ? make_number (0) : make_number (1),
3189 NULL
, NULL
, RES_TYPE_NUMBER
);
3190 x_default_parameter (f
, parms
, Qtool_bar_lines
,
3191 NILP (Vtool_bar_mode
)
3192 ? make_number (0) : make_number (1),
3193 NULL
, NULL
, RES_TYPE_NUMBER
);
3195 x_default_parameter (f
, parms
, Qbuffer_predicate
, Qnil
,
3196 "bufferPredicate", "BufferPredicate",
3198 x_default_parameter (f
, parms
, Qtitle
, Qnil
,
3199 "title", "Title", RES_TYPE_STRING
);
3200 x_default_parameter (f
, parms
, Qwait_for_wm
, Qt
,
3201 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN
);
3202 x_default_parameter (f
, parms
, Qfullscreen
, Qnil
,
3203 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL
);
3204 x_default_parameter (f
, parms
, Qtool_bar_position
,
3205 FRAME_TOOL_BAR_POSITION (f
), 0, 0, RES_TYPE_SYMBOL
);
3207 /* Compute the size of the X window. */
3208 window_prompting
= x_figure_window_size (f
, parms
, 1);
3210 tem
= x_get_arg (dpyinfo
, parms
, Qunsplittable
, 0, 0, RES_TYPE_BOOLEAN
);
3211 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
3213 x_icon_verify (f
, parms
);
3215 /* Create the X widget or window. */
3216 #ifdef USE_X_TOOLKIT
3217 x_window (f
, window_prompting
, minibuffer_only
);
3225 /* Now consider the frame official. */
3226 f
->terminal
->reference_count
++;
3227 FRAME_DISPLAY_INFO (f
)->reference_count
++;
3228 Vframe_list
= Fcons (frame
, Vframe_list
);
3230 /* We need to do this after creating the X window, so that the
3231 icon-creation functions can say whose icon they're describing. */
3232 x_default_parameter (f
, parms
, Qicon_type
, Qt
,
3233 "bitmapIcon", "BitmapIcon", RES_TYPE_BOOLEAN
);
3235 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
3236 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3237 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
3238 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3239 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
3240 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
3241 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
3242 "scrollBarWidth", "ScrollBarWidth",
3244 x_default_parameter (f
, parms
, Qscroll_bar_height
, Qnil
,
3245 "scrollBarHeight", "ScrollBarHeight",
3247 x_default_parameter (f
, parms
, Qalpha
, Qnil
,
3248 "alpha", "Alpha", RES_TYPE_NUMBER
);
3250 /* Consider frame official, now. */
3251 f
->can_x_set_window_size
= true;
3253 adjust_frame_size (f
, FRAME_TEXT_WIDTH (f
), FRAME_TEXT_HEIGHT (f
), 0, 1, Qnil
);
3255 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3256 /* Create the menu bar. */
3257 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
3259 /* If this signals an error, we haven't set size hints for the
3260 frame and we didn't make it visible. */
3261 initialize_frame_menubar (f
);
3264 /* This is a no-op, except under Motif where it arranges the
3265 main window for the widgets on it. */
3266 lw_set_main_areas (f
->output_data
.x
->column_widget
,
3267 f
->output_data
.x
->menubar_widget
,
3268 f
->output_data
.x
->edit_widget
);
3269 #endif /* not USE_GTK */
3271 #endif /* USE_X_TOOLKIT || USE_GTK */
3273 /* Tell the server what size and position, etc, we want, and how
3274 badly we want them. This should be done after we have the menu
3275 bar so that its size can be taken into account. */
3277 x_wm_set_size_hint (f
, window_prompting
, 0);
3280 /* Make the window appear on the frame and enable display, unless
3281 the caller says not to. However, with explicit parent, Emacs
3282 cannot control visibility, so don't try. */
3283 if (! f
->output_data
.x
->explicit_parent
)
3285 Lisp_Object visibility
;
3287 visibility
= x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0,
3289 if (EQ (visibility
, Qunbound
))
3292 if (EQ (visibility
, Qicon
))
3293 x_iconify_frame (f
);
3294 else if (! NILP (visibility
))
3295 x_make_frame_visible (f
);
3298 /* Must have been Qnil. */
3304 /* Set machine name and pid for the purpose of window managers. */
3305 set_machine_and_pid_properties (f
);
3307 /* Set the WM leader property. GTK does this itself, so this is not
3308 needed when using GTK. */
3309 if (dpyinfo
->client_leader_window
!= 0)
3311 XChangeProperty (FRAME_X_DISPLAY (f
),
3312 FRAME_OUTER_WINDOW (f
),
3313 dpyinfo
->Xatom_wm_client_leader
,
3314 XA_WINDOW
, 32, PropModeReplace
,
3315 (unsigned char *) &dpyinfo
->client_leader_window
, 1);
3320 /* Initialize `default-minibuffer-frame' in case this is the first
3321 frame on this terminal. */
3322 if (FRAME_HAS_MINIBUF_P (f
)
3323 && (!FRAMEP (KVAR (kb
, Vdefault_minibuffer_frame
))
3324 || !FRAME_LIVE_P (XFRAME (KVAR (kb
, Vdefault_minibuffer_frame
)))))
3325 kset_default_minibuffer_frame (kb
, frame
);
3327 /* All remaining specified parameters, which have not been "used"
3328 by x_get_arg and friends, now go in the misc. alist of the frame. */
3329 for (tem
= parms
; CONSP (tem
); tem
= XCDR (tem
))
3330 if (CONSP (XCAR (tem
)) && !NILP (XCAR (XCAR (tem
))))
3331 fset_param_alist (f
, Fcons (XCAR (tem
), f
->param_alist
));
3335 /* Make sure windows on this frame appear in calls to next-window
3336 and similar functions. */
3337 Vwindow_list
= Qnil
;
3339 return unbind_to (count
, frame
);
3343 /* FRAME is used only to get a handle on the X display. We don't pass the
3344 display info directly because we're called from frame.c, which doesn't
3345 know about that structure. */
3348 x_get_focus_frame (struct frame
*frame
)
3350 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (frame
);
3352 if (! dpyinfo
->x_focus_frame
)
3355 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
3360 /* In certain situations, when the window manager follows a
3361 click-to-focus policy, there seems to be no way around calling
3362 XSetInputFocus to give another frame the input focus .
3364 In an ideal world, XSetInputFocus should generally be avoided so
3365 that applications don't interfere with the window manager's focus
3366 policy. But I think it's okay to use when it's clearly done
3367 following a user-command. */
3370 x_focus_frame (struct frame
*f
)
3372 Display
*dpy
= FRAME_X_DISPLAY (f
);
3375 x_catch_errors (dpy
);
3377 if (FRAME_X_EMBEDDED_P (f
))
3379 /* For Xembedded frames, normally the embedder forwards key
3380 events. See XEmbed Protocol Specification at
3381 http://freedesktop.org/wiki/Specifications/xembed-spec */
3382 xembed_request_focus (f
);
3386 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3387 RevertToParent
, CurrentTime
);
3388 x_ewmh_activate_frame (f
);
3391 x_uncatch_errors ();
3396 DEFUN ("xw-color-defined-p", Fxw_color_defined_p
, Sxw_color_defined_p
, 1, 2, 0,
3397 doc
: /* Internal function called by `color-defined-p', which see
3398 .\(Note that the Nextstep version of this function ignores FRAME.) */)
3399 (Lisp_Object color
, Lisp_Object frame
)
3402 struct frame
*f
= decode_window_system_frame (frame
);
3404 CHECK_STRING (color
);
3406 if (x_defined_color (f
, SSDATA (color
), &foo
, 0))
3412 DEFUN ("xw-color-values", Fxw_color_values
, Sxw_color_values
, 1, 2, 0,
3413 doc
: /* Internal function called by `color-values', which see. */)
3414 (Lisp_Object color
, Lisp_Object frame
)
3417 struct frame
*f
= decode_window_system_frame (frame
);
3419 CHECK_STRING (color
);
3421 if (x_defined_color (f
, SSDATA (color
), &foo
, 0))
3422 return list3i (foo
.red
, foo
.green
, foo
.blue
);
3427 DEFUN ("xw-display-color-p", Fxw_display_color_p
, Sxw_display_color_p
, 0, 1, 0,
3428 doc
: /* Internal function called by `display-color-p', which see. */)
3429 (Lisp_Object terminal
)
3431 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3433 if (dpyinfo
->n_planes
<= 2)
3436 switch (dpyinfo
->visual
->class)
3449 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
3451 doc
: /* Return t if the X display supports shades of gray.
3452 Note that color displays do support shades of gray.
3453 The optional argument TERMINAL specifies which display to ask about.
3454 TERMINAL should be a terminal object, a frame or a display name (a string).
3455 If omitted or nil, that stands for the selected frame's display. */)
3456 (Lisp_Object terminal
)
3458 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3460 if (dpyinfo
->n_planes
<= 1)
3463 switch (dpyinfo
->visual
->class)
3478 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
3480 doc
: /* Return the width in pixels of the X display TERMINAL.
3481 The optional argument TERMINAL specifies which display to ask about.
3482 TERMINAL should be a terminal object, a frame or a display name (a string).
3483 If omitted or nil, that stands for the selected frame's display.
3485 On \"multi-monitor\" setups this refers to the pixel width for all
3486 physical monitors associated with TERMINAL. To get information for
3487 each physical monitor, use `display-monitor-attributes-list'. */)
3488 (Lisp_Object terminal
)
3490 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3492 return make_number (x_display_pixel_width (dpyinfo
));
3495 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
3496 Sx_display_pixel_height
, 0, 1, 0,
3497 doc
: /* Return the height in pixels of the X display TERMINAL.
3498 The optional argument TERMINAL specifies which display to ask about.
3499 TERMINAL should be a terminal object, a frame or a display name (a string).
3500 If omitted or nil, that stands for the selected frame's display.
3502 On \"multi-monitor\" setups this refers to the pixel height for all
3503 physical monitors associated with TERMINAL. To get information for
3504 each physical monitor, use `display-monitor-attributes-list'. */)
3505 (Lisp_Object terminal
)
3507 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3509 return make_number (x_display_pixel_height (dpyinfo
));
3512 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
3514 doc
: /* Return the number of bitplanes of the X display TERMINAL.
3515 The optional argument TERMINAL specifies which display to ask about.
3516 TERMINAL should be a terminal object, a frame or a display name (a string).
3517 If omitted or nil, that stands for the selected frame's display. */)
3518 (Lisp_Object terminal
)
3520 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3522 return make_number (dpyinfo
->n_planes
);
3525 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
3527 doc
: /* Return the number of color cells of the X display TERMINAL.
3528 The optional argument TERMINAL specifies which display to ask about.
3529 TERMINAL should be a terminal object, a frame or a display name (a string).
3530 If omitted or nil, that stands for the selected frame's display. */)
3531 (Lisp_Object terminal
)
3533 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3535 int nr_planes
= DisplayPlanes (dpyinfo
->display
,
3536 XScreenNumberOfScreen (dpyinfo
->screen
));
3538 /* Truncate nr_planes to 24 to avoid integer overflow.
3539 Some displays says 32, but only 24 bits are actually significant.
3540 There are only very few and rare video cards that have more than
3541 24 significant bits. Also 24 bits is more than 16 million colors,
3542 it "should be enough for everyone". */
3543 if (nr_planes
> 24) nr_planes
= 24;
3545 return make_number (1 << nr_planes
);
3548 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
3549 Sx_server_max_request_size
,
3551 doc
: /* Return the maximum request size of the X server of display TERMINAL.
3552 The optional argument TERMINAL specifies which display to ask about.
3553 TERMINAL should be a terminal object, a frame or a display name (a string).
3554 If omitted or nil, that stands for the selected frame's display. */)
3555 (Lisp_Object terminal
)
3557 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3559 return make_number (MAXREQUEST (dpyinfo
->display
));
3562 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
3563 doc
: /* Return the "vendor ID" string of the X server of display TERMINAL.
3564 \(Labeling every distributor as a "vendor" embodies the false assumption
3565 that operating systems cannot be developed and distributed noncommercially.)
3566 The optional argument TERMINAL specifies which display to ask about.
3567 TERMINAL should be a terminal object, a frame or a display name (a string).
3568 If omitted or nil, that stands for the selected frame's display. */)
3569 (Lisp_Object terminal
)
3571 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3572 const char *vendor
= ServerVendor (dpyinfo
->display
);
3574 if (! vendor
) vendor
= "";
3575 return build_string (vendor
);
3578 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
3579 doc
: /* Return the version numbers of the X server of display TERMINAL.
3580 The value is a list of three integers: the major and minor
3581 version numbers of the X Protocol in use, and the distributor-specific release
3582 number. See also the function `x-server-vendor'.
3584 The optional argument TERMINAL specifies which display to ask about.
3585 TERMINAL should be a terminal object, a frame or a display name (a string).
3586 If omitted or nil, that stands for the selected frame's display. */)
3587 (Lisp_Object terminal
)
3589 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3590 Display
*dpy
= dpyinfo
->display
;
3592 return list3i (ProtocolVersion (dpy
), ProtocolRevision (dpy
),
3593 VendorRelease (dpy
));
3596 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
3597 doc
: /* Return the number of screens on the X server of display TERMINAL.
3598 The optional argument TERMINAL specifies which display to ask about.
3599 TERMINAL should be a terminal object, a frame or a display name (a string).
3600 If omitted or nil, that stands for the selected frame's display. */)
3601 (Lisp_Object terminal
)
3603 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3605 return make_number (ScreenCount (dpyinfo
->display
));
3608 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
3609 doc
: /* Return the height in millimeters of the X display TERMINAL.
3610 The optional argument TERMINAL specifies which display to ask about.
3611 TERMINAL should be a terminal object, a frame or a display name (a string).
3612 If omitted or nil, that stands for the selected frame's display.
3614 On \"multi-monitor\" setups this refers to the height in millimeters for
3615 all physical monitors associated with TERMINAL. To get information
3616 for each physical monitor, use `display-monitor-attributes-list'. */)
3617 (Lisp_Object terminal
)
3619 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3621 return make_number (HeightMMOfScreen (dpyinfo
->screen
));
3624 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
3625 doc
: /* Return the width in millimeters of the X display TERMINAL.
3626 The optional argument TERMINAL specifies which display to ask about.
3627 TERMINAL should be a terminal object, a frame or a display name (a string).
3628 If omitted or nil, that stands for the selected frame's display.
3630 On \"multi-monitor\" setups this refers to the width in millimeters for
3631 all physical monitors associated with TERMINAL. To get information
3632 for each physical monitor, use `display-monitor-attributes-list'. */)
3633 (Lisp_Object terminal
)
3635 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3637 return make_number (WidthMMOfScreen (dpyinfo
->screen
));
3640 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
3641 Sx_display_backing_store
, 0, 1, 0,
3642 doc
: /* Return an indication of whether X display TERMINAL does backing store.
3643 The value may be `always', `when-mapped', or `not-useful'.
3644 The optional argument TERMINAL specifies which display to ask about.
3645 TERMINAL should be a terminal object, a frame or a display name (a string).
3646 If omitted or nil, that stands for the selected frame's display. */)
3647 (Lisp_Object terminal
)
3649 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3652 switch (DoesBackingStore (dpyinfo
->screen
))
3655 result
= intern ("always");
3659 result
= intern ("when-mapped");
3663 result
= intern ("not-useful");
3667 error ("Strange value for BackingStore parameter of screen");
3673 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
3674 Sx_display_visual_class
, 0, 1, 0,
3675 doc
: /* Return the visual class of the X display TERMINAL.
3676 The value is one of the symbols `static-gray', `gray-scale',
3677 `static-color', `pseudo-color', `true-color', or `direct-color'.
3679 The optional argument TERMINAL specifies which display to ask about.
3680 TERMINAL should a terminal object, a frame or a display name (a string).
3681 If omitted or nil, that stands for the selected frame's display. */)
3682 (Lisp_Object terminal
)
3684 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3687 switch (dpyinfo
->visual
->class)
3690 result
= intern ("static-gray");
3693 result
= intern ("gray-scale");
3696 result
= intern ("static-color");
3699 result
= intern ("pseudo-color");
3702 result
= intern ("true-color");
3705 result
= intern ("direct-color");
3708 error ("Display has an unknown visual class");
3714 DEFUN ("x-display-save-under", Fx_display_save_under
,
3715 Sx_display_save_under
, 0, 1, 0,
3716 doc
: /* Return t if the X display TERMINAL supports the save-under feature.
3717 The optional argument TERMINAL specifies which display to ask about.
3718 TERMINAL should be a terminal object, a frame or a display name (a string).
3719 If omitted or nil, that stands for the selected frame's display. */)
3720 (Lisp_Object terminal
)
3722 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3724 if (DoesSaveUnders (dpyinfo
->screen
) == True
)
3730 /* Store the geometry of the workarea on display DPYINFO into *RECT.
3731 Return false if and only if the workarea information cannot be
3732 obtained via the _NET_WORKAREA root window property. */
3734 #if ! GTK_CHECK_VERSION (3, 4, 0)
3736 x_get_net_workarea (struct x_display_info
*dpyinfo
, XRectangle
*rect
)
3738 Display
*dpy
= dpyinfo
->display
;
3739 long offset
, max_len
;
3740 Atom target_type
, actual_type
;
3741 unsigned long actual_size
, bytes_remaining
;
3742 int rc
, actual_format
;
3743 unsigned char *tmp_data
= NULL
;
3744 bool result
= false;
3746 x_catch_errors (dpy
);
3749 target_type
= XA_CARDINAL
;
3750 rc
= XGetWindowProperty (dpy
, dpyinfo
->root_window
,
3751 dpyinfo
->Xatom_net_current_desktop
,
3752 offset
, max_len
, False
, target_type
,
3753 &actual_type
, &actual_format
, &actual_size
,
3754 &bytes_remaining
, &tmp_data
);
3755 if (rc
== Success
&& actual_type
== target_type
&& !x_had_errors_p (dpy
)
3756 && actual_format
== 32 && actual_size
== max_len
)
3758 long current_desktop
= ((long *) tmp_data
)[0];
3763 offset
= 4 * current_desktop
;
3765 rc
= XGetWindowProperty (dpy
, dpyinfo
->root_window
,
3766 dpyinfo
->Xatom_net_workarea
,
3767 offset
, max_len
, False
, target_type
,
3768 &actual_type
, &actual_format
, &actual_size
,
3769 &bytes_remaining
, &tmp_data
);
3770 if (rc
== Success
&& actual_type
== target_type
&& !x_had_errors_p (dpy
)
3771 && actual_format
== 32 && actual_size
== max_len
)
3773 long *values
= (long *) tmp_data
;
3775 rect
->x
= values
[0];
3776 rect
->y
= values
[1];
3777 rect
->width
= values
[2];
3778 rect
->height
= values
[3];
3788 x_uncatch_errors ();
3796 /* Return monitor number where F is "most" or closest to. */
3798 x_get_monitor_for_frame (struct frame
*f
,
3799 struct MonitorInfo
*monitors
,
3803 int area
= 0, dist
= -1;
3804 int best_area
= -1, best_dist
= -1;
3807 if (n_monitors
== 1) return 0;
3808 frect
.x
= f
->left_pos
;
3809 frect
.y
= f
->top_pos
;
3810 frect
.width
= FRAME_PIXEL_WIDTH (f
);
3811 frect
.height
= FRAME_PIXEL_HEIGHT (f
);
3813 for (i
= 0; i
< n_monitors
; ++i
)
3815 struct MonitorInfo
*mi
= &monitors
[i
];
3819 if (mi
->geom
.width
== 0) continue;
3821 if (x_intersect_rectangles (&mi
->geom
, &frect
, &res
))
3823 a
= res
.width
* res
.height
;
3831 if (a
== 0 && area
== 0)
3834 if (frect
.x
+ frect
.width
< mi
->geom
.x
)
3835 dx
= mi
->geom
.x
- frect
.x
+ frect
.width
;
3836 else if (frect
.x
> mi
->geom
.x
+ mi
->geom
.width
)
3837 dx
= frect
.x
- mi
->geom
.x
+ mi
->geom
.width
;
3840 if (frect
.y
+ frect
.height
< mi
->geom
.y
)
3841 dy
= mi
->geom
.y
- frect
.y
+ frect
.height
;
3842 else if (frect
.y
> mi
->geom
.y
+ mi
->geom
.height
)
3843 dy
= frect
.y
- mi
->geom
.y
+ mi
->geom
.height
;
3848 if (dist
== -1 || dist
> d
)
3856 return best_area
!= -1 ? best_area
: (best_dist
!= -1 ? best_dist
: 0);
3860 x_make_monitor_attribute_list (struct MonitorInfo
*monitors
,
3862 int primary_monitor
,
3863 struct x_display_info
*dpyinfo
,
3866 Lisp_Object monitor_frames
= Fmake_vector (make_number (n_monitors
), Qnil
);
3867 Lisp_Object frame
, rest
;
3869 FOR_EACH_FRAME (rest
, frame
)
3871 struct frame
*f
= XFRAME (frame
);
3873 if (FRAME_X_P (f
) && FRAME_DISPLAY_INFO (f
) == dpyinfo
3874 && !EQ (frame
, tip_frame
))
3876 int i
= x_get_monitor_for_frame (f
, monitors
, n_monitors
);
3877 ASET (monitor_frames
, i
, Fcons (frame
, AREF (monitor_frames
, i
)));
3881 return make_monitor_attribute_list (monitors
, n_monitors
, primary_monitor
,
3882 monitor_frames
, source
);
3886 x_get_monitor_attributes_fallback (struct x_display_info
*dpyinfo
)
3888 struct MonitorInfo monitor
;
3889 XRectangle workarea_r
;
3891 /* Fallback: treat (possibly) multiple physical monitors as if they
3892 formed a single monitor as a whole. This should provide a
3893 consistent result at least on single monitor environments. */
3894 monitor
.geom
.x
= monitor
.geom
.y
= 0;
3895 monitor
.geom
.width
= x_display_pixel_width (dpyinfo
);
3896 monitor
.geom
.height
= x_display_pixel_height (dpyinfo
);
3897 monitor
.mm_width
= WidthMMOfScreen (dpyinfo
->screen
);
3898 monitor
.mm_height
= HeightMMOfScreen (dpyinfo
->screen
);
3899 monitor
.name
= xstrdup ("combined screen");
3901 if (x_get_net_workarea (dpyinfo
, &workarea_r
))
3902 monitor
.work
= workarea_r
;
3904 monitor
.work
= monitor
.geom
;
3905 return x_make_monitor_attribute_list (&monitor
, 1, 0, dpyinfo
, "fallback");
3909 #ifdef HAVE_XINERAMA
3911 x_get_monitor_attributes_xinerama (struct x_display_info
*dpyinfo
)
3914 Lisp_Object attributes_list
= Qnil
;
3915 Display
*dpy
= dpyinfo
->display
;
3916 XineramaScreenInfo
*info
= XineramaQueryScreens (dpy
, &n_monitors
);
3917 struct MonitorInfo
*monitors
;
3918 double mm_width_per_pixel
, mm_height_per_pixel
;
3920 if (! info
|| n_monitors
== 0)
3924 return attributes_list
;
3927 mm_width_per_pixel
= ((double) WidthMMOfScreen (dpyinfo
->screen
)
3928 / x_display_pixel_width (dpyinfo
));
3929 mm_height_per_pixel
= ((double) HeightMMOfScreen (dpyinfo
->screen
)
3930 / x_display_pixel_height (dpyinfo
));
3931 monitors
= xzalloc (n_monitors
* sizeof *monitors
);
3932 for (i
= 0; i
< n_monitors
; ++i
)
3934 struct MonitorInfo
*mi
= &monitors
[i
];
3935 XRectangle workarea_r
;
3937 mi
->geom
.x
= info
[i
].x_org
;
3938 mi
->geom
.y
= info
[i
].y_org
;
3939 mi
->geom
.width
= info
[i
].width
;
3940 mi
->geom
.height
= info
[i
].height
;
3941 mi
->mm_width
= mi
->geom
.width
* mm_width_per_pixel
+ 0.5;
3942 mi
->mm_height
= mi
->geom
.height
* mm_height_per_pixel
+ 0.5;
3945 /* Xinerama usually have primary monitor first, just use that. */
3946 if (i
== 0 && x_get_net_workarea (dpyinfo
, &workarea_r
))
3948 mi
->work
= workarea_r
;
3949 if (! x_intersect_rectangles (&mi
->geom
, &mi
->work
, &mi
->work
))
3950 mi
->work
= mi
->geom
;
3953 mi
->work
= mi
->geom
;
3957 attributes_list
= x_make_monitor_attribute_list (monitors
,
3962 free_monitors (monitors
, n_monitors
);
3963 return attributes_list
;
3965 #endif /* HAVE_XINERAMA */
3970 x_get_monitor_attributes_xrandr (struct x_display_info
*dpyinfo
)
3972 Lisp_Object attributes_list
= Qnil
;
3973 XRRScreenResources
*resources
;
3974 Display
*dpy
= dpyinfo
->display
;
3975 int i
, n_monitors
, primary
= -1;
3976 RROutput pxid
= None
;
3977 struct MonitorInfo
*monitors
;
3979 #ifdef HAVE_XRRGETSCREENRESOURCESCURRENT
3980 resources
= XRRGetScreenResourcesCurrent (dpy
, dpyinfo
->root_window
);
3982 resources
= XRRGetScreenResources (dpy
, dpyinfo
->root_window
);
3984 if (! resources
|| resources
->noutput
== 0)
3987 XRRFreeScreenResources (resources
);
3990 n_monitors
= resources
->noutput
;
3991 monitors
= xzalloc (n_monitors
* sizeof *monitors
);
3993 #ifdef HAVE_XRRGETOUTPUTPRIMARY
3994 pxid
= XRRGetOutputPrimary (dpy
, dpyinfo
->root_window
);
3997 for (i
= 0; i
< n_monitors
; ++i
)
3999 XRROutputInfo
*info
= XRRGetOutputInfo (dpy
, resources
,
4000 resources
->outputs
[i
]);
4001 Connection conn
= info
? info
->connection
: RR_Disconnected
;
4002 RRCrtc id
= info
? info
->crtc
: None
;
4004 if (strcmp (info
->name
, "default") == 0)
4006 /* Non XRandr 1.2 driver, does not give useful data. */
4007 XRRFreeOutputInfo (info
);
4008 XRRFreeScreenResources (resources
);
4009 free_monitors (monitors
, n_monitors
);
4013 if (conn
!= RR_Disconnected
&& id
!= None
)
4015 XRRCrtcInfo
*crtc
= XRRGetCrtcInfo (dpy
, resources
, id
);
4016 struct MonitorInfo
*mi
= &monitors
[i
];
4017 XRectangle workarea_r
;
4021 XRRFreeOutputInfo (info
);
4025 mi
->geom
.x
= crtc
->x
;
4026 mi
->geom
.y
= crtc
->y
;
4027 mi
->geom
.width
= crtc
->width
;
4028 mi
->geom
.height
= crtc
->height
;
4029 mi
->mm_width
= info
->mm_width
;
4030 mi
->mm_height
= info
->mm_height
;
4031 mi
->name
= xstrdup (info
->name
);
4033 if (pxid
!= None
&& pxid
== resources
->outputs
[i
])
4035 else if (primary
== -1 && strcmp (info
->name
, "LVDS") == 0)
4038 if (i
== primary
&& x_get_net_workarea (dpyinfo
, &workarea_r
))
4040 mi
->work
= workarea_r
;
4041 if (! x_intersect_rectangles (&mi
->geom
, &mi
->work
, &mi
->work
))
4042 mi
->work
= mi
->geom
;
4045 mi
->work
= mi
->geom
;
4047 XRRFreeCrtcInfo (crtc
);
4049 XRRFreeOutputInfo (info
);
4051 XRRFreeScreenResources (resources
);
4053 attributes_list
= x_make_monitor_attribute_list (monitors
,
4058 free_monitors (monitors
, n_monitors
);
4059 return attributes_list
;
4061 #endif /* HAVE_XRANDR */
4064 x_get_monitor_attributes (struct x_display_info
*dpyinfo
)
4066 Lisp_Object attributes_list
= Qnil
;
4067 Display
*dpy
= dpyinfo
->display
;
4069 (void) dpy
; /* Suppress unused variable warning. */
4072 int xrr_event_base
, xrr_error_base
;
4073 bool xrr_ok
= false;
4074 xrr_ok
= XRRQueryExtension (dpy
, &xrr_event_base
, &xrr_error_base
);
4077 int xrr_major
, xrr_minor
;
4078 XRRQueryVersion (dpy
, &xrr_major
, &xrr_minor
);
4079 xrr_ok
= (xrr_major
== 1 && xrr_minor
>= 2) || xrr_major
> 1;
4083 attributes_list
= x_get_monitor_attributes_xrandr (dpyinfo
);
4084 #endif /* HAVE_XRANDR */
4086 #ifdef HAVE_XINERAMA
4087 if (NILP (attributes_list
))
4089 int xin_event_base
, xin_error_base
;
4090 bool xin_ok
= false;
4091 xin_ok
= XineramaQueryExtension (dpy
, &xin_event_base
, &xin_error_base
);
4092 if (xin_ok
&& XineramaIsActive (dpy
))
4093 attributes_list
= x_get_monitor_attributes_xinerama (dpyinfo
);
4095 #endif /* HAVE_XINERAMA */
4097 if (NILP (attributes_list
))
4098 attributes_list
= x_get_monitor_attributes_fallback (dpyinfo
);
4100 return attributes_list
;
4103 #endif /* !USE_GTK */
4105 DEFUN ("x-display-monitor-attributes-list", Fx_display_monitor_attributes_list
,
4106 Sx_display_monitor_attributes_list
,
4108 doc
: /* Return a list of physical monitor attributes on the X display TERMINAL.
4110 The optional argument TERMINAL specifies which display to ask about.
4111 TERMINAL should be a terminal object, a frame or a display name (a string).
4112 If omitted or nil, that stands for the selected frame's display.
4114 In addition to the standard attribute keys listed in
4115 `display-monitor-attributes-list', the following keys are contained in
4118 source -- String describing the source from which multi-monitor
4119 information is obtained, one of \"Gdk\", \"XRandr\",
4120 \"Xinerama\", or \"fallback\"
4122 Internal use only, use `display-monitor-attributes-list' instead. */)
4123 (Lisp_Object terminal
)
4125 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4126 Lisp_Object attributes_list
= Qnil
;
4129 double mm_width_per_pixel
, mm_height_per_pixel
;
4132 gint primary_monitor
= 0, n_monitors
, i
;
4133 Lisp_Object monitor_frames
, rest
, frame
;
4134 static const char *source
= "Gdk";
4135 struct MonitorInfo
*monitors
;
4138 mm_width_per_pixel
= ((double) WidthMMOfScreen (dpyinfo
->screen
)
4139 / x_display_pixel_width (dpyinfo
));
4140 mm_height_per_pixel
= ((double) HeightMMOfScreen (dpyinfo
->screen
)
4141 / x_display_pixel_height (dpyinfo
));
4142 gdpy
= gdk_x11_lookup_xdisplay (dpyinfo
->display
);
4143 gscreen
= gdk_display_get_default_screen (gdpy
);
4144 #if GTK_CHECK_VERSION (2, 20, 0)
4145 primary_monitor
= gdk_screen_get_primary_monitor (gscreen
);
4147 n_monitors
= gdk_screen_get_n_monitors (gscreen
);
4148 monitor_frames
= Fmake_vector (make_number (n_monitors
), Qnil
);
4149 monitors
= xzalloc (n_monitors
* sizeof *monitors
);
4151 FOR_EACH_FRAME (rest
, frame
)
4153 struct frame
*f
= XFRAME (frame
);
4155 if (FRAME_X_P (f
) && FRAME_DISPLAY_INFO (f
) == dpyinfo
4156 && !EQ (frame
, tip_frame
))
4158 GdkWindow
*gwin
= gtk_widget_get_window (FRAME_GTK_WIDGET (f
));
4160 i
= gdk_screen_get_monitor_at_window (gscreen
, gwin
);
4161 ASET (monitor_frames
, i
, Fcons (frame
, AREF (monitor_frames
, i
)));
4165 for (i
= 0; i
< n_monitors
; ++i
)
4167 gint width_mm
= -1, height_mm
= -1;
4168 GdkRectangle rec
, work
;
4169 struct MonitorInfo
*mi
= &monitors
[i
];
4171 gdk_screen_get_monitor_geometry (gscreen
, i
, &rec
);
4173 #if GTK_CHECK_VERSION (2, 14, 0)
4174 width_mm
= gdk_screen_get_monitor_width_mm (gscreen
, i
);
4175 height_mm
= gdk_screen_get_monitor_height_mm (gscreen
, i
);
4178 width_mm
= rec
.width
* mm_width_per_pixel
+ 0.5;
4180 height_mm
= rec
.height
* mm_height_per_pixel
+ 0.5;
4182 #if GTK_CHECK_VERSION (3, 4, 0)
4183 gdk_screen_get_monitor_workarea (gscreen
, i
, &work
);
4185 /* Emulate the behavior of GTK+ 3.4. */
4187 XRectangle workarea_r
;
4189 if (i
== primary_monitor
&& x_get_net_workarea (dpyinfo
, &workarea_r
))
4191 work
.x
= workarea_r
.x
;
4192 work
.y
= workarea_r
.y
;
4193 work
.width
= workarea_r
.width
;
4194 work
.height
= workarea_r
.height
;
4195 if (! gdk_rectangle_intersect (&rec
, &work
, &work
))
4206 mi
->geom
.width
= rec
.width
;
4207 mi
->geom
.height
= rec
.height
;
4208 mi
->work
.x
= work
.x
;
4209 mi
->work
.y
= work
.y
;
4210 mi
->work
.width
= work
.width
;
4211 mi
->work
.height
= work
.height
;
4212 mi
->mm_width
= width_mm
;
4213 mi
->mm_height
= height_mm
;
4215 #if GTK_CHECK_VERSION (2, 14, 0)
4216 mi
->name
= gdk_screen_get_monitor_plug_name (gscreen
, i
);
4220 attributes_list
= make_monitor_attribute_list (monitors
,
4226 #else /* not USE_GTK */
4229 attributes_list
= x_get_monitor_attributes (dpyinfo
);
4232 #endif /* not USE_GTK */
4234 return attributes_list
;
4237 DEFUN ("x-frame-geometry", Fx_frame_geometry
, Sx_frame_geometry
, 0, 1, 0,
4238 doc
: /* Return geometric attributes of frame FRAME.
4240 FRAME must be a live frame and defaults to the selected one.
4242 The return value is an association list containing the following
4243 elements (all size values are in pixels).
4245 - `frame-outer-size' is a cons of the outer width and height of FRAME.
4246 The outer size include the title bar and the external borders as well
4247 as any menu and/or tool bar of frame.
4249 - `border' is a cons of the horizontal and vertical width of FRAME's
4252 - `title-bar-height' is the height of the title bar of FRAME.
4254 - `menu-bar-external' if `t' means the menu bar is external (not
4255 included in the inner edges of FRAME).
4257 - `menu-bar-size' is a cons of the width and height of the menu bar of
4260 - `tool-bar-external' if `t' means the tool bar is external (not
4261 included in the inner edges of FRAME).
4263 - `tool-bar-side' tells tells on which side the tool bar on FRAME is and
4264 can be one of `left', `top', `right' or `bottom'.
4266 - `tool-bar-size' is a cons of the width and height of the tool bar of
4269 - `frame-inner-size' is a cons of the inner width and height of FRAME.
4270 This excludes FRAME's title bar and external border as well as any
4271 external menu and/or tool bar. */)
4274 struct frame
*f
= decode_live_frame (frame
);
4275 int inner_width
= FRAME_PIXEL_WIDTH (f
);
4276 int inner_height
= FRAME_PIXEL_HEIGHT (f
);
4277 int outer_width
, outer_height
, border
, title
;
4278 Lisp_Object fullscreen
= Fframe_parameter (frame
, Qfullscreen
);
4279 int menu_bar_height
, menu_bar_width
, tool_bar_height
, tool_bar_width
;
4281 border
= FRAME_OUTER_TO_INNER_DIFF_X (f
);
4282 title
= FRAME_X_OUTPUT (f
)->y_pixels_outer_diff
- border
;
4284 outer_width
= FRAME_PIXEL_WIDTH (f
) + 2 * border
;
4285 outer_height
= (FRAME_PIXEL_HEIGHT (f
)
4286 + FRAME_OUTER_TO_INNER_DIFF_Y (f
)
4287 + FRAME_OUTER_TO_INNER_DIFF_X (f
));
4289 #if defined (USE_GTK)
4291 bool tool_bar_left_right
= (EQ (FRAME_TOOL_BAR_POSITION (f
), Qleft
)
4292 || EQ (FRAME_TOOL_BAR_POSITION (f
), Qright
));
4294 tool_bar_width
= (tool_bar_left_right
4295 ? FRAME_TOOLBAR_WIDTH (f
)
4296 : FRAME_PIXEL_WIDTH (f
));
4297 tool_bar_height
= (tool_bar_left_right
4298 ? FRAME_PIXEL_HEIGHT (f
)
4299 : FRAME_TOOLBAR_HEIGHT (f
));
4300 if (tool_bar_left_right
)
4301 /* For some reason FRAME_OUTER_TO_INNER_DIFF_X does not count the
4302 width of a tool bar. */
4303 outer_width
+= FRAME_TOOLBAR_WIDTH (f
);
4306 tool_bar_height
= FRAME_TOOL_BAR_HEIGHT (f
);
4307 tool_bar_width
= ((tool_bar_height
> 0)
4308 ? outer_width
- 2 * FRAME_INTERNAL_BORDER_WIDTH (f
)
4312 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
4313 menu_bar_height
= FRAME_MENUBAR_HEIGHT (f
);
4315 menu_bar_height
= FRAME_MENU_BAR_HEIGHT (f
);
4318 menu_bar_width
= ((menu_bar_height
> 0)
4319 ? outer_width
- 2 * border
4322 if (!FRAME_EXTERNAL_MENU_BAR (f
))
4323 inner_height
-= menu_bar_height
;
4324 if (!FRAME_EXTERNAL_TOOL_BAR (f
))
4325 inner_height
-= tool_bar_height
;
4328 listn (CONSTYPE_PURE
, 10,
4329 Fcons (Qframe_position
,
4330 Fcons (make_number (f
->left_pos
), make_number (f
->top_pos
))),
4331 Fcons (Qframe_outer_size
,
4332 Fcons (make_number (outer_width
), make_number (outer_height
))),
4333 Fcons (Qexternal_border_size
,
4334 ((EQ (fullscreen
, Qfullboth
) || EQ (fullscreen
, Qfullscreen
))
4335 ? Fcons (make_number (0), make_number (0))
4336 : Fcons (make_number (border
), make_number (border
)))),
4337 Fcons (Qtitle_height
,
4338 ((EQ (fullscreen
, Qfullboth
) || EQ (fullscreen
, Qfullscreen
))
4340 : make_number (title
))),
4341 Fcons (Qmenu_bar_external
, FRAME_EXTERNAL_MENU_BAR (f
) ? Qt
: Qnil
),
4342 Fcons (Qmenu_bar_size
,
4343 Fcons (make_number (menu_bar_width
),
4344 make_number (menu_bar_height
))),
4345 Fcons (Qtool_bar_external
, FRAME_EXTERNAL_TOOL_BAR (f
) ? Qt
: Qnil
),
4346 Fcons (Qtool_bar_position
, FRAME_TOOL_BAR_POSITION (f
)),
4347 Fcons (Qtool_bar_size
,
4348 Fcons (make_number (tool_bar_width
),
4349 make_number (tool_bar_height
))),
4350 Fcons (Qframe_inner_size
,
4351 Fcons (make_number (inner_width
),
4352 make_number (inner_height
))));
4355 /************************************************************************
4357 ************************************************************************/
4360 /* Mapping visual names to visuals. */
4362 static struct visual_class
4369 {"StaticGray", StaticGray
},
4370 {"GrayScale", GrayScale
},
4371 {"StaticColor", StaticColor
},
4372 {"PseudoColor", PseudoColor
},
4373 {"TrueColor", TrueColor
},
4374 {"DirectColor", DirectColor
},
4379 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4381 /* Value is the screen number of screen SCR. This is a substitute for
4382 the X function with the same name when that doesn't exist. */
4385 XScreenNumberOfScreen (scr
)
4386 register Screen
*scr
;
4388 Display
*dpy
= scr
->display
;
4391 for (i
= 0; i
< dpy
->nscreens
; ++i
)
4392 if (scr
== dpy
->screens
+ i
)
4398 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4401 /* Select the visual that should be used on display DPYINFO. Set
4402 members of DPYINFO appropriately. Called from x_term_init. */
4405 select_visual (struct x_display_info
*dpyinfo
)
4407 Display
*dpy
= dpyinfo
->display
;
4408 Screen
*screen
= dpyinfo
->screen
;
4410 /* See if a visual is specified. */
4411 AUTO_STRING (visualClass
, "visualClass");
4412 AUTO_STRING (VisualClass
, "VisualClass");
4413 Lisp_Object value
= display_x_get_resource (dpyinfo
, visualClass
,
4414 VisualClass
, Qnil
, Qnil
);
4416 if (STRINGP (value
))
4418 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
4419 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
4420 depth, a decimal number. NAME is compared with case ignored. */
4421 char *s
= alloca (SBYTES (value
) + 1);
4426 lispstpcpy (s
, value
);
4427 dash
= strchr (s
, '-');
4430 dpyinfo
->n_planes
= atoi (dash
+ 1);
4434 /* We won't find a matching visual with depth 0, so that
4435 an error will be printed below. */
4436 dpyinfo
->n_planes
= 0;
4438 /* Determine the visual class. */
4439 for (i
= 0; visual_classes
[i
].name
; ++i
)
4440 if (xstrcasecmp (s
, visual_classes
[i
].name
) == 0)
4442 class = visual_classes
[i
].class;
4446 /* Look up a matching visual for the specified class. */
4448 || !XMatchVisualInfo (dpy
, XScreenNumberOfScreen (screen
),
4449 dpyinfo
->n_planes
, class, &vinfo
))
4450 fatal ("Invalid visual specification `%s'", SDATA (value
));
4452 dpyinfo
->visual
= vinfo
.visual
;
4457 XVisualInfo
*vinfo
, vinfo_template
;
4459 dpyinfo
->visual
= DefaultVisualOfScreen (screen
);
4461 vinfo_template
.visualid
= XVisualIDFromVisual (dpyinfo
->visual
);
4462 vinfo_template
.screen
= XScreenNumberOfScreen (screen
);
4463 vinfo
= XGetVisualInfo (dpy
, VisualIDMask
| VisualScreenMask
,
4464 &vinfo_template
, &n_visuals
);
4466 fatal ("Can't get proper X visual info");
4468 dpyinfo
->n_planes
= vinfo
->depth
;
4474 /* Return the X display structure for the display named NAME.
4475 Open a new connection if necessary. */
4477 static struct x_display_info
*
4478 x_display_info_for_name (Lisp_Object name
)
4480 struct x_display_info
*dpyinfo
;
4482 CHECK_STRING (name
);
4484 for (dpyinfo
= x_display_list
; dpyinfo
; dpyinfo
= dpyinfo
->next
)
4485 if (!NILP (Fstring_equal (XCAR (dpyinfo
->name_list_element
), name
)))
4488 /* Use this general default value to start with. */
4489 Vx_resource_name
= Vinvocation_name
;
4491 validate_x_resource_name ();
4493 dpyinfo
= x_term_init (name
, 0, SSDATA (Vx_resource_name
));
4496 error ("Cannot connect to X server %s", SDATA (name
));
4498 XSETFASTINT (Vwindow_system_version
, 11);
4504 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
4506 doc
: /* Open a connection to a display server.
4507 DISPLAY is the name of the display to connect to.
4508 Optional second arg XRM-STRING is a string of resources in xrdb format.
4509 If the optional third arg MUST-SUCCEED is non-nil,
4510 terminate Emacs if we can't open the connection.
4511 \(In the Nextstep version, the last two arguments are currently ignored.) */)
4512 (Lisp_Object display
, Lisp_Object xrm_string
, Lisp_Object must_succeed
)
4515 struct x_display_info
*dpyinfo
;
4517 CHECK_STRING (display
);
4518 if (! NILP (xrm_string
))
4519 CHECK_STRING (xrm_string
);
4521 xrm_option
= NILP (xrm_string
) ? 0 : SSDATA (xrm_string
);
4523 validate_x_resource_name ();
4525 /* This is what opens the connection and sets x_current_display.
4526 This also initializes many symbols, such as those used for input. */
4527 dpyinfo
= x_term_init (display
, xrm_option
,
4528 SSDATA (Vx_resource_name
));
4532 if (!NILP (must_succeed
))
4533 fatal ("Cannot connect to X server %s.\n\
4534 Check the DISPLAY environment variable or use `-d'.\n\
4535 Also use the `xauth' program to verify that you have the proper\n\
4536 authorization information needed to connect the X server.\n\
4537 An insecure way to solve the problem may be to use `xhost'.\n",
4540 error ("Cannot connect to X server %s", SDATA (display
));
4543 XSETFASTINT (Vwindow_system_version
, 11);
4547 DEFUN ("x-close-connection", Fx_close_connection
,
4548 Sx_close_connection
, 1, 1, 0,
4549 doc
: /* Close the connection to TERMINAL's X server.
4550 For TERMINAL, specify a terminal object, a frame or a display name (a
4551 string). If TERMINAL is nil, that stands for the selected frame's
4553 (Lisp_Object terminal
)
4555 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4557 if (dpyinfo
->reference_count
> 0)
4558 error ("Display still has frames on it");
4560 x_delete_terminal (dpyinfo
->terminal
);
4565 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
4566 doc
: /* Return the list of display names that Emacs has connections to. */)
4569 Lisp_Object result
= Qnil
;
4570 struct x_display_info
*xdi
;
4572 for (xdi
= x_display_list
; xdi
; xdi
= xdi
->next
)
4573 result
= Fcons (XCAR (xdi
->name_list_element
), result
);
4578 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
4579 doc
: /* If ON is non-nil, report X errors as soon as the erring request is made.
4580 This function only has an effect on X Windows. With MS Windows, it is
4581 defined but does nothing.
4583 If ON is nil, allow buffering of requests.
4584 Turning on synchronization prohibits the Xlib routines from buffering
4585 requests and seriously degrades performance, but makes debugging much
4587 The optional second argument TERMINAL specifies which display to act on.
4588 TERMINAL should be a terminal object, a frame or a display name (a string).
4589 If TERMINAL is omitted or nil, that stands for the selected frame's display. */)
4590 (Lisp_Object on
, Lisp_Object terminal
)
4592 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4594 XSynchronize (dpyinfo
->display
, !EQ (on
, Qnil
));
4599 /* Wait for responses to all X commands issued so far for frame F. */
4602 x_sync (struct frame
*f
)
4605 XSync (FRAME_X_DISPLAY (f
), False
);
4610 /***********************************************************************
4612 ***********************************************************************/
4614 DEFUN ("x-change-window-property", Fx_change_window_property
,
4615 Sx_change_window_property
, 2, 6, 0,
4616 doc
: /* Change window property PROP to VALUE on the X window of FRAME.
4617 PROP must be a string. VALUE may be a string or a list of conses,
4618 numbers and/or strings. If an element in the list is a string, it is
4619 converted to an atom and the value of the atom is used. If an element
4620 is a cons, it is converted to a 32 bit number where the car is the 16
4621 top bits and the cdr is the lower 16 bits.
4623 FRAME nil or omitted means use the selected frame.
4624 If TYPE is given and non-nil, it is the name of the type of VALUE.
4625 If TYPE is not given or nil, the type is STRING.
4626 FORMAT gives the size in bits of each element if VALUE is a list.
4627 It must be one of 8, 16 or 32.
4628 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
4629 If OUTER-P is non-nil, the property is changed for the outer X window of
4630 FRAME. Default is to change on the edit X window. */)
4631 (Lisp_Object prop
, Lisp_Object value
, Lisp_Object frame
,
4632 Lisp_Object type
, Lisp_Object format
, Lisp_Object outer_p
)
4634 struct frame
*f
= decode_window_system_frame (frame
);
4636 Atom target_type
= XA_STRING
;
4637 int element_format
= 8;
4638 unsigned char *data
;
4642 CHECK_STRING (prop
);
4644 if (! NILP (format
))
4646 CHECK_NUMBER (format
);
4648 if (XINT (format
) != 8 && XINT (format
) != 16
4649 && XINT (format
) != 32)
4650 error ("FORMAT must be one of 8, 16 or 32");
4651 element_format
= XINT (format
);
4658 nelements
= x_check_property_data (value
);
4659 if (nelements
== -1)
4660 error ("Bad data in VALUE, must be number, string or cons");
4662 /* The man page for XChangeProperty:
4663 "If the specified format is 32, the property data must be a
4665 This applies even if long is more than 32 bits. The X library
4666 converts to 32 bits before sending to the X server. */
4667 elsize
= element_format
== 32 ? sizeof (long) : element_format
>> 3;
4668 data
= xnmalloc (nelements
, elsize
);
4670 x_fill_property_data (FRAME_X_DISPLAY (f
), value
, data
, element_format
);
4674 CHECK_STRING (value
);
4675 data
= SDATA (value
);
4676 if (INT_MAX
< SBYTES (value
))
4677 error ("VALUE too long");
4678 nelements
= SBYTES (value
);
4682 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (prop
), False
);
4685 CHECK_STRING (type
);
4686 target_type
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (type
), False
);
4689 if (! NILP (outer_p
)) w
= FRAME_OUTER_WINDOW (f
);
4690 else w
= FRAME_X_WINDOW (f
);
4692 XChangeProperty (FRAME_X_DISPLAY (f
), w
,
4693 prop_atom
, target_type
, element_format
, PropModeReplace
,
4696 if (CONSP (value
)) xfree (data
);
4698 /* Make sure the property is set when we return. */
4699 XFlush (FRAME_X_DISPLAY (f
));
4706 DEFUN ("x-delete-window-property", Fx_delete_window_property
,
4707 Sx_delete_window_property
, 1, 2, 0,
4708 doc
: /* Remove window property PROP from X window of FRAME.
4709 FRAME nil or omitted means use the selected frame. Value is PROP. */)
4710 (Lisp_Object prop
, Lisp_Object frame
)
4712 struct frame
*f
= decode_window_system_frame (frame
);
4715 CHECK_STRING (prop
);
4717 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (prop
), False
);
4718 XDeleteProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), prop_atom
);
4720 /* Make sure the property is removed when we return. */
4721 XFlush (FRAME_X_DISPLAY (f
));
4729 x_window_property_intern (struct frame
*f
,
4730 Window target_window
,
4733 Lisp_Object delete_p
,
4734 Lisp_Object vector_ret_p
,
4737 unsigned char *tmp_data
= NULL
;
4738 Lisp_Object prop_value
= Qnil
;
4741 unsigned long actual_size
, bytes_remaining
;
4743 struct gcpro gcpro1
;
4745 GCPRO1 (prop_value
);
4747 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), target_window
,
4748 prop_atom
, 0, 0, False
, target_type
,
4749 &actual_type
, &actual_format
, &actual_size
,
4750 &bytes_remaining
, &tmp_data
);
4752 *found
= actual_format
!= 0;
4754 if (rc
== Success
&& *found
)
4759 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), target_window
,
4760 prop_atom
, 0, bytes_remaining
,
4761 ! NILP (delete_p
), target_type
,
4762 &actual_type
, &actual_format
,
4763 &actual_size
, &bytes_remaining
,
4765 if (rc
== Success
&& tmp_data
)
4767 /* The man page for XGetWindowProperty says:
4768 "If the returned format is 32, the returned data is represented
4769 as a long array and should be cast to that type to obtain the
4771 This applies even if long is more than 32 bits, the X library
4772 converts from 32 bit elements received from the X server to long
4773 and passes the long array to us. Thus, for that case memcpy can not
4774 be used. We convert to a 32 bit type here, because so much code
4777 The bytes and offsets passed to XGetWindowProperty refers to the
4778 property and those are indeed in 32 bit quantities if format is
4781 if (BITS_PER_LONG
> 32 && actual_format
== 32)
4784 int *idata
= (int *) tmp_data
;
4785 long *ldata
= (long *) tmp_data
;
4787 for (i
= 0; i
< actual_size
; ++i
)
4788 idata
[i
] = (int) ldata
[i
];
4791 if (NILP (vector_ret_p
))
4792 prop_value
= make_string ((char *) tmp_data
, actual_size
);
4794 prop_value
= x_property_data_to_lisp (f
,
4801 if (tmp_data
) XFree (tmp_data
);
4808 DEFUN ("x-window-property", Fx_window_property
, Sx_window_property
,
4810 doc
: /* Value is the value of window property PROP on FRAME.
4811 If FRAME is nil or omitted, use the selected frame.
4813 On X Windows, the following optional arguments are also accepted:
4814 If TYPE is nil or omitted, get the property as a string.
4815 Otherwise TYPE is the name of the atom that denotes the type expected.
4816 If SOURCE is non-nil, get the property on that window instead of from
4817 FRAME. The number 0 denotes the root window.
4818 If DELETE-P is non-nil, delete the property after retrieving it.
4819 If VECTOR-RET-P is non-nil, don't return a string but a vector of values.
4821 On MS Windows, this function accepts but ignores those optional arguments.
4823 Value is nil if FRAME hasn't a property with name PROP or if PROP has
4824 no value of TYPE (always string in the MS Windows case). */)
4825 (Lisp_Object prop
, Lisp_Object frame
, Lisp_Object type
,
4826 Lisp_Object source
, Lisp_Object delete_p
, Lisp_Object vector_ret_p
)
4828 struct frame
*f
= decode_window_system_frame (frame
);
4830 Lisp_Object prop_value
= Qnil
;
4831 Atom target_type
= XA_STRING
;
4832 Window target_window
= FRAME_X_WINDOW (f
);
4833 struct gcpro gcpro1
;
4836 GCPRO1 (prop_value
);
4837 CHECK_STRING (prop
);
4839 if (! NILP (source
))
4841 CONS_TO_INTEGER (source
, Window
, target_window
);
4842 if (! target_window
)
4843 target_window
= FRAME_DISPLAY_INFO (f
)->root_window
;
4849 if (strcmp ("AnyPropertyType", SSDATA (type
)) == 0)
4850 target_type
= AnyPropertyType
;
4852 target_type
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (type
), False
);
4855 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (prop
), False
);
4856 prop_value
= x_window_property_intern (f
,
4863 if (NILP (prop_value
)
4866 && target_window
!= FRAME_OUTER_WINDOW (f
))
4868 prop_value
= x_window_property_intern (f
,
4869 FRAME_OUTER_WINDOW (f
),
4883 /***********************************************************************
4885 ***********************************************************************/
4887 static Lisp_Object
x_create_tip_frame (struct x_display_info
*,
4888 Lisp_Object
, Lisp_Object
);
4889 static void compute_tip_xy (struct frame
*, Lisp_Object
, Lisp_Object
,
4890 Lisp_Object
, int, int, int *, int *);
4892 /* The frame of a currently visible tooltip. */
4894 Lisp_Object tip_frame
;
4896 /* If non-nil, a timer started that hides the last tooltip when it
4899 static Lisp_Object tip_timer
;
4902 /* If non-nil, a vector of 3 elements containing the last args
4903 with which x-show-tip was called. See there. */
4905 static Lisp_Object last_show_tip_args
;
4909 unwind_create_tip_frame (Lisp_Object frame
)
4911 Lisp_Object deleted
;
4913 deleted
= unwind_create_frame (frame
);
4914 if (EQ (deleted
, Qt
))
4922 /* Create a frame for a tooltip on the display described by DPYINFO.
4923 PARMS is a list of frame parameters. TEXT is the string to
4924 display in the tip frame. Value is the frame.
4926 Note that functions called here, esp. x_default_parameter can
4927 signal errors, for instance when a specified color name is
4928 undefined. We have to make sure that we're in a consistent state
4929 when this happens. */
4932 x_create_tip_frame (struct x_display_info
*dpyinfo
,
4940 ptrdiff_t count
= SPECPDL_INDEX ();
4941 struct gcpro gcpro1
, gcpro2
, gcpro3
;
4942 int face_change_count_before
= face_change_count
;
4944 struct buffer
*old_buffer
;
4946 if (!dpyinfo
->terminal
->name
)
4947 error ("Terminal is not live, can't create new frames on it");
4949 parms
= Fcopy_alist (parms
);
4951 /* Get the name of the frame to use for resource lookup. */
4952 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
4954 && !EQ (name
, Qunbound
)
4956 error ("Invalid frame name--not a string or nil");
4959 GCPRO3 (parms
, name
, frame
);
4961 XSETFRAME (frame
, f
);
4963 AUTO_STRING (tip
, " *tip*");
4964 buffer
= Fget_buffer_create (tip
);
4965 /* Use set_window_buffer instead of Fset_window_buffer (see
4966 discussion of bug#11984, bug#12025, bug#12026). */
4967 set_window_buffer (FRAME_ROOT_WINDOW (f
), buffer
, 0, 0);
4968 old_buffer
= current_buffer
;
4969 set_buffer_internal_1 (XBUFFER (buffer
));
4970 bset_truncate_lines (current_buffer
, Qnil
);
4971 specbind (Qinhibit_read_only
, Qt
);
4972 specbind (Qinhibit_modification_hooks
, Qt
);
4975 set_buffer_internal_1 (old_buffer
);
4977 record_unwind_protect (unwind_create_tip_frame
, frame
);
4979 f
->terminal
= dpyinfo
->terminal
;
4981 /* By setting the output method, we're essentially saying that
4982 the frame is live, as per FRAME_LIVE_P. If we get a signal
4983 from this point on, x_destroy_window might screw up reference
4985 f
->output_method
= output_x_window
;
4986 f
->output_data
.x
= xzalloc (sizeof *f
->output_data
.x
);
4987 f
->output_data
.x
->icon_bitmap
= -1;
4988 FRAME_FONTSET (f
) = -1;
4989 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
4990 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
4991 #if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
4992 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
4993 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
4994 #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
4995 f
->output_data
.x
->white_relief
.pixel
= -1;
4996 f
->output_data
.x
->black_relief
.pixel
= -1;
4998 fset_icon_name (f
, Qnil
);
4999 FRAME_DISPLAY_INFO (f
) = dpyinfo
;
5000 f
->output_data
.x
->parent_desc
= FRAME_DISPLAY_INFO (f
)->root_window
;
5001 f
->output_data
.x
->explicit_parent
= 0;
5003 /* These colors will be set anyway later, but it's important
5004 to get the color reference counts right, so initialize them! */
5007 struct gcpro gcpro1
;
5009 /* Function x_decode_color can signal an error. Make
5010 sure to initialize color slots so that we won't try
5011 to free colors we haven't allocated. */
5012 FRAME_FOREGROUND_PIXEL (f
) = -1;
5013 FRAME_BACKGROUND_PIXEL (f
) = -1;
5014 f
->output_data
.x
->cursor_pixel
= -1;
5015 f
->output_data
.x
->cursor_foreground_pixel
= -1;
5016 f
->output_data
.x
->border_pixel
= -1;
5017 f
->output_data
.x
->mouse_pixel
= -1;
5019 black
= build_string ("black");
5021 FRAME_FOREGROUND_PIXEL (f
)
5022 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
5023 FRAME_BACKGROUND_PIXEL (f
)
5024 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
5025 f
->output_data
.x
->cursor_pixel
5026 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
5027 f
->output_data
.x
->cursor_foreground_pixel
5028 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
5029 f
->output_data
.x
->border_pixel
5030 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
5031 f
->output_data
.x
->mouse_pixel
5032 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
5036 /* Set the name; the functions to which we pass f expect the name to
5038 if (EQ (name
, Qunbound
) || NILP (name
))
5040 fset_name (f
, build_string (dpyinfo
->x_id_name
));
5041 f
->explicit_name
= 0;
5045 fset_name (f
, name
);
5046 f
->explicit_name
= 1;
5047 /* use the frame's title when getting resources for this frame. */
5048 specbind (Qx_resource_name
, name
);
5051 register_font_driver (&xfont_driver
, f
);
5052 #ifdef HAVE_FREETYPE
5054 register_font_driver (&xftfont_driver
, f
);
5055 #else /* not HAVE_XFT */
5056 register_font_driver (&ftxfont_driver
, f
);
5057 #endif /* not HAVE_XFT */
5058 #endif /* HAVE_FREETYPE */
5060 x_default_parameter (f
, parms
, Qfont_backend
, Qnil
,
5061 "fontBackend", "FontBackend", RES_TYPE_STRING
);
5063 /* Extract the window parameters from the supplied values that are
5064 needed to determine window geometry. */
5065 x_default_font_parameter (f
, parms
);
5067 x_default_parameter (f
, parms
, Qborder_width
, make_number (0),
5068 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
5070 /* This defaults to 2 in order to match xterm. We recognize either
5071 internalBorderWidth or internalBorder (which is what xterm calls
5073 if (NILP (Fassq (Qinternal_border_width
, parms
)))
5077 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
5078 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
5079 if (! EQ (value
, Qunbound
))
5080 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
5084 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
5085 "internalBorderWidth", "internalBorderWidth",
5087 x_default_parameter (f
, parms
, Qright_divider_width
, make_number (0),
5088 NULL
, NULL
, RES_TYPE_NUMBER
);
5089 x_default_parameter (f
, parms
, Qbottom_divider_width
, make_number (0),
5090 NULL
, NULL
, RES_TYPE_NUMBER
);
5092 /* Also do the stuff which must be set before the window exists. */
5093 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
5094 "foreground", "Foreground", RES_TYPE_STRING
);
5095 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
5096 "background", "Background", RES_TYPE_STRING
);
5097 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
5098 "pointerColor", "Foreground", RES_TYPE_STRING
);
5099 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
5100 "cursorColor", "Foreground", RES_TYPE_STRING
);
5101 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
5102 "borderColor", "BorderColor", RES_TYPE_STRING
);
5105 image_cache_refcount
=
5106 FRAME_IMAGE_CACHE (f
) ? FRAME_IMAGE_CACHE (f
)->refcount
: 0;
5107 dpyinfo_refcount
= dpyinfo
->reference_count
;
5108 #endif /* GLYPH_DEBUG */
5110 /* Init faces before x_default_parameter is called for the
5111 scroll-bar-width parameter because otherwise we end up in
5112 init_iterator with a null face cache, which should not happen. */
5113 init_frame_faces (f
);
5115 f
->output_data
.x
->parent_desc
= FRAME_DISPLAY_INFO (f
)->root_window
;
5117 x_figure_window_size (f
, parms
, 0);
5120 XSetWindowAttributes attrs
;
5122 Atom type
= FRAME_DISPLAY_INFO (f
)->Xatom_net_window_type_tooltip
;
5125 mask
= CWBackPixel
| CWOverrideRedirect
| CWEventMask
;
5126 if (DoesSaveUnders (dpyinfo
->screen
))
5127 mask
|= CWSaveUnder
;
5129 /* Window managers look at the override-redirect flag to determine
5130 whether or net to give windows a decoration (Xlib spec, chapter
5132 attrs
.override_redirect
= True
;
5133 attrs
.save_under
= True
;
5134 attrs
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
5135 /* Arrange for getting MapNotify and UnmapNotify events. */
5136 attrs
.event_mask
= StructureNotifyMask
;
5138 = FRAME_X_WINDOW (f
)
5139 = XCreateWindow (FRAME_X_DISPLAY (f
),
5140 FRAME_DISPLAY_INFO (f
)->root_window
,
5141 /* x, y, width, height */
5145 CopyFromParent
, InputOutput
, CopyFromParent
,
5147 XChangeProperty (FRAME_X_DISPLAY (f
), tip_window
,
5148 FRAME_DISPLAY_INFO (f
)->Xatom_net_window_type
,
5149 XA_ATOM
, 32, PropModeReplace
,
5150 (unsigned char *)&type
, 1);
5156 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
5157 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
5158 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
5159 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
5160 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
5161 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
5163 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
5164 Change will not be effected unless different from the current
5166 width
= FRAME_COLS (f
);
5167 height
= FRAME_LINES (f
);
5168 SET_FRAME_COLS (f
, 0);
5169 SET_FRAME_LINES (f
, 0);
5170 change_frame_size (f
, width
, height
, 1, 0, 0, 0);
5172 /* Add `tooltip' frame parameter's default value. */
5173 if (NILP (Fframe_parameter (frame
, Qtooltip
)))
5175 AUTO_FRAME_ARG (arg
, Qtooltip
, Qt
);
5176 Fmodify_frame_parameters (frame
, arg
);
5179 /* FIXME - can this be done in a similar way to normal frames?
5180 http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
5182 /* Set the `display-type' frame parameter before setting up faces. */
5184 Lisp_Object disptype
;
5186 if (FRAME_DISPLAY_INFO (f
)->n_planes
== 1)
5187 disptype
= intern ("mono");
5188 else if (FRAME_DISPLAY_INFO (f
)->visual
->class == GrayScale
5189 || FRAME_DISPLAY_INFO (f
)->visual
->class == StaticGray
)
5190 disptype
= intern ("grayscale");
5192 disptype
= intern ("color");
5194 if (NILP (Fframe_parameter (frame
, Qdisplay_type
)))
5196 AUTO_FRAME_ARG (arg
, Qdisplay_type
, disptype
);
5197 Fmodify_frame_parameters (frame
, arg
);
5201 /* Set up faces after all frame parameters are known. This call
5202 also merges in face attributes specified for new frames.
5204 Frame parameters may be changed if .Xdefaults contains
5205 specifications for the default font. For example, if there is an
5206 `Emacs.default.attributeBackground: pink', the `background-color'
5207 attribute of the frame get's set, which let's the internal border
5208 of the tooltip frame appear in pink. Prevent this. */
5210 Lisp_Object bg
= Fframe_parameter (frame
, Qbackground_color
);
5212 /* Set tip_frame here, so that */
5214 call2 (Qface_set_after_frame_default
, frame
, Qnil
);
5216 if (!EQ (bg
, Fframe_parameter (frame
, Qbackground_color
)))
5218 AUTO_FRAME_ARG (arg
, Qbackground_color
, bg
);
5219 Fmodify_frame_parameters (frame
, arg
);
5227 /* Now that the frame will be official, it counts as a reference to
5228 its display and terminal. */
5229 FRAME_DISPLAY_INFO (f
)->reference_count
++;
5230 f
->terminal
->reference_count
++;
5232 /* It is now ok to make the frame official even if we get an error
5233 below. And the frame needs to be on Vframe_list or making it
5234 visible won't work. */
5235 Vframe_list
= Fcons (frame
, Vframe_list
);
5236 f
->can_x_set_window_size
= true;
5238 /* Setting attributes of faces of the tooltip frame from resources
5239 and similar will increment face_change_count, which leads to the
5240 clearing of all current matrices. Since this isn't necessary
5241 here, avoid it by resetting face_change_count to the value it
5242 had before we created the tip frame. */
5243 face_change_count
= face_change_count_before
;
5245 /* Discard the unwind_protect. */
5246 return unbind_to (count
, frame
);
5250 /* Compute where to display tip frame F. PARMS is the list of frame
5251 parameters for F. DX and DY are specified offsets from the current
5252 location of the mouse. WIDTH and HEIGHT are the width and height
5253 of the tooltip. Return coordinates relative to the root window of
5254 the display in *ROOT_X, and *ROOT_Y. */
5257 compute_tip_xy (struct frame
*f
, Lisp_Object parms
, Lisp_Object dx
, Lisp_Object dy
, int width
, int height
, int *root_x
, int *root_y
)
5259 Lisp_Object left
, top
;
5264 /* User-specified position? */
5265 left
= Fcdr (Fassq (Qleft
, parms
));
5266 top
= Fcdr (Fassq (Qtop
, parms
));
5268 /* Move the tooltip window where the mouse pointer is. Resize and
5270 if (!INTEGERP (left
) || !INTEGERP (top
))
5273 XQueryPointer (FRAME_X_DISPLAY (f
), FRAME_DISPLAY_INFO (f
)->root_window
,
5274 &root
, &child
, root_x
, root_y
, &win_x
, &win_y
, &pmask
);
5279 *root_y
= XINT (top
);
5280 else if (*root_y
+ XINT (dy
) <= 0)
5281 *root_y
= 0; /* Can happen for negative dy */
5282 else if (*root_y
+ XINT (dy
) + height
5283 <= x_display_pixel_height (FRAME_DISPLAY_INFO (f
)))
5284 /* It fits below the pointer */
5285 *root_y
+= XINT (dy
);
5286 else if (height
+ XINT (dy
) <= *root_y
)
5287 /* It fits above the pointer. */
5288 *root_y
-= height
+ XINT (dy
);
5290 /* Put it on the top. */
5293 if (INTEGERP (left
))
5294 *root_x
= XINT (left
);
5295 else if (*root_x
+ XINT (dx
) <= 0)
5296 *root_x
= 0; /* Can happen for negative dx */
5297 else if (*root_x
+ XINT (dx
) + width
5298 <= x_display_pixel_width (FRAME_DISPLAY_INFO (f
)))
5299 /* It fits to the right of the pointer. */
5300 *root_x
+= XINT (dx
);
5301 else if (width
+ XINT (dx
) <= *root_x
)
5302 /* It fits to the left of the pointer. */
5303 *root_x
-= width
+ XINT (dx
);
5305 /* Put it left-justified on the screen--it ought to fit that way. */
5310 DEFUN ("x-show-tip", Fx_show_tip
, Sx_show_tip
, 1, 6, 0,
5311 doc
: /* Show STRING in a "tooltip" window on frame FRAME.
5312 A tooltip window is a small X window displaying a string.
5314 This is an internal function; Lisp code should call `tooltip-show'.
5316 FRAME nil or omitted means use the selected frame.
5318 PARMS is an optional list of frame parameters which can be used to
5319 change the tooltip's appearance.
5321 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
5322 means use the default timeout of 5 seconds.
5324 If the list of frame parameters PARMS contains a `left' parameters,
5325 the tooltip is displayed at that x-position. Otherwise it is
5326 displayed at the mouse position, with offset DX added (default is 5 if
5327 DX isn't specified). Likewise for the y-position; if a `top' frame
5328 parameter is specified, it determines the y-position of the tooltip
5329 window, otherwise it is displayed at the mouse position, with offset
5330 DY added (default is -10).
5332 A tooltip's maximum size is specified by `x-max-tooltip-size'.
5333 Text larger than the specified size is clipped. */)
5334 (Lisp_Object string
, Lisp_Object frame
, Lisp_Object parms
, Lisp_Object timeout
, Lisp_Object dx
, Lisp_Object dy
)
5339 struct buffer
*old_buffer
;
5340 struct text_pos pos
;
5341 int i
, width
, height
, seen_reversed_p
;
5342 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
5343 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
5344 ptrdiff_t count
= SPECPDL_INDEX ();
5346 specbind (Qinhibit_redisplay
, Qt
);
5348 GCPRO4 (string
, parms
, frame
, timeout
);
5350 CHECK_STRING (string
);
5351 if (SCHARS (string
) == 0)
5352 string
= make_unibyte_string (" ", 1);
5354 f
= decode_window_system_frame (frame
);
5356 timeout
= make_number (5);
5358 CHECK_NATNUM (timeout
);
5361 dx
= make_number (5);
5366 dy
= make_number (-10);
5371 if (x_gtk_use_system_tooltips
)
5375 /* Hide a previous tip, if any. */
5379 ok
= xg_prepare_tooltip (f
, string
, &width
, &height
);
5382 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, &root_x
, &root_y
);
5383 xg_show_tooltip (f
, root_x
, root_y
);
5384 /* This is used in Fx_hide_tip. */
5385 XSETFRAME (tip_frame
, f
);
5388 if (ok
) goto start_timer
;
5390 #endif /* USE_GTK */
5392 if (NILP (last_show_tip_args
))
5393 last_show_tip_args
= Fmake_vector (make_number (3), Qnil
);
5395 if (!NILP (tip_frame
))
5397 Lisp_Object last_string
= AREF (last_show_tip_args
, 0);
5398 Lisp_Object last_frame
= AREF (last_show_tip_args
, 1);
5399 Lisp_Object last_parms
= AREF (last_show_tip_args
, 2);
5401 if (EQ (frame
, last_frame
)
5402 && !NILP (Fequal (last_string
, string
))
5403 && !NILP (Fequal (last_parms
, parms
)))
5405 struct frame
*tip_f
= XFRAME (tip_frame
);
5407 /* Only DX and DY have changed. */
5408 if (!NILP (tip_timer
))
5410 Lisp_Object timer
= tip_timer
;
5412 call1 (Qcancel_timer
, timer
);
5416 compute_tip_xy (tip_f
, parms
, dx
, dy
, FRAME_PIXEL_WIDTH (tip_f
),
5417 FRAME_PIXEL_HEIGHT (tip_f
), &root_x
, &root_y
);
5418 XMoveWindow (FRAME_X_DISPLAY (tip_f
), FRAME_X_WINDOW (tip_f
),
5425 /* Hide a previous tip, if any. */
5428 ASET (last_show_tip_args
, 0, string
);
5429 ASET (last_show_tip_args
, 1, frame
);
5430 ASET (last_show_tip_args
, 2, parms
);
5432 /* Add default values to frame parameters. */
5433 if (NILP (Fassq (Qname
, parms
)))
5434 parms
= Fcons (Fcons (Qname
, build_string ("tooltip")), parms
);
5435 if (NILP (Fassq (Qinternal_border_width
, parms
)))
5436 parms
= Fcons (Fcons (Qinternal_border_width
, make_number (3)), parms
);
5437 if (NILP (Fassq (Qborder_width
, parms
)))
5438 parms
= Fcons (Fcons (Qborder_width
, make_number (1)), parms
);
5439 if (NILP (Fassq (Qbottom_divider_width
, parms
)))
5440 parms
= Fcons (Fcons (Qbottom_divider_width
, make_number (0)), parms
);
5441 if (NILP (Fassq (Qright_divider_width
, parms
)))
5442 parms
= Fcons (Fcons (Qright_divider_width
, make_number (0)), parms
);
5443 if (NILP (Fassq (Qborder_color
, parms
)))
5444 parms
= Fcons (Fcons (Qborder_color
, build_string ("lightyellow")), parms
);
5445 if (NILP (Fassq (Qbackground_color
, parms
)))
5446 parms
= Fcons (Fcons (Qbackground_color
, build_string ("lightyellow")),
5449 /* Create a frame for the tooltip, and record it in the global
5450 variable tip_frame. */
5451 frame
= x_create_tip_frame (FRAME_DISPLAY_INFO (f
), parms
, string
);
5454 /* Set up the frame's root window. */
5455 w
= XWINDOW (FRAME_ROOT_WINDOW (f
));
5461 if (CONSP (Vx_max_tooltip_size
)
5462 && RANGED_INTEGERP (1, XCAR (Vx_max_tooltip_size
), INT_MAX
)
5463 && RANGED_INTEGERP (1, XCDR (Vx_max_tooltip_size
), INT_MAX
))
5465 w
->total_cols
= XFASTINT (XCAR (Vx_max_tooltip_size
));
5466 w
->total_lines
= XFASTINT (XCDR (Vx_max_tooltip_size
));
5471 w
->total_lines
= 40;
5474 w
->pixel_width
= w
->total_cols
* FRAME_COLUMN_WIDTH (f
);
5475 w
->pixel_height
= w
->total_lines
* FRAME_LINE_HEIGHT (f
);
5477 FRAME_TOTAL_COLS (f
) = w
->total_cols
;
5478 adjust_frame_glyphs (f
);
5479 w
->pseudo_window_p
= 1;
5481 /* Display the tooltip text in a temporary buffer. */
5482 old_buffer
= current_buffer
;
5483 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f
))->contents
));
5484 bset_truncate_lines (current_buffer
, Qnil
);
5485 clear_glyph_matrix (w
->desired_matrix
);
5486 clear_glyph_matrix (w
->current_matrix
);
5487 SET_TEXT_POS (pos
, BEGV
, BEGV_BYTE
);
5488 try_window (FRAME_ROOT_WINDOW (f
), pos
, TRY_WINDOW_IGNORE_FONTS_CHANGE
);
5490 /* Compute width and height of the tooltip. */
5491 width
= height
= seen_reversed_p
= 0;
5492 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
5494 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
5498 /* Stop at the first empty row at the end. */
5499 if (!row
->enabled_p
|| !MATRIX_ROW_DISPLAYS_TEXT_P (row
))
5502 /* Let the row go over the full width of the frame. */
5503 row
->full_width_p
= 1;
5505 row_width
= row
->pixel_width
;
5506 if (row
->used
[TEXT_AREA
])
5508 /* There's a glyph at the end of rows that is used to place
5509 the cursor there. Don't include the width of this glyph. */
5510 if (!row
->reversed_p
)
5512 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
5513 if (INTEGERP (last
->object
))
5514 row_width
-= last
->pixel_width
;
5518 /* There could be a stretch glyph at the beginning of R2L
5519 rows that is produced by extend_face_to_end_of_line.
5520 Don't count that glyph. */
5521 struct glyph
*g
= row
->glyphs
[TEXT_AREA
];
5523 if (g
->type
== STRETCH_GLYPH
&& INTEGERP (g
->object
))
5525 row_width
-= g
->pixel_width
;
5526 seen_reversed_p
= 1;
5531 height
+= row
->height
;
5532 width
= max (width
, row_width
);
5535 /* If we've seen partial-length R2L rows, we need to re-adjust the
5536 tool-tip frame width and redisplay it again, to avoid over-wide
5537 tips due to the stretch glyph that extends R2L lines to full
5538 width of the frame. */
5539 if (seen_reversed_p
)
5541 /* w->total_cols and FRAME_TOTAL_COLS want the width in columns,
5543 w
->pixel_width
= width
;
5544 width
/= WINDOW_FRAME_COLUMN_WIDTH (w
);
5545 w
->total_cols
= width
;
5546 FRAME_TOTAL_COLS (f
) = width
;
5547 SET_FRAME_WIDTH (f
, width
);
5548 adjust_frame_glyphs (f
);
5549 clear_glyph_matrix (w
->desired_matrix
);
5550 clear_glyph_matrix (w
->current_matrix
);
5551 try_window (FRAME_ROOT_WINDOW (f
), pos
, 0);
5553 /* Recompute width and height of the tooltip. */
5554 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
5556 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
5560 if (!row
->enabled_p
|| !MATRIX_ROW_DISPLAYS_TEXT_P (row
))
5562 row
->full_width_p
= 1;
5563 row_width
= row
->pixel_width
;
5564 if (row
->used
[TEXT_AREA
] && !row
->reversed_p
)
5566 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
5567 if (INTEGERP (last
->object
))
5568 row_width
-= last
->pixel_width
;
5571 height
+= row
->height
;
5572 width
= max (width
, row_width
);
5576 /* Add the frame's internal border to the width and height the X
5577 window should have. */
5578 height
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
5579 width
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
5581 /* Move the tooltip window where the mouse pointer is. Resize and
5583 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, &root_x
, &root_y
);
5586 XMoveResizeWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5587 root_x
, root_y
, width
, height
);
5588 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
5591 /* Draw into the window. */
5592 w
->must_be_updated_p
= 1;
5593 update_single_window (w
, 1);
5595 /* Restore original current buffer. */
5596 set_buffer_internal_1 (old_buffer
);
5597 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
5600 /* Let the tip disappear after timeout seconds. */
5601 tip_timer
= call3 (intern ("run-at-time"), timeout
, Qnil
,
5602 intern ("x-hide-tip"));
5605 return unbind_to (count
, Qnil
);
5609 DEFUN ("x-hide-tip", Fx_hide_tip
, Sx_hide_tip
, 0, 0, 0,
5610 doc
: /* Hide the current tooltip window, if there is any.
5611 Value is t if tooltip was open, nil otherwise. */)
5615 Lisp_Object deleted
, frame
, timer
;
5616 struct gcpro gcpro1
, gcpro2
;
5618 /* Return quickly if nothing to do. */
5619 if (NILP (tip_timer
) && NILP (tip_frame
))
5624 GCPRO2 (frame
, timer
);
5625 tip_frame
= tip_timer
= deleted
= Qnil
;
5627 count
= SPECPDL_INDEX ();
5628 specbind (Qinhibit_redisplay
, Qt
);
5629 specbind (Qinhibit_quit
, Qt
);
5632 call1 (Qcancel_timer
, timer
);
5636 /* When using system tooltip, tip_frame is the Emacs frame on which
5637 the tip is shown. */
5638 struct frame
*f
= XFRAME (frame
);
5639 if (FRAME_LIVE_P (f
) && xg_hide_tooltip (f
))
5646 delete_frame (frame
, Qnil
);
5650 /* Bloodcurdling hack alert: The Lucid menu bar widget's
5651 redisplay procedure is not called when a tip frame over menu
5652 items is unmapped. Redisplay the menu manually... */
5655 struct frame
*f
= SELECTED_FRAME ();
5656 w
= f
->output_data
.x
->menubar_widget
;
5658 if (!DoesSaveUnders (FRAME_DISPLAY_INFO (f
)->screen
)
5662 xlwmenu_redisplay (w
);
5666 #endif /* USE_LUCID */
5670 return unbind_to (count
, deleted
);
5675 /***********************************************************************
5676 File selection dialog
5677 ***********************************************************************/
5679 DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog
,
5680 Sx_uses_old_gtk_dialog
,
5682 doc
: /* Return t if the old Gtk+ file selection dialog is used. */)
5688 && window_system_available (SELECTED_FRAME ())
5689 && xg_uses_old_file_dialog ())
5697 /* Callback for "OK" and "Cancel" on file selection dialog. */
5700 file_dialog_cb (Widget widget
, XtPointer client_data
, XtPointer call_data
)
5702 int *result
= client_data
;
5703 XmAnyCallbackStruct
*cb
= call_data
;
5704 *result
= cb
->reason
;
5708 /* Callback for unmapping a file selection dialog. This is used to
5709 capture the case where a dialog is closed via a window manager's
5710 closer button, for example. Using a XmNdestroyCallback didn't work
5714 file_dialog_unmap_cb (Widget widget
, XtPointer client_data
, XtPointer call_data
)
5716 int *result
= client_data
;
5717 *result
= XmCR_CANCEL
;
5721 clean_up_file_dialog (void *arg
)
5723 Widget dialog
= arg
;
5727 XtUnmanageChild (dialog
);
5728 XtDestroyWidget (dialog
);
5729 x_menu_set_in_use (0);
5734 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 5, 0,
5735 doc
: /* Read file name, prompting with PROMPT in directory DIR.
5736 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5737 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5738 or directory must exist.
5740 This function is only defined on NS, MS Windows, and X Windows with the
5741 Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
5742 Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.
5743 On Windows 7 and later, the file selection dialog "remembers" the last
5744 directory where the user selected a file, and will open that directory
5745 instead of DIR on subsequent invocations of this function with the same
5746 value of DIR as in previous invocations; this is standard Windows behavior. */)
5747 (Lisp_Object prompt
, Lisp_Object dir
, Lisp_Object default_filename
,
5748 Lisp_Object mustmatch
, Lisp_Object only_dir_p
)
5751 struct frame
*f
= SELECTED_FRAME ();
5752 Lisp_Object file
= Qnil
;
5753 Lisp_Object decoded_file
;
5754 Widget dialog
, text
, help
;
5757 XmString dir_xmstring
, pattern_xmstring
;
5758 ptrdiff_t count
= SPECPDL_INDEX ();
5759 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
, gcpro6
;
5761 check_window_system (f
);
5763 GCPRO6 (prompt
, dir
, default_filename
, mustmatch
, only_dir_p
, file
);
5765 if (popup_activated ())
5766 error ("Trying to use a menu from within a menu-entry");
5768 CHECK_STRING (prompt
);
5771 /* Prevent redisplay. */
5772 specbind (Qinhibit_redisplay
, Qt
);
5776 /* Create the dialog with PROMPT as title, using DIR as initial
5777 directory and using "*" as pattern. */
5778 dir
= Fexpand_file_name (dir
, Qnil
);
5779 dir_xmstring
= XmStringCreateLocalized (SSDATA (dir
));
5780 pattern_xmstring
= XmStringCreateLocalized ("*");
5782 XtSetArg (al
[ac
], XmNtitle
, SDATA (prompt
)); ++ac
;
5783 XtSetArg (al
[ac
], XmNdirectory
, dir_xmstring
); ++ac
;
5784 XtSetArg (al
[ac
], XmNpattern
, pattern_xmstring
); ++ac
;
5785 XtSetArg (al
[ac
], XmNresizePolicy
, XmRESIZE_GROW
); ++ac
;
5786 XtSetArg (al
[ac
], XmNdialogStyle
, XmDIALOG_APPLICATION_MODAL
); ++ac
;
5787 dialog
= XmCreateFileSelectionDialog (f
->output_data
.x
->widget
,
5789 XmStringFree (dir_xmstring
);
5790 XmStringFree (pattern_xmstring
);
5792 /* Add callbacks for OK and Cancel. */
5793 XtAddCallback (dialog
, XmNokCallback
, file_dialog_cb
,
5794 (XtPointer
) &result
);
5795 XtAddCallback (dialog
, XmNcancelCallback
, file_dialog_cb
,
5796 (XtPointer
) &result
);
5797 XtAddCallback (dialog
, XmNunmapCallback
, file_dialog_unmap_cb
,
5798 (XtPointer
) &result
);
5800 /* Remove the help button since we can't display help. */
5801 help
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_HELP_BUTTON
);
5802 XtUnmanageChild (help
);
5804 /* Mark OK button as default. */
5805 XtVaSetValues (XmFileSelectionBoxGetChild (dialog
, XmDIALOG_OK_BUTTON
),
5806 XmNshowAsDefault
, True
, NULL
);
5808 /* If MUSTMATCH is non-nil, disable the file entry field of the
5809 dialog, so that the user must select a file from the files list
5810 box. We can't remove it because we wouldn't have a way to get at
5811 the result file name, then. */
5812 text
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
5813 if (!NILP (mustmatch
))
5816 label
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_SELECTION_LABEL
);
5817 XtSetSensitive (text
, False
);
5818 XtSetSensitive (label
, False
);
5821 /* Manage the dialog, so that list boxes get filled. */
5822 XtManageChild (dialog
);
5824 if (STRINGP (default_filename
))
5826 XmString default_xmstring
;
5827 Widget wtext
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
5828 Widget list
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_LIST
);
5830 XmTextPosition last_pos
= XmTextFieldGetLastPosition (wtext
);
5831 XmTextFieldReplace (wtext
, 0, last_pos
,
5832 (SSDATA (Ffile_name_nondirectory (default_filename
))));
5834 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
5835 must include the path for this to work. */
5837 default_xmstring
= XmStringCreateLocalized (SSDATA (default_filename
));
5839 if (XmListItemExists (list
, default_xmstring
))
5841 int item_pos
= XmListItemPos (list
, default_xmstring
);
5842 /* Select the item and scroll it into view. */
5843 XmListSelectPos (list
, item_pos
, True
);
5844 XmListSetPos (list
, item_pos
);
5847 XmStringFree (default_xmstring
);
5850 record_unwind_protect_ptr (clean_up_file_dialog
, dialog
);
5852 /* Process events until the user presses Cancel or OK. */
5853 x_menu_set_in_use (1);
5858 x_menu_wait_for_event (0);
5859 XtAppNextEvent (Xt_app_con
, &event
);
5860 if (event
.type
== KeyPress
5861 && FRAME_X_DISPLAY (f
) == event
.xkey
.display
)
5863 KeySym keysym
= XLookupKeysym (&event
.xkey
, 0);
5865 /* Pop down on C-g. */
5866 if (keysym
== XK_g
&& (event
.xkey
.state
& ControlMask
) != 0)
5867 XtUnmanageChild (dialog
);
5870 (void) x_dispatch_event (&event
, FRAME_X_DISPLAY (f
));
5873 /* Get the result. */
5874 if (result
== XmCR_OK
)
5876 XmString text_string
;
5879 XtVaGetValues (dialog
, XmNtextString
, &text_string
, NULL
);
5880 XmStringGetLtoR (text_string
, XmFONTLIST_DEFAULT_TAG
, &data
);
5881 XmStringFree (text_string
);
5882 file
= build_string (data
);
5891 /* Make "Cancel" equivalent to C-g. */
5893 Fsignal (Qquit
, Qnil
);
5895 decoded_file
= DECODE_FILE (file
);
5897 return unbind_to (count
, decoded_file
);
5900 #endif /* USE_MOTIF */
5905 clean_up_dialog (void)
5907 x_menu_set_in_use (0);
5910 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 5, 0,
5911 doc
: /* Read file name, prompting with PROMPT in directory DIR.
5912 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5913 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5914 or directory must exist.
5916 This function is only defined on NS, MS Windows, and X Windows with the
5917 Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
5918 Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.
5919 On Windows 7 and later, the file selection dialog "remembers" the last
5920 directory where the user selected a file, and will open that directory
5921 instead of DIR on subsequent invocations of this function with the same
5922 value of DIR as in previous invocations; this is standard Windows behavior. */)
5923 (Lisp_Object prompt
, Lisp_Object dir
, Lisp_Object default_filename
, Lisp_Object mustmatch
, Lisp_Object only_dir_p
)
5925 struct frame
*f
= SELECTED_FRAME ();
5927 Lisp_Object file
= Qnil
;
5928 Lisp_Object decoded_file
;
5929 ptrdiff_t count
= SPECPDL_INDEX ();
5930 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
, gcpro6
;
5933 check_window_system (f
);
5935 GCPRO6 (prompt
, dir
, default_filename
, mustmatch
, only_dir_p
, file
);
5937 if (popup_activated ())
5938 error ("Trying to use a menu from within a menu-entry");
5940 CHECK_STRING (prompt
);
5943 /* Prevent redisplay. */
5944 specbind (Qinhibit_redisplay
, Qt
);
5945 record_unwind_protect_void (clean_up_dialog
);
5949 if (STRINGP (default_filename
))
5950 cdef_file
= SSDATA (default_filename
);
5952 cdef_file
= SSDATA (dir
);
5954 fn
= xg_get_file_name (f
, SSDATA (prompt
), cdef_file
,
5956 ! NILP (only_dir_p
));
5960 file
= build_string (fn
);
5967 /* Make "Cancel" equivalent to C-g. */
5969 Fsignal (Qquit
, Qnil
);
5971 decoded_file
= DECODE_FILE (file
);
5973 return unbind_to (count
, decoded_file
);
5977 #ifdef HAVE_FREETYPE
5979 DEFUN ("x-select-font", Fx_select_font
, Sx_select_font
, 0, 2, 0,
5980 doc
: /* Read a font using a GTK dialog.
5981 Return either a font spec (for GTK versions >= 3.2) or a string
5982 containing a GTK-style font name.
5984 FRAME is the frame on which to pop up the font chooser. If omitted or
5985 nil, it defaults to the selected frame. */)
5986 (Lisp_Object frame
, Lisp_Object ignored
)
5988 struct frame
*f
= decode_window_system_frame (frame
);
5990 Lisp_Object font_param
;
5991 char *default_name
= NULL
;
5992 struct gcpro gcpro1
, gcpro2
;
5993 ptrdiff_t count
= SPECPDL_INDEX ();
5995 if (popup_activated ())
5996 error ("Trying to use a menu from within a menu-entry");
5998 /* Prevent redisplay. */
5999 specbind (Qinhibit_redisplay
, Qt
);
6000 record_unwind_protect_void (clean_up_dialog
);
6004 GCPRO2 (font_param
, font
);
6006 XSETFONT (font
, FRAME_FONT (f
));
6007 font_param
= Ffont_get (font
, intern (":name"));
6008 if (STRINGP (font_param
))
6009 default_name
= xstrdup (SSDATA (font_param
));
6012 font_param
= Fframe_parameter (frame
, Qfont_param
);
6013 if (STRINGP (font_param
))
6014 default_name
= xstrdup (SSDATA (font_param
));
6017 font
= xg_get_font (f
, default_name
);
6018 xfree (default_name
);
6023 Fsignal (Qquit
, Qnil
);
6025 return unbind_to (count
, font
);
6027 #endif /* HAVE_FREETYPE */
6029 #endif /* USE_GTK */
6032 /***********************************************************************
6034 ***********************************************************************/
6037 #include <X11/XKBlib.h>
6038 #include <X11/keysym.h>
6041 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p
,
6042 Sx_backspace_delete_keys_p
, 0, 1, 0,
6043 doc
: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
6044 FRAME nil means use the selected frame.
6045 Value is t if we know that both keys are present, and are mapped to the
6046 usual X keysyms. Value is `lambda' if we cannot determine if both keys are
6047 present and mapped to the usual X keysyms. */)
6054 struct frame
*f
= decode_window_system_frame (frame
);
6055 Display
*dpy
= FRAME_X_DISPLAY (f
);
6056 Lisp_Object have_keys
;
6057 int major
, minor
, op
, event
, error_code
;
6061 /* Check library version in case we're dynamically linked. */
6062 major
= XkbMajorVersion
;
6063 minor
= XkbMinorVersion
;
6064 if (!XkbLibraryVersion (&major
, &minor
))
6070 /* Check that the server supports XKB. */
6071 major
= XkbMajorVersion
;
6072 minor
= XkbMinorVersion
;
6073 if (!XkbQueryExtension (dpy
, &op
, &event
, &error_code
, &major
, &minor
))
6079 /* In this code we check that the keyboard has physical keys with names
6080 that start with BKSP (Backspace) and DELE (Delete), and that they
6081 generate keysym XK_BackSpace and XK_Delete respectively.
6082 This function is used to test if normal-erase-is-backspace should be
6084 An alternative approach would be to just check if XK_BackSpace and
6085 XK_Delete are mapped to any key. But if any of those are mapped to
6086 some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the
6087 user doesn't know about it, it is better to return false here.
6088 It is more obvious to the user what to do if she/he has two keys
6089 clearly marked with names/symbols and one key does something not
6090 expected (i.e. she/he then tries the other).
6091 The cases where Backspace/Delete is mapped to some other key combination
6092 are rare, and in those cases, normal-erase-is-backspace can be turned on
6096 kb
= XkbGetMap (dpy
, XkbAllMapComponentsMask
, XkbUseCoreKbd
);
6099 int delete_keycode
= 0, backspace_keycode
= 0, i
;
6101 if (XkbGetNames (dpy
, XkbAllNamesMask
, kb
) == Success
)
6103 for (i
= kb
->min_key_code
;
6104 (i
< kb
->max_key_code
6105 && (delete_keycode
== 0 || backspace_keycode
== 0));
6108 /* The XKB symbolic key names can be seen most easily in
6109 the PS file generated by `xkbprint -label name
6111 if (memcmp ("DELE", kb
->names
->keys
[i
].name
, 4) == 0)
6113 else if (memcmp ("BKSP", kb
->names
->keys
[i
].name
, 4) == 0)
6114 backspace_keycode
= i
;
6117 XkbFreeNames (kb
, 0, True
);
6120 /* As of libX11-1.6.2, XkbGetMap manual says that you should use
6121 XkbFreeClientMap to free the data returned by XkbGetMap. But
6122 this function just frees the data referenced from KB and not
6123 KB itself. To free KB as well, call XkbFreeKeyboard. */
6124 XkbFreeKeyboard (kb
, XkbAllMapComponentsMask
, True
);
6127 && backspace_keycode
6128 && XKeysymToKeycode (dpy
, XK_Delete
) == delete_keycode
6129 && XKeysymToKeycode (dpy
, XK_BackSpace
) == backspace_keycode
)
6139 /***********************************************************************
6141 ***********************************************************************/
6143 /* Keep this list in the same order as frame_parms in frame.c.
6144 Use 0 for unsupported frame parameters. */
6146 frame_parm_handler x_frame_parm_handlers
[] =
6150 x_set_background_color
,
6156 x_set_foreground_color
,
6159 x_set_internal_border_width
,
6160 x_set_right_divider_width
,
6161 x_set_bottom_divider_width
,
6162 x_set_menu_bar_lines
,
6164 x_explicitly_set_name
,
6165 x_set_scroll_bar_width
,
6166 x_set_scroll_bar_height
,
6169 x_set_vertical_scroll_bars
,
6170 x_set_horizontal_scroll_bars
,
6172 x_set_tool_bar_lines
,
6173 x_set_scroll_bar_foreground
,
6174 x_set_scroll_bar_background
,
6184 x_set_tool_bar_position
,
6190 DEFSYM (Qundefined_color
, "undefined-color");
6191 DEFSYM (Qcompound_text
, "compound-text");
6192 DEFSYM (Qcancel_timer
, "cancel-timer");
6193 DEFSYM (Qfont_param
, "font-parameter");
6195 Fput (Qundefined_color
, Qerror_conditions
,
6196 listn (CONSTYPE_PURE
, 2, Qundefined_color
, Qerror
));
6197 Fput (Qundefined_color
, Qerror_message
,
6198 build_pure_c_string ("Undefined color"));
6200 DEFVAR_LISP ("x-pointer-shape", Vx_pointer_shape
,
6201 doc
: /* The shape of the pointer when over text.
6202 Changing the value does not affect existing frames
6203 unless you set the mouse color. */);
6204 Vx_pointer_shape
= Qnil
;
6206 #if 0 /* This doesn't really do anything. */
6207 DEFVAR_LISP ("x-nontext-pointer-shape", Vx_nontext_pointer_shape
,
6208 doc
: /* The shape of the pointer when not over text.
6209 This variable takes effect when you create a new frame
6210 or when you set the mouse color. */);
6212 Vx_nontext_pointer_shape
= Qnil
;
6214 DEFVAR_LISP ("x-hourglass-pointer-shape", Vx_hourglass_pointer_shape
,
6215 doc
: /* The shape of the pointer when Emacs is busy.
6216 This variable takes effect when you create a new frame
6217 or when you set the mouse color. */);
6218 Vx_hourglass_pointer_shape
= Qnil
;
6220 #if 0 /* This doesn't really do anything. */
6221 DEFVAR_LISP ("x-mode-pointer-shape", Vx_mode_pointer_shape
,
6222 doc
: /* The shape of the pointer when over the mode line.
6223 This variable takes effect when you create a new frame
6224 or when you set the mouse color. */);
6226 Vx_mode_pointer_shape
= Qnil
;
6228 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
6229 Vx_sensitive_text_pointer_shape
,
6230 doc
: /* The shape of the pointer when over mouse-sensitive text.
6231 This variable takes effect when you create a new frame
6232 or when you set the mouse color. */);
6233 Vx_sensitive_text_pointer_shape
= Qnil
;
6235 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
6236 Vx_window_horizontal_drag_shape
,
6237 doc
: /* Pointer shape to use for indicating a window can be dragged horizontally.
6238 This variable takes effect when you create a new frame
6239 or when you set the mouse color. */);
6240 Vx_window_horizontal_drag_shape
= Qnil
;
6242 DEFVAR_LISP ("x-window-vertical-drag-cursor",
6243 Vx_window_vertical_drag_shape
,
6244 doc
: /* Pointer shape to use for indicating a window can be dragged vertically.
6245 This variable takes effect when you create a new frame
6246 or when you set the mouse color. */);
6247 Vx_window_vertical_drag_shape
= Qnil
;
6249 DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel
,
6250 doc
: /* A string indicating the foreground color of the cursor box. */);
6251 Vx_cursor_fore_pixel
= Qnil
;
6253 DEFVAR_LISP ("x-max-tooltip-size", Vx_max_tooltip_size
,
6254 doc
: /* Maximum size for tooltips.
6255 Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */);
6256 Vx_max_tooltip_size
= Fcons (make_number (80), make_number (40));
6258 DEFVAR_LISP ("x-no-window-manager", Vx_no_window_manager
,
6259 doc
: /* Non-nil if no X window manager is in use.
6260 Emacs doesn't try to figure this out; this is always nil
6261 unless you set it to something else. */);
6262 /* We don't have any way to find this out, so set it to nil
6263 and maybe the user would like to set it to t. */
6264 Vx_no_window_manager
= Qnil
;
6266 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
6267 Vx_pixel_size_width_font_regexp
,
6268 doc
: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
6270 Since Emacs gets width of a font matching with this regexp from
6271 PIXEL_SIZE field of the name, font finding mechanism gets faster for
6272 such a font. This is especially effective for such large fonts as
6273 Chinese, Japanese, and Korean. */);
6274 Vx_pixel_size_width_font_regexp
= Qnil
;
6276 /* This is not ifdef:ed, so other builds than GTK can customize it. */
6277 DEFVAR_BOOL ("x-gtk-use-old-file-dialog", x_gtk_use_old_file_dialog
,
6278 doc
: /* Non-nil means prompt with the old GTK file selection dialog.
6279 If nil or if the file selection dialog is not available, the new GTK file
6280 chooser is used instead. To turn off all file dialogs set the
6281 variable `use-file-dialog'. */);
6282 x_gtk_use_old_file_dialog
= 0;
6284 DEFVAR_BOOL ("x-gtk-show-hidden-files", x_gtk_show_hidden_files
,
6285 doc
: /* If non-nil, the GTK file chooser will by default show hidden files.
6286 Note that this is just the default, there is a toggle button on the file
6287 chooser to show or not show hidden files on a case by case basis. */);
6288 x_gtk_show_hidden_files
= 0;
6290 DEFVAR_BOOL ("x-gtk-file-dialog-help-text", x_gtk_file_dialog_help_text
,
6291 doc
: /* If non-nil, the GTK file chooser will show additional help text.
6292 If more space for files in the file chooser dialog is wanted, set this to nil
6293 to turn the additional text off. */);
6294 x_gtk_file_dialog_help_text
= 1;
6296 DEFVAR_BOOL ("x-gtk-use-system-tooltips", x_gtk_use_system_tooltips
,
6297 doc
: /* If non-nil with a Gtk+ built Emacs, the Gtk+ tooltip is used.
6298 Otherwise use Emacs own tooltip implementation.
6299 When using Gtk+ tooltips, the tooltip face is not used. */);
6300 x_gtk_use_system_tooltips
= 1;
6302 /* Tell Emacs about this window system. */
6303 Fprovide (Qx
, Qnil
);
6305 #ifdef USE_X_TOOLKIT
6306 Fprovide (intern_c_string ("x-toolkit"), Qnil
);
6308 Fprovide (intern_c_string ("motif"), Qnil
);
6310 DEFVAR_LISP ("motif-version-string", Vmotif_version_string
,
6311 doc
: /* Version info for LessTif/Motif. */);
6312 Vmotif_version_string
= build_string (XmVERSION_STRING
);
6313 #endif /* USE_MOTIF */
6314 #endif /* USE_X_TOOLKIT */
6317 /* Provide x-toolkit also for GTK. Internally GTK does not use Xt so it
6318 is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
6319 But for a user it is a toolkit for X, and indeed, configure
6320 accepts --with-x-toolkit=gtk. */
6321 Fprovide (intern_c_string ("x-toolkit"), Qnil
);
6322 Fprovide (intern_c_string ("gtk"), Qnil
);
6323 Fprovide (intern_c_string ("move-toolbar"), Qnil
);
6325 DEFVAR_LISP ("gtk-version-string", Vgtk_version_string
,
6326 doc
: /* Version info for GTK+. */);
6328 char gtk_version
[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
6329 int len
= sprintf (gtk_version
, "%d.%d.%d",
6330 GTK_MAJOR_VERSION
, GTK_MINOR_VERSION
, GTK_MICRO_VERSION
);
6331 Vgtk_version_string
= make_pure_string (gtk_version
, len
, len
, 0);
6333 #endif /* USE_GTK */
6335 /* X window properties. */
6336 defsubr (&Sx_change_window_property
);
6337 defsubr (&Sx_delete_window_property
);
6338 defsubr (&Sx_window_property
);
6340 defsubr (&Sxw_display_color_p
);
6341 defsubr (&Sx_display_grayscale_p
);
6342 defsubr (&Sxw_color_defined_p
);
6343 defsubr (&Sxw_color_values
);
6344 defsubr (&Sx_server_max_request_size
);
6345 defsubr (&Sx_server_vendor
);
6346 defsubr (&Sx_server_version
);
6347 defsubr (&Sx_display_pixel_width
);
6348 defsubr (&Sx_display_pixel_height
);
6349 defsubr (&Sx_display_mm_width
);
6350 defsubr (&Sx_display_mm_height
);
6351 defsubr (&Sx_display_screens
);
6352 defsubr (&Sx_display_planes
);
6353 defsubr (&Sx_display_color_cells
);
6354 defsubr (&Sx_display_visual_class
);
6355 defsubr (&Sx_display_backing_store
);
6356 defsubr (&Sx_display_save_under
);
6357 defsubr (&Sx_display_monitor_attributes_list
);
6358 defsubr (&Sx_frame_geometry
);
6359 defsubr (&Sx_wm_set_size_hint
);
6360 defsubr (&Sx_create_frame
);
6361 defsubr (&Sx_open_connection
);
6362 defsubr (&Sx_close_connection
);
6363 defsubr (&Sx_display_list
);
6364 defsubr (&Sx_synchronize
);
6365 defsubr (&Sx_backspace_delete_keys_p
);
6367 defsubr (&Sx_show_tip
);
6368 defsubr (&Sx_hide_tip
);
6370 staticpro (&tip_timer
);
6372 staticpro (&tip_frame
);
6374 last_show_tip_args
= Qnil
;
6375 staticpro (&last_show_tip_args
);
6377 defsubr (&Sx_uses_old_gtk_dialog
);
6378 #if defined (USE_MOTIF) || defined (USE_GTK)
6379 defsubr (&Sx_file_dialog
);
6382 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
6383 defsubr (&Sx_select_font
);