1 /* Functions for the X window system.
3 Copyright (C) 1989, 1992-2016 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 <http://www.gnu.org/licenses/>. */
30 #include "dispextern.h"
32 #include "blockinput.h"
35 #include "termhooks.h"
38 #include <sys/types.h>
41 #include "bitmaps/gray.xbm"
42 #include "xsettings.h"
45 #include <X11/extensions/Xrandr.h>
48 #include <X11/extensions/Xinerama.h>
56 #include <X11/Shell.h>
60 #include <X11/Xaw3d/Paned.h>
61 #include <X11/Xaw3d/Label.h>
62 #else /* !HAVE_XAW3D */
63 #include <X11/Xaw/Paned.h>
64 #include <X11/Xaw/Label.h>
65 #endif /* HAVE_XAW3D */
66 #endif /* USE_MOTIF */
69 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
72 #ifdef USG /* Pacify gcc -Wunused-macros. */
80 #include "../lwlib/lwlib.h"
84 #include <Xm/DialogS.h>
85 #include <Xm/FileSB.h>
91 #include "../lwlib/xlwmenu.h"
94 /* Unique id counter for widgets created by the Lucid Widget Library. */
96 extern LWLIB_ID widget_id_tick
;
100 #endif /* USE_MOTIF */
102 #endif /* USE_X_TOOLKIT */
108 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
110 static ptrdiff_t image_cache_refcount
;
112 static int dpyinfo_refcount
;
115 static struct x_display_info
*x_display_info_for_name (Lisp_Object
);
117 /* Let the user specify an X display with a Lisp object.
118 OBJECT may be nil, a frame or a terminal object.
119 nil stands for the selected frame--or, if that is not an X frame,
120 the first X display on the list. */
122 struct x_display_info
*
123 check_x_display_info (Lisp_Object object
)
125 struct x_display_info
*dpyinfo
= NULL
;
129 struct frame
*sf
= XFRAME (selected_frame
);
131 if (FRAME_X_P (sf
) && FRAME_LIVE_P (sf
))
132 dpyinfo
= FRAME_DISPLAY_INFO (sf
);
133 else if (x_display_list
!= 0)
134 dpyinfo
= x_display_list
;
136 error ("X windows are not in use or not initialized");
138 else if (TERMINALP (object
))
140 struct terminal
*t
= decode_live_terminal (object
);
142 if (t
->type
!= output_x_window
)
143 error ("Terminal %d is not an X display", t
->id
);
145 dpyinfo
= t
->display_info
.x
;
147 else if (STRINGP (object
))
148 dpyinfo
= x_display_info_for_name (object
);
151 struct frame
*f
= decode_window_system_frame (object
);
152 dpyinfo
= FRAME_DISPLAY_INFO (f
);
158 /* Return the screen positions and offsets of frame F.
159 Store the offsets between FRAME_OUTER_WINDOW and the containing
160 window manager window into LEFT_OFFSET_X, RIGHT_OFFSET_X,
161 TOP_OFFSET_Y and BOTTOM_OFFSET_Y.
162 Store the offsets between FRAME_X_WINDOW and the containing
163 window manager window into X_PIXELS_DIFF and Y_PIXELS_DIFF.
164 Store the screen positions of frame F into XPTR and YPTR.
165 These are the positions of the containing window manager window,
166 not Emacs's own window. */
168 x_real_pos_and_offsets (struct frame
*f
,
172 int *bottom_offset_y
,
179 int win_x
= 0, win_y
= 0, outer_x
= 0, outer_y
= 0;
180 int real_x
= 0, real_y
= 0;
181 bool had_errors
= false;
182 Window win
= f
->output_data
.x
->parent_desc
;
183 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
185 Atom target_type
= XA_CARDINAL
;
186 unsigned int ow
= 0, oh
= 0;
187 unsigned int fw
= 0, fh
= 0;
189 /* We resort to XCB if possible because there are several X calls
190 here which require responses from the server but do not have data
191 dependencies between them. Using XCB lets us pipeline requests,
192 whereas with Xlib we must wait for each answer before sending the
195 For a non-local display, the round-trip time could be a few tens
196 of milliseconds, depending on the network distance. It doesn't
197 take a lot of those to add up to a noticeable hesitation in
198 responding to user actions. */
200 xcb_connection_t
*xcb_conn
= dpyinfo
->xcb_connection
;
201 xcb_get_property_cookie_t prop_cookie
;
202 xcb_get_geometry_cookie_t outer_geom_cookie
;
203 bool sent_requests
= false;
206 unsigned long actual_size
, bytes_remaining
;
207 int rc
, actual_format
;
208 Display
*dpy
= FRAME_X_DISPLAY (f
);
209 unsigned char *tmp_data
= NULL
;
212 if (x_pixels_diff
) *x_pixels_diff
= 0;
213 if (y_pixels_diff
) *y_pixels_diff
= 0;
214 if (left_offset_x
) *left_offset_x
= 0;
215 if (top_offset_y
) *top_offset_y
= 0;
216 if (right_offset_x
) *right_offset_x
= 0;
217 if (bottom_offset_y
) *bottom_offset_y
= 0;
220 if (outer_border
) *outer_border
= 0;
222 if (win
== dpyinfo
->root_window
)
223 win
= FRAME_OUTER_WINDOW (f
);
228 /* If we're using XCB, all errors are checked for on each call. */
229 x_catch_errors (dpy
);
232 /* This loop traverses up the containment tree until we hit the root
233 window. Window managers may intersect many windows between our window
234 and the root window. The window we find just before the root window
235 should be the outer WM window. */
238 Window wm_window
, rootw
;
241 xcb_query_tree_cookie_t query_tree_cookie
;
242 xcb_query_tree_reply_t
*query_tree
;
244 query_tree_cookie
= xcb_query_tree (xcb_conn
, win
);
245 query_tree
= xcb_query_tree_reply (xcb_conn
, query_tree_cookie
, NULL
);
246 if (query_tree
== NULL
)
250 wm_window
= query_tree
->parent
;
251 rootw
= query_tree
->root
;
255 Window
*tmp_children
;
256 unsigned int tmp_nchildren
;
259 success
= XQueryTree (dpy
, win
, &rootw
,
260 &wm_window
, &tmp_children
, &tmp_nchildren
);
262 had_errors
= x_had_errors_p (dpy
);
264 /* Don't free tmp_children if XQueryTree failed. */
268 XFree (tmp_children
);
271 if (had_errors
|| wm_window
== rootw
)
280 xcb_get_geometry_cookie_t geom_cookie
;
281 xcb_translate_coordinates_cookie_t trans_cookie
;
282 xcb_translate_coordinates_cookie_t outer_trans_cookie
;
284 xcb_translate_coordinates_reply_t
*trans
;
285 xcb_get_geometry_reply_t
*geom
;
292 /* Fire off the requests that don't have data dependencies.
294 Once we've done this, we must collect the results for each
295 one before returning, even if other errors are detected,
296 making the other responses moot. */
297 geom_cookie
= xcb_get_geometry (xcb_conn
, win
);
300 xcb_translate_coordinates (xcb_conn
,
301 /* From-window, to-window. */
302 FRAME_DISPLAY_INFO (f
)->root_window
,
307 if (FRAME_X_WINDOW (f
) != FRAME_OUTER_WINDOW (f
))
309 xcb_translate_coordinates (xcb_conn
,
310 /* From-window, to-window. */
311 FRAME_DISPLAY_INFO (f
)->root_window
,
312 FRAME_OUTER_WINDOW (f
),
316 if (right_offset_x
|| bottom_offset_y
)
317 outer_geom_cookie
= xcb_get_geometry (xcb_conn
,
318 FRAME_OUTER_WINDOW (f
));
320 if (dpyinfo
->root_window
== f
->output_data
.x
->parent_desc
)
321 /* Try _NET_FRAME_EXTENTS if our parent is the root window. */
322 prop_cookie
= xcb_get_property (xcb_conn
, 0, win
,
323 dpyinfo
->Xatom_net_frame_extents
,
324 target_type
, 0, max_len
);
326 sent_requests
= true;
329 /* Get the real coordinates for the WM window upper left corner */
331 geom
= xcb_get_geometry_reply (xcb_conn
, geom_cookie
, NULL
);
338 bw
= geom
->border_width
;
344 XGetGeometry (dpy
, win
,
345 &rootw
, &real_x
, &real_y
, &ow
, &oh
, &bw
, &ign
);
348 /* Translate real coordinates to coordinates relative to our
349 window. For our window, the upper left corner is 0, 0.
350 Since the upper left corner of the WM window is outside
351 our window, win_x and win_y will be negative:
353 ------------------ ---> x
355 | ----------------- v y
358 Since we don't care about the child window corresponding to
359 the actual coordinates, we can send zero to get the offsets
360 and compute the resulting coordinates below. This reduces
361 the data dependencies between calls and lets us pipeline the
362 requests better in the XCB case. */
364 trans
= xcb_translate_coordinates_reply (xcb_conn
, trans_cookie
, NULL
);
367 win_x
= trans
->dst_x
;
368 win_y
= trans
->dst_y
;
374 XTranslateCoordinates (dpy
,
376 /* From-window, to-window. */
377 FRAME_DISPLAY_INFO (f
)->root_window
,
380 /* From-position, to-position. */
381 0, 0, &win_x
, &win_y
,
390 if (FRAME_X_WINDOW (f
) == FRAME_OUTER_WINDOW (f
))
398 xcb_translate_coordinates_reply_t
*outer_trans
;
400 outer_trans
= xcb_translate_coordinates_reply (xcb_conn
,
405 outer_x
= outer_trans
->dst_x
;
406 outer_y
= outer_trans
->dst_y
;
412 XTranslateCoordinates (dpy
,
414 /* From-window, to-window. */
415 FRAME_DISPLAY_INFO (f
)->root_window
,
416 FRAME_OUTER_WINDOW (f
),
418 /* From-position, to-position. */
419 0, 0, &outer_x
, &outer_y
,
430 had_errors
= x_had_errors_p (dpy
);
434 if (dpyinfo
->root_window
== f
->output_data
.x
->parent_desc
)
436 /* Try _NET_FRAME_EXTENTS if our parent is the root window. */
438 /* Make sure we didn't get an X error early and skip sending the
442 xcb_get_property_reply_t
*prop
;
444 prop
= xcb_get_property_reply (xcb_conn
, prop_cookie
, NULL
);
447 if (prop
->type
== target_type
448 && prop
->format
== 32
449 && (xcb_get_property_value_length (prop
)
450 == 4 * sizeof (int32_t)))
452 int32_t *fe
= xcb_get_property_value (prop
);
461 /* Xlib version doesn't set had_errors here. Intentional or bug? */
464 rc
= XGetWindowProperty (dpy
, win
, dpyinfo
->Xatom_net_frame_extents
,
465 0, max_len
, False
, target_type
,
466 &actual_type
, &actual_format
, &actual_size
,
467 &bytes_remaining
, &tmp_data
);
469 if (rc
== Success
&& actual_type
== target_type
&& !x_had_errors_p (dpy
)
470 && actual_size
== 4 && actual_format
== 32)
472 long *fe
= (long *)tmp_data
;
480 if (tmp_data
) XFree (tmp_data
);
484 if (right_offset_x
|| bottom_offset_y
)
487 /* Make sure we didn't get an X error early and skip sending the
491 xcb_get_geometry_reply_t
*outer_geom
;
493 outer_geom
= xcb_get_geometry_reply (xcb_conn
, outer_geom_cookie
,
497 fw
= outer_geom
->width
;
498 fh
= outer_geom
->height
;
509 XGetGeometry (dpy
, FRAME_OUTER_WINDOW (f
),
510 &rootw
, &xy_ign
, &xy_ign
, &fw
, &fh
, &ign
, &ign
);
520 if (had_errors
) return;
522 if (x_pixels_diff
) *x_pixels_diff
= -win_x
;
523 if (y_pixels_diff
) *y_pixels_diff
= -win_y
;
525 if (left_offset_x
) *left_offset_x
= -outer_x
;
526 if (top_offset_y
) *top_offset_y
= -outer_y
;
528 if (xptr
) *xptr
= real_x
;
529 if (yptr
) *yptr
= real_y
;
531 if (outer_border
) *outer_border
= bw
;
533 if (right_offset_x
) *right_offset_x
= ow
- fw
+ outer_x
;
534 if (bottom_offset_y
) *bottom_offset_y
= oh
- fh
+ outer_y
;
537 /* Store the screen positions of frame F into XPTR and YPTR.
538 These are the positions of the containing window manager window,
539 not Emacs's own window. */
542 x_real_positions (struct frame
*f
, int *xptr
, int *yptr
)
544 x_real_pos_and_offsets (f
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, xptr
, yptr
,
549 /* Get the mouse position in frame relative coordinates. */
552 x_relative_mouse_position (struct frame
*f
, int *x
, int *y
)
554 Window root
, dummy_window
;
557 eassert (FRAME_X_P (f
));
561 XQueryPointer (FRAME_X_DISPLAY (f
),
562 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
564 /* The root window which contains the pointer. */
567 /* Window pointer is on, not used */
570 /* The position on that root window. */
573 /* x/y in dummy_window coordinates, not used. */
576 /* Modifier keys and pointer buttons, about which
578 (unsigned int *) &dummy
);
580 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
582 /* From-window, to-window. */
583 FRAME_DISPLAY_INFO (f
)->root_window
,
586 /* From-position, to-position. */
595 /* Gamma-correct COLOR on frame F. */
598 gamma_correct (struct frame
*f
, XColor
*color
)
602 color
->red
= pow (color
->red
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
603 color
->green
= pow (color
->green
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
604 color
->blue
= pow (color
->blue
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
609 /* Decide if color named COLOR_NAME is valid for use on frame F. If
610 so, return the RGB values in COLOR. If ALLOC_P,
611 allocate the color. Value is false if COLOR_NAME is invalid, or
612 no color could be allocated. */
615 x_defined_color (struct frame
*f
, const char *color_name
,
616 XColor
*color
, bool alloc_p
)
618 bool success_p
= false;
619 Colormap cmap
= FRAME_X_COLORMAP (f
);
623 success_p
= xg_check_special_colors (f
, color_name
, color
);
626 success_p
= x_parse_color (f
, color_name
, color
) != 0;
627 if (success_p
&& alloc_p
)
628 success_p
= x_alloc_nearest_color (f
, cmap
, color
);
635 /* Return the pixel color value for color COLOR_NAME on frame F. If F
636 is a monochrome frame, return MONO_COLOR regardless of what ARG says.
637 Signal an error if color can't be allocated. */
640 x_decode_color (struct frame
*f
, Lisp_Object color_name
, int mono_color
)
644 CHECK_STRING (color_name
);
646 #if false /* Don't do this. It's wrong when we're not using the default
647 colormap, it makes freeing difficult, and it's probably not
648 an important optimization. */
649 if (strcmp (SDATA (color_name
), "black") == 0)
650 return BLACK_PIX_DEFAULT (f
);
651 else if (strcmp (SDATA (color_name
), "white") == 0)
652 return WHITE_PIX_DEFAULT (f
);
655 /* Return MONO_COLOR for monochrome frames. */
656 if (FRAME_DISPLAY_INFO (f
)->n_planes
== 1)
659 /* x_defined_color is responsible for coping with failures
660 by looking for a near-miss. */
661 if (x_defined_color (f
, SSDATA (color_name
), &cdef
, true))
664 signal_error ("Undefined color", color_name
);
669 /* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
670 the previous value of that parameter, NEW_VALUE is the new value.
671 See also the comment of wait_for_wm in struct x_output. */
674 x_set_wait_for_wm (struct frame
*f
, Lisp_Object new_value
, Lisp_Object old_value
)
676 f
->output_data
.x
->wait_for_wm
= !NILP (new_value
);
680 x_set_tool_bar_position (struct frame
*f
,
681 Lisp_Object new_value
,
682 Lisp_Object old_value
)
684 Lisp_Object choice
= list4 (Qleft
, Qright
, Qtop
, Qbottom
);
686 if (!NILP (Fmemq (new_value
, choice
)))
689 if (!EQ (new_value
, old_value
))
691 xg_change_toolbar_position (f
, new_value
);
692 fset_tool_bar_position (f
, new_value
);
695 if (!EQ (new_value
, Qtop
))
696 error ("The only supported tool bar position is top");
700 wrong_choice (choice
, new_value
);
705 /* Set icon from FILE for frame F. By using GTK functions the icon
706 may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
709 xg_set_icon (struct frame
*f
, Lisp_Object file
)
714 found
= x_find_image_file (file
);
720 char *filename
= SSDATA (ENCODE_FILE (found
));
723 pixbuf
= gdk_pixbuf_new_from_file (filename
, &err
);
727 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
729 g_object_unref (pixbuf
);
743 xg_set_icon_from_xpm_data (struct frame
*f
, const char **data
)
745 GdkPixbuf
*pixbuf
= gdk_pixbuf_new_from_xpm_data (data
);
750 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)), pixbuf
);
751 g_object_unref (pixbuf
);
757 /* Functions called only from `x_set_frame_param'
758 to set individual parameters.
760 If FRAME_X_WINDOW (f) is 0,
761 the frame is being created and its X-window does not exist yet.
762 In that case, just record the parameter's new value
763 in the standard place; do not attempt to change the window. */
766 x_set_foreground_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
768 struct x_output
*x
= f
->output_data
.x
;
769 unsigned long fg
, old_fg
;
771 fg
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
772 old_fg
= FRAME_FOREGROUND_PIXEL (f
);
773 FRAME_FOREGROUND_PIXEL (f
) = fg
;
775 if (FRAME_X_WINDOW (f
) != 0)
777 Display
*dpy
= FRAME_X_DISPLAY (f
);
780 XSetForeground (dpy
, x
->normal_gc
, fg
);
781 XSetBackground (dpy
, x
->reverse_gc
, fg
);
783 if (x
->cursor_pixel
== old_fg
)
785 unload_color (f
, x
->cursor_pixel
);
786 x
->cursor_pixel
= x_copy_color (f
, fg
);
787 XSetBackground (dpy
, x
->cursor_gc
, x
->cursor_pixel
);
792 update_face_from_frame_parameter (f
, Qforeground_color
, arg
);
794 if (FRAME_VISIBLE_P (f
))
798 unload_color (f
, old_fg
);
802 x_set_background_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
804 struct x_output
*x
= f
->output_data
.x
;
807 bg
= x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
808 unload_color (f
, FRAME_BACKGROUND_PIXEL (f
));
809 FRAME_BACKGROUND_PIXEL (f
) = bg
;
811 if (FRAME_X_WINDOW (f
) != 0)
813 Display
*dpy
= FRAME_X_DISPLAY (f
);
816 XSetBackground (dpy
, x
->normal_gc
, bg
);
817 XSetForeground (dpy
, x
->reverse_gc
, bg
);
818 XSetWindowBackground (dpy
, FRAME_X_WINDOW (f
), bg
);
819 XSetForeground (dpy
, x
->cursor_gc
, bg
);
822 xg_set_background_color (f
, bg
);
825 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
826 toolkit scroll bars. */
829 for (bar
= FRAME_SCROLL_BARS (f
);
831 bar
= XSCROLL_BAR (bar
)->next
)
833 Window window
= XSCROLL_BAR (bar
)->x_window
;
834 XSetWindowBackground (dpy
, window
, bg
);
837 #endif /* USE_TOOLKIT_SCROLL_BARS */
840 update_face_from_frame_parameter (f
, Qbackground_color
, arg
);
842 if (FRAME_VISIBLE_P (f
))
847 /* This array must stay in sync with the mouse_cursor_types array below! */
850 mouse_cursor_nontext
,
851 mouse_cursor_hourglass
,
854 mouse_cursor_horizontal_drag
,
855 mouse_cursor_vertical_drag
,
859 struct mouse_cursor_types
{
860 /* Printable name for error messages (optional). */
863 /* Lisp variable controlling the cursor shape. */
864 /* FIXME: A couple of these variables are defined in the C code but
865 are not actually accessible from Lisp. They should probably be
866 made accessible or removed. */
867 Lisp_Object
*shape_var_ptr
;
869 /* The default shape. */
873 /* This array must stay in sync with enum mouse_cursor above! */
874 static const struct mouse_cursor_types mouse_cursor_types
[] = {
875 { "text", &Vx_pointer_shape
, XC_xterm
},
876 { "nontext", &Vx_nontext_pointer_shape
, XC_left_ptr
},
877 { "hourglass", &Vx_hourglass_pointer_shape
, XC_watch
},
878 { "modeline", &Vx_mode_pointer_shape
, XC_xterm
},
879 { NULL
, &Vx_sensitive_text_pointer_shape
, XC_hand2
},
880 { NULL
, &Vx_window_horizontal_drag_shape
, XC_sb_h_double_arrow
},
881 { NULL
, &Vx_window_vertical_drag_shape
, XC_sb_v_double_arrow
},
884 struct mouse_cursor_data
{
885 /* Last index for which XCreateFontCursor has been called, and thus
886 the last index for which x_request_serial[] is valid. */
887 int last_cursor_create_request
;
889 /* Last index for which an X error event was received in response to
890 attempting to create the cursor. */
893 /* Cursor numbers chosen. */
894 unsigned int cursor_num
[mouse_cursor_max
];
896 /* Allocated Cursor values, or zero for failed attempts. */
897 Cursor cursor
[mouse_cursor_max
];
899 /* X serial numbers for the first request sent by XCreateFontCursor.
900 Note that there may be more than one request sent. */
901 unsigned long x_request_serial
[mouse_cursor_max
];
903 /* If an error has been received, a pointer to where the current
904 error-message text is stored. */
909 x_set_mouse_color_handler (Display
*dpy
, XErrorEvent
*event
,
910 char *error_string
, void *data
)
912 struct mouse_cursor_data
*cursor_data
= data
;
915 cursor_data
->error_cursor
= -1;
916 cursor_data
->error_string
= error_string
;
917 for (i
= 0; i
< cursor_data
->last_cursor_create_request
; i
++)
919 if (event
->serial
>= cursor_data
->x_request_serial
[i
])
920 cursor_data
->error_cursor
= i
;
922 if (cursor_data
->error_cursor
>= 0)
923 /* If we failed to allocate it, don't try to free it. */
924 cursor_data
->cursor
[cursor_data
->error_cursor
] = 0;
928 x_set_mouse_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
930 struct x_output
*x
= f
->output_data
.x
;
931 Display
*dpy
= FRAME_X_DISPLAY (f
);
932 struct mouse_cursor_data cursor_data
= { -1, -1 };
933 unsigned long pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
934 unsigned long mask_color
= FRAME_BACKGROUND_PIXEL (f
);
937 /* Don't let pointers be invisible. */
938 if (mask_color
== pixel
)
940 x_free_colors (f
, &pixel
, 1);
941 pixel
= x_copy_color (f
, FRAME_FOREGROUND_PIXEL (f
));
944 unload_color (f
, x
->mouse_pixel
);
945 x
->mouse_pixel
= pixel
;
947 for (i
= 0; i
< mouse_cursor_max
; i
++)
949 Lisp_Object shape_var
= *mouse_cursor_types
[i
].shape_var_ptr
;
950 if (!NILP (shape_var
))
952 CHECK_TYPE_RANGED_INTEGER (unsigned, shape_var
);
953 cursor_data
.cursor_num
[i
] = XINT (shape_var
);
956 cursor_data
.cursor_num
[i
] = mouse_cursor_types
[i
].default_shape
;
961 /* It's not okay to crash if the user selects a screwy cursor. */
962 x_catch_errors_with_handler (dpy
, x_set_mouse_color_handler
, &cursor_data
);
964 for (i
= 0; i
< mouse_cursor_max
; i
++)
966 cursor_data
.x_request_serial
[i
] = XNextRequest (dpy
);
967 cursor_data
.last_cursor_create_request
= i
;
968 cursor_data
.cursor
[i
] = XCreateFontCursor (dpy
,
969 cursor_data
.cursor_num
[i
]);
972 /* Now sync up and process all received errors from cursor
974 if (x_had_errors_p (dpy
))
976 const char *bad_cursor_name
= NULL
;
977 /* Bounded by X_ERROR_MESSAGE_SIZE in xterm.c. */
978 size_t message_length
= strlen (cursor_data
.error_string
);
979 char *xmessage
= alloca (1 + message_length
);
980 memcpy (xmessage
, cursor_data
.error_string
, message_length
);
984 /* Free any successfully created cursors. */
985 for (i
= 0; i
< mouse_cursor_max
; i
++)
986 if (cursor_data
.cursor
[i
] != 0)
987 XFreeCursor (dpy
, cursor_data
.cursor
[i
]);
989 /* This should only be able to fail if the server's serial
990 number tracking is broken. */
991 if (cursor_data
.error_cursor
>= 0)
992 bad_cursor_name
= mouse_cursor_types
[cursor_data
.error_cursor
].name
;
994 error ("bad %s pointer cursor: %s", bad_cursor_name
, xmessage
);
996 error ("can't set cursor shape: %s", xmessage
);
999 x_uncatch_errors_after_check ();
1002 XColor colors
[2]; /* 0=foreground, 1=background */
1004 colors
[0].pixel
= x
->mouse_pixel
;
1005 colors
[1].pixel
= mask_color
;
1006 x_query_colors (f
, colors
, 2);
1008 for (i
= 0; i
< mouse_cursor_max
; i
++)
1009 XRecolorCursor (dpy
, cursor_data
.cursor
[i
], &colors
[0], &colors
[1]);
1012 if (FRAME_X_WINDOW (f
) != 0)
1014 f
->output_data
.x
->current_cursor
= cursor_data
.cursor
[mouse_cursor_text
];
1015 XDefineCursor (dpy
, FRAME_X_WINDOW (f
),
1016 f
->output_data
.x
->current_cursor
);
1019 #define INSTALL_CURSOR(FIELD, SHORT_INDEX) \
1020 eassert (x->FIELD != cursor_data.cursor[mouse_cursor_ ## SHORT_INDEX]); \
1021 if (x->FIELD != 0) \
1022 XFreeCursor (dpy, x->FIELD); \
1023 x->FIELD = cursor_data.cursor[mouse_cursor_ ## SHORT_INDEX];
1025 INSTALL_CURSOR (text_cursor
, text
);
1026 INSTALL_CURSOR (nontext_cursor
, nontext
);
1027 INSTALL_CURSOR (hourglass_cursor
, hourglass
);
1028 INSTALL_CURSOR (modeline_cursor
, mode
);
1029 INSTALL_CURSOR (hand_cursor
, hand
);
1030 INSTALL_CURSOR (horizontal_drag_cursor
, horizontal_drag
);
1031 INSTALL_CURSOR (vertical_drag_cursor
, vertical_drag
);
1033 #undef INSTALL_CURSOR
1038 update_face_from_frame_parameter (f
, Qmouse_color
, arg
);
1042 x_set_cursor_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1044 unsigned long fore_pixel
, pixel
;
1045 bool fore_pixel_allocated_p
= false, pixel_allocated_p
= false;
1046 struct x_output
*x
= f
->output_data
.x
;
1048 if (!NILP (Vx_cursor_fore_pixel
))
1050 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
1051 WHITE_PIX_DEFAULT (f
));
1052 fore_pixel_allocated_p
= true;
1055 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
1057 pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1058 pixel_allocated_p
= true;
1060 /* Make sure that the cursor color differs from the background color. */
1061 if (pixel
== FRAME_BACKGROUND_PIXEL (f
))
1063 if (pixel_allocated_p
)
1065 x_free_colors (f
, &pixel
, 1);
1066 pixel_allocated_p
= false;
1069 pixel
= x
->mouse_pixel
;
1070 if (pixel
== fore_pixel
)
1072 if (fore_pixel_allocated_p
)
1074 x_free_colors (f
, &fore_pixel
, 1);
1075 fore_pixel_allocated_p
= false;
1077 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
1081 unload_color (f
, x
->cursor_foreground_pixel
);
1082 if (!fore_pixel_allocated_p
)
1083 fore_pixel
= x_copy_color (f
, fore_pixel
);
1084 x
->cursor_foreground_pixel
= fore_pixel
;
1086 unload_color (f
, x
->cursor_pixel
);
1087 if (!pixel_allocated_p
)
1088 pixel
= x_copy_color (f
, pixel
);
1089 x
->cursor_pixel
= pixel
;
1091 if (FRAME_X_WINDOW (f
) != 0)
1094 XSetBackground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, x
->cursor_pixel
);
1095 XSetForeground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, fore_pixel
);
1098 if (FRAME_VISIBLE_P (f
))
1100 x_update_cursor (f
, false);
1101 x_update_cursor (f
, true);
1105 update_face_from_frame_parameter (f
, Qcursor_color
, arg
);
1108 /* Set the border-color of frame F to pixel value PIX.
1109 Note that this does not fully take effect if done before
1110 F has an x-window. */
1113 x_set_border_pixel (struct frame
*f
, int pix
)
1115 unload_color (f
, f
->output_data
.x
->border_pixel
);
1116 f
->output_data
.x
->border_pixel
= pix
;
1118 if (FRAME_X_WINDOW (f
) != 0 && f
->border_width
> 0)
1121 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), pix
);
1124 if (FRAME_VISIBLE_P (f
))
1129 /* Set the border-color of frame F to value described by ARG.
1130 ARG can be a string naming a color.
1131 The border-color is used for the border that is drawn by the X server.
1132 Note that this does not fully take effect if done before
1133 F has an x-window; it must be redone when the window is created.
1135 Note: this is done in two routines because of the way X10 works.
1137 Note: under X11, this is normally the province of the window manager,
1138 and so emacs's border colors may be overridden. */
1141 x_set_border_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1146 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1147 x_set_border_pixel (f
, pix
);
1148 update_face_from_frame_parameter (f
, Qborder_color
, arg
);
1153 x_set_cursor_type (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1155 set_frame_cursor_types (f
, arg
);
1159 x_set_icon_type (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1165 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1168 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1173 result
= x_text_icon (f
,
1174 SSDATA ((!NILP (f
->icon_name
)
1178 result
= x_bitmap_icon (f
, arg
);
1183 error ("No icon window available");
1186 XFlush (FRAME_X_DISPLAY (f
));
1191 x_set_icon_name (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1197 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1200 else if (!NILP (arg
) || NILP (oldval
))
1203 fset_icon_name (f
, arg
);
1205 if (f
->output_data
.x
->icon_bitmap
!= 0)
1210 result
= x_text_icon (f
,
1211 SSDATA ((!NILP (f
->icon_name
)
1220 error ("No icon window available");
1223 XFlush (FRAME_X_DISPLAY (f
));
1229 x_set_menu_bar_lines (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
1232 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
1233 int olines
= FRAME_MENU_BAR_LINES (f
);
1236 /* Right now, menu bars don't work properly in minibuf-only frames;
1237 most of the commands try to apply themselves to the minibuffer
1238 frame itself, and get an error because you can't switch buffers
1239 in or split the minibuffer window. */
1240 if (FRAME_MINIBUF_ONLY_P (f
))
1243 if (TYPE_RANGED_INTEGERP (int, value
))
1244 nlines
= XINT (value
);
1248 /* Make sure we redisplay all windows in this frame. */
1251 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1252 FRAME_MENU_BAR_LINES (f
) = 0;
1253 FRAME_MENU_BAR_HEIGHT (f
) = 0;
1256 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
1257 if (FRAME_X_P (f
) && f
->output_data
.x
->menubar_widget
== 0)
1258 /* Make sure next redisplay shows the menu bar. */
1259 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= true;
1263 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
1264 free_frame_menubar (f
);
1265 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
1267 f
->output_data
.x
->menubar_widget
= 0;
1269 #else /* not USE_X_TOOLKIT && not USE_GTK */
1270 FRAME_MENU_BAR_LINES (f
) = nlines
;
1271 FRAME_MENU_BAR_HEIGHT (f
) = nlines
* FRAME_LINE_HEIGHT (f
);
1272 adjust_frame_size (f
, -1, -1, 2, true, Qx_set_menu_bar_lines
);
1273 if (FRAME_X_WINDOW (f
))
1274 x_clear_under_internal_border (f
);
1276 /* If the menu bar height gets changed, the internal border below
1277 the top margin has to be cleared. Also, if the menu bar gets
1278 larger, the area for the added lines has to be cleared except for
1279 the first menu bar line that is to be drawn later. */
1280 if (nlines
!= olines
)
1282 int height
= FRAME_INTERNAL_BORDER_WIDTH (f
);
1283 int width
= FRAME_PIXEL_WIDTH (f
);
1286 /* height can be zero here. */
1287 if (FRAME_X_WINDOW (f
) && height
> 0 && width
> 0)
1289 y
= FRAME_TOP_MARGIN_HEIGHT (f
);
1292 x_clear_area (f
, 0, y
, width
, height
);
1296 if (nlines
> 1 && nlines
> olines
)
1298 y
= (olines
== 0 ? 1 : olines
) * FRAME_LINE_HEIGHT (f
);
1299 height
= nlines
* FRAME_LINE_HEIGHT (f
) - y
;
1302 x_clear_area (f
, 0, y
, width
, height
);
1306 if (nlines
== 0 && WINDOWP (f
->menu_bar_window
))
1307 clear_glyph_matrix (XWINDOW (f
->menu_bar_window
)->current_matrix
);
1309 #endif /* not USE_X_TOOLKIT && not USE_GTK */
1310 adjust_frame_glyphs (f
);
1314 /* Set the number of lines used for the tool bar of frame F to VALUE.
1315 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1316 is the old number of tool bar lines. This function changes the
1317 height of all windows on frame F to match the new tool bar height.
1318 The frame's height doesn't change. */
1321 x_set_tool_bar_lines (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
1325 /* Treat tool bars like menu bars. */
1326 if (FRAME_MINIBUF_ONLY_P (f
))
1329 /* Use VALUE only if an int >= 0. */
1330 if (RANGED_INTEGERP (0, value
, INT_MAX
))
1331 nlines
= XFASTINT (value
);
1335 x_change_tool_bar_height (f
, nlines
* FRAME_LINE_HEIGHT (f
));
1339 /* Set the pixel height of the tool bar of frame F to HEIGHT. */
1341 x_change_tool_bar_height (struct frame
*f
, int height
)
1344 FRAME_TOOL_BAR_LINES (f
) = 0;
1345 FRAME_TOOL_BAR_HEIGHT (f
) = 0;
1348 FRAME_EXTERNAL_TOOL_BAR (f
) = true;
1349 if (FRAME_X_P (f
) && f
->output_data
.x
->toolbar_widget
== 0)
1350 /* Make sure next redisplay shows the tool bar. */
1351 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= true;
1352 update_frame_tool_bar (f
);
1356 if (FRAME_EXTERNAL_TOOL_BAR (f
))
1357 free_frame_tool_bar (f
);
1358 FRAME_EXTERNAL_TOOL_BAR (f
) = false;
1360 #else /* !USE_GTK */
1361 int unit
= FRAME_LINE_HEIGHT (f
);
1362 int old_height
= FRAME_TOOL_BAR_HEIGHT (f
);
1363 int lines
= (height
+ unit
- 1) / unit
;
1364 Lisp_Object fullscreen
;
1366 /* Make sure we redisplay all windows in this frame. */
1369 /* Recalculate tool bar and frame text sizes. */
1370 FRAME_TOOL_BAR_HEIGHT (f
) = height
;
1371 FRAME_TOOL_BAR_LINES (f
) = lines
;
1372 /* Store the `tool-bar-lines' and `height' frame parameters. */
1373 store_frame_param (f
, Qtool_bar_lines
, make_number (lines
));
1374 store_frame_param (f
, Qheight
, make_number (FRAME_LINES (f
)));
1376 /* We also have to make sure that the internal border at the top of
1377 the frame, below the menu bar or tool bar, is redrawn when the
1378 tool bar disappears. This is so because the internal border is
1379 below the tool bar if one is displayed, but is below the menu bar
1380 if there isn't a tool bar. The tool bar draws into the area
1381 below the menu bar. */
1382 if (FRAME_X_WINDOW (f
) && FRAME_TOOL_BAR_HEIGHT (f
) == 0)
1385 clear_current_matrices (f
);
1388 if ((height
< old_height
) && WINDOWP (f
->tool_bar_window
))
1389 clear_glyph_matrix (XWINDOW (f
->tool_bar_window
)->current_matrix
);
1391 /* Recalculate toolbar height. */
1392 f
->n_tool_bar_rows
= 0;
1394 && (!f
->after_make_frame
1395 || NILP (frame_inhibit_implied_resize
)
1396 || (CONSP (frame_inhibit_implied_resize
)
1397 && NILP (Fmemq (Qtool_bar_lines
, frame_inhibit_implied_resize
)))))
1398 f
->tool_bar_redisplayed
= f
->tool_bar_resized
= false;
1400 adjust_frame_size (f
, -1, -1,
1401 ((!f
->tool_bar_resized
1402 && (NILP (fullscreen
=
1403 get_frame_param (f
, Qfullscreen
))
1404 || EQ (fullscreen
, Qfullwidth
))) ? 1
1405 : (old_height
== 0 || height
== 0) ? 2
1407 false, Qtool_bar_lines
);
1409 f
->tool_bar_resized
= f
->tool_bar_redisplayed
;
1411 /* adjust_frame_size might not have done anything, garbage frame
1413 adjust_frame_glyphs (f
);
1414 SET_FRAME_GARBAGED (f
);
1415 if (FRAME_X_WINDOW (f
))
1416 x_clear_under_internal_border (f
);
1418 #endif /* USE_GTK */
1423 x_set_internal_border_width (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1427 CHECK_TYPE_RANGED_INTEGER (int, arg
);
1428 border
= max (XINT (arg
), 0);
1430 if (border
!= FRAME_INTERNAL_BORDER_WIDTH (f
))
1432 f
->internal_border_width
= border
;
1434 #ifdef USE_X_TOOLKIT
1435 if (FRAME_X_OUTPUT (f
)->edit_widget
)
1436 widget_store_internal_border (FRAME_X_OUTPUT (f
)->edit_widget
);
1439 if (FRAME_X_WINDOW (f
) != 0)
1441 adjust_frame_size (f
, -1, -1, 3, false, Qinternal_border_width
);
1444 xg_clear_under_internal_border (f
);
1446 x_clear_under_internal_border (f
);
1454 /* Set the foreground color for scroll bars on frame F to VALUE.
1455 VALUE should be a string, a color name. If it isn't a string or
1456 isn't a valid color name, do nothing. OLDVAL is the old value of
1457 the frame parameter. */
1460 x_set_scroll_bar_foreground (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
1462 unsigned long pixel
;
1464 if (STRINGP (value
))
1465 pixel
= x_decode_color (f
, value
, BLACK_PIX_DEFAULT (f
));
1469 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
1470 unload_color (f
, f
->output_data
.x
->scroll_bar_foreground_pixel
);
1472 f
->output_data
.x
->scroll_bar_foreground_pixel
= pixel
;
1473 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1475 /* Remove all scroll bars because they have wrong colors. */
1476 if (FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
)
1477 (*FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
) (f
);
1478 if (FRAME_TERMINAL (f
)->judge_scroll_bars_hook
)
1479 (*FRAME_TERMINAL (f
)->judge_scroll_bars_hook
) (f
);
1481 update_face_from_frame_parameter (f
, Qscroll_bar_foreground
, value
);
1487 /* Set the background color for scroll bars on frame F to VALUE VALUE
1488 should be a string, a color name. If it isn't a string or isn't a
1489 valid color name, do nothing. OLDVAL is the old value of the frame
1493 x_set_scroll_bar_background (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
1495 unsigned long pixel
;
1497 if (STRINGP (value
))
1498 pixel
= x_decode_color (f
, value
, WHITE_PIX_DEFAULT (f
));
1502 if (f
->output_data
.x
->scroll_bar_background_pixel
!= -1)
1503 unload_color (f
, f
->output_data
.x
->scroll_bar_background_pixel
);
1505 #if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
1506 /* Scrollbar shadow colors. */
1507 if (f
->output_data
.x
->scroll_bar_top_shadow_pixel
!= -1)
1509 unload_color (f
, f
->output_data
.x
->scroll_bar_top_shadow_pixel
);
1510 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
1512 if (f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
!= -1)
1514 unload_color (f
, f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
);
1515 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
1517 #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
1519 f
->output_data
.x
->scroll_bar_background_pixel
= pixel
;
1520 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1522 /* Remove all scroll bars because they have wrong colors. */
1523 if (FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
)
1524 (*FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
) (f
);
1525 if (FRAME_TERMINAL (f
)->judge_scroll_bars_hook
)
1526 (*FRAME_TERMINAL (f
)->judge_scroll_bars_hook
) (f
);
1528 update_face_from_frame_parameter (f
, Qscroll_bar_background
, value
);
1534 /* Encode Lisp string STRING as a text in a format appropriate for
1535 XICCC (X Inter Client Communication Conventions).
1537 If STRING contains only ASCII characters, do no conversion and
1538 return the string data of STRING. Otherwise, encode the text by
1539 CODING_SYSTEM, and return a newly allocated memory area which
1540 should be freed by `xfree' by a caller.
1542 Store the byte length of resulting text in *TEXT_BYTES.
1544 If the text contains only ASCII and Latin-1, store true in *STRING_P,
1545 which means that the `encoding' of the result can be `STRING'.
1546 Otherwise store false in *STRINGP, which means that the `encoding' of
1547 the result should be `COMPOUND_TEXT'. */
1549 static unsigned char *
1550 x_encode_text (Lisp_Object string
, Lisp_Object coding_system
,
1551 ptrdiff_t *text_bytes
, bool *stringp
, bool *freep
)
1553 int result
= string_xstring_p (string
);
1554 struct coding_system coding
;
1558 /* No multibyte character in OBJ. We need not encode it. */
1559 *text_bytes
= SBYTES (string
);
1562 return SDATA (string
);
1565 setup_coding_system (coding_system
, &coding
);
1566 coding
.mode
|= (CODING_MODE_SAFE_ENCODING
| CODING_MODE_LAST_BLOCK
);
1567 /* We suppress producing escape sequences for composition. */
1568 coding
.common_flags
&= ~CODING_ANNOTATION_MASK
;
1569 coding
.destination
= xnmalloc (SCHARS (string
), 2);
1570 coding
.dst_bytes
= SCHARS (string
) * 2;
1571 encode_coding_object (&coding
, string
, 0, 0,
1572 SCHARS (string
), SBYTES (string
), Qnil
);
1573 *text_bytes
= coding
.produced
;
1574 *stringp
= (result
== 1 || !EQ (coding_system
, Qcompound_text
));
1576 return coding
.destination
;
1580 /* Set the WM name to NAME for frame F. Also set the icon name.
1581 If the frame already has an icon name, use that, otherwise set the
1582 icon name to NAME. */
1585 x_set_name_internal (struct frame
*f
, Lisp_Object name
)
1587 if (FRAME_X_WINDOW (f
))
1591 XTextProperty text
, icon
;
1594 bool do_free_icon_value
= false, do_free_text_value
= false;
1595 Lisp_Object coding_system
;
1596 Lisp_Object encoded_name
;
1597 Lisp_Object encoded_icon_name
;
1599 /* As ENCODE_UTF_8 may cause GC and relocation of string data,
1600 we use it before x_encode_text that may return string data. */
1601 encoded_name
= ENCODE_UTF_8 (name
);
1603 coding_system
= Qcompound_text
;
1604 /* Note: Encoding strategy
1606 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1607 text.encoding. But, there are non-internationalized window
1608 managers which don't support that encoding. So, if NAME
1609 contains only ASCII and 8859-1 characters, encode it by
1610 iso-latin-1, and use "STRING" in text.encoding hoping that
1611 such window managers at least analyze this format correctly,
1612 i.e. treat 8-bit bytes as 8859-1 characters.
1614 We may also be able to use "UTF8_STRING" in text.encoding
1615 in the future which can encode all Unicode characters.
1616 But, for the moment, there's no way to know that the
1617 current window manager supports it or not.
1619 Either way, we also set the _NET_WM_NAME and _NET_WM_ICON_NAME
1620 properties. Per the EWMH specification, those two properties
1621 are always UTF8_STRING. This matches what gtk_window_set_title()
1622 does in the USE_GTK case. */
1623 text
.value
= x_encode_text (name
, coding_system
, &bytes
,
1624 &stringp
, &do_free_text_value
);
1625 text
.encoding
= (stringp
? XA_STRING
1626 : FRAME_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1628 text
.nitems
= bytes
;
1630 if (!STRINGP (f
->icon_name
))
1633 encoded_icon_name
= encoded_name
;
1637 /* See the above comment "Note: Encoding strategy". */
1638 icon
.value
= x_encode_text (f
->icon_name
, coding_system
, &bytes
,
1639 &stringp
, &do_free_icon_value
);
1640 icon
.encoding
= (stringp
? XA_STRING
1641 : FRAME_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1643 icon
.nitems
= bytes
;
1645 encoded_icon_name
= ENCODE_UTF_8 (f
->icon_name
);
1649 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
1650 SSDATA (encoded_name
));
1651 #else /* not USE_GTK */
1652 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &text
);
1653 XChangeProperty (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
1654 FRAME_DISPLAY_INFO (f
)->Xatom_net_wm_name
,
1655 FRAME_DISPLAY_INFO (f
)->Xatom_UTF8_STRING
,
1657 SDATA (encoded_name
),
1658 SBYTES (encoded_name
));
1659 #endif /* not USE_GTK */
1661 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &icon
);
1662 XChangeProperty (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
1663 FRAME_DISPLAY_INFO (f
)->Xatom_net_wm_icon_name
,
1664 FRAME_DISPLAY_INFO (f
)->Xatom_UTF8_STRING
,
1666 SDATA (encoded_icon_name
),
1667 SBYTES (encoded_icon_name
));
1669 if (do_free_icon_value
)
1671 if (do_free_text_value
)
1678 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1681 If EXPLICIT is true, that indicates that lisp code is setting the
1682 name; if NAME is a string, set F's name to NAME and set
1683 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1685 If EXPLICIT is false, that indicates that Emacs redisplay code is
1686 suggesting a new name, which lisp code should override; if
1687 F->explicit_name is set, ignore the new name; otherwise, set it. */
1690 x_set_name (struct frame
*f
, Lisp_Object name
, bool explicit)
1692 /* Make sure that requests from lisp code override requests from
1693 Emacs redisplay code. */
1696 /* If we're switching from explicit to implicit, we had better
1697 update the mode lines and thereby update the title. */
1698 if (f
->explicit_name
&& NILP (name
))
1699 update_mode_lines
= 37;
1701 f
->explicit_name
= ! NILP (name
);
1703 else if (f
->explicit_name
)
1706 /* If NAME is nil, set the name to the x_id_name. */
1709 /* Check for no change needed in this very common case
1710 before we do any consing. */
1711 if (!strcmp (FRAME_DISPLAY_INFO (f
)->x_id_name
,
1714 name
= build_string (FRAME_DISPLAY_INFO (f
)->x_id_name
);
1717 CHECK_STRING (name
);
1719 /* Don't change the name if it's already NAME. */
1720 if (! NILP (Fstring_equal (name
, f
->name
)))
1723 fset_name (f
, name
);
1725 /* For setting the frame title, the title parameter should override
1726 the name parameter. */
1727 if (! NILP (f
->title
))
1730 x_set_name_internal (f
, name
);
1733 /* This function should be called when the user's lisp code has
1734 specified a name for the frame; the name will override any set by the
1737 x_explicitly_set_name (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1739 x_set_name (f
, arg
, true);
1742 /* This function should be called by Emacs redisplay code to set the
1743 name; names set this way will never override names set by the user's
1746 x_implicitly_set_name (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1748 x_set_name (f
, arg
, false);
1751 /* Change the title of frame F to NAME.
1752 If NAME is nil, use the frame name as the title. */
1755 x_set_title (struct frame
*f
, Lisp_Object name
, Lisp_Object old_name
)
1757 /* Don't change the title if it's already NAME. */
1758 if (EQ (name
, f
->title
))
1761 update_mode_lines
= 38;
1763 fset_title (f
, name
);
1768 CHECK_STRING (name
);
1770 x_set_name_internal (f
, name
);
1774 x_set_scroll_bar_default_width (struct frame
*f
)
1776 int unit
= FRAME_COLUMN_WIDTH (f
);
1777 #ifdef USE_TOOLKIT_SCROLL_BARS
1779 int minw
= xg_get_default_scrollbar_width ();
1783 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
1784 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (minw
+ unit
- 1) / unit
;
1785 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = minw
;
1787 /* The width of a non-toolkit scrollbar is 14 pixels. */
1788 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + unit
- 1) / unit
;
1789 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
)
1790 = FRAME_CONFIG_SCROLL_BAR_COLS (f
) * unit
;
1795 x_set_scroll_bar_default_height (struct frame
*f
)
1797 int height
= FRAME_LINE_HEIGHT (f
);
1798 #ifdef USE_TOOLKIT_SCROLL_BARS
1800 int min_height
= xg_get_default_scrollbar_height ();
1802 int min_height
= 16;
1804 /* A minimum height of 14 doesn't look good for toolkit scroll bars. */
1805 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f
) = min_height
;
1806 FRAME_CONFIG_SCROLL_BAR_LINES (f
) = (min_height
+ height
- 1) / height
;
1808 /* The height of a non-toolkit scrollbar is 14 pixels. */
1809 FRAME_CONFIG_SCROLL_BAR_LINES (f
) = (14 + height
- 1) / height
;
1811 /* Use all of that space (aside from required margins) for the
1813 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f
) = 14;
1818 /* Record in frame F the specified or default value according to ALIST
1819 of the parameter named PROP (a Lisp symbol). If no value is
1820 specified for PROP, look for an X default for XPROP on the frame
1821 named NAME. If that is not found either, use the value DEFLT. */
1824 x_default_scroll_bar_color_parameter (struct frame
*f
,
1825 Lisp_Object alist
, Lisp_Object prop
,
1826 const char *xprop
, const char *xclass
,
1829 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
1832 tem
= x_get_arg (dpyinfo
, alist
, prop
, xprop
, xclass
, RES_TYPE_STRING
);
1833 if (EQ (tem
, Qunbound
))
1835 #ifdef USE_TOOLKIT_SCROLL_BARS
1837 /* See if an X resource for the scroll bar color has been
1839 AUTO_STRING (foreground
, "foreground");
1840 AUTO_STRING (background
, "foreground");
1841 AUTO_STRING (verticalScrollBar
, "verticalScrollBar");
1842 tem
= (display_x_get_resource
1843 (dpyinfo
, foreground_p
? foreground
: background
,
1844 empty_unibyte_string
,
1846 empty_unibyte_string
));
1849 /* If nothing has been specified, scroll bars will use a
1850 toolkit-dependent default. Because these defaults are
1851 difficult to get at without actually creating a scroll
1852 bar, use nil to indicate that no color has been
1857 #else /* not USE_TOOLKIT_SCROLL_BARS */
1861 #endif /* not USE_TOOLKIT_SCROLL_BARS */
1864 AUTO_FRAME_ARG (arg
, prop
, tem
);
1865 x_set_frame_parameters (f
, arg
);
1872 #ifdef USE_X_TOOLKIT
1874 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
1875 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
1876 already be present because of the toolkit (Motif adds some of them,
1877 for example, but Xt doesn't). */
1880 hack_wm_protocols (struct frame
*f
, Widget widget
)
1882 Display
*dpy
= XtDisplay (widget
);
1883 Window w
= XtWindow (widget
);
1884 bool need_delete
= true;
1885 bool need_focus
= true;
1886 bool need_save
= true;
1891 unsigned char *catoms
;
1893 unsigned long nitems
= 0;
1894 unsigned long bytes_after
;
1896 if ((XGetWindowProperty (dpy
, w
,
1897 FRAME_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
1898 0, 100, False
, XA_ATOM
,
1899 &type
, &format
, &nitems
, &bytes_after
,
1902 && format
== 32 && type
== XA_ATOM
)
1904 Atom
*atoms
= (Atom
*) catoms
;
1909 == FRAME_DISPLAY_INFO (f
)->Xatom_wm_delete_window
)
1910 need_delete
= false;
1911 else if (atoms
[nitems
]
1912 == FRAME_DISPLAY_INFO (f
)->Xatom_wm_take_focus
)
1914 else if (atoms
[nitems
]
1915 == FRAME_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
)
1926 props
[count
++] = FRAME_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
1928 props
[count
++] = FRAME_DISPLAY_INFO (f
)->Xatom_wm_take_focus
;
1930 props
[count
++] = FRAME_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
1932 XChangeProperty (dpy
, w
, FRAME_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
1933 XA_ATOM
, 32, PropModeAppend
,
1934 (unsigned char *) props
, count
);
1942 /* Support routines for XIC (X Input Context). */
1946 static XFontSet
xic_create_xfontset (struct frame
*);
1947 static XIMStyle
best_xim_style (XIMStyles
*);
1950 /* Supported XIM styles, ordered by preference. */
1952 static const XIMStyle supported_xim_styles
[] =
1954 XIMPreeditPosition
| XIMStatusArea
,
1955 XIMPreeditPosition
| XIMStatusNothing
,
1956 XIMPreeditPosition
| XIMStatusNone
,
1957 XIMPreeditNothing
| XIMStatusArea
,
1958 XIMPreeditNothing
| XIMStatusNothing
,
1959 XIMPreeditNothing
| XIMStatusNone
,
1960 XIMPreeditNone
| XIMStatusArea
,
1961 XIMPreeditNone
| XIMStatusNothing
,
1962 XIMPreeditNone
| XIMStatusNone
,
1967 #if defined HAVE_X_WINDOWS && defined USE_X_TOOLKIT
1968 /* Create an X fontset on frame F with base font name BASE_FONTNAME. */
1970 static const char xic_default_fontset
[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
1972 /* Create an Xt fontset spec from the name of a base font.
1973 If `motif' is True use the Motif syntax. */
1975 xic_create_fontsetname (const char *base_fontname
, bool motif
)
1977 const char *sep
= motif
? ";" : ",";
1981 /* Make a fontset name from the base font name. */
1982 if (xic_default_fontset
== base_fontname
)
1984 /* There is no base font name, use the default. */
1985 fontsetname
= xmalloc (strlen (base_fontname
) + 2);
1986 z
= stpcpy (fontsetname
, base_fontname
);
1990 /* Make a fontset name from the base font name.
1991 The font set will be made of the following elements:
1993 - the base font where the charset spec is replaced by -*-*.
1994 - the same but with the family also replaced with -*-*-. */
1995 const char *p
= base_fontname
;
1998 for (i
= 0; *p
; p
++)
2002 /* As the font name doesn't conform to XLFD, we can't
2003 modify it to generalize it to allcs and allfamilies.
2004 Use the specified font plus the default. */
2005 fontsetname
= xmalloc (strlen (base_fontname
)
2006 + strlen (xic_default_fontset
) + 3);
2007 z
= stpcpy (fontsetname
, base_fontname
);
2008 z
= stpcpy (z
, sep
);
2009 z
= stpcpy (z
, xic_default_fontset
);
2014 const char *p1
= NULL
, *p2
= NULL
, *p3
= NULL
;
2015 char *font_allcs
= NULL
;
2016 char *font_allfamilies
= NULL
;
2017 char *font_all
= NULL
;
2018 const char *allcs
= "*-*-*-*-*-*-*";
2019 const char *allfamilies
= "-*-*-";
2020 const char *all
= "*-*-*-*-";
2023 for (i
= 0, p
= base_fontname
; i
< 8; p
++)
2036 /* If base_fontname specifies ADSTYLE, make it a
2040 ptrdiff_t diff
= (p2
- p3
) - 2;
2042 base
= alloca (strlen (base_fontname
) + 1);
2043 memcpy (base
, base_fontname
, p3
- base_fontname
);
2044 base
[p3
- base_fontname
] = '*';
2045 base
[(p3
- base_fontname
) + 1] = '-';
2046 strcpy (base
+ (p3
- base_fontname
) + 2, p2
);
2047 p
= base
+ (p
- base_fontname
) - diff
;
2048 p1
= base
+ (p1
- base_fontname
);
2049 p2
= base
+ (p2
- base_fontname
) - diff
;
2050 base_fontname
= base
;
2053 /* Build the font spec that matches all charsets. */
2054 len
= p
- base_fontname
+ strlen (allcs
) + 1;
2055 font_allcs
= alloca (len
);
2056 memcpy (font_allcs
, base_fontname
, p
- base_fontname
);
2057 strcpy (font_allcs
+ (p
- base_fontname
), allcs
);
2059 /* Build the font spec that matches all families and
2061 len
= p
- p1
+ strlen (allcs
) + strlen (allfamilies
) + 1;
2062 font_allfamilies
= alloca (len
);
2063 strcpy (font_allfamilies
, allfamilies
);
2064 memcpy (font_allfamilies
+ strlen (allfamilies
), p1
, p
- p1
);
2065 strcpy (font_allfamilies
+ strlen (allfamilies
) + (p
- p1
), allcs
);
2067 /* Build the font spec that matches all. */
2068 len
= p
- p2
+ strlen (allcs
) + strlen (all
) + strlen (allfamilies
) + 1;
2069 font_all
= alloca (len
);
2070 z
= stpcpy (font_all
, allfamilies
);
2071 z
= stpcpy (z
, all
);
2072 memcpy (z
, p2
, p
- p2
);
2073 strcpy (z
+ (p
- p2
), allcs
);
2075 /* Build the actual font set name. */
2076 len
= strlen (base_fontname
) + strlen (font_allcs
)
2077 + strlen (font_allfamilies
) + strlen (font_all
) + 5;
2078 fontsetname
= xmalloc (len
);
2079 z
= stpcpy (fontsetname
, base_fontname
);
2080 z
= stpcpy (z
, sep
);
2081 z
= stpcpy (z
, font_allcs
);
2082 z
= stpcpy (z
, sep
);
2083 z
= stpcpy (z
, font_allfamilies
);
2084 z
= stpcpy (z
, sep
);
2085 z
= stpcpy (z
, font_all
);
2092 #endif /* HAVE_X_WINDOWS && USE_X_TOOLKIT */
2094 #ifdef DEBUG_XIC_FONTSET
2096 print_fontset_result (XFontSet xfs
, char *name
, char **missing_list
,
2100 fprintf (stderr
, "XIC Fontset created: %s\n", name
);
2103 fprintf (stderr
, "XIC Fontset failed: %s\n", name
);
2104 while (missing_count
-- > 0)
2106 fprintf (stderr
, " missing: %s\n", *missing_list
);
2115 xic_create_xfontset (struct frame
*f
)
2117 XFontSet xfs
= NULL
;
2118 struct font
*font
= FRAME_FONT (f
);
2119 int pixel_size
= font
->pixel_size
;
2120 Lisp_Object rest
, frame
;
2122 /* See if there is another frame already using same fontset. */
2123 FOR_EACH_FRAME (rest
, frame
)
2125 struct frame
*cf
= XFRAME (frame
);
2127 if (cf
!= f
&& FRAME_LIVE_P (f
) && FRAME_X_P (cf
)
2128 && FRAME_DISPLAY_INFO (cf
) == FRAME_DISPLAY_INFO (f
)
2130 && FRAME_FONT (f
)->pixel_size
== pixel_size
)
2132 xfs
= FRAME_XIC_FONTSET (cf
);
2140 char **missing_list
;
2143 const char *xlfd_format
= "-*-*-medium-r-normal--%d-*-*-*-*-*";
2145 sprintf (buf
, xlfd_format
, pixel_size
);
2146 missing_list
= NULL
;
2147 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
), buf
,
2148 &missing_list
, &missing_count
, &def_string
);
2149 #ifdef DEBUG_XIC_FONTSET
2150 print_fontset_result (xfs
, buf
, missing_list
, missing_count
);
2153 XFreeStringList (missing_list
);
2156 /* List of pixel sizes most likely available. Find one that
2157 is closest to pixel_size. */
2158 int sizes
[] = {0, 8, 10, 11, 12, 14, 17, 18, 20, 24, 26, 34, 0};
2159 int *smaller
, *larger
;
2161 for (smaller
= sizes
; smaller
[1]; smaller
++)
2162 if (smaller
[1] >= pixel_size
)
2164 larger
= smaller
+ 1;
2165 if (*larger
== pixel_size
)
2167 while (*smaller
|| *larger
)
2172 this_size
= *smaller
--;
2173 else if (! *smaller
)
2174 this_size
= *larger
++;
2175 else if (pixel_size
- *smaller
< *larger
- pixel_size
)
2176 this_size
= *smaller
--;
2178 this_size
= *larger
++;
2179 sprintf (buf
, xlfd_format
, this_size
);
2180 missing_list
= NULL
;
2181 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
), buf
,
2182 &missing_list
, &missing_count
, &def_string
);
2183 #ifdef DEBUG_XIC_FONTSET
2184 print_fontset_result (xfs
, buf
, missing_list
, missing_count
);
2187 XFreeStringList (missing_list
);
2194 const char *last_resort
= "-*-*-*-r-normal--*-*-*-*-*-*";
2196 missing_list
= NULL
;
2197 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
), last_resort
,
2198 &missing_list
, &missing_count
, &def_string
);
2199 #ifdef DEBUG_XIC_FONTSET
2200 print_fontset_result (xfs
, last_resort
, missing_list
, missing_count
);
2203 XFreeStringList (missing_list
);
2211 /* Free the X fontset of frame F if it is the last frame using it. */
2214 xic_free_xfontset (struct frame
*f
)
2216 Lisp_Object rest
, frame
;
2217 bool shared_p
= false;
2219 if (!FRAME_XIC_FONTSET (f
))
2222 /* See if there is another frame sharing the same fontset. */
2223 FOR_EACH_FRAME (rest
, frame
)
2225 struct frame
*cf
= XFRAME (frame
);
2226 if (cf
!= f
&& FRAME_LIVE_P (f
) && FRAME_X_P (cf
)
2227 && FRAME_DISPLAY_INFO (cf
) == FRAME_DISPLAY_INFO (f
)
2228 && FRAME_XIC_FONTSET (cf
) == FRAME_XIC_FONTSET (f
))
2236 /* The fontset is not used anymore. It is safe to free it. */
2237 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
2239 FRAME_XIC_FONTSET (f
) = NULL
;
2243 /* Value is the best input style, given user preferences USER (already
2244 checked to be supported by Emacs), and styles supported by the
2245 input method XIM. */
2248 best_xim_style (XIMStyles
*xim
)
2251 int nr_supported
= ARRAYELTS (supported_xim_styles
);
2253 for (i
= 0; i
< nr_supported
; ++i
)
2254 for (j
= 0; j
< xim
->count_styles
; ++j
)
2255 if (supported_xim_styles
[i
] == xim
->supported_styles
[j
])
2256 return supported_xim_styles
[i
];
2258 /* Return the default style. */
2259 return XIMPreeditNothing
| XIMStatusNothing
;
2262 /* Create XIC for frame F. */
2265 create_frame_xic (struct frame
*f
)
2269 XFontSet xfs
= NULL
;
2270 XVaNestedList status_attr
= NULL
;
2271 XVaNestedList preedit_attr
= NULL
;
2279 xim
= FRAME_X_XIM (f
);
2283 /* Determine XIC style. */
2284 xic_style
= best_xim_style (FRAME_X_XIM_STYLES (f
));
2286 /* Create X fontset. */
2287 if (xic_style
& (XIMPreeditPosition
| XIMStatusArea
))
2289 xfs
= xic_create_xfontset (f
);
2293 FRAME_XIC_FONTSET (f
) = xfs
;
2296 if (xic_style
& XIMPreeditPosition
)
2298 spot
.x
= 0; spot
.y
= 1;
2299 preedit_attr
= XVaCreateNestedList (0,
2302 FRAME_FOREGROUND_PIXEL (f
),
2304 FRAME_BACKGROUND_PIXEL (f
),
2305 (xic_style
& XIMPreeditPosition
2315 if (xic_style
& XIMStatusArea
)
2317 s_area
.x
= 0; s_area
.y
= 0; s_area
.width
= 1; s_area
.height
= 1;
2318 status_attr
= XVaCreateNestedList (0,
2324 FRAME_FOREGROUND_PIXEL (f
),
2326 FRAME_BACKGROUND_PIXEL (f
),
2333 if (preedit_attr
&& status_attr
)
2334 xic
= XCreateIC (xim
,
2335 XNInputStyle
, xic_style
,
2336 XNClientWindow
, FRAME_X_WINDOW (f
),
2337 XNFocusWindow
, FRAME_X_WINDOW (f
),
2338 XNStatusAttributes
, status_attr
,
2339 XNPreeditAttributes
, preedit_attr
,
2341 else if (preedit_attr
)
2342 xic
= XCreateIC (xim
,
2343 XNInputStyle
, xic_style
,
2344 XNClientWindow
, FRAME_X_WINDOW (f
),
2345 XNFocusWindow
, FRAME_X_WINDOW (f
),
2346 XNPreeditAttributes
, preedit_attr
,
2348 else if (status_attr
)
2349 xic
= XCreateIC (xim
,
2350 XNInputStyle
, xic_style
,
2351 XNClientWindow
, FRAME_X_WINDOW (f
),
2352 XNFocusWindow
, FRAME_X_WINDOW (f
),
2353 XNStatusAttributes
, status_attr
,
2356 xic
= XCreateIC (xim
,
2357 XNInputStyle
, xic_style
,
2358 XNClientWindow
, FRAME_X_WINDOW (f
),
2359 XNFocusWindow
, FRAME_X_WINDOW (f
),
2365 FRAME_XIC (f
) = xic
;
2366 FRAME_XIC_STYLE (f
) = xic_style
;
2367 xfs
= NULL
; /* Don't free below. */
2375 XFree (preedit_attr
);
2378 XFree (status_attr
);
2382 /* Destroy XIC and free XIC fontset of frame F, if any. */
2385 free_frame_xic (struct frame
*f
)
2387 if (FRAME_XIC (f
) == NULL
)
2390 XDestroyIC (FRAME_XIC (f
));
2391 xic_free_xfontset (f
);
2393 FRAME_XIC (f
) = NULL
;
2397 /* Place preedit area for XIC of window W's frame to specified
2398 pixel position X/Y. X and Y are relative to window W. */
2401 xic_set_preeditarea (struct window
*w
, int x
, int y
)
2403 struct frame
*f
= XFRAME (w
->frame
);
2407 spot
.x
= WINDOW_TO_FRAME_PIXEL_X (w
, x
) + WINDOW_LEFT_FRINGE_WIDTH (w
);
2408 spot
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, y
) + FONT_BASE (FRAME_FONT (f
));
2409 attr
= XVaCreateNestedList (0, XNSpotLocation
, &spot
, NULL
);
2410 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2415 /* Place status area for XIC in bottom right corner of frame F.. */
2418 xic_set_statusarea (struct frame
*f
)
2420 XIC xic
= FRAME_XIC (f
);
2425 /* Negotiate geometry of status area. If input method has existing
2426 status area, use its current size. */
2427 area
.x
= area
.y
= area
.width
= area
.height
= 0;
2428 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &area
, NULL
);
2429 XSetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2432 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &needed
, NULL
);
2433 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2436 if (needed
->width
== 0) /* Use XNArea instead of XNAreaNeeded */
2438 attr
= XVaCreateNestedList (0, XNArea
, &needed
, NULL
);
2439 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2443 area
.width
= needed
->width
;
2444 area
.height
= needed
->height
;
2445 area
.x
= FRAME_PIXEL_WIDTH (f
) - area
.width
- FRAME_INTERNAL_BORDER_WIDTH (f
);
2446 area
.y
= (FRAME_PIXEL_HEIGHT (f
) - area
.height
2447 - FRAME_MENUBAR_HEIGHT (f
)
2448 - FRAME_TOOLBAR_TOP_HEIGHT (f
)
2449 - FRAME_INTERNAL_BORDER_WIDTH (f
));
2452 attr
= XVaCreateNestedList (0, XNArea
, &area
, NULL
);
2453 XSetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2458 /* Set X fontset for XIC of frame F, using base font name
2459 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2462 xic_set_xfontset (struct frame
*f
, const char *base_fontname
)
2467 xic_free_xfontset (f
);
2469 xfs
= xic_create_xfontset (f
);
2471 attr
= XVaCreateNestedList (0, XNFontSet
, xfs
, NULL
);
2472 if (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
)
2473 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2474 if (FRAME_XIC_STYLE (f
) & XIMStatusArea
)
2475 XSetICValues (FRAME_XIC (f
), XNStatusAttributes
, attr
, NULL
);
2478 FRAME_XIC_FONTSET (f
) = xfs
;
2481 #endif /* HAVE_X_I18N */
2485 #ifdef USE_X_TOOLKIT
2487 /* Create and set up the X widget for frame F. */
2490 x_window (struct frame
*f
, long window_prompting
)
2492 XClassHint class_hints
;
2493 XSetWindowAttributes attributes
;
2494 unsigned long attribute_mask
;
2495 Widget shell_widget
;
2497 Widget frame_widget
;
2503 /* Use the resource name as the top-level widget name
2504 for looking up resources. Make a non-Lisp copy
2505 for the window manager, so GC relocation won't bother it.
2507 Elsewhere we specify the window name for the window manager. */
2508 f
->namebuf
= xlispstrdup (Vx_resource_name
);
2511 XtSetArg (al
[ac
], XtNallowShellResize
, 1); ac
++;
2512 XtSetArg (al
[ac
], XtNinput
, 1); ac
++;
2513 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2514 XtSetArg (al
[ac
], XtNborderWidth
, f
->border_width
); ac
++;
2515 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2516 XtSetArg (al
[ac
], XtNdepth
, FRAME_DISPLAY_INFO (f
)->n_planes
); ac
++;
2517 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2518 shell_widget
= XtAppCreateShell (f
->namebuf
, EMACS_CLASS
,
2519 applicationShellWidgetClass
,
2520 FRAME_X_DISPLAY (f
), al
, ac
);
2522 f
->output_data
.x
->widget
= shell_widget
;
2523 /* maybe_set_screen_title_format (shell_widget); */
2525 pane_widget
= lw_create_widget ("main", "pane", widget_id_tick
++,
2526 NULL
, shell_widget
, False
,
2527 NULL
, NULL
, NULL
, NULL
);
2530 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2531 XtSetArg (al
[ac
], XtNdepth
, FRAME_DISPLAY_INFO (f
)->n_planes
); ac
++;
2532 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2533 XtSetArg (al
[ac
], XtNborderWidth
, 0); ac
++;
2534 XtSetValues (pane_widget
, al
, ac
);
2535 f
->output_data
.x
->column_widget
= pane_widget
;
2537 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2538 the emacs screen when changing menubar. This reduces flickering. */
2541 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2542 XtSetArg (al
[ac
], XtNshowGrip
, 0); ac
++;
2543 XtSetArg (al
[ac
], XtNallowResize
, 1); ac
++;
2544 XtSetArg (al
[ac
], XtNresizeToPreferred
, 1); ac
++;
2545 XtSetArg (al
[ac
], XtNemacsFrame
, f
); ac
++;
2546 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2547 XtSetArg (al
[ac
], XtNdepth
, FRAME_DISPLAY_INFO (f
)->n_planes
); ac
++;
2548 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2549 XtSetArg (al
[ac
], XtNborderWidth
, 0); ac
++;
2550 frame_widget
= XtCreateWidget (f
->namebuf
, emacsFrameClass
, pane_widget
,
2553 f
->output_data
.x
->edit_widget
= frame_widget
;
2555 XtManageChild (frame_widget
);
2557 /* Do some needed geometry management. */
2561 int extra_borders
= 0;
2563 = (f
->output_data
.x
->menubar_widget
2564 ? (f
->output_data
.x
->menubar_widget
->core
.height
2565 + f
->output_data
.x
->menubar_widget
->core
.border_width
)
2568 #if false /* Experimentally, we now get the right results
2569 for -geometry -0-0 without this. 24 Aug 96, rms. */
2570 if (FRAME_EXTERNAL_MENU_BAR (f
))
2573 XtVaGetValues (pane_widget
, XtNinternalBorderWidth
, &ibw
, NULL
);
2574 menubar_size
+= ibw
;
2578 FRAME_MENUBAR_HEIGHT (f
) = menubar_size
;
2581 /* Motif seems to need this amount added to the sizes
2582 specified for the shell widget. The Athena/Lucid widgets don't.
2583 Both conclusions reached experimentally. -- rms. */
2584 XtVaGetValues (f
->output_data
.x
->edit_widget
, XtNinternalBorderWidth
,
2585 &extra_borders
, NULL
);
2589 f
->shell_position
= xmalloc (sizeof "=x++" + 4 * INT_STRLEN_BOUND (int));
2591 /* Convert our geometry parameters into a geometry string
2593 Note that we do not specify here whether the position
2594 is a user-specified or program-specified one.
2595 We pass that information later, in x_wm_set_size_hints. */
2597 int left
= f
->left_pos
;
2598 bool xneg
= (window_prompting
& XNegative
) != 0;
2599 int top
= f
->top_pos
;
2600 bool yneg
= (window_prompting
& YNegative
) != 0;
2606 if (window_prompting
& USPosition
)
2607 sprintf (f
->shell_position
, "=%dx%d%c%d%c%d",
2608 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2609 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
,
2610 (xneg
? '-' : '+'), left
,
2611 (yneg
? '-' : '+'), top
);
2614 sprintf (f
->shell_position
, "=%dx%d",
2615 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2616 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
);
2618 /* Setting x and y when the position is not specified in
2619 the geometry string will set program position in the WM hints.
2620 If Emacs had just one program position, we could set it in
2621 fallback resources, but since each make-frame call can specify
2622 different program positions, this is easier. */
2623 XtSetArg (gal
[gac
], XtNx
, left
); gac
++;
2624 XtSetArg (gal
[gac
], XtNy
, top
); gac
++;
2628 XtSetArg (gal
[gac
], XtNgeometry
, f
->shell_position
); gac
++;
2629 XtSetValues (shell_widget
, gal
, gac
);
2632 XtManageChild (pane_widget
);
2633 XtRealizeWidget (shell_widget
);
2635 if (FRAME_X_EMBEDDED_P (f
))
2636 XReparentWindow (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
),
2637 f
->output_data
.x
->parent_desc
, 0, 0);
2639 FRAME_X_WINDOW (f
) = XtWindow (frame_widget
);
2641 validate_x_resource_name ();
2643 class_hints
.res_name
= SSDATA (Vx_resource_name
);
2644 class_hints
.res_class
= SSDATA (Vx_resource_class
);
2645 XSetClassHint (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
), &class_hints
);
2648 FRAME_XIC (f
) = NULL
;
2650 create_frame_xic (f
);
2653 f
->output_data
.x
->wm_hints
.input
= True
;
2654 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2655 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2656 &f
->output_data
.x
->wm_hints
);
2658 hack_wm_protocols (f
, shell_widget
);
2660 #ifdef X_TOOLKIT_EDITRES
2661 XtAddEventHandler (shell_widget
, 0, True
, _XEditResCheckMessages
, 0);
2664 /* Do a stupid property change to force the server to generate a
2665 PropertyNotify event so that the event_stream server timestamp will
2666 be initialized to something relevant to the time we created the window.
2668 XChangeProperty (XtDisplay (frame_widget
), XtWindow (frame_widget
),
2669 FRAME_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2670 XA_ATOM
, 32, PropModeAppend
, NULL
, 0);
2672 /* Make all the standard events reach the Emacs frame. */
2673 attributes
.event_mask
= STANDARD_EVENT_SET
;
2678 /* XIM server might require some X events. */
2679 unsigned long fevent
= NoEventMask
;
2680 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2681 attributes
.event_mask
|= fevent
;
2683 #endif /* HAVE_X_I18N */
2685 attribute_mask
= CWEventMask
;
2686 XChangeWindowAttributes (XtDisplay (shell_widget
), XtWindow (shell_widget
),
2687 attribute_mask
, &attributes
);
2689 XtMapWidget (frame_widget
);
2691 /* x_set_name normally ignores requests to set the name if the
2692 requested name is the same as the current name. This is the one
2693 place where that assumption isn't correct; f->name is set, but
2694 the X server hasn't been told. */
2697 bool explicit = f
->explicit_name
;
2699 f
->explicit_name
= false;
2701 fset_name (f
, Qnil
);
2702 x_set_name (f
, name
, explicit);
2705 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2706 f
->output_data
.x
->current_cursor
2707 = f
->output_data
.x
->text_cursor
);
2711 /* This is a no-op, except under Motif. Make sure main areas are
2712 set to something reasonable, in case we get an error later. */
2713 lw_set_main_areas (pane_widget
, 0, frame_widget
);
2716 #else /* not USE_X_TOOLKIT */
2719 x_window (struct frame
*f
)
2721 if (! xg_create_frame_widgets (f
))
2722 error ("Unable to create window");
2725 FRAME_XIC (f
) = NULL
;
2729 create_frame_xic (f
);
2732 /* XIM server might require some X events. */
2733 unsigned long fevent
= NoEventMask
;
2734 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2736 if (fevent
!= NoEventMask
)
2738 XSetWindowAttributes attributes
;
2739 XWindowAttributes wattr
;
2740 unsigned long attribute_mask
;
2742 XGetWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2744 attributes
.event_mask
= wattr
.your_event_mask
| fevent
;
2745 attribute_mask
= CWEventMask
;
2746 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2747 attribute_mask
, &attributes
);
2755 #else /*! USE_GTK */
2756 /* Create and set up the X window for frame F. */
2759 x_window (struct frame
*f
)
2761 XClassHint class_hints
;
2762 XSetWindowAttributes attributes
;
2763 unsigned long attribute_mask
;
2765 attributes
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
2766 attributes
.border_pixel
= f
->output_data
.x
->border_pixel
;
2767 attributes
.bit_gravity
= StaticGravity
;
2768 attributes
.backing_store
= NotUseful
;
2769 attributes
.save_under
= True
;
2770 attributes
.event_mask
= STANDARD_EVENT_SET
;
2771 attributes
.colormap
= FRAME_X_COLORMAP (f
);
2772 attribute_mask
= (CWBackPixel
| CWBorderPixel
| CWBitGravity
| CWEventMask
2777 = XCreateWindow (FRAME_X_DISPLAY (f
),
2778 f
->output_data
.x
->parent_desc
,
2781 FRAME_PIXEL_WIDTH (f
), FRAME_PIXEL_HEIGHT (f
),
2783 CopyFromParent
, /* depth */
2784 InputOutput
, /* class */
2786 attribute_mask
, &attributes
);
2791 create_frame_xic (f
);
2794 /* XIM server might require some X events. */
2795 unsigned long fevent
= NoEventMask
;
2796 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2797 attributes
.event_mask
|= fevent
;
2798 attribute_mask
= CWEventMask
;
2799 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2800 attribute_mask
, &attributes
);
2803 #endif /* HAVE_X_I18N */
2805 validate_x_resource_name ();
2807 class_hints
.res_name
= SSDATA (Vx_resource_name
);
2808 class_hints
.res_class
= SSDATA (Vx_resource_class
);
2809 XSetClassHint (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &class_hints
);
2811 /* This indicates that we use the "Passive Input" input model.
2812 Unless we do this, we don't get the Focus{In,Out} events that we
2813 need to draw the cursor correctly. Accursed bureaucrats.
2814 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2816 f
->output_data
.x
->wm_hints
.input
= True
;
2817 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2818 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2819 &f
->output_data
.x
->wm_hints
);
2820 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
2822 /* Request "save yourself" and "delete window" commands from wm. */
2825 protocols
[0] = FRAME_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2826 protocols
[1] = FRAME_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2827 XSetWMProtocols (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), protocols
, 2);
2830 /* x_set_name normally ignores requests to set the name if the
2831 requested name is the same as the current name. This is the one
2832 place where that assumption isn't correct; f->name is set, but
2833 the X server hasn't been told. */
2836 bool explicit = f
->explicit_name
;
2838 f
->explicit_name
= false;
2840 fset_name (f
, Qnil
);
2841 x_set_name (f
, name
, explicit);
2844 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2845 f
->output_data
.x
->current_cursor
2846 = f
->output_data
.x
->text_cursor
);
2850 if (FRAME_X_WINDOW (f
) == 0)
2851 error ("Unable to create window");
2854 #endif /* not USE_GTK */
2855 #endif /* not USE_X_TOOLKIT */
2857 /* Verify that the icon position args for this window are valid. */
2860 x_icon_verify (struct frame
*f
, Lisp_Object parms
)
2862 Lisp_Object icon_x
, icon_y
;
2864 /* Set the position of the icon. Note that twm groups all
2865 icons in an icon window. */
2866 icon_x
= x_frame_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
2867 icon_y
= x_frame_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
2868 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2870 CHECK_NUMBER (icon_x
);
2871 CHECK_NUMBER (icon_y
);
2873 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2874 error ("Both left and top icon corners of icon must be specified");
2877 /* Handle the icon stuff for this window. Perhaps later we might
2878 want an x_set_icon_position which can be called interactively as
2882 x_icon (struct frame
*f
, Lisp_Object parms
)
2884 /* Set the position of the icon. Note that twm groups all
2885 icons in an icon window. */
2887 = x_frame_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
2889 = x_frame_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
2890 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2892 CHECK_TYPE_RANGED_INTEGER (int, icon_x
);
2893 CHECK_TYPE_RANGED_INTEGER (int, icon_y
);
2895 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2896 error ("Both left and top icon corners of icon must be specified");
2900 if (! EQ (icon_x
, Qunbound
))
2901 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
2903 #if false /* x_get_arg removes the visibility parameter as a side effect,
2904 but x_create_frame still needs it. */
2905 /* Start up iconic or window? */
2906 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
2907 x_wm_set_window_state
2908 (f
, (EQ (x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
),
2914 x_text_icon (f
, SSDATA ((!NILP (f
->icon_name
)
2921 /* Make the GCs needed for this window, setting the
2922 background, border and mouse colors; also create the
2923 mouse cursor and the gray border tile. */
2926 x_make_gc (struct frame
*f
)
2928 XGCValues gc_values
;
2932 /* Create the GCs of this frame.
2933 Note that many default values are used. */
2935 gc_values
.foreground
= FRAME_FOREGROUND_PIXEL (f
);
2936 gc_values
.background
= FRAME_BACKGROUND_PIXEL (f
);
2937 gc_values
.line_width
= 0; /* Means 1 using fast algorithm. */
2938 f
->output_data
.x
->normal_gc
2939 = XCreateGC (FRAME_X_DISPLAY (f
),
2941 GCLineWidth
| GCForeground
| GCBackground
,
2944 /* Reverse video style. */
2945 gc_values
.foreground
= FRAME_BACKGROUND_PIXEL (f
);
2946 gc_values
.background
= FRAME_FOREGROUND_PIXEL (f
);
2947 f
->output_data
.x
->reverse_gc
2948 = XCreateGC (FRAME_X_DISPLAY (f
),
2950 GCForeground
| GCBackground
| GCLineWidth
,
2953 /* Cursor has cursor-color background, background-color foreground. */
2954 gc_values
.foreground
= FRAME_BACKGROUND_PIXEL (f
);
2955 gc_values
.background
= f
->output_data
.x
->cursor_pixel
;
2956 gc_values
.fill_style
= FillOpaqueStippled
;
2957 f
->output_data
.x
->cursor_gc
2958 = XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2959 (GCForeground
| GCBackground
2960 | GCFillStyle
| GCLineWidth
),
2963 /* Create the gray border tile used when the pointer is not in
2964 the frame. Since this depends on the frame's pixel values,
2965 this must be done on a per-frame basis. */
2966 f
->output_data
.x
->border_tile
2967 = (XCreatePixmapFromBitmapData
2968 (FRAME_X_DISPLAY (f
), FRAME_DISPLAY_INFO (f
)->root_window
,
2969 gray_bits
, gray_width
, gray_height
,
2970 FRAME_FOREGROUND_PIXEL (f
),
2971 FRAME_BACKGROUND_PIXEL (f
),
2972 DefaultDepth (FRAME_X_DISPLAY (f
), FRAME_X_SCREEN_NUMBER (f
))));
2978 /* Free what was allocated in x_make_gc. */
2981 x_free_gcs (struct frame
*f
)
2983 Display
*dpy
= FRAME_X_DISPLAY (f
);
2987 if (f
->output_data
.x
->normal_gc
)
2989 XFreeGC (dpy
, f
->output_data
.x
->normal_gc
);
2990 f
->output_data
.x
->normal_gc
= 0;
2993 if (f
->output_data
.x
->reverse_gc
)
2995 XFreeGC (dpy
, f
->output_data
.x
->reverse_gc
);
2996 f
->output_data
.x
->reverse_gc
= 0;
2999 if (f
->output_data
.x
->cursor_gc
)
3001 XFreeGC (dpy
, f
->output_data
.x
->cursor_gc
);
3002 f
->output_data
.x
->cursor_gc
= 0;
3005 if (f
->output_data
.x
->border_tile
)
3007 XFreePixmap (dpy
, f
->output_data
.x
->border_tile
);
3008 f
->output_data
.x
->border_tile
= 0;
3015 /* Handler for signals raised during x_create_frame and
3016 x_create_tip_frame. FRAME is the frame which is partially
3020 unwind_create_frame (Lisp_Object frame
)
3022 struct frame
*f
= XFRAME (frame
);
3024 /* If frame is already dead, nothing to do. This can happen if the
3025 display is disconnected after the frame has become official, but
3026 before x_create_frame removes the unwind protect. */
3027 if (!FRAME_LIVE_P (f
))
3030 /* If frame is ``official'', nothing to do. */
3031 if (NILP (Fmemq (frame
, Vframe_list
)))
3033 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
3034 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
3037 /* If the frame's image cache refcount is still the same as our
3038 private shadow variable, it means we are unwinding a frame
3039 for which we didn't yet call init_frame_faces, where the
3040 refcount is incremented. Therefore, we increment it here, so
3041 that free_frame_faces, called in x_free_frame_resources
3042 below, will not mistakenly decrement the counter that was not
3043 incremented yet to account for this new frame. */
3044 if (FRAME_IMAGE_CACHE (f
) != NULL
3045 && FRAME_IMAGE_CACHE (f
)->refcount
== image_cache_refcount
)
3046 FRAME_IMAGE_CACHE (f
)->refcount
++;
3048 x_free_frame_resources (f
);
3051 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
3052 /* Check that reference counts are indeed correct. */
3053 eassert (dpyinfo
->reference_count
== dpyinfo_refcount
);
3054 eassert (dpyinfo
->terminal
->image_cache
->refcount
== image_cache_refcount
);
3063 do_unwind_create_frame (Lisp_Object frame
)
3065 unwind_create_frame (frame
);
3069 x_default_font_parameter (struct frame
*f
, Lisp_Object parms
)
3071 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
3072 Lisp_Object font_param
= x_get_arg (dpyinfo
, parms
, Qfont
, NULL
, NULL
,
3074 Lisp_Object font
= Qnil
;
3075 if (EQ (font_param
, Qunbound
))
3078 if (NILP (font_param
))
3080 /* System font should take precedence over X resources. We suggest this
3081 regardless of font-use-system-font because .emacs may not have been
3083 const char *system_font
= xsettings_get_system_font ();
3085 font
= font_open_by_name (f
, build_unibyte_string (system_font
));
3089 font
= !NILP (font_param
) ? font_param
3090 : x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
3092 if (! FONTP (font
) && ! STRINGP (font
))
3097 /* This will find the normal Xft font. */
3100 "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
3101 "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3102 "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
3103 /* This was formerly the first thing tried, but it finds
3104 too many fonts and takes too long. */
3105 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
3106 /* If those didn't work, look for something which will
3108 "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
3113 for (i
= 0; names
[i
]; i
++)
3115 font
= font_open_by_name (f
, build_unibyte_string (names
[i
]));
3120 error ("No suitable font was found");
3122 else if (!NILP (font_param
))
3124 /* Remember the explicit font parameter, so we can re-apply it after
3125 we've applied the `default' face settings. */
3126 AUTO_FRAME_ARG (arg
, Qfont_parameter
, font_param
);
3127 x_set_frame_parameters (f
, arg
);
3130 /* This call will make X resources override any system font setting. */
3131 x_default_parameter (f
, parms
, Qfont
, font
, "font", "Font", RES_TYPE_STRING
);
3135 DEFUN ("x-wm-set-size-hint", Fx_wm_set_size_hint
, Sx_wm_set_size_hint
,
3137 doc
: /* Send the size hints for frame FRAME to the window manager.
3138 If FRAME is omitted or nil, use the selected frame.
3139 Signal error if FRAME is not an X frame. */)
3142 struct frame
*f
= decode_window_system_frame (frame
);
3145 x_wm_set_size_hint (f
, 0, false);
3151 set_machine_and_pid_properties (struct frame
*f
)
3153 /* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME. */
3154 XSetWMProperties (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), NULL
, NULL
,
3155 NULL
, 0, NULL
, NULL
, NULL
);
3156 pid_t pid
= getpid ();
3157 if (pid
<= 0xffffffffu
)
3159 unsigned long xpid
= pid
;
3160 XChangeProperty (FRAME_X_DISPLAY (f
),
3161 FRAME_OUTER_WINDOW (f
),
3162 XInternAtom (FRAME_X_DISPLAY (f
),
3165 XA_CARDINAL
, 32, PropModeReplace
,
3166 (unsigned char *) &xpid
, 1);
3170 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
3172 doc
: /* Make a new X window, which is called a "frame" in Emacs terms.
3173 Return an Emacs frame object. PARMS is an alist of frame parameters.
3174 If the parameters specify that the frame should not have a minibuffer,
3175 and do not specify a specific minibuffer window to use, then
3176 `default-minibuffer-frame' must be a frame whose minibuffer can be
3177 shared by the new frame.
3179 This function is an internal primitive--use `make-frame' instead. */)
3183 Lisp_Object frame
, tem
;
3185 bool minibuffer_only
= false;
3186 long window_prompting
= 0;
3187 ptrdiff_t count
= SPECPDL_INDEX ();
3188 Lisp_Object display
;
3189 struct x_display_info
*dpyinfo
= NULL
;
3192 int x_width
= 0, x_height
= 0;
3194 parms
= Fcopy_alist (parms
);
3196 /* Use this general default value to start with
3197 until we know if this frame has a specified name. */
3198 Vx_resource_name
= Vinvocation_name
;
3200 display
= x_get_arg (dpyinfo
, parms
, Qterminal
, 0, 0, RES_TYPE_NUMBER
);
3201 if (EQ (display
, Qunbound
))
3202 display
= x_get_arg (dpyinfo
, parms
, Qdisplay
, 0, 0, RES_TYPE_STRING
);
3203 if (EQ (display
, Qunbound
))
3205 dpyinfo
= check_x_display_info (display
);
3206 kb
= dpyinfo
->terminal
->kboard
;
3208 if (!dpyinfo
->terminal
->name
)
3209 error ("Terminal is not live, can't create new frames on it");
3211 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
3213 && ! EQ (name
, Qunbound
)
3215 error ("Invalid frame name--not a string or nil");
3218 Vx_resource_name
= name
;
3220 /* See if parent window is specified. */
3221 parent
= x_get_arg (dpyinfo
, parms
, Qparent_id
, NULL
, NULL
, RES_TYPE_NUMBER
);
3222 if (EQ (parent
, Qunbound
))
3224 if (! NILP (parent
))
3225 CHECK_NUMBER (parent
);
3228 tem
= x_get_arg (dpyinfo
, parms
, Qminibuffer
, "minibuffer", "Minibuffer",
3230 if (EQ (tem
, Qnone
) || NILP (tem
))
3231 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
3232 else if (EQ (tem
, Qonly
))
3234 f
= make_minibuffer_frame ();
3235 minibuffer_only
= true;
3237 else if (WINDOWP (tem
))
3238 f
= make_frame_without_minibuffer (tem
, kb
, display
);
3240 f
= make_frame (true);
3242 XSETFRAME (frame
, f
);
3244 f
->terminal
= dpyinfo
->terminal
;
3246 f
->output_method
= output_x_window
;
3247 f
->output_data
.x
= xzalloc (sizeof *f
->output_data
.x
);
3248 f
->output_data
.x
->icon_bitmap
= -1;
3249 FRAME_FONTSET (f
) = -1;
3250 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
3251 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
3252 #if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
3253 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
3254 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
3255 #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
3256 f
->output_data
.x
->white_relief
.pixel
= -1;
3257 f
->output_data
.x
->black_relief
.pixel
= -1;
3260 x_get_arg (dpyinfo
, parms
, Qicon_name
, "iconName", "Title",
3262 if (! STRINGP (f
->icon_name
))
3263 fset_icon_name (f
, Qnil
);
3265 FRAME_DISPLAY_INFO (f
) = dpyinfo
;
3267 /* With FRAME_DISPLAY_INFO set up, this unwind-protect is safe. */
3268 record_unwind_protect (do_unwind_create_frame
, frame
);
3270 /* These colors will be set anyway later, but it's important
3271 to get the color reference counts right, so initialize them! */
3275 /* Function x_decode_color can signal an error. Make
3276 sure to initialize color slots so that we won't try
3277 to free colors we haven't allocated. */
3278 FRAME_FOREGROUND_PIXEL (f
) = -1;
3279 FRAME_BACKGROUND_PIXEL (f
) = -1;
3280 f
->output_data
.x
->cursor_pixel
= -1;
3281 f
->output_data
.x
->cursor_foreground_pixel
= -1;
3282 f
->output_data
.x
->border_pixel
= -1;
3283 f
->output_data
.x
->mouse_pixel
= -1;
3285 black
= build_string ("black");
3286 FRAME_FOREGROUND_PIXEL (f
)
3287 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3288 FRAME_BACKGROUND_PIXEL (f
)
3289 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3290 f
->output_data
.x
->cursor_pixel
3291 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3292 f
->output_data
.x
->cursor_foreground_pixel
3293 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3294 f
->output_data
.x
->border_pixel
3295 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3296 f
->output_data
.x
->mouse_pixel
3297 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3300 /* Specify the parent under which to make this X window. */
3303 f
->output_data
.x
->parent_desc
= (Window
) XFASTINT (parent
);
3304 f
->output_data
.x
->explicit_parent
= true;
3308 f
->output_data
.x
->parent_desc
= FRAME_DISPLAY_INFO (f
)->root_window
;
3309 f
->output_data
.x
->explicit_parent
= false;
3312 /* Set the name; the functions to which we pass f expect the name to
3314 if (EQ (name
, Qunbound
) || NILP (name
))
3316 fset_name (f
, build_string (dpyinfo
->x_id_name
));
3317 f
->explicit_name
= false;
3321 fset_name (f
, name
);
3322 f
->explicit_name
= true;
3323 /* Use the frame's title when getting resources for this frame. */
3324 specbind (Qx_resource_name
, name
);
3328 register_font_driver (&ftcrfont_driver
, f
);
3330 #ifdef HAVE_FREETYPE
3332 register_font_driver (&xftfont_driver
, f
);
3333 #else /* not HAVE_XFT */
3334 register_font_driver (&ftxfont_driver
, f
);
3335 #endif /* not HAVE_XFT */
3336 #endif /* HAVE_FREETYPE */
3337 register_font_driver (&xfont_driver
, f
);
3338 #endif /* not USE_CAIRO */
3340 image_cache_refcount
=
3341 FRAME_IMAGE_CACHE (f
) ? FRAME_IMAGE_CACHE (f
)->refcount
: 0;
3343 dpyinfo_refcount
= dpyinfo
->reference_count
;
3344 #endif /* GLYPH_DEBUG */
3346 x_default_parameter (f
, parms
, Qfont_backend
, Qnil
,
3347 "fontBackend", "FontBackend", RES_TYPE_STRING
);
3349 /* Extract the window parameters from the supplied values
3350 that are needed to determine window geometry. */
3351 x_default_font_parameter (f
, parms
);
3352 if (!FRAME_FONT (f
))
3354 delete_frame (frame
, Qnoelisp
);
3355 error ("Invalid frame font");
3358 /* Frame contents get displaced if an embedded X window has a border. */
3359 if (! FRAME_X_EMBEDDED_P (f
))
3360 x_default_parameter (f
, parms
, Qborder_width
, make_number (0),
3361 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
3363 /* This defaults to 1 in order to match xterm. We recognize either
3364 internalBorderWidth or internalBorder (which is what xterm calls
3366 if (NILP (Fassq (Qinternal_border_width
, parms
)))
3370 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
3371 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
3372 if (! EQ (value
, Qunbound
))
3373 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
3376 x_default_parameter (f
, parms
, Qinternal_border_width
,
3377 #ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */
3382 "internalBorderWidth", "internalBorderWidth",
3384 x_default_parameter (f
, parms
, Qright_divider_width
, make_number (0),
3385 NULL
, NULL
, RES_TYPE_NUMBER
);
3386 x_default_parameter (f
, parms
, Qbottom_divider_width
, make_number (0),
3387 NULL
, NULL
, RES_TYPE_NUMBER
);
3388 x_default_parameter (f
, parms
, Qvertical_scroll_bars
,
3389 #if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
3394 "verticalScrollBars", "ScrollBars",
3396 x_default_parameter (f
, parms
, Qhorizontal_scroll_bars
, Qnil
,
3397 "horizontalScrollBars", "ScrollBars",
3399 /* Also do the stuff which must be set before the window exists. */
3400 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
3401 "foreground", "Foreground", RES_TYPE_STRING
);
3402 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
3403 "background", "Background", RES_TYPE_STRING
);
3404 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
3405 "pointerColor", "Foreground", RES_TYPE_STRING
);
3406 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
3407 "borderColor", "BorderColor", RES_TYPE_STRING
);
3408 x_default_parameter (f
, parms
, Qscreen_gamma
, Qnil
,
3409 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT
);
3410 x_default_parameter (f
, parms
, Qline_spacing
, Qnil
,
3411 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER
);
3412 x_default_parameter (f
, parms
, Qleft_fringe
, Qnil
,
3413 "leftFringe", "LeftFringe", RES_TYPE_NUMBER
);
3414 x_default_parameter (f
, parms
, Qright_fringe
, Qnil
,
3415 "rightFringe", "RightFringe", RES_TYPE_NUMBER
);
3417 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_foreground
,
3418 "scrollBarForeground",
3419 "ScrollBarForeground", true);
3420 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_background
,
3421 "scrollBarBackground",
3422 "ScrollBarBackground", false);
3424 /* Init faces before x_default_parameter is called for the
3425 scroll-bar-width parameter because otherwise we end up in
3426 init_iterator with a null face cache, which should not happen. */
3427 init_frame_faces (f
);
3429 /* The following call of change_frame_size is needed since otherwise
3430 x_set_tool_bar_lines will already work with the character sizes
3431 installed by init_frame_faces while the frame's pixel size is
3432 still calculated from a character size of 1 and we subsequently
3433 hit the (height >= 0) assertion in window_box_height.
3435 The non-pixelwise code apparently worked around this because it
3436 had one frame line vs one toolbar line which left us with a zero
3437 root window height which was obviously wrong as well ... */
3438 adjust_frame_size (f
, FRAME_COLS (f
) * FRAME_COLUMN_WIDTH (f
),
3439 FRAME_LINES (f
) * FRAME_LINE_HEIGHT (f
), 5, true,
3442 /* Set the menu-bar-lines and tool-bar-lines parameters. We don't
3443 look up the X resources controlling the menu-bar and tool-bar
3444 here; they are processed specially at startup, and reflected in
3445 the values of the mode variables. */
3447 x_default_parameter (f
, parms
, Qmenu_bar_lines
,
3448 NILP (Vmenu_bar_mode
)
3449 ? make_number (0) : make_number (1),
3450 NULL
, NULL
, RES_TYPE_NUMBER
);
3451 x_default_parameter (f
, parms
, Qtool_bar_lines
,
3452 NILP (Vtool_bar_mode
)
3453 ? make_number (0) : make_number (1),
3454 NULL
, NULL
, RES_TYPE_NUMBER
);
3456 x_default_parameter (f
, parms
, Qbuffer_predicate
, Qnil
,
3457 "bufferPredicate", "BufferPredicate",
3459 x_default_parameter (f
, parms
, Qtitle
, Qnil
,
3460 "title", "Title", RES_TYPE_STRING
);
3461 x_default_parameter (f
, parms
, Qwait_for_wm
, Qt
,
3462 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN
);
3463 x_default_parameter (f
, parms
, Qtool_bar_position
,
3464 FRAME_TOOL_BAR_POSITION (f
), 0, 0, RES_TYPE_SYMBOL
);
3466 /* Compute the size of the X window. */
3467 window_prompting
= x_figure_window_size (f
, parms
, true, &x_width
, &x_height
);
3469 tem
= x_get_arg (dpyinfo
, parms
, Qunsplittable
, 0, 0, RES_TYPE_BOOLEAN
);
3470 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
3472 x_icon_verify (f
, parms
);
3474 /* Create the X widget or window. */
3475 #ifdef USE_X_TOOLKIT
3476 x_window (f
, window_prompting
);
3484 /* Now consider the frame official. */
3485 f
->terminal
->reference_count
++;
3486 FRAME_DISPLAY_INFO (f
)->reference_count
++;
3487 Vframe_list
= Fcons (frame
, Vframe_list
);
3489 /* We need to do this after creating the X window, so that the
3490 icon-creation functions can say whose icon they're describing. */
3491 x_default_parameter (f
, parms
, Qicon_type
, Qt
,
3492 "bitmapIcon", "BitmapIcon", RES_TYPE_BOOLEAN
);
3494 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
3495 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3496 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
3497 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3498 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
3499 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
3500 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
3501 "scrollBarWidth", "ScrollBarWidth",
3503 x_default_parameter (f
, parms
, Qscroll_bar_height
, Qnil
,
3504 "scrollBarHeight", "ScrollBarHeight",
3506 x_default_parameter (f
, parms
, Qalpha
, Qnil
,
3507 "alpha", "Alpha", RES_TYPE_NUMBER
);
3509 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3510 /* Create the menu bar. */
3511 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
3513 /* If this signals an error, we haven't set size hints for the
3514 frame and we didn't make it visible. */
3515 initialize_frame_menubar (f
);
3518 /* This is a no-op, except under Motif where it arranges the
3519 main window for the widgets on it. */
3520 lw_set_main_areas (f
->output_data
.x
->column_widget
,
3521 f
->output_data
.x
->menubar_widget
,
3522 f
->output_data
.x
->edit_widget
);
3523 #endif /* not USE_GTK */
3525 #endif /* USE_X_TOOLKIT || USE_GTK */
3527 /* Consider frame official, now. */
3528 f
->can_x_set_window_size
= true;
3531 SET_FRAME_WIDTH (f
, x_width
);
3533 SET_FRAME_HEIGHT (f
, x_height
);
3535 /* Tell the server what size and position, etc, we want, and how
3536 badly we want them. This should be done after we have the menu
3537 bar so that its size can be taken into account. */
3539 x_wm_set_size_hint (f
, window_prompting
, false);
3542 adjust_frame_size (f
, FRAME_TEXT_WIDTH (f
), FRAME_TEXT_HEIGHT (f
),
3543 0, true, Qx_create_frame_2
);
3545 /* Process fullscreen parameter here in the hope that normalizing a
3546 fullheight/fullwidth frame will produce the size set by the last
3547 adjust_frame_size call. */
3548 x_default_parameter (f
, parms
, Qfullscreen
, Qnil
,
3549 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL
);
3551 /* Make the window appear on the frame and enable display, unless
3552 the caller says not to. However, with explicit parent, Emacs
3553 cannot control visibility, so don't try. */
3554 if (! f
->output_data
.x
->explicit_parent
)
3556 Lisp_Object visibility
;
3558 visibility
= x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0,
3560 if (EQ (visibility
, Qunbound
))
3563 if (EQ (visibility
, Qicon
))
3564 x_iconify_frame (f
);
3565 else if (! NILP (visibility
))
3566 x_make_frame_visible (f
);
3569 /* Must have been Qnil. */
3575 /* Set machine name and pid for the purpose of window managers. */
3576 set_machine_and_pid_properties (f
);
3578 /* Set the WM leader property. GTK does this itself, so this is not
3579 needed when using GTK. */
3580 if (dpyinfo
->client_leader_window
!= 0)
3582 XChangeProperty (FRAME_X_DISPLAY (f
),
3583 FRAME_OUTER_WINDOW (f
),
3584 dpyinfo
->Xatom_wm_client_leader
,
3585 XA_WINDOW
, 32, PropModeReplace
,
3586 (unsigned char *) &dpyinfo
->client_leader_window
, 1);
3591 /* Initialize `default-minibuffer-frame' in case this is the first
3592 frame on this terminal. */
3593 if (FRAME_HAS_MINIBUF_P (f
)
3594 && (!FRAMEP (KVAR (kb
, Vdefault_minibuffer_frame
))
3595 || !FRAME_LIVE_P (XFRAME (KVAR (kb
, Vdefault_minibuffer_frame
)))))
3596 kset_default_minibuffer_frame (kb
, frame
);
3598 /* All remaining specified parameters, which have not been "used"
3599 by x_get_arg and friends, now go in the misc. alist of the frame. */
3600 for (tem
= parms
; CONSP (tem
); tem
= XCDR (tem
))
3601 if (CONSP (XCAR (tem
)) && !NILP (XCAR (XCAR (tem
))))
3602 fset_param_alist (f
, Fcons (XCAR (tem
), f
->param_alist
));
3604 /* Make sure windows on this frame appear in calls to next-window
3605 and similar functions. */
3606 Vwindow_list
= Qnil
;
3608 return unbind_to (count
, frame
);
3612 /* FRAME is used only to get a handle on the X display. We don't pass the
3613 display info directly because we're called from frame.c, which doesn't
3614 know about that structure. */
3617 x_get_focus_frame (struct frame
*frame
)
3619 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (frame
);
3621 if (! dpyinfo
->x_focus_frame
)
3624 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
3629 /* In certain situations, when the window manager follows a
3630 click-to-focus policy, there seems to be no way around calling
3631 XSetInputFocus to give another frame the input focus .
3633 In an ideal world, XSetInputFocus should generally be avoided so
3634 that applications don't interfere with the window manager's focus
3635 policy. But I think it's okay to use when it's clearly done
3636 following a user-command. */
3639 x_focus_frame (struct frame
*f
)
3641 Display
*dpy
= FRAME_X_DISPLAY (f
);
3644 x_catch_errors (dpy
);
3646 if (FRAME_X_EMBEDDED_P (f
))
3648 /* For Xembedded frames, normally the embedder forwards key
3649 events. See XEmbed Protocol Specification at
3650 http://freedesktop.org/wiki/Specifications/xembed-spec */
3651 xembed_request_focus (f
);
3655 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3656 RevertToParent
, CurrentTime
);
3657 x_ewmh_activate_frame (f
);
3660 x_uncatch_errors ();
3665 DEFUN ("xw-color-defined-p", Fxw_color_defined_p
, Sxw_color_defined_p
, 1, 2, 0,
3666 doc
: /* Internal function called by `color-defined-p', which see.
3667 \(Note that the Nextstep version of this function ignores FRAME.) */)
3668 (Lisp_Object color
, Lisp_Object frame
)
3671 struct frame
*f
= decode_window_system_frame (frame
);
3673 CHECK_STRING (color
);
3675 if (x_defined_color (f
, SSDATA (color
), &foo
, false))
3681 DEFUN ("xw-color-values", Fxw_color_values
, Sxw_color_values
, 1, 2, 0,
3682 doc
: /* Internal function called by `color-values', which see. */)
3683 (Lisp_Object color
, Lisp_Object frame
)
3686 struct frame
*f
= decode_window_system_frame (frame
);
3688 CHECK_STRING (color
);
3690 if (x_defined_color (f
, SSDATA (color
), &foo
, false))
3691 return list3i (foo
.red
, foo
.green
, foo
.blue
);
3696 DEFUN ("xw-display-color-p", Fxw_display_color_p
, Sxw_display_color_p
, 0, 1, 0,
3697 doc
: /* Internal function called by `display-color-p', which see. */)
3698 (Lisp_Object terminal
)
3700 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3702 if (dpyinfo
->n_planes
<= 2)
3705 switch (dpyinfo
->visual
->class)
3718 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
3720 doc
: /* Return t if the X display supports shades of gray.
3721 Note that color displays do support shades of gray.
3722 The optional argument TERMINAL specifies which display to ask about.
3723 TERMINAL should be a terminal object, a frame or a display name (a string).
3724 If omitted or nil, that stands for the selected frame's display. */)
3725 (Lisp_Object terminal
)
3727 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3729 if (dpyinfo
->n_planes
<= 1)
3732 switch (dpyinfo
->visual
->class)
3747 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
3749 doc
: /* Return the width in pixels of the X display TERMINAL.
3750 The optional argument TERMINAL specifies which display to ask about.
3751 TERMINAL should be a terminal object, a frame or a display name (a string).
3752 If omitted or nil, that stands for the selected frame's display.
3754 On \"multi-monitor\" setups this refers to the pixel width for all
3755 physical monitors associated with TERMINAL. To get information for
3756 each physical monitor, use `display-monitor-attributes-list'. */)
3757 (Lisp_Object terminal
)
3759 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3761 return make_number (x_display_pixel_width (dpyinfo
));
3764 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
3765 Sx_display_pixel_height
, 0, 1, 0,
3766 doc
: /* Return the height in pixels of the X display TERMINAL.
3767 The optional argument TERMINAL specifies which display to ask about.
3768 TERMINAL should be a terminal object, a frame or a display name (a string).
3769 If omitted or nil, that stands for the selected frame's display.
3771 On \"multi-monitor\" setups this refers to the pixel height for all
3772 physical monitors associated with TERMINAL. To get information for
3773 each physical monitor, use `display-monitor-attributes-list'. */)
3774 (Lisp_Object terminal
)
3776 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3778 return make_number (x_display_pixel_height (dpyinfo
));
3781 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
3783 doc
: /* Return the number of bitplanes of the X display TERMINAL.
3784 The optional argument TERMINAL specifies which display to ask about.
3785 TERMINAL should be a terminal object, a frame or a display name (a string).
3786 If omitted or nil, that stands for the selected frame's display. */)
3787 (Lisp_Object terminal
)
3789 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3791 return make_number (dpyinfo
->n_planes
);
3794 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
3796 doc
: /* Return the number of color cells of the X display TERMINAL.
3797 The optional argument TERMINAL specifies which display to ask about.
3798 TERMINAL should be a terminal object, a frame or a display name (a string).
3799 If omitted or nil, that stands for the selected frame's display. */)
3800 (Lisp_Object terminal
)
3802 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3804 int nr_planes
= DisplayPlanes (dpyinfo
->display
,
3805 XScreenNumberOfScreen (dpyinfo
->screen
));
3807 /* Truncate nr_planes to 24 to avoid integer overflow.
3808 Some displays says 32, but only 24 bits are actually significant.
3809 There are only very few and rare video cards that have more than
3810 24 significant bits. Also 24 bits is more than 16 million colors,
3811 it "should be enough for everyone". */
3812 if (nr_planes
> 24) nr_planes
= 24;
3814 return make_number (1 << nr_planes
);
3817 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
3818 Sx_server_max_request_size
,
3820 doc
: /* Return the maximum request size of the X server of display TERMINAL.
3821 The optional argument TERMINAL specifies which display to ask about.
3822 TERMINAL should be a terminal object, a frame or a display name (a string).
3823 If omitted or nil, that stands for the selected frame's display. */)
3824 (Lisp_Object terminal
)
3826 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3828 return make_number (MAXREQUEST (dpyinfo
->display
));
3831 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
3832 doc
: /* Return the "vendor ID" string of the GUI software on TERMINAL.
3834 \(Labeling every distributor as a "vendor" embodies the false assumption
3835 that operating systems cannot be developed and distributed noncommercially.)
3836 The optional argument TERMINAL specifies which display to ask about.
3838 For GNU and Unix systems, this queries the X server software; for
3839 MS-Windows, this queries the OS.
3841 TERMINAL should be a terminal object, a frame or a display name (a string).
3842 If omitted or nil, that stands for the selected frame's display. */)
3843 (Lisp_Object terminal
)
3845 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3846 const char *vendor
= ServerVendor (dpyinfo
->display
);
3848 if (! vendor
) vendor
= "";
3849 return build_string (vendor
);
3852 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
3853 doc
: /* Return the version numbers of the GUI software on TERMINAL.
3854 The value is a list of three integers specifying the version of the GUI
3857 For GNU and Unix system, the first 2 numbers are the version of the X
3858 Protocol used on TERMINAL and the 3rd number is the distributor-specific
3859 release number. For MS-Windows, the 3 numbers report the version and
3860 the build number of the OS.
3862 See also the function `x-server-vendor'.
3864 The optional argument TERMINAL specifies which display to ask about.
3865 TERMINAL should be a terminal object, a frame or a display name (a string).
3866 If omitted or nil, that stands for the selected frame's display. */)
3867 (Lisp_Object terminal
)
3869 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3870 Display
*dpy
= dpyinfo
->display
;
3872 return list3i (ProtocolVersion (dpy
), ProtocolRevision (dpy
),
3873 VendorRelease (dpy
));
3876 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
3877 doc
: /* Return the number of screens on the X server of display TERMINAL.
3878 The optional argument TERMINAL specifies which display to ask about.
3879 TERMINAL should be a terminal object, a frame or a display name (a string).
3880 If omitted or nil, that stands for the selected frame's display. */)
3881 (Lisp_Object terminal
)
3883 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3885 return make_number (ScreenCount (dpyinfo
->display
));
3888 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
3889 doc
: /* Return the height in millimeters of the X display TERMINAL.
3890 The optional argument TERMINAL specifies which display to ask about.
3891 TERMINAL should be a terminal object, a frame or a display name (a string).
3892 If omitted or nil, that stands for the selected frame's display.
3894 On \"multi-monitor\" setups this refers to the height in millimeters for
3895 all physical monitors associated with TERMINAL. To get information
3896 for each physical monitor, use `display-monitor-attributes-list'. */)
3897 (Lisp_Object terminal
)
3899 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3901 return make_number (HeightMMOfScreen (dpyinfo
->screen
));
3904 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
3905 doc
: /* Return the width in millimeters of the X display TERMINAL.
3906 The optional argument TERMINAL specifies which display to ask about.
3907 TERMINAL should be a terminal object, a frame or a display name (a string).
3908 If omitted or nil, that stands for the selected frame's display.
3910 On \"multi-monitor\" setups this refers to the width in millimeters for
3911 all physical monitors associated with TERMINAL. To get information
3912 for each physical monitor, use `display-monitor-attributes-list'. */)
3913 (Lisp_Object terminal
)
3915 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3917 return make_number (WidthMMOfScreen (dpyinfo
->screen
));
3920 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
3921 Sx_display_backing_store
, 0, 1, 0,
3922 doc
: /* Return an indication of whether X display TERMINAL does backing store.
3923 The value may be `always', `when-mapped', or `not-useful'.
3924 The optional argument TERMINAL specifies which display to ask about.
3925 TERMINAL should be a terminal object, a frame or a display name (a string).
3926 If omitted or nil, that stands for the selected frame's display. */)
3927 (Lisp_Object terminal
)
3929 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3932 switch (DoesBackingStore (dpyinfo
->screen
))
3935 result
= intern ("always");
3939 result
= intern ("when-mapped");
3943 result
= intern ("not-useful");
3947 error ("Strange value for BackingStore parameter of screen");
3953 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
3954 Sx_display_visual_class
, 0, 1, 0,
3955 doc
: /* Return the visual class of the X display TERMINAL.
3956 The value is one of the symbols `static-gray', `gray-scale',
3957 `static-color', `pseudo-color', `true-color', or `direct-color'.
3959 The optional argument TERMINAL specifies which display to ask about.
3960 TERMINAL should a terminal object, a frame or a display name (a string).
3961 If omitted or nil, that stands for the selected frame's display. */)
3962 (Lisp_Object terminal
)
3964 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3967 switch (dpyinfo
->visual
->class)
3970 result
= intern ("static-gray");
3973 result
= intern ("gray-scale");
3976 result
= intern ("static-color");
3979 result
= intern ("pseudo-color");
3982 result
= intern ("true-color");
3985 result
= intern ("direct-color");
3988 error ("Display has an unknown visual class");
3994 DEFUN ("x-display-save-under", Fx_display_save_under
,
3995 Sx_display_save_under
, 0, 1, 0,
3996 doc
: /* Return t if the X display TERMINAL supports the save-under feature.
3997 The optional argument TERMINAL specifies which display to ask about.
3998 TERMINAL should be a terminal object, a frame or a display name (a string).
3999 If omitted or nil, that stands for the selected frame's display. */)
4000 (Lisp_Object terminal
)
4002 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4004 if (DoesSaveUnders (dpyinfo
->screen
) == True
)
4010 /* Store the geometry of the workarea on display DPYINFO into *RECT.
4011 Return false if and only if the workarea information cannot be
4012 obtained via the _NET_WORKAREA root window property. */
4014 #if ! GTK_CHECK_VERSION (3, 4, 0)
4016 x_get_net_workarea (struct x_display_info
*dpyinfo
, XRectangle
*rect
)
4018 Display
*dpy
= dpyinfo
->display
;
4019 long offset
, max_len
;
4020 Atom target_type
, actual_type
;
4021 unsigned long actual_size
, bytes_remaining
;
4022 int rc
, actual_format
;
4023 unsigned char *tmp_data
= NULL
;
4024 bool result
= false;
4026 x_catch_errors (dpy
);
4029 target_type
= XA_CARDINAL
;
4030 rc
= XGetWindowProperty (dpy
, dpyinfo
->root_window
,
4031 dpyinfo
->Xatom_net_current_desktop
,
4032 offset
, max_len
, False
, target_type
,
4033 &actual_type
, &actual_format
, &actual_size
,
4034 &bytes_remaining
, &tmp_data
);
4035 if (rc
== Success
&& actual_type
== target_type
&& !x_had_errors_p (dpy
)
4036 && actual_format
== 32 && actual_size
== max_len
)
4038 long current_desktop
= ((long *) tmp_data
)[0];
4043 offset
= 4 * current_desktop
;
4045 rc
= XGetWindowProperty (dpy
, dpyinfo
->root_window
,
4046 dpyinfo
->Xatom_net_workarea
,
4047 offset
, max_len
, False
, target_type
,
4048 &actual_type
, &actual_format
, &actual_size
,
4049 &bytes_remaining
, &tmp_data
);
4050 if (rc
== Success
&& actual_type
== target_type
&& !x_had_errors_p (dpy
)
4051 && actual_format
== 32 && actual_size
== max_len
)
4053 long *values
= (long *) tmp_data
;
4055 rect
->x
= values
[0];
4056 rect
->y
= values
[1];
4057 rect
->width
= values
[2];
4058 rect
->height
= values
[3];
4068 x_uncatch_errors ();
4076 /* Return monitor number where F is "most" or closest to. */
4078 x_get_monitor_for_frame (struct frame
*f
,
4079 struct MonitorInfo
*monitors
,
4083 int area
= 0, dist
= -1;
4084 int best_area
= -1, best_dist
= -1;
4087 if (n_monitors
== 1) return 0;
4088 frect
.x
= f
->left_pos
;
4089 frect
.y
= f
->top_pos
;
4090 frect
.width
= FRAME_PIXEL_WIDTH (f
);
4091 frect
.height
= FRAME_PIXEL_HEIGHT (f
);
4093 for (i
= 0; i
< n_monitors
; ++i
)
4095 struct MonitorInfo
*mi
= &monitors
[i
];
4099 if (mi
->geom
.width
== 0) continue;
4101 if (x_intersect_rectangles (&mi
->geom
, &frect
, &res
))
4103 a
= res
.width
* res
.height
;
4111 if (a
== 0 && area
== 0)
4114 if (frect
.x
+ frect
.width
< mi
->geom
.x
)
4115 dx
= mi
->geom
.x
- frect
.x
+ frect
.width
;
4116 else if (frect
.x
> mi
->geom
.x
+ mi
->geom
.width
)
4117 dx
= frect
.x
- mi
->geom
.x
+ mi
->geom
.width
;
4120 if (frect
.y
+ frect
.height
< mi
->geom
.y
)
4121 dy
= mi
->geom
.y
- frect
.y
+ frect
.height
;
4122 else if (frect
.y
> mi
->geom
.y
+ mi
->geom
.height
)
4123 dy
= frect
.y
- mi
->geom
.y
+ mi
->geom
.height
;
4128 if (dist
== -1 || dist
> d
)
4136 return best_area
!= -1 ? best_area
: (best_dist
!= -1 ? best_dist
: 0);
4140 x_make_monitor_attribute_list (struct MonitorInfo
*monitors
,
4142 int primary_monitor
,
4143 struct x_display_info
*dpyinfo
,
4146 Lisp_Object monitor_frames
= Fmake_vector (make_number (n_monitors
), Qnil
);
4147 Lisp_Object frame
, rest
;
4149 FOR_EACH_FRAME (rest
, frame
)
4151 struct frame
*f
= XFRAME (frame
);
4153 if (FRAME_X_P (f
) && FRAME_DISPLAY_INFO (f
) == dpyinfo
4154 && !EQ (frame
, tip_frame
))
4156 int i
= x_get_monitor_for_frame (f
, monitors
, n_monitors
);
4157 ASET (monitor_frames
, i
, Fcons (frame
, AREF (monitor_frames
, i
)));
4161 return make_monitor_attribute_list (monitors
, n_monitors
, primary_monitor
,
4162 monitor_frames
, source
);
4166 x_get_monitor_attributes_fallback (struct x_display_info
*dpyinfo
)
4168 struct MonitorInfo monitor
;
4169 XRectangle workarea_r
;
4171 /* Fallback: treat (possibly) multiple physical monitors as if they
4172 formed a single monitor as a whole. This should provide a
4173 consistent result at least on single monitor environments. */
4174 monitor
.geom
.x
= monitor
.geom
.y
= 0;
4175 monitor
.geom
.width
= x_display_pixel_width (dpyinfo
);
4176 monitor
.geom
.height
= x_display_pixel_height (dpyinfo
);
4177 monitor
.mm_width
= WidthMMOfScreen (dpyinfo
->screen
);
4178 monitor
.mm_height
= HeightMMOfScreen (dpyinfo
->screen
);
4179 monitor
.name
= xstrdup ("combined screen");
4181 if (x_get_net_workarea (dpyinfo
, &workarea_r
))
4182 monitor
.work
= workarea_r
;
4184 monitor
.work
= monitor
.geom
;
4185 return x_make_monitor_attribute_list (&monitor
, 1, 0, dpyinfo
, "fallback");
4189 #ifdef HAVE_XINERAMA
4191 x_get_monitor_attributes_xinerama (struct x_display_info
*dpyinfo
)
4194 Lisp_Object attributes_list
= Qnil
;
4195 Display
*dpy
= dpyinfo
->display
;
4196 XineramaScreenInfo
*info
= XineramaQueryScreens (dpy
, &n_monitors
);
4197 struct MonitorInfo
*monitors
;
4198 double mm_width_per_pixel
, mm_height_per_pixel
;
4200 if (! info
|| n_monitors
== 0)
4204 return attributes_list
;
4207 mm_width_per_pixel
= ((double) WidthMMOfScreen (dpyinfo
->screen
)
4208 / x_display_pixel_width (dpyinfo
));
4209 mm_height_per_pixel
= ((double) HeightMMOfScreen (dpyinfo
->screen
)
4210 / x_display_pixel_height (dpyinfo
));
4211 monitors
= xzalloc (n_monitors
* sizeof *monitors
);
4212 for (i
= 0; i
< n_monitors
; ++i
)
4214 struct MonitorInfo
*mi
= &monitors
[i
];
4215 XRectangle workarea_r
;
4217 mi
->geom
.x
= info
[i
].x_org
;
4218 mi
->geom
.y
= info
[i
].y_org
;
4219 mi
->geom
.width
= info
[i
].width
;
4220 mi
->geom
.height
= info
[i
].height
;
4221 mi
->mm_width
= mi
->geom
.width
* mm_width_per_pixel
+ 0.5;
4222 mi
->mm_height
= mi
->geom
.height
* mm_height_per_pixel
+ 0.5;
4225 /* Xinerama usually have primary monitor first, just use that. */
4226 if (i
== 0 && x_get_net_workarea (dpyinfo
, &workarea_r
))
4228 mi
->work
= workarea_r
;
4229 if (! x_intersect_rectangles (&mi
->geom
, &mi
->work
, &mi
->work
))
4230 mi
->work
= mi
->geom
;
4233 mi
->work
= mi
->geom
;
4237 attributes_list
= x_make_monitor_attribute_list (monitors
,
4242 free_monitors (monitors
, n_monitors
);
4243 return attributes_list
;
4245 #endif /* HAVE_XINERAMA */
4250 x_get_monitor_attributes_xrandr (struct x_display_info
*dpyinfo
)
4252 Lisp_Object attributes_list
= Qnil
;
4253 XRRScreenResources
*resources
;
4254 Display
*dpy
= dpyinfo
->display
;
4255 int i
, n_monitors
, primary
= -1;
4256 RROutput pxid
= None
;
4257 struct MonitorInfo
*monitors
;
4259 #define RANDR13_LIBRARY \
4260 (RANDR_MAJOR > 1 || (RANDR_MAJOR == 1 && RANDR_MINOR >= 3))
4263 /* Check if the display supports 1.3 too. */
4264 bool randr13_avail
= (dpyinfo
->xrandr_major_version
> 1
4265 || (dpyinfo
->xrandr_major_version
== 1
4266 && dpyinfo
->xrandr_minor_version
>= 3));
4269 resources
= XRRGetScreenResourcesCurrent (dpy
, dpyinfo
->root_window
);
4271 resources
= XRRGetScreenResources (dpy
, dpyinfo
->root_window
);
4273 resources
= XRRGetScreenResources (dpy
, dpyinfo
->root_window
);
4275 if (! resources
|| resources
->noutput
== 0)
4278 XRRFreeScreenResources (resources
);
4281 n_monitors
= resources
->noutput
;
4282 monitors
= xzalloc (n_monitors
* sizeof *monitors
);
4286 pxid
= XRRGetOutputPrimary (dpy
, dpyinfo
->root_window
);
4289 for (i
= 0; i
< n_monitors
; ++i
)
4291 XRROutputInfo
*info
= XRRGetOutputInfo (dpy
, resources
,
4292 resources
->outputs
[i
]);
4296 if (strcmp (info
->name
, "default") == 0)
4298 /* Non XRandr 1.2 driver, does not give useful data. */
4299 XRRFreeOutputInfo (info
);
4300 XRRFreeScreenResources (resources
);
4301 free_monitors (monitors
, n_monitors
);
4305 if (info
->connection
!= RR_Disconnected
&& info
->crtc
!= None
)
4307 XRRCrtcInfo
*crtc
= XRRGetCrtcInfo (dpy
, resources
, info
->crtc
);
4308 struct MonitorInfo
*mi
= &monitors
[i
];
4309 XRectangle workarea_r
;
4313 XRRFreeOutputInfo (info
);
4317 mi
->geom
.x
= crtc
->x
;
4318 mi
->geom
.y
= crtc
->y
;
4319 mi
->geom
.width
= crtc
->width
;
4320 mi
->geom
.height
= crtc
->height
;
4321 mi
->mm_width
= info
->mm_width
;
4322 mi
->mm_height
= info
->mm_height
;
4323 mi
->name
= xstrdup (info
->name
);
4325 if (pxid
!= None
&& pxid
== resources
->outputs
[i
])
4327 else if (primary
== -1 && strcmp (info
->name
, "LVDS") == 0)
4330 if (i
== primary
&& x_get_net_workarea (dpyinfo
, &workarea_r
))
4332 mi
->work
= workarea_r
;
4333 if (! x_intersect_rectangles (&mi
->geom
, &mi
->work
, &mi
->work
))
4334 mi
->work
= mi
->geom
;
4337 mi
->work
= mi
->geom
;
4339 XRRFreeCrtcInfo (crtc
);
4341 XRRFreeOutputInfo (info
);
4343 XRRFreeScreenResources (resources
);
4345 attributes_list
= x_make_monitor_attribute_list (monitors
,
4350 free_monitors (monitors
, n_monitors
);
4351 return attributes_list
;
4353 #endif /* HAVE_XRANDR */
4356 x_get_monitor_attributes (struct x_display_info
*dpyinfo
)
4358 Lisp_Object attributes_list
= Qnil
;
4359 Display
*dpy
= dpyinfo
->display
;
4361 (void) dpy
; /* Suppress unused variable warning. */
4364 int xrr_event_base
, xrr_error_base
;
4365 bool xrr_ok
= false;
4366 xrr_ok
= XRRQueryExtension (dpy
, &xrr_event_base
, &xrr_error_base
);
4369 XRRQueryVersion (dpy
, &dpyinfo
->xrandr_major_version
,
4370 &dpyinfo
->xrandr_minor_version
);
4371 xrr_ok
= ((dpyinfo
->xrandr_major_version
== 1
4372 && dpyinfo
->xrandr_minor_version
>= 2)
4373 || dpyinfo
->xrandr_major_version
> 1);
4377 attributes_list
= x_get_monitor_attributes_xrandr (dpyinfo
);
4378 #endif /* HAVE_XRANDR */
4380 #ifdef HAVE_XINERAMA
4381 if (NILP (attributes_list
))
4383 int xin_event_base
, xin_error_base
;
4384 bool xin_ok
= false;
4385 xin_ok
= XineramaQueryExtension (dpy
, &xin_event_base
, &xin_error_base
);
4386 if (xin_ok
&& XineramaIsActive (dpy
))
4387 attributes_list
= x_get_monitor_attributes_xinerama (dpyinfo
);
4389 #endif /* HAVE_XINERAMA */
4391 if (NILP (attributes_list
))
4392 attributes_list
= x_get_monitor_attributes_fallback (dpyinfo
);
4394 return attributes_list
;
4397 #endif /* !USE_GTK */
4399 DEFUN ("x-display-monitor-attributes-list", Fx_display_monitor_attributes_list
,
4400 Sx_display_monitor_attributes_list
,
4402 doc
: /* Return a list of physical monitor attributes on the X display TERMINAL.
4404 The optional argument TERMINAL specifies which display to ask about.
4405 TERMINAL should be a terminal object, a frame or a display name (a string).
4406 If omitted or nil, that stands for the selected frame's display.
4408 In addition to the standard attribute keys listed in
4409 `display-monitor-attributes-list', the following keys are contained in
4412 source -- String describing the source from which multi-monitor
4413 information is obtained, one of \"Gdk\", \"XRandr\",
4414 \"Xinerama\", or \"fallback\"
4416 Internal use only, use `display-monitor-attributes-list' instead. */)
4417 (Lisp_Object terminal
)
4419 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4420 Lisp_Object attributes_list
= Qnil
;
4423 double mm_width_per_pixel
, mm_height_per_pixel
;
4426 gint primary_monitor
= 0, n_monitors
, i
;
4427 Lisp_Object monitor_frames
, rest
, frame
;
4428 static const char *source
= "Gdk";
4429 struct MonitorInfo
*monitors
;
4432 mm_width_per_pixel
= ((double) WidthMMOfScreen (dpyinfo
->screen
)
4433 / x_display_pixel_width (dpyinfo
));
4434 mm_height_per_pixel
= ((double) HeightMMOfScreen (dpyinfo
->screen
)
4435 / x_display_pixel_height (dpyinfo
));
4436 gdpy
= gdk_x11_lookup_xdisplay (dpyinfo
->display
);
4437 gscreen
= gdk_display_get_default_screen (gdpy
);
4438 #if GTK_CHECK_VERSION (2, 20, 0)
4439 primary_monitor
= gdk_screen_get_primary_monitor (gscreen
);
4441 n_monitors
= gdk_screen_get_n_monitors (gscreen
);
4442 monitor_frames
= Fmake_vector (make_number (n_monitors
), Qnil
);
4443 monitors
= xzalloc (n_monitors
* sizeof *monitors
);
4445 FOR_EACH_FRAME (rest
, frame
)
4447 struct frame
*f
= XFRAME (frame
);
4449 if (FRAME_X_P (f
) && FRAME_DISPLAY_INFO (f
) == dpyinfo
4450 && !EQ (frame
, tip_frame
))
4452 GdkWindow
*gwin
= gtk_widget_get_window (FRAME_GTK_WIDGET (f
));
4454 i
= gdk_screen_get_monitor_at_window (gscreen
, gwin
);
4455 ASET (monitor_frames
, i
, Fcons (frame
, AREF (monitor_frames
, i
)));
4459 for (i
= 0; i
< n_monitors
; ++i
)
4461 gint width_mm
= -1, height_mm
= -1;
4462 GdkRectangle rec
, work
;
4463 struct MonitorInfo
*mi
= &monitors
[i
];
4465 gdk_screen_get_monitor_geometry (gscreen
, i
, &rec
);
4467 #if GTK_CHECK_VERSION (2, 14, 0)
4468 width_mm
= gdk_screen_get_monitor_width_mm (gscreen
, i
);
4469 height_mm
= gdk_screen_get_monitor_height_mm (gscreen
, i
);
4472 width_mm
= rec
.width
* mm_width_per_pixel
+ 0.5;
4474 height_mm
= rec
.height
* mm_height_per_pixel
+ 0.5;
4476 #if GTK_CHECK_VERSION (3, 4, 0)
4477 gdk_screen_get_monitor_workarea (gscreen
, i
, &work
);
4479 /* Emulate the behavior of GTK+ 3.4. */
4481 XRectangle workarea_r
;
4483 if (i
== primary_monitor
&& x_get_net_workarea (dpyinfo
, &workarea_r
))
4485 work
.x
= workarea_r
.x
;
4486 work
.y
= workarea_r
.y
;
4487 work
.width
= workarea_r
.width
;
4488 work
.height
= workarea_r
.height
;
4489 if (! gdk_rectangle_intersect (&rec
, &work
, &work
))
4500 mi
->geom
.width
= rec
.width
;
4501 mi
->geom
.height
= rec
.height
;
4502 mi
->work
.x
= work
.x
;
4503 mi
->work
.y
= work
.y
;
4504 mi
->work
.width
= work
.width
;
4505 mi
->work
.height
= work
.height
;
4506 mi
->mm_width
= width_mm
;
4507 mi
->mm_height
= height_mm
;
4509 #if GTK_CHECK_VERSION (2, 14, 0)
4510 mi
->name
= gdk_screen_get_monitor_plug_name (gscreen
, i
);
4514 attributes_list
= make_monitor_attribute_list (monitors
,
4520 #else /* not USE_GTK */
4523 attributes_list
= x_get_monitor_attributes (dpyinfo
);
4526 #endif /* not USE_GTK */
4528 return attributes_list
;
4531 /* Return geometric attributes of FRAME. According to the value of
4532 ATTRIBUTES return the outer edges of FRAME (Qouter_edges), the native
4533 edges of FRAME (Qnative_edges), or the inner edges of frame
4534 (Qinner_edges). Any other value means to return the geometry as
4535 returned by Fx_frame_geometry. */
4537 frame_geometry (Lisp_Object frame
, Lisp_Object attribute
)
4539 struct frame
*f
= decode_live_frame (frame
);
4540 /** XWindowAttributes atts; **/
4542 unsigned int ign
, native_width
, native_height
;
4543 int xy_ign
, xptr
, yptr
;
4544 int left_off
, right_off
, top_off
, bottom_off
;
4545 int outer_left
, outer_top
, outer_right
, outer_bottom
;
4546 int native_left
, native_top
, native_right
, native_bottom
;
4547 int inner_left
, inner_top
, inner_right
, inner_bottom
;
4548 int internal_border_width
;
4549 bool menu_bar_external
= false, tool_bar_external
= false;
4550 int menu_bar_height
= 0, menu_bar_width
= 0;
4551 int tool_bar_height
= 0, tool_bar_width
= 0;
4553 if (FRAME_INITIAL_P (f
) || !FRAME_X_P (f
))
4557 XGetGeometry (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
4558 &rootw
, &xy_ign
, &xy_ign
, &native_width
, &native_height
,
4560 /** XGetWindowAttributes (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &atts); **/
4561 x_real_pos_and_offsets (f
, &left_off
, &right_off
, &top_off
, &bottom_off
,
4562 NULL
, NULL
, &xptr
, &yptr
, NULL
);
4565 /** native_width = atts.width; **/
4566 /** native_height = atts.height; **/
4570 outer_right
= outer_left
+ left_off
+ native_width
+ right_off
;
4571 outer_bottom
= outer_top
+ top_off
+ native_height
+ bottom_off
;
4573 native_left
= outer_left
+ left_off
;
4574 native_top
= outer_top
+ top_off
;
4575 native_right
= native_left
+ native_width
;
4576 native_bottom
= native_top
+ native_height
;
4578 internal_border_width
= FRAME_INTERNAL_BORDER_WIDTH (f
);
4579 inner_left
= native_left
+ internal_border_width
;
4580 inner_top
= native_top
+ internal_border_width
;
4581 inner_right
= native_right
- internal_border_width
;
4582 inner_bottom
= native_bottom
- internal_border_width
;
4584 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
4585 menu_bar_external
= true;
4586 menu_bar_height
= FRAME_MENUBAR_HEIGHT (f
);
4587 native_top
+= menu_bar_height
;
4588 inner_top
+= menu_bar_height
;
4590 menu_bar_height
= FRAME_MENU_BAR_HEIGHT (f
);
4591 inner_top
+= menu_bar_height
;
4593 menu_bar_width
= menu_bar_height
? native_width
: 0;
4595 #if defined (USE_GTK)
4596 tool_bar_external
= true;
4597 if (EQ (FRAME_TOOL_BAR_POSITION (f
), Qleft
))
4599 tool_bar_width
= FRAME_TOOLBAR_WIDTH (f
);
4600 native_left
+= tool_bar_width
;
4601 inner_left
+= tool_bar_width
;
4603 = tool_bar_width
? native_height
- menu_bar_height
: 0;
4605 else if (EQ (FRAME_TOOL_BAR_POSITION (f
), Qtop
))
4607 tool_bar_height
= FRAME_TOOLBAR_HEIGHT (f
);
4608 native_top
+= tool_bar_height
;
4609 inner_top
+= tool_bar_height
;
4610 tool_bar_width
= tool_bar_height
? native_width
: 0;
4612 else if (EQ (FRAME_TOOL_BAR_POSITION (f
), Qright
))
4614 tool_bar_width
= FRAME_TOOLBAR_WIDTH (f
);
4615 native_right
-= tool_bar_width
;
4616 inner_right
-= tool_bar_width
;
4618 = tool_bar_width
? native_height
- menu_bar_height
: 0;
4622 tool_bar_height
= FRAME_TOOLBAR_HEIGHT (f
);
4623 native_bottom
-= tool_bar_height
;
4624 inner_bottom
-= tool_bar_height
;
4625 tool_bar_width
= tool_bar_height
? native_width
: 0;
4628 tool_bar_height
= FRAME_TOOL_BAR_HEIGHT (f
);
4629 tool_bar_width
= (tool_bar_height
4630 ? native_width
- 2 * internal_border_width
4632 inner_top
+= tool_bar_height
;
4635 /* Construct list. */
4636 if (EQ (attribute
, Qouter_edges
))
4637 return list4 (make_number (outer_left
), make_number (outer_top
),
4638 make_number (outer_right
), make_number (outer_bottom
));
4639 else if (EQ (attribute
, Qnative_edges
))
4640 return list4 (make_number (native_left
), make_number (native_top
),
4641 make_number (native_right
), make_number (native_bottom
));
4642 else if (EQ (attribute
, Qinner_edges
))
4643 return list4 (make_number (inner_left
), make_number (inner_top
),
4644 make_number (inner_right
), make_number (inner_bottom
));
4647 listn (CONSTYPE_HEAP
, 10,
4648 Fcons (Qouter_position
,
4649 Fcons (make_number (outer_left
),
4650 make_number (outer_top
))),
4652 Fcons (make_number (outer_right
- outer_left
),
4653 make_number (outer_bottom
- outer_top
))),
4655 Fcons (Qexternal_border_size
,
4656 Fcons (make_number (right_off
),
4657 make_number (bottom_off
))),
4659 Fcons (Qtitle_bar_size
,
4660 Fcons (make_number (0),
4661 make_number (top_off
- bottom_off
))),
4662 Fcons (Qmenu_bar_external
, menu_bar_external
? Qt
: Qnil
),
4663 Fcons (Qmenu_bar_size
,
4664 Fcons (make_number (menu_bar_width
),
4665 make_number (menu_bar_height
))),
4666 Fcons (Qtool_bar_external
, tool_bar_external
? Qt
: Qnil
),
4667 Fcons (Qtool_bar_position
, FRAME_TOOL_BAR_POSITION (f
)),
4668 Fcons (Qtool_bar_size
,
4669 Fcons (make_number (tool_bar_width
),
4670 make_number (tool_bar_height
))),
4671 Fcons (Qinternal_border_width
,
4672 make_number (internal_border_width
)));
4675 DEFUN ("x-frame-geometry", Fx_frame_geometry
, Sx_frame_geometry
, 0, 1, 0,
4676 doc
: /* Return geometric attributes of FRAME.
4677 FRAME must be a live frame and defaults to the selected one. The return
4678 value is an association list of the attributes listed below. All height
4679 and width values are in pixels.
4681 `outer-position' is a cons of the outer left and top edges of FRAME
4682 relative to the origin - the position (0, 0) - of FRAME's display.
4684 `outer-size' is a cons of the outer width and height of FRAME. The
4685 outer size includes the title bar and the external borders as well as
4686 any menu and/or tool bar of frame.
4688 `external-border-size' is a cons of the horizontal and vertical width of
4689 FRAME's external borders as supplied by the window manager.
4691 `title-bar-size' is a cons of the width and height of the title bar of
4692 FRAME as supplied by the window manager. If both of them are zero,
4693 FRAME has no title bar. If only the width is zero, Emacs was not
4694 able to retrieve the width information.
4696 `menu-bar-external', if non-nil, means the menu bar is external (never
4697 included in the inner edges of FRAME).
4699 `menu-bar-size' is a cons of the width and height of the menu bar of
4702 `tool-bar-external', if non-nil, means the tool bar is external (never
4703 included in the inner edges of FRAME).
4705 `tool-bar-position' tells on which side the tool bar on FRAME is and can
4706 be one of `left', `top', `right' or `bottom'. If this is nil, FRAME
4709 `tool-bar-size' is a cons of the width and height of the tool bar of
4712 `internal-border-width' is the width of the internal border of
4716 return frame_geometry (frame
, Qnil
);
4719 DEFUN ("x-frame-edges", Fx_frame_edges
, Sx_frame_edges
, 0, 2, 0,
4720 doc
: /* Return edge coordinates of FRAME.
4721 FRAME must be a live frame and defaults to the selected one. The return
4722 value is a list of the form (LEFT, TOP, RIGHT, BOTTOM). All values are
4723 in pixels relative to the origin - the position (0, 0) - of FRAME's
4726 If optional argument TYPE is the symbol `outer-edges', return the outer
4727 edges of FRAME. The outer edges comprise the decorations of the window
4728 manager (like the title bar or external borders) as well as any external
4729 menu or tool bar of FRAME. If optional argument TYPE is the symbol
4730 `native-edges' or nil, return the native edges of FRAME. The native
4731 edges exclude the decorations of the window manager and any external
4732 menu or tool bar of FRAME. If TYPE is the symbol `inner-edges', return
4733 the inner edges of FRAME. These edges exclude title bar, any borders,
4734 menu bar or tool bar of FRAME. */)
4735 (Lisp_Object frame
, Lisp_Object type
)
4737 return frame_geometry (frame
, ((EQ (type
, Qouter_edges
)
4738 || EQ (type
, Qinner_edges
))
4743 DEFUN ("x-mouse-absolute-pixel-position", Fx_mouse_absolute_pixel_position
,
4744 Sx_mouse_absolute_pixel_position
, 0, 0, 0,
4745 doc
: /* Return absolute position of mouse cursor in pixels.
4746 The position is returned as a cons cell (X . Y) of the coordinates of
4747 the mouse cursor position in pixels relative to a position (0, 0) of the
4748 selected frame's display. */)
4751 struct frame
*f
= SELECTED_FRAME ();
4752 Window root
, dummy_window
;
4755 if (FRAME_INITIAL_P (f
) || !FRAME_X_P (f
))
4759 XQueryPointer (FRAME_X_DISPLAY (f
),
4760 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
4761 &root
, &dummy_window
, &x
, &y
, &dummy
, &dummy
,
4762 (unsigned int *) &dummy
);
4765 return Fcons (make_number (x
), make_number (y
));
4768 DEFUN ("x-set-mouse-absolute-pixel-position", Fx_set_mouse_absolute_pixel_position
,
4769 Sx_set_mouse_absolute_pixel_position
, 2, 2, 0,
4770 doc
: /* Move mouse pointer to absolute pixel position (X, Y).
4771 The coordinates X and Y are interpreted in pixels relative to a position
4772 \(0, 0) of the selected frame's display. */)
4773 (Lisp_Object x
, Lisp_Object y
)
4775 struct frame
*f
= SELECTED_FRAME ();
4777 if (FRAME_INITIAL_P (f
) || !FRAME_X_P (f
))
4780 CHECK_TYPE_RANGED_INTEGER (int, x
);
4781 CHECK_TYPE_RANGED_INTEGER (int, y
);
4784 XWarpPointer (FRAME_X_DISPLAY (f
), None
, DefaultRootWindow (FRAME_X_DISPLAY (f
)),
4785 0, 0, 0, 0, XINT (x
), XINT (y
));
4791 /************************************************************************
4793 ************************************************************************/
4796 /* Mapping visual names to visuals. */
4798 static struct visual_class
4805 {"StaticGray", StaticGray
},
4806 {"GrayScale", GrayScale
},
4807 {"StaticColor", StaticColor
},
4808 {"PseudoColor", PseudoColor
},
4809 {"TrueColor", TrueColor
},
4810 {"DirectColor", DirectColor
},
4815 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4817 /* Value is the screen number of screen SCR. This is a substitute for
4818 the X function with the same name when that doesn't exist. */
4821 XScreenNumberOfScreen (scr
)
4822 register Screen
*scr
;
4824 Display
*dpy
= scr
->display
;
4827 for (i
= 0; i
< dpy
->nscreens
; ++i
)
4828 if (scr
== dpy
->screens
+ i
)
4834 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4837 /* Select the visual that should be used on display DPYINFO. Set
4838 members of DPYINFO appropriately. Called from x_term_init. */
4841 select_visual (struct x_display_info
*dpyinfo
)
4843 Display
*dpy
= dpyinfo
->display
;
4844 Screen
*screen
= dpyinfo
->screen
;
4846 /* See if a visual is specified. */
4847 AUTO_STRING (visualClass
, "visualClass");
4848 AUTO_STRING (VisualClass
, "VisualClass");
4849 Lisp_Object value
= display_x_get_resource (dpyinfo
, visualClass
,
4850 VisualClass
, Qnil
, Qnil
);
4852 if (STRINGP (value
))
4854 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
4855 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
4856 depth, a decimal number. NAME is compared with case ignored. */
4857 char *s
= alloca (SBYTES (value
) + 1);
4862 lispstpcpy (s
, value
);
4863 dash
= strchr (s
, '-');
4866 dpyinfo
->n_planes
= atoi (dash
+ 1);
4870 /* We won't find a matching visual with depth 0, so that
4871 an error will be printed below. */
4872 dpyinfo
->n_planes
= 0;
4874 /* Determine the visual class. */
4875 for (i
= 0; visual_classes
[i
].name
; ++i
)
4876 if (xstrcasecmp (s
, visual_classes
[i
].name
) == 0)
4878 class = visual_classes
[i
].class;
4882 /* Look up a matching visual for the specified class. */
4884 || !XMatchVisualInfo (dpy
, XScreenNumberOfScreen (screen
),
4885 dpyinfo
->n_planes
, class, &vinfo
))
4886 fatal ("Invalid visual specification '%s'",
4887 SSDATA (ENCODE_SYSTEM (value
)));
4889 dpyinfo
->visual
= vinfo
.visual
;
4894 XVisualInfo
*vinfo
, vinfo_template
;
4896 dpyinfo
->visual
= DefaultVisualOfScreen (screen
);
4898 vinfo_template
.visualid
= XVisualIDFromVisual (dpyinfo
->visual
);
4899 vinfo_template
.screen
= XScreenNumberOfScreen (screen
);
4900 vinfo
= XGetVisualInfo (dpy
, VisualIDMask
| VisualScreenMask
,
4901 &vinfo_template
, &n_visuals
);
4903 fatal ("Can't get proper X visual info");
4905 dpyinfo
->n_planes
= vinfo
->depth
;
4911 /* Return the X display structure for the display named NAME.
4912 Open a new connection if necessary. */
4914 static struct x_display_info
*
4915 x_display_info_for_name (Lisp_Object name
)
4917 struct x_display_info
*dpyinfo
;
4919 CHECK_STRING (name
);
4921 for (dpyinfo
= x_display_list
; dpyinfo
; dpyinfo
= dpyinfo
->next
)
4922 if (!NILP (Fstring_equal (XCAR (dpyinfo
->name_list_element
), name
)))
4925 /* Use this general default value to start with. */
4926 Vx_resource_name
= Vinvocation_name
;
4928 validate_x_resource_name ();
4930 dpyinfo
= x_term_init (name
, 0, SSDATA (Vx_resource_name
));
4933 error ("Cannot connect to X server %s", SDATA (name
));
4935 XSETFASTINT (Vwindow_system_version
, 11);
4941 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
4943 doc
: /* Open a connection to a display server.
4944 DISPLAY is the name of the display to connect to.
4945 Optional second arg XRM-STRING is a string of resources in xrdb format.
4946 If the optional third arg MUST-SUCCEED is non-nil,
4947 terminate Emacs if we can't open the connection.
4948 \(In the Nextstep version, the last two arguments are currently ignored.) */)
4949 (Lisp_Object display
, Lisp_Object xrm_string
, Lisp_Object must_succeed
)
4952 struct x_display_info
*dpyinfo
;
4954 CHECK_STRING (display
);
4955 if (! NILP (xrm_string
))
4956 CHECK_STRING (xrm_string
);
4958 xrm_option
= NILP (xrm_string
) ? 0 : SSDATA (xrm_string
);
4960 validate_x_resource_name ();
4962 /* This is what opens the connection and sets x_current_display.
4963 This also initializes many symbols, such as those used for input. */
4964 dpyinfo
= x_term_init (display
, xrm_option
,
4965 SSDATA (Vx_resource_name
));
4969 if (!NILP (must_succeed
))
4970 fatal ("Cannot connect to X server %s.\n\
4971 Check the DISPLAY environment variable or use `-d'.\n\
4972 Also use the `xauth' program to verify that you have the proper\n\
4973 authorization information needed to connect the X server.\n\
4974 An insecure way to solve the problem may be to use `xhost'.\n",
4977 error ("Cannot connect to X server %s", SDATA (display
));
4980 XSETFASTINT (Vwindow_system_version
, 11);
4984 DEFUN ("x-close-connection", Fx_close_connection
,
4985 Sx_close_connection
, 1, 1, 0,
4986 doc
: /* Close the connection to TERMINAL's X server.
4987 For TERMINAL, specify a terminal object, a frame or a display name (a
4988 string). If TERMINAL is nil, that stands for the selected frame's
4990 (Lisp_Object terminal
)
4992 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4994 if (dpyinfo
->reference_count
> 0)
4995 error ("Display still has frames on it");
4997 x_delete_terminal (dpyinfo
->terminal
);
5002 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
5003 doc
: /* Return the list of display names that Emacs has connections to. */)
5006 Lisp_Object result
= Qnil
;
5007 struct x_display_info
*xdi
;
5009 for (xdi
= x_display_list
; xdi
; xdi
= xdi
->next
)
5010 result
= Fcons (XCAR (xdi
->name_list_element
), result
);
5015 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
5016 doc
: /* If ON is non-nil, report X errors as soon as the erring request is made.
5017 This function only has an effect on X Windows. With MS Windows, it is
5018 defined but does nothing.
5020 If ON is nil, allow buffering of requests.
5021 Turning on synchronization prohibits the Xlib routines from buffering
5022 requests and seriously degrades performance, but makes debugging much
5024 The optional second argument TERMINAL specifies which display to act on.
5025 TERMINAL should be a terminal object, a frame or a display name (a string).
5026 If TERMINAL is omitted or nil, that stands for the selected frame's display. */)
5027 (Lisp_Object on
, Lisp_Object terminal
)
5029 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
5031 XSynchronize (dpyinfo
->display
, !EQ (on
, Qnil
));
5036 /* Wait for responses to all X commands issued so far for frame F. */
5039 x_sync (struct frame
*f
)
5042 XSync (FRAME_X_DISPLAY (f
), False
);
5047 /***********************************************************************
5049 ***********************************************************************/
5051 DEFUN ("x-change-window-property", Fx_change_window_property
,
5052 Sx_change_window_property
, 2, 6, 0,
5053 doc
: /* Change window property PROP to VALUE on the X window of FRAME.
5054 PROP must be a string. VALUE may be a string or a list of conses,
5055 numbers and/or strings. If an element in the list is a string, it is
5056 converted to an atom and the value of the atom is used. If an element
5057 is a cons, it is converted to a 32 bit number where the car is the 16
5058 top bits and the cdr is the lower 16 bits.
5060 FRAME nil or omitted means use the selected frame.
5061 If TYPE is given and non-nil, it is the name of the type of VALUE.
5062 If TYPE is not given or nil, the type is STRING.
5063 FORMAT gives the size in bits of each element if VALUE is a list.
5064 It must be one of 8, 16 or 32.
5065 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
5066 If OUTER-P is non-nil, the property is changed for the outer X window of
5067 FRAME. Default is to change on the edit X window. */)
5068 (Lisp_Object prop
, Lisp_Object value
, Lisp_Object frame
,
5069 Lisp_Object type
, Lisp_Object format
, Lisp_Object outer_p
)
5071 struct frame
*f
= decode_window_system_frame (frame
);
5073 Atom target_type
= XA_STRING
;
5074 int element_format
= 8;
5075 unsigned char *data
;
5079 CHECK_STRING (prop
);
5081 if (! NILP (format
))
5083 CHECK_NUMBER (format
);
5085 if (XINT (format
) != 8 && XINT (format
) != 16
5086 && XINT (format
) != 32)
5087 error ("FORMAT must be one of 8, 16 or 32");
5088 element_format
= XINT (format
);
5095 nelements
= x_check_property_data (value
);
5096 if (nelements
== -1)
5097 error ("Bad data in VALUE, must be number, string or cons");
5099 /* The man page for XChangeProperty:
5100 "If the specified format is 32, the property data must be a
5102 This applies even if long is more than 32 bits. The X library
5103 converts to 32 bits before sending to the X server. */
5104 elsize
= element_format
== 32 ? sizeof (long) : element_format
>> 3;
5105 data
= xnmalloc (nelements
, elsize
);
5107 x_fill_property_data (FRAME_X_DISPLAY (f
), value
, data
, element_format
);
5113 CHECK_STRING (value
);
5114 data
= SDATA (value
);
5115 if (INT_MAX
< SBYTES (value
))
5116 error ("VALUE too long");
5118 /* See comment above about longs and format=32 */
5119 elsize
= element_format
== 32 ? sizeof (long) : element_format
>> 3;
5120 if (SBYTES (value
) % elsize
!= 0)
5121 error ("VALUE must contain an integral number of octets for FORMAT");
5122 nelements
= SBYTES (value
) / elsize
;
5126 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (prop
), False
);
5129 CHECK_STRING (type
);
5130 target_type
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (type
), False
);
5133 if (! NILP (outer_p
)) w
= FRAME_OUTER_WINDOW (f
);
5134 else w
= FRAME_X_WINDOW (f
);
5136 XChangeProperty (FRAME_X_DISPLAY (f
), w
,
5137 prop_atom
, target_type
, element_format
, PropModeReplace
,
5140 if (CONSP (value
)) xfree (data
);
5142 /* Make sure the property is set when we return. */
5143 XFlush (FRAME_X_DISPLAY (f
));
5150 DEFUN ("x-delete-window-property", Fx_delete_window_property
,
5151 Sx_delete_window_property
, 1, 2, 0,
5152 doc
: /* Remove window property PROP from X window of FRAME.
5153 FRAME nil or omitted means use the selected frame. Value is PROP. */)
5154 (Lisp_Object prop
, Lisp_Object frame
)
5156 struct frame
*f
= decode_window_system_frame (frame
);
5159 CHECK_STRING (prop
);
5161 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (prop
), False
);
5162 XDeleteProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), prop_atom
);
5164 /* Make sure the property is removed when we return. */
5165 XFlush (FRAME_X_DISPLAY (f
));
5173 x_window_property_intern (struct frame
*f
,
5174 Window target_window
,
5177 Lisp_Object delete_p
,
5178 Lisp_Object vector_ret_p
,
5181 unsigned char *tmp_data
= NULL
;
5182 Lisp_Object prop_value
= Qnil
;
5185 unsigned long actual_size
, bytes_remaining
;
5188 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), target_window
,
5189 prop_atom
, 0, 0, False
, target_type
,
5190 &actual_type
, &actual_format
, &actual_size
,
5191 &bytes_remaining
, &tmp_data
);
5193 *found
= actual_format
!= 0;
5195 if (rc
== Success
&& *found
)
5200 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), target_window
,
5201 prop_atom
, 0, bytes_remaining
,
5202 ! NILP (delete_p
), target_type
,
5203 &actual_type
, &actual_format
,
5204 &actual_size
, &bytes_remaining
,
5206 if (rc
== Success
&& tmp_data
)
5208 /* The man page for XGetWindowProperty says:
5209 "If the returned format is 32, the returned data is represented
5210 as a long array and should be cast to that type to obtain the
5212 This applies even if long is more than 32 bits, the X library
5213 converts from 32 bit elements received from the X server to long
5214 and passes the long array to us. Thus, for that case memcpy can not
5215 be used. We convert to a 32 bit type here, because so much code
5218 The bytes and offsets passed to XGetWindowProperty refers to the
5219 property and those are indeed in 32 bit quantities if format is
5222 if (LONG_WIDTH
> 32 && actual_format
== 32)
5225 int *idata
= (int *) tmp_data
;
5226 long *ldata
= (long *) tmp_data
;
5228 for (i
= 0; i
< actual_size
; ++i
)
5229 idata
[i
] = (int) ldata
[i
];
5232 if (NILP (vector_ret_p
))
5233 prop_value
= make_string ((char *) tmp_data
,
5234 (actual_format
>> 3) * actual_size
);
5236 prop_value
= x_property_data_to_lisp (f
,
5243 if (tmp_data
) XFree (tmp_data
);
5249 DEFUN ("x-window-property", Fx_window_property
, Sx_window_property
,
5251 doc
: /* Value is the value of window property PROP on FRAME.
5252 If FRAME is nil or omitted, use the selected frame.
5254 On X Windows, the following optional arguments are also accepted:
5255 If TYPE is nil or omitted, get the property as a string.
5256 Otherwise TYPE is the name of the atom that denotes the type expected.
5257 If SOURCE is non-nil, get the property on that window instead of from
5258 FRAME. The number 0 denotes the root window.
5259 If DELETE-P is non-nil, delete the property after retrieving it.
5260 If VECTOR-RET-P is non-nil, don't return a string but a vector of values.
5262 On MS Windows, this function accepts but ignores those optional arguments.
5264 Value is nil if FRAME hasn't a property with name PROP or if PROP has
5265 no value of TYPE (always string in the MS Windows case). */)
5266 (Lisp_Object prop
, Lisp_Object frame
, Lisp_Object type
,
5267 Lisp_Object source
, Lisp_Object delete_p
, Lisp_Object vector_ret_p
)
5269 struct frame
*f
= decode_window_system_frame (frame
);
5271 Lisp_Object prop_value
= Qnil
;
5272 Atom target_type
= XA_STRING
;
5273 Window target_window
= FRAME_X_WINDOW (f
);
5276 CHECK_STRING (prop
);
5278 if (! NILP (source
))
5280 CONS_TO_INTEGER (source
, Window
, target_window
);
5281 if (! target_window
)
5282 target_window
= FRAME_DISPLAY_INFO (f
)->root_window
;
5288 if (strcmp ("AnyPropertyType", SSDATA (type
)) == 0)
5289 target_type
= AnyPropertyType
;
5291 target_type
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (type
), False
);
5294 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (prop
), False
);
5295 prop_value
= x_window_property_intern (f
,
5302 if (NILP (prop_value
)
5305 && target_window
!= FRAME_OUTER_WINDOW (f
))
5307 prop_value
= x_window_property_intern (f
,
5308 FRAME_OUTER_WINDOW (f
),
5321 DEFUN ("x-window-property-attributes", Fx_window_property_attributes
, Sx_window_property_attributes
,
5323 doc
: /* Retrieve metadata about window property PROP on FRAME.
5324 If FRAME is nil or omitted, use the selected frame.
5325 If SOURCE is non-nil, get the property on that window instead of from
5326 FRAME. The number 0 denotes the root window.
5328 Return value is nil if FRAME hasn't a property with name PROP.
5329 Otherwise, the return value is a vector with the following fields:
5331 0. The property type, as an integer. The symbolic name of
5332 the type can be obtained with `x-get-atom-name'.
5333 1. The format of each element; one of 8, 16, or 32.
5334 2. The length of the property, in number of elements. */)
5335 (Lisp_Object prop
, Lisp_Object frame
, Lisp_Object source
)
5337 struct frame
*f
= decode_window_system_frame (frame
);
5338 Window target_window
= FRAME_X_WINDOW (f
);
5340 Lisp_Object prop_attr
= Qnil
;
5343 unsigned long actual_size
, bytes_remaining
;
5344 unsigned char *tmp_data
= NULL
;
5347 CHECK_STRING (prop
);
5349 if (! NILP (source
))
5351 CONS_TO_INTEGER (source
, Window
, target_window
);
5352 if (! target_window
)
5353 target_window
= FRAME_DISPLAY_INFO (f
)->root_window
;
5358 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (prop
), False
);
5359 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), target_window
,
5360 prop_atom
, 0, 0, False
, AnyPropertyType
,
5361 &actual_type
, &actual_format
, &actual_size
,
5362 &bytes_remaining
, &tmp_data
);
5363 if (rc
== Success
/* no invalid params */
5364 && actual_format
== 0 /* but prop not found */
5366 && target_window
!= FRAME_OUTER_WINDOW (f
))
5368 /* analogous behavior to x-window-property: if property isn't found
5369 on the frame's inner window and no alternate window id was
5370 provided, try the frame's outer window. */
5371 target_window
= FRAME_OUTER_WINDOW (f
);
5372 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), target_window
,
5373 prop_atom
, 0, 0, False
, AnyPropertyType
,
5374 &actual_type
, &actual_format
, &actual_size
,
5375 &bytes_remaining
, &tmp_data
);
5378 if (rc
== Success
&& actual_format
!= 0)
5382 prop_attr
= make_uninit_vector (3);
5383 ASET (prop_attr
, 0, make_number (actual_type
));
5384 ASET (prop_attr
, 1, make_number (actual_format
));
5385 ASET (prop_attr
, 2, make_number (bytes_remaining
/ (actual_format
>> 3)));
5392 /***********************************************************************
5394 ***********************************************************************/
5396 static void compute_tip_xy (struct frame
*, Lisp_Object
, Lisp_Object
,
5397 Lisp_Object
, int, int, int *, int *);
5399 /* The frame of a currently visible tooltip. */
5401 Lisp_Object tip_frame
;
5403 /* If non-nil, a timer started that hides the last tooltip when it
5406 static Lisp_Object tip_timer
;
5409 /* If non-nil, a vector of 3 elements containing the last args
5410 with which x-show-tip was called. See there. */
5412 static Lisp_Object last_show_tip_args
;
5416 unwind_create_tip_frame (Lisp_Object frame
)
5418 Lisp_Object deleted
;
5420 deleted
= unwind_create_frame (frame
);
5421 if (EQ (deleted
, Qt
))
5429 /* Create a frame for a tooltip on the display described by DPYINFO.
5430 PARMS is a list of frame parameters. TEXT is the string to
5431 display in the tip frame. Value is the frame.
5433 Note that functions called here, esp. x_default_parameter can
5434 signal errors, for instance when a specified color name is
5435 undefined. We have to make sure that we're in a consistent state
5436 when this happens. */
5439 x_create_tip_frame (struct x_display_info
*dpyinfo
, Lisp_Object parms
)
5445 ptrdiff_t count
= SPECPDL_INDEX ();
5446 bool face_change_before
= face_change
;
5447 int x_width
= 0, x_height
= 0;
5449 if (!dpyinfo
->terminal
->name
)
5450 error ("Terminal is not live, can't create new frames on it");
5452 parms
= Fcopy_alist (parms
);
5454 /* Get the name of the frame to use for resource lookup. */
5455 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
5457 && !EQ (name
, Qunbound
)
5459 error ("Invalid frame name--not a string or nil");
5462 f
= make_frame (false);
5463 f
->wants_modeline
= false;
5464 XSETFRAME (frame
, f
);
5465 record_unwind_protect (unwind_create_tip_frame
, frame
);
5467 f
->terminal
= dpyinfo
->terminal
;
5469 /* By setting the output method, we're essentially saying that
5470 the frame is live, as per FRAME_LIVE_P. If we get a signal
5471 from this point on, x_destroy_window might screw up reference
5473 f
->output_method
= output_x_window
;
5474 f
->output_data
.x
= xzalloc (sizeof *f
->output_data
.x
);
5475 f
->output_data
.x
->icon_bitmap
= -1;
5476 FRAME_FONTSET (f
) = -1;
5477 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
5478 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
5479 #if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
5480 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
5481 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
5482 #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
5483 f
->output_data
.x
->white_relief
.pixel
= -1;
5484 f
->output_data
.x
->black_relief
.pixel
= -1;
5486 fset_icon_name (f
, Qnil
);
5487 FRAME_DISPLAY_INFO (f
) = dpyinfo
;
5488 f
->output_data
.x
->parent_desc
= FRAME_DISPLAY_INFO (f
)->root_window
;
5489 f
->output_data
.x
->explicit_parent
= false;
5491 /* These colors will be set anyway later, but it's important
5492 to get the color reference counts right, so initialize them! */
5496 /* Function x_decode_color can signal an error. Make
5497 sure to initialize color slots so that we won't try
5498 to free colors we haven't allocated. */
5499 FRAME_FOREGROUND_PIXEL (f
) = -1;
5500 FRAME_BACKGROUND_PIXEL (f
) = -1;
5501 f
->output_data
.x
->cursor_pixel
= -1;
5502 f
->output_data
.x
->cursor_foreground_pixel
= -1;
5503 f
->output_data
.x
->border_pixel
= -1;
5504 f
->output_data
.x
->mouse_pixel
= -1;
5506 black
= build_string ("black");
5507 FRAME_FOREGROUND_PIXEL (f
)
5508 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
5509 FRAME_BACKGROUND_PIXEL (f
)
5510 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
5511 f
->output_data
.x
->cursor_pixel
5512 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
5513 f
->output_data
.x
->cursor_foreground_pixel
5514 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
5515 f
->output_data
.x
->border_pixel
5516 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
5517 f
->output_data
.x
->mouse_pixel
5518 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
5521 /* Set the name; the functions to which we pass f expect the name to
5523 if (EQ (name
, Qunbound
) || NILP (name
))
5525 fset_name (f
, build_string (dpyinfo
->x_id_name
));
5526 f
->explicit_name
= false;
5530 fset_name (f
, name
);
5531 f
->explicit_name
= true;
5532 /* use the frame's title when getting resources for this frame. */
5533 specbind (Qx_resource_name
, name
);
5537 register_font_driver (&ftcrfont_driver
, f
);
5539 register_font_driver (&xfont_driver
, f
);
5540 #ifdef HAVE_FREETYPE
5542 register_font_driver (&xftfont_driver
, f
);
5543 #else /* not HAVE_XFT */
5544 register_font_driver (&ftxfont_driver
, f
);
5545 #endif /* not HAVE_XFT */
5546 #endif /* HAVE_FREETYPE */
5547 #endif /* not USE_CAIRO */
5549 image_cache_refcount
=
5550 FRAME_IMAGE_CACHE (f
) ? FRAME_IMAGE_CACHE (f
)->refcount
: 0;
5552 dpyinfo_refcount
= dpyinfo
->reference_count
;
5553 #endif /* GLYPH_DEBUG */
5555 x_default_parameter (f
, parms
, Qfont_backend
, Qnil
,
5556 "fontBackend", "FontBackend", RES_TYPE_STRING
);
5558 /* Extract the window parameters from the supplied values that are
5559 needed to determine window geometry. */
5560 x_default_font_parameter (f
, parms
);
5562 x_default_parameter (f
, parms
, Qborder_width
, make_number (0),
5563 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
5565 /* This defaults to 2 in order to match xterm. We recognize either
5566 internalBorderWidth or internalBorder (which is what xterm calls
5568 if (NILP (Fassq (Qinternal_border_width
, parms
)))
5572 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
5573 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
5574 if (! EQ (value
, Qunbound
))
5575 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
5579 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
5580 "internalBorderWidth", "internalBorderWidth",
5582 x_default_parameter (f
, parms
, Qright_divider_width
, make_number (0),
5583 NULL
, NULL
, RES_TYPE_NUMBER
);
5584 x_default_parameter (f
, parms
, Qbottom_divider_width
, make_number (0),
5585 NULL
, NULL
, RES_TYPE_NUMBER
);
5587 /* Also do the stuff which must be set before the window exists. */
5588 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
5589 "foreground", "Foreground", RES_TYPE_STRING
);
5590 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
5591 "background", "Background", RES_TYPE_STRING
);
5592 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
5593 "pointerColor", "Foreground", RES_TYPE_STRING
);
5594 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
5595 "cursorColor", "Foreground", RES_TYPE_STRING
);
5596 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
5597 "borderColor", "BorderColor", RES_TYPE_STRING
);
5599 /* Init faces before x_default_parameter is called for the
5600 scroll-bar-width parameter because otherwise we end up in
5601 init_iterator with a null face cache, which should not happen. */
5602 init_frame_faces (f
);
5604 f
->output_data
.x
->parent_desc
= FRAME_DISPLAY_INFO (f
)->root_window
;
5606 x_figure_window_size (f
, parms
, false, &x_width
, &x_height
);
5609 XSetWindowAttributes attrs
;
5611 Atom type
= FRAME_DISPLAY_INFO (f
)->Xatom_net_window_type_tooltip
;
5614 mask
= CWBackPixel
| CWOverrideRedirect
| CWEventMask
| CWCursor
;
5615 if (DoesSaveUnders (dpyinfo
->screen
))
5616 mask
|= CWSaveUnder
;
5618 /* Window managers look at the override-redirect flag to determine
5619 whether or net to give windows a decoration (Xlib spec, chapter
5621 attrs
.override_redirect
= True
;
5622 attrs
.save_under
= True
;
5623 attrs
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
5625 f
->output_data
.x
->current_cursor
5626 = f
->output_data
.x
->text_cursor
;
5627 /* Arrange for getting MapNotify and UnmapNotify events. */
5628 attrs
.event_mask
= StructureNotifyMask
;
5630 = FRAME_X_WINDOW (f
)
5631 = XCreateWindow (FRAME_X_DISPLAY (f
),
5632 FRAME_DISPLAY_INFO (f
)->root_window
,
5633 /* x, y, width, height */
5637 CopyFromParent
, InputOutput
, CopyFromParent
,
5639 XChangeProperty (FRAME_X_DISPLAY (f
), tip_window
,
5640 FRAME_DISPLAY_INFO (f
)->Xatom_net_window_type
,
5641 XA_ATOM
, 32, PropModeReplace
,
5642 (unsigned char *)&type
, 1);
5648 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
5649 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
5650 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
5651 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
5652 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
5653 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
5654 x_default_parameter (f
, parms
, Qalpha
, Qnil
,
5655 "alpha", "Alpha", RES_TYPE_NUMBER
);
5657 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
5658 Change will not be effected unless different from the current
5660 width
= FRAME_COLS (f
);
5661 height
= FRAME_LINES (f
);
5662 SET_FRAME_COLS (f
, 0);
5663 SET_FRAME_LINES (f
, 0);
5664 change_frame_size (f
, width
, height
, true, false, false, false);
5666 /* Add `tooltip' frame parameter's default value. */
5667 if (NILP (Fframe_parameter (frame
, Qtooltip
)))
5669 AUTO_FRAME_ARG (arg
, Qtooltip
, Qt
);
5670 Fmodify_frame_parameters (frame
, arg
);
5673 /* FIXME - can this be done in a similar way to normal frames?
5674 http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
5676 /* Set the `display-type' frame parameter before setting up faces. */
5678 Lisp_Object disptype
;
5680 if (FRAME_DISPLAY_INFO (f
)->n_planes
== 1)
5682 else if (FRAME_DISPLAY_INFO (f
)->visual
->class == GrayScale
5683 || FRAME_DISPLAY_INFO (f
)->visual
->class == StaticGray
)
5684 disptype
= intern ("grayscale");
5686 disptype
= intern ("color");
5688 if (NILP (Fframe_parameter (frame
, Qdisplay_type
)))
5690 AUTO_FRAME_ARG (arg
, Qdisplay_type
, disptype
);
5691 Fmodify_frame_parameters (frame
, arg
);
5695 /* Set up faces after all frame parameters are known. This call
5696 also merges in face attributes specified for new frames.
5698 Frame parameters may be changed if .Xdefaults contains
5699 specifications for the default font. For example, if there is an
5700 `Emacs.default.attributeBackground: pink', the `background-color'
5701 attribute of the frame get's set, which let's the internal border
5702 of the tooltip frame appear in pink. Prevent this. */
5704 Lisp_Object bg
= Fframe_parameter (frame
, Qbackground_color
);
5706 call2 (Qface_set_after_frame_default
, frame
, Qnil
);
5708 if (!EQ (bg
, Fframe_parameter (frame
, Qbackground_color
)))
5710 AUTO_FRAME_ARG (arg
, Qbackground_color
, bg
);
5711 Fmodify_frame_parameters (frame
, arg
);
5717 /* Now that the frame will be official, it counts as a reference to
5718 its display and terminal. */
5719 FRAME_DISPLAY_INFO (f
)->reference_count
++;
5720 f
->terminal
->reference_count
++;
5722 /* It is now ok to make the frame official even if we get an error
5723 below. And the frame needs to be on Vframe_list or making it
5724 visible won't work. */
5725 Vframe_list
= Fcons (frame
, Vframe_list
);
5726 f
->can_x_set_window_size
= true;
5728 /* Setting attributes of faces of the tooltip frame from resources
5729 and similar will set face_change, which leads to the clearing of
5730 all current matrices. Since this isn't necessary here, avoid it
5731 by resetting face_change to the value it had before we created
5733 face_change
= face_change_before
;
5735 /* Discard the unwind_protect. */
5736 return unbind_to (count
, frame
);
5740 /* Compute where to display tip frame F. PARMS is the list of frame
5741 parameters for F. DX and DY are specified offsets from the current
5742 location of the mouse. WIDTH and HEIGHT are the width and height
5743 of the tooltip. Return coordinates relative to the root window of
5744 the display in *ROOT_X, and *ROOT_Y. */
5747 compute_tip_xy (struct frame
*f
, Lisp_Object parms
, Lisp_Object dx
, Lisp_Object dy
, int width
, int height
, int *root_x
, int *root_y
)
5749 Lisp_Object left
, top
, right
, bottom
;
5753 int min_x
, min_y
, max_x
, max_y
= -1;
5755 /* User-specified position? */
5756 left
= Fcdr (Fassq (Qleft
, parms
));
5757 top
= Fcdr (Fassq (Qtop
, parms
));
5758 right
= Fcdr (Fassq (Qright
, parms
));
5759 bottom
= Fcdr (Fassq (Qbottom
, parms
));
5761 /* Move the tooltip window where the mouse pointer is. Resize and
5763 if ((!INTEGERP (left
) && !INTEGERP (right
))
5764 || (!INTEGERP (top
) && !INTEGERP (bottom
)))
5766 Lisp_Object frame
, attributes
, monitor
, geometry
;
5769 XQueryPointer (FRAME_X_DISPLAY (f
), FRAME_DISPLAY_INFO (f
)->root_window
,
5770 &root
, &child
, root_x
, root_y
, &win_x
, &win_y
, &pmask
);
5773 XSETFRAME(frame
, f
);
5774 attributes
= Fx_display_monitor_attributes_list (frame
);
5776 /* Try to determine the monitor where the mouse pointer is and
5777 its geometry. See bug#22549. */
5778 while (CONSP (attributes
))
5780 monitor
= XCAR (attributes
);
5781 geometry
= Fassq (Qgeometry
, monitor
);
5782 if (CONSP (geometry
))
5784 min_x
= XINT (Fnth (make_number (1), geometry
));
5785 min_y
= XINT (Fnth (make_number (2), geometry
));
5786 max_x
= min_x
+ XINT (Fnth (make_number (3), geometry
));
5787 max_y
= min_y
+ XINT (Fnth (make_number (4), geometry
));
5788 if (min_x
<= *root_x
&& *root_x
< max_x
5789 && min_y
<= *root_y
&& *root_y
< max_y
)
5796 attributes
= XCDR (attributes
);
5800 /* It was not possible to determine the monitor's geometry, so we
5801 assign some sane defaults here: */
5806 max_x
= x_display_pixel_width (FRAME_DISPLAY_INFO (f
));
5807 max_y
= x_display_pixel_height (FRAME_DISPLAY_INFO (f
));
5811 *root_y
= XINT (top
);
5812 else if (INTEGERP (bottom
))
5813 *root_y
= XINT (bottom
) - height
;
5814 else if (*root_y
+ XINT (dy
) <= min_y
)
5815 *root_y
= min_y
; /* Can happen for negative dy */
5816 else if (*root_y
+ XINT (dy
) + height
<= max_y
)
5817 /* It fits below the pointer */
5818 *root_y
+= XINT (dy
);
5819 else if (height
+ XINT (dy
) + min_y
<= *root_y
)
5820 /* It fits above the pointer. */
5821 *root_y
-= height
+ XINT (dy
);
5823 /* Put it on the top. */
5826 if (INTEGERP (left
))
5827 *root_x
= XINT (left
);
5828 else if (INTEGERP (right
))
5829 *root_x
= XINT (right
) - width
;
5830 else if (*root_x
+ XINT (dx
) <= min_x
)
5831 *root_x
= 0; /* Can happen for negative dx */
5832 else if (*root_x
+ XINT (dx
) + width
<= max_x
)
5833 /* It fits to the right of the pointer. */
5834 *root_x
+= XINT (dx
);
5835 else if (width
+ XINT (dx
) + min_x
<= *root_x
)
5836 /* It fits to the left of the pointer. */
5837 *root_x
-= width
+ XINT (dx
);
5839 /* Put it left justified on the screen -- it ought to fit that way. */
5844 /* Hide tooltip. Delete its frame if DELETE is true. */
5846 x_hide_tip (bool delete)
5848 if (!NILP (tip_timer
))
5850 call1 (Qcancel_timer
, tip_timer
);
5855 if (NILP (tip_frame
)
5856 || (!delete && FRAMEP (tip_frame
)
5857 && !FRAME_VISIBLE_P (XFRAME (tip_frame
))))
5862 Lisp_Object was_open
= Qnil
;
5864 count
= SPECPDL_INDEX ();
5865 specbind (Qinhibit_redisplay
, Qt
);
5866 specbind (Qinhibit_quit
, Qt
);
5870 /* When using system tooltip, tip_frame is the Emacs frame on
5871 which the tip is shown. */
5872 struct frame
*f
= XFRAME (tip_frame
);
5874 if (FRAME_LIVE_P (f
) && xg_hide_tooltip (f
))
5882 if (FRAMEP (tip_frame
))
5886 delete_frame (tip_frame
, Qnil
);
5890 x_make_frame_invisible (XFRAME (tip_frame
));
5895 /* Bloodcurdling hack alert: The Lucid menu bar widget's
5896 redisplay procedure is not called when a tip frame over
5897 menu items is unmapped. Redisplay the menu manually... */
5900 struct frame
*f
= SELECTED_FRAME ();
5901 if (FRAME_X_P (f
) && FRAME_LIVE_P (f
))
5903 w
= f
->output_data
.x
->menubar_widget
;
5905 if (!DoesSaveUnders (FRAME_DISPLAY_INFO (f
)->screen
)
5909 xlwmenu_redisplay (w
);
5914 #endif /* USE_LUCID */
5919 return unbind_to (count
, was_open
);
5923 DEFUN ("x-show-tip", Fx_show_tip
, Sx_show_tip
, 1, 6, 0,
5924 doc
: /* Show STRING in a "tooltip" window on frame FRAME.
5925 A tooltip window is a small X window displaying a string.
5927 This is an internal function; Lisp code should call `tooltip-show'.
5929 FRAME nil or omitted means use the selected frame.
5931 PARMS is an optional list of frame parameters which can be used to
5932 change the tooltip's appearance.
5934 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
5935 means use the default timeout of 5 seconds.
5937 If the list of frame parameters PARMS contains a `left' parameter,
5938 display the tooltip at that x-position. If the list of frame parameters
5939 PARMS contains no `left' but a `right' parameter, display the tooltip
5940 right-adjusted at that x-position. Otherwise display it at the
5941 x-position of the mouse, with offset DX added (default is 5 if DX isn't
5944 Likewise for the y-position: If a `top' frame parameter is specified, it
5945 determines the position of the upper edge of the tooltip window. If a
5946 `bottom' parameter but no `top' frame parameter is specified, it
5947 determines the position of the lower edge of the tooltip window.
5948 Otherwise display the tooltip window at the y-position of the mouse,
5949 with offset DY added (default is -10).
5951 A tooltip's maximum size is specified by `x-max-tooltip-size'.
5952 Text larger than the specified size is clipped. */)
5953 (Lisp_Object string
, Lisp_Object frame
, Lisp_Object parms
, Lisp_Object timeout
, Lisp_Object dx
, Lisp_Object dy
)
5955 struct frame
*f
, *tip_f
;
5958 struct buffer
*old_buffer
;
5959 struct text_pos pos
;
5961 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
5962 ptrdiff_t count
= SPECPDL_INDEX ();
5964 Lisp_Object window
, size
;
5965 AUTO_STRING (tip
, " *tip*");
5967 specbind (Qinhibit_redisplay
, Qt
);
5969 CHECK_STRING (string
);
5970 if (SCHARS (string
) == 0)
5971 string
= make_unibyte_string (" ", 1);
5973 f
= decode_window_system_frame (frame
);
5975 timeout
= make_number (5);
5977 CHECK_NATNUM (timeout
);
5980 dx
= make_number (5);
5985 dy
= make_number (-10);
5990 if (x_gtk_use_system_tooltips
)
5994 /* Hide a previous tip, if any. */
5998 ok
= xg_prepare_tooltip (f
, string
, &width
, &height
);
6001 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, &root_x
, &root_y
);
6002 xg_show_tooltip (f
, root_x
, root_y
);
6003 /* This is used in Fx_hide_tip. */
6004 XSETFRAME (tip_frame
, f
);
6007 if (ok
) goto start_timer
;
6009 #endif /* USE_GTK */
6011 if (NILP (last_show_tip_args
))
6012 last_show_tip_args
= Fmake_vector (make_number (3), Qnil
);
6014 if (FRAMEP (tip_frame
) && FRAME_LIVE_P (XFRAME (tip_frame
)))
6016 Lisp_Object last_string
= AREF (last_show_tip_args
, 0);
6017 Lisp_Object last_frame
= AREF (last_show_tip_args
, 1);
6018 Lisp_Object last_parms
= AREF (last_show_tip_args
, 2);
6020 if (FRAME_VISIBLE_P (XFRAME (tip_frame
))
6021 && EQ (frame
, last_frame
)
6022 && !NILP (Fequal_including_properties (last_string
, string
))
6023 && !NILP (Fequal (last_parms
, parms
)))
6025 /* Only DX and DY have changed. */
6026 tip_f
= XFRAME (tip_frame
);
6027 if (!NILP (tip_timer
))
6029 Lisp_Object timer
= tip_timer
;
6032 call1 (Qcancel_timer
, timer
);
6036 compute_tip_xy (tip_f
, parms
, dx
, dy
, FRAME_PIXEL_WIDTH (tip_f
),
6037 FRAME_PIXEL_HEIGHT (tip_f
), &root_x
, &root_y
);
6038 XMoveWindow (FRAME_X_DISPLAY (tip_f
), FRAME_X_WINDOW (tip_f
),
6044 else if (tooltip_reuse_hidden_frame
&& EQ (frame
, last_frame
))
6046 bool delete = false;
6047 Lisp_Object tail
, elt
, parm
, last
;
6049 /* Check if every parameter in PARMS has the same value in
6050 last_parms unless it should be ignored by means of
6051 Vtooltip_reuse_hidden_frame_parameters. This may destruct
6052 last_parms which, however, will be recreated below. */
6053 for (tail
= parms
; CONSP (tail
); tail
= XCDR (tail
))
6057 /* The left, top, right and bottom parameters are handled
6058 by compute_tip_xy so they can be ignored here. */
6059 if (!EQ (parm
, Qleft
) && !EQ (parm
, Qtop
)
6060 && !EQ (parm
, Qright
) && !EQ (parm
, Qbottom
))
6062 last
= Fassq (parm
, last_parms
);
6063 if (NILP (Fequal (Fcdr (elt
), Fcdr (last
))))
6065 /* We lost, delete the old tooltip. */
6070 last_parms
= call2 (Qassq_delete_all
, parm
, last_parms
);
6073 last_parms
= call2 (Qassq_delete_all
, parm
, last_parms
);
6076 /* Now check if every parameter in what is left of last_parms
6077 with a non-nil value has an association in PARMS unless it
6078 should be ignored by means of
6079 Vtooltip_reuse_hidden_frame_parameters. */
6080 for (tail
= last_parms
; CONSP (tail
); tail
= XCDR (tail
))
6084 if (!EQ (parm
, Qleft
) && !EQ (parm
, Qtop
) && !EQ (parm
, Qright
)
6085 && !EQ (parm
, Qbottom
) && !NILP (Fcdr (elt
)))
6087 /* We lost, delete the old tooltip. */
6093 x_hide_tip (delete);
6101 ASET (last_show_tip_args
, 0, string
);
6102 ASET (last_show_tip_args
, 1, frame
);
6103 ASET (last_show_tip_args
, 2, parms
);
6105 if (!FRAMEP (tip_frame
) || !FRAME_LIVE_P (XFRAME (tip_frame
)))
6107 /* Add default values to frame parameters. */
6108 if (NILP (Fassq (Qname
, parms
)))
6109 parms
= Fcons (Fcons (Qname
, build_string ("tooltip")), parms
);
6110 if (NILP (Fassq (Qinternal_border_width
, parms
)))
6111 parms
= Fcons (Fcons (Qinternal_border_width
, make_number (3)), parms
);
6112 if (NILP (Fassq (Qborder_width
, parms
)))
6113 parms
= Fcons (Fcons (Qborder_width
, make_number (1)), parms
);
6114 if (NILP (Fassq (Qborder_color
, parms
)))
6115 parms
= Fcons (Fcons (Qborder_color
, build_string ("lightyellow")), parms
);
6116 if (NILP (Fassq (Qbackground_color
, parms
)))
6117 parms
= Fcons (Fcons (Qbackground_color
, build_string ("lightyellow")),
6120 /* Create a frame for the tooltip, and record it in the global
6121 variable tip_frame. */
6122 if (NILP (tip_frame
= x_create_tip_frame (FRAME_DISPLAY_INFO (f
), parms
)))
6123 /* Creating the tip frame failed. */
6124 return unbind_to (count
, Qnil
);
6127 tip_f
= XFRAME (tip_frame
);
6128 window
= FRAME_ROOT_WINDOW (tip_f
);
6129 set_window_buffer (window
, Fget_buffer_create (tip
), false, false);
6130 w
= XWINDOW (window
);
6131 w
->pseudo_window_p
= true;
6133 /* Set up the frame's root window. Note: The following code does not
6134 try to size the window or its frame correctly. Its only purpose is
6135 to make the subsequent text size calculations work. The right
6136 sizes should get installed when the toolkit gets back to us. */
6142 if (CONSP (Vx_max_tooltip_size
)
6143 && RANGED_INTEGERP (1, XCAR (Vx_max_tooltip_size
), INT_MAX
)
6144 && RANGED_INTEGERP (1, XCDR (Vx_max_tooltip_size
), INT_MAX
))
6146 w
->total_cols
= XFASTINT (XCAR (Vx_max_tooltip_size
));
6147 w
->total_lines
= XFASTINT (XCDR (Vx_max_tooltip_size
));
6152 w
->total_lines
= 40;
6155 w
->pixel_width
= w
->total_cols
* FRAME_COLUMN_WIDTH (tip_f
);
6156 w
->pixel_height
= w
->total_lines
* FRAME_LINE_HEIGHT (tip_f
);
6157 FRAME_TOTAL_COLS (tip_f
) = w
->total_cols
;
6158 adjust_frame_glyphs (tip_f
);
6160 /* Insert STRING into root window's buffer and fit the frame to the
6162 count_1
= SPECPDL_INDEX ();
6163 old_buffer
= current_buffer
;
6164 set_buffer_internal_1 (XBUFFER (w
->contents
));
6165 bset_truncate_lines (current_buffer
, Qnil
);
6166 specbind (Qinhibit_read_only
, Qt
);
6167 specbind (Qinhibit_modification_hooks
, Qt
);
6168 specbind (Qinhibit_point_motion_hooks
, Qt
);
6170 Finsert (1, &string
);
6171 clear_glyph_matrix (w
->desired_matrix
);
6172 clear_glyph_matrix (w
->current_matrix
);
6173 SET_TEXT_POS (pos
, BEGV
, BEGV_BYTE
);
6174 try_window (window
, pos
, TRY_WINDOW_IGNORE_FONTS_CHANGE
);
6175 /* Calculate size of tooltip window. */
6176 size
= Fwindow_text_pixel_size (window
, Qnil
, Qnil
, Qnil
,
6177 make_number (w
->pixel_height
), Qnil
);
6178 /* Add the frame's internal border to calculated size. */
6179 width
= XINT (Fcar (size
)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f
);
6180 height
= XINT (Fcdr (size
)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f
);
6182 /* Calculate position of tooltip frame. */
6183 compute_tip_xy (tip_f
, parms
, dx
, dy
, width
, height
, &root_x
, &root_y
);
6185 /* Show tooltip frame. */
6187 XMoveResizeWindow (FRAME_X_DISPLAY (tip_f
), FRAME_X_WINDOW (tip_f
),
6188 root_x
, root_y
, width
, height
);
6189 XMapRaised (FRAME_X_DISPLAY (tip_f
), FRAME_X_WINDOW (tip_f
));
6192 w
->must_be_updated_p
= true;
6193 update_single_window (w
);
6194 set_buffer_internal_1 (old_buffer
);
6195 unbind_to (count_1
, Qnil
);
6196 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
6199 /* Let the tip disappear after timeout seconds. */
6200 tip_timer
= call3 (intern ("run-at-time"), timeout
, Qnil
,
6201 intern ("x-hide-tip"));
6203 return unbind_to (count
, Qnil
);
6207 DEFUN ("x-hide-tip", Fx_hide_tip
, Sx_hide_tip
, 0, 0, 0,
6208 doc
: /* Hide the current tooltip window, if there is any.
6209 Value is t if tooltip was open, nil otherwise. */)
6212 return x_hide_tip (!tooltip_reuse_hidden_frame
);
6216 /***********************************************************************
6217 File selection dialog
6218 ***********************************************************************/
6220 DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog
,
6221 Sx_uses_old_gtk_dialog
,
6223 doc
: /* Return t if the old Gtk+ file selection dialog is used. */)
6229 && window_system_available (SELECTED_FRAME ())
6230 && xg_uses_old_file_dialog ())
6238 /* Callback for "OK" and "Cancel" on file selection dialog. */
6241 file_dialog_cb (Widget widget
, XtPointer client_data
, XtPointer call_data
)
6243 int *result
= client_data
;
6244 XmAnyCallbackStruct
*cb
= call_data
;
6245 *result
= cb
->reason
;
6249 /* Callback for unmapping a file selection dialog. This is used to
6250 capture the case where a dialog is closed via a window manager's
6251 closer button, for example. Using a XmNdestroyCallback didn't work
6255 file_dialog_unmap_cb (Widget widget
, XtPointer client_data
, XtPointer call_data
)
6257 int *result
= client_data
;
6258 *result
= XmCR_CANCEL
;
6262 clean_up_file_dialog (void *arg
)
6264 Widget dialog
= arg
;
6268 XtUnmanageChild (dialog
);
6269 XtDestroyWidget (dialog
);
6270 x_menu_set_in_use (false);
6275 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 5, 0,
6276 doc
: /* Read file name, prompting with PROMPT in directory DIR.
6277 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
6278 selection box, if specified. If MUSTMATCH is non-nil, the returned file
6279 or directory must exist.
6281 This function is only defined on NS, MS Windows, and X Windows with the
6282 Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
6283 Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.
6284 On Windows 7 and later, the file selection dialog "remembers" the last
6285 directory where the user selected a file, and will open that directory
6286 instead of DIR on subsequent invocations of this function with the same
6287 value of DIR as in previous invocations; this is standard Windows behavior. */)
6288 (Lisp_Object prompt
, Lisp_Object dir
, Lisp_Object default_filename
,
6289 Lisp_Object mustmatch
, Lisp_Object only_dir_p
)
6292 struct frame
*f
= SELECTED_FRAME ();
6293 Lisp_Object file
= Qnil
;
6294 Lisp_Object decoded_file
;
6295 Widget dialog
, text
, help
;
6298 XmString dir_xmstring
, pattern_xmstring
;
6299 ptrdiff_t count
= SPECPDL_INDEX ();
6301 check_window_system (f
);
6303 if (popup_activated ())
6304 error ("Trying to use a menu from within a menu-entry");
6306 CHECK_STRING (prompt
);
6309 /* Prevent redisplay. */
6310 specbind (Qinhibit_redisplay
, Qt
);
6314 /* Create the dialog with PROMPT as title, using DIR as initial
6315 directory and using "*" as pattern. */
6316 dir
= Fexpand_file_name (dir
, Qnil
);
6317 dir_xmstring
= XmStringCreateLocalized (SSDATA (dir
));
6318 pattern_xmstring
= XmStringCreateLocalized ("*");
6320 XtSetArg (al
[ac
], XmNtitle
, SDATA (prompt
)); ++ac
;
6321 XtSetArg (al
[ac
], XmNdirectory
, dir_xmstring
); ++ac
;
6322 XtSetArg (al
[ac
], XmNpattern
, pattern_xmstring
); ++ac
;
6323 XtSetArg (al
[ac
], XmNresizePolicy
, XmRESIZE_GROW
); ++ac
;
6324 XtSetArg (al
[ac
], XmNdialogStyle
, XmDIALOG_APPLICATION_MODAL
); ++ac
;
6325 dialog
= XmCreateFileSelectionDialog (f
->output_data
.x
->widget
,
6327 XmStringFree (dir_xmstring
);
6328 XmStringFree (pattern_xmstring
);
6330 /* Add callbacks for OK and Cancel. */
6331 XtAddCallback (dialog
, XmNokCallback
, file_dialog_cb
,
6332 (XtPointer
) &result
);
6333 XtAddCallback (dialog
, XmNcancelCallback
, file_dialog_cb
,
6334 (XtPointer
) &result
);
6335 XtAddCallback (dialog
, XmNunmapCallback
, file_dialog_unmap_cb
,
6336 (XtPointer
) &result
);
6338 /* Remove the help button since we can't display help. */
6339 help
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_HELP_BUTTON
);
6340 XtUnmanageChild (help
);
6342 /* Mark OK button as default. */
6343 XtVaSetValues (XmFileSelectionBoxGetChild (dialog
, XmDIALOG_OK_BUTTON
),
6344 XmNshowAsDefault
, True
, NULL
);
6346 /* If MUSTMATCH is non-nil, disable the file entry field of the
6347 dialog, so that the user must select a file from the files list
6348 box. We can't remove it because we wouldn't have a way to get at
6349 the result file name, then. */
6350 text
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
6351 if (!NILP (mustmatch
))
6354 label
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_SELECTION_LABEL
);
6355 XtSetSensitive (text
, False
);
6356 XtSetSensitive (label
, False
);
6359 /* Manage the dialog, so that list boxes get filled. */
6360 XtManageChild (dialog
);
6362 if (STRINGP (default_filename
))
6364 XmString default_xmstring
;
6365 Widget wtext
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
6366 Widget list
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_LIST
);
6368 XmTextPosition last_pos
= XmTextFieldGetLastPosition (wtext
);
6369 XmTextFieldReplace (wtext
, 0, last_pos
,
6370 (SSDATA (Ffile_name_nondirectory (default_filename
))));
6372 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
6373 must include the path for this to work. */
6375 default_xmstring
= XmStringCreateLocalized (SSDATA (default_filename
));
6377 if (XmListItemExists (list
, default_xmstring
))
6379 int item_pos
= XmListItemPos (list
, default_xmstring
);
6380 /* Select the item and scroll it into view. */
6381 XmListSelectPos (list
, item_pos
, True
);
6382 XmListSetPos (list
, item_pos
);
6385 XmStringFree (default_xmstring
);
6388 record_unwind_protect_ptr (clean_up_file_dialog
, dialog
);
6390 /* Process events until the user presses Cancel or OK. */
6391 x_menu_set_in_use (true);
6396 x_menu_wait_for_event (0);
6397 XtAppNextEvent (Xt_app_con
, &event
);
6398 if (event
.type
== KeyPress
6399 && FRAME_X_DISPLAY (f
) == event
.xkey
.display
)
6401 KeySym keysym
= XLookupKeysym (&event
.xkey
, 0);
6403 /* Pop down on C-g. */
6404 if (keysym
== XK_g
&& (event
.xkey
.state
& ControlMask
) != 0)
6405 XtUnmanageChild (dialog
);
6408 (void) x_dispatch_event (&event
, FRAME_X_DISPLAY (f
));
6411 /* Get the result. */
6412 if (result
== XmCR_OK
)
6414 XmString text_string
;
6417 XtVaGetValues (dialog
, XmNtextString
, &text_string
, NULL
);
6418 XmStringGetLtoR (text_string
, XmFONTLIST_DEFAULT_TAG
, &data
);
6419 XmStringFree (text_string
);
6420 file
= build_string (data
);
6428 /* Make "Cancel" equivalent to C-g. */
6432 decoded_file
= DECODE_FILE (file
);
6434 return unbind_to (count
, decoded_file
);
6437 #endif /* USE_MOTIF */
6442 clean_up_dialog (void)
6444 x_menu_set_in_use (false);
6447 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 5, 0,
6448 doc
: /* Read file name, prompting with PROMPT in directory DIR.
6449 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
6450 selection box, if specified. If MUSTMATCH is non-nil, the returned file
6451 or directory must exist.
6453 This function is only defined on NS, MS Windows, and X Windows with the
6454 Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
6455 Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.
6456 On Windows 7 and later, the file selection dialog "remembers" the last
6457 directory where the user selected a file, and will open that directory
6458 instead of DIR on subsequent invocations of this function with the same
6459 value of DIR as in previous invocations; this is standard Windows behavior. */)
6460 (Lisp_Object prompt
, Lisp_Object dir
, Lisp_Object default_filename
, Lisp_Object mustmatch
, Lisp_Object only_dir_p
)
6462 struct frame
*f
= SELECTED_FRAME ();
6464 Lisp_Object file
= Qnil
;
6465 Lisp_Object decoded_file
;
6466 ptrdiff_t count
= SPECPDL_INDEX ();
6469 check_window_system (f
);
6471 if (popup_activated ())
6472 error ("Trying to use a menu from within a menu-entry");
6474 CHECK_STRING (prompt
);
6477 /* Prevent redisplay. */
6478 specbind (Qinhibit_redisplay
, Qt
);
6479 record_unwind_protect_void (clean_up_dialog
);
6483 if (STRINGP (default_filename
))
6484 cdef_file
= SSDATA (default_filename
);
6486 cdef_file
= SSDATA (dir
);
6488 fn
= xg_get_file_name (f
, SSDATA (prompt
), cdef_file
,
6490 ! NILP (only_dir_p
));
6494 file
= build_string (fn
);
6500 /* Make "Cancel" equivalent to C-g. */
6504 decoded_file
= DECODE_FILE (file
);
6506 return unbind_to (count
, decoded_file
);
6510 #ifdef HAVE_FREETYPE
6512 DEFUN ("x-select-font", Fx_select_font
, Sx_select_font
, 0, 2, 0,
6513 doc
: /* Read a font using a GTK dialog.
6514 Return either a font spec (for GTK versions >= 3.2) or a string
6515 containing a GTK-style font name.
6517 FRAME is the frame on which to pop up the font chooser. If omitted or
6518 nil, it defaults to the selected frame. */)
6519 (Lisp_Object frame
, Lisp_Object ignored
)
6521 struct frame
*f
= decode_window_system_frame (frame
);
6523 Lisp_Object font_param
;
6524 char *default_name
= NULL
;
6525 ptrdiff_t count
= SPECPDL_INDEX ();
6527 if (popup_activated ())
6528 error ("Trying to use a menu from within a menu-entry");
6530 /* Prevent redisplay. */
6531 specbind (Qinhibit_redisplay
, Qt
);
6532 record_unwind_protect_void (clean_up_dialog
);
6536 XSETFONT (font
, FRAME_FONT (f
));
6537 font_param
= Ffont_get (font
, QCname
);
6538 if (STRINGP (font_param
))
6539 default_name
= xlispstrdup (font_param
);
6542 font_param
= Fframe_parameter (frame
, Qfont_parameter
);
6543 if (STRINGP (font_param
))
6544 default_name
= xlispstrdup (font_param
);
6547 font
= xg_get_font (f
, default_name
);
6548 xfree (default_name
);
6555 return unbind_to (count
, font
);
6557 #endif /* HAVE_FREETYPE */
6559 #endif /* USE_GTK */
6562 /***********************************************************************
6564 ***********************************************************************/
6567 #include <X11/XKBlib.h>
6568 #include <X11/keysym.h>
6571 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p
,
6572 Sx_backspace_delete_keys_p
, 0, 1, 0,
6573 doc
: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
6574 FRAME nil means use the selected frame.
6575 Value is t if we know that both keys are present, and are mapped to the
6576 usual X keysyms. Value is `lambda' if we cannot determine if both keys are
6577 present and mapped to the usual X keysyms. */)
6584 struct frame
*f
= decode_window_system_frame (frame
);
6585 Display
*dpy
= FRAME_X_DISPLAY (f
);
6586 Lisp_Object have_keys
;
6587 int major
, minor
, op
, event
, error_code
;
6591 /* Check library version in case we're dynamically linked. */
6592 major
= XkbMajorVersion
;
6593 minor
= XkbMinorVersion
;
6594 if (!XkbLibraryVersion (&major
, &minor
))
6600 /* Check that the server supports XKB. */
6601 major
= XkbMajorVersion
;
6602 minor
= XkbMinorVersion
;
6603 if (!XkbQueryExtension (dpy
, &op
, &event
, &error_code
, &major
, &minor
))
6609 /* In this code we check that the keyboard has physical keys with names
6610 that start with BKSP (Backspace) and DELE (Delete), and that they
6611 generate keysym XK_BackSpace and XK_Delete respectively.
6612 This function is used to test if normal-erase-is-backspace should be
6614 An alternative approach would be to just check if XK_BackSpace and
6615 XK_Delete are mapped to any key. But if any of those are mapped to
6616 some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the
6617 user doesn't know about it, it is better to return false here.
6618 It is more obvious to the user what to do if she/he has two keys
6619 clearly marked with names/symbols and one key does something not
6620 expected (i.e. she/he then tries the other).
6621 The cases where Backspace/Delete is mapped to some other key combination
6622 are rare, and in those cases, normal-erase-is-backspace can be turned on
6626 kb
= XkbGetMap (dpy
, XkbAllMapComponentsMask
, XkbUseCoreKbd
);
6629 int delete_keycode
= 0, backspace_keycode
= 0, i
;
6631 if (XkbGetNames (dpy
, XkbAllNamesMask
, kb
) == Success
)
6633 for (i
= kb
->min_key_code
;
6634 (i
< kb
->max_key_code
6635 && (delete_keycode
== 0 || backspace_keycode
== 0));
6638 /* The XKB symbolic key names can be seen most easily in
6639 the PS file generated by `xkbprint -label name
6641 if (memcmp ("DELE", kb
->names
->keys
[i
].name
, 4) == 0)
6643 else if (memcmp ("BKSP", kb
->names
->keys
[i
].name
, 4) == 0)
6644 backspace_keycode
= i
;
6647 XkbFreeNames (kb
, 0, True
);
6650 /* As of libX11-1.6.2, XkbGetMap manual says that you should use
6651 XkbFreeClientMap to free the data returned by XkbGetMap. But
6652 this function just frees the data referenced from KB and not
6653 KB itself. To free KB as well, call XkbFreeKeyboard. */
6654 XkbFreeKeyboard (kb
, XkbAllMapComponentsMask
, True
);
6657 && backspace_keycode
6658 && XKeysymToKeycode (dpy
, XK_Delete
) == delete_keycode
6659 && XKeysymToKeycode (dpy
, XK_BackSpace
) == backspace_keycode
)
6669 /***********************************************************************
6671 ***********************************************************************/
6674 DEFUN ("x-export-frames", Fx_export_frames
, Sx_export_frames
, 0, 2, 0,
6675 doc
: /* Return image data of FRAMES in TYPE format.
6676 FRAMES should be nil (the selected frame), a frame, or a list of
6677 frames (each of which corresponds to one page). Each frame should be
6678 visible. Optional arg TYPE should be either `pdf' (default), `png',
6679 `postscript', or `svg'. Supported types are determined by the
6680 compile-time configuration of cairo. */)
6681 (Lisp_Object frames
, Lisp_Object type
)
6683 Lisp_Object rest
, tmp
;
6684 cairo_surface_type_t surface_type
;
6686 if (!CONSP (frames
))
6687 frames
= list1 (frames
);
6690 for (rest
= frames
; CONSP (rest
); rest
= XCDR (rest
))
6692 struct frame
*f
= decode_window_system_frame (XCAR (rest
));
6695 XSETFRAME (frame
, f
);
6696 if (!FRAME_VISIBLE_P (f
))
6697 error ("Frames to be exported must be visible.");
6698 tmp
= Fcons (frame
, tmp
);
6700 frames
= Fnreverse (tmp
);
6702 #ifdef CAIRO_HAS_PDF_SURFACE
6703 if (NILP (type
) || EQ (type
, Qpdf
))
6704 surface_type
= CAIRO_SURFACE_TYPE_PDF
;
6707 #ifdef CAIRO_HAS_PNG_FUNCTIONS
6708 if (EQ (type
, Qpng
))
6710 if (!NILP (XCDR (frames
)))
6711 error ("PNG export cannot handle multiple frames.");
6712 surface_type
= CAIRO_SURFACE_TYPE_IMAGE
;
6716 #ifdef CAIRO_HAS_PS_SURFACE
6717 if (EQ (type
, Qpostscript
))
6718 surface_type
= CAIRO_SURFACE_TYPE_PS
;
6721 #ifdef CAIRO_HAS_SVG_SURFACE
6722 if (EQ (type
, Qsvg
))
6724 /* For now, we stick to SVG 1.1. */
6725 if (!NILP (XCDR (frames
)))
6726 error ("SVG export cannot handle multiple frames.");
6727 surface_type
= CAIRO_SURFACE_TYPE_SVG
;
6731 error ("Unsupported export type");
6733 return x_cr_export_frames (frames
, surface_type
);
6737 DEFUN ("x-page-setup-dialog", Fx_page_setup_dialog
, Sx_page_setup_dialog
, 0, 0, 0,
6738 doc
: /* Pop up a page setup dialog.
6739 The current page setup can be obtained using `x-get-page-setup'. */)
6743 xg_page_setup_dialog ();
6749 DEFUN ("x-get-page-setup", Fx_get_page_setup
, Sx_get_page_setup
, 0, 0, 0,
6750 doc
: /* Return the value of the current page setup.
6751 The return value is an alist containing the following keys:
6753 orientation: page orientation (symbol `portrait', `landscape',
6754 `reverse-portrait', or `reverse-landscape').
6755 width, height: page width/height in points not including margins.
6756 left-margin, right-margin, top-margin, bottom-margin: print margins,
6757 which is the parts of the page that the printer cannot print
6760 The paper width can be obtained as the sum of width, left-margin, and
6761 right-margin values if the page orientation is `portrait' or
6762 `reverse-portrait'. Otherwise, it is the sum of width, top-margin,
6763 and bottom-margin values. Likewise, the paper height is the sum of
6764 height, top-margin, and bottom-margin values if the page orientation
6765 is `portrait' or `reverse-portrait'. Otherwise, it is the sum of
6766 height, left-margin, and right-margin values. */)
6772 result
= xg_get_page_setup ();
6778 DEFUN ("x-print-frames-dialog", Fx_print_frames_dialog
, Sx_print_frames_dialog
, 0, 1, "",
6779 doc
: /* Pop up a print dialog to print the current contents of FRAMES.
6780 FRAMES should be nil (the selected frame), a frame, or a list of
6781 frames (each of which corresponds to one page). Each frame should be
6783 (Lisp_Object frames
)
6785 Lisp_Object rest
, tmp
;
6788 if (!CONSP (frames
))
6789 frames
= list1 (frames
);
6792 for (rest
= frames
; CONSP (rest
); rest
= XCDR (rest
))
6794 struct frame
*f
= decode_window_system_frame (XCAR (rest
));
6797 XSETFRAME (frame
, f
);
6798 if (!FRAME_VISIBLE_P (f
))
6799 error ("Frames to be printed must be visible.");
6800 tmp
= Fcons (frame
, tmp
);
6802 frames
= Fnreverse (tmp
);
6804 /* Make sure the current matrices are up-to-date. */
6805 count
= SPECPDL_INDEX ();
6806 specbind (Qredisplay_dont_pause
, Qt
);
6807 redisplay_preserve_echo_area (32);
6808 unbind_to (count
, Qnil
);
6811 xg_print_frames_dialog (frames
);
6816 #endif /* USE_GTK */
6817 #endif /* USE_CAIRO */
6820 /***********************************************************************
6822 ***********************************************************************/
6824 /* Keep this list in the same order as frame_parms in frame.c.
6825 Use 0 for unsupported frame parameters. */
6827 frame_parm_handler x_frame_parm_handlers
[] =
6831 x_set_background_color
,
6837 x_set_foreground_color
,
6840 x_set_internal_border_width
,
6841 x_set_right_divider_width
,
6842 x_set_bottom_divider_width
,
6843 x_set_menu_bar_lines
,
6845 x_explicitly_set_name
,
6846 x_set_scroll_bar_width
,
6847 x_set_scroll_bar_height
,
6850 x_set_vertical_scroll_bars
,
6851 x_set_horizontal_scroll_bars
,
6853 x_set_tool_bar_lines
,
6854 x_set_scroll_bar_foreground
,
6855 x_set_scroll_bar_background
,
6865 x_set_tool_bar_position
,
6871 DEFSYM (Qundefined_color
, "undefined-color");
6872 DEFSYM (Qcompound_text
, "compound-text");
6873 DEFSYM (Qcancel_timer
, "cancel-timer");
6874 DEFSYM (Qfont_parameter
, "font-parameter");
6875 DEFSYM (Qmono
, "mono");
6876 DEFSYM (Qassq_delete_all
, "assq-delete-all");
6879 DEFSYM (Qpdf
, "pdf");
6881 DEFSYM (Qorientation
, "orientation");
6882 DEFSYM (Qtop_margin
, "top-margin");
6883 DEFSYM (Qbottom_margin
, "bottom-margin");
6884 DEFSYM (Qportrait
, "portrait");
6885 DEFSYM (Qlandscape
, "landscape");
6886 DEFSYM (Qreverse_portrait
, "reverse-portrait");
6887 DEFSYM (Qreverse_landscape
, "reverse-landscape");
6890 Fput (Qundefined_color
, Qerror_conditions
,
6891 listn (CONSTYPE_PURE
, 2, Qundefined_color
, Qerror
));
6892 Fput (Qundefined_color
, Qerror_message
,
6893 build_pure_c_string ("Undefined color"));
6895 DEFVAR_LISP ("x-pointer-shape", Vx_pointer_shape
,
6896 doc
: /* The shape of the pointer when over text.
6897 Changing the value does not affect existing frames
6898 unless you set the mouse color. */);
6899 Vx_pointer_shape
= Qnil
;
6901 #if false /* This doesn't really do anything. */
6902 DEFVAR_LISP ("x-nontext-pointer-shape", Vx_nontext_pointer_shape
,
6903 doc
: /* The shape of the pointer when not over text.
6904 This variable takes effect when you create a new frame
6905 or when you set the mouse color. */);
6907 Vx_nontext_pointer_shape
= Qnil
;
6909 DEFVAR_LISP ("x-hourglass-pointer-shape", Vx_hourglass_pointer_shape
,
6910 doc
: /* The shape of the pointer when Emacs is busy.
6911 This variable takes effect when you create a new frame
6912 or when you set the mouse color. */);
6913 Vx_hourglass_pointer_shape
= Qnil
;
6915 #if false /* This doesn't really do anything. */
6916 DEFVAR_LISP ("x-mode-pointer-shape", Vx_mode_pointer_shape
,
6917 doc
: /* The shape of the pointer when over the mode line.
6918 This variable takes effect when you create a new frame
6919 or when you set the mouse color. */);
6921 Vx_mode_pointer_shape
= Qnil
;
6923 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
6924 Vx_sensitive_text_pointer_shape
,
6925 doc
: /* The shape of the pointer when over mouse-sensitive text.
6926 This variable takes effect when you create a new frame
6927 or when you set the mouse color. */);
6928 Vx_sensitive_text_pointer_shape
= Qnil
;
6930 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
6931 Vx_window_horizontal_drag_shape
,
6932 doc
: /* Pointer shape to use for indicating a window can be dragged horizontally.
6933 This variable takes effect when you create a new frame
6934 or when you set the mouse color. */);
6935 Vx_window_horizontal_drag_shape
= Qnil
;
6937 DEFVAR_LISP ("x-window-vertical-drag-cursor",
6938 Vx_window_vertical_drag_shape
,
6939 doc
: /* Pointer shape to use for indicating a window can be dragged vertically.
6940 This variable takes effect when you create a new frame
6941 or when you set the mouse color. */);
6942 Vx_window_vertical_drag_shape
= Qnil
;
6944 DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel
,
6945 doc
: /* A string indicating the foreground color of the cursor box. */);
6946 Vx_cursor_fore_pixel
= Qnil
;
6948 DEFVAR_LISP ("x-max-tooltip-size", Vx_max_tooltip_size
,
6949 doc
: /* Maximum size for tooltips.
6950 Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */);
6951 Vx_max_tooltip_size
= Fcons (make_number (80), make_number (40));
6953 DEFVAR_LISP ("x-no-window-manager", Vx_no_window_manager
,
6954 doc
: /* Non-nil if no X window manager is in use.
6955 Emacs doesn't try to figure this out; this is always nil
6956 unless you set it to something else. */);
6957 /* We don't have any way to find this out, so set it to nil
6958 and maybe the user would like to set it to t. */
6959 Vx_no_window_manager
= Qnil
;
6961 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
6962 Vx_pixel_size_width_font_regexp
,
6963 doc
: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
6965 Since Emacs gets width of a font matching with this regexp from
6966 PIXEL_SIZE field of the name, font finding mechanism gets faster for
6967 such a font. This is especially effective for such large fonts as
6968 Chinese, Japanese, and Korean. */);
6969 Vx_pixel_size_width_font_regexp
= Qnil
;
6971 /* This is not ifdef:ed, so other builds than GTK can customize it. */
6972 DEFVAR_BOOL ("x-gtk-use-old-file-dialog", x_gtk_use_old_file_dialog
,
6973 doc
: /* Non-nil means prompt with the old GTK file selection dialog.
6974 If nil or if the file selection dialog is not available, the new GTK file
6975 chooser is used instead. To turn off all file dialogs set the
6976 variable `use-file-dialog'. */);
6977 x_gtk_use_old_file_dialog
= false;
6979 DEFVAR_BOOL ("x-gtk-show-hidden-files", x_gtk_show_hidden_files
,
6980 doc
: /* If non-nil, the GTK file chooser will by default show hidden files.
6981 Note that this is just the default, there is a toggle button on the file
6982 chooser to show or not show hidden files on a case by case basis. */);
6983 x_gtk_show_hidden_files
= false;
6985 DEFVAR_BOOL ("x-gtk-file-dialog-help-text", x_gtk_file_dialog_help_text
,
6986 doc
: /* If non-nil, the GTK file chooser will show additional help text.
6987 If more space for files in the file chooser dialog is wanted, set this to nil
6988 to turn the additional text off. */);
6989 x_gtk_file_dialog_help_text
= true;
6991 DEFVAR_BOOL ("x-gtk-use-system-tooltips", x_gtk_use_system_tooltips
,
6992 doc
: /* If non-nil with a Gtk+ built Emacs, the Gtk+ tooltip is used.
6993 Otherwise use Emacs own tooltip implementation.
6994 When using Gtk+ tooltips, the tooltip face is not used. */);
6995 x_gtk_use_system_tooltips
= true;
6997 /* Tell Emacs about this window system. */
6998 Fprovide (Qx
, Qnil
);
7000 #ifdef USE_X_TOOLKIT
7001 Fprovide (intern_c_string ("x-toolkit"), Qnil
);
7003 Fprovide (intern_c_string ("motif"), Qnil
);
7005 DEFVAR_LISP ("motif-version-string", Vmotif_version_string
,
7006 doc
: /* Version info for LessTif/Motif. */);
7007 Vmotif_version_string
= build_string (XmVERSION_STRING
);
7008 #endif /* USE_MOTIF */
7009 #endif /* USE_X_TOOLKIT */
7012 /* Provide x-toolkit also for GTK. Internally GTK does not use Xt so it
7013 is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
7014 But for a user it is a toolkit for X, and indeed, configure
7015 accepts --with-x-toolkit=gtk. */
7016 Fprovide (intern_c_string ("x-toolkit"), Qnil
);
7017 Fprovide (intern_c_string ("gtk"), Qnil
);
7018 Fprovide (intern_c_string ("move-toolbar"), Qnil
);
7020 DEFVAR_LISP ("gtk-version-string", Vgtk_version_string
,
7021 doc
: /* Version info for GTK+. */);
7023 char gtk_version
[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
7024 int len
= sprintf (gtk_version
, "%d.%d.%d",
7025 GTK_MAJOR_VERSION
, GTK_MINOR_VERSION
, GTK_MICRO_VERSION
);
7026 Vgtk_version_string
= make_pure_string (gtk_version
, len
, len
, false);
7028 #endif /* USE_GTK */
7031 Fprovide (intern_c_string ("cairo"), Qnil
);
7033 DEFVAR_LISP ("cairo-version-string", Vcairo_version_string
,
7034 doc
: /* Version info for cairo. */);
7036 char cairo_version
[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
7037 int len
= sprintf (cairo_version
, "%d.%d.%d",
7038 CAIRO_VERSION_MAJOR
, CAIRO_VERSION_MINOR
,
7039 CAIRO_VERSION_MICRO
);
7040 Vcairo_version_string
= make_pure_string (cairo_version
, len
, len
, false);
7044 /* X window properties. */
7045 defsubr (&Sx_change_window_property
);
7046 defsubr (&Sx_delete_window_property
);
7047 defsubr (&Sx_window_property
);
7048 defsubr (&Sx_window_property_attributes
);
7050 defsubr (&Sxw_display_color_p
);
7051 defsubr (&Sx_display_grayscale_p
);
7052 defsubr (&Sxw_color_defined_p
);
7053 defsubr (&Sxw_color_values
);
7054 defsubr (&Sx_server_max_request_size
);
7055 defsubr (&Sx_server_vendor
);
7056 defsubr (&Sx_server_version
);
7057 defsubr (&Sx_display_pixel_width
);
7058 defsubr (&Sx_display_pixel_height
);
7059 defsubr (&Sx_display_mm_width
);
7060 defsubr (&Sx_display_mm_height
);
7061 defsubr (&Sx_display_screens
);
7062 defsubr (&Sx_display_planes
);
7063 defsubr (&Sx_display_color_cells
);
7064 defsubr (&Sx_display_visual_class
);
7065 defsubr (&Sx_display_backing_store
);
7066 defsubr (&Sx_display_save_under
);
7067 defsubr (&Sx_display_monitor_attributes_list
);
7068 defsubr (&Sx_frame_geometry
);
7069 defsubr (&Sx_frame_edges
);
7070 defsubr (&Sx_mouse_absolute_pixel_position
);
7071 defsubr (&Sx_set_mouse_absolute_pixel_position
);
7072 defsubr (&Sx_wm_set_size_hint
);
7073 defsubr (&Sx_create_frame
);
7074 defsubr (&Sx_open_connection
);
7075 defsubr (&Sx_close_connection
);
7076 defsubr (&Sx_display_list
);
7077 defsubr (&Sx_synchronize
);
7078 defsubr (&Sx_backspace_delete_keys_p
);
7080 defsubr (&Sx_show_tip
);
7081 defsubr (&Sx_hide_tip
);
7083 staticpro (&tip_timer
);
7085 staticpro (&tip_frame
);
7087 last_show_tip_args
= Qnil
;
7088 staticpro (&last_show_tip_args
);
7090 defsubr (&Sx_uses_old_gtk_dialog
);
7091 #if defined (USE_MOTIF) || defined (USE_GTK)
7092 defsubr (&Sx_file_dialog
);
7095 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
7096 defsubr (&Sx_select_font
);
7100 defsubr (&Sx_export_frames
);
7102 defsubr (&Sx_page_setup_dialog
);
7103 defsubr (&Sx_get_page_setup
);
7104 defsubr (&Sx_print_frames_dialog
);