1 /* Functions for the X window system.
3 Copyright (C) 1989, 1992-2018 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 (at
10 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 <https://www.gnu.org/licenses/>. */
31 #include "dispextern.h"
33 #include "blockinput.h"
36 #include "termhooks.h"
39 #include <sys/types.h>
42 #include "bitmaps/gray.xbm"
43 #include "xsettings.h"
46 #include <X11/extensions/Xrandr.h>
49 #include <X11/extensions/Xinerama.h>
57 #include <X11/extensions/Xdbe.h>
61 #include <X11/Shell.h>
65 #include <X11/Xaw3d/Paned.h>
66 #include <X11/Xaw3d/Label.h>
67 #else /* !HAVE_XAW3D */
68 #include <X11/Xaw/Paned.h>
69 #include <X11/Xaw/Label.h>
70 #endif /* HAVE_XAW3D */
71 #endif /* USE_MOTIF */
74 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
77 #ifdef USG /* Pacify gcc -Wunused-macros. */
85 #include "../lwlib/lwlib.h"
89 #include <Xm/DialogS.h>
90 #include <Xm/FileSB.h>
93 #include <Xm/MwmUtil.h>
97 #include "../lwlib/xlwmenu.h"
100 /* Unique id counter for widgets created by the Lucid Widget Library. */
102 extern LWLIB_ID widget_id_tick
;
106 #endif /* USE_MOTIF */
108 #endif /* USE_X_TOOLKIT */
114 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
116 static ptrdiff_t image_cache_refcount
;
118 static int dpyinfo_refcount
;
123 /** #define MWM_HINTS_FUNCTIONS (1L << 0) **/
124 #define MWM_HINTS_DECORATIONS (1L << 1)
125 /** #define MWM_HINTS_INPUT_MODE (1L << 2) **/
126 /** #define MWM_HINTS_STATUS (1L << 3) **/
128 #define MWM_DECOR_ALL (1L << 0)
129 /** #define MWM_DECOR_BORDER (1L << 1) **/
130 /** #define MWM_DECOR_RESIZEH (1L << 2) **/
131 /** #define MWM_DECOR_TITLE (1L << 3) **/
132 /** #define MWM_DECOR_MENU (1L << 4) **/
133 /** #define MWM_DECOR_MINIMIZE (1L << 5) **/
134 /** #define MWM_DECOR_MAXIMIZE (1L << 6) **/
136 /** #define _XA_MOTIF_WM_HINTS "_MOTIF_WM_HINTS" **/
140 unsigned long functions
;
141 unsigned long decorations
;
143 unsigned long status
;
146 #define PROP_MOTIF_WM_HINTS_ELEMENTS 5
147 #endif /* NOT USE_GTK */
148 #endif /* NOT USE_MOTIF */
150 static struct x_display_info
*x_display_info_for_name (Lisp_Object
);
151 static void set_up_x_back_buffer (struct frame
*f
);
153 /* Let the user specify an X display with a Lisp object.
154 OBJECT may be nil, a frame or a terminal object.
155 nil stands for the selected frame--or, if that is not an X frame,
156 the first X display on the list. */
158 struct x_display_info
*
159 check_x_display_info (Lisp_Object object
)
161 struct x_display_info
*dpyinfo
= NULL
;
165 struct frame
*sf
= XFRAME (selected_frame
);
167 if (FRAME_X_P (sf
) && FRAME_LIVE_P (sf
))
168 dpyinfo
= FRAME_DISPLAY_INFO (sf
);
169 else if (x_display_list
!= 0)
170 dpyinfo
= x_display_list
;
172 error ("X windows are not in use or not initialized");
174 else if (TERMINALP (object
))
176 struct terminal
*t
= decode_live_terminal (object
);
178 if (t
->type
!= output_x_window
)
179 error ("Terminal %d is not an X display", t
->id
);
181 dpyinfo
= t
->display_info
.x
;
183 else if (STRINGP (object
))
184 dpyinfo
= x_display_info_for_name (object
);
187 struct frame
*f
= decode_window_system_frame (object
);
188 dpyinfo
= FRAME_DISPLAY_INFO (f
);
194 /* Return the screen positions and offsets of frame F.
195 Store the offsets between FRAME_OUTER_WINDOW and the containing
196 window manager window into LEFT_OFFSET_X, RIGHT_OFFSET_X,
197 TOP_OFFSET_Y and BOTTOM_OFFSET_Y.
198 Store the offsets between FRAME_X_WINDOW and the containing
199 window manager window into X_PIXELS_DIFF and Y_PIXELS_DIFF.
200 Store the screen positions of frame F into XPTR and YPTR.
201 These are the positions of the containing window manager window,
202 not Emacs's own window. */
204 x_real_pos_and_offsets (struct frame
*f
,
208 int *bottom_offset_y
,
215 int win_x
= 0, win_y
= 0, outer_x
= 0, outer_y
= 0;
216 int real_x
= 0, real_y
= 0;
217 bool had_errors
= false;
218 struct frame
*parent_frame
= FRAME_PARENT_FRAME (f
);
219 Window win
= (parent_frame
220 ? FRAME_X_WINDOW (parent_frame
)
221 : f
->output_data
.x
->parent_desc
);
222 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
224 Atom target_type
= XA_CARDINAL
;
225 unsigned int ow
= 0, oh
= 0;
226 unsigned int fw
= 0, fh
= 0;
228 /* We resort to XCB if possible because there are several X calls
229 here which require responses from the server but do not have data
230 dependencies between them. Using XCB lets us pipeline requests,
231 whereas with Xlib we must wait for each answer before sending the
234 For a non-local display, the round-trip time could be a few tens
235 of milliseconds, depending on the network distance. It doesn't
236 take a lot of those to add up to a noticeable hesitation in
237 responding to user actions. */
239 xcb_connection_t
*xcb_conn
= dpyinfo
->xcb_connection
;
240 xcb_get_property_cookie_t prop_cookie
;
241 xcb_get_geometry_cookie_t outer_geom_cookie
;
242 bool sent_requests
= false;
245 unsigned long actual_size
, bytes_remaining
;
246 int rc
, actual_format
;
247 Display
*dpy
= FRAME_X_DISPLAY (f
);
248 unsigned char *tmp_data
= NULL
;
251 if (x_pixels_diff
) *x_pixels_diff
= 0;
252 if (y_pixels_diff
) *y_pixels_diff
= 0;
253 if (left_offset_x
) *left_offset_x
= 0;
254 if (top_offset_y
) *top_offset_y
= 0;
255 if (right_offset_x
) *right_offset_x
= 0;
256 if (bottom_offset_y
) *bottom_offset_y
= 0;
259 if (outer_border
) *outer_border
= 0;
261 if (win
== dpyinfo
->root_window
)
262 win
= FRAME_OUTER_WINDOW (f
);
267 /* If we're using XCB, all errors are checked for on each call. */
268 x_catch_errors (dpy
);
271 /* This loop traverses up the containment tree until we hit the root
272 window. Window managers may intersect many windows between our window
273 and the root window. The window we find just before the root window
274 should be the outer WM window. */
277 Window wm_window
, rootw
;
280 xcb_query_tree_cookie_t query_tree_cookie
;
281 xcb_query_tree_reply_t
*query_tree
;
283 query_tree_cookie
= xcb_query_tree (xcb_conn
, win
);
284 query_tree
= xcb_query_tree_reply (xcb_conn
, query_tree_cookie
, NULL
);
285 if (query_tree
== NULL
)
289 wm_window
= query_tree
->parent
;
290 rootw
= query_tree
->root
;
294 Window
*tmp_children
;
295 unsigned int tmp_nchildren
;
298 success
= XQueryTree (dpy
, win
, &rootw
,
299 &wm_window
, &tmp_children
, &tmp_nchildren
);
301 had_errors
= x_had_errors_p (dpy
);
303 /* Don't free tmp_children if XQueryTree failed. */
307 XFree (tmp_children
);
310 if (had_errors
|| wm_window
== rootw
)
319 xcb_get_geometry_cookie_t geom_cookie
;
320 xcb_translate_coordinates_cookie_t trans_cookie
;
321 xcb_translate_coordinates_cookie_t outer_trans_cookie
;
323 xcb_translate_coordinates_reply_t
*trans
;
324 xcb_get_geometry_reply_t
*geom
;
331 /* Fire off the requests that don't have data dependencies.
333 Once we've done this, we must collect the results for each
334 one before returning, even if other errors are detected,
335 making the other responses moot. */
336 geom_cookie
= xcb_get_geometry (xcb_conn
, win
);
339 xcb_translate_coordinates (xcb_conn
,
340 /* From-window, to-window. */
341 FRAME_DISPLAY_INFO (f
)->root_window
,
346 if (FRAME_X_WINDOW (f
) != FRAME_OUTER_WINDOW (f
))
348 xcb_translate_coordinates (xcb_conn
,
349 /* From-window, to-window. */
350 FRAME_DISPLAY_INFO (f
)->root_window
,
351 FRAME_OUTER_WINDOW (f
),
355 if (right_offset_x
|| bottom_offset_y
)
356 outer_geom_cookie
= xcb_get_geometry (xcb_conn
,
357 FRAME_OUTER_WINDOW (f
));
360 && dpyinfo
->root_window
== f
->output_data
.x
->parent_desc
)
361 /* Try _NET_FRAME_EXTENTS if our parent is the root window. */
362 prop_cookie
= xcb_get_property (xcb_conn
, 0, win
,
363 dpyinfo
->Xatom_net_frame_extents
,
364 target_type
, 0, max_len
);
366 sent_requests
= true;
369 /* Get the real coordinates for the WM window upper left corner */
371 geom
= xcb_get_geometry_reply (xcb_conn
, geom_cookie
, NULL
);
378 bw
= geom
->border_width
;
384 XGetGeometry (dpy
, win
,
385 &rootw
, &real_x
, &real_y
, &ow
, &oh
, &bw
, &ign
);
388 /* Translate real coordinates to coordinates relative to our
389 window. For our window, the upper left corner is 0, 0.
390 Since the upper left corner of the WM window is outside
391 our window, win_x and win_y will be negative:
393 ------------------ ---> x
395 | ----------------- v y
398 Since we don't care about the child window corresponding to
399 the actual coordinates, we can send zero to get the offsets
400 and compute the resulting coordinates below. This reduces
401 the data dependencies between calls and lets us pipeline the
402 requests better in the XCB case. */
404 trans
= xcb_translate_coordinates_reply (xcb_conn
, trans_cookie
, NULL
);
407 win_x
= trans
->dst_x
;
408 win_y
= trans
->dst_y
;
414 XTranslateCoordinates (dpy
,
416 /* From-window, to-window. */
417 FRAME_DISPLAY_INFO (f
)->root_window
,
420 /* From-position, to-position. */
421 0, 0, &win_x
, &win_y
,
430 if (FRAME_X_WINDOW (f
) == FRAME_OUTER_WINDOW (f
))
438 xcb_translate_coordinates_reply_t
*outer_trans
;
440 outer_trans
= xcb_translate_coordinates_reply (xcb_conn
,
445 outer_x
= outer_trans
->dst_x
;
446 outer_y
= outer_trans
->dst_y
;
452 XTranslateCoordinates (dpy
,
454 /* From-window, to-window. */
455 FRAME_DISPLAY_INFO (f
)->root_window
,
456 FRAME_OUTER_WINDOW (f
),
458 /* From-position, to-position. */
459 0, 0, &outer_x
, &outer_y
,
470 had_errors
= x_had_errors_p (dpy
);
474 if (!parent_frame
&& dpyinfo
->root_window
== f
->output_data
.x
->parent_desc
)
476 /* Try _NET_FRAME_EXTENTS if our parent is the root window. */
478 /* Make sure we didn't get an X error early and skip sending the
482 xcb_get_property_reply_t
*prop
;
484 prop
= xcb_get_property_reply (xcb_conn
, prop_cookie
, NULL
);
487 if (prop
->type
== target_type
488 && prop
->format
== 32
489 && (xcb_get_property_value_length (prop
)
490 == 4 * sizeof (int32_t)))
492 int32_t *fe
= xcb_get_property_value (prop
);
501 /* Xlib version doesn't set had_errors here. Intentional or bug? */
504 rc
= XGetWindowProperty (dpy
, win
, dpyinfo
->Xatom_net_frame_extents
,
505 0, max_len
, False
, target_type
,
506 &actual_type
, &actual_format
, &actual_size
,
507 &bytes_remaining
, &tmp_data
);
509 if (rc
== Success
&& actual_type
== target_type
&& !x_had_errors_p (dpy
)
510 && actual_size
== 4 && actual_format
== 32)
512 long *fe
= (long *)tmp_data
;
520 if (tmp_data
) XFree (tmp_data
);
524 if (right_offset_x
|| bottom_offset_y
)
527 /* Make sure we didn't get an X error early and skip sending the
531 xcb_get_geometry_reply_t
*outer_geom
;
533 outer_geom
= xcb_get_geometry_reply (xcb_conn
, outer_geom_cookie
,
537 fw
= outer_geom
->width
;
538 fh
= outer_geom
->height
;
549 XGetGeometry (dpy
, FRAME_OUTER_WINDOW (f
),
550 &rootw
, &xy_ign
, &xy_ign
, &fw
, &fh
, &ign
, &ign
);
560 if (had_errors
) return;
562 if (x_pixels_diff
) *x_pixels_diff
= -win_x
;
563 if (y_pixels_diff
) *y_pixels_diff
= -win_y
;
565 if (left_offset_x
) *left_offset_x
= -outer_x
;
566 if (top_offset_y
) *top_offset_y
= -outer_y
;
568 if (xptr
) *xptr
= real_x
;
569 if (yptr
) *yptr
= real_y
;
571 if (outer_border
) *outer_border
= bw
;
573 if (right_offset_x
) *right_offset_x
= ow
- fw
+ outer_x
;
574 if (bottom_offset_y
) *bottom_offset_y
= oh
- fh
+ outer_y
;
577 /* Store the screen positions of frame F into XPTR and YPTR.
578 These are the positions of the containing window manager window,
579 not Emacs's own window. */
582 x_real_positions (struct frame
*f
, int *xptr
, int *yptr
)
584 x_real_pos_and_offsets (f
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, xptr
, yptr
,
589 /* Get the mouse position in frame relative coordinates. */
592 x_relative_mouse_position (struct frame
*f
, int *x
, int *y
)
594 Window root
, dummy_window
;
597 eassert (FRAME_X_P (f
));
601 XQueryPointer (FRAME_X_DISPLAY (f
),
602 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
604 /* The root window which contains the pointer. */
607 /* Window pointer is on, not used */
610 /* The position on that root window. */
613 /* x/y in dummy_window coordinates, not used. */
616 /* Modifier keys and pointer buttons, about which
618 (unsigned int *) &dummy
);
620 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
622 /* From-window, to-window. */
623 FRAME_DISPLAY_INFO (f
)->root_window
,
626 /* From-position, to-position. */
635 /* Gamma-correct COLOR on frame F. */
638 gamma_correct (struct frame
*f
, XColor
*color
)
642 color
->red
= pow (color
->red
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
643 color
->green
= pow (color
->green
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
644 color
->blue
= pow (color
->blue
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
649 /* Decide if color named COLOR_NAME is valid for use on frame F. If
650 so, return the RGB values in COLOR. If ALLOC_P,
651 allocate the color. Value is false if COLOR_NAME is invalid, or
652 no color could be allocated. */
655 x_defined_color (struct frame
*f
, const char *color_name
,
656 XColor
*color
, bool alloc_p
)
658 bool success_p
= false;
659 Colormap cmap
= FRAME_X_COLORMAP (f
);
663 success_p
= xg_check_special_colors (f
, color_name
, color
);
666 success_p
= x_parse_color (f
, color_name
, color
) != 0;
667 if (success_p
&& alloc_p
)
668 success_p
= x_alloc_nearest_color (f
, cmap
, color
);
675 /* Return the pixel color value for color COLOR_NAME on frame F. If F
676 is a monochrome frame, return MONO_COLOR regardless of what ARG says.
677 Signal an error if color can't be allocated. */
680 x_decode_color (struct frame
*f
, Lisp_Object color_name
, int mono_color
)
684 CHECK_STRING (color_name
);
686 #if false /* Don't do this. It's wrong when we're not using the default
687 colormap, it makes freeing difficult, and it's probably not
688 an important optimization. */
689 if (strcmp (SDATA (color_name
), "black") == 0)
690 return BLACK_PIX_DEFAULT (f
);
691 else if (strcmp (SDATA (color_name
), "white") == 0)
692 return WHITE_PIX_DEFAULT (f
);
695 /* Return MONO_COLOR for monochrome frames. */
696 if (FRAME_DISPLAY_INFO (f
)->n_planes
== 1)
699 /* x_defined_color is responsible for coping with failures
700 by looking for a near-miss. */
701 if (x_defined_color (f
, SSDATA (color_name
), &cdef
, true))
704 signal_error ("Undefined color", color_name
);
709 /* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
710 the previous value of that parameter, NEW_VALUE is the new value.
711 See also the comment of wait_for_wm in struct x_output. */
714 x_set_wait_for_wm (struct frame
*f
, Lisp_Object new_value
, Lisp_Object old_value
)
716 f
->output_data
.x
->wait_for_wm
= !NILP (new_value
);
720 x_set_tool_bar_position (struct frame
*f
,
721 Lisp_Object new_value
,
722 Lisp_Object old_value
)
724 Lisp_Object choice
= list4 (Qleft
, Qright
, Qtop
, Qbottom
);
726 if (!NILP (Fmemq (new_value
, choice
)))
729 if (!EQ (new_value
, old_value
))
731 xg_change_toolbar_position (f
, new_value
);
732 fset_tool_bar_position (f
, new_value
);
735 if (!EQ (new_value
, Qtop
))
736 error ("The only supported tool bar position is top");
740 wrong_choice (choice
, new_value
);
744 x_set_inhibit_double_buffering (struct frame
*f
,
745 Lisp_Object new_value
,
746 Lisp_Object old_value
)
749 if (FRAME_X_WINDOW (f
) && !EQ (new_value
, old_value
))
751 bool want_double_buffering
= NILP (new_value
);
752 bool was_double_buffered
= FRAME_X_DOUBLE_BUFFERED_P (f
);
753 /* font_drop_xrender_surfaces in xftfont does something only if
754 we're double-buffered, so call font_drop_xrender_surfaces before
755 and after any potential change. One of the calls will end up
757 if (want_double_buffering
!= was_double_buffered
)
758 font_drop_xrender_surfaces (f
);
759 if (FRAME_X_DOUBLE_BUFFERED_P (f
) && !want_double_buffering
)
760 tear_down_x_back_buffer (f
);
761 else if (!FRAME_X_DOUBLE_BUFFERED_P (f
) && want_double_buffering
)
762 set_up_x_back_buffer (f
);
763 if (FRAME_X_DOUBLE_BUFFERED_P (f
) != was_double_buffered
)
765 SET_FRAME_GARBAGED (f
);
766 font_drop_xrender_surfaces (f
);
775 * Set frame F's `undecorated' parameter. If non-nil, F's window-system
776 * window is drawn without decorations, title, minimize/maximize boxes
777 * and external borders. This usually means that the window cannot be
778 * dragged, resized, iconified, maximized or deleted with the mouse. If
779 * nil, draw the frame with all the elements listed above unless these
780 * have been suspended via window manager settings.
782 * Some window managers may not honor this parameter.
785 x_set_undecorated (struct frame
*f
, Lisp_Object new_value
, Lisp_Object old_value
)
787 if (!EQ (new_value
, old_value
))
789 FRAME_UNDECORATED (f
) = NILP (new_value
) ? false : true;
791 xg_set_undecorated (f
, new_value
);
793 Display
*dpy
= FRAME_X_DISPLAY (f
);
794 PropMotifWmHints hints
;
795 Atom prop
= XInternAtom (dpy
, "_MOTIF_WM_HINTS", False
);
797 memset (&hints
, 0, sizeof(hints
));
798 hints
.flags
= MWM_HINTS_DECORATIONS
;
799 hints
.decorations
= NILP (new_value
) ? MWM_DECOR_ALL
: 0;
802 /* For some reason the third and fourth arguments in the following
803 call must be identical: In the corresponding XGetWindowProperty
804 call in getMotifHints, xfwm has the third and seventh args both
805 display_info->atoms[MOTIF_WM_HINTS]. Obviously, YMMV. */
806 XChangeProperty (dpy
, FRAME_OUTER_WINDOW (f
), prop
, prop
, 32,
807 PropModeReplace
, (unsigned char *) &hints
,
808 PROP_MOTIF_WM_HINTS_ELEMENTS
);
816 * x_set_parent_frame:
818 * Set frame F's `parent-frame' parameter. If non-nil, make F a child
819 * frame of the frame specified by that parameter. Technically, this
820 * makes F's window-system window a child window of the parent frame's
821 * window-system window. If nil, make F's window-system window a
822 * top-level window--a child of its display's root window.
824 * A child frame is clipped at the native edges of its parent frame.
825 * Its `left' and `top' parameters specify positions relative to the
826 * top-left corner of its parent frame's native rectangle. Usually,
827 * moving a parent frame moves all its child frames too, keeping their
828 * position relative to the parent unaltered. When a parent frame is
829 * iconified or made invisible, its child frames are made invisible.
830 * When a parent frame is deleted, its child frames are deleted too.
832 * A visible child frame always appears on top of its parent frame thus
833 * obscuring parts of it. When a frame has more than one child frame,
834 * their stacking order is specified just as that of non-child frames
835 * relative to their display.
837 * Whether a child frame has a menu or tool bar may be window-system or
838 * window manager dependent. It's advisable to disable both via the
839 * frame parameter settings.
841 * Some window managers may not honor this parameter.
844 x_set_parent_frame (struct frame
*f
, Lisp_Object new_value
, Lisp_Object old_value
)
846 struct frame
*p
= NULL
;
848 if (!NILP (new_value
)
849 && (!FRAMEP (new_value
)
850 || !FRAME_LIVE_P (p
= XFRAME (new_value
))
853 store_frame_param (f
, Qparent_frame
, old_value
);
854 error ("Invalid specification of `parent-frame'");
857 if (p
!= FRAME_PARENT_FRAME (f
))
861 (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
862 p
? FRAME_X_WINDOW (p
) : DefaultRootWindow (FRAME_X_DISPLAY (f
)),
863 f
->left_pos
, f
->top_pos
);
866 fset_parent_frame (f
, new_value
);
871 * x_set_no_focus_on_map:
873 * Set frame F's `no-focus-on-map' parameter which, if non-nil, means
874 * that F's window-system window does not want to receive input focus
875 * when it is mapped. (A frame's window is mapped when the frame is
876 * displayed for the first time and when the frame changes its state
877 * from `iconified' or `invisible' to `visible'.)
879 * Some window managers may not honor this parameter.
882 x_set_no_focus_on_map (struct frame
*f
, Lisp_Object new_value
, Lisp_Object old_value
)
884 if (!EQ (new_value
, old_value
))
887 xg_set_no_focus_on_map (f
, new_value
);
888 #else /* not USE_GTK */
889 Display
*dpy
= FRAME_X_DISPLAY (f
);
890 Atom prop
= XInternAtom (dpy
, "_NET_WM_USER_TIME", False
);
891 Time timestamp
= NILP (new_value
) ? CurrentTime
: 0;
893 XChangeProperty (dpy
, FRAME_OUTER_WINDOW (f
), prop
,
894 XA_CARDINAL
, 32, PropModeReplace
,
895 (unsigned char *) ×tamp
, 1);
897 FRAME_NO_FOCUS_ON_MAP (f
) = !NILP (new_value
);
902 * x_set_no_accept_focus:
904 * Set frame F's `no-accept-focus' parameter which, if non-nil, hints
905 * that F's window-system window does not want to receive input focus
906 * via mouse clicks or by moving the mouse into it.
908 * If non-nil, this may have the unwanted side-effect that a user cannot
909 * scroll a non-selected frame with the mouse.
911 * Some window managers may not honor this parameter.
914 x_set_no_accept_focus (struct frame
*f
, Lisp_Object new_value
, Lisp_Object old_value
)
916 if (!EQ (new_value
, old_value
))
919 xg_set_no_accept_focus (f
, new_value
);
920 #else /* not USE_GTK */
924 XtSetArg (al
[0], XtNinput
, NILP (new_value
) ? True
: False
);
925 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
926 #else /* not USE_X_TOOLKIT */
927 Window window
= FRAME_X_WINDOW (f
);
929 f
->output_data
.x
->wm_hints
.input
= NILP (new_value
) ? True
: False
;
930 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
931 #endif /* USE_X_TOOLKIT */
933 FRAME_NO_ACCEPT_FOCUS (f
) = !NILP (new_value
);
938 * x_set_override_redirect:
940 * Set frame F's `override_redirect' parameter which, if non-nil, hints
941 * that the window manager doesn't want to deal with F. Usually, such
942 * frames have no decorations and always appear on top of all frames.
944 * Some window managers may not honor this parameter.
947 x_set_override_redirect (struct frame
*f
, Lisp_Object new_value
, Lisp_Object old_value
)
949 if (!EQ (new_value
, old_value
))
951 /* Here (xfwm) override_redirect can be changed for invisible
953 x_make_frame_invisible (f
);
956 xg_set_override_redirect (f
, new_value
);
957 #else /* not USE_GTK */
958 XSetWindowAttributes attributes
;
960 attributes
.override_redirect
= NILP (new_value
) ? False
: True
;
961 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
962 CWOverrideRedirect
, &attributes
);
964 x_make_frame_visible (f
);
965 FRAME_OVERRIDE_REDIRECT (f
) = !NILP (new_value
);
972 /* Set icon from FILE for frame F. By using GTK functions the icon
973 may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
976 xg_set_icon (struct frame
*f
, Lisp_Object file
)
981 found
= x_find_image_file (file
);
987 char *filename
= SSDATA (ENCODE_FILE (found
));
990 pixbuf
= gdk_pixbuf_new_from_file (filename
, &err
);
994 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
996 g_object_unref (pixbuf
);
1010 xg_set_icon_from_xpm_data (struct frame
*f
, const char **data
)
1012 GdkPixbuf
*pixbuf
= gdk_pixbuf_new_from_xpm_data (data
);
1017 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)), pixbuf
);
1018 g_object_unref (pixbuf
);
1021 #endif /* USE_GTK */
1024 /* Functions called only from `x_set_frame_param'
1025 to set individual parameters.
1027 If FRAME_X_WINDOW (f) is 0,
1028 the frame is being created and its X-window does not exist yet.
1029 In that case, just record the parameter's new value
1030 in the standard place; do not attempt to change the window. */
1033 x_set_foreground_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1035 struct x_output
*x
= f
->output_data
.x
;
1036 unsigned long fg
, old_fg
;
1038 fg
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1039 old_fg
= FRAME_FOREGROUND_PIXEL (f
);
1040 FRAME_FOREGROUND_PIXEL (f
) = fg
;
1042 if (FRAME_X_WINDOW (f
) != 0)
1044 Display
*dpy
= FRAME_X_DISPLAY (f
);
1047 XSetForeground (dpy
, x
->normal_gc
, fg
);
1048 XSetBackground (dpy
, x
->reverse_gc
, fg
);
1050 if (x
->cursor_pixel
== old_fg
)
1052 unload_color (f
, x
->cursor_pixel
);
1053 x
->cursor_pixel
= x_copy_color (f
, fg
);
1054 XSetBackground (dpy
, x
->cursor_gc
, x
->cursor_pixel
);
1059 update_face_from_frame_parameter (f
, Qforeground_color
, arg
);
1061 if (FRAME_VISIBLE_P (f
))
1065 unload_color (f
, old_fg
);
1069 x_set_background_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1071 struct x_output
*x
= f
->output_data
.x
;
1074 bg
= x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
1075 unload_color (f
, FRAME_BACKGROUND_PIXEL (f
));
1076 FRAME_BACKGROUND_PIXEL (f
) = bg
;
1078 if (FRAME_X_WINDOW (f
) != 0)
1080 Display
*dpy
= FRAME_X_DISPLAY (f
);
1083 XSetBackground (dpy
, x
->normal_gc
, bg
);
1084 XSetForeground (dpy
, x
->reverse_gc
, bg
);
1085 XSetWindowBackground (dpy
, FRAME_X_WINDOW (f
), bg
);
1086 XSetForeground (dpy
, x
->cursor_gc
, bg
);
1089 xg_set_background_color (f
, bg
);
1092 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
1093 toolkit scroll bars. */
1096 for (bar
= FRAME_SCROLL_BARS (f
);
1098 bar
= XSCROLL_BAR (bar
)->next
)
1100 Window window
= XSCROLL_BAR (bar
)->x_window
;
1101 XSetWindowBackground (dpy
, window
, bg
);
1104 #endif /* USE_TOOLKIT_SCROLL_BARS */
1107 update_face_from_frame_parameter (f
, Qbackground_color
, arg
);
1109 if (FRAME_VISIBLE_P (f
))
1114 /* This array must stay in sync with the mouse_cursor_types array below! */
1117 mouse_cursor_nontext
,
1118 mouse_cursor_hourglass
,
1121 mouse_cursor_horizontal_drag
,
1122 mouse_cursor_vertical_drag
,
1123 mouse_cursor_left_edge
,
1124 mouse_cursor_top_left_corner
,
1125 mouse_cursor_top_edge
,
1126 mouse_cursor_top_right_corner
,
1127 mouse_cursor_right_edge
,
1128 mouse_cursor_bottom_right_corner
,
1129 mouse_cursor_bottom_edge
,
1130 mouse_cursor_bottom_left_corner
,
1134 struct mouse_cursor_types
{
1135 /* Printable name for error messages (optional). */
1138 /* Lisp variable controlling the cursor shape. */
1139 /* FIXME: A couple of these variables are defined in the C code but
1140 are not actually accessible from Lisp. They should probably be
1141 made accessible or removed. */
1142 Lisp_Object
*shape_var_ptr
;
1144 /* The default shape. */
1148 /* This array must stay in sync with enum mouse_cursor above! */
1149 static const struct mouse_cursor_types mouse_cursor_types
[] = {
1150 { "text", &Vx_pointer_shape
, XC_xterm
},
1151 { "nontext", &Vx_nontext_pointer_shape
, XC_left_ptr
},
1152 { "hourglass", &Vx_hourglass_pointer_shape
, XC_watch
},
1153 { "modeline", &Vx_mode_pointer_shape
, XC_xterm
},
1154 { NULL
, &Vx_sensitive_text_pointer_shape
, XC_hand2
},
1155 { NULL
, &Vx_window_horizontal_drag_shape
, XC_sb_h_double_arrow
},
1156 { NULL
, &Vx_window_vertical_drag_shape
, XC_sb_v_double_arrow
},
1157 { NULL
, &Vx_window_left_edge_shape
, XC_left_side
},
1158 { NULL
, &Vx_window_top_left_corner_shape
, XC_top_left_corner
},
1159 { NULL
, &Vx_window_top_edge_shape
, XC_top_side
},
1160 { NULL
, &Vx_window_top_right_corner_shape
, XC_top_right_corner
},
1161 { NULL
, &Vx_window_right_edge_shape
, XC_right_side
},
1162 { NULL
, &Vx_window_bottom_right_corner_shape
, XC_bottom_right_corner
},
1163 { NULL
, &Vx_window_bottom_edge_shape
, XC_bottom_side
},
1164 { NULL
, &Vx_window_bottom_left_corner_shape
, XC_bottom_left_corner
},
1167 struct mouse_cursor_data
{
1168 /* Last index for which XCreateFontCursor has been called, and thus
1169 the last index for which x_request_serial[] is valid. */
1170 int last_cursor_create_request
;
1172 /* Last index for which an X error event was received in response to
1173 attempting to create the cursor. */
1176 /* Cursor numbers chosen. */
1177 unsigned int cursor_num
[mouse_cursor_max
];
1179 /* Allocated Cursor values, or zero for failed attempts. */
1180 Cursor cursor
[mouse_cursor_max
];
1182 /* X serial numbers for the first request sent by XCreateFontCursor.
1183 Note that there may be more than one request sent. */
1184 unsigned long x_request_serial
[mouse_cursor_max
];
1186 /* If an error has been received, a pointer to where the current
1187 error-message text is stored. */
1192 x_set_mouse_color_handler (Display
*dpy
, XErrorEvent
*event
,
1193 char *error_string
, void *data
)
1195 struct mouse_cursor_data
*cursor_data
= data
;
1198 cursor_data
->error_cursor
= -1;
1199 cursor_data
->error_string
= error_string
;
1200 for (i
= 0; i
< cursor_data
->last_cursor_create_request
; i
++)
1202 if (event
->serial
>= cursor_data
->x_request_serial
[i
])
1203 cursor_data
->error_cursor
= i
;
1205 if (cursor_data
->error_cursor
>= 0)
1206 /* If we failed to allocate it, don't try to free it. */
1207 cursor_data
->cursor
[cursor_data
->error_cursor
] = 0;
1211 x_set_mouse_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1213 struct x_output
*x
= f
->output_data
.x
;
1214 Display
*dpy
= FRAME_X_DISPLAY (f
);
1215 struct mouse_cursor_data cursor_data
= { -1, -1 };
1216 unsigned long pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1217 unsigned long mask_color
= FRAME_BACKGROUND_PIXEL (f
);
1220 /* Don't let pointers be invisible. */
1221 if (mask_color
== pixel
)
1223 x_free_colors (f
, &pixel
, 1);
1224 pixel
= x_copy_color (f
, FRAME_FOREGROUND_PIXEL (f
));
1227 unload_color (f
, x
->mouse_pixel
);
1228 x
->mouse_pixel
= pixel
;
1230 for (i
= 0; i
< mouse_cursor_max
; i
++)
1232 Lisp_Object shape_var
= *mouse_cursor_types
[i
].shape_var_ptr
;
1233 if (!NILP (shape_var
))
1235 CHECK_TYPE_RANGED_INTEGER (unsigned, shape_var
);
1236 cursor_data
.cursor_num
[i
] = XINT (shape_var
);
1239 cursor_data
.cursor_num
[i
] = mouse_cursor_types
[i
].default_shape
;
1244 /* It's not okay to crash if the user selects a screwy cursor. */
1245 x_catch_errors_with_handler (dpy
, x_set_mouse_color_handler
, &cursor_data
);
1247 for (i
= 0; i
< mouse_cursor_max
; i
++)
1249 cursor_data
.x_request_serial
[i
] = XNextRequest (dpy
);
1250 cursor_data
.last_cursor_create_request
= i
;
1251 cursor_data
.cursor
[i
] = XCreateFontCursor (dpy
,
1252 cursor_data
.cursor_num
[i
]);
1255 /* Now sync up and process all received errors from cursor
1257 if (x_had_errors_p (dpy
))
1259 const char *bad_cursor_name
= NULL
;
1260 /* Bounded by X_ERROR_MESSAGE_SIZE in xterm.c. */
1261 size_t message_length
= strlen (cursor_data
.error_string
);
1262 char *xmessage
= alloca (1 + message_length
);
1263 memcpy (xmessage
, cursor_data
.error_string
, message_length
);
1265 x_uncatch_errors ();
1267 /* Free any successfully created cursors. */
1268 for (i
= 0; i
< mouse_cursor_max
; i
++)
1269 if (cursor_data
.cursor
[i
] != 0)
1270 XFreeCursor (dpy
, cursor_data
.cursor
[i
]);
1272 /* This should only be able to fail if the server's serial
1273 number tracking is broken. */
1274 if (cursor_data
.error_cursor
>= 0)
1275 bad_cursor_name
= mouse_cursor_types
[cursor_data
.error_cursor
].name
;
1276 if (bad_cursor_name
)
1277 error ("bad %s pointer cursor: %s", bad_cursor_name
, xmessage
);
1279 error ("can't set cursor shape: %s", xmessage
);
1282 x_uncatch_errors_after_check ();
1285 XColor colors
[2]; /* 0=foreground, 1=background */
1287 colors
[0].pixel
= x
->mouse_pixel
;
1288 colors
[1].pixel
= mask_color
;
1289 x_query_colors (f
, colors
, 2);
1291 for (i
= 0; i
< mouse_cursor_max
; i
++)
1292 XRecolorCursor (dpy
, cursor_data
.cursor
[i
], &colors
[0], &colors
[1]);
1295 if (FRAME_X_WINDOW (f
) != 0)
1297 f
->output_data
.x
->current_cursor
= cursor_data
.cursor
[mouse_cursor_text
];
1298 XDefineCursor (dpy
, FRAME_X_WINDOW (f
),
1299 f
->output_data
.x
->current_cursor
);
1302 #define INSTALL_CURSOR(FIELD, SHORT_INDEX) \
1303 eassert (x->FIELD != cursor_data.cursor[mouse_cursor_ ## SHORT_INDEX]); \
1304 if (x->FIELD != 0) \
1305 XFreeCursor (dpy, x->FIELD); \
1306 x->FIELD = cursor_data.cursor[mouse_cursor_ ## SHORT_INDEX];
1308 INSTALL_CURSOR (text_cursor
, text
);
1309 INSTALL_CURSOR (nontext_cursor
, nontext
);
1310 INSTALL_CURSOR (hourglass_cursor
, hourglass
);
1311 INSTALL_CURSOR (modeline_cursor
, mode
);
1312 INSTALL_CURSOR (hand_cursor
, hand
);
1313 INSTALL_CURSOR (horizontal_drag_cursor
, horizontal_drag
);
1314 INSTALL_CURSOR (vertical_drag_cursor
, vertical_drag
);
1315 INSTALL_CURSOR (left_edge_cursor
, left_edge
);
1316 INSTALL_CURSOR (top_left_corner_cursor
, top_left_corner
);
1317 INSTALL_CURSOR (top_edge_cursor
, top_edge
);
1318 INSTALL_CURSOR (top_right_corner_cursor
, top_right_corner
);
1319 INSTALL_CURSOR (right_edge_cursor
, right_edge
);
1320 INSTALL_CURSOR (bottom_right_corner_cursor
, bottom_right_corner
);
1321 INSTALL_CURSOR (bottom_edge_cursor
, bottom_edge
);
1322 INSTALL_CURSOR (bottom_left_corner_cursor
, bottom_left_corner
);
1324 #undef INSTALL_CURSOR
1329 update_face_from_frame_parameter (f
, Qmouse_color
, arg
);
1333 x_set_cursor_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1335 unsigned long fore_pixel
, pixel
;
1336 bool fore_pixel_allocated_p
= false, pixel_allocated_p
= false;
1337 struct x_output
*x
= f
->output_data
.x
;
1339 if (!NILP (Vx_cursor_fore_pixel
))
1341 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
1342 WHITE_PIX_DEFAULT (f
));
1343 fore_pixel_allocated_p
= true;
1346 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
1348 pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1349 pixel_allocated_p
= true;
1351 /* Make sure that the cursor color differs from the background color. */
1352 if (pixel
== FRAME_BACKGROUND_PIXEL (f
))
1354 if (pixel_allocated_p
)
1356 x_free_colors (f
, &pixel
, 1);
1357 pixel_allocated_p
= false;
1360 pixel
= x
->mouse_pixel
;
1361 if (pixel
== fore_pixel
)
1363 if (fore_pixel_allocated_p
)
1365 x_free_colors (f
, &fore_pixel
, 1);
1366 fore_pixel_allocated_p
= false;
1368 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
1372 unload_color (f
, x
->cursor_foreground_pixel
);
1373 if (!fore_pixel_allocated_p
)
1374 fore_pixel
= x_copy_color (f
, fore_pixel
);
1375 x
->cursor_foreground_pixel
= fore_pixel
;
1377 unload_color (f
, x
->cursor_pixel
);
1378 if (!pixel_allocated_p
)
1379 pixel
= x_copy_color (f
, pixel
);
1380 x
->cursor_pixel
= pixel
;
1382 if (FRAME_X_WINDOW (f
) != 0)
1385 XSetBackground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, x
->cursor_pixel
);
1386 XSetForeground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, fore_pixel
);
1389 if (FRAME_VISIBLE_P (f
))
1391 x_update_cursor (f
, false);
1392 x_update_cursor (f
, true);
1396 update_face_from_frame_parameter (f
, Qcursor_color
, arg
);
1399 /* Set the border-color of frame F to pixel value PIX.
1400 Note that this does not fully take effect if done before
1401 F has an x-window. */
1404 x_set_border_pixel (struct frame
*f
, int pix
)
1406 unload_color (f
, f
->output_data
.x
->border_pixel
);
1407 f
->output_data
.x
->border_pixel
= pix
;
1409 if (FRAME_X_WINDOW (f
) != 0 && f
->border_width
> 0)
1412 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), pix
);
1415 if (FRAME_VISIBLE_P (f
))
1420 /* Set the border-color of frame F to value described by ARG.
1421 ARG can be a string naming a color.
1422 The border-color is used for the border that is drawn by the X server.
1423 Note that this does not fully take effect if done before
1424 F has an x-window; it must be redone when the window is created.
1426 Note: this is done in two routines because of the way X10 works.
1428 Note: under X11, this is normally the province of the window manager,
1429 and so emacs's border colors may be overridden. */
1432 x_set_border_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1437 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1438 x_set_border_pixel (f
, pix
);
1439 update_face_from_frame_parameter (f
, Qborder_color
, arg
);
1444 x_set_cursor_type (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1446 set_frame_cursor_types (f
, arg
);
1450 x_set_icon_type (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1456 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1459 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1464 result
= x_text_icon (f
,
1465 SSDATA ((!NILP (f
->icon_name
)
1469 result
= x_bitmap_icon (f
, arg
);
1474 error ("No icon window available");
1477 XFlush (FRAME_X_DISPLAY (f
));
1482 x_set_icon_name (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1488 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1491 else if (!NILP (arg
) || NILP (oldval
))
1494 fset_icon_name (f
, arg
);
1496 if (f
->output_data
.x
->icon_bitmap
!= 0)
1501 result
= x_text_icon (f
,
1502 SSDATA ((!NILP (f
->icon_name
)
1511 error ("No icon window available");
1514 XFlush (FRAME_X_DISPLAY (f
));
1520 x_set_menu_bar_lines (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
1523 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
1524 int olines
= FRAME_MENU_BAR_LINES (f
);
1527 /* Right now, menu bars don't work properly in minibuf-only frames;
1528 most of the commands try to apply themselves to the minibuffer
1529 frame itself, and get an error because you can't switch buffers
1530 in or split the minibuffer window. */
1531 if (FRAME_MINIBUF_ONLY_P (f
) || FRAME_PARENT_FRAME (f
))
1534 if (TYPE_RANGED_INTEGERP (int, value
))
1535 nlines
= XINT (value
);
1539 /* Make sure we redisplay all windows in this frame. */
1542 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1543 FRAME_MENU_BAR_LINES (f
) = 0;
1544 FRAME_MENU_BAR_HEIGHT (f
) = 0;
1547 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
1548 if (FRAME_X_P (f
) && f
->output_data
.x
->menubar_widget
== 0)
1549 /* Make sure next redisplay shows the menu bar. */
1550 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= true;
1554 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
1555 free_frame_menubar (f
);
1556 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
1558 f
->output_data
.x
->menubar_widget
= 0;
1560 #else /* not USE_X_TOOLKIT && not USE_GTK */
1561 FRAME_MENU_BAR_LINES (f
) = nlines
;
1562 FRAME_MENU_BAR_HEIGHT (f
) = nlines
* FRAME_LINE_HEIGHT (f
);
1563 adjust_frame_size (f
, -1, -1, 2, true, Qx_set_menu_bar_lines
);
1564 if (FRAME_X_WINDOW (f
))
1565 x_clear_under_internal_border (f
);
1567 /* If the menu bar height gets changed, the internal border below
1568 the top margin has to be cleared. Also, if the menu bar gets
1569 larger, the area for the added lines has to be cleared except for
1570 the first menu bar line that is to be drawn later. */
1571 if (nlines
!= olines
)
1573 int height
= FRAME_INTERNAL_BORDER_WIDTH (f
);
1574 int width
= FRAME_PIXEL_WIDTH (f
);
1577 /* height can be zero here. */
1578 if (FRAME_X_WINDOW (f
) && height
> 0 && width
> 0)
1580 y
= FRAME_TOP_MARGIN_HEIGHT (f
);
1583 x_clear_area (f
, 0, y
, width
, height
);
1587 if (nlines
> 1 && nlines
> olines
)
1589 y
= (olines
== 0 ? 1 : olines
) * FRAME_LINE_HEIGHT (f
);
1590 height
= nlines
* FRAME_LINE_HEIGHT (f
) - y
;
1593 x_clear_area (f
, 0, y
, width
, height
);
1597 if (nlines
== 0 && WINDOWP (f
->menu_bar_window
))
1598 clear_glyph_matrix (XWINDOW (f
->menu_bar_window
)->current_matrix
);
1600 #endif /* not USE_X_TOOLKIT && not USE_GTK */
1601 adjust_frame_glyphs (f
);
1605 /* Set the number of lines used for the tool bar of frame F to VALUE.
1606 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1607 is the old number of tool bar lines. This function changes the
1608 height of all windows on frame F to match the new tool bar height.
1609 The frame's height doesn't change. */
1612 x_set_tool_bar_lines (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
1616 /* Treat tool bars like menu bars. */
1617 if (FRAME_MINIBUF_ONLY_P (f
))
1620 /* Use VALUE only if an int >= 0. */
1621 if (RANGED_INTEGERP (0, value
, INT_MAX
))
1622 nlines
= XFASTINT (value
);
1626 x_change_tool_bar_height (f
, nlines
* FRAME_LINE_HEIGHT (f
));
1630 /* Set the pixel height of the tool bar of frame F to HEIGHT. */
1632 x_change_tool_bar_height (struct frame
*f
, int height
)
1635 FRAME_TOOL_BAR_LINES (f
) = 0;
1636 FRAME_TOOL_BAR_HEIGHT (f
) = 0;
1639 FRAME_EXTERNAL_TOOL_BAR (f
) = true;
1640 if (FRAME_X_P (f
) && f
->output_data
.x
->toolbar_widget
== 0)
1641 /* Make sure next redisplay shows the tool bar. */
1642 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= true;
1643 update_frame_tool_bar (f
);
1647 if (FRAME_EXTERNAL_TOOL_BAR (f
))
1648 free_frame_tool_bar (f
);
1649 FRAME_EXTERNAL_TOOL_BAR (f
) = false;
1651 #else /* !USE_GTK */
1652 int unit
= FRAME_LINE_HEIGHT (f
);
1653 int old_height
= FRAME_TOOL_BAR_HEIGHT (f
);
1654 int lines
= (height
+ unit
- 1) / unit
;
1655 Lisp_Object fullscreen
;
1657 /* Make sure we redisplay all windows in this frame. */
1660 /* Recalculate tool bar and frame text sizes. */
1661 FRAME_TOOL_BAR_HEIGHT (f
) = height
;
1662 FRAME_TOOL_BAR_LINES (f
) = lines
;
1663 /* Store the `tool-bar-lines' and `height' frame parameters. */
1664 store_frame_param (f
, Qtool_bar_lines
, make_number (lines
));
1665 store_frame_param (f
, Qheight
, make_number (FRAME_LINES (f
)));
1667 /* We also have to make sure that the internal border at the top of
1668 the frame, below the menu bar or tool bar, is redrawn when the
1669 tool bar disappears. This is so because the internal border is
1670 below the tool bar if one is displayed, but is below the menu bar
1671 if there isn't a tool bar. The tool bar draws into the area
1672 below the menu bar. */
1673 if (FRAME_X_WINDOW (f
) && FRAME_TOOL_BAR_HEIGHT (f
) == 0)
1676 clear_current_matrices (f
);
1679 if ((height
< old_height
) && WINDOWP (f
->tool_bar_window
))
1680 clear_glyph_matrix (XWINDOW (f
->tool_bar_window
)->current_matrix
);
1682 /* Recalculate toolbar height. */
1683 f
->n_tool_bar_rows
= 0;
1685 && (!f
->after_make_frame
1686 || NILP (frame_inhibit_implied_resize
)
1687 || (CONSP (frame_inhibit_implied_resize
)
1688 && NILP (Fmemq (Qtool_bar_lines
, frame_inhibit_implied_resize
)))))
1689 f
->tool_bar_redisplayed
= f
->tool_bar_resized
= false;
1691 adjust_frame_size (f
, -1, -1,
1692 ((!f
->tool_bar_resized
1693 && (NILP (fullscreen
=
1694 get_frame_param (f
, Qfullscreen
))
1695 || EQ (fullscreen
, Qfullwidth
))) ? 1
1696 : (old_height
== 0 || height
== 0) ? 2
1698 false, Qtool_bar_lines
);
1700 f
->tool_bar_resized
= f
->tool_bar_redisplayed
;
1702 /* adjust_frame_size might not have done anything, garbage frame
1704 adjust_frame_glyphs (f
);
1705 SET_FRAME_GARBAGED (f
);
1706 if (FRAME_X_WINDOW (f
))
1707 x_clear_under_internal_border (f
);
1709 #endif /* USE_GTK */
1714 x_set_internal_border_width (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1718 CHECK_TYPE_RANGED_INTEGER (int, arg
);
1719 border
= max (XINT (arg
), 0);
1721 if (border
!= FRAME_INTERNAL_BORDER_WIDTH (f
))
1723 f
->internal_border_width
= border
;
1725 #ifdef USE_X_TOOLKIT
1726 if (FRAME_X_OUTPUT (f
)->edit_widget
)
1727 widget_store_internal_border (FRAME_X_OUTPUT (f
)->edit_widget
);
1730 if (FRAME_X_WINDOW (f
))
1732 adjust_frame_size (f
, -1, -1, 3, false, Qinternal_border_width
);
1733 x_clear_under_internal_border (f
);
1740 /* Set the foreground color for scroll bars on frame F to VALUE.
1741 VALUE should be a string, a color name. If it isn't a string or
1742 isn't a valid color name, do nothing. OLDVAL is the old value of
1743 the frame parameter. */
1746 x_set_scroll_bar_foreground (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
1748 unsigned long pixel
;
1750 if (STRINGP (value
))
1751 pixel
= x_decode_color (f
, value
, BLACK_PIX_DEFAULT (f
));
1755 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
1756 unload_color (f
, f
->output_data
.x
->scroll_bar_foreground_pixel
);
1758 f
->output_data
.x
->scroll_bar_foreground_pixel
= pixel
;
1759 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1761 /* Remove all scroll bars because they have wrong colors. */
1762 if (FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
)
1763 (*FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
) (f
);
1764 if (FRAME_TERMINAL (f
)->judge_scroll_bars_hook
)
1765 (*FRAME_TERMINAL (f
)->judge_scroll_bars_hook
) (f
);
1767 update_face_from_frame_parameter (f
, Qscroll_bar_foreground
, value
);
1773 /* Set the background color for scroll bars on frame F to VALUE VALUE
1774 should be a string, a color name. If it isn't a string or isn't a
1775 valid color name, do nothing. OLDVAL is the old value of the frame
1779 x_set_scroll_bar_background (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
1781 unsigned long pixel
;
1783 if (STRINGP (value
))
1784 pixel
= x_decode_color (f
, value
, WHITE_PIX_DEFAULT (f
));
1788 if (f
->output_data
.x
->scroll_bar_background_pixel
!= -1)
1789 unload_color (f
, f
->output_data
.x
->scroll_bar_background_pixel
);
1791 #if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
1792 /* Scrollbar shadow colors. */
1793 if (f
->output_data
.x
->scroll_bar_top_shadow_pixel
!= -1)
1795 unload_color (f
, f
->output_data
.x
->scroll_bar_top_shadow_pixel
);
1796 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
1798 if (f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
!= -1)
1800 unload_color (f
, f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
);
1801 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
1803 #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
1805 f
->output_data
.x
->scroll_bar_background_pixel
= pixel
;
1806 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1808 /* Remove all scroll bars because they have wrong colors. */
1809 if (FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
)
1810 (*FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
) (f
);
1811 if (FRAME_TERMINAL (f
)->judge_scroll_bars_hook
)
1812 (*FRAME_TERMINAL (f
)->judge_scroll_bars_hook
) (f
);
1814 update_face_from_frame_parameter (f
, Qscroll_bar_background
, value
);
1820 /* Encode Lisp string STRING as a text in a format appropriate for
1821 XICCC (X Inter Client Communication Conventions).
1823 If STRING contains only ASCII characters, do no conversion and
1824 return the string data of STRING. Otherwise, encode the text by
1825 CODING_SYSTEM, and return a newly allocated memory area which
1826 should be freed by `xfree' by a caller.
1828 Store the byte length of resulting text in *TEXT_BYTES.
1830 If the text contains only ASCII and Latin-1, store true in *STRING_P,
1831 which means that the `encoding' of the result can be `STRING'.
1832 Otherwise store false in *STRINGP, which means that the `encoding' of
1833 the result should be `COMPOUND_TEXT'. */
1835 static unsigned char *
1836 x_encode_text (Lisp_Object string
, Lisp_Object coding_system
,
1837 ptrdiff_t *text_bytes
, bool *stringp
, bool *freep
)
1839 int result
= string_xstring_p (string
);
1840 struct coding_system coding
;
1844 /* No multibyte character in OBJ. We need not encode it. */
1845 *text_bytes
= SBYTES (string
);
1848 return SDATA (string
);
1851 setup_coding_system (coding_system
, &coding
);
1852 coding
.mode
|= (CODING_MODE_SAFE_ENCODING
| CODING_MODE_LAST_BLOCK
);
1853 /* We suppress producing escape sequences for composition. */
1854 coding
.common_flags
&= ~CODING_ANNOTATION_MASK
;
1855 coding
.destination
= xnmalloc (SCHARS (string
), 2);
1856 coding
.dst_bytes
= SCHARS (string
) * 2;
1857 encode_coding_object (&coding
, string
, 0, 0,
1858 SCHARS (string
), SBYTES (string
), Qnil
);
1859 *text_bytes
= coding
.produced
;
1860 *stringp
= (result
== 1 || !EQ (coding_system
, Qcompound_text
));
1862 return coding
.destination
;
1866 /* Set the WM name to NAME for frame F. Also set the icon name.
1867 If the frame already has an icon name, use that, otherwise set the
1868 icon name to NAME. */
1871 x_set_name_internal (struct frame
*f
, Lisp_Object name
)
1873 if (FRAME_X_WINDOW (f
))
1877 XTextProperty text
, icon
;
1880 bool do_free_icon_value
= false, do_free_text_value
= false;
1881 Lisp_Object coding_system
;
1882 Lisp_Object encoded_name
;
1883 Lisp_Object encoded_icon_name
;
1885 /* As ENCODE_UTF_8 may cause GC and relocation of string data,
1886 we use it before x_encode_text that may return string data. */
1887 encoded_name
= ENCODE_UTF_8 (name
);
1889 coding_system
= Qcompound_text
;
1890 /* Note: Encoding strategy
1892 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1893 text.encoding. But, there are non-internationalized window
1894 managers which don't support that encoding. So, if NAME
1895 contains only ASCII and 8859-1 characters, encode it by
1896 iso-latin-1, and use "STRING" in text.encoding hoping that
1897 such window managers at least analyze this format correctly,
1898 i.e. treat 8-bit bytes as 8859-1 characters.
1900 We may also be able to use "UTF8_STRING" in text.encoding
1901 in the future which can encode all Unicode characters.
1902 But, for the moment, there's no way to know that the
1903 current window manager supports it or not.
1905 Either way, we also set the _NET_WM_NAME and _NET_WM_ICON_NAME
1906 properties. Per the EWMH specification, those two properties
1907 are always UTF8_STRING. This matches what gtk_window_set_title()
1908 does in the USE_GTK case. */
1909 text
.value
= x_encode_text (name
, coding_system
, &bytes
,
1910 &stringp
, &do_free_text_value
);
1911 text
.encoding
= (stringp
? XA_STRING
1912 : FRAME_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1914 text
.nitems
= bytes
;
1916 if (!STRINGP (f
->icon_name
))
1919 encoded_icon_name
= encoded_name
;
1923 /* See the above comment "Note: Encoding strategy". */
1924 icon
.value
= x_encode_text (f
->icon_name
, coding_system
, &bytes
,
1925 &stringp
, &do_free_icon_value
);
1926 icon
.encoding
= (stringp
? XA_STRING
1927 : FRAME_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1929 icon
.nitems
= bytes
;
1931 encoded_icon_name
= ENCODE_UTF_8 (f
->icon_name
);
1935 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
1936 SSDATA (encoded_name
));
1937 #else /* not USE_GTK */
1938 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &text
);
1939 XChangeProperty (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
1940 FRAME_DISPLAY_INFO (f
)->Xatom_net_wm_name
,
1941 FRAME_DISPLAY_INFO (f
)->Xatom_UTF8_STRING
,
1943 SDATA (encoded_name
),
1944 SBYTES (encoded_name
));
1945 #endif /* not USE_GTK */
1947 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &icon
);
1948 XChangeProperty (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
1949 FRAME_DISPLAY_INFO (f
)->Xatom_net_wm_icon_name
,
1950 FRAME_DISPLAY_INFO (f
)->Xatom_UTF8_STRING
,
1952 SDATA (encoded_icon_name
),
1953 SBYTES (encoded_icon_name
));
1955 if (do_free_icon_value
)
1957 if (do_free_text_value
)
1964 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1967 If EXPLICIT is true, that indicates that lisp code is setting the
1968 name; if NAME is a string, set F's name to NAME and set
1969 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1971 If EXPLICIT is false, that indicates that Emacs redisplay code is
1972 suggesting a new name, which lisp code should override; if
1973 F->explicit_name is set, ignore the new name; otherwise, set it. */
1976 x_set_name (struct frame
*f
, Lisp_Object name
, bool explicit)
1978 /* Make sure that requests from lisp code override requests from
1979 Emacs redisplay code. */
1982 /* If we're switching from explicit to implicit, we had better
1983 update the mode lines and thereby update the title. */
1984 if (f
->explicit_name
&& NILP (name
))
1985 update_mode_lines
= 37;
1987 f
->explicit_name
= ! NILP (name
);
1989 else if (f
->explicit_name
)
1992 /* If NAME is nil, set the name to the x_id_name. */
1995 /* Check for no change needed in this very common case
1996 before we do any consing. */
1997 if (!strcmp (FRAME_DISPLAY_INFO (f
)->x_id_name
,
2000 name
= build_string (FRAME_DISPLAY_INFO (f
)->x_id_name
);
2003 CHECK_STRING (name
);
2005 /* Don't change the name if it's already NAME. */
2006 if (! NILP (Fstring_equal (name
, f
->name
)))
2009 fset_name (f
, name
);
2011 /* For setting the frame title, the title parameter should override
2012 the name parameter. */
2013 if (! NILP (f
->title
))
2016 x_set_name_internal (f
, name
);
2019 /* This function should be called when the user's lisp code has
2020 specified a name for the frame; the name will override any set by the
2023 x_explicitly_set_name (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
2025 x_set_name (f
, arg
, true);
2028 /* This function should be called by Emacs redisplay code to set the
2029 name; names set this way will never override names set by the user's
2032 x_implicitly_set_name (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
2034 x_set_name (f
, arg
, false);
2037 /* Change the title of frame F to NAME.
2038 If NAME is nil, use the frame name as the title. */
2041 x_set_title (struct frame
*f
, Lisp_Object name
, Lisp_Object old_name
)
2043 /* Don't change the title if it's already NAME. */
2044 if (EQ (name
, f
->title
))
2047 update_mode_lines
= 38;
2049 fset_title (f
, name
);
2054 CHECK_STRING (name
);
2056 x_set_name_internal (f
, name
);
2060 x_set_scroll_bar_default_width (struct frame
*f
)
2062 int unit
= FRAME_COLUMN_WIDTH (f
);
2063 #ifdef USE_TOOLKIT_SCROLL_BARS
2065 int minw
= xg_get_default_scrollbar_width (f
);
2069 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
2070 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (minw
+ unit
- 1) / unit
;
2071 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = minw
;
2073 /* The width of a non-toolkit scrollbar is 14 pixels. */
2074 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + unit
- 1) / unit
;
2075 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
)
2076 = FRAME_CONFIG_SCROLL_BAR_COLS (f
) * unit
;
2081 x_set_scroll_bar_default_height (struct frame
*f
)
2083 int height
= FRAME_LINE_HEIGHT (f
);
2084 #ifdef USE_TOOLKIT_SCROLL_BARS
2086 int min_height
= xg_get_default_scrollbar_height (f
);
2088 int min_height
= 16;
2090 /* A minimum height of 14 doesn't look good for toolkit scroll bars. */
2091 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f
) = min_height
;
2092 FRAME_CONFIG_SCROLL_BAR_LINES (f
) = (min_height
+ height
- 1) / height
;
2094 /* The height of a non-toolkit scrollbar is 14 pixels. */
2095 FRAME_CONFIG_SCROLL_BAR_LINES (f
) = (14 + height
- 1) / height
;
2097 /* Use all of that space (aside from required margins) for the
2099 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f
) = 14;
2104 /* Record in frame F the specified or default value according to ALIST
2105 of the parameter named PROP (a Lisp symbol). If no value is
2106 specified for PROP, look for an X default for XPROP on the frame
2107 named NAME. If that is not found either, use the value DEFLT. */
2110 x_default_scroll_bar_color_parameter (struct frame
*f
,
2111 Lisp_Object alist
, Lisp_Object prop
,
2112 const char *xprop
, const char *xclass
,
2115 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
2118 tem
= x_get_arg (dpyinfo
, alist
, prop
, xprop
, xclass
, RES_TYPE_STRING
);
2119 if (EQ (tem
, Qunbound
))
2121 #ifdef USE_TOOLKIT_SCROLL_BARS
2123 /* See if an X resource for the scroll bar color has been
2125 AUTO_STRING (foreground
, "foreground");
2126 AUTO_STRING (background
, "foreground");
2127 AUTO_STRING (verticalScrollBar
, "verticalScrollBar");
2128 tem
= (display_x_get_resource
2129 (dpyinfo
, foreground_p
? foreground
: background
,
2130 empty_unibyte_string
,
2132 empty_unibyte_string
));
2135 /* If nothing has been specified, scroll bars will use a
2136 toolkit-dependent default. Because these defaults are
2137 difficult to get at without actually creating a scroll
2138 bar, use nil to indicate that no color has been
2143 #else /* not USE_TOOLKIT_SCROLL_BARS */
2147 #endif /* not USE_TOOLKIT_SCROLL_BARS */
2150 AUTO_FRAME_ARG (arg
, prop
, tem
);
2151 x_set_frame_parameters (f
, arg
);
2158 #ifdef USE_X_TOOLKIT
2160 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
2161 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
2162 already be present because of the toolkit (Motif adds some of them,
2163 for example, but Xt doesn't). */
2166 hack_wm_protocols (struct frame
*f
, Widget widget
)
2168 Display
*dpy
= XtDisplay (widget
);
2169 Window w
= XtWindow (widget
);
2170 bool need_delete
= true;
2171 bool need_focus
= true;
2172 bool need_save
= true;
2177 unsigned char *catoms
;
2179 unsigned long nitems
= 0;
2180 unsigned long bytes_after
;
2182 if ((XGetWindowProperty (dpy
, w
,
2183 FRAME_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2184 0, 100, False
, XA_ATOM
,
2185 &type
, &format
, &nitems
, &bytes_after
,
2188 && format
== 32 && type
== XA_ATOM
)
2190 Atom
*atoms
= (Atom
*) catoms
;
2195 == FRAME_DISPLAY_INFO (f
)->Xatom_wm_delete_window
)
2196 need_delete
= false;
2197 else if (atoms
[nitems
]
2198 == FRAME_DISPLAY_INFO (f
)->Xatom_wm_take_focus
)
2200 else if (atoms
[nitems
]
2201 == FRAME_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
)
2212 props
[count
++] = FRAME_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2214 props
[count
++] = FRAME_DISPLAY_INFO (f
)->Xatom_wm_take_focus
;
2216 props
[count
++] = FRAME_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2218 XChangeProperty (dpy
, w
, FRAME_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2219 XA_ATOM
, 32, PropModeAppend
,
2220 (unsigned char *) props
, count
);
2228 /* Support routines for XIC (X Input Context). */
2232 static XFontSet
xic_create_xfontset (struct frame
*);
2233 static XIMStyle
best_xim_style (XIMStyles
*);
2236 /* Supported XIM styles, ordered by preference. */
2238 static const XIMStyle supported_xim_styles
[] =
2240 XIMPreeditPosition
| XIMStatusArea
,
2241 XIMPreeditPosition
| XIMStatusNothing
,
2242 XIMPreeditPosition
| XIMStatusNone
,
2243 XIMPreeditNothing
| XIMStatusArea
,
2244 XIMPreeditNothing
| XIMStatusNothing
,
2245 XIMPreeditNothing
| XIMStatusNone
,
2246 XIMPreeditNone
| XIMStatusArea
,
2247 XIMPreeditNone
| XIMStatusNothing
,
2248 XIMPreeditNone
| XIMStatusNone
,
2253 #if defined HAVE_X_WINDOWS && defined USE_X_TOOLKIT
2254 /* Create an X fontset on frame F with base font name BASE_FONTNAME. */
2256 static const char xic_default_fontset
[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
2258 /* Create an Xt fontset spec from the name of a base font.
2259 If `motif' is True use the Motif syntax. */
2261 xic_create_fontsetname (const char *base_fontname
, bool motif
)
2263 const char *sep
= motif
? ";" : ",";
2267 /* Make a fontset name from the base font name. */
2268 if (xic_default_fontset
== base_fontname
)
2270 /* There is no base font name, use the default. */
2271 fontsetname
= xmalloc (strlen (base_fontname
) + 2);
2272 z
= stpcpy (fontsetname
, base_fontname
);
2276 /* Make a fontset name from the base font name.
2277 The font set will be made of the following elements:
2279 - the base font where the charset spec is replaced by -*-*.
2280 - the same but with the family also replaced with -*-*-. */
2281 const char *p
= base_fontname
;
2284 for (i
= 0; *p
; p
++)
2288 /* As the font name doesn't conform to XLFD, we can't
2289 modify it to generalize it to allcs and allfamilies.
2290 Use the specified font plus the default. */
2291 fontsetname
= xmalloc (strlen (base_fontname
)
2292 + strlen (xic_default_fontset
) + 3);
2293 z
= stpcpy (fontsetname
, base_fontname
);
2294 z
= stpcpy (z
, sep
);
2295 z
= stpcpy (z
, xic_default_fontset
);
2300 const char *p1
= NULL
, *p2
= NULL
, *p3
= NULL
;
2301 char *font_allcs
= NULL
;
2302 char *font_allfamilies
= NULL
;
2303 char *font_all
= NULL
;
2304 const char *allcs
= "*-*-*-*-*-*-*";
2305 const char *allfamilies
= "-*-*-";
2306 const char *all
= "*-*-*-*-";
2309 for (i
= 0, p
= base_fontname
; i
< 8; p
++)
2322 /* If base_fontname specifies ADSTYLE, make it a
2326 ptrdiff_t diff
= (p2
- p3
) - 2;
2328 base
= alloca (strlen (base_fontname
) + 1);
2329 memcpy (base
, base_fontname
, p3
- base_fontname
);
2330 base
[p3
- base_fontname
] = '*';
2331 base
[(p3
- base_fontname
) + 1] = '-';
2332 strcpy (base
+ (p3
- base_fontname
) + 2, p2
);
2333 p
= base
+ (p
- base_fontname
) - diff
;
2334 p1
= base
+ (p1
- base_fontname
);
2335 p2
= base
+ (p2
- base_fontname
) - diff
;
2336 base_fontname
= base
;
2339 /* Build the font spec that matches all charsets. */
2340 len
= p
- base_fontname
+ strlen (allcs
) + 1;
2341 font_allcs
= alloca (len
);
2342 memcpy (font_allcs
, base_fontname
, p
- base_fontname
);
2343 strcpy (font_allcs
+ (p
- base_fontname
), allcs
);
2345 /* Build the font spec that matches all families and
2347 len
= p
- p1
+ strlen (allcs
) + strlen (allfamilies
) + 1;
2348 font_allfamilies
= alloca (len
);
2349 strcpy (font_allfamilies
, allfamilies
);
2350 memcpy (font_allfamilies
+ strlen (allfamilies
), p1
, p
- p1
);
2351 strcpy (font_allfamilies
+ strlen (allfamilies
) + (p
- p1
), allcs
);
2353 /* Build the font spec that matches all. */
2354 len
= p
- p2
+ strlen (allcs
) + strlen (all
) + strlen (allfamilies
) + 1;
2355 font_all
= alloca (len
);
2356 z
= stpcpy (font_all
, allfamilies
);
2357 z
= stpcpy (z
, all
);
2358 memcpy (z
, p2
, p
- p2
);
2359 strcpy (z
+ (p
- p2
), allcs
);
2361 /* Build the actual font set name. */
2362 len
= strlen (base_fontname
) + strlen (font_allcs
)
2363 + strlen (font_allfamilies
) + strlen (font_all
) + 5;
2364 fontsetname
= xmalloc (len
);
2365 z
= stpcpy (fontsetname
, base_fontname
);
2366 z
= stpcpy (z
, sep
);
2367 z
= stpcpy (z
, font_allcs
);
2368 z
= stpcpy (z
, sep
);
2369 z
= stpcpy (z
, font_allfamilies
);
2370 z
= stpcpy (z
, sep
);
2371 z
= stpcpy (z
, font_all
);
2378 #endif /* HAVE_X_WINDOWS && USE_X_TOOLKIT */
2380 #ifdef DEBUG_XIC_FONTSET
2382 print_fontset_result (XFontSet xfs
, char *name
, char **missing_list
,
2386 fprintf (stderr
, "XIC Fontset created: %s\n", name
);
2389 fprintf (stderr
, "XIC Fontset failed: %s\n", name
);
2390 while (missing_count
-- > 0)
2392 fprintf (stderr
, " missing: %s\n", *missing_list
);
2401 xic_create_xfontset (struct frame
*f
)
2403 XFontSet xfs
= NULL
;
2404 struct font
*font
= FRAME_FONT (f
);
2405 int pixel_size
= font
->pixel_size
;
2406 Lisp_Object rest
, frame
;
2408 /* See if there is another frame already using same fontset. */
2409 FOR_EACH_FRAME (rest
, frame
)
2411 struct frame
*cf
= XFRAME (frame
);
2413 if (cf
!= f
&& FRAME_LIVE_P (f
) && FRAME_X_P (cf
)
2414 && FRAME_DISPLAY_INFO (cf
) == FRAME_DISPLAY_INFO (f
)
2416 && FRAME_FONT (f
)->pixel_size
== pixel_size
)
2418 xfs
= FRAME_XIC_FONTSET (cf
);
2426 char **missing_list
;
2429 const char *xlfd_format
= "-*-*-medium-r-normal--%d-*-*-*-*-*";
2431 sprintf (buf
, xlfd_format
, pixel_size
);
2432 missing_list
= NULL
;
2433 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
), buf
,
2434 &missing_list
, &missing_count
, &def_string
);
2435 #ifdef DEBUG_XIC_FONTSET
2436 print_fontset_result (xfs
, buf
, missing_list
, missing_count
);
2439 XFreeStringList (missing_list
);
2442 /* List of pixel sizes most likely available. Find one that
2443 is closest to pixel_size. */
2444 int sizes
[] = {0, 8, 10, 11, 12, 14, 17, 18, 20, 24, 26, 34, 0};
2445 int *smaller
, *larger
;
2447 for (smaller
= sizes
; smaller
[1]; smaller
++)
2448 if (smaller
[1] >= pixel_size
)
2450 larger
= smaller
+ 1;
2451 if (*larger
== pixel_size
)
2453 while (*smaller
|| *larger
)
2458 this_size
= *smaller
--;
2459 else if (! *smaller
)
2460 this_size
= *larger
++;
2461 else if (pixel_size
- *smaller
< *larger
- pixel_size
)
2462 this_size
= *smaller
--;
2464 this_size
= *larger
++;
2465 sprintf (buf
, xlfd_format
, this_size
);
2466 missing_list
= NULL
;
2467 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
), buf
,
2468 &missing_list
, &missing_count
, &def_string
);
2469 #ifdef DEBUG_XIC_FONTSET
2470 print_fontset_result (xfs
, buf
, missing_list
, missing_count
);
2473 XFreeStringList (missing_list
);
2480 const char *last_resort
= "-*-*-*-r-normal--*-*-*-*-*-*";
2482 missing_list
= NULL
;
2483 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
), last_resort
,
2484 &missing_list
, &missing_count
, &def_string
);
2485 #ifdef DEBUG_XIC_FONTSET
2486 print_fontset_result (xfs
, last_resort
, missing_list
, missing_count
);
2489 XFreeStringList (missing_list
);
2497 /* Free the X fontset of frame F if it is the last frame using it. */
2500 xic_free_xfontset (struct frame
*f
)
2502 Lisp_Object rest
, frame
;
2503 bool shared_p
= false;
2505 if (!FRAME_XIC_FONTSET (f
))
2508 /* See if there is another frame sharing the same fontset. */
2509 FOR_EACH_FRAME (rest
, frame
)
2511 struct frame
*cf
= XFRAME (frame
);
2512 if (cf
!= f
&& FRAME_LIVE_P (f
) && FRAME_X_P (cf
)
2513 && FRAME_DISPLAY_INFO (cf
) == FRAME_DISPLAY_INFO (f
)
2514 && FRAME_XIC_FONTSET (cf
) == FRAME_XIC_FONTSET (f
))
2522 /* The fontset is not used anymore. It is safe to free it. */
2523 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
2525 FRAME_XIC_FONTSET (f
) = NULL
;
2529 /* Value is the best input style, given user preferences USER (already
2530 checked to be supported by Emacs), and styles supported by the
2531 input method XIM. */
2534 best_xim_style (XIMStyles
*xim
)
2537 int nr_supported
= ARRAYELTS (supported_xim_styles
);
2539 for (i
= 0; i
< nr_supported
; ++i
)
2540 for (j
= 0; j
< xim
->count_styles
; ++j
)
2541 if (supported_xim_styles
[i
] == xim
->supported_styles
[j
])
2542 return supported_xim_styles
[i
];
2544 /* Return the default style. */
2545 return XIMPreeditNothing
| XIMStatusNothing
;
2548 /* Create XIC for frame F. */
2551 create_frame_xic (struct frame
*f
)
2555 XFontSet xfs
= NULL
;
2556 XVaNestedList status_attr
= NULL
;
2557 XVaNestedList preedit_attr
= NULL
;
2565 xim
= FRAME_X_XIM (f
);
2569 /* Determine XIC style. */
2570 xic_style
= best_xim_style (FRAME_X_XIM_STYLES (f
));
2572 /* Create X fontset. */
2573 if (xic_style
& (XIMPreeditPosition
| XIMStatusArea
))
2575 xfs
= xic_create_xfontset (f
);
2579 FRAME_XIC_FONTSET (f
) = xfs
;
2582 if (xic_style
& XIMPreeditPosition
)
2584 spot
.x
= 0; spot
.y
= 1;
2585 preedit_attr
= XVaCreateNestedList (0,
2588 FRAME_FOREGROUND_PIXEL (f
),
2590 FRAME_BACKGROUND_PIXEL (f
),
2591 (xic_style
& XIMPreeditPosition
2601 if (xic_style
& XIMStatusArea
)
2603 s_area
.x
= 0; s_area
.y
= 0; s_area
.width
= 1; s_area
.height
= 1;
2604 status_attr
= XVaCreateNestedList (0,
2610 FRAME_FOREGROUND_PIXEL (f
),
2612 FRAME_BACKGROUND_PIXEL (f
),
2619 if (preedit_attr
&& status_attr
)
2620 xic
= XCreateIC (xim
,
2621 XNInputStyle
, xic_style
,
2622 XNClientWindow
, FRAME_X_WINDOW (f
),
2623 XNFocusWindow
, FRAME_X_WINDOW (f
),
2624 XNStatusAttributes
, status_attr
,
2625 XNPreeditAttributes
, preedit_attr
,
2627 else if (preedit_attr
)
2628 xic
= XCreateIC (xim
,
2629 XNInputStyle
, xic_style
,
2630 XNClientWindow
, FRAME_X_WINDOW (f
),
2631 XNFocusWindow
, FRAME_X_WINDOW (f
),
2632 XNPreeditAttributes
, preedit_attr
,
2634 else if (status_attr
)
2635 xic
= XCreateIC (xim
,
2636 XNInputStyle
, xic_style
,
2637 XNClientWindow
, FRAME_X_WINDOW (f
),
2638 XNFocusWindow
, FRAME_X_WINDOW (f
),
2639 XNStatusAttributes
, status_attr
,
2642 xic
= XCreateIC (xim
,
2643 XNInputStyle
, xic_style
,
2644 XNClientWindow
, FRAME_X_WINDOW (f
),
2645 XNFocusWindow
, FRAME_X_WINDOW (f
),
2651 FRAME_XIC (f
) = xic
;
2652 FRAME_XIC_STYLE (f
) = xic_style
;
2653 xfs
= NULL
; /* Don't free below. */
2661 XFree (preedit_attr
);
2664 XFree (status_attr
);
2668 /* Destroy XIC and free XIC fontset of frame F, if any. */
2671 free_frame_xic (struct frame
*f
)
2673 if (FRAME_XIC (f
) == NULL
)
2676 XDestroyIC (FRAME_XIC (f
));
2677 xic_free_xfontset (f
);
2679 FRAME_XIC (f
) = NULL
;
2683 /* Place preedit area for XIC of window W's frame to specified
2684 pixel position X/Y. X and Y are relative to window W. */
2687 xic_set_preeditarea (struct window
*w
, int x
, int y
)
2689 struct frame
*f
= XFRAME (w
->frame
);
2693 spot
.x
= WINDOW_TO_FRAME_PIXEL_X (w
, x
) + WINDOW_LEFT_FRINGE_WIDTH (w
);
2694 spot
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, y
) + FONT_BASE (FRAME_FONT (f
));
2695 attr
= XVaCreateNestedList (0, XNSpotLocation
, &spot
, NULL
);
2696 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2701 /* Place status area for XIC in bottom right corner of frame F.. */
2704 xic_set_statusarea (struct frame
*f
)
2706 XIC xic
= FRAME_XIC (f
);
2711 /* Negotiate geometry of status area. If input method has existing
2712 status area, use its current size. */
2713 area
.x
= area
.y
= area
.width
= area
.height
= 0;
2714 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &area
, NULL
);
2715 XSetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2718 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &needed
, NULL
);
2719 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2722 if (needed
->width
== 0) /* Use XNArea instead of XNAreaNeeded */
2724 attr
= XVaCreateNestedList (0, XNArea
, &needed
, NULL
);
2725 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2729 area
.width
= needed
->width
;
2730 area
.height
= needed
->height
;
2731 area
.x
= FRAME_PIXEL_WIDTH (f
) - area
.width
- FRAME_INTERNAL_BORDER_WIDTH (f
);
2732 area
.y
= (FRAME_PIXEL_HEIGHT (f
) - area
.height
2733 - FRAME_MENUBAR_HEIGHT (f
)
2734 - FRAME_TOOLBAR_TOP_HEIGHT (f
)
2735 - FRAME_INTERNAL_BORDER_WIDTH (f
));
2738 attr
= XVaCreateNestedList (0, XNArea
, &area
, NULL
);
2739 XSetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2744 /* Set X fontset for XIC of frame F, using base font name
2745 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2748 xic_set_xfontset (struct frame
*f
, const char *base_fontname
)
2753 xic_free_xfontset (f
);
2755 xfs
= xic_create_xfontset (f
);
2757 attr
= XVaCreateNestedList (0, XNFontSet
, xfs
, NULL
);
2758 if (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
)
2759 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2760 if (FRAME_XIC_STYLE (f
) & XIMStatusArea
)
2761 XSetICValues (FRAME_XIC (f
), XNStatusAttributes
, attr
, NULL
);
2764 FRAME_XIC_FONTSET (f
) = xfs
;
2767 #endif /* HAVE_X_I18N */
2773 x_mark_frame_dirty (struct frame
*f
)
2775 if (FRAME_X_DOUBLE_BUFFERED_P (f
) && !FRAME_X_NEED_BUFFER_FLIP (f
))
2776 FRAME_X_NEED_BUFFER_FLIP (f
) = true;
2780 set_up_x_back_buffer (struct frame
*f
)
2784 if (FRAME_X_WINDOW (f
) && !FRAME_X_DOUBLE_BUFFERED_P (f
))
2786 FRAME_X_RAW_DRAWABLE (f
) = FRAME_X_WINDOW (f
);
2787 if (FRAME_DISPLAY_INFO (f
)->supports_xdbe
)
2789 /* If allocating a back buffer fails, either because the
2790 server ran out of memory or we don't have the right kind
2791 of visual, just use single-buffered rendering. */
2792 x_catch_errors (FRAME_X_DISPLAY (f
));
2793 FRAME_X_RAW_DRAWABLE (f
) = XdbeAllocateBackBufferName (
2794 FRAME_X_DISPLAY (f
),
2797 if (x_had_errors_p (FRAME_X_DISPLAY (f
)))
2798 FRAME_X_RAW_DRAWABLE (f
) = FRAME_X_WINDOW (f
);
2799 x_uncatch_errors_after_check ();
2807 tear_down_x_back_buffer (struct frame
*f
)
2811 if (FRAME_X_WINDOW (f
) && FRAME_X_DOUBLE_BUFFERED_P (f
))
2813 if (FRAME_X_DOUBLE_BUFFERED_P (f
))
2815 XdbeDeallocateBackBufferName (FRAME_X_DISPLAY (f
),
2816 FRAME_X_DRAWABLE (f
));
2817 FRAME_X_RAW_DRAWABLE (f
) = FRAME_X_WINDOW (f
);
2824 /* Set up double buffering if the frame parameters don't prohibit
2827 initial_set_up_x_back_buffer (struct frame
*f
)
2830 eassert (FRAME_X_WINDOW (f
));
2831 FRAME_X_RAW_DRAWABLE (f
) = FRAME_X_WINDOW (f
);
2832 if (NILP (CDR (Fassq (Qinhibit_double_buffering
, f
->param_alist
))))
2833 set_up_x_back_buffer (f
);
2837 #ifdef USE_X_TOOLKIT
2839 /* Create and set up the X widget for frame F. */
2842 x_window (struct frame
*f
, long window_prompting
)
2844 XClassHint class_hints
;
2845 XSetWindowAttributes attributes
;
2846 unsigned long attribute_mask
;
2847 Widget shell_widget
;
2849 Widget frame_widget
;
2855 /* Use the resource name as the top-level widget name
2856 for looking up resources. Make a non-Lisp copy
2857 for the window manager, so GC relocation won't bother it.
2859 Elsewhere we specify the window name for the window manager. */
2860 f
->namebuf
= xlispstrdup (Vx_resource_name
);
2863 XtSetArg (al
[ac
], XtNallowShellResize
, 1); ac
++;
2864 XtSetArg (al
[ac
], XtNinput
, 1); ac
++;
2865 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2866 XtSetArg (al
[ac
], XtNborderWidth
, f
->border_width
); ac
++;
2867 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2868 XtSetArg (al
[ac
], XtNdepth
, FRAME_DISPLAY_INFO (f
)->n_planes
); ac
++;
2869 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2870 shell_widget
= XtAppCreateShell (f
->namebuf
, EMACS_CLASS
,
2871 applicationShellWidgetClass
,
2872 FRAME_X_DISPLAY (f
), al
, ac
);
2874 f
->output_data
.x
->widget
= shell_widget
;
2875 /* maybe_set_screen_title_format (shell_widget); */
2877 pane_widget
= lw_create_widget ("main", "pane", widget_id_tick
++,
2878 NULL
, shell_widget
, False
,
2879 NULL
, NULL
, NULL
, NULL
);
2882 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2883 XtSetArg (al
[ac
], XtNdepth
, FRAME_DISPLAY_INFO (f
)->n_planes
); ac
++;
2884 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2885 XtSetArg (al
[ac
], XtNborderWidth
, 0); ac
++;
2886 XtSetValues (pane_widget
, al
, ac
);
2887 f
->output_data
.x
->column_widget
= pane_widget
;
2889 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2890 the emacs screen when changing menubar. This reduces flickering. */
2893 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2894 XtSetArg (al
[ac
], (char *) XtNshowGrip
, 0); ac
++;
2895 XtSetArg (al
[ac
], (char *) XtNallowResize
, 1); ac
++;
2896 XtSetArg (al
[ac
], (char *) XtNresizeToPreferred
, 1); ac
++;
2897 XtSetArg (al
[ac
], (char *) XtNemacsFrame
, f
); ac
++;
2898 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2899 XtSetArg (al
[ac
], XtNdepth
, FRAME_DISPLAY_INFO (f
)->n_planes
); ac
++;
2900 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2901 XtSetArg (al
[ac
], XtNborderWidth
, 0); ac
++;
2902 frame_widget
= XtCreateWidget (f
->namebuf
, emacsFrameClass (), pane_widget
,
2905 f
->output_data
.x
->edit_widget
= frame_widget
;
2907 XtManageChild (frame_widget
);
2909 /* Do some needed geometry management. */
2913 int extra_borders
= 0;
2915 = (f
->output_data
.x
->menubar_widget
2916 ? (f
->output_data
.x
->menubar_widget
->core
.height
2917 + f
->output_data
.x
->menubar_widget
->core
.border_width
)
2920 #if false /* Experimentally, we now get the right results
2921 for -geometry -0-0 without this. 24 Aug 96, rms. */
2922 if (FRAME_EXTERNAL_MENU_BAR (f
))
2925 XtVaGetValues (pane_widget
, XtNinternalBorderWidth
, &ibw
, NULL
);
2926 menubar_size
+= ibw
;
2930 FRAME_MENUBAR_HEIGHT (f
) = menubar_size
;
2933 /* Motif seems to need this amount added to the sizes
2934 specified for the shell widget. The Athena/Lucid widgets don't.
2935 Both conclusions reached experimentally. -- rms. */
2936 XtVaGetValues (f
->output_data
.x
->edit_widget
, XtNinternalBorderWidth
,
2937 &extra_borders
, NULL
);
2941 f
->shell_position
= xmalloc (sizeof "=x++" + 4 * INT_STRLEN_BOUND (int));
2943 /* Convert our geometry parameters into a geometry string
2945 Note that we do not specify here whether the position
2946 is a user-specified or program-specified one.
2947 We pass that information later, in x_wm_set_size_hint. */
2949 int left
= f
->left_pos
;
2950 bool xneg
= (window_prompting
& XNegative
) != 0;
2951 int top
= f
->top_pos
;
2952 bool yneg
= (window_prompting
& YNegative
) != 0;
2958 if (window_prompting
& USPosition
)
2959 sprintf (f
->shell_position
, "=%dx%d%c%d%c%d",
2960 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2961 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
,
2962 (xneg
? '-' : '+'), left
,
2963 (yneg
? '-' : '+'), top
);
2966 sprintf (f
->shell_position
, "=%dx%d",
2967 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2968 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
);
2970 /* Setting x and y when the position is not specified in
2971 the geometry string will set program position in the WM hints.
2972 If Emacs had just one program position, we could set it in
2973 fallback resources, but since each make-frame call can specify
2974 different program positions, this is easier. */
2975 XtSetArg (gal
[gac
], XtNx
, left
); gac
++;
2976 XtSetArg (gal
[gac
], XtNy
, top
); gac
++;
2980 XtSetArg (gal
[gac
], XtNgeometry
, f
->shell_position
); gac
++;
2981 XtSetValues (shell_widget
, gal
, gac
);
2984 XtManageChild (pane_widget
);
2985 XtRealizeWidget (shell_widget
);
2987 if (FRAME_X_EMBEDDED_P (f
))
2988 XReparentWindow (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
),
2989 f
->output_data
.x
->parent_desc
, 0, 0);
2991 FRAME_X_WINDOW (f
) = XtWindow (frame_widget
);
2992 initial_set_up_x_back_buffer (f
);
2993 validate_x_resource_name ();
2995 class_hints
.res_name
= SSDATA (Vx_resource_name
);
2996 class_hints
.res_class
= SSDATA (Vx_resource_class
);
2997 XSetClassHint (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
), &class_hints
);
3000 FRAME_XIC (f
) = NULL
;
3002 create_frame_xic (f
);
3005 f
->output_data
.x
->wm_hints
.input
= True
;
3006 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
3007 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3008 &f
->output_data
.x
->wm_hints
);
3010 hack_wm_protocols (f
, shell_widget
);
3012 #ifdef X_TOOLKIT_EDITRES
3013 XtAddEventHandler (shell_widget
, 0, True
, _XEditResCheckMessages
, 0);
3016 /* Do a stupid property change to force the server to generate a
3017 PropertyNotify event so that the event_stream server timestamp will
3018 be initialized to something relevant to the time we created the window.
3020 XChangeProperty (XtDisplay (frame_widget
), XtWindow (frame_widget
),
3021 FRAME_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
3022 XA_ATOM
, 32, PropModeAppend
, NULL
, 0);
3024 /* Make all the standard events reach the Emacs frame. */
3025 attributes
.event_mask
= STANDARD_EVENT_SET
;
3030 /* XIM server might require some X events. */
3031 unsigned long fevent
= NoEventMask
;
3032 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
3033 attributes
.event_mask
|= fevent
;
3035 #endif /* HAVE_X_I18N */
3037 attributes
.override_redirect
= FRAME_OVERRIDE_REDIRECT (f
);
3038 attribute_mask
= CWEventMask
| CWOverrideRedirect
;
3039 XChangeWindowAttributes (XtDisplay (shell_widget
), XtWindow (shell_widget
),
3040 attribute_mask
, &attributes
);
3042 XtMapWidget (frame_widget
);
3044 /* x_set_name normally ignores requests to set the name if the
3045 requested name is the same as the current name. This is the one
3046 place where that assumption isn't correct; f->name is set, but
3047 the X server hasn't been told. */
3050 bool explicit = f
->explicit_name
;
3052 f
->explicit_name
= false;
3054 fset_name (f
, Qnil
);
3055 x_set_name (f
, name
, explicit);
3058 if (FRAME_UNDECORATED (f
))
3060 Display
*dpy
= FRAME_X_DISPLAY (f
);
3061 PropMotifWmHints hints
;
3062 Atom prop
= XInternAtom (dpy
, "_MOTIF_WM_HINTS", False
);
3064 memset (&hints
, 0, sizeof(hints
));
3065 hints
.flags
= MWM_HINTS_DECORATIONS
;
3066 hints
.decorations
= 0;
3068 /* For some reason the third and fourth arguments in the following
3069 call must be identical: In the corresponding XGetWindowProperty
3070 call in getMotifHints, xfwm has the third and seventh args both
3071 display_info->atoms[MOTIF_WM_HINTS]. Obviously, YMMV. */
3072 XChangeProperty (dpy
, FRAME_OUTER_WINDOW (f
), prop
, prop
, 32,
3073 PropModeReplace
, (unsigned char *) &hints
,
3074 PROP_MOTIF_WM_HINTS_ELEMENTS
);
3077 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3078 f
->output_data
.x
->current_cursor
3079 = f
->output_data
.x
->text_cursor
);
3083 /* This is a no-op, except under Motif. Make sure main areas are
3084 set to something reasonable, in case we get an error later. */
3085 lw_set_main_areas (pane_widget
, 0, frame_widget
);
3088 #else /* not USE_X_TOOLKIT */
3091 x_window (struct frame
*f
)
3093 if (! xg_create_frame_widgets (f
))
3094 error ("Unable to create window");
3097 FRAME_XIC (f
) = NULL
;
3101 create_frame_xic (f
);
3104 /* XIM server might require some X events. */
3105 unsigned long fevent
= NoEventMask
;
3106 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
3108 if (fevent
!= NoEventMask
)
3110 XSetWindowAttributes attributes
;
3111 XWindowAttributes wattr
;
3112 unsigned long attribute_mask
;
3114 XGetWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3116 attributes
.event_mask
= wattr
.your_event_mask
| fevent
;
3117 attribute_mask
= CWEventMask
;
3118 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3119 attribute_mask
, &attributes
);
3127 #else /*! USE_GTK */
3128 /* Create and set up the X window for frame F. */
3131 x_window (struct frame
*f
)
3133 XClassHint class_hints
;
3134 XSetWindowAttributes attributes
;
3135 unsigned long attribute_mask
;
3137 attributes
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
3138 attributes
.border_pixel
= f
->output_data
.x
->border_pixel
;
3139 attributes
.bit_gravity
= StaticGravity
;
3140 attributes
.backing_store
= NotUseful
;
3141 attributes
.save_under
= True
;
3142 attributes
.event_mask
= STANDARD_EVENT_SET
;
3143 attributes
.colormap
= FRAME_X_COLORMAP (f
);
3144 attributes
.override_redirect
= FRAME_OVERRIDE_REDIRECT (f
);
3145 attribute_mask
= (CWBackPixel
| CWBorderPixel
| CWBitGravity
| CWEventMask
3146 | CWOverrideRedirect
| CWColormap
);
3150 = XCreateWindow (FRAME_X_DISPLAY (f
),
3151 f
->output_data
.x
->parent_desc
,
3154 FRAME_PIXEL_WIDTH (f
), FRAME_PIXEL_HEIGHT (f
),
3156 CopyFromParent
, /* depth */
3157 InputOutput
, /* class */
3159 attribute_mask
, &attributes
);
3160 initial_set_up_x_back_buffer (f
);
3165 create_frame_xic (f
);
3168 /* XIM server might require some X events. */
3169 unsigned long fevent
= NoEventMask
;
3170 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
3171 attributes
.event_mask
|= fevent
;
3172 attribute_mask
= CWEventMask
;
3173 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3174 attribute_mask
, &attributes
);
3177 #endif /* HAVE_X_I18N */
3179 validate_x_resource_name ();
3181 class_hints
.res_name
= SSDATA (Vx_resource_name
);
3182 class_hints
.res_class
= SSDATA (Vx_resource_class
);
3183 XSetClassHint (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &class_hints
);
3185 /* This indicates that we use the "Passive Input" input model.
3186 Unless we do this, we don't get the Focus{In,Out} events that we
3187 need to draw the cursor correctly. Accursed bureaucrats.
3188 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
3190 f
->output_data
.x
->wm_hints
.input
= True
;
3191 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
3192 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3193 &f
->output_data
.x
->wm_hints
);
3194 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
3196 /* Request "save yourself" and "delete window" commands from wm. */
3199 protocols
[0] = FRAME_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
3200 protocols
[1] = FRAME_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
3201 XSetWMProtocols (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), protocols
, 2);
3204 /* x_set_name normally ignores requests to set the name if the
3205 requested name is the same as the current name. This is the one
3206 place where that assumption isn't correct; f->name is set, but
3207 the X server hasn't been told. */
3210 bool explicit = f
->explicit_name
;
3212 f
->explicit_name
= false;
3214 fset_name (f
, Qnil
);
3215 x_set_name (f
, name
, explicit);
3218 if (FRAME_UNDECORATED (f
))
3220 Display
*dpy
= FRAME_X_DISPLAY (f
);
3221 PropMotifWmHints hints
;
3222 Atom prop
= XInternAtom (dpy
, "_MOTIF_WM_HINTS", False
);
3224 memset (&hints
, 0, sizeof(hints
));
3225 hints
.flags
= MWM_HINTS_DECORATIONS
;
3226 hints
.decorations
= 0;
3228 /* For some reason the third and fourth arguments in the following
3229 call must be identical: In the corresponding XGetWindowProperty
3230 call in getMotifHints, xfwm has the third and seventh args both
3231 display_info->atoms[MOTIF_WM_HINTS]. Obviously, YMMV. */
3232 XChangeProperty (dpy
, FRAME_OUTER_WINDOW (f
), prop
, prop
, 32,
3233 PropModeReplace
, (unsigned char *) &hints
,
3234 PROP_MOTIF_WM_HINTS_ELEMENTS
);
3238 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3239 f
->output_data
.x
->current_cursor
3240 = f
->output_data
.x
->text_cursor
);
3244 if (FRAME_X_WINDOW (f
) == 0)
3245 error ("Unable to create window");
3248 #endif /* not USE_GTK */
3249 #endif /* not USE_X_TOOLKIT */
3251 /* Verify that the icon position args for this window are valid. */
3254 x_icon_verify (struct frame
*f
, Lisp_Object parms
)
3256 Lisp_Object icon_x
, icon_y
;
3258 /* Set the position of the icon. Note that twm groups all
3259 icons in an icon window. */
3260 icon_x
= x_frame_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
3261 icon_y
= x_frame_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
3262 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
3264 CHECK_NUMBER (icon_x
);
3265 CHECK_NUMBER (icon_y
);
3267 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
3268 error ("Both left and top icon corners of icon must be specified");
3271 /* Handle the icon stuff for this window. Perhaps later we might
3272 want an x_set_icon_position which can be called interactively as
3276 x_icon (struct frame
*f
, Lisp_Object parms
)
3278 /* Set the position of the icon. Note that twm groups all
3279 icons in an icon window. */
3281 = x_frame_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
3283 = x_frame_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
3284 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
3286 CHECK_TYPE_RANGED_INTEGER (int, icon_x
);
3287 CHECK_TYPE_RANGED_INTEGER (int, icon_y
);
3289 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
3290 error ("Both left and top icon corners of icon must be specified");
3294 if (! EQ (icon_x
, Qunbound
))
3295 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
3297 #if false /* x_get_arg removes the visibility parameter as a side effect,
3298 but x_create_frame still needs it. */
3299 /* Start up iconic or window? */
3300 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
3301 x_wm_set_window_state
3302 (f
, (EQ (x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
),
3308 x_text_icon (f
, SSDATA ((!NILP (f
->icon_name
)
3315 /* Make the GCs needed for this window, setting the
3316 background, border and mouse colors; also create the
3317 mouse cursor and the gray border tile. */
3320 x_make_gc (struct frame
*f
)
3322 XGCValues gc_values
;
3326 /* Create the GCs of this frame.
3327 Note that many default values are used. */
3329 gc_values
.foreground
= FRAME_FOREGROUND_PIXEL (f
);
3330 gc_values
.background
= FRAME_BACKGROUND_PIXEL (f
);
3331 gc_values
.line_width
= 0; /* Means 1 using fast algorithm. */
3332 f
->output_data
.x
->normal_gc
3333 = XCreateGC (FRAME_X_DISPLAY (f
),
3334 FRAME_X_DRAWABLE (f
),
3335 GCLineWidth
| GCForeground
| GCBackground
,
3338 /* Reverse video style. */
3339 gc_values
.foreground
= FRAME_BACKGROUND_PIXEL (f
);
3340 gc_values
.background
= FRAME_FOREGROUND_PIXEL (f
);
3341 f
->output_data
.x
->reverse_gc
3342 = XCreateGC (FRAME_X_DISPLAY (f
),
3343 FRAME_X_DRAWABLE (f
),
3344 GCForeground
| GCBackground
| GCLineWidth
,
3347 /* Cursor has cursor-color background, background-color foreground. */
3348 gc_values
.foreground
= FRAME_BACKGROUND_PIXEL (f
);
3349 gc_values
.background
= f
->output_data
.x
->cursor_pixel
;
3350 gc_values
.fill_style
= FillOpaqueStippled
;
3351 f
->output_data
.x
->cursor_gc
3352 = XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_DRAWABLE (f
),
3353 (GCForeground
| GCBackground
3354 | GCFillStyle
| GCLineWidth
),
3357 /* Create the gray border tile used when the pointer is not in
3358 the frame. Since this depends on the frame's pixel values,
3359 this must be done on a per-frame basis. */
3360 f
->output_data
.x
->border_tile
3361 = (XCreatePixmapFromBitmapData
3362 (FRAME_X_DISPLAY (f
), FRAME_DISPLAY_INFO (f
)->root_window
,
3363 gray_bits
, gray_width
, gray_height
,
3364 FRAME_FOREGROUND_PIXEL (f
),
3365 FRAME_BACKGROUND_PIXEL (f
),
3366 DefaultDepth (FRAME_X_DISPLAY (f
), FRAME_X_SCREEN_NUMBER (f
))));
3372 /* Free what was allocated in x_make_gc. */
3375 x_free_gcs (struct frame
*f
)
3377 Display
*dpy
= FRAME_X_DISPLAY (f
);
3381 if (f
->output_data
.x
->normal_gc
)
3383 XFreeGC (dpy
, f
->output_data
.x
->normal_gc
);
3384 f
->output_data
.x
->normal_gc
= 0;
3387 if (f
->output_data
.x
->reverse_gc
)
3389 XFreeGC (dpy
, f
->output_data
.x
->reverse_gc
);
3390 f
->output_data
.x
->reverse_gc
= 0;
3393 if (f
->output_data
.x
->cursor_gc
)
3395 XFreeGC (dpy
, f
->output_data
.x
->cursor_gc
);
3396 f
->output_data
.x
->cursor_gc
= 0;
3399 if (f
->output_data
.x
->border_tile
)
3401 XFreePixmap (dpy
, f
->output_data
.x
->border_tile
);
3402 f
->output_data
.x
->border_tile
= 0;
3409 /* Handler for signals raised during x_create_frame and
3410 x_create_tip_frame. FRAME is the frame which is partially
3414 unwind_create_frame (Lisp_Object frame
)
3416 struct frame
*f
= XFRAME (frame
);
3418 /* If frame is already dead, nothing to do. This can happen if the
3419 display is disconnected after the frame has become official, but
3420 before x_create_frame removes the unwind protect. */
3421 if (!FRAME_LIVE_P (f
))
3424 /* If frame is ``official'', nothing to do. */
3425 if (NILP (Fmemq (frame
, Vframe_list
)))
3427 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
3428 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
3431 /* If the frame's image cache refcount is still the same as our
3432 private shadow variable, it means we are unwinding a frame
3433 for which we didn't yet call init_frame_faces, where the
3434 refcount is incremented. Therefore, we increment it here, so
3435 that free_frame_faces, called in x_free_frame_resources
3436 below, will not mistakenly decrement the counter that was not
3437 incremented yet to account for this new frame. */
3438 if (FRAME_IMAGE_CACHE (f
) != NULL
3439 && FRAME_IMAGE_CACHE (f
)->refcount
== image_cache_refcount
)
3440 FRAME_IMAGE_CACHE (f
)->refcount
++;
3442 x_free_frame_resources (f
);
3445 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
3446 /* Check that reference counts are indeed correct. */
3447 eassert (dpyinfo
->reference_count
== dpyinfo_refcount
);
3448 eassert (dpyinfo
->terminal
->image_cache
->refcount
== image_cache_refcount
);
3457 do_unwind_create_frame (Lisp_Object frame
)
3459 unwind_create_frame (frame
);
3463 x_default_font_parameter (struct frame
*f
, Lisp_Object parms
)
3465 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
3466 Lisp_Object font_param
= x_get_arg (dpyinfo
, parms
, Qfont
, NULL
, NULL
,
3468 Lisp_Object font
= Qnil
;
3469 if (EQ (font_param
, Qunbound
))
3472 if (NILP (font_param
))
3474 /* System font should take precedence over X resources. We suggest this
3475 regardless of font-use-system-font because .emacs may not have been
3477 const char *system_font
= xsettings_get_system_font ();
3479 font
= font_open_by_name (f
, build_unibyte_string (system_font
));
3483 font
= !NILP (font_param
) ? font_param
3484 : x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
3486 if (! FONTP (font
) && ! STRINGP (font
))
3491 /* This will find the normal Xft font. */
3494 "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
3495 "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3496 "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3497 /* This was formerly the first thing tried, but it finds
3498 too many fonts and takes too long. */
3499 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
3500 /* If those didn't work, look for something which will
3502 "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
3507 for (i
= 0; names
[i
]; i
++)
3509 font
= font_open_by_name (f
, build_unibyte_string (names
[i
]));
3514 error ("No suitable font was found");
3516 else if (!NILP (font_param
))
3518 /* Remember the explicit font parameter, so we can re-apply it after
3519 we've applied the `default' face settings. */
3520 AUTO_FRAME_ARG (arg
, Qfont_parameter
, font_param
);
3521 x_set_frame_parameters (f
, arg
);
3524 /* This call will make X resources override any system font setting. */
3525 x_default_parameter (f
, parms
, Qfont
, font
, "font", "Font", RES_TYPE_STRING
);
3529 DEFUN ("x-wm-set-size-hint", Fx_wm_set_size_hint
, Sx_wm_set_size_hint
,
3531 doc
: /* Send the size hints for frame FRAME to the window manager.
3532 If FRAME is omitted or nil, use the selected frame.
3533 Signal error if FRAME is not an X frame. */)
3536 struct frame
*f
= decode_window_system_frame (frame
);
3539 x_wm_set_size_hint (f
, 0, false);
3545 set_machine_and_pid_properties (struct frame
*f
)
3547 /* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME. */
3548 XSetWMProperties (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), NULL
, NULL
,
3549 NULL
, 0, NULL
, NULL
, NULL
);
3550 pid_t pid
= getpid ();
3551 if (pid
<= 0xffffffffu
)
3553 unsigned long xpid
= pid
;
3554 XChangeProperty (FRAME_X_DISPLAY (f
),
3555 FRAME_OUTER_WINDOW (f
),
3556 XInternAtom (FRAME_X_DISPLAY (f
),
3559 XA_CARDINAL
, 32, PropModeReplace
,
3560 (unsigned char *) &xpid
, 1);
3564 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
3566 doc
: /* Make a new X window, which is called a "frame" in Emacs terms.
3567 Return an Emacs frame object. PARMS is an alist of frame parameters.
3568 If the parameters specify that the frame should not have a minibuffer,
3569 and do not specify a specific minibuffer window to use, then
3570 `default-minibuffer-frame' must be a frame whose minibuffer can be
3571 shared by the new frame.
3573 This function is an internal primitive--use `make-frame' instead. */)
3577 Lisp_Object frame
, tem
;
3579 bool minibuffer_only
= false;
3580 bool undecorated
= false, override_redirect
= false;
3581 long window_prompting
= 0;
3582 ptrdiff_t count
= SPECPDL_INDEX ();
3583 Lisp_Object display
;
3584 struct x_display_info
*dpyinfo
= NULL
;
3585 Lisp_Object parent
, parent_frame
;
3587 int x_width
= 0, x_height
= 0;
3589 parms
= Fcopy_alist (parms
);
3591 /* Use this general default value to start with
3592 until we know if this frame has a specified name. */
3593 Vx_resource_name
= Vinvocation_name
;
3595 display
= x_get_arg (dpyinfo
, parms
, Qterminal
, 0, 0, RES_TYPE_NUMBER
);
3596 if (EQ (display
, Qunbound
))
3597 display
= x_get_arg (dpyinfo
, parms
, Qdisplay
, 0, 0, RES_TYPE_STRING
);
3598 if (EQ (display
, Qunbound
))
3600 dpyinfo
= check_x_display_info (display
);
3601 kb
= dpyinfo
->terminal
->kboard
;
3603 if (!dpyinfo
->terminal
->name
)
3604 error ("Terminal is not live, can't create new frames on it");
3606 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
3608 && ! EQ (name
, Qunbound
)
3610 error ("Invalid frame name--not a string or nil");
3613 Vx_resource_name
= name
;
3615 /* See if parent window is specified. */
3616 parent
= x_get_arg (dpyinfo
, parms
, Qparent_id
, NULL
, NULL
, RES_TYPE_NUMBER
);
3617 if (EQ (parent
, Qunbound
))
3619 if (! NILP (parent
))
3620 CHECK_NUMBER (parent
);
3623 tem
= x_get_arg (dpyinfo
, parms
, Qminibuffer
, "minibuffer", "Minibuffer",
3625 if (EQ (tem
, Qnone
) || NILP (tem
))
3626 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
3627 else if (EQ (tem
, Qonly
))
3629 f
= make_minibuffer_frame ();
3630 minibuffer_only
= true;
3632 else if (WINDOWP (tem
))
3633 f
= make_frame_without_minibuffer (tem
, kb
, display
);
3635 f
= make_frame (true);
3637 parent_frame
= x_get_arg (dpyinfo
, parms
, Qparent_frame
, NULL
, NULL
,
3639 /* Accept parent-frame iff parent-id was not specified. */
3641 || EQ (parent_frame
, Qunbound
)
3642 || NILP (parent_frame
)
3643 || !FRAMEP (parent_frame
)
3644 || !FRAME_LIVE_P (XFRAME (parent_frame
))
3645 || !FRAME_X_P (XFRAME (parent_frame
)))
3646 parent_frame
= Qnil
;
3648 fset_parent_frame (f
, parent_frame
);
3649 store_frame_param (f
, Qparent_frame
, parent_frame
);
3651 if (!NILP (tem
= (x_get_arg (dpyinfo
, parms
, Qundecorated
, NULL
, NULL
,
3653 && !(EQ (tem
, Qunbound
)))
3656 FRAME_UNDECORATED (f
) = undecorated
;
3657 store_frame_param (f
, Qundecorated
, undecorated
? Qt
: Qnil
);
3659 if (!NILP (tem
= (x_get_arg (dpyinfo
, parms
, Qoverride_redirect
, NULL
, NULL
,
3661 && !(EQ (tem
, Qunbound
)))
3662 override_redirect
= true;
3664 FRAME_OVERRIDE_REDIRECT (f
) = override_redirect
;
3665 store_frame_param (f
, Qoverride_redirect
, override_redirect
? Qt
: Qnil
);
3667 XSETFRAME (frame
, f
);
3669 f
->terminal
= dpyinfo
->terminal
;
3671 f
->output_method
= output_x_window
;
3672 f
->output_data
.x
= xzalloc (sizeof *f
->output_data
.x
);
3673 f
->output_data
.x
->icon_bitmap
= -1;
3674 FRAME_FONTSET (f
) = -1;
3675 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
3676 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
3677 #if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
3678 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
3679 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
3680 #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
3681 f
->output_data
.x
->white_relief
.pixel
= -1;
3682 f
->output_data
.x
->black_relief
.pixel
= -1;
3685 x_get_arg (dpyinfo
, parms
, Qicon_name
, "iconName", "Title",
3687 if (! STRINGP (f
->icon_name
))
3688 fset_icon_name (f
, Qnil
);
3690 FRAME_DISPLAY_INFO (f
) = dpyinfo
;
3692 /* With FRAME_DISPLAY_INFO set up, this unwind-protect is safe. */
3693 record_unwind_protect (do_unwind_create_frame
, frame
);
3695 /* These colors will be set anyway later, but it's important
3696 to get the color reference counts right, so initialize them! */
3700 /* Function x_decode_color can signal an error. Make
3701 sure to initialize color slots so that we won't try
3702 to free colors we haven't allocated. */
3703 FRAME_FOREGROUND_PIXEL (f
) = -1;
3704 FRAME_BACKGROUND_PIXEL (f
) = -1;
3705 f
->output_data
.x
->cursor_pixel
= -1;
3706 f
->output_data
.x
->cursor_foreground_pixel
= -1;
3707 f
->output_data
.x
->border_pixel
= -1;
3708 f
->output_data
.x
->mouse_pixel
= -1;
3710 black
= build_string ("black");
3711 FRAME_FOREGROUND_PIXEL (f
)
3712 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3713 FRAME_BACKGROUND_PIXEL (f
)
3714 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3715 f
->output_data
.x
->cursor_pixel
3716 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3717 f
->output_data
.x
->cursor_foreground_pixel
3718 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3719 f
->output_data
.x
->border_pixel
3720 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3721 f
->output_data
.x
->mouse_pixel
3722 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3725 /* Specify the parent under which to make this X window. */
3728 f
->output_data
.x
->parent_desc
= (Window
) XFASTINT (parent
);
3729 f
->output_data
.x
->explicit_parent
= true;
3733 f
->output_data
.x
->parent_desc
= FRAME_DISPLAY_INFO (f
)->root_window
;
3734 f
->output_data
.x
->explicit_parent
= false;
3737 /* Set the name; the functions to which we pass f expect the name to
3739 if (EQ (name
, Qunbound
) || NILP (name
))
3741 fset_name (f
, build_string (dpyinfo
->x_id_name
));
3742 f
->explicit_name
= false;
3746 fset_name (f
, name
);
3747 f
->explicit_name
= true;
3748 /* Use the frame's title when getting resources for this frame. */
3749 specbind (Qx_resource_name
, name
);
3753 register_font_driver (&ftcrfont_driver
, f
);
3755 #ifdef HAVE_FREETYPE
3757 register_font_driver (&xftfont_driver
, f
);
3758 #else /* not HAVE_XFT */
3759 register_font_driver (&ftxfont_driver
, f
);
3760 #endif /* not HAVE_XFT */
3761 #endif /* HAVE_FREETYPE */
3762 register_font_driver (&xfont_driver
, f
);
3763 #endif /* not USE_CAIRO */
3765 image_cache_refcount
=
3766 FRAME_IMAGE_CACHE (f
) ? FRAME_IMAGE_CACHE (f
)->refcount
: 0;
3768 dpyinfo_refcount
= dpyinfo
->reference_count
;
3769 #endif /* GLYPH_DEBUG */
3771 x_default_parameter (f
, parms
, Qfont_backend
, Qnil
,
3772 "fontBackend", "FontBackend", RES_TYPE_STRING
);
3774 /* Extract the window parameters from the supplied values
3775 that are needed to determine window geometry. */
3776 x_default_font_parameter (f
, parms
);
3777 if (!FRAME_FONT (f
))
3779 delete_frame (frame
, Qnoelisp
);
3780 error ("Invalid frame font");
3783 /* Frame contents get displaced if an embedded X window has a border. */
3784 if (! FRAME_X_EMBEDDED_P (f
))
3785 x_default_parameter (f
, parms
, Qborder_width
, make_number (0),
3786 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
3788 /* This defaults to 1 in order to match xterm. We recognize either
3789 internalBorderWidth or internalBorder (which is what xterm calls
3791 if (NILP (Fassq (Qinternal_border_width
, parms
)))
3795 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
3796 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
3797 if (! EQ (value
, Qunbound
))
3798 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
3801 x_default_parameter (f
, parms
, Qinternal_border_width
,
3802 #ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */
3807 "internalBorderWidth", "internalBorderWidth",
3809 x_default_parameter (f
, parms
, Qright_divider_width
, make_number (0),
3810 NULL
, NULL
, RES_TYPE_NUMBER
);
3811 x_default_parameter (f
, parms
, Qbottom_divider_width
, make_number (0),
3812 NULL
, NULL
, RES_TYPE_NUMBER
);
3813 x_default_parameter (f
, parms
, Qvertical_scroll_bars
,
3814 #if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
3819 "verticalScrollBars", "ScrollBars",
3821 x_default_parameter (f
, parms
, Qhorizontal_scroll_bars
, Qnil
,
3822 "horizontalScrollBars", "ScrollBars",
3824 /* Also do the stuff which must be set before the window exists. */
3825 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
3826 "foreground", "Foreground", RES_TYPE_STRING
);
3827 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
3828 "background", "Background", RES_TYPE_STRING
);
3829 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
3830 "pointerColor", "Foreground", RES_TYPE_STRING
);
3831 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
3832 "borderColor", "BorderColor", RES_TYPE_STRING
);
3833 x_default_parameter (f
, parms
, Qscreen_gamma
, Qnil
,
3834 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT
);
3835 x_default_parameter (f
, parms
, Qline_spacing
, Qnil
,
3836 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER
);
3837 x_default_parameter (f
, parms
, Qleft_fringe
, Qnil
,
3838 "leftFringe", "LeftFringe", RES_TYPE_NUMBER
);
3839 x_default_parameter (f
, parms
, Qright_fringe
, Qnil
,
3840 "rightFringe", "RightFringe", RES_TYPE_NUMBER
);
3841 x_default_parameter (f
, parms
, Qno_special_glyphs
, Qnil
,
3842 NULL
, NULL
, RES_TYPE_BOOLEAN
);
3844 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_foreground
,
3845 "scrollBarForeground",
3846 "ScrollBarForeground", true);
3847 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_background
,
3848 "scrollBarBackground",
3849 "ScrollBarBackground", false);
3851 /* Init faces before x_default_parameter is called for the
3852 scroll-bar-width parameter because otherwise we end up in
3853 init_iterator with a null face cache, which should not happen. */
3854 init_frame_faces (f
);
3856 /* We have to call adjust_frame_size here since otherwise
3857 x_set_tool_bar_lines will already work with the character sizes
3858 installed by init_frame_faces while the frame's pixel size is still
3859 calculated from a character size of 1 and we subsequently hit the
3860 (height >= 0) assertion in window_box_height.
3862 The non-pixelwise code apparently worked around this because it
3863 had one frame line vs one toolbar line which left us with a zero
3864 root window height which was obviously wrong as well ...
3866 Also process `min-width' and `min-height' parameters right here
3867 because `frame-windows-min-size' needs them. */
3868 tem
= x_get_arg (dpyinfo
, parms
, Qmin_width
, NULL
, NULL
, RES_TYPE_NUMBER
);
3870 store_frame_param (f
, Qmin_width
, tem
);
3871 tem
= x_get_arg (dpyinfo
, parms
, Qmin_height
, NULL
, NULL
, RES_TYPE_NUMBER
);
3873 store_frame_param (f
, Qmin_height
, tem
);
3874 adjust_frame_size (f
, FRAME_COLS (f
) * FRAME_COLUMN_WIDTH (f
),
3875 FRAME_LINES (f
) * FRAME_LINE_HEIGHT (f
), 5, true,
3878 /* Set the menu-bar-lines and tool-bar-lines parameters. We don't
3879 look up the X resources controlling the menu-bar and tool-bar
3880 here; they are processed specially at startup, and reflected in
3881 the values of the mode variables. */
3883 x_default_parameter (f
, parms
, Qmenu_bar_lines
,
3884 NILP (Vmenu_bar_mode
)
3885 ? make_number (0) : make_number (1),
3886 NULL
, NULL
, RES_TYPE_NUMBER
);
3887 x_default_parameter (f
, parms
, Qtool_bar_lines
,
3888 NILP (Vtool_bar_mode
)
3889 ? make_number (0) : make_number (1),
3890 NULL
, NULL
, RES_TYPE_NUMBER
);
3892 x_default_parameter (f
, parms
, Qbuffer_predicate
, Qnil
,
3893 "bufferPredicate", "BufferPredicate",
3895 x_default_parameter (f
, parms
, Qtitle
, Qnil
,
3896 "title", "Title", RES_TYPE_STRING
);
3897 x_default_parameter (f
, parms
, Qwait_for_wm
, Qt
,
3898 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN
);
3899 x_default_parameter (f
, parms
, Qtool_bar_position
,
3900 FRAME_TOOL_BAR_POSITION (f
), 0, 0, RES_TYPE_SYMBOL
);
3901 x_default_parameter (f
, parms
, Qinhibit_double_buffering
, Qnil
,
3902 "inhibitDoubleBuffering", "InhibitDoubleBuffering",
3905 /* Compute the size of the X window. */
3906 window_prompting
= x_figure_window_size (f
, parms
, true, &x_width
, &x_height
);
3908 tem
= x_get_arg (dpyinfo
, parms
, Qunsplittable
, 0, 0, RES_TYPE_BOOLEAN
);
3909 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
3911 x_icon_verify (f
, parms
);
3913 /* Create the X widget or window. */
3914 #ifdef USE_X_TOOLKIT
3915 x_window (f
, window_prompting
);
3923 /* Now consider the frame official. */
3924 f
->terminal
->reference_count
++;
3925 FRAME_DISPLAY_INFO (f
)->reference_count
++;
3926 Vframe_list
= Fcons (frame
, Vframe_list
);
3928 /* We need to do this after creating the X window, so that the
3929 icon-creation functions can say whose icon they're describing. */
3930 x_default_parameter (f
, parms
, Qicon_type
, Qt
,
3931 "bitmapIcon", "BitmapIcon", RES_TYPE_BOOLEAN
);
3933 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
3934 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3935 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
3936 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3937 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
3938 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
3939 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
3940 "scrollBarWidth", "ScrollBarWidth",
3942 x_default_parameter (f
, parms
, Qscroll_bar_height
, Qnil
,
3943 "scrollBarHeight", "ScrollBarHeight",
3945 x_default_parameter (f
, parms
, Qalpha
, Qnil
,
3946 "alpha", "Alpha", RES_TYPE_NUMBER
);
3948 if (!NILP (parent_frame
))
3950 struct frame
*p
= XFRAME (parent_frame
);
3953 XReparentWindow (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
3954 FRAME_X_WINDOW (p
), f
->left_pos
, f
->top_pos
);
3958 x_default_parameter (f
, parms
, Qno_focus_on_map
, Qnil
,
3959 NULL
, NULL
, RES_TYPE_BOOLEAN
);
3960 x_default_parameter (f
, parms
, Qno_accept_focus
, Qnil
,
3961 NULL
, NULL
, RES_TYPE_BOOLEAN
);
3963 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3964 /* Create the menu bar. */
3965 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
3967 /* If this signals an error, we haven't set size hints for the
3968 frame and we didn't make it visible. */
3969 initialize_frame_menubar (f
);
3972 /* This is a no-op, except under Motif where it arranges the
3973 main window for the widgets on it. */
3974 lw_set_main_areas (f
->output_data
.x
->column_widget
,
3975 f
->output_data
.x
->menubar_widget
,
3976 f
->output_data
.x
->edit_widget
);
3977 #endif /* not USE_GTK */
3979 #endif /* USE_X_TOOLKIT || USE_GTK */
3981 /* Consider frame official, now. */
3982 f
->can_x_set_window_size
= true;
3985 SET_FRAME_WIDTH (f
, x_width
);
3987 SET_FRAME_HEIGHT (f
, x_height
);
3989 /* Tell the server what size and position, etc, we want, and how
3990 badly we want them. This should be done after we have the menu
3991 bar so that its size can be taken into account. */
3993 x_wm_set_size_hint (f
, window_prompting
, false);
3996 adjust_frame_size (f
, FRAME_TEXT_WIDTH (f
), FRAME_TEXT_HEIGHT (f
),
3997 0, true, Qx_create_frame_2
);
3999 /* Process fullscreen parameter here in the hope that normalizing a
4000 fullheight/fullwidth frame will produce the size set by the last
4001 adjust_frame_size call. */
4002 x_default_parameter (f
, parms
, Qfullscreen
, Qnil
,
4003 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL
);
4005 /* Make the window appear on the frame and enable display, unless
4006 the caller says not to. However, with explicit parent, Emacs
4007 cannot control visibility, so don't try. */
4008 if (!f
->output_data
.x
->explicit_parent
)
4010 Lisp_Object visibility
4011 = x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
);
4013 if (EQ (visibility
, Qicon
))
4014 x_iconify_frame (f
);
4017 if (EQ (visibility
, Qunbound
))
4020 if (!NILP (visibility
))
4021 x_make_frame_visible (f
);
4024 store_frame_param (f
, Qvisibility
, visibility
);
4029 /* Set machine name and pid for the purpose of window managers. */
4030 set_machine_and_pid_properties (f
);
4032 /* Set the WM leader property. GTK does this itself, so this is not
4033 needed when using GTK. */
4034 if (dpyinfo
->client_leader_window
!= 0)
4036 XChangeProperty (FRAME_X_DISPLAY (f
),
4037 FRAME_OUTER_WINDOW (f
),
4038 dpyinfo
->Xatom_wm_client_leader
,
4039 XA_WINDOW
, 32, PropModeReplace
,
4040 (unsigned char *) &dpyinfo
->client_leader_window
, 1);
4045 /* Works iff frame has been already mapped. */
4046 x_default_parameter (f
, parms
, Qskip_taskbar
, Qnil
,
4047 NULL
, NULL
, RES_TYPE_BOOLEAN
);
4048 /* The `z-group' parameter works only for visible frames. */
4049 x_default_parameter (f
, parms
, Qz_group
, Qnil
,
4050 NULL
, NULL
, RES_TYPE_SYMBOL
);
4052 /* Initialize `default-minibuffer-frame' in case this is the first
4053 frame on this terminal. */
4054 if (FRAME_HAS_MINIBUF_P (f
)
4055 && (!FRAMEP (KVAR (kb
, Vdefault_minibuffer_frame
))
4056 || !FRAME_LIVE_P (XFRAME (KVAR (kb
, Vdefault_minibuffer_frame
)))))
4057 kset_default_minibuffer_frame (kb
, frame
);
4059 /* All remaining specified parameters, which have not been "used"
4060 by x_get_arg and friends, now go in the misc. alist of the frame. */
4061 for (tem
= parms
; CONSP (tem
); tem
= XCDR (tem
))
4062 if (CONSP (XCAR (tem
)) && !NILP (XCAR (XCAR (tem
))))
4063 fset_param_alist (f
, Fcons (XCAR (tem
), f
->param_alist
));
4065 /* Make sure windows on this frame appear in calls to next-window
4066 and similar functions. */
4067 Vwindow_list
= Qnil
;
4069 return unbind_to (count
, frame
);
4073 /* FRAME is used only to get a handle on the X display. We don't pass the
4074 display info directly because we're called from frame.c, which doesn't
4075 know about that structure. */
4078 x_get_focus_frame (struct frame
*frame
)
4080 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (frame
);
4082 if (! dpyinfo
->x_focus_frame
)
4085 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
4090 /* In certain situations, when the window manager follows a
4091 click-to-focus policy, there seems to be no way around calling
4092 XSetInputFocus to give another frame the input focus .
4094 In an ideal world, XSetInputFocus should generally be avoided so
4095 that applications don't interfere with the window manager's focus
4096 policy. But I think it's okay to use when it's clearly done
4097 following a user-command. */
4100 x_focus_frame (struct frame
*f
, bool noactivate
)
4102 Display
*dpy
= FRAME_X_DISPLAY (f
);
4105 x_catch_errors (dpy
);
4107 if (FRAME_X_EMBEDDED_P (f
))
4109 /* For Xembedded frames, normally the embedder forwards key
4110 events. See XEmbed Protocol Specification at
4111 http://freedesktop.org/wiki/Specifications/xembed-spec */
4112 xembed_request_focus (f
);
4116 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4117 RevertToParent
, CurrentTime
);
4119 x_ewmh_activate_frame (f
);
4122 x_uncatch_errors ();
4127 DEFUN ("xw-color-defined-p", Fxw_color_defined_p
, Sxw_color_defined_p
, 1, 2, 0,
4128 doc
: /* Internal function called by `color-defined-p'.
4129 \(Note that the Nextstep version of this function ignores FRAME.) */)
4130 (Lisp_Object color
, Lisp_Object frame
)
4133 struct frame
*f
= decode_window_system_frame (frame
);
4135 CHECK_STRING (color
);
4137 if (x_defined_color (f
, SSDATA (color
), &foo
, false))
4143 DEFUN ("xw-color-values", Fxw_color_values
, Sxw_color_values
, 1, 2, 0,
4144 doc
: /* Internal function called by `color-values'.
4145 \(Note that the Nextstep version of this function ignores FRAME.) */)
4146 (Lisp_Object color
, Lisp_Object frame
)
4149 struct frame
*f
= decode_window_system_frame (frame
);
4151 CHECK_STRING (color
);
4153 if (x_defined_color (f
, SSDATA (color
), &foo
, false))
4154 return list3i (foo
.red
, foo
.green
, foo
.blue
);
4159 DEFUN ("xw-display-color-p", Fxw_display_color_p
, Sxw_display_color_p
, 0, 1, 0,
4160 doc
: /* Internal function called by `display-color-p'. */)
4161 (Lisp_Object terminal
)
4163 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4165 if (dpyinfo
->n_planes
<= 2)
4168 switch (dpyinfo
->visual
->class)
4181 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
4183 doc
: /* Return t if the X display supports shades of gray.
4184 Note that color displays do support shades of gray.
4185 The optional argument TERMINAL specifies which display to ask about.
4186 TERMINAL should be a terminal object, a frame or a display name (a string).
4187 If omitted or nil, that stands for the selected frame's display. */)
4188 (Lisp_Object terminal
)
4190 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4192 if (dpyinfo
->n_planes
<= 1)
4195 switch (dpyinfo
->visual
->class)
4210 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
4212 doc
: /* Return the width in pixels of the X display TERMINAL.
4213 The optional argument TERMINAL specifies which display to ask about.
4214 TERMINAL should be a terminal object, a frame or a display name (a string).
4215 If omitted or nil, that stands for the selected frame's display.
4216 \(On MS Windows, this function does not accept terminal objects.)
4218 On \"multi-monitor\" setups this refers to the pixel width for all
4219 physical monitors associated with TERMINAL. To get information for
4220 each physical monitor, use `display-monitor-attributes-list'. */)
4221 (Lisp_Object terminal
)
4223 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4225 return make_number (x_display_pixel_width (dpyinfo
));
4228 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
4229 Sx_display_pixel_height
, 0, 1, 0,
4230 doc
: /* Return the height in pixels of the X display TERMINAL.
4231 The optional argument TERMINAL specifies which display to ask about.
4232 TERMINAL should be a terminal object, a frame or a display name (a string).
4233 If omitted or nil, that stands for the selected frame's display.
4234 \(On MS Windows, this function does not accept terminal objects.)
4236 On \"multi-monitor\" setups this refers to the pixel height for all
4237 physical monitors associated with TERMINAL. To get information for
4238 each physical monitor, use `display-monitor-attributes-list'. */)
4239 (Lisp_Object terminal
)
4241 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4243 return make_number (x_display_pixel_height (dpyinfo
));
4246 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
4248 doc
: /* Return the number of bitplanes of the X display TERMINAL.
4249 The optional argument TERMINAL specifies which display to ask about.
4250 TERMINAL should be a terminal object, a frame or a display name (a string).
4251 If omitted or nil, that stands for the selected frame's display.
4252 \(On MS Windows, this function does not accept terminal objects.) */)
4253 (Lisp_Object terminal
)
4255 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4257 return make_number (dpyinfo
->n_planes
);
4260 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
4262 doc
: /* Return the number of color cells of the X display TERMINAL.
4263 The optional argument TERMINAL specifies which display to ask about.
4264 TERMINAL should be a terminal object, a frame or a display name (a string).
4265 If omitted or nil, that stands for the selected frame's display.
4266 \(On MS Windows, this function does not accept terminal objects.) */)
4267 (Lisp_Object terminal
)
4269 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4271 int nr_planes
= DisplayPlanes (dpyinfo
->display
,
4272 XScreenNumberOfScreen (dpyinfo
->screen
));
4274 /* Truncate nr_planes to 24 to avoid integer overflow.
4275 Some displays says 32, but only 24 bits are actually significant.
4276 There are only very few and rare video cards that have more than
4277 24 significant bits. Also 24 bits is more than 16 million colors,
4278 it "should be enough for everyone". */
4279 if (nr_planes
> 24) nr_planes
= 24;
4281 return make_number (1 << nr_planes
);
4284 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
4285 Sx_server_max_request_size
,
4287 doc
: /* Return the maximum request size of the X server of display TERMINAL.
4288 The optional argument TERMINAL specifies which display to ask about.
4289 TERMINAL should be a terminal object, a frame or a display name (a string).
4290 If omitted or nil, that stands for the selected frame's display.
4292 On MS Windows, this function just returns 1.
4293 On Nextstep, this function just returns nil. */)
4294 (Lisp_Object terminal
)
4296 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4298 return make_number (MAXREQUEST (dpyinfo
->display
));
4301 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
4302 doc
: /* Return the "vendor ID" string of the GUI software on TERMINAL.
4304 \(Labeling every distributor as a "vendor" embodies the false assumption
4305 that operating systems cannot be developed and distributed noncommercially.)
4306 The optional argument TERMINAL specifies which display to ask about.
4308 For GNU and Unix systems, this queries the X server software.
4309 For MS Windows and Nextstep the result is hard-coded.
4311 TERMINAL should be a terminal object, a frame or a display name (a string).
4312 If omitted or nil, that stands for the selected frame's display. */)
4313 (Lisp_Object terminal
)
4315 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4316 const char *vendor
= ServerVendor (dpyinfo
->display
);
4318 if (! vendor
) vendor
= "";
4319 return build_string (vendor
);
4322 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
4323 doc
: /* Return the version numbers of the GUI software on TERMINAL.
4324 The value is a list of three integers specifying the version of the GUI
4327 For GNU and Unix system, the first 2 numbers are the version of the X
4328 Protocol used on TERMINAL and the 3rd number is the distributor-specific
4329 release number. For MS Windows, the 3 numbers report the OS major and
4330 minor version and build number. For Nextstep, the first 2 numbers are
4331 hard-coded and the 3rd represents the OS version.
4333 See also the function `x-server-vendor'.
4335 The optional argument TERMINAL specifies which display to ask about.
4336 TERMINAL should be a terminal object, a frame or a display name (a string).
4337 If omitted or nil, that stands for the selected frame's display. */)
4338 (Lisp_Object terminal
)
4340 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4341 Display
*dpy
= dpyinfo
->display
;
4343 return list3i (ProtocolVersion (dpy
), ProtocolRevision (dpy
),
4344 VendorRelease (dpy
));
4347 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
4348 doc
: /* Return the number of screens on the X server of display TERMINAL.
4349 The optional argument TERMINAL specifies which display to ask about.
4350 TERMINAL should be a terminal object, a frame or a display name (a string).
4351 If omitted or nil, that stands for the selected frame's display.
4353 On MS Windows, this function just returns 1.
4354 On Nextstep, "screen" is in X terminology, not that of Nextstep.
4355 For the number of physical monitors, use `(length
4356 \(display-monitor-attributes-list TERMINAL))' instead. */)
4357 (Lisp_Object terminal
)
4359 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4361 return make_number (ScreenCount (dpyinfo
->display
));
4364 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
4365 doc
: /* Return the height in millimeters of the X display TERMINAL.
4366 The optional argument TERMINAL specifies which display to ask about.
4367 TERMINAL should be a terminal object, a frame or a display name (a string).
4368 If omitted or nil, that stands for the selected frame's display.
4369 \(On MS Windows, this function does not accept terminal objects.)
4371 On \"multi-monitor\" setups this refers to the height in millimeters for
4372 all physical monitors associated with TERMINAL. To get information
4373 for each physical monitor, use `display-monitor-attributes-list'. */)
4374 (Lisp_Object terminal
)
4376 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4378 return make_number (HeightMMOfScreen (dpyinfo
->screen
));
4381 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
4382 doc
: /* Return the width in millimeters of the X display TERMINAL.
4383 The optional argument TERMINAL specifies which display to ask about.
4384 TERMINAL should be a terminal object, a frame or a display name (a string).
4385 If omitted or nil, that stands for the selected frame's display.
4386 \(On MS Windows, this function does not accept terminal objects.)
4388 On \"multi-monitor\" setups this refers to the width in millimeters for
4389 all physical monitors associated with TERMINAL. To get information
4390 for each physical monitor, use `display-monitor-attributes-list'. */)
4391 (Lisp_Object terminal
)
4393 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4395 return make_number (WidthMMOfScreen (dpyinfo
->screen
));
4398 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
4399 Sx_display_backing_store
, 0, 1, 0,
4400 doc
: /* Return an indication of whether X display TERMINAL does backing store.
4401 The optional argument TERMINAL specifies which display to ask about.
4402 TERMINAL should be a terminal object, a frame or a display name (a string).
4403 If omitted or nil, that stands for the selected frame's display.
4405 The value may be `always', `when-mapped', or `not-useful'.
4406 On Nextstep, the value may be `buffered', `retained', or `non-retained'.
4407 On MS Windows, this returns nothing useful. */)
4408 (Lisp_Object terminal
)
4410 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4413 switch (DoesBackingStore (dpyinfo
->screen
))
4416 result
= intern ("always");
4420 result
= intern ("when-mapped");
4424 result
= intern ("not-useful");
4428 error ("Strange value for BackingStore parameter of screen");
4434 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
4435 Sx_display_visual_class
, 0, 1, 0,
4436 doc
: /* Return the visual class of the X display TERMINAL.
4437 The value is one of the symbols `static-gray', `gray-scale',
4438 `static-color', `pseudo-color', `true-color', or `direct-color'.
4439 \(On MS Windows, the second and last result above are not possible.)
4441 The optional argument TERMINAL specifies which display to ask about.
4442 TERMINAL should a terminal object, a frame or a display name (a string).
4443 If omitted or nil, that stands for the selected frame's display.
4444 \(On MS Windows, this function does not accept terminal objects.) */)
4445 (Lisp_Object terminal
)
4447 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4450 switch (dpyinfo
->visual
->class)
4453 result
= intern ("static-gray");
4456 result
= intern ("gray-scale");
4459 result
= intern ("static-color");
4462 result
= intern ("pseudo-color");
4465 result
= intern ("true-color");
4468 result
= intern ("direct-color");
4471 error ("Display has an unknown visual class");
4477 DEFUN ("x-display-save-under", Fx_display_save_under
,
4478 Sx_display_save_under
, 0, 1, 0,
4479 doc
: /* Return t if the X display TERMINAL supports the save-under feature.
4480 The optional argument TERMINAL specifies which display to ask about.
4481 TERMINAL should be a terminal object, a frame or a display name (a string).
4482 If omitted or nil, that stands for the selected frame's display.
4484 On MS Windows, this just returns nil. */)
4485 (Lisp_Object terminal
)
4487 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4489 if (DoesSaveUnders (dpyinfo
->screen
) == True
)
4495 /* Store the geometry of the workarea on display DPYINFO into *RECT.
4496 Return false if and only if the workarea information cannot be
4497 obtained via the _NET_WORKAREA root window property. */
4499 #if ! GTK_CHECK_VERSION (3, 4, 0)
4501 x_get_net_workarea (struct x_display_info
*dpyinfo
, XRectangle
*rect
)
4503 Display
*dpy
= dpyinfo
->display
;
4504 long offset
, max_len
;
4505 Atom target_type
, actual_type
;
4506 unsigned long actual_size
, bytes_remaining
;
4507 int rc
, actual_format
;
4508 unsigned char *tmp_data
= NULL
;
4509 bool result
= false;
4511 x_catch_errors (dpy
);
4514 target_type
= XA_CARDINAL
;
4515 rc
= XGetWindowProperty (dpy
, dpyinfo
->root_window
,
4516 dpyinfo
->Xatom_net_current_desktop
,
4517 offset
, max_len
, False
, target_type
,
4518 &actual_type
, &actual_format
, &actual_size
,
4519 &bytes_remaining
, &tmp_data
);
4520 if (rc
== Success
&& actual_type
== target_type
&& !x_had_errors_p (dpy
)
4521 && actual_format
== 32 && actual_size
== max_len
)
4523 long current_desktop
= ((long *) tmp_data
)[0];
4528 offset
= 4 * current_desktop
;
4530 rc
= XGetWindowProperty (dpy
, dpyinfo
->root_window
,
4531 dpyinfo
->Xatom_net_workarea
,
4532 offset
, max_len
, False
, target_type
,
4533 &actual_type
, &actual_format
, &actual_size
,
4534 &bytes_remaining
, &tmp_data
);
4535 if (rc
== Success
&& actual_type
== target_type
&& !x_had_errors_p (dpy
)
4536 && actual_format
== 32 && actual_size
== max_len
)
4538 long *values
= (long *) tmp_data
;
4540 rect
->x
= values
[0];
4541 rect
->y
= values
[1];
4542 rect
->width
= values
[2];
4543 rect
->height
= values
[3];
4553 x_uncatch_errors ();
4561 /* Return monitor number where F is "most" or closest to. */
4563 x_get_monitor_for_frame (struct frame
*f
,
4564 struct MonitorInfo
*monitors
,
4568 int area
= 0, dist
= -1;
4569 int best_area
= -1, best_dist
= -1;
4572 if (n_monitors
== 1) return 0;
4573 frect
.x
= f
->left_pos
;
4574 frect
.y
= f
->top_pos
;
4575 frect
.width
= FRAME_PIXEL_WIDTH (f
);
4576 frect
.height
= FRAME_PIXEL_HEIGHT (f
);
4578 for (i
= 0; i
< n_monitors
; ++i
)
4580 struct MonitorInfo
*mi
= &monitors
[i
];
4584 if (mi
->geom
.width
== 0) continue;
4586 if (x_intersect_rectangles (&mi
->geom
, &frect
, &res
))
4588 a
= res
.width
* res
.height
;
4596 if (a
== 0 && area
== 0)
4599 if (frect
.x
+ frect
.width
< mi
->geom
.x
)
4600 dx
= mi
->geom
.x
- frect
.x
+ frect
.width
;
4601 else if (frect
.x
> mi
->geom
.x
+ mi
->geom
.width
)
4602 dx
= frect
.x
- mi
->geom
.x
+ mi
->geom
.width
;
4605 if (frect
.y
+ frect
.height
< mi
->geom
.y
)
4606 dy
= mi
->geom
.y
- frect
.y
+ frect
.height
;
4607 else if (frect
.y
> mi
->geom
.y
+ mi
->geom
.height
)
4608 dy
= frect
.y
- mi
->geom
.y
+ mi
->geom
.height
;
4613 if (dist
== -1 || dist
> d
)
4621 return best_area
!= -1 ? best_area
: (best_dist
!= -1 ? best_dist
: 0);
4625 x_make_monitor_attribute_list (struct MonitorInfo
*monitors
,
4627 int primary_monitor
,
4628 struct x_display_info
*dpyinfo
,
4631 Lisp_Object monitor_frames
= Fmake_vector (make_number (n_monitors
), Qnil
);
4632 Lisp_Object frame
, rest
;
4634 FOR_EACH_FRAME (rest
, frame
)
4636 struct frame
*f
= XFRAME (frame
);
4639 && FRAME_DISPLAY_INFO (f
) == dpyinfo
4640 && !FRAME_TOOLTIP_P (f
))
4642 int i
= x_get_monitor_for_frame (f
, monitors
, n_monitors
);
4643 ASET (monitor_frames
, i
, Fcons (frame
, AREF (monitor_frames
, i
)));
4647 return make_monitor_attribute_list (monitors
, n_monitors
, primary_monitor
,
4648 monitor_frames
, source
);
4652 x_get_monitor_attributes_fallback (struct x_display_info
*dpyinfo
)
4654 struct MonitorInfo monitor
;
4655 XRectangle workarea_r
;
4657 /* Fallback: treat (possibly) multiple physical monitors as if they
4658 formed a single monitor as a whole. This should provide a
4659 consistent result at least on single monitor environments. */
4660 monitor
.geom
.x
= monitor
.geom
.y
= 0;
4661 monitor
.geom
.width
= x_display_pixel_width (dpyinfo
);
4662 monitor
.geom
.height
= x_display_pixel_height (dpyinfo
);
4663 monitor
.mm_width
= WidthMMOfScreen (dpyinfo
->screen
);
4664 monitor
.mm_height
= HeightMMOfScreen (dpyinfo
->screen
);
4665 monitor
.name
= xstrdup ("combined screen");
4667 if (x_get_net_workarea (dpyinfo
, &workarea_r
))
4668 monitor
.work
= workarea_r
;
4670 monitor
.work
= monitor
.geom
;
4671 return x_make_monitor_attribute_list (&monitor
, 1, 0, dpyinfo
, "fallback");
4675 #ifdef HAVE_XINERAMA
4677 x_get_monitor_attributes_xinerama (struct x_display_info
*dpyinfo
)
4680 Lisp_Object attributes_list
= Qnil
;
4681 Display
*dpy
= dpyinfo
->display
;
4682 XineramaScreenInfo
*info
= XineramaQueryScreens (dpy
, &n_monitors
);
4683 struct MonitorInfo
*monitors
;
4684 double mm_width_per_pixel
, mm_height_per_pixel
;
4686 if (! info
|| n_monitors
== 0)
4690 return attributes_list
;
4693 mm_width_per_pixel
= ((double) WidthMMOfScreen (dpyinfo
->screen
)
4694 / x_display_pixel_width (dpyinfo
));
4695 mm_height_per_pixel
= ((double) HeightMMOfScreen (dpyinfo
->screen
)
4696 / x_display_pixel_height (dpyinfo
));
4697 monitors
= xzalloc (n_monitors
* sizeof *monitors
);
4698 for (i
= 0; i
< n_monitors
; ++i
)
4700 struct MonitorInfo
*mi
= &monitors
[i
];
4701 XRectangle workarea_r
;
4703 mi
->geom
.x
= info
[i
].x_org
;
4704 mi
->geom
.y
= info
[i
].y_org
;
4705 mi
->geom
.width
= info
[i
].width
;
4706 mi
->geom
.height
= info
[i
].height
;
4707 mi
->mm_width
= mi
->geom
.width
* mm_width_per_pixel
+ 0.5;
4708 mi
->mm_height
= mi
->geom
.height
* mm_height_per_pixel
+ 0.5;
4711 /* Xinerama usually have primary monitor first, just use that. */
4712 if (i
== 0 && x_get_net_workarea (dpyinfo
, &workarea_r
))
4714 mi
->work
= workarea_r
;
4715 if (! x_intersect_rectangles (&mi
->geom
, &mi
->work
, &mi
->work
))
4716 mi
->work
= mi
->geom
;
4719 mi
->work
= mi
->geom
;
4723 attributes_list
= x_make_monitor_attribute_list (monitors
,
4728 free_monitors (monitors
, n_monitors
);
4729 return attributes_list
;
4731 #endif /* HAVE_XINERAMA */
4736 x_get_monitor_attributes_xrandr (struct x_display_info
*dpyinfo
)
4738 Lisp_Object attributes_list
= Qnil
;
4739 XRRScreenResources
*resources
;
4740 Display
*dpy
= dpyinfo
->display
;
4741 int i
, n_monitors
, primary
= -1;
4742 RROutput pxid
= None
;
4743 struct MonitorInfo
*monitors
;
4745 #define RANDR13_LIBRARY \
4746 (RANDR_MAJOR > 1 || (RANDR_MAJOR == 1 && RANDR_MINOR >= 3))
4749 /* Check if the display supports 1.3 too. */
4750 bool randr13_avail
= (dpyinfo
->xrandr_major_version
> 1
4751 || (dpyinfo
->xrandr_major_version
== 1
4752 && dpyinfo
->xrandr_minor_version
>= 3));
4755 resources
= XRRGetScreenResourcesCurrent (dpy
, dpyinfo
->root_window
);
4757 resources
= XRRGetScreenResources (dpy
, dpyinfo
->root_window
);
4759 resources
= XRRGetScreenResources (dpy
, dpyinfo
->root_window
);
4761 if (! resources
|| resources
->noutput
== 0)
4764 XRRFreeScreenResources (resources
);
4767 n_monitors
= resources
->noutput
;
4768 monitors
= xzalloc (n_monitors
* sizeof *monitors
);
4772 pxid
= XRRGetOutputPrimary (dpy
, dpyinfo
->root_window
);
4775 for (i
= 0; i
< n_monitors
; ++i
)
4777 XRROutputInfo
*info
= XRRGetOutputInfo (dpy
, resources
,
4778 resources
->outputs
[i
]);
4782 if (strcmp (info
->name
, "default") == 0)
4784 /* Non XRandr 1.2 driver, does not give useful data. */
4785 XRRFreeOutputInfo (info
);
4786 XRRFreeScreenResources (resources
);
4787 free_monitors (monitors
, n_monitors
);
4791 if (info
->connection
!= RR_Disconnected
&& info
->crtc
!= None
)
4793 XRRCrtcInfo
*crtc
= XRRGetCrtcInfo (dpy
, resources
, info
->crtc
);
4794 struct MonitorInfo
*mi
= &monitors
[i
];
4795 XRectangle workarea_r
;
4799 XRRFreeOutputInfo (info
);
4803 mi
->geom
.x
= crtc
->x
;
4804 mi
->geom
.y
= crtc
->y
;
4805 mi
->geom
.width
= crtc
->width
;
4806 mi
->geom
.height
= crtc
->height
;
4807 mi
->mm_width
= info
->mm_width
;
4808 mi
->mm_height
= info
->mm_height
;
4809 mi
->name
= xstrdup (info
->name
);
4811 if (pxid
!= None
&& pxid
== resources
->outputs
[i
])
4813 else if (primary
== -1 && strcmp (info
->name
, "LVDS") == 0)
4816 if (i
== primary
&& x_get_net_workarea (dpyinfo
, &workarea_r
))
4818 mi
->work
= workarea_r
;
4819 if (! x_intersect_rectangles (&mi
->geom
, &mi
->work
, &mi
->work
))
4820 mi
->work
= mi
->geom
;
4823 mi
->work
= mi
->geom
;
4825 XRRFreeCrtcInfo (crtc
);
4827 XRRFreeOutputInfo (info
);
4829 XRRFreeScreenResources (resources
);
4831 attributes_list
= x_make_monitor_attribute_list (monitors
,
4836 free_monitors (monitors
, n_monitors
);
4837 return attributes_list
;
4839 #endif /* HAVE_XRANDR */
4842 x_get_monitor_attributes (struct x_display_info
*dpyinfo
)
4844 Lisp_Object attributes_list
= Qnil
;
4845 Display
*dpy
= dpyinfo
->display
;
4847 (void) dpy
; /* Suppress unused variable warning. */
4850 int xrr_event_base
, xrr_error_base
;
4851 bool xrr_ok
= false;
4852 xrr_ok
= XRRQueryExtension (dpy
, &xrr_event_base
, &xrr_error_base
);
4855 XRRQueryVersion (dpy
, &dpyinfo
->xrandr_major_version
,
4856 &dpyinfo
->xrandr_minor_version
);
4857 xrr_ok
= ((dpyinfo
->xrandr_major_version
== 1
4858 && dpyinfo
->xrandr_minor_version
>= 2)
4859 || dpyinfo
->xrandr_major_version
> 1);
4863 attributes_list
= x_get_monitor_attributes_xrandr (dpyinfo
);
4864 #endif /* HAVE_XRANDR */
4866 #ifdef HAVE_XINERAMA
4867 if (NILP (attributes_list
))
4869 int xin_event_base
, xin_error_base
;
4870 bool xin_ok
= false;
4871 xin_ok
= XineramaQueryExtension (dpy
, &xin_event_base
, &xin_error_base
);
4872 if (xin_ok
&& XineramaIsActive (dpy
))
4873 attributes_list
= x_get_monitor_attributes_xinerama (dpyinfo
);
4875 #endif /* HAVE_XINERAMA */
4877 if (NILP (attributes_list
))
4878 attributes_list
= x_get_monitor_attributes_fallback (dpyinfo
);
4880 return attributes_list
;
4883 #endif /* !USE_GTK */
4885 DEFUN ("x-display-monitor-attributes-list", Fx_display_monitor_attributes_list
,
4886 Sx_display_monitor_attributes_list
,
4888 doc
: /* Return a list of physical monitor attributes on the X display TERMINAL.
4890 The optional argument TERMINAL specifies which display to ask about.
4891 TERMINAL should be a terminal object, a frame or a display name (a string).
4892 If omitted or nil, that stands for the selected frame's display.
4894 In addition to the standard attribute keys listed in
4895 `display-monitor-attributes-list', the following keys are contained in
4898 source -- String describing the source from which multi-monitor
4899 information is obtained, one of \"Gdk\", \"XRandr\",
4900 \"Xinerama\", or \"fallback\"
4902 Internal use only, use `display-monitor-attributes-list' instead. */)
4903 (Lisp_Object terminal
)
4905 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4906 Lisp_Object attributes_list
= Qnil
;
4909 double mm_width_per_pixel
, mm_height_per_pixel
;
4911 #if ! GTK_CHECK_VERSION (3, 22, 0)
4914 gint primary_monitor
= 0, n_monitors
, i
;
4915 Lisp_Object monitor_frames
, rest
, frame
;
4916 static const char *source
= "Gdk";
4917 struct MonitorInfo
*monitors
;
4920 mm_width_per_pixel
= ((double) WidthMMOfScreen (dpyinfo
->screen
)
4921 / x_display_pixel_width (dpyinfo
));
4922 mm_height_per_pixel
= ((double) HeightMMOfScreen (dpyinfo
->screen
)
4923 / x_display_pixel_height (dpyinfo
));
4924 gdpy
= gdk_x11_lookup_xdisplay (dpyinfo
->display
);
4925 #if GTK_CHECK_VERSION (3, 22, 0)
4926 n_monitors
= gdk_display_get_n_monitors (gdpy
);
4928 gscreen
= gdk_display_get_default_screen (gdpy
);
4929 #if GTK_CHECK_VERSION (2, 20, 0)
4930 primary_monitor
= gdk_screen_get_primary_monitor (gscreen
);
4932 n_monitors
= gdk_screen_get_n_monitors (gscreen
);
4934 monitor_frames
= Fmake_vector (make_number (n_monitors
), Qnil
);
4935 monitors
= xzalloc (n_monitors
* sizeof *monitors
);
4937 FOR_EACH_FRAME (rest
, frame
)
4939 struct frame
*f
= XFRAME (frame
);
4942 && FRAME_DISPLAY_INFO (f
) == dpyinfo
4943 && !FRAME_TOOLTIP_P (f
))
4945 GdkWindow
*gwin
= gtk_widget_get_window (FRAME_GTK_WIDGET (f
));
4947 #if GTK_CHECK_VERSION (3, 22, 0)
4948 for (i
= 0; i
< n_monitors
; i
++)
4949 if (gdk_display_get_monitor_at_window (gdpy
, gwin
)
4950 == gdk_display_get_monitor (gdpy
, i
))
4953 i
= gdk_screen_get_monitor_at_window (gscreen
, gwin
);
4955 ASET (monitor_frames
, i
, Fcons (frame
, AREF (monitor_frames
, i
)));
4959 for (i
= 0; i
< n_monitors
; ++i
)
4961 gint width_mm
= -1, height_mm
= -1;
4962 GdkRectangle rec
, work
;
4963 struct MonitorInfo
*mi
= &monitors
[i
];
4966 #if GTK_CHECK_VERSION (3, 22, 0)
4967 GdkMonitor
*monitor
= gdk_display_get_monitor (gdpy
, i
);
4968 if (gdk_monitor_is_primary (monitor
))
4969 primary_monitor
= i
;
4970 gdk_monitor_get_geometry (monitor
, &rec
);
4972 gdk_screen_get_monitor_geometry (gscreen
, i
, &rec
);
4975 #if GTK_CHECK_VERSION (3, 22, 0)
4976 width_mm
= gdk_monitor_get_width_mm (monitor
);
4977 height_mm
= gdk_monitor_get_height_mm (monitor
);
4978 #elif GTK_CHECK_VERSION (2, 14, 0)
4979 width_mm
= gdk_screen_get_monitor_width_mm (gscreen
, i
);
4980 height_mm
= gdk_screen_get_monitor_height_mm (gscreen
, i
);
4983 width_mm
= rec
.width
* mm_width_per_pixel
+ 0.5;
4985 height_mm
= rec
.height
* mm_height_per_pixel
+ 0.5;
4987 #if GTK_CHECK_VERSION (3, 22, 0)
4988 gdk_monitor_get_workarea (monitor
, &work
);
4989 #elif GTK_CHECK_VERSION (3, 4, 0)
4990 gdk_screen_get_monitor_workarea (gscreen
, i
, &work
);
4992 /* Emulate the behavior of GTK+ 3.4. */
4994 XRectangle workarea_r
;
4996 if (i
== primary_monitor
&& x_get_net_workarea (dpyinfo
, &workarea_r
))
4998 work
.x
= workarea_r
.x
;
4999 work
.y
= workarea_r
.y
;
5000 work
.width
= workarea_r
.width
;
5001 work
.height
= workarea_r
.height
;
5002 if (! gdk_rectangle_intersect (&rec
, &work
, &work
))
5010 /* GTK returns scaled sizes for the workareas. */
5011 #if GTK_CHECK_VERSION (3, 22, 0)
5012 scale
= gdk_monitor_get_scale_factor (monitor
);
5013 #elif GTK_CHECK_VERSION (3, 10, 0)
5014 scale
= gdk_screen_get_monitor_scale_factor (gscreen
, i
);
5017 rec
.height
*= scale
;
5018 work
.width
*= scale
;
5019 work
.height
*= scale
;
5023 mi
->geom
.width
= rec
.width
;
5024 mi
->geom
.height
= rec
.height
;
5025 mi
->work
.x
= work
.x
;
5026 mi
->work
.y
= work
.y
;
5027 mi
->work
.width
= work
.width
;
5028 mi
->work
.height
= work
.height
;
5029 mi
->mm_width
= width_mm
;
5030 mi
->mm_height
= height_mm
;
5032 #if GTK_CHECK_VERSION (3, 22, 0)
5033 mi
->name
= g_strdup (gdk_monitor_get_model (monitor
));
5034 #elif GTK_CHECK_VERSION (2, 14, 0)
5035 mi
->name
= gdk_screen_get_monitor_plug_name (gscreen
, i
);
5039 attributes_list
= make_monitor_attribute_list (monitors
,
5045 #else /* not USE_GTK */
5048 attributes_list
= x_get_monitor_attributes (dpyinfo
);
5051 #endif /* not USE_GTK */
5053 return attributes_list
;
5056 /* Return geometric attributes of FRAME. According to the value of
5057 ATTRIBUTES return the outer edges of FRAME (Qouter_edges), the native
5058 edges of FRAME (Qnative_edges), or the inner edges of frame
5059 (Qinner_edges). Any other value means to return the geometry as
5060 returned by Fx_frame_geometry. */
5062 frame_geometry (Lisp_Object frame
, Lisp_Object attribute
)
5064 struct frame
*f
= decode_live_frame (frame
);
5065 /** XWindowAttributes atts; **/
5067 unsigned int ign
, native_width
, native_height
, x_border_width
= 0;
5068 int x_native
= 0, y_native
= 0, xptr
= 0, yptr
= 0;
5069 int left_off
= 0, right_off
= 0, top_off
= 0, bottom_off
= 0;
5070 int outer_left
, outer_top
, outer_right
, outer_bottom
;
5071 int native_left
, native_top
, native_right
, native_bottom
;
5072 int inner_left
, inner_top
, inner_right
, inner_bottom
;
5073 int internal_border_width
;
5074 bool menu_bar_external
= false, tool_bar_external
= false;
5075 int menu_bar_height
= 0, menu_bar_width
= 0;
5076 int tool_bar_height
= 0, tool_bar_width
= 0;
5078 if (FRAME_INITIAL_P (f
) || !FRAME_X_P (f
))
5082 XGetGeometry (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
5083 &rootw
, &x_native
, &y_native
, &native_width
, &native_height
,
5084 &x_border_width
, &ign
);
5085 /** XGetWindowAttributes (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &atts); **/
5086 if (!FRAME_PARENT_FRAME (f
))
5087 x_real_pos_and_offsets (f
, &left_off
, &right_off
, &top_off
, &bottom_off
,
5088 NULL
, NULL
, &xptr
, &yptr
, NULL
);
5091 /** native_width = atts.width; **/
5092 /** native_height = atts.height; **/
5094 if (FRAME_PARENT_FRAME (f
))
5096 Lisp_Object parent
, edges
;
5098 XSETFRAME (parent
, FRAME_PARENT_FRAME (f
));
5099 edges
= Fx_frame_edges (parent
, Qnative_edges
);
5102 x_native
+= XINT (Fnth (make_number (0), edges
));
5103 y_native
+= XINT (Fnth (make_number (1), edges
));
5106 outer_left
= x_native
;
5107 outer_top
= y_native
;
5108 outer_right
= outer_left
+ native_width
+ 2 * x_border_width
;
5109 outer_bottom
= outer_top
+ native_height
+ 2 * x_border_width
;
5111 native_left
= x_native
+ x_border_width
;
5112 native_top
= y_native
+ x_border_width
;
5113 native_right
= native_left
+ native_width
;
5114 native_bottom
= native_top
+ native_height
;
5120 outer_right
= outer_left
+ left_off
+ native_width
+ right_off
;
5121 outer_bottom
= outer_top
+ top_off
+ native_height
+ bottom_off
;
5123 native_left
= outer_left
+ left_off
;
5124 native_top
= outer_top
+ top_off
;
5125 native_right
= native_left
+ native_width
;
5126 native_bottom
= native_top
+ native_height
;
5129 internal_border_width
= FRAME_INTERNAL_BORDER_WIDTH (f
);
5130 inner_left
= native_left
+ internal_border_width
;
5131 inner_top
= native_top
+ internal_border_width
;
5132 inner_right
= native_right
- internal_border_width
;
5133 inner_bottom
= native_bottom
- internal_border_width
;
5135 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
5136 menu_bar_external
= true;
5137 menu_bar_height
= FRAME_MENUBAR_HEIGHT (f
);
5138 native_top
+= menu_bar_height
;
5139 inner_top
+= menu_bar_height
;
5141 menu_bar_height
= FRAME_MENU_BAR_HEIGHT (f
);
5142 inner_top
+= menu_bar_height
;
5144 menu_bar_width
= menu_bar_height
? native_width
: 0;
5146 #if defined (USE_GTK)
5147 tool_bar_external
= true;
5148 if (EQ (FRAME_TOOL_BAR_POSITION (f
), Qleft
))
5150 tool_bar_width
= FRAME_TOOLBAR_WIDTH (f
);
5151 native_left
+= tool_bar_width
;
5152 inner_left
+= tool_bar_width
;
5154 = tool_bar_width
? native_height
- menu_bar_height
: 0;
5156 else if (EQ (FRAME_TOOL_BAR_POSITION (f
), Qtop
))
5158 tool_bar_height
= FRAME_TOOLBAR_HEIGHT (f
);
5159 native_top
+= tool_bar_height
;
5160 inner_top
+= tool_bar_height
;
5161 tool_bar_width
= tool_bar_height
? native_width
: 0;
5163 else if (EQ (FRAME_TOOL_BAR_POSITION (f
), Qright
))
5165 tool_bar_width
= FRAME_TOOLBAR_WIDTH (f
);
5166 native_right
-= tool_bar_width
;
5167 inner_right
-= tool_bar_width
;
5169 = tool_bar_width
? native_height
- menu_bar_height
: 0;
5173 tool_bar_height
= FRAME_TOOLBAR_HEIGHT (f
);
5174 native_bottom
-= tool_bar_height
;
5175 inner_bottom
-= tool_bar_height
;
5176 tool_bar_width
= tool_bar_height
? native_width
: 0;
5179 tool_bar_height
= FRAME_TOOL_BAR_HEIGHT (f
);
5180 tool_bar_width
= (tool_bar_height
5181 ? native_width
- 2 * internal_border_width
5183 inner_top
+= tool_bar_height
;
5186 /* Construct list. */
5187 if (EQ (attribute
, Qouter_edges
))
5188 return list4 (make_number (outer_left
), make_number (outer_top
),
5189 make_number (outer_right
), make_number (outer_bottom
));
5190 else if (EQ (attribute
, Qnative_edges
))
5191 return list4 (make_number (native_left
), make_number (native_top
),
5192 make_number (native_right
), make_number (native_bottom
));
5193 else if (EQ (attribute
, Qinner_edges
))
5194 return list4 (make_number (inner_left
), make_number (inner_top
),
5195 make_number (inner_right
), make_number (inner_bottom
));
5198 listn (CONSTYPE_HEAP
, 11,
5199 Fcons (Qouter_position
,
5200 Fcons (make_number (outer_left
),
5201 make_number (outer_top
))),
5203 Fcons (make_number (outer_right
- outer_left
),
5204 make_number (outer_bottom
- outer_top
))),
5206 Fcons (Qexternal_border_size
,
5207 Fcons (make_number (right_off
),
5208 make_number (bottom_off
))),
5209 Fcons (Qouter_border_width
, make_number (x_border_width
)),
5211 Fcons (Qtitle_bar_size
,
5212 Fcons (make_number (0),
5213 make_number (top_off
- bottom_off
))),
5214 Fcons (Qmenu_bar_external
, menu_bar_external
? Qt
: Qnil
),
5215 Fcons (Qmenu_bar_size
,
5216 Fcons (make_number (menu_bar_width
),
5217 make_number (menu_bar_height
))),
5218 Fcons (Qtool_bar_external
, tool_bar_external
? Qt
: Qnil
),
5219 Fcons (Qtool_bar_position
, FRAME_TOOL_BAR_POSITION (f
)),
5220 Fcons (Qtool_bar_size
,
5221 Fcons (make_number (tool_bar_width
),
5222 make_number (tool_bar_height
))),
5223 Fcons (Qinternal_border_width
,
5224 make_number (internal_border_width
)));
5227 DEFUN ("x-frame-geometry", Fx_frame_geometry
, Sx_frame_geometry
, 0, 1, 0,
5228 doc
: /* Return geometric attributes of FRAME.
5229 FRAME must be a live frame and defaults to the selected one. The return
5230 value is an association list of the attributes listed below. All height
5231 and width values are in pixels.
5233 `outer-position' is a cons of the outer left and top edges of FRAME
5234 relative to the origin - the position (0, 0) - of FRAME's display.
5236 `outer-size' is a cons of the outer width and height of FRAME. The
5237 outer size includes the title bar and the external borders as well as
5238 any menu and/or tool bar of frame. For a child frame the value
5239 includes FRAME's X borders, if any.
5241 `external-border-size' is a cons of the horizontal and vertical width of
5242 FRAME's external borders as supplied by the window manager.
5244 `title-bar-size' is a cons of the width and height of the title bar of
5245 FRAME as supplied by the window manager. If both of them are zero,
5246 FRAME has no title bar. If only the width is zero, Emacs was not
5247 able to retrieve the width information.
5249 `menu-bar-external', if non-nil, means the menu bar is external (never
5250 included in the inner edges of FRAME).
5252 `menu-bar-size' is a cons of the width and height of the menu bar of
5255 `tool-bar-external', if non-nil, means the tool bar is external (never
5256 included in the inner edges of FRAME).
5258 `tool-bar-position' tells on which side the tool bar on FRAME is and can
5259 be one of `left', `top', `right' or `bottom'. If this is nil, FRAME
5262 `tool-bar-size' is a cons of the width and height of the tool bar of
5265 `internal-border-width' is the width of the internal border of
5268 `outer-border-width' is the width of the X border of FRAME. The X
5269 border is usually only shown for frames without window manager
5270 decorations like child and tooltip frames. */)
5273 return frame_geometry (frame
, Qnil
);
5276 DEFUN ("x-frame-edges", Fx_frame_edges
, Sx_frame_edges
, 0, 2, 0,
5277 doc
: /* Return edge coordinates of FRAME.
5278 FRAME must be a live frame and defaults to the selected one. The return
5279 value is a list of the form (LEFT, TOP, RIGHT, BOTTOM). All values are
5280 in pixels relative to the origin - the position (0, 0) - of FRAME's
5283 If optional argument TYPE is the symbol `outer-edges', return the outer
5284 edges of FRAME. The outer edges comprise the decorations of the window
5285 manager (like the title bar or external borders) as well as any external
5286 menu or tool bar of FRAME. If optional argument TYPE is the symbol
5287 `native-edges' or nil, return the native edges of FRAME. The native
5288 edges exclude the decorations of the window manager and any external
5289 menu or tool bar of FRAME. If TYPE is the symbol `inner-edges', return
5290 the inner edges of FRAME. These edges exclude title bar, any borders,
5291 menu bar or tool bar of FRAME. */)
5292 (Lisp_Object frame
, Lisp_Object type
)
5294 return frame_geometry (frame
, ((EQ (type
, Qouter_edges
)
5295 || EQ (type
, Qinner_edges
))
5301 * x_frame_list_z_order:
5303 * Recursively add list of all frames on the display specified via
5304 * DPYINFO and whose window-system window's parent is specified by
5305 * WINDOW to FRAMES and return FRAMES.
5308 x_frame_list_z_order (Display
* dpy
, Window window
)
5310 Window root
, parent
, *children
;
5311 unsigned int nchildren
;
5313 Lisp_Object frames
= Qnil
;
5316 if (XQueryTree (dpy
, window
, &root
, &parent
, &children
, &nchildren
))
5319 for (i
= 0; i
< nchildren
; i
++)
5321 Lisp_Object frame
, tail
;
5323 FOR_EACH_FRAME (tail
, frame
)
5325 struct frame
*cf
= XFRAME (frame
);
5326 /* With a reparenting window manager the parent_desc
5327 field usually specifies the topmost windows of our
5328 frames. Otherwise FRAME_OUTER_WINDOW should do. */
5330 && (cf
->output_data
.x
->parent_desc
== children
[i
]
5331 || FRAME_OUTER_WINDOW (cf
) == children
[i
]))
5332 frames
= Fcons (frame
, frames
);
5336 if (children
) XFree ((char *)children
);
5345 DEFUN ("x-frame-list-z-order", Fx_frame_list_z_order
,
5346 Sx_frame_list_z_order
, 0, 1, 0,
5347 doc
: /* Return list of Emacs' frames, in Z (stacking) order.
5348 The optional argument TERMINAL specifies which display to ask about.
5349 TERMINAL should be either a frame or a display name (a string). If
5350 omitted or nil, that stands for the selected frame's display. Return
5351 nil if TERMINAL contains no Emacs frame.
5353 As a special case, if TERMINAL is non-nil and specifies a live frame,
5354 return the child frames of that frame in Z (stacking) order.
5356 Frames are listed from topmost (first) to bottommost (last). */)
5357 (Lisp_Object terminal
)
5359 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
5360 Display
*dpy
= dpyinfo
->display
;
5363 if (FRAMEP (terminal
) && FRAME_LIVE_P (XFRAME (terminal
)))
5364 window
= FRAME_X_WINDOW (XFRAME (terminal
));
5366 window
= dpyinfo
->root_window
;
5368 return x_frame_list_z_order (dpy
, window
);
5374 * Restack frame F1 below frame F2, above if ABOVE_FLAG is non-nil. In
5375 * practice this is a two-step action: The first step removes F1's
5376 * window-system window from the display. The second step reinserts
5377 * F1's window below (above if ABOVE_FLAG is true) that of F2.
5380 x_frame_restack (struct frame
*f1
, struct frame
*f2
, bool above_flag
)
5382 #if defined (USE_GTK) && GTK_CHECK_VERSION (2, 18, 0)
5384 xg_frame_restack (f1
, f2
, above_flag
);
5387 Display
*dpy
= FRAME_X_DISPLAY (f1
);
5388 Window window1
= FRAME_OUTER_WINDOW (f1
);
5390 unsigned long mask
= (CWSibling
| CWStackMode
);
5392 wc
.sibling
= FRAME_OUTER_WINDOW (f2
);
5393 wc
.stack_mode
= above_flag
? Above
: Below
;
5395 /* Configure the window manager window (a normal XConfigureWindow
5396 won't cut it). This should also work for child frames. */
5397 XReconfigureWMWindow (dpy
, window1
, FRAME_X_SCREEN_NUMBER (f1
), mask
, &wc
);
5399 #endif /* USE_GTK */
5403 DEFUN ("x-frame-restack", Fx_frame_restack
, Sx_frame_restack
, 2, 3, 0,
5404 doc
: /* Restack FRAME1 below FRAME2.
5405 This means that if both frames are visible and the display areas of
5406 these frames overlap, FRAME2 (partially) obscures FRAME1. If optional
5407 third argument ABOVE is non-nil, restack FRAME1 above FRAME2. This
5408 means that if both frames are visible and the display areas of these
5409 frames overlap, FRAME1 (partially) obscures FRAME2.
5411 This may be thought of as an atomic action performed in two steps: The
5412 first step removes FRAME1's window-step window from the display. The
5413 second step reinserts FRAME1's window below (above if ABOVE is true)
5414 that of FRAME2. Hence the position of FRAME2 in its display's Z
5415 \(stacking) order relative to all other frames excluding FRAME1 remains
5418 Some window managers may refuse to restack windows. */)
5419 (Lisp_Object frame1
, Lisp_Object frame2
, Lisp_Object above
)
5421 struct frame
*f1
= decode_live_frame (frame1
);
5422 struct frame
*f2
= decode_live_frame (frame2
);
5424 if (FRAME_OUTER_WINDOW (f1
) && FRAME_OUTER_WINDOW (f2
))
5426 x_frame_restack (f1
, f2
, !NILP (above
));
5431 error ("Cannot restack frames");
5437 DEFUN ("x-mouse-absolute-pixel-position", Fx_mouse_absolute_pixel_position
,
5438 Sx_mouse_absolute_pixel_position
, 0, 0, 0,
5439 doc
: /* Return absolute position of mouse cursor in pixels.
5440 The position is returned as a cons cell (X . Y) of the coordinates of
5441 the mouse cursor position in pixels relative to a position (0, 0) of the
5442 selected frame's display. */)
5445 struct frame
*f
= SELECTED_FRAME ();
5446 Window root
, dummy_window
;
5449 if (FRAME_INITIAL_P (f
) || !FRAME_X_P (f
))
5453 XQueryPointer (FRAME_X_DISPLAY (f
),
5454 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
5455 &root
, &dummy_window
, &x
, &y
, &dummy
, &dummy
,
5456 (unsigned int *) &dummy
);
5459 return Fcons (make_number (x
), make_number (y
));
5462 DEFUN ("x-set-mouse-absolute-pixel-position", Fx_set_mouse_absolute_pixel_position
,
5463 Sx_set_mouse_absolute_pixel_position
, 2, 2, 0,
5464 doc
: /* Move mouse pointer to absolute pixel position (X, Y).
5465 The coordinates X and Y are interpreted in pixels relative to a position
5466 \(0, 0) of the selected frame's display. */)
5467 (Lisp_Object x
, Lisp_Object y
)
5469 struct frame
*f
= SELECTED_FRAME ();
5471 if (FRAME_INITIAL_P (f
) || !FRAME_X_P (f
))
5474 CHECK_TYPE_RANGED_INTEGER (int, x
);
5475 CHECK_TYPE_RANGED_INTEGER (int, y
);
5478 XWarpPointer (FRAME_X_DISPLAY (f
), None
, DefaultRootWindow (FRAME_X_DISPLAY (f
)),
5479 0, 0, 0, 0, XINT (x
), XINT (y
));
5485 /************************************************************************
5487 ************************************************************************/
5490 /* Mapping visual names to visuals. */
5492 static struct visual_class
5499 {"StaticGray", StaticGray
},
5500 {"GrayScale", GrayScale
},
5501 {"StaticColor", StaticColor
},
5502 {"PseudoColor", PseudoColor
},
5503 {"TrueColor", TrueColor
},
5504 {"DirectColor", DirectColor
},
5509 #ifndef HAVE_XSCREENNUMBEROFSCREEN
5511 /* Value is the screen number of screen SCR. This is a substitute for
5512 the X function with the same name when that doesn't exist. */
5515 XScreenNumberOfScreen (scr
)
5516 register Screen
*scr
;
5518 Display
*dpy
= scr
->display
;
5521 for (i
= 0; i
< dpy
->nscreens
; ++i
)
5522 if (scr
== dpy
->screens
+ i
)
5528 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
5531 /* Select the visual that should be used on display DPYINFO. Set
5532 members of DPYINFO appropriately. Called from x_term_init. */
5535 select_visual (struct x_display_info
*dpyinfo
)
5537 Display
*dpy
= dpyinfo
->display
;
5538 Screen
*screen
= dpyinfo
->screen
;
5540 /* See if a visual is specified. */
5541 AUTO_STRING (visualClass
, "visualClass");
5542 AUTO_STRING (VisualClass
, "VisualClass");
5543 Lisp_Object value
= display_x_get_resource (dpyinfo
, visualClass
,
5544 VisualClass
, Qnil
, Qnil
);
5546 if (STRINGP (value
))
5548 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
5549 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
5550 depth, a decimal number. NAME is compared with case ignored. */
5551 char *s
= alloca (SBYTES (value
) + 1);
5556 lispstpcpy (s
, value
);
5557 dash
= strchr (s
, '-');
5560 dpyinfo
->n_planes
= atoi (dash
+ 1);
5564 /* We won't find a matching visual with depth 0, so that
5565 an error will be printed below. */
5566 dpyinfo
->n_planes
= 0;
5568 /* Determine the visual class. */
5569 for (i
= 0; visual_classes
[i
].name
; ++i
)
5570 if (xstrcasecmp (s
, visual_classes
[i
].name
) == 0)
5572 class = visual_classes
[i
].class;
5576 /* Look up a matching visual for the specified class. */
5578 || !XMatchVisualInfo (dpy
, XScreenNumberOfScreen (screen
),
5579 dpyinfo
->n_planes
, class, &vinfo
))
5580 fatal ("Invalid visual specification '%s'",
5581 SSDATA (ENCODE_SYSTEM (value
)));
5583 dpyinfo
->visual
= vinfo
.visual
;
5588 XVisualInfo
*vinfo
, vinfo_template
;
5590 dpyinfo
->visual
= DefaultVisualOfScreen (screen
);
5592 vinfo_template
.visualid
= XVisualIDFromVisual (dpyinfo
->visual
);
5593 vinfo_template
.screen
= XScreenNumberOfScreen (screen
);
5594 vinfo
= XGetVisualInfo (dpy
, VisualIDMask
| VisualScreenMask
,
5595 &vinfo_template
, &n_visuals
);
5597 fatal ("Can't get proper X visual info");
5599 dpyinfo
->n_planes
= vinfo
->depth
;
5605 /* Return the X display structure for the display named NAME.
5606 Open a new connection if necessary. */
5608 static struct x_display_info
*
5609 x_display_info_for_name (Lisp_Object name
)
5611 struct x_display_info
*dpyinfo
;
5613 CHECK_STRING (name
);
5615 for (dpyinfo
= x_display_list
; dpyinfo
; dpyinfo
= dpyinfo
->next
)
5616 if (!NILP (Fstring_equal (XCAR (dpyinfo
->name_list_element
), name
)))
5619 /* Use this general default value to start with. */
5620 Vx_resource_name
= Vinvocation_name
;
5622 validate_x_resource_name ();
5624 dpyinfo
= x_term_init (name
, 0, SSDATA (Vx_resource_name
));
5627 error ("Cannot connect to X server %s", SDATA (name
));
5629 XSETFASTINT (Vwindow_system_version
, 11);
5635 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
5637 doc
: /* Open a connection to a display server.
5638 DISPLAY is the name of the display to connect to.
5639 Optional second arg XRM-STRING is a string of resources in xrdb format.
5640 If the optional third arg MUST-SUCCEED is non-nil,
5641 terminate Emacs if we can't open the connection.
5642 \(In the Nextstep version, the last two arguments are currently ignored.) */)
5643 (Lisp_Object display
, Lisp_Object xrm_string
, Lisp_Object must_succeed
)
5646 struct x_display_info
*dpyinfo
;
5648 CHECK_STRING (display
);
5649 if (! NILP (xrm_string
))
5650 CHECK_STRING (xrm_string
);
5652 xrm_option
= NILP (xrm_string
) ? 0 : SSDATA (xrm_string
);
5654 validate_x_resource_name ();
5656 /* This is what opens the connection and sets x_current_display.
5657 This also initializes many symbols, such as those used for input. */
5658 dpyinfo
= x_term_init (display
, xrm_option
,
5659 SSDATA (Vx_resource_name
));
5663 if (!NILP (must_succeed
))
5664 fatal ("Cannot connect to X server %s.\n\
5665 Check the DISPLAY environment variable or use `-d'.\n\
5666 Also use the `xauth' program to verify that you have the proper\n\
5667 authorization information needed to connect the X server.\n\
5668 An insecure way to solve the problem may be to use `xhost'.\n",
5671 error ("Cannot connect to X server %s", SDATA (display
));
5674 XSETFASTINT (Vwindow_system_version
, 11);
5678 DEFUN ("x-close-connection", Fx_close_connection
,
5679 Sx_close_connection
, 1, 1, 0,
5680 doc
: /* Close the connection to TERMINAL's X server.
5681 For TERMINAL, specify a terminal object, a frame or a display name (a
5682 string). If TERMINAL is nil, that stands for the selected frame's terminal.
5683 \(On MS Windows, this function does not accept terminal objects.) */)
5684 (Lisp_Object terminal
)
5686 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
5688 if (dpyinfo
->reference_count
> 0)
5689 error ("Display still has frames on it");
5691 x_delete_terminal (dpyinfo
->terminal
);
5696 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
5697 doc
: /* Return the list of display names that Emacs has connections to. */)
5700 Lisp_Object result
= Qnil
;
5701 struct x_display_info
*xdi
;
5703 for (xdi
= x_display_list
; xdi
; xdi
= xdi
->next
)
5704 result
= Fcons (XCAR (xdi
->name_list_element
), result
);
5709 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
5710 doc
: /* If ON is non-nil, report X errors as soon as the erring request is made.
5711 This function only has an effect on X Windows. With MS Windows, it is
5712 defined but does nothing.
5714 If ON is nil, allow buffering of requests.
5715 Turning on synchronization prohibits the Xlib routines from buffering
5716 requests and seriously degrades performance, but makes debugging much
5718 The optional second argument TERMINAL specifies which display to act on.
5719 TERMINAL should be a terminal object, a frame or a display name (a string).
5720 If TERMINAL is omitted or nil, that stands for the selected frame's display. */)
5721 (Lisp_Object on
, Lisp_Object terminal
)
5723 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
5725 XSynchronize (dpyinfo
->display
, !EQ (on
, Qnil
));
5730 /* Wait for responses to all X commands issued so far for frame F. */
5733 x_sync (struct frame
*f
)
5736 XSync (FRAME_X_DISPLAY (f
), False
);
5741 /***********************************************************************
5743 ***********************************************************************/
5745 DEFUN ("x-change-window-property", Fx_change_window_property
,
5746 Sx_change_window_property
, 2, 6, 0,
5747 doc
: /* Change window property PROP to VALUE on the X window of FRAME.
5748 PROP must be a string. VALUE may be a string or a list of conses,
5749 numbers and/or strings. If an element in the list is a string, it is
5750 converted to an atom and the value of the atom is used. If an element
5751 is a cons, it is converted to a 32 bit number where the car is the 16
5752 top bits and the cdr is the lower 16 bits.
5754 FRAME nil or omitted means use the selected frame.
5755 If TYPE is given and non-nil, it is the name of the type of VALUE.
5756 If TYPE is not given or nil, the type is STRING.
5757 FORMAT gives the size in bits of each element if VALUE is a list.
5758 It must be one of 8, 16 or 32.
5759 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
5760 If OUTER-P is non-nil, the property is changed for the outer X window of
5761 FRAME. Default is to change on the edit X window. */)
5762 (Lisp_Object prop
, Lisp_Object value
, Lisp_Object frame
,
5763 Lisp_Object type
, Lisp_Object format
, Lisp_Object outer_p
)
5765 struct frame
*f
= decode_window_system_frame (frame
);
5767 Atom target_type
= XA_STRING
;
5768 int element_format
= 8;
5769 unsigned char *data
;
5773 CHECK_STRING (prop
);
5775 if (! NILP (format
))
5777 CHECK_NUMBER (format
);
5779 if (XINT (format
) != 8 && XINT (format
) != 16
5780 && XINT (format
) != 32)
5781 error ("FORMAT must be one of 8, 16 or 32");
5782 element_format
= XINT (format
);
5789 nelements
= x_check_property_data (value
);
5790 if (nelements
== -1)
5791 error ("Bad data in VALUE, must be number, string or cons");
5793 /* The man page for XChangeProperty:
5794 "If the specified format is 32, the property data must be a
5796 This applies even if long is more than 32 bits. The X library
5797 converts to 32 bits before sending to the X server. */
5798 elsize
= element_format
== 32 ? sizeof (long) : element_format
>> 3;
5799 data
= xnmalloc (nelements
, elsize
);
5801 x_fill_property_data (FRAME_X_DISPLAY (f
), value
, data
, element_format
);
5807 CHECK_STRING (value
);
5808 data
= SDATA (value
);
5809 if (INT_MAX
< SBYTES (value
))
5810 error ("VALUE too long");
5812 /* See comment above about longs and format=32 */
5813 elsize
= element_format
== 32 ? sizeof (long) : element_format
>> 3;
5814 if (SBYTES (value
) % elsize
!= 0)
5815 error ("VALUE must contain an integral number of octets for FORMAT");
5816 nelements
= SBYTES (value
) / elsize
;
5820 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (prop
), False
);
5823 CHECK_STRING (type
);
5824 target_type
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (type
), False
);
5827 if (! NILP (outer_p
)) w
= FRAME_OUTER_WINDOW (f
);
5828 else w
= FRAME_X_WINDOW (f
);
5830 XChangeProperty (FRAME_X_DISPLAY (f
), w
,
5831 prop_atom
, target_type
, element_format
, PropModeReplace
,
5834 if (CONSP (value
)) xfree (data
);
5836 /* Make sure the property is set when we return. */
5837 XFlush (FRAME_X_DISPLAY (f
));
5844 DEFUN ("x-delete-window-property", Fx_delete_window_property
,
5845 Sx_delete_window_property
, 1, 2, 0,
5846 doc
: /* Remove window property PROP from X window of FRAME.
5847 FRAME nil or omitted means use the selected frame. Value is PROP. */)
5848 (Lisp_Object prop
, Lisp_Object frame
)
5850 struct frame
*f
= decode_window_system_frame (frame
);
5853 CHECK_STRING (prop
);
5855 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (prop
), False
);
5856 XDeleteProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), prop_atom
);
5858 /* Make sure the property is removed when we return. */
5859 XFlush (FRAME_X_DISPLAY (f
));
5867 x_window_property_intern (struct frame
*f
,
5868 Window target_window
,
5871 Lisp_Object delete_p
,
5872 Lisp_Object vector_ret_p
,
5875 unsigned char *tmp_data
= NULL
;
5876 Lisp_Object prop_value
= Qnil
;
5879 unsigned long actual_size
, bytes_remaining
;
5882 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), target_window
,
5883 prop_atom
, 0, 0, False
, target_type
,
5884 &actual_type
, &actual_format
, &actual_size
,
5885 &bytes_remaining
, &tmp_data
);
5887 *found
= actual_format
!= 0;
5889 if (rc
== Success
&& *found
)
5894 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), target_window
,
5895 prop_atom
, 0, bytes_remaining
,
5896 ! NILP (delete_p
), target_type
,
5897 &actual_type
, &actual_format
,
5898 &actual_size
, &bytes_remaining
,
5900 if (rc
== Success
&& tmp_data
)
5902 /* The man page for XGetWindowProperty says:
5903 "If the returned format is 32, the returned data is represented
5904 as a long array and should be cast to that type to obtain the
5906 This applies even if long is more than 32 bits, the X library
5907 converts from 32 bit elements received from the X server to long
5908 and passes the long array to us. Thus, for that case memcpy can not
5909 be used. We convert to a 32 bit type here, because so much code
5912 The bytes and offsets passed to XGetWindowProperty refers to the
5913 property and those are indeed in 32 bit quantities if format is
5916 if (LONG_WIDTH
> 32 && actual_format
== 32)
5919 int *idata
= (int *) tmp_data
;
5920 long *ldata
= (long *) tmp_data
;
5922 for (i
= 0; i
< actual_size
; ++i
)
5923 idata
[i
] = (int) ldata
[i
];
5926 if (NILP (vector_ret_p
))
5927 prop_value
= make_string ((char *) tmp_data
,
5928 (actual_format
>> 3) * actual_size
);
5930 prop_value
= x_property_data_to_lisp (f
,
5937 if (tmp_data
) XFree (tmp_data
);
5943 DEFUN ("x-window-property", Fx_window_property
, Sx_window_property
,
5945 doc
: /* Value is the value of window property PROP on FRAME.
5946 If FRAME is nil or omitted, use the selected frame.
5948 On X Windows, the following optional arguments are also accepted:
5949 If TYPE is nil or omitted, get the property as a string.
5950 Otherwise TYPE is the name of the atom that denotes the type expected.
5951 If SOURCE is non-nil, get the property on that window instead of from
5952 FRAME. The number 0 denotes the root window.
5953 If DELETE-P is non-nil, delete the property after retrieving it.
5954 If VECTOR-RET-P is non-nil, don't return a string but a vector of values.
5956 Value is nil if FRAME hasn't a property with name PROP or if PROP has
5957 no value of TYPE (always string in the MS Windows case). */)
5958 (Lisp_Object prop
, Lisp_Object frame
, Lisp_Object type
,
5959 Lisp_Object source
, Lisp_Object delete_p
, Lisp_Object vector_ret_p
)
5961 struct frame
*f
= decode_window_system_frame (frame
);
5963 Lisp_Object prop_value
= Qnil
;
5964 Atom target_type
= XA_STRING
;
5965 Window target_window
= FRAME_X_WINDOW (f
);
5968 CHECK_STRING (prop
);
5970 if (! NILP (source
))
5972 CONS_TO_INTEGER (source
, Window
, target_window
);
5973 if (! target_window
)
5974 target_window
= FRAME_DISPLAY_INFO (f
)->root_window
;
5980 if (strcmp ("AnyPropertyType", SSDATA (type
)) == 0)
5981 target_type
= AnyPropertyType
;
5983 target_type
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (type
), False
);
5986 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (prop
), False
);
5987 prop_value
= x_window_property_intern (f
,
5994 if (NILP (prop_value
)
5997 && target_window
!= FRAME_OUTER_WINDOW (f
))
5999 prop_value
= x_window_property_intern (f
,
6000 FRAME_OUTER_WINDOW (f
),
6013 DEFUN ("x-window-property-attributes", Fx_window_property_attributes
, Sx_window_property_attributes
,
6015 doc
: /* Retrieve metadata about window property PROP on FRAME.
6016 If FRAME is nil or omitted, use the selected frame.
6017 If SOURCE is non-nil, get the property on that window instead of from
6018 FRAME. The number 0 denotes the root window.
6020 Return value is nil if FRAME hasn't a property with name PROP.
6021 Otherwise, the return value is a vector with the following fields:
6023 0. The property type, as an integer. The symbolic name of
6024 the type can be obtained with `x-get-atom-name'.
6025 1. The format of each element; one of 8, 16, or 32.
6026 2. The length of the property, in number of elements. */)
6027 (Lisp_Object prop
, Lisp_Object frame
, Lisp_Object source
)
6029 struct frame
*f
= decode_window_system_frame (frame
);
6030 Window target_window
= FRAME_X_WINDOW (f
);
6032 Lisp_Object prop_attr
= Qnil
;
6035 unsigned long actual_size
, bytes_remaining
;
6036 unsigned char *tmp_data
= NULL
;
6039 CHECK_STRING (prop
);
6041 if (! NILP (source
))
6043 CONS_TO_INTEGER (source
, Window
, target_window
);
6044 if (! target_window
)
6045 target_window
= FRAME_DISPLAY_INFO (f
)->root_window
;
6050 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (prop
), False
);
6051 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), target_window
,
6052 prop_atom
, 0, 0, False
, AnyPropertyType
,
6053 &actual_type
, &actual_format
, &actual_size
,
6054 &bytes_remaining
, &tmp_data
);
6055 if (rc
== Success
/* no invalid params */
6056 && actual_format
== 0 /* but prop not found */
6058 && target_window
!= FRAME_OUTER_WINDOW (f
))
6060 /* analogous behavior to x-window-property: if property isn't found
6061 on the frame's inner window and no alternate window id was
6062 provided, try the frame's outer window. */
6063 target_window
= FRAME_OUTER_WINDOW (f
);
6064 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), target_window
,
6065 prop_atom
, 0, 0, False
, AnyPropertyType
,
6066 &actual_type
, &actual_format
, &actual_size
,
6067 &bytes_remaining
, &tmp_data
);
6070 if (rc
== Success
&& actual_format
!= 0)
6074 prop_attr
= make_uninit_vector (3);
6075 ASET (prop_attr
, 0, make_number (actual_type
));
6076 ASET (prop_attr
, 1, make_number (actual_format
));
6077 ASET (prop_attr
, 2, make_number (bytes_remaining
/ (actual_format
>> 3)));
6084 /***********************************************************************
6086 ***********************************************************************/
6088 static void compute_tip_xy (struct frame
*, Lisp_Object
, Lisp_Object
,
6089 Lisp_Object
, int, int, int *, int *);
6091 /* The frame of the currently visible tooltip. */
6092 static Lisp_Object tip_frame
;
6094 /* The window-system window corresponding to the frame of the
6095 currently visible tooltip. */
6098 /* A timer that hides or deletes the currently visible tooltip when it
6100 static Lisp_Object tip_timer
;
6102 /* STRING argument of last `x-show-tip' call. */
6103 static Lisp_Object tip_last_string
;
6105 /* Normalized FRAME argument of last `x-show-tip' call. */
6106 static Lisp_Object tip_last_frame
;
6108 /* PARMS argument of last `x-show-tip' call. */
6109 static Lisp_Object tip_last_parms
;
6113 unwind_create_tip_frame (Lisp_Object frame
)
6115 Lisp_Object deleted
;
6117 deleted
= unwind_create_frame (frame
);
6118 if (EQ (deleted
, Qt
))
6126 /* Create a frame for a tooltip on the display described by DPYINFO.
6127 PARMS is a list of frame parameters. TEXT is the string to
6128 display in the tip frame. Value is the frame.
6130 Note that functions called here, esp. x_default_parameter can
6131 signal errors, for instance when a specified color name is
6132 undefined. We have to make sure that we're in a consistent state
6133 when this happens. */
6136 x_create_tip_frame (struct x_display_info
*dpyinfo
, Lisp_Object parms
)
6142 ptrdiff_t count
= SPECPDL_INDEX ();
6143 bool face_change_before
= face_change
;
6144 int x_width
= 0, x_height
= 0;
6146 if (!dpyinfo
->terminal
->name
)
6147 error ("Terminal is not live, can't create new frames on it");
6149 parms
= Fcopy_alist (parms
);
6151 /* Get the name of the frame to use for resource lookup. */
6152 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
6154 && !EQ (name
, Qunbound
)
6156 error ("Invalid frame name--not a string or nil");
6159 f
= make_frame (false);
6160 f
->wants_modeline
= false;
6161 XSETFRAME (frame
, f
);
6162 record_unwind_protect (unwind_create_tip_frame
, frame
);
6164 f
->terminal
= dpyinfo
->terminal
;
6166 /* By setting the output method, we're essentially saying that
6167 the frame is live, as per FRAME_LIVE_P. If we get a signal
6168 from this point on, x_destroy_window might screw up reference
6170 f
->output_method
= output_x_window
;
6171 f
->output_data
.x
= xzalloc (sizeof *f
->output_data
.x
);
6172 f
->output_data
.x
->icon_bitmap
= -1;
6173 FRAME_FONTSET (f
) = -1;
6174 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
6175 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
6176 #if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
6177 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
6178 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
6179 #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
6180 f
->output_data
.x
->white_relief
.pixel
= -1;
6181 f
->output_data
.x
->black_relief
.pixel
= -1;
6184 fset_icon_name (f
, Qnil
);
6185 FRAME_DISPLAY_INFO (f
) = dpyinfo
;
6186 f
->output_data
.x
->parent_desc
= FRAME_DISPLAY_INFO (f
)->root_window
;
6187 f
->output_data
.x
->explicit_parent
= false;
6189 /* These colors will be set anyway later, but it's important
6190 to get the color reference counts right, so initialize them! */
6194 /* Function x_decode_color can signal an error. Make
6195 sure to initialize color slots so that we won't try
6196 to free colors we haven't allocated. */
6197 FRAME_FOREGROUND_PIXEL (f
) = -1;
6198 FRAME_BACKGROUND_PIXEL (f
) = -1;
6199 f
->output_data
.x
->cursor_pixel
= -1;
6200 f
->output_data
.x
->cursor_foreground_pixel
= -1;
6201 f
->output_data
.x
->border_pixel
= -1;
6202 f
->output_data
.x
->mouse_pixel
= -1;
6204 black
= build_string ("black");
6205 FRAME_FOREGROUND_PIXEL (f
)
6206 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
6207 FRAME_BACKGROUND_PIXEL (f
)
6208 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
6209 f
->output_data
.x
->cursor_pixel
6210 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
6211 f
->output_data
.x
->cursor_foreground_pixel
6212 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
6213 f
->output_data
.x
->border_pixel
6214 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
6215 f
->output_data
.x
->mouse_pixel
6216 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
6219 /* Set the name; the functions to which we pass f expect the name to
6221 if (EQ (name
, Qunbound
) || NILP (name
))
6223 fset_name (f
, build_string (dpyinfo
->x_id_name
));
6224 f
->explicit_name
= false;
6228 fset_name (f
, name
);
6229 f
->explicit_name
= true;
6230 /* use the frame's title when getting resources for this frame. */
6231 specbind (Qx_resource_name
, name
);
6235 register_font_driver (&ftcrfont_driver
, f
);
6237 register_font_driver (&xfont_driver
, f
);
6238 #ifdef HAVE_FREETYPE
6240 register_font_driver (&xftfont_driver
, f
);
6241 #else /* not HAVE_XFT */
6242 register_font_driver (&ftxfont_driver
, f
);
6243 #endif /* not HAVE_XFT */
6244 #endif /* HAVE_FREETYPE */
6245 #endif /* not USE_CAIRO */
6247 image_cache_refcount
=
6248 FRAME_IMAGE_CACHE (f
) ? FRAME_IMAGE_CACHE (f
)->refcount
: 0;
6250 dpyinfo_refcount
= dpyinfo
->reference_count
;
6251 #endif /* GLYPH_DEBUG */
6253 x_default_parameter (f
, parms
, Qfont_backend
, Qnil
,
6254 "fontBackend", "FontBackend", RES_TYPE_STRING
);
6256 /* Extract the window parameters from the supplied values that are
6257 needed to determine window geometry. */
6258 x_default_font_parameter (f
, parms
);
6260 x_default_parameter (f
, parms
, Qborder_width
, make_number (0),
6261 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
6263 /* This defaults to 2 in order to match xterm. We recognize either
6264 internalBorderWidth or internalBorder (which is what xterm calls
6266 if (NILP (Fassq (Qinternal_border_width
, parms
)))
6270 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
6271 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
6272 if (! EQ (value
, Qunbound
))
6273 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
6277 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
6278 "internalBorderWidth", "internalBorderWidth",
6280 x_default_parameter (f
, parms
, Qright_divider_width
, make_number (0),
6281 NULL
, NULL
, RES_TYPE_NUMBER
);
6282 x_default_parameter (f
, parms
, Qbottom_divider_width
, make_number (0),
6283 NULL
, NULL
, RES_TYPE_NUMBER
);
6285 /* Also do the stuff which must be set before the window exists. */
6286 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
6287 "foreground", "Foreground", RES_TYPE_STRING
);
6288 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
6289 "background", "Background", RES_TYPE_STRING
);
6290 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
6291 "pointerColor", "Foreground", RES_TYPE_STRING
);
6292 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
6293 "cursorColor", "Foreground", RES_TYPE_STRING
);
6294 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
6295 "borderColor", "BorderColor", RES_TYPE_STRING
);
6296 x_default_parameter (f
, parms
, Qno_special_glyphs
, Qnil
,
6297 NULL
, NULL
, RES_TYPE_BOOLEAN
);
6299 /* Init faces before x_default_parameter is called for the
6300 scroll-bar-width parameter because otherwise we end up in
6301 init_iterator with a null face cache, which should not happen. */
6302 init_frame_faces (f
);
6304 f
->output_data
.x
->parent_desc
= FRAME_DISPLAY_INFO (f
)->root_window
;
6306 x_figure_window_size (f
, parms
, false, &x_width
, &x_height
);
6309 XSetWindowAttributes attrs
;
6311 Atom type
= FRAME_DISPLAY_INFO (f
)->Xatom_net_window_type_tooltip
;
6314 mask
= CWBackPixel
| CWOverrideRedirect
| CWEventMask
| CWCursor
;
6315 if (DoesSaveUnders (dpyinfo
->screen
))
6316 mask
|= CWSaveUnder
;
6318 /* Window managers look at the override-redirect flag to determine
6319 whether or net to give windows a decoration (Xlib spec, chapter
6321 attrs
.override_redirect
= True
;
6322 attrs
.save_under
= True
;
6323 attrs
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
6325 f
->output_data
.x
->current_cursor
6326 = f
->output_data
.x
->text_cursor
;
6327 /* Arrange for getting MapNotify and UnmapNotify events. */
6328 attrs
.event_mask
= StructureNotifyMask
;
6330 = FRAME_X_WINDOW (f
)
6331 = XCreateWindow (FRAME_X_DISPLAY (f
),
6332 FRAME_DISPLAY_INFO (f
)->root_window
,
6333 /* x, y, width, height */
6337 CopyFromParent
, InputOutput
, CopyFromParent
,
6339 initial_set_up_x_back_buffer (f
);
6340 XChangeProperty (FRAME_X_DISPLAY (f
), tip_window
,
6341 FRAME_DISPLAY_INFO (f
)->Xatom_net_window_type
,
6342 XA_ATOM
, 32, PropModeReplace
,
6343 (unsigned char *)&type
, 1);
6349 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
6350 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
6351 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
6352 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
6353 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
6354 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
6355 x_default_parameter (f
, parms
, Qalpha
, Qnil
,
6356 "alpha", "Alpha", RES_TYPE_NUMBER
);
6358 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
6359 Change will not be effected unless different from the current
6361 width
= FRAME_COLS (f
);
6362 height
= FRAME_LINES (f
);
6363 SET_FRAME_COLS (f
, 0);
6364 SET_FRAME_LINES (f
, 0);
6365 change_frame_size (f
, width
, height
, true, false, false, false);
6367 /* Add `tooltip' frame parameter's default value. */
6368 if (NILP (Fframe_parameter (frame
, Qtooltip
)))
6370 AUTO_FRAME_ARG (arg
, Qtooltip
, Qt
);
6371 Fmodify_frame_parameters (frame
, arg
);
6374 /* FIXME - can this be done in a similar way to normal frames?
6375 https://lists.gnu.org/r/emacs-devel/2007-10/msg00641.html */
6377 /* Set the `display-type' frame parameter before setting up faces. */
6379 Lisp_Object disptype
;
6381 if (FRAME_DISPLAY_INFO (f
)->n_planes
== 1)
6383 else if (FRAME_DISPLAY_INFO (f
)->visual
->class == GrayScale
6384 || FRAME_DISPLAY_INFO (f
)->visual
->class == StaticGray
)
6385 disptype
= intern ("grayscale");
6387 disptype
= intern ("color");
6389 if (NILP (Fframe_parameter (frame
, Qdisplay_type
)))
6391 AUTO_FRAME_ARG (arg
, Qdisplay_type
, disptype
);
6392 Fmodify_frame_parameters (frame
, arg
);
6396 /* Set up faces after all frame parameters are known. This call
6397 also merges in face attributes specified for new frames.
6399 Frame parameters may be changed if .Xdefaults contains
6400 specifications for the default font. For example, if there is an
6401 `Emacs.default.attributeBackground: pink', the `background-color'
6402 attribute of the frame get's set, which let's the internal border
6403 of the tooltip frame appear in pink. Prevent this. */
6405 Lisp_Object bg
= Fframe_parameter (frame
, Qbackground_color
);
6407 call2 (Qface_set_after_frame_default
, frame
, Qnil
);
6409 if (!EQ (bg
, Fframe_parameter (frame
, Qbackground_color
)))
6411 AUTO_FRAME_ARG (arg
, Qbackground_color
, bg
);
6412 Fmodify_frame_parameters (frame
, arg
);
6418 /* Now that the frame will be official, it counts as a reference to
6419 its display and terminal. */
6420 FRAME_DISPLAY_INFO (f
)->reference_count
++;
6421 f
->terminal
->reference_count
++;
6423 /* It is now ok to make the frame official even if we get an error
6424 below. And the frame needs to be on Vframe_list or making it
6425 visible won't work. */
6426 Vframe_list
= Fcons (frame
, Vframe_list
);
6427 f
->can_x_set_window_size
= true;
6429 /* Setting attributes of faces of the tooltip frame from resources
6430 and similar will set face_change, which leads to the clearing of
6431 all current matrices. Since this isn't necessary here, avoid it
6432 by resetting face_change to the value it had before we created
6434 face_change
= face_change_before
;
6436 /* Discard the unwind_protect. */
6437 return unbind_to (count
, frame
);
6441 /* Compute where to display tip frame F. PARMS is the list of frame
6442 parameters for F. DX and DY are specified offsets from the current
6443 location of the mouse. WIDTH and HEIGHT are the width and height
6444 of the tooltip. Return coordinates relative to the root window of
6445 the display in *ROOT_X, and *ROOT_Y. */
6448 compute_tip_xy (struct frame
*f
,
6449 Lisp_Object parms
, Lisp_Object dx
, Lisp_Object dy
,
6450 int width
, int height
, int *root_x
, int *root_y
)
6452 Lisp_Object left
, top
, right
, bottom
;
6456 int min_x
, min_y
, max_x
, max_y
= -1;
6458 /* User-specified position? */
6459 left
= Fcdr (Fassq (Qleft
, parms
));
6460 top
= Fcdr (Fassq (Qtop
, parms
));
6461 right
= Fcdr (Fassq (Qright
, parms
));
6462 bottom
= Fcdr (Fassq (Qbottom
, parms
));
6464 /* Move the tooltip window where the mouse pointer is. Resize and
6466 if ((!INTEGERP (left
) && !INTEGERP (right
))
6467 || (!INTEGERP (top
) && !INTEGERP (bottom
)))
6469 Lisp_Object frame
, attributes
, monitor
, geometry
;
6472 XQueryPointer (FRAME_X_DISPLAY (f
), FRAME_DISPLAY_INFO (f
)->root_window
,
6473 &root
, &child
, root_x
, root_y
, &win_x
, &win_y
, &pmask
);
6476 XSETFRAME(frame
, f
);
6477 attributes
= Fx_display_monitor_attributes_list (frame
);
6479 /* Try to determine the monitor where the mouse pointer is and
6480 its geometry. See bug#22549. */
6481 while (CONSP (attributes
))
6483 monitor
= XCAR (attributes
);
6484 geometry
= Fassq (Qgeometry
, monitor
);
6485 if (CONSP (geometry
))
6487 min_x
= XINT (Fnth (make_number (1), geometry
));
6488 min_y
= XINT (Fnth (make_number (2), geometry
));
6489 max_x
= min_x
+ XINT (Fnth (make_number (3), geometry
));
6490 max_y
= min_y
+ XINT (Fnth (make_number (4), geometry
));
6491 if (min_x
<= *root_x
&& *root_x
< max_x
6492 && min_y
<= *root_y
&& *root_y
< max_y
)
6499 attributes
= XCDR (attributes
);
6503 /* It was not possible to determine the monitor's geometry, so we
6504 assign some sane defaults here: */
6509 max_x
= x_display_pixel_width (FRAME_DISPLAY_INFO (f
));
6510 max_y
= x_display_pixel_height (FRAME_DISPLAY_INFO (f
));
6514 *root_y
= XINT (top
);
6515 else if (INTEGERP (bottom
))
6516 *root_y
= XINT (bottom
) - height
;
6517 else if (*root_y
+ XINT (dy
) <= min_y
)
6518 *root_y
= min_y
; /* Can happen for negative dy */
6519 else if (*root_y
+ XINT (dy
) + height
<= max_y
)
6520 /* It fits below the pointer */
6521 *root_y
+= XINT (dy
);
6522 else if (height
+ XINT (dy
) + min_y
<= *root_y
)
6523 /* It fits above the pointer. */
6524 *root_y
-= height
+ XINT (dy
);
6526 /* Put it on the top. */
6529 if (INTEGERP (left
))
6530 *root_x
= XINT (left
);
6531 else if (INTEGERP (right
))
6532 *root_x
= XINT (right
) - width
;
6533 else if (*root_x
+ XINT (dx
) <= min_x
)
6534 *root_x
= 0; /* Can happen for negative dx */
6535 else if (*root_x
+ XINT (dx
) + width
<= max_x
)
6536 /* It fits to the right of the pointer. */
6537 *root_x
+= XINT (dx
);
6538 else if (width
+ XINT (dx
) + min_x
<= *root_x
)
6539 /* It fits to the left of the pointer. */
6540 *root_x
-= width
+ XINT (dx
);
6542 /* Put it left justified on the screen -- it ought to fit that way. */
6550 * Hide currently visible tooltip and cancel its timer.
6552 * If GTK+ system tooltips are used, this will try to hide the tooltip
6553 * referenced by the x_output structure of tooltip_last_frame. For
6554 * Emacs tooltips this will try to make tooltip_frame invisible (if
6555 * DELETE is false) or delete tooltip_frame (if DELETE is true).
6557 * Return Qt if the tooltip was either deleted or made invisible, Qnil
6561 x_hide_tip (bool delete)
6563 if (!NILP (tip_timer
))
6565 call1 (Qcancel_timer
, tip_timer
);
6570 /* Any GTK+ system tooltip can be found via the x_output structure of
6571 tip_last_frame, provided that frame is still live. Any Emacs
6572 tooltip is found via the tip_frame variable. Note that the current
6573 value of x_gtk_use_system_tooltips might not be the same as used
6574 for the tooltip we have to hide, see Bug#30399. */
6575 if ((NILP (tip_last_frame
) && NILP (tip_frame
))
6576 || (!x_gtk_use_system_tooltips
6578 && FRAMEP (tip_frame
)
6579 && FRAME_LIVE_P (XFRAME (tip_frame
))
6580 && !FRAME_VISIBLE_P (XFRAME (tip_frame
))))
6581 /* Either there's no tooltip to hide or it's an already invisible
6582 Emacs tooltip and we don't want to change its type. Return
6588 Lisp_Object was_open
= Qnil
;
6590 count
= SPECPDL_INDEX ();
6591 specbind (Qinhibit_redisplay
, Qt
);
6592 specbind (Qinhibit_quit
, Qt
);
6594 /* Try to hide the GTK+ system tip first. */
6595 if (FRAMEP (tip_last_frame
))
6597 struct frame
*f
= XFRAME (tip_last_frame
);
6599 if (FRAME_LIVE_P (f
))
6601 if (xg_hide_tooltip (f
))
6606 /* Reset tip_last_frame, it will be reassigned when showing the
6607 next GTK+ system tooltip. */
6608 tip_last_frame
= Qnil
;
6610 /* Now look whether there's an Emacs tip around. */
6611 if (FRAMEP (tip_frame
))
6613 struct frame
*f
= XFRAME (tip_frame
);
6615 if (FRAME_LIVE_P (f
))
6617 if (delete || x_gtk_use_system_tooltips
)
6619 /* Delete the Emacs tooltip frame when DELETE is true
6620 or we change the tooltip type from an Emacs one to
6621 a GTK+ system one. */
6622 delete_frame (tip_frame
, Qnil
);
6626 x_make_frame_invisible (f
);
6636 return unbind_to (count
, was_open
);
6638 #else /* not USE_GTK */
6639 if (NILP (tip_frame
)
6641 && FRAMEP (tip_frame
)
6642 && FRAME_LIVE_P (XFRAME (tip_frame
))
6643 && !FRAME_VISIBLE_P (XFRAME (tip_frame
))))
6648 Lisp_Object was_open
= Qnil
;
6650 count
= SPECPDL_INDEX ();
6651 specbind (Qinhibit_redisplay
, Qt
);
6652 specbind (Qinhibit_quit
, Qt
);
6654 if (FRAMEP (tip_frame
))
6656 struct frame
*f
= XFRAME (tip_frame
);
6658 if (FRAME_LIVE_P (f
))
6662 delete_frame (tip_frame
, Qnil
);
6666 x_make_frame_invisible (XFRAME (tip_frame
));
6669 /* Bloodcurdling hack alert: The Lucid menu bar widget's
6670 redisplay procedure is not called when a tip frame over
6671 menu items is unmapped. Redisplay the menu manually... */
6674 struct frame
*f
= SELECTED_FRAME ();
6676 if (FRAME_X_P (f
) && FRAME_LIVE_P (f
))
6678 w
= f
->output_data
.x
->menubar_widget
;
6680 if (!DoesSaveUnders (FRAME_DISPLAY_INFO (f
)->screen
)
6684 xlwmenu_redisplay (w
);
6689 #endif /* USE_LUCID */
6699 return unbind_to (count
, was_open
);
6701 #endif /* USE_GTK */
6705 DEFUN ("x-show-tip", Fx_show_tip
, Sx_show_tip
, 1, 6, 0,
6706 doc
: /* Show STRING in a "tooltip" window on frame FRAME.
6707 A tooltip window is a small X window displaying a string.
6709 This is an internal function; Lisp code should call `tooltip-show'.
6711 FRAME nil or omitted means use the selected frame.
6713 PARMS is an optional list of frame parameters which can be used to
6714 change the tooltip's appearance.
6716 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
6717 means use the default timeout of 5 seconds.
6719 If the list of frame parameters PARMS contains a `left' parameter,
6720 display the tooltip at that x-position. If the list of frame parameters
6721 PARMS contains no `left' but a `right' parameter, display the tooltip
6722 right-adjusted at that x-position. Otherwise display it at the
6723 x-position of the mouse, with offset DX added (default is 5 if DX isn't
6726 Likewise for the y-position: If a `top' frame parameter is specified, it
6727 determines the position of the upper edge of the tooltip window. If a
6728 `bottom' parameter but no `top' frame parameter is specified, it
6729 determines the position of the lower edge of the tooltip window.
6730 Otherwise display the tooltip window at the y-position of the mouse,
6731 with offset DY added (default is -10).
6733 A tooltip's maximum size is specified by `x-max-tooltip-size'.
6734 Text larger than the specified size is clipped. */)
6735 (Lisp_Object string
, Lisp_Object frame
, Lisp_Object parms
,
6736 Lisp_Object timeout
, Lisp_Object dx
, Lisp_Object dy
)
6738 struct frame
*f
, *tip_f
;
6741 struct buffer
*old_buffer
;
6742 struct text_pos pos
;
6744 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
6745 ptrdiff_t count
= SPECPDL_INDEX ();
6747 Lisp_Object window
, size
, tip_buf
;
6748 AUTO_STRING (tip
, " *tip*");
6750 specbind (Qinhibit_redisplay
, Qt
);
6752 CHECK_STRING (string
);
6753 if (SCHARS (string
) == 0)
6754 string
= make_unibyte_string (" ", 1);
6757 frame
= selected_frame
;
6758 f
= decode_window_system_frame (frame
);
6761 timeout
= make_number (5);
6763 CHECK_NATNUM (timeout
);
6766 dx
= make_number (5);
6771 dy
= make_number (-10);
6776 if (x_gtk_use_system_tooltips
)
6780 /* Hide a previous tip, if any. */
6784 ok
= xg_prepare_tooltip (f
, string
, &width
, &height
);
6787 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, &root_x
, &root_y
);
6788 xg_show_tooltip (f
, root_x
, root_y
);
6789 tip_last_frame
= frame
;
6793 if (ok
) goto start_timer
;
6795 #endif /* USE_GTK */
6797 if (FRAMEP (tip_frame
) && FRAME_LIVE_P (XFRAME (tip_frame
)))
6799 if (FRAME_VISIBLE_P (XFRAME (tip_frame
))
6800 && EQ (frame
, tip_last_frame
)
6801 && !NILP (Fequal_including_properties (tip_last_string
, string
))
6802 && !NILP (Fequal (tip_last_parms
, parms
)))
6804 /* Only DX and DY have changed. */
6805 tip_f
= XFRAME (tip_frame
);
6806 if (!NILP (tip_timer
))
6808 call1 (Qcancel_timer
, tip_timer
);
6813 compute_tip_xy (tip_f
, parms
, dx
, dy
, FRAME_PIXEL_WIDTH (tip_f
),
6814 FRAME_PIXEL_HEIGHT (tip_f
), &root_x
, &root_y
);
6815 XMoveWindow (FRAME_X_DISPLAY (tip_f
), FRAME_X_WINDOW (tip_f
),
6821 else if (tooltip_reuse_hidden_frame
&& EQ (frame
, tip_last_frame
))
6823 bool delete = false;
6824 Lisp_Object tail
, elt
, parm
, last
;
6826 /* Check if every parameter in PARMS has the same value in
6827 tip_last_parms. This may destruct tip_last_parms which,
6828 however, will be recreated below. */
6829 for (tail
= parms
; CONSP (tail
); tail
= XCDR (tail
))
6833 /* The left, top, right and bottom parameters are handled
6834 by compute_tip_xy so they can be ignored here. */
6835 if (!EQ (parm
, Qleft
) && !EQ (parm
, Qtop
)
6836 && !EQ (parm
, Qright
) && !EQ (parm
, Qbottom
))
6838 last
= Fassq (parm
, tip_last_parms
);
6839 if (NILP (Fequal (Fcdr (elt
), Fcdr (last
))))
6841 /* We lost, delete the old tooltip. */
6847 call2 (Qassq_delete_all
, parm
, tip_last_parms
);
6851 call2 (Qassq_delete_all
, parm
, tip_last_parms
);
6854 /* Now check if every parameter in what is left of
6855 tip_last_parms with a non-nil value has an association in
6857 for (tail
= tip_last_parms
; CONSP (tail
); tail
= XCDR (tail
))
6861 if (!EQ (parm
, Qleft
) && !EQ (parm
, Qtop
) && !EQ (parm
, Qright
)
6862 && !EQ (parm
, Qbottom
) && !NILP (Fcdr (elt
)))
6864 /* We lost, delete the old tooltip. */
6870 x_hide_tip (delete);
6878 tip_last_frame
= frame
;
6879 tip_last_string
= string
;
6880 tip_last_parms
= parms
;
6882 if (!FRAMEP (tip_frame
) || !FRAME_LIVE_P (XFRAME (tip_frame
)))
6884 /* Add default values to frame parameters. */
6885 if (NILP (Fassq (Qname
, parms
)))
6886 parms
= Fcons (Fcons (Qname
, build_string ("tooltip")), parms
);
6887 if (NILP (Fassq (Qinternal_border_width
, parms
)))
6888 parms
= Fcons (Fcons (Qinternal_border_width
, make_number (3)), parms
);
6889 if (NILP (Fassq (Qborder_width
, parms
)))
6890 parms
= Fcons (Fcons (Qborder_width
, make_number (1)), parms
);
6891 if (NILP (Fassq (Qborder_color
, parms
)))
6892 parms
= Fcons (Fcons (Qborder_color
, build_string ("lightyellow")), parms
);
6893 if (NILP (Fassq (Qbackground_color
, parms
)))
6894 parms
= Fcons (Fcons (Qbackground_color
, build_string ("lightyellow")),
6897 /* Create a frame for the tooltip, and record it in the global
6898 variable tip_frame. */
6899 if (NILP (tip_frame
= x_create_tip_frame (FRAME_DISPLAY_INFO (f
), parms
)))
6900 /* Creating the tip frame failed. */
6901 return unbind_to (count
, Qnil
);
6904 tip_f
= XFRAME (tip_frame
);
6905 window
= FRAME_ROOT_WINDOW (tip_f
);
6906 tip_buf
= Fget_buffer_create (tip
);
6907 /* We will mark the tip window a "pseudo-window" below, and such
6908 windows cannot have display margins. */
6909 bset_left_margin_cols (XBUFFER (tip_buf
), make_number (0));
6910 bset_right_margin_cols (XBUFFER (tip_buf
), make_number (0));
6911 set_window_buffer (window
, tip_buf
, false, false);
6912 w
= XWINDOW (window
);
6913 w
->pseudo_window_p
= true;
6915 /* Set up the frame's root window. Note: The following code does not
6916 try to size the window or its frame correctly. Its only purpose is
6917 to make the subsequent text size calculations work. The right
6918 sizes should get installed when the toolkit gets back to us. */
6924 if (CONSP (Vx_max_tooltip_size
)
6925 && RANGED_INTEGERP (1, XCAR (Vx_max_tooltip_size
), INT_MAX
)
6926 && RANGED_INTEGERP (1, XCDR (Vx_max_tooltip_size
), INT_MAX
))
6928 w
->total_cols
= XFASTINT (XCAR (Vx_max_tooltip_size
));
6929 w
->total_lines
= XFASTINT (XCDR (Vx_max_tooltip_size
));
6934 w
->total_lines
= 40;
6937 w
->pixel_width
= w
->total_cols
* FRAME_COLUMN_WIDTH (tip_f
);
6938 w
->pixel_height
= w
->total_lines
* FRAME_LINE_HEIGHT (tip_f
);
6939 FRAME_TOTAL_COLS (tip_f
) = w
->total_cols
;
6940 adjust_frame_glyphs (tip_f
);
6942 /* Insert STRING into root window's buffer and fit the frame to the
6944 count_1
= SPECPDL_INDEX ();
6945 old_buffer
= current_buffer
;
6946 set_buffer_internal_1 (XBUFFER (w
->contents
));
6947 bset_truncate_lines (current_buffer
, Qnil
);
6948 specbind (Qinhibit_read_only
, Qt
);
6949 specbind (Qinhibit_modification_hooks
, Qt
);
6950 specbind (Qinhibit_point_motion_hooks
, Qt
);
6952 Finsert (1, &string
);
6953 clear_glyph_matrix (w
->desired_matrix
);
6954 clear_glyph_matrix (w
->current_matrix
);
6955 SET_TEXT_POS (pos
, BEGV
, BEGV_BYTE
);
6956 try_window (window
, pos
, TRY_WINDOW_IGNORE_FONTS_CHANGE
);
6957 /* Calculate size of tooltip window. */
6958 size
= Fwindow_text_pixel_size (window
, Qnil
, Qnil
, Qnil
,
6959 make_number (w
->pixel_height
), Qnil
);
6960 /* Add the frame's internal border to calculated size. */
6961 width
= XINT (Fcar (size
)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f
);
6962 height
= XINT (Fcdr (size
)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f
);
6964 /* Calculate position of tooltip frame. */
6965 compute_tip_xy (tip_f
, parms
, dx
, dy
, width
, height
, &root_x
, &root_y
);
6967 /* Show tooltip frame. */
6969 XMoveResizeWindow (FRAME_X_DISPLAY (tip_f
), FRAME_X_WINDOW (tip_f
),
6970 root_x
, root_y
, width
, height
);
6971 XMapRaised (FRAME_X_DISPLAY (tip_f
), FRAME_X_WINDOW (tip_f
));
6974 w
->must_be_updated_p
= true;
6975 update_single_window (w
);
6976 set_buffer_internal_1 (old_buffer
);
6977 unbind_to (count_1
, Qnil
);
6978 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
6981 /* Let the tip disappear after timeout seconds. */
6982 tip_timer
= call3 (intern ("run-at-time"), timeout
, Qnil
,
6983 intern ("x-hide-tip"));
6985 return unbind_to (count
, Qnil
);
6989 DEFUN ("x-hide-tip", Fx_hide_tip
, Sx_hide_tip
, 0, 0, 0,
6990 doc
: /* Hide the current tooltip window, if there is any.
6991 Value is t if tooltip was open, nil otherwise. */)
6994 return x_hide_tip (!tooltip_reuse_hidden_frame
);
6997 DEFUN ("x-double-buffered-p", Fx_double_buffered_p
, Sx_double_buffered_p
,
6999 doc
: /* Return t if FRAME is being double buffered. */)
7002 struct frame
*f
= decode_live_frame (frame
);
7003 return FRAME_X_DOUBLE_BUFFERED_P (f
) ? Qt
: Qnil
;
7007 /***********************************************************************
7008 File selection dialog
7009 ***********************************************************************/
7011 DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog
,
7012 Sx_uses_old_gtk_dialog
,
7014 doc
: /* Return t if the old Gtk+ file selection dialog is used. */)
7020 && window_system_available (SELECTED_FRAME ())
7021 && xg_uses_old_file_dialog ())
7029 /* Callback for "OK" and "Cancel" on file selection dialog. */
7032 file_dialog_cb (Widget widget
, XtPointer client_data
, XtPointer call_data
)
7034 int *result
= client_data
;
7035 XmAnyCallbackStruct
*cb
= call_data
;
7036 *result
= cb
->reason
;
7040 /* Callback for unmapping a file selection dialog. This is used to
7041 capture the case where a dialog is closed via a window manager's
7042 closer button, for example. Using a XmNdestroyCallback didn't work
7046 file_dialog_unmap_cb (Widget widget
, XtPointer client_data
, XtPointer call_data
)
7048 int *result
= client_data
;
7049 *result
= XmCR_CANCEL
;
7053 clean_up_file_dialog (void *arg
)
7055 Widget dialog
= arg
;
7059 XtUnmanageChild (dialog
);
7060 XtDestroyWidget (dialog
);
7061 x_menu_set_in_use (false);
7066 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 5, 0,
7067 doc
: /* SKIP: real doc in USE_GTK definition in xfns.c. */)
7068 (Lisp_Object prompt
, Lisp_Object dir
, Lisp_Object default_filename
,
7069 Lisp_Object mustmatch
, Lisp_Object only_dir_p
)
7072 struct frame
*f
= SELECTED_FRAME ();
7073 Lisp_Object file
= Qnil
;
7074 Lisp_Object decoded_file
;
7075 Widget dialog
, text
, help
;
7078 XmString dir_xmstring
, pattern_xmstring
;
7079 ptrdiff_t count
= SPECPDL_INDEX ();
7081 check_window_system (f
);
7083 if (popup_activated ())
7084 error ("Trying to use a menu from within a menu-entry");
7086 CHECK_STRING (prompt
);
7089 /* Prevent redisplay. */
7090 specbind (Qinhibit_redisplay
, Qt
);
7094 /* Create the dialog with PROMPT as title, using DIR as initial
7095 directory and using "*" as pattern. */
7096 dir
= Fexpand_file_name (dir
, Qnil
);
7097 dir_xmstring
= XmStringCreateLocalized (SSDATA (dir
));
7098 pattern_xmstring
= XmStringCreateLocalized ("*");
7100 XtSetArg (al
[ac
], XmNtitle
, SDATA (prompt
)); ++ac
;
7101 XtSetArg (al
[ac
], XmNdirectory
, dir_xmstring
); ++ac
;
7102 XtSetArg (al
[ac
], XmNpattern
, pattern_xmstring
); ++ac
;
7103 XtSetArg (al
[ac
], XmNresizePolicy
, XmRESIZE_GROW
); ++ac
;
7104 XtSetArg (al
[ac
], XmNdialogStyle
, XmDIALOG_APPLICATION_MODAL
); ++ac
;
7105 dialog
= XmCreateFileSelectionDialog (f
->output_data
.x
->widget
,
7107 XmStringFree (dir_xmstring
);
7108 XmStringFree (pattern_xmstring
);
7110 /* Add callbacks for OK and Cancel. */
7111 XtAddCallback (dialog
, XmNokCallback
, file_dialog_cb
,
7112 (XtPointer
) &result
);
7113 XtAddCallback (dialog
, XmNcancelCallback
, file_dialog_cb
,
7114 (XtPointer
) &result
);
7115 XtAddCallback (dialog
, XmNunmapCallback
, file_dialog_unmap_cb
,
7116 (XtPointer
) &result
);
7118 /* Remove the help button since we can't display help. */
7119 help
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_HELP_BUTTON
);
7120 XtUnmanageChild (help
);
7122 /* Mark OK button as default. */
7123 XtVaSetValues (XmFileSelectionBoxGetChild (dialog
, XmDIALOG_OK_BUTTON
),
7124 XmNshowAsDefault
, True
, NULL
);
7126 /* If MUSTMATCH is non-nil, disable the file entry field of the
7127 dialog, so that the user must select a file from the files list
7128 box. We can't remove it because we wouldn't have a way to get at
7129 the result file name, then. */
7130 text
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
7131 if (!NILP (mustmatch
))
7134 label
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_SELECTION_LABEL
);
7135 XtSetSensitive (text
, False
);
7136 XtSetSensitive (label
, False
);
7139 /* Manage the dialog, so that list boxes get filled. */
7140 XtManageChild (dialog
);
7142 if (STRINGP (default_filename
))
7144 XmString default_xmstring
;
7145 Widget wtext
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
7146 Widget list
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_LIST
);
7148 XmTextPosition last_pos
= XmTextFieldGetLastPosition (wtext
);
7149 XmTextFieldReplace (wtext
, 0, last_pos
,
7150 (SSDATA (Ffile_name_nondirectory (default_filename
))));
7152 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
7153 must include the path for this to work. */
7155 default_xmstring
= XmStringCreateLocalized (SSDATA (default_filename
));
7157 if (XmListItemExists (list
, default_xmstring
))
7159 int item_pos
= XmListItemPos (list
, default_xmstring
);
7160 /* Select the item and scroll it into view. */
7161 XmListSelectPos (list
, item_pos
, True
);
7162 XmListSetPos (list
, item_pos
);
7165 XmStringFree (default_xmstring
);
7168 record_unwind_protect_ptr (clean_up_file_dialog
, dialog
);
7170 /* Process events until the user presses Cancel or OK. */
7171 x_menu_set_in_use (true);
7176 x_menu_wait_for_event (0);
7177 XtAppNextEvent (Xt_app_con
, &event
);
7178 if (event
.type
== KeyPress
7179 && FRAME_X_DISPLAY (f
) == event
.xkey
.display
)
7181 KeySym keysym
= XLookupKeysym (&event
.xkey
, 0);
7183 /* Pop down on C-g. */
7184 if (keysym
== XK_g
&& (event
.xkey
.state
& ControlMask
) != 0)
7185 XtUnmanageChild (dialog
);
7188 (void) x_dispatch_event (&event
, FRAME_X_DISPLAY (f
));
7191 /* Get the result. */
7192 if (result
== XmCR_OK
)
7194 XmString text_string
;
7197 XtVaGetValues (dialog
, XmNtextString
, &text_string
, NULL
);
7198 XmStringGetLtoR (text_string
, XmFONTLIST_DEFAULT_TAG
, &data
);
7199 XmStringFree (text_string
);
7200 file
= build_string (data
);
7208 /* Make "Cancel" equivalent to C-g. */
7212 decoded_file
= DECODE_FILE (file
);
7214 return unbind_to (count
, decoded_file
);
7217 #endif /* USE_MOTIF */
7222 clean_up_dialog (void)
7224 x_menu_set_in_use (false);
7227 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 5, 0,
7228 doc
: /* Read file name, prompting with PROMPT in directory DIR.
7229 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
7230 selection box, if specified. If MUSTMATCH is non-nil, the returned file
7231 or directory must exist.
7233 This function is only defined on NS, MS Windows, and X Windows with the
7234 Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
7235 Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.
7236 On MS Windows 7 and later, the file selection dialog "remembers" the last
7237 directory where the user selected a file, and will open that directory
7238 instead of DIR on subsequent invocations of this function with the same
7239 value of DIR as in previous invocations; this is standard MS Windows behavior. */)
7240 (Lisp_Object prompt
, Lisp_Object dir
, Lisp_Object default_filename
, Lisp_Object mustmatch
, Lisp_Object only_dir_p
)
7242 struct frame
*f
= SELECTED_FRAME ();
7244 Lisp_Object file
= Qnil
;
7245 Lisp_Object decoded_file
;
7246 ptrdiff_t count
= SPECPDL_INDEX ();
7249 check_window_system (f
);
7251 if (popup_activated ())
7252 error ("Trying to use a menu from within a menu-entry");
7254 x_menu_set_in_use (true);
7256 CHECK_STRING (prompt
);
7259 /* Prevent redisplay. */
7260 specbind (Qinhibit_redisplay
, Qt
);
7261 record_unwind_protect_void (clean_up_dialog
);
7265 if (STRINGP (default_filename
))
7266 cdef_file
= SSDATA (default_filename
);
7268 cdef_file
= SSDATA (dir
);
7270 fn
= xg_get_file_name (f
, SSDATA (prompt
), cdef_file
,
7272 ! NILP (only_dir_p
));
7276 file
= build_string (fn
);
7282 /* Make "Cancel" equivalent to C-g. */
7286 decoded_file
= DECODE_FILE (file
);
7288 return unbind_to (count
, decoded_file
);
7292 #ifdef HAVE_FREETYPE
7294 DEFUN ("x-select-font", Fx_select_font
, Sx_select_font
, 0, 2, 0,
7295 doc
: /* Read a font using a GTK dialog.
7296 Return either a font spec (for GTK versions >= 3.2) or a string
7297 containing a GTK-style font name.
7299 FRAME is the frame on which to pop up the font chooser. If omitted or
7300 nil, it defaults to the selected frame. */)
7301 (Lisp_Object frame
, Lisp_Object ignored
)
7303 struct frame
*f
= decode_window_system_frame (frame
);
7305 Lisp_Object font_param
;
7306 char *default_name
= NULL
;
7307 ptrdiff_t count
= SPECPDL_INDEX ();
7309 if (popup_activated ())
7310 error ("Trying to use a menu from within a menu-entry");
7312 x_menu_set_in_use (true);
7314 /* Prevent redisplay. */
7315 specbind (Qinhibit_redisplay
, Qt
);
7316 record_unwind_protect_void (clean_up_dialog
);
7320 XSETFONT (font
, FRAME_FONT (f
));
7321 font_param
= Ffont_get (font
, QCname
);
7322 if (STRINGP (font_param
))
7323 default_name
= xlispstrdup (font_param
);
7326 font_param
= Fframe_parameter (frame
, Qfont_parameter
);
7327 if (STRINGP (font_param
))
7328 default_name
= xlispstrdup (font_param
);
7331 font
= xg_get_font (f
, default_name
);
7332 xfree (default_name
);
7339 return unbind_to (count
, font
);
7341 #endif /* HAVE_FREETYPE */
7343 #endif /* USE_GTK */
7346 /***********************************************************************
7348 ***********************************************************************/
7351 #include <X11/XKBlib.h>
7352 #include <X11/keysym.h>
7355 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p
,
7356 Sx_backspace_delete_keys_p
, 0, 1, 0,
7357 doc
: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
7358 FRAME nil means use the selected frame.
7359 Value is t if we know that both keys are present, and are mapped to the
7360 usual X keysyms. Value is `lambda' if we cannot determine if both keys are
7361 present and mapped to the usual X keysyms. */)
7368 struct frame
*f
= decode_window_system_frame (frame
);
7369 Display
*dpy
= FRAME_X_DISPLAY (f
);
7370 Lisp_Object have_keys
;
7371 int major
, minor
, op
, event
, error_code
;
7375 /* Check library version in case we're dynamically linked. */
7376 major
= XkbMajorVersion
;
7377 minor
= XkbMinorVersion
;
7378 if (!XkbLibraryVersion (&major
, &minor
))
7384 /* Check that the server supports XKB. */
7385 major
= XkbMajorVersion
;
7386 minor
= XkbMinorVersion
;
7387 if (!XkbQueryExtension (dpy
, &op
, &event
, &error_code
, &major
, &minor
))
7393 /* In this code we check that the keyboard has physical keys with names
7394 that start with BKSP (Backspace) and DELE (Delete), and that they
7395 generate keysym XK_BackSpace and XK_Delete respectively.
7396 This function is used to test if normal-erase-is-backspace should be
7398 An alternative approach would be to just check if XK_BackSpace and
7399 XK_Delete are mapped to any key. But if any of those are mapped to
7400 some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the
7401 user doesn't know about it, it is better to return false here.
7402 It is more obvious to the user what to do if she/he has two keys
7403 clearly marked with names/symbols and one key does something not
7404 expected (i.e. she/he then tries the other).
7405 The cases where Backspace/Delete is mapped to some other key combination
7406 are rare, and in those cases, normal-erase-is-backspace can be turned on
7410 kb
= XkbGetMap (dpy
, XkbAllMapComponentsMask
, XkbUseCoreKbd
);
7413 int delete_keycode
= 0, backspace_keycode
= 0, i
;
7415 if (XkbGetNames (dpy
, XkbAllNamesMask
, kb
) == Success
)
7417 for (i
= kb
->min_key_code
;
7418 (i
< kb
->max_key_code
7419 && (delete_keycode
== 0 || backspace_keycode
== 0));
7422 /* The XKB symbolic key names can be seen most easily in
7423 the PS file generated by `xkbprint -label name
7425 if (memcmp ("DELE", kb
->names
->keys
[i
].name
, 4) == 0)
7427 else if (memcmp ("BKSP", kb
->names
->keys
[i
].name
, 4) == 0)
7428 backspace_keycode
= i
;
7431 XkbFreeNames (kb
, 0, True
);
7434 /* As of libX11-1.6.2, XkbGetMap manual says that you should use
7435 XkbFreeClientMap to free the data returned by XkbGetMap. But
7436 this function just frees the data referenced from KB and not
7437 KB itself. To free KB as well, call XkbFreeKeyboard. */
7438 XkbFreeKeyboard (kb
, XkbAllMapComponentsMask
, True
);
7441 && backspace_keycode
7442 && XKeysymToKeycode (dpy
, XK_Delete
) == delete_keycode
7443 && XKeysymToKeycode (dpy
, XK_BackSpace
) == backspace_keycode
)
7453 /***********************************************************************
7455 ***********************************************************************/
7458 DEFUN ("x-export-frames", Fx_export_frames
, Sx_export_frames
, 0, 2, 0,
7459 doc
: /* Return image data of FRAMES in TYPE format.
7460 FRAMES should be nil (the selected frame), a frame, or a list of
7461 frames (each of which corresponds to one page). Each frame should be
7462 visible. Optional arg TYPE should be either `pdf' (default), `png',
7463 `postscript', or `svg'. Supported types are determined by the
7464 compile-time configuration of cairo. */)
7465 (Lisp_Object frames
, Lisp_Object type
)
7467 Lisp_Object rest
, tmp
;
7468 cairo_surface_type_t surface_type
;
7470 if (!CONSP (frames
))
7471 frames
= list1 (frames
);
7474 for (rest
= frames
; CONSP (rest
); rest
= XCDR (rest
))
7476 struct frame
*f
= decode_window_system_frame (XCAR (rest
));
7479 XSETFRAME (frame
, f
);
7480 if (!FRAME_VISIBLE_P (f
))
7481 error ("Frames to be exported must be visible.");
7482 tmp
= Fcons (frame
, tmp
);
7484 frames
= Fnreverse (tmp
);
7486 #ifdef CAIRO_HAS_PDF_SURFACE
7487 if (NILP (type
) || EQ (type
, Qpdf
))
7488 surface_type
= CAIRO_SURFACE_TYPE_PDF
;
7491 #ifdef CAIRO_HAS_PNG_FUNCTIONS
7492 if (EQ (type
, Qpng
))
7494 if (!NILP (XCDR (frames
)))
7495 error ("PNG export cannot handle multiple frames.");
7496 surface_type
= CAIRO_SURFACE_TYPE_IMAGE
;
7500 #ifdef CAIRO_HAS_PS_SURFACE
7501 if (EQ (type
, Qpostscript
))
7502 surface_type
= CAIRO_SURFACE_TYPE_PS
;
7505 #ifdef CAIRO_HAS_SVG_SURFACE
7506 if (EQ (type
, Qsvg
))
7508 /* For now, we stick to SVG 1.1. */
7509 if (!NILP (XCDR (frames
)))
7510 error ("SVG export cannot handle multiple frames.");
7511 surface_type
= CAIRO_SURFACE_TYPE_SVG
;
7515 error ("Unsupported export type");
7517 return x_cr_export_frames (frames
, surface_type
);
7521 DEFUN ("x-page-setup-dialog", Fx_page_setup_dialog
, Sx_page_setup_dialog
, 0, 0, 0,
7522 doc
: /* Pop up a page setup dialog.
7523 The current page setup can be obtained using `x-get-page-setup'. */)
7527 xg_page_setup_dialog ();
7533 DEFUN ("x-get-page-setup", Fx_get_page_setup
, Sx_get_page_setup
, 0, 0, 0,
7534 doc
: /* Return the value of the current page setup.
7535 The return value is an alist containing the following keys:
7537 orientation: page orientation (symbol `portrait', `landscape',
7538 `reverse-portrait', or `reverse-landscape').
7539 width, height: page width/height in points not including margins.
7540 left-margin, right-margin, top-margin, bottom-margin: print margins,
7541 which is the parts of the page that the printer cannot print
7544 The paper width can be obtained as the sum of width, left-margin, and
7545 right-margin values if the page orientation is `portrait' or
7546 `reverse-portrait'. Otherwise, it is the sum of width, top-margin,
7547 and bottom-margin values. Likewise, the paper height is the sum of
7548 height, top-margin, and bottom-margin values if the page orientation
7549 is `portrait' or `reverse-portrait'. Otherwise, it is the sum of
7550 height, left-margin, and right-margin values. */)
7556 result
= xg_get_page_setup ();
7562 DEFUN ("x-print-frames-dialog", Fx_print_frames_dialog
, Sx_print_frames_dialog
, 0, 1, "",
7563 doc
: /* Pop up a print dialog to print the current contents of FRAMES.
7564 FRAMES should be nil (the selected frame), a frame, or a list of
7565 frames (each of which corresponds to one page). Each frame should be
7567 (Lisp_Object frames
)
7569 Lisp_Object rest
, tmp
;
7572 if (!CONSP (frames
))
7573 frames
= list1 (frames
);
7576 for (rest
= frames
; CONSP (rest
); rest
= XCDR (rest
))
7578 struct frame
*f
= decode_window_system_frame (XCAR (rest
));
7581 XSETFRAME (frame
, f
);
7582 if (!FRAME_VISIBLE_P (f
))
7583 error ("Frames to be printed must be visible.");
7584 tmp
= Fcons (frame
, tmp
);
7586 frames
= Fnreverse (tmp
);
7588 /* Make sure the current matrices are up-to-date. */
7589 count
= SPECPDL_INDEX ();
7590 specbind (Qredisplay_dont_pause
, Qt
);
7591 redisplay_preserve_echo_area (32);
7592 unbind_to (count
, Qnil
);
7595 xg_print_frames_dialog (frames
);
7600 #endif /* USE_GTK */
7601 #endif /* USE_CAIRO */
7604 /***********************************************************************
7606 ***********************************************************************/
7608 /* Keep this list in the same order as frame_parms in frame.c.
7609 Use 0 for unsupported frame parameters. */
7611 frame_parm_handler x_frame_parm_handlers
[] =
7615 x_set_background_color
,
7621 x_set_foreground_color
,
7624 x_set_internal_border_width
,
7625 x_set_right_divider_width
,
7626 x_set_bottom_divider_width
,
7627 x_set_menu_bar_lines
,
7629 x_explicitly_set_name
,
7630 x_set_scroll_bar_width
,
7631 x_set_scroll_bar_height
,
7634 x_set_vertical_scroll_bars
,
7635 x_set_horizontal_scroll_bars
,
7637 x_set_tool_bar_lines
,
7638 x_set_scroll_bar_foreground
,
7639 x_set_scroll_bar_background
,
7649 x_set_tool_bar_position
,
7650 x_set_inhibit_double_buffering
,
7654 x_set_no_focus_on_map
,
7655 x_set_no_accept_focus
,
7657 x_set_override_redirect
,
7658 x_set_no_special_glyphs
,
7664 DEFSYM (Qundefined_color
, "undefined-color");
7665 DEFSYM (Qcompound_text
, "compound-text");
7666 DEFSYM (Qcancel_timer
, "cancel-timer");
7667 DEFSYM (Qfont_parameter
, "font-parameter");
7668 DEFSYM (Qmono
, "mono");
7669 DEFSYM (Qassq_delete_all
, "assq-delete-all");
7672 DEFSYM (Qpdf
, "pdf");
7674 DEFSYM (Qorientation
, "orientation");
7675 DEFSYM (Qtop_margin
, "top-margin");
7676 DEFSYM (Qbottom_margin
, "bottom-margin");
7677 DEFSYM (Qportrait
, "portrait");
7678 DEFSYM (Qlandscape
, "landscape");
7679 DEFSYM (Qreverse_portrait
, "reverse-portrait");
7680 DEFSYM (Qreverse_landscape
, "reverse-landscape");
7683 Fput (Qundefined_color
, Qerror_conditions
,
7684 listn (CONSTYPE_PURE
, 2, Qundefined_color
, Qerror
));
7685 Fput (Qundefined_color
, Qerror_message
,
7686 build_pure_c_string ("Undefined color"));
7688 DEFVAR_LISP ("x-pointer-shape", Vx_pointer_shape
,
7689 doc
: /* The shape of the pointer when over text.
7690 Changing the value does not affect existing frames
7691 unless you set the mouse color. */);
7692 Vx_pointer_shape
= Qnil
;
7694 #if false /* This doesn't really do anything. */
7695 DEFVAR_LISP ("x-nontext-pointer-shape", Vx_nontext_pointer_shape
,
7696 doc
: /* The shape of the pointer when not over text.
7697 This variable takes effect when you create a new frame
7698 or when you set the mouse color. */);
7700 Vx_nontext_pointer_shape
= Qnil
;
7702 DEFVAR_LISP ("x-hourglass-pointer-shape", Vx_hourglass_pointer_shape
,
7703 doc
: /* The shape of the pointer when Emacs is busy.
7704 This variable takes effect when you create a new frame
7705 or when you set the mouse color. */);
7706 Vx_hourglass_pointer_shape
= Qnil
;
7708 #if false /* This doesn't really do anything. */
7709 DEFVAR_LISP ("x-mode-pointer-shape", Vx_mode_pointer_shape
,
7710 doc
: /* The shape of the pointer when over the mode line.
7711 This variable takes effect when you create a new frame
7712 or when you set the mouse color. */);
7714 Vx_mode_pointer_shape
= Qnil
;
7716 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
7717 Vx_sensitive_text_pointer_shape
,
7718 doc
: /* The shape of the pointer when over mouse-sensitive text.
7719 This variable takes effect when you create a new frame
7720 or when you set the mouse color. */);
7721 Vx_sensitive_text_pointer_shape
= Qnil
;
7723 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
7724 Vx_window_horizontal_drag_shape
,
7725 doc
: /* Pointer shape to use for indicating a window can be dragged horizontally.
7726 This variable takes effect when you create a new frame
7727 or when you set the mouse color. */);
7728 Vx_window_horizontal_drag_shape
= Qnil
;
7730 DEFVAR_LISP ("x-window-vertical-drag-cursor",
7731 Vx_window_vertical_drag_shape
,
7732 doc
: /* Pointer shape to use for indicating a window can be dragged vertically.
7733 This variable takes effect when you create a new frame
7734 or when you set the mouse color. */);
7735 Vx_window_vertical_drag_shape
= Qnil
;
7737 DEFVAR_LISP ("x-window-left-edge-cursor",
7738 Vx_window_left_edge_shape
,
7739 doc
: /* Pointer shape indicating a left x-window edge can be dragged.
7740 This variable takes effect when you create a new frame
7741 or when you set the mouse color. */);
7742 Vx_window_left_edge_shape
= Qnil
;
7744 DEFVAR_LISP ("x-window-top-left-corner-cursor",
7745 Vx_window_top_left_corner_shape
,
7746 doc
: /* Pointer shape indicating a top left x-window corner can be dragged.
7747 This variable takes effect when you create a new frame
7748 or when you set the mouse color. */);
7749 Vx_window_top_left_corner_shape
= Qnil
;
7751 DEFVAR_LISP ("x-window-top-edge-cursor",
7752 Vx_window_top_edge_shape
,
7753 doc
: /* Pointer shape indicating a top x-window edge can be dragged.
7754 This variable takes effect when you create a new frame
7755 or when you set the mouse color. */);
7756 Vx_window_top_edge_shape
= Qnil
;
7758 DEFVAR_LISP ("x-window-top-right-corner-cursor",
7759 Vx_window_top_right_corner_shape
,
7760 doc
: /* Pointer shape indicating a top right x-window corner can be dragged.
7761 This variable takes effect when you create a new frame
7762 or when you set the mouse color. */);
7763 Vx_window_top_right_corner_shape
= Qnil
;
7765 DEFVAR_LISP ("x-window-right-edge-cursor",
7766 Vx_window_right_edge_shape
,
7767 doc
: /* Pointer shape indicating a right x-window edge can be dragged.
7768 This variable takes effect when you create a new frame
7769 or when you set the mouse color. */);
7770 Vx_window_right_edge_shape
= Qnil
;
7772 DEFVAR_LISP ("x-window-bottom-right-corner-cursor",
7773 Vx_window_bottom_right_corner_shape
,
7774 doc
: /* Pointer shape indicating a bottom right x-window corner can be dragged.
7775 This variable takes effect when you create a new frame
7776 or when you set the mouse color. */);
7777 Vx_window_bottom_right_corner_shape
= Qnil
;
7779 DEFVAR_LISP ("x-window-bottom-edge-cursor",
7780 Vx_window_bottom_edge_shape
,
7781 doc
: /* Pointer shape indicating a bottom x-window edge can be dragged.
7782 This variable takes effect when you create a new frame
7783 or when you set the mouse color. */);
7784 Vx_window_bottom_edge_shape
= Qnil
;
7786 DEFVAR_LISP ("x-window-bottom-left-corner-cursor",
7787 Vx_window_bottom_left_corner_shape
,
7788 doc
: /* Pointer shape indicating a bottom left x-window corner can be dragged.
7789 This variable takes effect when you create a new frame
7790 or when you set the mouse color. */);
7791 Vx_window_bottom_left_corner_shape
= Qnil
;
7793 DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel
,
7794 doc
: /* A string indicating the foreground color of the cursor box. */);
7795 Vx_cursor_fore_pixel
= Qnil
;
7797 DEFVAR_LISP ("x-max-tooltip-size", Vx_max_tooltip_size
,
7798 doc
: /* Maximum size for tooltips.
7799 Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */);
7800 Vx_max_tooltip_size
= Fcons (make_number (80), make_number (40));
7802 DEFVAR_LISP ("x-no-window-manager", Vx_no_window_manager
,
7803 doc
: /* Non-nil if no X window manager is in use.
7804 Emacs doesn't try to figure this out; this is always nil
7805 unless you set it to something else. */);
7806 /* We don't have any way to find this out, so set it to nil
7807 and maybe the user would like to set it to t. */
7808 Vx_no_window_manager
= Qnil
;
7810 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
7811 Vx_pixel_size_width_font_regexp
,
7812 doc
: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
7814 Since Emacs gets the width of a font matching this regexp from the
7815 PIXEL_SIZE field of the name, the font-finding mechanism gets faster for
7816 such a font. This is especially effective for large fonts such as
7817 Chinese, Japanese, and Korean. */);
7818 Vx_pixel_size_width_font_regexp
= Qnil
;
7820 /* This is not ifdef:ed, so other builds than GTK can customize it. */
7821 DEFVAR_BOOL ("x-gtk-use-old-file-dialog", x_gtk_use_old_file_dialog
,
7822 doc
: /* Non-nil means prompt with the old GTK file selection dialog.
7823 If nil or if the file selection dialog is not available, the new GTK file
7824 chooser is used instead. To turn off all file dialogs set the
7825 variable `use-file-dialog'. */);
7826 x_gtk_use_old_file_dialog
= false;
7828 DEFVAR_BOOL ("x-gtk-show-hidden-files", x_gtk_show_hidden_files
,
7829 doc
: /* If non-nil, the GTK file chooser will by default show hidden files.
7830 Note that this is just the default, there is a toggle button on the file
7831 chooser to show or not show hidden files on a case by case basis. */);
7832 x_gtk_show_hidden_files
= false;
7834 DEFVAR_BOOL ("x-gtk-file-dialog-help-text", x_gtk_file_dialog_help_text
,
7835 doc
: /* If non-nil, the GTK file chooser will show additional help text.
7836 If more space for files in the file chooser dialog is wanted, set this to nil
7837 to turn the additional text off. */);
7838 x_gtk_file_dialog_help_text
= true;
7840 DEFVAR_BOOL ("x-gtk-use-system-tooltips", x_gtk_use_system_tooltips
,
7841 doc
: /* If non-nil with a Gtk+ built Emacs, the Gtk+ tooltip is used.
7842 Otherwise use Emacs own tooltip implementation.
7843 When using Gtk+ tooltips, the tooltip face is not used. */);
7844 x_gtk_use_system_tooltips
= true;
7846 /* Tell Emacs about this window system. */
7847 Fprovide (Qx
, Qnil
);
7849 #ifdef USE_X_TOOLKIT
7850 Fprovide (intern_c_string ("x-toolkit"), Qnil
);
7852 Fprovide (intern_c_string ("motif"), Qnil
);
7854 DEFVAR_LISP ("motif-version-string", Vmotif_version_string
,
7855 doc
: /* Version info for LessTif/Motif. */);
7856 Vmotif_version_string
= build_string (XmVERSION_STRING
);
7857 #endif /* USE_MOTIF */
7858 #endif /* USE_X_TOOLKIT */
7861 /* Provide x-toolkit also for GTK. Internally GTK does not use Xt so it
7862 is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
7863 But for a user it is a toolkit for X, and indeed, configure
7864 accepts --with-x-toolkit=gtk. */
7865 Fprovide (intern_c_string ("x-toolkit"), Qnil
);
7866 Fprovide (intern_c_string ("gtk"), Qnil
);
7867 Fprovide (intern_c_string ("move-toolbar"), Qnil
);
7869 DEFVAR_LISP ("gtk-version-string", Vgtk_version_string
,
7870 doc
: /* Version info for GTK+. */);
7872 char gtk_version
[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
7873 int len
= sprintf (gtk_version
, "%d.%d.%d",
7874 GTK_MAJOR_VERSION
, GTK_MINOR_VERSION
, GTK_MICRO_VERSION
);
7875 Vgtk_version_string
= make_pure_string (gtk_version
, len
, len
, false);
7877 #endif /* USE_GTK */
7880 Fprovide (intern_c_string ("cairo"), Qnil
);
7882 DEFVAR_LISP ("cairo-version-string", Vcairo_version_string
,
7883 doc
: /* Version info for cairo. */);
7885 char cairo_version
[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
7886 int len
= sprintf (cairo_version
, "%d.%d.%d",
7887 CAIRO_VERSION_MAJOR
, CAIRO_VERSION_MINOR
,
7888 CAIRO_VERSION_MICRO
);
7889 Vcairo_version_string
= make_pure_string (cairo_version
, len
, len
, false);
7893 /* X window properties. */
7894 defsubr (&Sx_change_window_property
);
7895 defsubr (&Sx_delete_window_property
);
7896 defsubr (&Sx_window_property
);
7897 defsubr (&Sx_window_property_attributes
);
7899 defsubr (&Sxw_display_color_p
);
7900 defsubr (&Sx_display_grayscale_p
);
7901 defsubr (&Sxw_color_defined_p
);
7902 defsubr (&Sxw_color_values
);
7903 defsubr (&Sx_server_max_request_size
);
7904 defsubr (&Sx_server_vendor
);
7905 defsubr (&Sx_server_version
);
7906 defsubr (&Sx_display_pixel_width
);
7907 defsubr (&Sx_display_pixel_height
);
7908 defsubr (&Sx_display_mm_width
);
7909 defsubr (&Sx_display_mm_height
);
7910 defsubr (&Sx_display_screens
);
7911 defsubr (&Sx_display_planes
);
7912 defsubr (&Sx_display_color_cells
);
7913 defsubr (&Sx_display_visual_class
);
7914 defsubr (&Sx_display_backing_store
);
7915 defsubr (&Sx_display_save_under
);
7916 defsubr (&Sx_display_monitor_attributes_list
);
7917 defsubr (&Sx_frame_geometry
);
7918 defsubr (&Sx_frame_edges
);
7919 defsubr (&Sx_frame_list_z_order
);
7920 defsubr (&Sx_frame_restack
);
7921 defsubr (&Sx_mouse_absolute_pixel_position
);
7922 defsubr (&Sx_set_mouse_absolute_pixel_position
);
7923 defsubr (&Sx_wm_set_size_hint
);
7924 defsubr (&Sx_create_frame
);
7925 defsubr (&Sx_open_connection
);
7926 defsubr (&Sx_close_connection
);
7927 defsubr (&Sx_display_list
);
7928 defsubr (&Sx_synchronize
);
7929 defsubr (&Sx_backspace_delete_keys_p
);
7930 defsubr (&Sx_show_tip
);
7931 defsubr (&Sx_hide_tip
);
7932 defsubr (&Sx_double_buffered_p
);
7934 staticpro (&tip_timer
);
7936 staticpro (&tip_frame
);
7937 tip_last_frame
= Qnil
;
7938 staticpro (&tip_last_frame
);
7939 tip_last_string
= Qnil
;
7940 staticpro (&tip_last_string
);
7941 tip_last_parms
= Qnil
;
7942 staticpro (&tip_last_parms
);
7944 defsubr (&Sx_uses_old_gtk_dialog
);
7945 #if defined (USE_MOTIF) || defined (USE_GTK)
7946 defsubr (&Sx_file_dialog
);
7949 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
7950 defsubr (&Sx_select_font
);
7954 defsubr (&Sx_export_frames
);
7956 defsubr (&Sx_page_setup_dialog
);
7957 defsubr (&Sx_get_page_setup
);
7958 defsubr (&Sx_print_frames_dialog
);