1 /* Functions for the X window system.
3 Copyright (C) 1989, 1992-2015 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
30 #include "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 #if !defined (NO_EDITRES)
96 extern void _XEditResCheckMessages (Widget
, XtPointer
, XEvent
*, Boolean
*);
97 #endif /* not defined NO_EDITRES */
99 /* Unique id counter for widgets created by the Lucid Widget Library. */
101 extern LWLIB_ID widget_id_tick
;
105 #endif /* USE_MOTIF */
107 #endif /* USE_X_TOOLKIT */
113 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
115 static ptrdiff_t image_cache_refcount
;
117 static int dpyinfo_refcount
;
120 static struct x_display_info
*x_display_info_for_name (Lisp_Object
);
122 /* Let the user specify an X display with a Lisp object.
123 OBJECT may be nil, a frame or a terminal object.
124 nil stands for the selected frame--or, if that is not an X frame,
125 the first X display on the list. */
127 struct x_display_info
*
128 check_x_display_info (Lisp_Object object
)
130 struct x_display_info
*dpyinfo
= NULL
;
134 struct frame
*sf
= XFRAME (selected_frame
);
136 if (FRAME_X_P (sf
) && FRAME_LIVE_P (sf
))
137 dpyinfo
= FRAME_DISPLAY_INFO (sf
);
138 else if (x_display_list
!= 0)
139 dpyinfo
= x_display_list
;
141 error ("X windows are not in use or not initialized");
143 else if (TERMINALP (object
))
145 struct terminal
*t
= decode_live_terminal (object
);
147 if (t
->type
!= output_x_window
)
148 error ("Terminal %d is not an X display", t
->id
);
150 dpyinfo
= t
->display_info
.x
;
152 else if (STRINGP (object
))
153 dpyinfo
= x_display_info_for_name (object
);
156 struct frame
*f
= decode_window_system_frame (object
);
157 dpyinfo
= FRAME_DISPLAY_INFO (f
);
163 /* Return the screen positions and offsets of frame F.
164 Store the offsets between FRAME_OUTER_WINDOW and the containing
165 window manager window into LEFT_OFFSET_X, RIGHT_OFFSET_X,
166 TOP_OFFSET_Y and BOTTOM_OFFSET_Y.
167 Store the offsets between FRAME_X_WINDOW and the containing
168 window manager window into X_PIXELS_DIFF and Y_PIXELS_DIFF.
169 Store the screen positions of frame F into XPTR and YPTR.
170 These are the positions of the containing window manager window,
171 not Emacs's own window. */
173 x_real_pos_and_offsets (struct frame
*f
,
177 int *bottom_offset_y
,
184 int win_x
, win_y
, outer_x
IF_LINT (= 0), outer_y
IF_LINT (= 0);
185 int real_x
= 0, real_y
= 0;
186 bool had_errors
= false;
187 Window win
= f
->output_data
.x
->parent_desc
;
189 unsigned long actual_size
, bytes_remaining
;
190 int rc
, actual_format
;
191 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
193 Display
*dpy
= FRAME_X_DISPLAY (f
);
194 unsigned char *tmp_data
= NULL
;
195 Atom target_type
= XA_CARDINAL
;
196 unsigned int ow
IF_LINT (= 0), oh
IF_LINT (= 0);
200 x_catch_errors (dpy
);
202 if (x_pixels_diff
) *x_pixels_diff
= 0;
203 if (y_pixels_diff
) *y_pixels_diff
= 0;
204 if (left_offset_x
) *left_offset_x
= 0;
205 if (top_offset_y
) *top_offset_y
= 0;
206 if (right_offset_x
) *right_offset_x
= 0;
207 if (bottom_offset_y
) *bottom_offset_y
= 0;
210 if (outer_border
) *outer_border
= 0;
212 if (win
== dpyinfo
->root_window
)
213 win
= FRAME_OUTER_WINDOW (f
);
215 /* This loop traverses up the containment tree until we hit the root
216 window. Window managers may intersect many windows between our window
217 and the root window. The window we find just before the root window
218 should be the outer WM window. */
221 Window wm_window
, rootw
;
222 Window
*tmp_children
;
223 unsigned int tmp_nchildren
;
226 success
= XQueryTree (FRAME_X_DISPLAY (f
), win
, &rootw
,
227 &wm_window
, &tmp_children
, &tmp_nchildren
);
229 had_errors
= x_had_errors_p (FRAME_X_DISPLAY (f
));
231 /* Don't free tmp_children if XQueryTree failed. */
235 XFree (tmp_children
);
237 if (wm_window
== rootw
|| had_errors
)
245 unsigned int bw
, ign
;
248 /* Get the real coordinates for the WM window upper left corner */
249 XGetGeometry (FRAME_X_DISPLAY (f
), win
,
250 &rootw
, &real_x
, &real_y
, &ow
, &oh
, &bw
, &ign
);
255 /* Translate real coordinates to coordinates relative to our
256 window. For our window, the upper left corner is 0, 0.
257 Since the upper left corner of the WM window is outside
258 our window, win_x and win_y will be negative:
260 ------------------ ---> x
262 | ----------------- v y
265 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
267 /* From-window, to-window. */
268 FRAME_DISPLAY_INFO (f
)->root_window
,
271 /* From-position, to-position. */
272 real_x
, real_y
, &win_x
, &win_y
,
277 if (FRAME_X_WINDOW (f
) == FRAME_OUTER_WINDOW (f
))
284 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
286 /* From-window, to-window. */
287 FRAME_DISPLAY_INFO (f
)->root_window
,
288 FRAME_OUTER_WINDOW (f
),
290 /* From-position, to-position. */
291 real_x
, real_y
, &outer_x
, &outer_y
,
297 had_errors
= x_had_errors_p (FRAME_X_DISPLAY (f
));
300 if (!had_errors
&& dpyinfo
->root_window
== f
->output_data
.x
->parent_desc
)
302 /* Try _NET_FRAME_EXTENTS if our parent is the root window. */
303 rc
= XGetWindowProperty (dpy
, win
, dpyinfo
->Xatom_net_frame_extents
,
304 0, max_len
, False
, target_type
,
305 &actual_type
, &actual_format
, &actual_size
,
306 &bytes_remaining
, &tmp_data
);
308 if (rc
== Success
&& actual_type
== target_type
&& !x_had_errors_p (dpy
)
309 && actual_size
== 4 && actual_format
== 32)
311 long *fe
= (long *)tmp_data
;
319 if (tmp_data
) XFree (tmp_data
);
326 if (had_errors
) return;
328 if (x_pixels_diff
) *x_pixels_diff
= -win_x
;
329 if (y_pixels_diff
) *y_pixels_diff
= -win_y
;
331 if (left_offset_x
) *left_offset_x
= -outer_x
;
332 if (top_offset_y
) *top_offset_y
= -outer_y
;
334 if (xptr
) *xptr
= real_x
;
335 if (yptr
) *yptr
= real_y
;
337 if (right_offset_x
|| bottom_offset_y
)
340 unsigned int ign
, fw
, fh
;
343 XGetGeometry (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
344 &rootw
, &xy_ign
, &xy_ign
, &fw
, &fh
, &ign
, &ign
);
345 if (right_offset_x
) *right_offset_x
= ow
- fw
+ outer_x
;
346 if (bottom_offset_y
) *bottom_offset_y
= oh
- fh
+ outer_y
;
350 /* Store the screen positions of frame F into XPTR and YPTR.
351 These are the positions of the containing window manager window,
352 not Emacs's own window. */
355 x_real_positions (struct frame
*f
, int *xptr
, int *yptr
)
357 x_real_pos_and_offsets (f
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, xptr
, yptr
,
362 /* Get the mouse position in frame relative coordinates. */
365 x_relative_mouse_position (struct frame
*f
, int *x
, int *y
)
367 Window root
, dummy_window
;
370 eassert (FRAME_X_P (f
));
374 XQueryPointer (FRAME_X_DISPLAY (f
),
375 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
377 /* The root window which contains the pointer. */
380 /* Window pointer is on, not used */
383 /* The position on that root window. */
386 /* x/y in dummy_window coordinates, not used. */
389 /* Modifier keys and pointer buttons, about which
391 (unsigned int *) &dummy
);
393 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
395 /* From-window, to-window. */
396 FRAME_DISPLAY_INFO (f
)->root_window
,
399 /* From-position, to-position. */
408 /* Gamma-correct COLOR on frame F. */
411 gamma_correct (struct frame
*f
, XColor
*color
)
415 color
->red
= pow (color
->red
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
416 color
->green
= pow (color
->green
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
417 color
->blue
= pow (color
->blue
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
422 /* Decide if color named COLOR_NAME is valid for use on frame F. If
423 so, return the RGB values in COLOR. If ALLOC_P,
424 allocate the color. Value is false if COLOR_NAME is invalid, or
425 no color could be allocated. */
428 x_defined_color (struct frame
*f
, const char *color_name
,
429 XColor
*color
, bool alloc_p
)
431 bool success_p
= false;
432 Colormap cmap
= FRAME_X_COLORMAP (f
);
436 success_p
= xg_check_special_colors (f
, color_name
, color
);
439 success_p
= x_parse_color (f
, color_name
, color
) != 0;
440 if (success_p
&& alloc_p
)
441 success_p
= x_alloc_nearest_color (f
, cmap
, color
);
448 /* Return the pixel color value for color COLOR_NAME on frame F. If F
449 is a monochrome frame, return MONO_COLOR regardless of what ARG says.
450 Signal an error if color can't be allocated. */
453 x_decode_color (struct frame
*f
, Lisp_Object color_name
, int mono_color
)
457 CHECK_STRING (color_name
);
459 #if false /* Don't do this. It's wrong when we're not using the default
460 colormap, it makes freeing difficult, and it's probably not
461 an important optimization. */
462 if (strcmp (SDATA (color_name
), "black") == 0)
463 return BLACK_PIX_DEFAULT (f
);
464 else if (strcmp (SDATA (color_name
), "white") == 0)
465 return WHITE_PIX_DEFAULT (f
);
468 /* Return MONO_COLOR for monochrome frames. */
469 if (FRAME_DISPLAY_INFO (f
)->n_planes
== 1)
472 /* x_defined_color is responsible for coping with failures
473 by looking for a near-miss. */
474 if (x_defined_color (f
, SSDATA (color_name
), &cdef
, true))
477 signal_error ("Undefined color", color_name
);
482 /* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
483 the previous value of that parameter, NEW_VALUE is the new value.
484 See also the comment of wait_for_wm in struct x_output. */
487 x_set_wait_for_wm (struct frame
*f
, Lisp_Object new_value
, Lisp_Object old_value
)
489 f
->output_data
.x
->wait_for_wm
= !NILP (new_value
);
493 x_set_tool_bar_position (struct frame
*f
,
494 Lisp_Object new_value
,
495 Lisp_Object old_value
)
497 Lisp_Object choice
= list4 (Qleft
, Qright
, Qtop
, Qbottom
);
499 if (!NILP (Fmemq (new_value
, choice
)))
502 if (!EQ (new_value
, old_value
))
504 xg_change_toolbar_position (f
, new_value
);
505 fset_tool_bar_position (f
, new_value
);
508 if (!EQ (new_value
, Qtop
))
509 error ("The only supported tool bar position is top");
513 wrong_choice (choice
, new_value
);
518 /* Set icon from FILE for frame F. By using GTK functions the icon
519 may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
522 xg_set_icon (struct frame
*f
, Lisp_Object file
)
527 found
= x_find_image_file (file
);
533 char *filename
= SSDATA (ENCODE_FILE (found
));
536 pixbuf
= gdk_pixbuf_new_from_file (filename
, &err
);
540 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
542 g_object_unref (pixbuf
);
556 xg_set_icon_from_xpm_data (struct frame
*f
, const char **data
)
558 GdkPixbuf
*pixbuf
= gdk_pixbuf_new_from_xpm_data (data
);
563 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)), pixbuf
);
564 g_object_unref (pixbuf
);
570 /* Functions called only from `x_set_frame_param'
571 to set individual parameters.
573 If FRAME_X_WINDOW (f) is 0,
574 the frame is being created and its X-window does not exist yet.
575 In that case, just record the parameter's new value
576 in the standard place; do not attempt to change the window. */
579 x_set_foreground_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
581 struct x_output
*x
= f
->output_data
.x
;
582 unsigned long fg
, old_fg
;
584 fg
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
585 old_fg
= FRAME_FOREGROUND_PIXEL (f
);
586 FRAME_FOREGROUND_PIXEL (f
) = fg
;
588 if (FRAME_X_WINDOW (f
) != 0)
590 Display
*dpy
= FRAME_X_DISPLAY (f
);
593 XSetForeground (dpy
, x
->normal_gc
, fg
);
594 XSetBackground (dpy
, x
->reverse_gc
, fg
);
596 if (x
->cursor_pixel
== old_fg
)
598 unload_color (f
, x
->cursor_pixel
);
599 x
->cursor_pixel
= x_copy_color (f
, fg
);
600 XSetBackground (dpy
, x
->cursor_gc
, x
->cursor_pixel
);
605 update_face_from_frame_parameter (f
, Qforeground_color
, arg
);
607 if (FRAME_VISIBLE_P (f
))
611 unload_color (f
, old_fg
);
615 x_set_background_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
617 struct x_output
*x
= f
->output_data
.x
;
620 bg
= x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
621 unload_color (f
, FRAME_BACKGROUND_PIXEL (f
));
622 FRAME_BACKGROUND_PIXEL (f
) = bg
;
624 if (FRAME_X_WINDOW (f
) != 0)
626 Display
*dpy
= FRAME_X_DISPLAY (f
);
629 XSetBackground (dpy
, x
->normal_gc
, bg
);
630 XSetForeground (dpy
, x
->reverse_gc
, bg
);
631 XSetWindowBackground (dpy
, FRAME_X_WINDOW (f
), bg
);
632 XSetForeground (dpy
, x
->cursor_gc
, bg
);
635 xg_set_background_color (f
, bg
);
638 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
639 toolkit scroll bars. */
642 for (bar
= FRAME_SCROLL_BARS (f
);
644 bar
= XSCROLL_BAR (bar
)->next
)
646 Window window
= XSCROLL_BAR (bar
)->x_window
;
647 XSetWindowBackground (dpy
, window
, bg
);
650 #endif /* USE_TOOLKIT_SCROLL_BARS */
653 update_face_from_frame_parameter (f
, Qbackground_color
, arg
);
655 if (FRAME_VISIBLE_P (f
))
660 /* This array must stay in sync with the mouse_cursor_types array below! */
663 mouse_cursor_nontext
,
664 mouse_cursor_hourglass
,
667 mouse_cursor_horizontal_drag
,
668 mouse_cursor_vertical_drag
,
672 struct mouse_cursor_types
{
673 /* Printable name for error messages (optional). */
676 /* Lisp variable controlling the cursor shape. */
677 /* FIXME: A couple of these variables are defined in the C code but
678 are not actually accessible from Lisp. They should probably be
679 made accessible or removed. */
680 Lisp_Object
*shape_var_ptr
;
682 /* The default shape. */
686 /* This array must stay in sync with enum mouse_cursor above! */
687 static const struct mouse_cursor_types mouse_cursor_types
[] = {
688 { "text", &Vx_pointer_shape
, XC_xterm
},
689 { "nontext", &Vx_nontext_pointer_shape
, XC_left_ptr
},
690 { "hourglass", &Vx_hourglass_pointer_shape
, XC_watch
},
691 { "modeline", &Vx_mode_pointer_shape
, XC_xterm
},
692 { NULL
, &Vx_sensitive_text_pointer_shape
, XC_hand2
},
693 { NULL
, &Vx_window_horizontal_drag_shape
, XC_sb_h_double_arrow
},
694 { NULL
, &Vx_window_vertical_drag_shape
, XC_sb_v_double_arrow
},
697 struct mouse_cursor_data
{
698 /* Last index for which XCreateFontCursor has been called, and thus
699 the last index for which x_request_serial[] is valid. */
700 int last_cursor_create_request
;
702 /* Last index for which an X error event was received in response to
703 attempting to create the cursor. */
706 /* Cursor numbers chosen. */
707 unsigned int cursor_num
[mouse_cursor_max
];
709 /* Allocated Cursor values, or zero for failed attempts. */
710 Cursor cursor
[mouse_cursor_max
];
712 /* X serial numbers for the first request sent by XCreateFontCursor.
713 Note that there may be more than one request sent. */
714 unsigned long x_request_serial
[mouse_cursor_max
];
716 /* If an error has been received, a pointer to where the current
717 error-message text is stored. */
722 x_set_mouse_color_handler (Display
*dpy
, XErrorEvent
*event
,
723 char *error_string
, void *data
)
725 struct mouse_cursor_data
*cursor_data
= data
;
728 cursor_data
->error_cursor
= -1;
729 cursor_data
->error_string
= error_string
;
730 for (i
= 0; i
< cursor_data
->last_cursor_create_request
; i
++)
732 if (event
->serial
>= cursor_data
->x_request_serial
[i
])
733 cursor_data
->error_cursor
= i
;
735 if (cursor_data
->error_cursor
>= 0)
736 /* If we failed to allocate it, don't try to free it. */
737 cursor_data
->cursor
[cursor_data
->error_cursor
] = 0;
741 x_set_mouse_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
743 struct x_output
*x
= f
->output_data
.x
;
744 Display
*dpy
= FRAME_X_DISPLAY (f
);
745 struct mouse_cursor_data cursor_data
= { -1, -1 };
746 unsigned long pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
747 unsigned long mask_color
= FRAME_BACKGROUND_PIXEL (f
);
750 /* Don't let pointers be invisible. */
751 if (mask_color
== pixel
)
753 x_free_colors (f
, &pixel
, 1);
754 pixel
= x_copy_color (f
, FRAME_FOREGROUND_PIXEL (f
));
757 unload_color (f
, x
->mouse_pixel
);
758 x
->mouse_pixel
= pixel
;
760 for (i
= 0; i
< mouse_cursor_max
; i
++)
762 Lisp_Object shape_var
= *mouse_cursor_types
[i
].shape_var_ptr
;
763 if (!NILP (shape_var
))
765 CHECK_TYPE_RANGED_INTEGER (unsigned, shape_var
);
766 cursor_data
.cursor_num
[i
] = XINT (shape_var
);
769 cursor_data
.cursor_num
[i
] = mouse_cursor_types
[i
].default_shape
;
774 /* It's not okay to crash if the user selects a screwy cursor. */
775 x_catch_errors_with_handler (dpy
, x_set_mouse_color_handler
, &cursor_data
);
777 for (i
= 0; i
< mouse_cursor_max
; i
++)
779 cursor_data
.x_request_serial
[i
] = XNextRequest (dpy
);
780 cursor_data
.last_cursor_create_request
= i
;
781 cursor_data
.cursor
[i
] = XCreateFontCursor (dpy
,
782 cursor_data
.cursor_num
[i
]);
785 /* Now sync up and process all received errors from cursor
787 if (x_had_errors_p (dpy
))
789 const char *bad_cursor_name
= NULL
;
790 /* Bounded by X_ERROR_MESSAGE_SIZE in xterm.c. */
791 size_t message_length
= strlen (cursor_data
.error_string
);
792 char *xmessage
= alloca (1 + message_length
);
793 memcpy (xmessage
, cursor_data
.error_string
, message_length
);
797 /* Free any successfully created cursors. */
798 for (i
= 0; i
< mouse_cursor_max
; i
++)
799 if (cursor_data
.cursor
[i
] != 0)
800 XFreeCursor (dpy
, cursor_data
.cursor
[i
]);
802 /* This should only be able to fail if the server's serial
803 number tracking is broken. */
804 if (cursor_data
.error_cursor
>= 0)
805 bad_cursor_name
= mouse_cursor_types
[cursor_data
.error_cursor
].name
;
807 error ("bad %s pointer cursor: %s", bad_cursor_name
, xmessage
);
809 error ("can't set cursor shape: %s", xmessage
);
812 x_uncatch_errors_after_check ();
815 XColor colors
[2]; /* 0=foreground, 1=background */
817 colors
[0].pixel
= x
->mouse_pixel
;
818 colors
[1].pixel
= mask_color
;
819 x_query_colors (f
, colors
, 2);
821 for (i
= 0; i
< mouse_cursor_max
; i
++)
822 XRecolorCursor (dpy
, cursor_data
.cursor
[i
], &colors
[0], &colors
[1]);
825 if (FRAME_X_WINDOW (f
) != 0)
827 f
->output_data
.x
->current_cursor
= cursor_data
.cursor
[mouse_cursor_text
];
828 XDefineCursor (dpy
, FRAME_X_WINDOW (f
),
829 f
->output_data
.x
->current_cursor
);
832 #define INSTALL_CURSOR(FIELD, SHORT_INDEX) \
833 eassert (x->FIELD != cursor_data.cursor[mouse_cursor_ ## SHORT_INDEX]); \
835 XFreeCursor (dpy, x->FIELD); \
836 x->FIELD = cursor_data.cursor[mouse_cursor_ ## SHORT_INDEX];
838 INSTALL_CURSOR (text_cursor
, text
);
839 INSTALL_CURSOR (nontext_cursor
, nontext
);
840 INSTALL_CURSOR (hourglass_cursor
, hourglass
);
841 INSTALL_CURSOR (modeline_cursor
, mode
);
842 INSTALL_CURSOR (hand_cursor
, hand
);
843 INSTALL_CURSOR (horizontal_drag_cursor
, horizontal_drag
);
844 INSTALL_CURSOR (vertical_drag_cursor
, vertical_drag
);
846 #undef INSTALL_CURSOR
851 update_face_from_frame_parameter (f
, Qmouse_color
, arg
);
855 x_set_cursor_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
857 unsigned long fore_pixel
, pixel
;
858 bool fore_pixel_allocated_p
= false, pixel_allocated_p
= false;
859 struct x_output
*x
= f
->output_data
.x
;
861 if (!NILP (Vx_cursor_fore_pixel
))
863 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
864 WHITE_PIX_DEFAULT (f
));
865 fore_pixel_allocated_p
= true;
868 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
870 pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
871 pixel_allocated_p
= true;
873 /* Make sure that the cursor color differs from the background color. */
874 if (pixel
== FRAME_BACKGROUND_PIXEL (f
))
876 if (pixel_allocated_p
)
878 x_free_colors (f
, &pixel
, 1);
879 pixel_allocated_p
= false;
882 pixel
= x
->mouse_pixel
;
883 if (pixel
== fore_pixel
)
885 if (fore_pixel_allocated_p
)
887 x_free_colors (f
, &fore_pixel
, 1);
888 fore_pixel_allocated_p
= false;
890 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
894 unload_color (f
, x
->cursor_foreground_pixel
);
895 if (!fore_pixel_allocated_p
)
896 fore_pixel
= x_copy_color (f
, fore_pixel
);
897 x
->cursor_foreground_pixel
= fore_pixel
;
899 unload_color (f
, x
->cursor_pixel
);
900 if (!pixel_allocated_p
)
901 pixel
= x_copy_color (f
, pixel
);
902 x
->cursor_pixel
= pixel
;
904 if (FRAME_X_WINDOW (f
) != 0)
907 XSetBackground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, x
->cursor_pixel
);
908 XSetForeground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, fore_pixel
);
911 if (FRAME_VISIBLE_P (f
))
913 x_update_cursor (f
, false);
914 x_update_cursor (f
, true);
918 update_face_from_frame_parameter (f
, Qcursor_color
, arg
);
921 /* Set the border-color of frame F to pixel value PIX.
922 Note that this does not fully take effect if done before
923 F has an x-window. */
926 x_set_border_pixel (struct frame
*f
, int pix
)
928 unload_color (f
, f
->output_data
.x
->border_pixel
);
929 f
->output_data
.x
->border_pixel
= pix
;
931 if (FRAME_X_WINDOW (f
) != 0 && f
->border_width
> 0)
934 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), pix
);
937 if (FRAME_VISIBLE_P (f
))
942 /* Set the border-color of frame F to value described by ARG.
943 ARG can be a string naming a color.
944 The border-color is used for the border that is drawn by the X server.
945 Note that this does not fully take effect if done before
946 F has an x-window; it must be redone when the window is created.
948 Note: this is done in two routines because of the way X10 works.
950 Note: under X11, this is normally the province of the window manager,
951 and so emacs's border colors may be overridden. */
954 x_set_border_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
959 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
960 x_set_border_pixel (f
, pix
);
961 update_face_from_frame_parameter (f
, Qborder_color
, arg
);
966 x_set_cursor_type (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
968 set_frame_cursor_types (f
, arg
);
972 x_set_icon_type (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
978 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
981 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
986 result
= x_text_icon (f
,
987 SSDATA ((!NILP (f
->icon_name
)
991 result
= x_bitmap_icon (f
, arg
);
996 error ("No icon window available");
999 XFlush (FRAME_X_DISPLAY (f
));
1004 x_set_icon_name (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1010 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1013 else if (!NILP (arg
) || NILP (oldval
))
1016 fset_icon_name (f
, arg
);
1018 if (f
->output_data
.x
->icon_bitmap
!= 0)
1023 result
= x_text_icon (f
,
1024 SSDATA ((!NILP (f
->icon_name
)
1033 error ("No icon window available");
1036 XFlush (FRAME_X_DISPLAY (f
));
1042 x_set_menu_bar_lines (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
1045 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
1046 int olines
= FRAME_MENU_BAR_LINES (f
);
1049 /* Right now, menu bars don't work properly in minibuf-only frames;
1050 most of the commands try to apply themselves to the minibuffer
1051 frame itself, and get an error because you can't switch buffers
1052 in or split the minibuffer window. */
1053 if (FRAME_MINIBUF_ONLY_P (f
))
1056 if (TYPE_RANGED_INTEGERP (int, value
))
1057 nlines
= XINT (value
);
1061 /* Make sure we redisplay all windows in this frame. */
1064 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1065 FRAME_MENU_BAR_LINES (f
) = 0;
1066 FRAME_MENU_BAR_HEIGHT (f
) = 0;
1069 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
1070 if (FRAME_X_P (f
) && f
->output_data
.x
->menubar_widget
== 0)
1071 /* Make sure next redisplay shows the menu bar. */
1072 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= true;
1076 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
1077 free_frame_menubar (f
);
1078 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
1080 f
->output_data
.x
->menubar_widget
= 0;
1082 #else /* not USE_X_TOOLKIT && not USE_GTK */
1083 FRAME_MENU_BAR_LINES (f
) = nlines
;
1084 FRAME_MENU_BAR_HEIGHT (f
) = nlines
* FRAME_LINE_HEIGHT (f
);
1085 adjust_frame_size (f
, -1, -1, 2, true, Qx_set_menu_bar_lines
);
1086 if (FRAME_X_WINDOW (f
))
1087 x_clear_under_internal_border (f
);
1089 /* If the menu bar height gets changed, the internal border below
1090 the top margin has to be cleared. Also, if the menu bar gets
1091 larger, the area for the added lines has to be cleared except for
1092 the first menu bar line that is to be drawn later. */
1093 if (nlines
!= olines
)
1095 int height
= FRAME_INTERNAL_BORDER_WIDTH (f
);
1096 int width
= FRAME_PIXEL_WIDTH (f
);
1099 /* height can be zero here. */
1100 if (FRAME_X_WINDOW (f
) && height
> 0 && width
> 0)
1102 y
= FRAME_TOP_MARGIN_HEIGHT (f
);
1105 x_clear_area (f
, 0, y
, width
, height
);
1109 if (nlines
> 1 && nlines
> olines
)
1111 y
= (olines
== 0 ? 1 : olines
) * FRAME_LINE_HEIGHT (f
);
1112 height
= nlines
* FRAME_LINE_HEIGHT (f
) - y
;
1115 x_clear_area (f
, 0, y
, width
, height
);
1119 if (nlines
== 0 && WINDOWP (f
->menu_bar_window
))
1120 clear_glyph_matrix (XWINDOW (f
->menu_bar_window
)->current_matrix
);
1122 #endif /* not USE_X_TOOLKIT && not USE_GTK */
1123 adjust_frame_glyphs (f
);
1124 run_window_configuration_change_hook (f
);
1128 /* Set the number of lines used for the tool bar of frame F to VALUE.
1129 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1130 is the old number of tool bar lines. This function changes the
1131 height of all windows on frame F to match the new tool bar height.
1132 The frame's height doesn't change. */
1135 x_set_tool_bar_lines (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
1139 /* Treat tool bars like menu bars. */
1140 if (FRAME_MINIBUF_ONLY_P (f
))
1143 /* Use VALUE only if an int >= 0. */
1144 if (RANGED_INTEGERP (0, value
, INT_MAX
))
1145 nlines
= XFASTINT (value
);
1149 x_change_tool_bar_height (f
, nlines
* FRAME_LINE_HEIGHT (f
));
1153 /* Set the pixel height of the tool bar of frame F to HEIGHT. */
1155 x_change_tool_bar_height (struct frame
*f
, int height
)
1158 FRAME_TOOL_BAR_LINES (f
) = 0;
1159 FRAME_TOOL_BAR_HEIGHT (f
) = 0;
1162 FRAME_EXTERNAL_TOOL_BAR (f
) = true;
1163 if (FRAME_X_P (f
) && f
->output_data
.x
->toolbar_widget
== 0)
1164 /* Make sure next redisplay shows the tool bar. */
1165 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= true;
1166 update_frame_tool_bar (f
);
1170 if (FRAME_EXTERNAL_TOOL_BAR (f
))
1171 free_frame_tool_bar (f
);
1172 FRAME_EXTERNAL_TOOL_BAR (f
) = false;
1174 #else /* !USE_GTK */
1175 int unit
= FRAME_LINE_HEIGHT (f
);
1176 int old_height
= FRAME_TOOL_BAR_HEIGHT (f
);
1177 int lines
= (height
+ unit
- 1) / unit
;
1178 Lisp_Object fullscreen
;
1180 /* Make sure we redisplay all windows in this frame. */
1183 /* Recalculate tool bar and frame text sizes. */
1184 FRAME_TOOL_BAR_HEIGHT (f
) = height
;
1185 FRAME_TOOL_BAR_LINES (f
) = lines
;
1186 /* Store the `tool-bar-lines' and `height' frame parameters. */
1187 store_frame_param (f
, Qtool_bar_lines
, make_number (lines
));
1188 store_frame_param (f
, Qheight
, make_number (FRAME_LINES (f
)));
1190 /* We also have to make sure that the internal border at the top of
1191 the frame, below the menu bar or tool bar, is redrawn when the
1192 tool bar disappears. This is so because the internal border is
1193 below the tool bar if one is displayed, but is below the menu bar
1194 if there isn't a tool bar. The tool bar draws into the area
1195 below the menu bar. */
1196 if (FRAME_X_WINDOW (f
) && FRAME_TOOL_BAR_HEIGHT (f
) == 0)
1199 clear_current_matrices (f
);
1202 if ((height
< old_height
) && WINDOWP (f
->tool_bar_window
))
1203 clear_glyph_matrix (XWINDOW (f
->tool_bar_window
)->current_matrix
);
1205 /* Recalculate toolbar height. */
1206 f
->n_tool_bar_rows
= 0;
1208 && (!f
->after_make_frame
1209 || NILP (frame_inhibit_implied_resize
)
1210 || (CONSP (frame_inhibit_implied_resize
)
1211 && NILP (Fmemq (Qtool_bar_lines
, frame_inhibit_implied_resize
)))))
1212 f
->tool_bar_redisplayed
= f
->tool_bar_resized
= false;
1214 adjust_frame_size (f
, -1, -1,
1215 ((!f
->tool_bar_resized
1216 && (NILP (fullscreen
=
1217 get_frame_param (f
, Qfullscreen
))
1218 || EQ (fullscreen
, Qfullwidth
))) ? 1
1219 : (old_height
== 0 || height
== 0) ? 2
1221 false, Qtool_bar_lines
);
1223 f
->tool_bar_resized
= f
->tool_bar_redisplayed
;
1225 /* adjust_frame_size might not have done anything, garbage frame
1227 adjust_frame_glyphs (f
);
1228 SET_FRAME_GARBAGED (f
);
1229 if (FRAME_X_WINDOW (f
))
1230 x_clear_under_internal_border (f
);
1232 #endif /* USE_GTK */
1237 x_set_internal_border_width (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1241 CHECK_TYPE_RANGED_INTEGER (int, arg
);
1242 border
= max (XINT (arg
), 0);
1244 if (border
!= FRAME_INTERNAL_BORDER_WIDTH (f
))
1246 FRAME_INTERNAL_BORDER_WIDTH (f
) = border
;
1248 #ifdef USE_X_TOOLKIT
1249 if (FRAME_X_OUTPUT (f
)->edit_widget
)
1250 widget_store_internal_border (FRAME_X_OUTPUT (f
)->edit_widget
);
1253 if (FRAME_X_WINDOW (f
) != 0)
1255 adjust_frame_size (f
, -1, -1, 3, false, Qinternal_border_width
);
1258 xg_clear_under_internal_border (f
);
1260 x_clear_under_internal_border (f
);
1268 /* Set the foreground color for scroll bars on frame F to VALUE.
1269 VALUE should be a string, a color name. If it isn't a string or
1270 isn't a valid color name, do nothing. OLDVAL is the old value of
1271 the frame parameter. */
1274 x_set_scroll_bar_foreground (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
1276 unsigned long pixel
;
1278 if (STRINGP (value
))
1279 pixel
= x_decode_color (f
, value
, BLACK_PIX_DEFAULT (f
));
1283 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
1284 unload_color (f
, f
->output_data
.x
->scroll_bar_foreground_pixel
);
1286 f
->output_data
.x
->scroll_bar_foreground_pixel
= pixel
;
1287 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1289 /* Remove all scroll bars because they have wrong colors. */
1290 if (FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
)
1291 (*FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
) (f
);
1292 if (FRAME_TERMINAL (f
)->judge_scroll_bars_hook
)
1293 (*FRAME_TERMINAL (f
)->judge_scroll_bars_hook
) (f
);
1295 update_face_from_frame_parameter (f
, Qscroll_bar_foreground
, value
);
1301 /* Set the background color for scroll bars on frame F to VALUE VALUE
1302 should be a string, a color name. If it isn't a string or isn't a
1303 valid color name, do nothing. OLDVAL is the old value of the frame
1307 x_set_scroll_bar_background (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
1309 unsigned long pixel
;
1311 if (STRINGP (value
))
1312 pixel
= x_decode_color (f
, value
, WHITE_PIX_DEFAULT (f
));
1316 if (f
->output_data
.x
->scroll_bar_background_pixel
!= -1)
1317 unload_color (f
, f
->output_data
.x
->scroll_bar_background_pixel
);
1319 #if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
1320 /* Scrollbar shadow colors. */
1321 if (f
->output_data
.x
->scroll_bar_top_shadow_pixel
!= -1)
1323 unload_color (f
, f
->output_data
.x
->scroll_bar_top_shadow_pixel
);
1324 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
1326 if (f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
!= -1)
1328 unload_color (f
, f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
);
1329 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
1331 #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
1333 f
->output_data
.x
->scroll_bar_background_pixel
= pixel
;
1334 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1336 /* Remove all scroll bars because they have wrong colors. */
1337 if (FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
)
1338 (*FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
) (f
);
1339 if (FRAME_TERMINAL (f
)->judge_scroll_bars_hook
)
1340 (*FRAME_TERMINAL (f
)->judge_scroll_bars_hook
) (f
);
1342 update_face_from_frame_parameter (f
, Qscroll_bar_background
, value
);
1348 /* Encode Lisp string STRING as a text in a format appropriate for
1349 XICCC (X Inter Client Communication Conventions).
1351 If STRING contains only ASCII characters, do no conversion and
1352 return the string data of STRING. Otherwise, encode the text by
1353 CODING_SYSTEM, and return a newly allocated memory area which
1354 should be freed by `xfree' by a caller.
1356 Store the byte length of resulting text in *TEXT_BYTES.
1358 If the text contains only ASCII and Latin-1, store true in *STRING_P,
1359 which means that the `encoding' of the result can be `STRING'.
1360 Otherwise store false in *STRINGP, which means that the `encoding' of
1361 the result should be `COMPOUND_TEXT'. */
1363 static unsigned char *
1364 x_encode_text (Lisp_Object string
, Lisp_Object coding_system
,
1365 ptrdiff_t *text_bytes
, bool *stringp
, bool *freep
)
1367 int result
= string_xstring_p (string
);
1368 struct coding_system coding
;
1372 /* No multibyte character in OBJ. We need not encode it. */
1373 *text_bytes
= SBYTES (string
);
1376 return SDATA (string
);
1379 setup_coding_system (coding_system
, &coding
);
1380 coding
.mode
|= (CODING_MODE_SAFE_ENCODING
| CODING_MODE_LAST_BLOCK
);
1381 /* We suppress producing escape sequences for composition. */
1382 coding
.common_flags
&= ~CODING_ANNOTATION_MASK
;
1383 coding
.destination
= xnmalloc (SCHARS (string
), 2);
1384 coding
.dst_bytes
= SCHARS (string
) * 2;
1385 encode_coding_object (&coding
, string
, 0, 0,
1386 SCHARS (string
), SBYTES (string
), Qnil
);
1387 *text_bytes
= coding
.produced
;
1388 *stringp
= (result
== 1 || !EQ (coding_system
, Qcompound_text
));
1390 return coding
.destination
;
1394 /* Set the WM name to NAME for frame F. Also set the icon name.
1395 If the frame already has an icon name, use that, otherwise set the
1396 icon name to NAME. */
1399 x_set_name_internal (struct frame
*f
, Lisp_Object name
)
1401 if (FRAME_X_WINDOW (f
))
1405 XTextProperty text
, icon
;
1408 bool do_free_icon_value
= false, do_free_text_value
= false;
1409 Lisp_Object coding_system
;
1410 Lisp_Object encoded_name
;
1411 Lisp_Object encoded_icon_name
;
1413 /* As ENCODE_UTF_8 may cause GC and relocation of string data,
1414 we use it before x_encode_text that may return string data. */
1415 encoded_name
= ENCODE_UTF_8 (name
);
1417 coding_system
= Qcompound_text
;
1418 /* Note: Encoding strategy
1420 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1421 text.encoding. But, there are non-internationalized window
1422 managers which don't support that encoding. So, if NAME
1423 contains only ASCII and 8859-1 characters, encode it by
1424 iso-latin-1, and use "STRING" in text.encoding hoping that
1425 such window managers at least analyze this format correctly,
1426 i.e. treat 8-bit bytes as 8859-1 characters.
1428 We may also be able to use "UTF8_STRING" in text.encoding
1429 in the future which can encode all Unicode characters.
1430 But, for the moment, there's no way to know that the
1431 current window manager supports it or not.
1433 Either way, we also set the _NET_WM_NAME and _NET_WM_ICON_NAME
1434 properties. Per the EWMH specification, those two properties
1435 are always UTF8_STRING. This matches what gtk_window_set_title()
1436 does in the USE_GTK case. */
1437 text
.value
= x_encode_text (name
, coding_system
, &bytes
,
1438 &stringp
, &do_free_text_value
);
1439 text
.encoding
= (stringp
? XA_STRING
1440 : FRAME_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1442 text
.nitems
= bytes
;
1444 if (!STRINGP (f
->icon_name
))
1447 encoded_icon_name
= encoded_name
;
1451 /* See the above comment "Note: Encoding strategy". */
1452 icon
.value
= x_encode_text (f
->icon_name
, coding_system
, &bytes
,
1453 &stringp
, &do_free_icon_value
);
1454 icon
.encoding
= (stringp
? XA_STRING
1455 : FRAME_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1457 icon
.nitems
= bytes
;
1459 encoded_icon_name
= ENCODE_UTF_8 (f
->icon_name
);
1463 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
1464 SSDATA (encoded_name
));
1465 #else /* not USE_GTK */
1466 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &text
);
1467 XChangeProperty (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
1468 FRAME_DISPLAY_INFO (f
)->Xatom_net_wm_name
,
1469 FRAME_DISPLAY_INFO (f
)->Xatom_UTF8_STRING
,
1471 SDATA (encoded_name
),
1472 SBYTES (encoded_name
));
1473 #endif /* not USE_GTK */
1475 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &icon
);
1476 XChangeProperty (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
1477 FRAME_DISPLAY_INFO (f
)->Xatom_net_wm_icon_name
,
1478 FRAME_DISPLAY_INFO (f
)->Xatom_UTF8_STRING
,
1480 SDATA (encoded_icon_name
),
1481 SBYTES (encoded_icon_name
));
1483 if (do_free_icon_value
)
1485 if (do_free_text_value
)
1492 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1495 If EXPLICIT is true, that indicates that lisp code is setting the
1496 name; if NAME is a string, set F's name to NAME and set
1497 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1499 If EXPLICIT is false, that indicates that Emacs redisplay code is
1500 suggesting a new name, which lisp code should override; if
1501 F->explicit_name is set, ignore the new name; otherwise, set it. */
1504 x_set_name (struct frame
*f
, Lisp_Object name
, bool explicit)
1506 /* Make sure that requests from lisp code override requests from
1507 Emacs redisplay code. */
1510 /* If we're switching from explicit to implicit, we had better
1511 update the mode lines and thereby update the title. */
1512 if (f
->explicit_name
&& NILP (name
))
1513 update_mode_lines
= 37;
1515 f
->explicit_name
= ! NILP (name
);
1517 else if (f
->explicit_name
)
1520 /* If NAME is nil, set the name to the x_id_name. */
1523 /* Check for no change needed in this very common case
1524 before we do any consing. */
1525 if (!strcmp (FRAME_DISPLAY_INFO (f
)->x_id_name
,
1528 name
= build_string (FRAME_DISPLAY_INFO (f
)->x_id_name
);
1531 CHECK_STRING (name
);
1533 /* Don't change the name if it's already NAME. */
1534 if (! NILP (Fstring_equal (name
, f
->name
)))
1537 fset_name (f
, name
);
1539 /* For setting the frame title, the title parameter should override
1540 the name parameter. */
1541 if (! NILP (f
->title
))
1544 x_set_name_internal (f
, name
);
1547 /* This function should be called when the user's lisp code has
1548 specified a name for the frame; the name will override any set by the
1551 x_explicitly_set_name (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1553 x_set_name (f
, arg
, true);
1556 /* This function should be called by Emacs redisplay code to set the
1557 name; names set this way will never override names set by the user's
1560 x_implicitly_set_name (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1562 x_set_name (f
, arg
, false);
1565 /* Change the title of frame F to NAME.
1566 If NAME is nil, use the frame name as the title. */
1569 x_set_title (struct frame
*f
, Lisp_Object name
, Lisp_Object old_name
)
1571 /* Don't change the title if it's already NAME. */
1572 if (EQ (name
, f
->title
))
1575 update_mode_lines
= 38;
1577 fset_title (f
, name
);
1582 CHECK_STRING (name
);
1584 x_set_name_internal (f
, name
);
1588 x_set_scroll_bar_default_width (struct frame
*f
)
1590 int unit
= FRAME_COLUMN_WIDTH (f
);
1591 #ifdef USE_TOOLKIT_SCROLL_BARS
1593 int minw
= xg_get_default_scrollbar_width ();
1597 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
1598 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (minw
+ unit
- 1) / unit
;
1599 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = minw
;
1601 /* The width of a non-toolkit scrollbar is 14 pixels. */
1602 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + unit
- 1) / unit
;
1603 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
)
1604 = FRAME_CONFIG_SCROLL_BAR_COLS (f
) * unit
;
1609 x_set_scroll_bar_default_height (struct frame
*f
)
1611 int height
= FRAME_LINE_HEIGHT (f
);
1612 #ifdef USE_TOOLKIT_SCROLL_BARS
1614 int min_height
= xg_get_default_scrollbar_height ();
1616 int min_height
= 16;
1618 /* A minimum height of 14 doesn't look good for toolkit scroll bars. */
1619 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f
) = min_height
;
1620 FRAME_CONFIG_SCROLL_BAR_LINES (f
) = (min_height
+ height
- 1) / height
;
1622 /* The height of a non-toolkit scrollbar is 14 pixels. */
1623 FRAME_CONFIG_SCROLL_BAR_LINES (f
) = (14 + height
- 1) / height
;
1625 /* Use all of that space (aside from required margins) for the
1627 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f
) = 14;
1632 /* Record in frame F the specified or default value according to ALIST
1633 of the parameter named PROP (a Lisp symbol). If no value is
1634 specified for PROP, look for an X default for XPROP on the frame
1635 named NAME. If that is not found either, use the value DEFLT. */
1638 x_default_scroll_bar_color_parameter (struct frame
*f
,
1639 Lisp_Object alist
, Lisp_Object prop
,
1640 const char *xprop
, const char *xclass
,
1643 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
1646 tem
= x_get_arg (dpyinfo
, alist
, prop
, xprop
, xclass
, RES_TYPE_STRING
);
1647 if (EQ (tem
, Qunbound
))
1649 #ifdef USE_TOOLKIT_SCROLL_BARS
1651 /* See if an X resource for the scroll bar color has been
1653 AUTO_STRING (foreground
, "foreground");
1654 AUTO_STRING (background
, "foreground");
1655 AUTO_STRING (verticalScrollBar
, "verticalScrollBar");
1656 tem
= (display_x_get_resource
1657 (dpyinfo
, foreground_p
? foreground
: background
,
1658 empty_unibyte_string
,
1660 empty_unibyte_string
));
1663 /* If nothing has been specified, scroll bars will use a
1664 toolkit-dependent default. Because these defaults are
1665 difficult to get at without actually creating a scroll
1666 bar, use nil to indicate that no color has been
1671 #else /* not USE_TOOLKIT_SCROLL_BARS */
1675 #endif /* not USE_TOOLKIT_SCROLL_BARS */
1678 AUTO_FRAME_ARG (arg
, prop
, tem
);
1679 x_set_frame_parameters (f
, arg
);
1686 #ifdef USE_X_TOOLKIT
1688 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
1689 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
1690 already be present because of the toolkit (Motif adds some of them,
1691 for example, but Xt doesn't). */
1694 hack_wm_protocols (struct frame
*f
, Widget widget
)
1696 Display
*dpy
= XtDisplay (widget
);
1697 Window w
= XtWindow (widget
);
1698 bool need_delete
= true;
1699 bool need_focus
= true;
1700 bool need_save
= true;
1705 unsigned char *catoms
;
1707 unsigned long nitems
= 0;
1708 unsigned long bytes_after
;
1710 if ((XGetWindowProperty (dpy
, w
,
1711 FRAME_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
1712 0, 100, False
, XA_ATOM
,
1713 &type
, &format
, &nitems
, &bytes_after
,
1716 && format
== 32 && type
== XA_ATOM
)
1718 Atom
*atoms
= (Atom
*) catoms
;
1723 == FRAME_DISPLAY_INFO (f
)->Xatom_wm_delete_window
)
1724 need_delete
= false;
1725 else if (atoms
[nitems
]
1726 == FRAME_DISPLAY_INFO (f
)->Xatom_wm_take_focus
)
1728 else if (atoms
[nitems
]
1729 == FRAME_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
)
1740 props
[count
++] = FRAME_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
1742 props
[count
++] = FRAME_DISPLAY_INFO (f
)->Xatom_wm_take_focus
;
1744 props
[count
++] = FRAME_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
1746 XChangeProperty (dpy
, w
, FRAME_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
1747 XA_ATOM
, 32, PropModeAppend
,
1748 (unsigned char *) props
, count
);
1756 /* Support routines for XIC (X Input Context). */
1760 static XFontSet
xic_create_xfontset (struct frame
*);
1761 static XIMStyle
best_xim_style (XIMStyles
*);
1764 /* Supported XIM styles, ordered by preference. */
1766 static const XIMStyle supported_xim_styles
[] =
1768 XIMPreeditPosition
| XIMStatusArea
,
1769 XIMPreeditPosition
| XIMStatusNothing
,
1770 XIMPreeditPosition
| XIMStatusNone
,
1771 XIMPreeditNothing
| XIMStatusArea
,
1772 XIMPreeditNothing
| XIMStatusNothing
,
1773 XIMPreeditNothing
| XIMStatusNone
,
1774 XIMPreeditNone
| XIMStatusArea
,
1775 XIMPreeditNone
| XIMStatusNothing
,
1776 XIMPreeditNone
| XIMStatusNone
,
1781 #if defined HAVE_X_WINDOWS && defined USE_X_TOOLKIT
1782 /* Create an X fontset on frame F with base font name BASE_FONTNAME. */
1784 static const char xic_default_fontset
[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
1786 /* Create an Xt fontset spec from the name of a base font.
1787 If `motif' is True use the Motif syntax. */
1789 xic_create_fontsetname (const char *base_fontname
, bool motif
)
1791 const char *sep
= motif
? ";" : ",";
1795 /* Make a fontset name from the base font name. */
1796 if (xic_default_fontset
== base_fontname
)
1798 /* There is no base font name, use the default. */
1799 fontsetname
= xmalloc (strlen (base_fontname
) + 2);
1800 z
= stpcpy (fontsetname
, base_fontname
);
1804 /* Make a fontset name from the base font name.
1805 The font set will be made of the following elements:
1807 - the base font where the charset spec is replaced by -*-*.
1808 - the same but with the family also replaced with -*-*-. */
1809 const char *p
= base_fontname
;
1812 for (i
= 0; *p
; p
++)
1816 /* As the font name doesn't conform to XLFD, we can't
1817 modify it to generalize it to allcs and allfamilies.
1818 Use the specified font plus the default. */
1819 fontsetname
= xmalloc (strlen (base_fontname
)
1820 + strlen (xic_default_fontset
) + 3);
1821 z
= stpcpy (fontsetname
, base_fontname
);
1822 z
= stpcpy (z
, sep
);
1823 z
= stpcpy (z
, xic_default_fontset
);
1828 const char *p1
= NULL
, *p2
= NULL
, *p3
= NULL
;
1829 char *font_allcs
= NULL
;
1830 char *font_allfamilies
= NULL
;
1831 char *font_all
= NULL
;
1832 const char *allcs
= "*-*-*-*-*-*-*";
1833 const char *allfamilies
= "-*-*-";
1834 const char *all
= "*-*-*-*-";
1837 for (i
= 0, p
= base_fontname
; i
< 8; p
++)
1850 /* If base_fontname specifies ADSTYLE, make it a
1854 ptrdiff_t diff
= (p2
- p3
) - 2;
1856 base
= alloca (strlen (base_fontname
) + 1);
1857 memcpy (base
, base_fontname
, p3
- base_fontname
);
1858 base
[p3
- base_fontname
] = '*';
1859 base
[(p3
- base_fontname
) + 1] = '-';
1860 strcpy (base
+ (p3
- base_fontname
) + 2, p2
);
1861 p
= base
+ (p
- base_fontname
) - diff
;
1862 p1
= base
+ (p1
- base_fontname
);
1863 p2
= base
+ (p2
- base_fontname
) - diff
;
1864 base_fontname
= base
;
1867 /* Build the font spec that matches all charsets. */
1868 len
= p
- base_fontname
+ strlen (allcs
) + 1;
1869 font_allcs
= alloca (len
);
1870 memcpy (font_allcs
, base_fontname
, p
- base_fontname
);
1871 strcpy (font_allcs
+ (p
- base_fontname
), allcs
);
1873 /* Build the font spec that matches all families and
1875 len
= p
- p1
+ strlen (allcs
) + strlen (allfamilies
) + 1;
1876 font_allfamilies
= alloca (len
);
1877 strcpy (font_allfamilies
, allfamilies
);
1878 memcpy (font_allfamilies
+ strlen (allfamilies
), p1
, p
- p1
);
1879 strcpy (font_allfamilies
+ strlen (allfamilies
) + (p
- p1
), allcs
);
1881 /* Build the font spec that matches all. */
1882 len
= p
- p2
+ strlen (allcs
) + strlen (all
) + strlen (allfamilies
) + 1;
1883 font_all
= alloca (len
);
1884 z
= stpcpy (font_all
, allfamilies
);
1885 z
= stpcpy (z
, all
);
1886 memcpy (z
, p2
, p
- p2
);
1887 strcpy (z
+ (p
- p2
), allcs
);
1889 /* Build the actual font set name. */
1890 len
= strlen (base_fontname
) + strlen (font_allcs
)
1891 + strlen (font_allfamilies
) + strlen (font_all
) + 5;
1892 fontsetname
= xmalloc (len
);
1893 z
= stpcpy (fontsetname
, base_fontname
);
1894 z
= stpcpy (z
, sep
);
1895 z
= stpcpy (z
, font_allcs
);
1896 z
= stpcpy (z
, sep
);
1897 z
= stpcpy (z
, font_allfamilies
);
1898 z
= stpcpy (z
, sep
);
1899 z
= stpcpy (z
, font_all
);
1906 #endif /* HAVE_X_WINDOWS && USE_X_TOOLKIT */
1908 #ifdef DEBUG_XIC_FONTSET
1910 print_fontset_result (XFontSet xfs
, char *name
, char **missing_list
,
1914 fprintf (stderr
, "XIC Fontset created: %s\n", name
);
1917 fprintf (stderr
, "XIC Fontset failed: %s\n", name
);
1918 while (missing_count
-- > 0)
1920 fprintf (stderr
, " missing: %s\n", *missing_list
);
1929 xic_create_xfontset (struct frame
*f
)
1931 XFontSet xfs
= NULL
;
1932 struct font
*font
= FRAME_FONT (f
);
1933 int pixel_size
= font
->pixel_size
;
1934 Lisp_Object rest
, frame
;
1936 /* See if there is another frame already using same fontset. */
1937 FOR_EACH_FRAME (rest
, frame
)
1939 struct frame
*cf
= XFRAME (frame
);
1941 if (cf
!= f
&& FRAME_LIVE_P (f
) && FRAME_X_P (cf
)
1942 && FRAME_DISPLAY_INFO (cf
) == FRAME_DISPLAY_INFO (f
)
1944 && FRAME_FONT (f
)->pixel_size
== pixel_size
)
1946 xfs
= FRAME_XIC_FONTSET (cf
);
1954 char **missing_list
;
1957 const char *xlfd_format
= "-*-*-medium-r-normal--%d-*-*-*-*-*";
1959 sprintf (buf
, xlfd_format
, pixel_size
);
1960 missing_list
= NULL
;
1961 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
), buf
,
1962 &missing_list
, &missing_count
, &def_string
);
1963 #ifdef DEBUG_XIC_FONTSET
1964 print_fontset_result (xfs
, buf
, missing_list
, missing_count
);
1967 XFreeStringList (missing_list
);
1970 /* List of pixel sizes most likely available. Find one that
1971 is closest to pixel_size. */
1972 int sizes
[] = {0, 8, 10, 11, 12, 14, 17, 18, 20, 24, 26, 34, 0};
1973 int *smaller
, *larger
;
1975 for (smaller
= sizes
; smaller
[1]; smaller
++)
1976 if (smaller
[1] >= pixel_size
)
1978 larger
= smaller
+ 1;
1979 if (*larger
== pixel_size
)
1981 while (*smaller
|| *larger
)
1986 this_size
= *smaller
--;
1987 else if (! *smaller
)
1988 this_size
= *larger
++;
1989 else if (pixel_size
- *smaller
< *larger
- pixel_size
)
1990 this_size
= *smaller
--;
1992 this_size
= *larger
++;
1993 sprintf (buf
, xlfd_format
, this_size
);
1994 missing_list
= NULL
;
1995 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
), buf
,
1996 &missing_list
, &missing_count
, &def_string
);
1997 #ifdef DEBUG_XIC_FONTSET
1998 print_fontset_result (xfs
, buf
, missing_list
, missing_count
);
2001 XFreeStringList (missing_list
);
2008 const char *last_resort
= "-*-*-*-r-normal--*-*-*-*-*-*";
2010 missing_list
= NULL
;
2011 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
), last_resort
,
2012 &missing_list
, &missing_count
, &def_string
);
2013 #ifdef DEBUG_XIC_FONTSET
2014 print_fontset_result (xfs
, last_resort
, missing_list
, missing_count
);
2017 XFreeStringList (missing_list
);
2025 /* Free the X fontset of frame F if it is the last frame using it. */
2028 xic_free_xfontset (struct frame
*f
)
2030 Lisp_Object rest
, frame
;
2031 bool shared_p
= false;
2033 if (!FRAME_XIC_FONTSET (f
))
2036 /* See if there is another frame sharing the same fontset. */
2037 FOR_EACH_FRAME (rest
, frame
)
2039 struct frame
*cf
= XFRAME (frame
);
2040 if (cf
!= f
&& FRAME_LIVE_P (f
) && FRAME_X_P (cf
)
2041 && FRAME_DISPLAY_INFO (cf
) == FRAME_DISPLAY_INFO (f
)
2042 && FRAME_XIC_FONTSET (cf
) == FRAME_XIC_FONTSET (f
))
2050 /* The fontset is not used anymore. It is safe to free it. */
2051 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
2053 FRAME_XIC_FONTSET (f
) = NULL
;
2057 /* Value is the best input style, given user preferences USER (already
2058 checked to be supported by Emacs), and styles supported by the
2059 input method XIM. */
2062 best_xim_style (XIMStyles
*xim
)
2065 int nr_supported
= ARRAYELTS (supported_xim_styles
);
2067 for (i
= 0; i
< nr_supported
; ++i
)
2068 for (j
= 0; j
< xim
->count_styles
; ++j
)
2069 if (supported_xim_styles
[i
] == xim
->supported_styles
[j
])
2070 return supported_xim_styles
[i
];
2072 /* Return the default style. */
2073 return XIMPreeditNothing
| XIMStatusNothing
;
2076 /* Create XIC for frame F. */
2079 create_frame_xic (struct frame
*f
)
2083 XFontSet xfs
= NULL
;
2084 XVaNestedList status_attr
= NULL
;
2085 XVaNestedList preedit_attr
= NULL
;
2093 xim
= FRAME_X_XIM (f
);
2097 /* Determine XIC style. */
2098 xic_style
= best_xim_style (FRAME_X_XIM_STYLES (f
));
2100 /* Create X fontset. */
2101 if (xic_style
& (XIMPreeditPosition
| XIMStatusArea
))
2103 xfs
= xic_create_xfontset (f
);
2107 FRAME_XIC_FONTSET (f
) = xfs
;
2110 if (xic_style
& XIMPreeditPosition
)
2112 spot
.x
= 0; spot
.y
= 1;
2113 preedit_attr
= XVaCreateNestedList (0,
2116 FRAME_FOREGROUND_PIXEL (f
),
2118 FRAME_BACKGROUND_PIXEL (f
),
2119 (xic_style
& XIMPreeditPosition
2129 if (xic_style
& XIMStatusArea
)
2131 s_area
.x
= 0; s_area
.y
= 0; s_area
.width
= 1; s_area
.height
= 1;
2132 status_attr
= XVaCreateNestedList (0,
2138 FRAME_FOREGROUND_PIXEL (f
),
2140 FRAME_BACKGROUND_PIXEL (f
),
2147 if (preedit_attr
&& status_attr
)
2148 xic
= XCreateIC (xim
,
2149 XNInputStyle
, xic_style
,
2150 XNClientWindow
, FRAME_X_WINDOW (f
),
2151 XNFocusWindow
, FRAME_X_WINDOW (f
),
2152 XNStatusAttributes
, status_attr
,
2153 XNPreeditAttributes
, preedit_attr
,
2155 else if (preedit_attr
)
2156 xic
= XCreateIC (xim
,
2157 XNInputStyle
, xic_style
,
2158 XNClientWindow
, FRAME_X_WINDOW (f
),
2159 XNFocusWindow
, FRAME_X_WINDOW (f
),
2160 XNPreeditAttributes
, preedit_attr
,
2162 else if (status_attr
)
2163 xic
= XCreateIC (xim
,
2164 XNInputStyle
, xic_style
,
2165 XNClientWindow
, FRAME_X_WINDOW (f
),
2166 XNFocusWindow
, FRAME_X_WINDOW (f
),
2167 XNStatusAttributes
, status_attr
,
2170 xic
= XCreateIC (xim
,
2171 XNInputStyle
, xic_style
,
2172 XNClientWindow
, FRAME_X_WINDOW (f
),
2173 XNFocusWindow
, FRAME_X_WINDOW (f
),
2179 FRAME_XIC (f
) = xic
;
2180 FRAME_XIC_STYLE (f
) = xic_style
;
2181 xfs
= NULL
; /* Don't free below. */
2189 XFree (preedit_attr
);
2192 XFree (status_attr
);
2196 /* Destroy XIC and free XIC fontset of frame F, if any. */
2199 free_frame_xic (struct frame
*f
)
2201 if (FRAME_XIC (f
) == NULL
)
2204 XDestroyIC (FRAME_XIC (f
));
2205 xic_free_xfontset (f
);
2207 FRAME_XIC (f
) = NULL
;
2211 /* Place preedit area for XIC of window W's frame to specified
2212 pixel position X/Y. X and Y are relative to window W. */
2215 xic_set_preeditarea (struct window
*w
, int x
, int y
)
2217 struct frame
*f
= XFRAME (w
->frame
);
2221 spot
.x
= WINDOW_TO_FRAME_PIXEL_X (w
, x
) + WINDOW_LEFT_FRINGE_WIDTH (w
);
2222 spot
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, y
) + FONT_BASE (FRAME_FONT (f
));
2223 attr
= XVaCreateNestedList (0, XNSpotLocation
, &spot
, NULL
);
2224 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2229 /* Place status area for XIC in bottom right corner of frame F.. */
2232 xic_set_statusarea (struct frame
*f
)
2234 XIC xic
= FRAME_XIC (f
);
2239 /* Negotiate geometry of status area. If input method has existing
2240 status area, use its current size. */
2241 area
.x
= area
.y
= area
.width
= area
.height
= 0;
2242 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &area
, NULL
);
2243 XSetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2246 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &needed
, NULL
);
2247 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2250 if (needed
->width
== 0) /* Use XNArea instead of XNAreaNeeded */
2252 attr
= XVaCreateNestedList (0, XNArea
, &needed
, NULL
);
2253 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2257 area
.width
= needed
->width
;
2258 area
.height
= needed
->height
;
2259 area
.x
= FRAME_PIXEL_WIDTH (f
) - area
.width
- FRAME_INTERNAL_BORDER_WIDTH (f
);
2260 area
.y
= (FRAME_PIXEL_HEIGHT (f
) - area
.height
2261 - FRAME_MENUBAR_HEIGHT (f
)
2262 - FRAME_TOOLBAR_TOP_HEIGHT (f
)
2263 - FRAME_INTERNAL_BORDER_WIDTH (f
));
2266 attr
= XVaCreateNestedList (0, XNArea
, &area
, NULL
);
2267 XSetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2272 /* Set X fontset for XIC of frame F, using base font name
2273 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2276 xic_set_xfontset (struct frame
*f
, const char *base_fontname
)
2281 xic_free_xfontset (f
);
2283 xfs
= xic_create_xfontset (f
);
2285 attr
= XVaCreateNestedList (0, XNFontSet
, xfs
, NULL
);
2286 if (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
)
2287 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2288 if (FRAME_XIC_STYLE (f
) & XIMStatusArea
)
2289 XSetICValues (FRAME_XIC (f
), XNStatusAttributes
, attr
, NULL
);
2292 FRAME_XIC_FONTSET (f
) = xfs
;
2295 #endif /* HAVE_X_I18N */
2299 #ifdef USE_X_TOOLKIT
2301 /* Create and set up the X widget for frame F. */
2304 x_window (struct frame
*f
, long window_prompting
)
2306 XClassHint class_hints
;
2307 XSetWindowAttributes attributes
;
2308 unsigned long attribute_mask
;
2309 Widget shell_widget
;
2311 Widget frame_widget
;
2317 /* Use the resource name as the top-level widget name
2318 for looking up resources. Make a non-Lisp copy
2319 for the window manager, so GC relocation won't bother it.
2321 Elsewhere we specify the window name for the window manager. */
2322 f
->namebuf
= xlispstrdup (Vx_resource_name
);
2325 XtSetArg (al
[ac
], XtNallowShellResize
, 1); ac
++;
2326 XtSetArg (al
[ac
], XtNinput
, 1); ac
++;
2327 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2328 XtSetArg (al
[ac
], XtNborderWidth
, f
->border_width
); ac
++;
2329 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2330 XtSetArg (al
[ac
], XtNdepth
, FRAME_DISPLAY_INFO (f
)->n_planes
); ac
++;
2331 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2332 shell_widget
= XtAppCreateShell (f
->namebuf
, EMACS_CLASS
,
2333 applicationShellWidgetClass
,
2334 FRAME_X_DISPLAY (f
), al
, ac
);
2336 f
->output_data
.x
->widget
= shell_widget
;
2337 /* maybe_set_screen_title_format (shell_widget); */
2339 pane_widget
= lw_create_widget ("main", "pane", widget_id_tick
++,
2340 NULL
, shell_widget
, False
,
2341 NULL
, NULL
, NULL
, NULL
);
2344 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2345 XtSetArg (al
[ac
], XtNdepth
, FRAME_DISPLAY_INFO (f
)->n_planes
); ac
++;
2346 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2347 XtSetArg (al
[ac
], XtNborderWidth
, 0); ac
++;
2348 XtSetValues (pane_widget
, al
, ac
);
2349 f
->output_data
.x
->column_widget
= pane_widget
;
2351 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2352 the emacs screen when changing menubar. This reduces flickering. */
2355 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2356 XtSetArg (al
[ac
], XtNshowGrip
, 0); ac
++;
2357 XtSetArg (al
[ac
], XtNallowResize
, 1); ac
++;
2358 XtSetArg (al
[ac
], XtNresizeToPreferred
, 1); ac
++;
2359 XtSetArg (al
[ac
], XtNemacsFrame
, f
); ac
++;
2360 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2361 XtSetArg (al
[ac
], XtNdepth
, FRAME_DISPLAY_INFO (f
)->n_planes
); ac
++;
2362 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2363 XtSetArg (al
[ac
], XtNborderWidth
, 0); ac
++;
2364 frame_widget
= XtCreateWidget (f
->namebuf
, emacsFrameClass
, pane_widget
,
2367 f
->output_data
.x
->edit_widget
= frame_widget
;
2369 XtManageChild (frame_widget
);
2371 /* Do some needed geometry management. */
2375 int extra_borders
= 0;
2377 = (f
->output_data
.x
->menubar_widget
2378 ? (f
->output_data
.x
->menubar_widget
->core
.height
2379 + f
->output_data
.x
->menubar_widget
->core
.border_width
)
2382 #if false /* Experimentally, we now get the right results
2383 for -geometry -0-0 without this. 24 Aug 96, rms. */
2384 if (FRAME_EXTERNAL_MENU_BAR (f
))
2387 XtVaGetValues (pane_widget
, XtNinternalBorderWidth
, &ibw
, NULL
);
2388 menubar_size
+= ibw
;
2392 FRAME_MENUBAR_HEIGHT (f
) = menubar_size
;
2395 /* Motif seems to need this amount added to the sizes
2396 specified for the shell widget. The Athena/Lucid widgets don't.
2397 Both conclusions reached experimentally. -- rms. */
2398 XtVaGetValues (f
->output_data
.x
->edit_widget
, XtNinternalBorderWidth
,
2399 &extra_borders
, NULL
);
2403 f
->shell_position
= xmalloc (sizeof "=x++" + 4 * INT_STRLEN_BOUND (int));
2405 /* Convert our geometry parameters into a geometry string
2407 Note that we do not specify here whether the position
2408 is a user-specified or program-specified one.
2409 We pass that information later, in x_wm_set_size_hints. */
2411 int left
= f
->left_pos
;
2412 bool xneg
= (window_prompting
& XNegative
) != 0;
2413 int top
= f
->top_pos
;
2414 bool yneg
= (window_prompting
& YNegative
) != 0;
2420 if (window_prompting
& USPosition
)
2421 sprintf (f
->shell_position
, "=%dx%d%c%d%c%d",
2422 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2423 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
,
2424 (xneg
? '-' : '+'), left
,
2425 (yneg
? '-' : '+'), top
);
2428 sprintf (f
->shell_position
, "=%dx%d",
2429 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2430 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
);
2432 /* Setting x and y when the position is not specified in
2433 the geometry string will set program position in the WM hints.
2434 If Emacs had just one program position, we could set it in
2435 fallback resources, but since each make-frame call can specify
2436 different program positions, this is easier. */
2437 XtSetArg (gal
[gac
], XtNx
, left
); gac
++;
2438 XtSetArg (gal
[gac
], XtNy
, top
); gac
++;
2442 XtSetArg (gal
[gac
], XtNgeometry
, f
->shell_position
); gac
++;
2443 XtSetValues (shell_widget
, gal
, gac
);
2446 XtManageChild (pane_widget
);
2447 XtRealizeWidget (shell_widget
);
2449 if (FRAME_X_EMBEDDED_P (f
))
2450 XReparentWindow (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
),
2451 f
->output_data
.x
->parent_desc
, 0, 0);
2453 FRAME_X_WINDOW (f
) = XtWindow (frame_widget
);
2455 validate_x_resource_name ();
2457 class_hints
.res_name
= SSDATA (Vx_resource_name
);
2458 class_hints
.res_class
= SSDATA (Vx_resource_class
);
2459 XSetClassHint (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
), &class_hints
);
2462 FRAME_XIC (f
) = NULL
;
2464 create_frame_xic (f
);
2467 f
->output_data
.x
->wm_hints
.input
= True
;
2468 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2469 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2470 &f
->output_data
.x
->wm_hints
);
2472 hack_wm_protocols (f
, shell_widget
);
2475 XtAddEventHandler (shell_widget
, 0, True
, _XEditResCheckMessages
, 0);
2478 /* Do a stupid property change to force the server to generate a
2479 PropertyNotify event so that the event_stream server timestamp will
2480 be initialized to something relevant to the time we created the window.
2482 XChangeProperty (XtDisplay (frame_widget
), XtWindow (frame_widget
),
2483 FRAME_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2484 XA_ATOM
, 32, PropModeAppend
, NULL
, 0);
2486 /* Make all the standard events reach the Emacs frame. */
2487 attributes
.event_mask
= STANDARD_EVENT_SET
;
2492 /* XIM server might require some X events. */
2493 unsigned long fevent
= NoEventMask
;
2494 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2495 attributes
.event_mask
|= fevent
;
2497 #endif /* HAVE_X_I18N */
2499 attribute_mask
= CWEventMask
;
2500 XChangeWindowAttributes (XtDisplay (shell_widget
), XtWindow (shell_widget
),
2501 attribute_mask
, &attributes
);
2503 XtMapWidget (frame_widget
);
2505 /* x_set_name normally ignores requests to set the name if the
2506 requested name is the same as the current name. This is the one
2507 place where that assumption isn't correct; f->name is set, but
2508 the X server hasn't been told. */
2511 bool explicit = f
->explicit_name
;
2513 f
->explicit_name
= false;
2515 fset_name (f
, Qnil
);
2516 x_set_name (f
, name
, explicit);
2519 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2520 f
->output_data
.x
->current_cursor
2521 = f
->output_data
.x
->text_cursor
);
2525 /* This is a no-op, except under Motif. Make sure main areas are
2526 set to something reasonable, in case we get an error later. */
2527 lw_set_main_areas (pane_widget
, 0, frame_widget
);
2530 #else /* not USE_X_TOOLKIT */
2533 x_window (struct frame
*f
)
2535 if (! xg_create_frame_widgets (f
))
2536 error ("Unable to create window");
2539 FRAME_XIC (f
) = NULL
;
2543 create_frame_xic (f
);
2546 /* XIM server might require some X events. */
2547 unsigned long fevent
= NoEventMask
;
2548 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2550 if (fevent
!= NoEventMask
)
2552 XSetWindowAttributes attributes
;
2553 XWindowAttributes wattr
;
2554 unsigned long attribute_mask
;
2556 XGetWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2558 attributes
.event_mask
= wattr
.your_event_mask
| fevent
;
2559 attribute_mask
= CWEventMask
;
2560 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2561 attribute_mask
, &attributes
);
2569 #else /*! USE_GTK */
2570 /* Create and set up the X window for frame F. */
2573 x_window (struct frame
*f
)
2575 XClassHint class_hints
;
2576 XSetWindowAttributes attributes
;
2577 unsigned long attribute_mask
;
2579 attributes
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
2580 attributes
.border_pixel
= f
->output_data
.x
->border_pixel
;
2581 attributes
.bit_gravity
= StaticGravity
;
2582 attributes
.backing_store
= NotUseful
;
2583 attributes
.save_under
= True
;
2584 attributes
.event_mask
= STANDARD_EVENT_SET
;
2585 attributes
.colormap
= FRAME_X_COLORMAP (f
);
2586 attribute_mask
= (CWBackPixel
| CWBorderPixel
| CWBitGravity
| CWEventMask
2591 = XCreateWindow (FRAME_X_DISPLAY (f
),
2592 f
->output_data
.x
->parent_desc
,
2595 FRAME_PIXEL_WIDTH (f
), FRAME_PIXEL_HEIGHT (f
),
2597 CopyFromParent
, /* depth */
2598 InputOutput
, /* class */
2600 attribute_mask
, &attributes
);
2605 create_frame_xic (f
);
2608 /* XIM server might require some X events. */
2609 unsigned long fevent
= NoEventMask
;
2610 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2611 attributes
.event_mask
|= fevent
;
2612 attribute_mask
= CWEventMask
;
2613 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2614 attribute_mask
, &attributes
);
2617 #endif /* HAVE_X_I18N */
2619 validate_x_resource_name ();
2621 class_hints
.res_name
= SSDATA (Vx_resource_name
);
2622 class_hints
.res_class
= SSDATA (Vx_resource_class
);
2623 XSetClassHint (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &class_hints
);
2625 /* This indicates that we use the "Passive Input" input model.
2626 Unless we do this, we don't get the Focus{In,Out} events that we
2627 need to draw the cursor correctly. Accursed bureaucrats.
2628 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2630 f
->output_data
.x
->wm_hints
.input
= True
;
2631 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2632 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2633 &f
->output_data
.x
->wm_hints
);
2634 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
2636 /* Request "save yourself" and "delete window" commands from wm. */
2639 protocols
[0] = FRAME_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2640 protocols
[1] = FRAME_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2641 XSetWMProtocols (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), protocols
, 2);
2644 /* x_set_name normally ignores requests to set the name if the
2645 requested name is the same as the current name. This is the one
2646 place where that assumption isn't correct; f->name is set, but
2647 the X server hasn't been told. */
2650 bool explicit = f
->explicit_name
;
2652 f
->explicit_name
= false;
2654 fset_name (f
, Qnil
);
2655 x_set_name (f
, name
, explicit);
2658 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2659 f
->output_data
.x
->current_cursor
2660 = f
->output_data
.x
->text_cursor
);
2664 if (FRAME_X_WINDOW (f
) == 0)
2665 error ("Unable to create window");
2668 #endif /* not USE_GTK */
2669 #endif /* not USE_X_TOOLKIT */
2671 /* Verify that the icon position args for this window are valid. */
2674 x_icon_verify (struct frame
*f
, Lisp_Object parms
)
2676 Lisp_Object icon_x
, icon_y
;
2678 /* Set the position of the icon. Note that twm groups all
2679 icons in an icon window. */
2680 icon_x
= x_frame_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
2681 icon_y
= x_frame_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
2682 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2684 CHECK_NUMBER (icon_x
);
2685 CHECK_NUMBER (icon_y
);
2687 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2688 error ("Both left and top icon corners of icon must be specified");
2691 /* Handle the icon stuff for this window. Perhaps later we might
2692 want an x_set_icon_position which can be called interactively as
2696 x_icon (struct frame
*f
, Lisp_Object parms
)
2698 /* Set the position of the icon. Note that twm groups all
2699 icons in an icon window. */
2701 = x_frame_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
2703 = x_frame_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
2704 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2706 CHECK_TYPE_RANGED_INTEGER (int, icon_x
);
2707 CHECK_TYPE_RANGED_INTEGER (int, icon_y
);
2709 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2710 error ("Both left and top icon corners of icon must be specified");
2714 if (! EQ (icon_x
, Qunbound
))
2715 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
2717 #if false /* x_get_arg removes the visibility parameter as a side effect,
2718 but x_create_frame still needs it. */
2719 /* Start up iconic or window? */
2720 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
2721 x_wm_set_window_state
2722 (f
, (EQ (x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
),
2728 x_text_icon (f
, SSDATA ((!NILP (f
->icon_name
)
2735 /* Make the GCs needed for this window, setting the
2736 background, border and mouse colors; also create the
2737 mouse cursor and the gray border tile. */
2740 x_make_gc (struct frame
*f
)
2742 XGCValues gc_values
;
2746 /* Create the GCs of this frame.
2747 Note that many default values are used. */
2749 gc_values
.foreground
= FRAME_FOREGROUND_PIXEL (f
);
2750 gc_values
.background
= FRAME_BACKGROUND_PIXEL (f
);
2751 gc_values
.line_width
= 0; /* Means 1 using fast algorithm. */
2752 f
->output_data
.x
->normal_gc
2753 = XCreateGC (FRAME_X_DISPLAY (f
),
2755 GCLineWidth
| GCForeground
| GCBackground
,
2758 /* Reverse video style. */
2759 gc_values
.foreground
= FRAME_BACKGROUND_PIXEL (f
);
2760 gc_values
.background
= FRAME_FOREGROUND_PIXEL (f
);
2761 f
->output_data
.x
->reverse_gc
2762 = XCreateGC (FRAME_X_DISPLAY (f
),
2764 GCForeground
| GCBackground
| GCLineWidth
,
2767 /* Cursor has cursor-color background, background-color foreground. */
2768 gc_values
.foreground
= FRAME_BACKGROUND_PIXEL (f
);
2769 gc_values
.background
= f
->output_data
.x
->cursor_pixel
;
2770 gc_values
.fill_style
= FillOpaqueStippled
;
2771 f
->output_data
.x
->cursor_gc
2772 = XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2773 (GCForeground
| GCBackground
2774 | GCFillStyle
| GCLineWidth
),
2777 /* Create the gray border tile used when the pointer is not in
2778 the frame. Since this depends on the frame's pixel values,
2779 this must be done on a per-frame basis. */
2780 f
->output_data
.x
->border_tile
2781 = (XCreatePixmapFromBitmapData
2782 (FRAME_X_DISPLAY (f
), FRAME_DISPLAY_INFO (f
)->root_window
,
2783 gray_bits
, gray_width
, gray_height
,
2784 FRAME_FOREGROUND_PIXEL (f
),
2785 FRAME_BACKGROUND_PIXEL (f
),
2786 DefaultDepth (FRAME_X_DISPLAY (f
), FRAME_X_SCREEN_NUMBER (f
))));
2792 /* Free what was allocated in x_make_gc. */
2795 x_free_gcs (struct frame
*f
)
2797 Display
*dpy
= FRAME_X_DISPLAY (f
);
2801 if (f
->output_data
.x
->normal_gc
)
2803 XFreeGC (dpy
, f
->output_data
.x
->normal_gc
);
2804 f
->output_data
.x
->normal_gc
= 0;
2807 if (f
->output_data
.x
->reverse_gc
)
2809 XFreeGC (dpy
, f
->output_data
.x
->reverse_gc
);
2810 f
->output_data
.x
->reverse_gc
= 0;
2813 if (f
->output_data
.x
->cursor_gc
)
2815 XFreeGC (dpy
, f
->output_data
.x
->cursor_gc
);
2816 f
->output_data
.x
->cursor_gc
= 0;
2819 if (f
->output_data
.x
->border_tile
)
2821 XFreePixmap (dpy
, f
->output_data
.x
->border_tile
);
2822 f
->output_data
.x
->border_tile
= 0;
2829 /* Handler for signals raised during x_create_frame and
2830 x_create_tip_frame. FRAME is the frame which is partially
2834 unwind_create_frame (Lisp_Object frame
)
2836 struct frame
*f
= XFRAME (frame
);
2838 /* If frame is already dead, nothing to do. This can happen if the
2839 display is disconnected after the frame has become official, but
2840 before x_create_frame removes the unwind protect. */
2841 if (!FRAME_LIVE_P (f
))
2844 /* If frame is ``official'', nothing to do. */
2845 if (NILP (Fmemq (frame
, Vframe_list
)))
2847 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2848 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
2851 /* If the frame's image cache refcount is still the same as our
2852 private shadow variable, it means we are unwinding a frame
2853 for which we didn't yet call init_frame_faces, where the
2854 refcount is incremented. Therefore, we increment it here, so
2855 that free_frame_faces, called in x_free_frame_resources
2856 below, will not mistakenly decrement the counter that was not
2857 incremented yet to account for this new frame. */
2858 if (FRAME_IMAGE_CACHE (f
) != NULL
2859 && FRAME_IMAGE_CACHE (f
)->refcount
== image_cache_refcount
)
2860 FRAME_IMAGE_CACHE (f
)->refcount
++;
2862 x_free_frame_resources (f
);
2865 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2866 /* Check that reference counts are indeed correct. */
2867 eassert (dpyinfo
->reference_count
== dpyinfo_refcount
);
2868 eassert (dpyinfo
->terminal
->image_cache
->refcount
== image_cache_refcount
);
2877 do_unwind_create_frame (Lisp_Object frame
)
2879 unwind_create_frame (frame
);
2883 x_default_font_parameter (struct frame
*f
, Lisp_Object parms
)
2885 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
2886 Lisp_Object font_param
= x_get_arg (dpyinfo
, parms
, Qfont
, NULL
, NULL
,
2888 Lisp_Object font
= Qnil
;
2889 if (EQ (font_param
, Qunbound
))
2892 if (NILP (font_param
))
2894 /* System font should take precedence over X resources. We suggest this
2895 regardless of font-use-system-font because .emacs may not have been
2897 const char *system_font
= xsettings_get_system_font ();
2899 font
= font_open_by_name (f
, build_unibyte_string (system_font
));
2903 font
= !NILP (font_param
) ? font_param
2904 : x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
2906 if (! FONTP (font
) && ! STRINGP (font
))
2911 /* This will find the normal Xft font. */
2914 "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
2915 "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
2916 "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
2917 /* This was formerly the first thing tried, but it finds
2918 too many fonts and takes too long. */
2919 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
2920 /* If those didn't work, look for something which will
2922 "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
2927 for (i
= 0; names
[i
]; i
++)
2929 font
= font_open_by_name (f
, build_unibyte_string (names
[i
]));
2934 error ("No suitable font was found");
2936 else if (!NILP (font_param
))
2938 /* Remember the explicit font parameter, so we can re-apply it after
2939 we've applied the `default' face settings. */
2940 AUTO_FRAME_ARG (arg
, Qfont_param
, font_param
);
2941 x_set_frame_parameters (f
, arg
);
2944 /* This call will make X resources override any system font setting. */
2945 x_default_parameter (f
, parms
, Qfont
, font
, "font", "Font", RES_TYPE_STRING
);
2949 DEFUN ("x-wm-set-size-hint", Fx_wm_set_size_hint
, Sx_wm_set_size_hint
,
2951 doc
: /* Send the size hints for frame FRAME to the window manager.
2952 If FRAME is omitted or nil, use the selected frame.
2953 Signal error if FRAME is not an X frame. */)
2956 struct frame
*f
= decode_window_system_frame (frame
);
2959 x_wm_set_size_hint (f
, 0, false);
2965 set_machine_and_pid_properties (struct frame
*f
)
2967 /* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME. */
2968 XSetWMProperties (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), NULL
, NULL
,
2969 NULL
, 0, NULL
, NULL
, NULL
);
2970 pid_t pid
= getpid ();
2971 if (pid
<= 0xffffffffu
)
2973 unsigned long xpid
= pid
;
2974 XChangeProperty (FRAME_X_DISPLAY (f
),
2975 FRAME_OUTER_WINDOW (f
),
2976 XInternAtom (FRAME_X_DISPLAY (f
),
2979 XA_CARDINAL
, 32, PropModeReplace
,
2980 (unsigned char *) &xpid
, 1);
2984 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
2986 doc
: /* Make a new X window, which is called a "frame" in Emacs terms.
2987 Return an Emacs frame object. PARMS is an alist of frame parameters.
2988 If the parameters specify that the frame should not have a minibuffer,
2989 and do not specify a specific minibuffer window to use, then
2990 `default-minibuffer-frame' must be a frame whose minibuffer can be
2991 shared by the new frame.
2993 This function is an internal primitive--use `make-frame' instead. */)
2997 Lisp_Object frame
, tem
;
2999 bool minibuffer_only
= false;
3000 long window_prompting
= 0;
3001 ptrdiff_t count
= SPECPDL_INDEX ();
3002 Lisp_Object display
;
3003 struct x_display_info
*dpyinfo
= NULL
;
3006 int x_width
= 0, x_height
= 0;
3008 parms
= Fcopy_alist (parms
);
3010 /* Use this general default value to start with
3011 until we know if this frame has a specified name. */
3012 Vx_resource_name
= Vinvocation_name
;
3014 display
= x_get_arg (dpyinfo
, parms
, Qterminal
, 0, 0, RES_TYPE_NUMBER
);
3015 if (EQ (display
, Qunbound
))
3016 display
= x_get_arg (dpyinfo
, parms
, Qdisplay
, 0, 0, RES_TYPE_STRING
);
3017 if (EQ (display
, Qunbound
))
3019 dpyinfo
= check_x_display_info (display
);
3020 kb
= dpyinfo
->terminal
->kboard
;
3022 if (!dpyinfo
->terminal
->name
)
3023 error ("Terminal is not live, can't create new frames on it");
3025 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
3027 && ! EQ (name
, Qunbound
)
3029 error ("Invalid frame name--not a string or nil");
3032 Vx_resource_name
= name
;
3034 /* See if parent window is specified. */
3035 parent
= x_get_arg (dpyinfo
, parms
, Qparent_id
, NULL
, NULL
, RES_TYPE_NUMBER
);
3036 if (EQ (parent
, Qunbound
))
3038 if (! NILP (parent
))
3039 CHECK_NUMBER (parent
);
3042 tem
= x_get_arg (dpyinfo
, parms
, Qminibuffer
, "minibuffer", "Minibuffer",
3044 if (EQ (tem
, Qnone
) || NILP (tem
))
3045 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
3046 else if (EQ (tem
, Qonly
))
3048 f
= make_minibuffer_frame ();
3049 minibuffer_only
= true;
3051 else if (WINDOWP (tem
))
3052 f
= make_frame_without_minibuffer (tem
, kb
, display
);
3054 f
= make_frame (true);
3056 XSETFRAME (frame
, f
);
3058 f
->terminal
= dpyinfo
->terminal
;
3060 f
->output_method
= output_x_window
;
3061 f
->output_data
.x
= xzalloc (sizeof *f
->output_data
.x
);
3062 f
->output_data
.x
->icon_bitmap
= -1;
3063 FRAME_FONTSET (f
) = -1;
3064 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
3065 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
3066 #if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
3067 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
3068 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
3069 #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
3070 f
->output_data
.x
->white_relief
.pixel
= -1;
3071 f
->output_data
.x
->black_relief
.pixel
= -1;
3074 x_get_arg (dpyinfo
, parms
, Qicon_name
, "iconName", "Title",
3076 if (! STRINGP (f
->icon_name
))
3077 fset_icon_name (f
, Qnil
);
3079 FRAME_DISPLAY_INFO (f
) = dpyinfo
;
3081 /* With FRAME_DISPLAY_INFO set up, this unwind-protect is safe. */
3082 record_unwind_protect (do_unwind_create_frame
, frame
);
3084 /* These colors will be set anyway later, but it's important
3085 to get the color reference counts right, so initialize them! */
3089 /* Function x_decode_color can signal an error. Make
3090 sure to initialize color slots so that we won't try
3091 to free colors we haven't allocated. */
3092 FRAME_FOREGROUND_PIXEL (f
) = -1;
3093 FRAME_BACKGROUND_PIXEL (f
) = -1;
3094 f
->output_data
.x
->cursor_pixel
= -1;
3095 f
->output_data
.x
->cursor_foreground_pixel
= -1;
3096 f
->output_data
.x
->border_pixel
= -1;
3097 f
->output_data
.x
->mouse_pixel
= -1;
3099 black
= build_string ("black");
3100 FRAME_FOREGROUND_PIXEL (f
)
3101 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3102 FRAME_BACKGROUND_PIXEL (f
)
3103 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3104 f
->output_data
.x
->cursor_pixel
3105 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3106 f
->output_data
.x
->cursor_foreground_pixel
3107 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3108 f
->output_data
.x
->border_pixel
3109 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3110 f
->output_data
.x
->mouse_pixel
3111 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3114 /* Specify the parent under which to make this X window. */
3117 f
->output_data
.x
->parent_desc
= (Window
) XFASTINT (parent
);
3118 f
->output_data
.x
->explicit_parent
= true;
3122 f
->output_data
.x
->parent_desc
= FRAME_DISPLAY_INFO (f
)->root_window
;
3123 f
->output_data
.x
->explicit_parent
= false;
3126 /* Set the name; the functions to which we pass f expect the name to
3128 if (EQ (name
, Qunbound
) || NILP (name
))
3130 fset_name (f
, build_string (dpyinfo
->x_id_name
));
3131 f
->explicit_name
= false;
3135 fset_name (f
, name
);
3136 f
->explicit_name
= true;
3137 /* Use the frame's title when getting resources for this frame. */
3138 specbind (Qx_resource_name
, name
);
3142 register_font_driver (&ftcrfont_driver
, f
);
3144 #ifdef HAVE_FREETYPE
3146 register_font_driver (&xftfont_driver
, f
);
3147 #else /* not HAVE_XFT */
3148 register_font_driver (&ftxfont_driver
, f
);
3149 #endif /* not HAVE_XFT */
3150 #endif /* HAVE_FREETYPE */
3151 register_font_driver (&xfont_driver
, f
);
3152 #endif /* not USE_CAIRO */
3154 image_cache_refcount
=
3155 FRAME_IMAGE_CACHE (f
) ? FRAME_IMAGE_CACHE (f
)->refcount
: 0;
3157 dpyinfo_refcount
= dpyinfo
->reference_count
;
3158 #endif /* GLYPH_DEBUG */
3160 x_default_parameter (f
, parms
, Qfont_backend
, Qnil
,
3161 "fontBackend", "FontBackend", RES_TYPE_STRING
);
3163 /* Extract the window parameters from the supplied values
3164 that are needed to determine window geometry. */
3165 x_default_font_parameter (f
, parms
);
3166 if (!FRAME_FONT (f
))
3168 delete_frame (frame
, Qnoelisp
);
3169 error ("Invalid frame font");
3172 /* Frame contents get displaced if an embedded X window has a border. */
3173 if (! FRAME_X_EMBEDDED_P (f
))
3174 x_default_parameter (f
, parms
, Qborder_width
, make_number (0),
3175 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
3177 /* This defaults to 1 in order to match xterm. We recognize either
3178 internalBorderWidth or internalBorder (which is what xterm calls
3180 if (NILP (Fassq (Qinternal_border_width
, parms
)))
3184 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
3185 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
3186 if (! EQ (value
, Qunbound
))
3187 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
3190 x_default_parameter (f
, parms
, Qinternal_border_width
,
3191 #ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */
3196 "internalBorderWidth", "internalBorderWidth",
3198 x_default_parameter (f
, parms
, Qright_divider_width
, make_number (0),
3199 NULL
, NULL
, RES_TYPE_NUMBER
);
3200 x_default_parameter (f
, parms
, Qbottom_divider_width
, make_number (0),
3201 NULL
, NULL
, RES_TYPE_NUMBER
);
3202 x_default_parameter (f
, parms
, Qvertical_scroll_bars
,
3203 #if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
3208 "verticalScrollBars", "ScrollBars",
3210 x_default_parameter (f
, parms
, Qhorizontal_scroll_bars
, Qnil
,
3211 "horizontalScrollBars", "ScrollBars",
3213 /* Also do the stuff which must be set before the window exists. */
3214 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
3215 "foreground", "Foreground", RES_TYPE_STRING
);
3216 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
3217 "background", "Background", RES_TYPE_STRING
);
3218 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
3219 "pointerColor", "Foreground", RES_TYPE_STRING
);
3220 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
3221 "borderColor", "BorderColor", RES_TYPE_STRING
);
3222 x_default_parameter (f
, parms
, Qscreen_gamma
, Qnil
,
3223 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT
);
3224 x_default_parameter (f
, parms
, Qline_spacing
, Qnil
,
3225 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER
);
3226 x_default_parameter (f
, parms
, Qleft_fringe
, Qnil
,
3227 "leftFringe", "LeftFringe", RES_TYPE_NUMBER
);
3228 x_default_parameter (f
, parms
, Qright_fringe
, Qnil
,
3229 "rightFringe", "RightFringe", RES_TYPE_NUMBER
);
3231 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_foreground
,
3232 "scrollBarForeground",
3233 "ScrollBarForeground", true);
3234 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_background
,
3235 "scrollBarBackground",
3236 "ScrollBarBackground", false);
3238 /* Init faces before x_default_parameter is called for the
3239 scroll-bar-width parameter because otherwise we end up in
3240 init_iterator with a null face cache, which should not happen. */
3241 init_frame_faces (f
);
3243 /* The following call of change_frame_size is needed since otherwise
3244 x_set_tool_bar_lines will already work with the character sizes
3245 installed by init_frame_faces while the frame's pixel size is
3246 still calculated from a character size of 1 and we subsequently
3247 hit the (height >= 0) assertion in window_box_height.
3249 The non-pixelwise code apparently worked around this because it
3250 had one frame line vs one toolbar line which left us with a zero
3251 root window height which was obviously wrong as well ... */
3252 adjust_frame_size (f
, FRAME_COLS (f
) * FRAME_COLUMN_WIDTH (f
),
3253 FRAME_LINES (f
) * FRAME_LINE_HEIGHT (f
), 5, true,
3256 /* Set the menu-bar-lines and tool-bar-lines parameters. We don't
3257 look up the X resources controlling the menu-bar and tool-bar
3258 here; they are processed specially at startup, and reflected in
3259 the values of the mode variables. */
3261 x_default_parameter (f
, parms
, Qmenu_bar_lines
,
3262 NILP (Vmenu_bar_mode
)
3263 ? make_number (0) : make_number (1),
3264 NULL
, NULL
, RES_TYPE_NUMBER
);
3265 x_default_parameter (f
, parms
, Qtool_bar_lines
,
3266 NILP (Vtool_bar_mode
)
3267 ? make_number (0) : make_number (1),
3268 NULL
, NULL
, RES_TYPE_NUMBER
);
3270 x_default_parameter (f
, parms
, Qbuffer_predicate
, Qnil
,
3271 "bufferPredicate", "BufferPredicate",
3273 x_default_parameter (f
, parms
, Qtitle
, Qnil
,
3274 "title", "Title", RES_TYPE_STRING
);
3275 x_default_parameter (f
, parms
, Qwait_for_wm
, Qt
,
3276 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN
);
3277 x_default_parameter (f
, parms
, Qtool_bar_position
,
3278 FRAME_TOOL_BAR_POSITION (f
), 0, 0, RES_TYPE_SYMBOL
);
3280 /* Compute the size of the X window. */
3281 window_prompting
= x_figure_window_size (f
, parms
, true, &x_width
, &x_height
);
3283 tem
= x_get_arg (dpyinfo
, parms
, Qunsplittable
, 0, 0, RES_TYPE_BOOLEAN
);
3284 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
3286 x_icon_verify (f
, parms
);
3288 /* Create the X widget or window. */
3289 #ifdef USE_X_TOOLKIT
3290 x_window (f
, window_prompting
);
3298 /* Now consider the frame official. */
3299 f
->terminal
->reference_count
++;
3300 FRAME_DISPLAY_INFO (f
)->reference_count
++;
3301 Vframe_list
= Fcons (frame
, Vframe_list
);
3303 /* We need to do this after creating the X window, so that the
3304 icon-creation functions can say whose icon they're describing. */
3305 x_default_parameter (f
, parms
, Qicon_type
, Qt
,
3306 "bitmapIcon", "BitmapIcon", RES_TYPE_BOOLEAN
);
3308 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
3309 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3310 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
3311 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3312 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
3313 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
3314 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
3315 "scrollBarWidth", "ScrollBarWidth",
3317 x_default_parameter (f
, parms
, Qscroll_bar_height
, Qnil
,
3318 "scrollBarHeight", "ScrollBarHeight",
3320 x_default_parameter (f
, parms
, Qalpha
, Qnil
,
3321 "alpha", "Alpha", RES_TYPE_NUMBER
);
3323 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3324 /* Create the menu bar. */
3325 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
3327 /* If this signals an error, we haven't set size hints for the
3328 frame and we didn't make it visible. */
3329 initialize_frame_menubar (f
);
3332 /* This is a no-op, except under Motif where it arranges the
3333 main window for the widgets on it. */
3334 lw_set_main_areas (f
->output_data
.x
->column_widget
,
3335 f
->output_data
.x
->menubar_widget
,
3336 f
->output_data
.x
->edit_widget
);
3337 #endif /* not USE_GTK */
3339 #endif /* USE_X_TOOLKIT || USE_GTK */
3341 /* Consider frame official, now. */
3342 f
->can_x_set_window_size
= true;
3345 SET_FRAME_WIDTH (f
, x_width
);
3347 SET_FRAME_HEIGHT (f
, x_height
);
3349 /* Tell the server what size and position, etc, we want, and how
3350 badly we want them. This should be done after we have the menu
3351 bar so that its size can be taken into account. */
3353 x_wm_set_size_hint (f
, window_prompting
, false);
3356 adjust_frame_size (f
, FRAME_TEXT_WIDTH (f
), FRAME_TEXT_HEIGHT (f
),
3357 0, true, Qx_create_frame_2
);
3359 /* Process fullscreen parameter here in the hope that normalizing a
3360 fullheight/fullwidth frame will produce the size set by the last
3361 adjust_frame_size call. */
3362 x_default_parameter (f
, parms
, Qfullscreen
, Qnil
,
3363 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL
);
3365 /* Make the window appear on the frame and enable display, unless
3366 the caller says not to. However, with explicit parent, Emacs
3367 cannot control visibility, so don't try. */
3368 if (! f
->output_data
.x
->explicit_parent
)
3370 Lisp_Object visibility
;
3372 visibility
= x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0,
3374 if (EQ (visibility
, Qunbound
))
3377 if (EQ (visibility
, Qicon
))
3378 x_iconify_frame (f
);
3379 else if (! NILP (visibility
))
3380 x_make_frame_visible (f
);
3383 /* Must have been Qnil. */
3389 /* Set machine name and pid for the purpose of window managers. */
3390 set_machine_and_pid_properties (f
);
3392 /* Set the WM leader property. GTK does this itself, so this is not
3393 needed when using GTK. */
3394 if (dpyinfo
->client_leader_window
!= 0)
3396 XChangeProperty (FRAME_X_DISPLAY (f
),
3397 FRAME_OUTER_WINDOW (f
),
3398 dpyinfo
->Xatom_wm_client_leader
,
3399 XA_WINDOW
, 32, PropModeReplace
,
3400 (unsigned char *) &dpyinfo
->client_leader_window
, 1);
3405 /* Initialize `default-minibuffer-frame' in case this is the first
3406 frame on this terminal. */
3407 if (FRAME_HAS_MINIBUF_P (f
)
3408 && (!FRAMEP (KVAR (kb
, Vdefault_minibuffer_frame
))
3409 || !FRAME_LIVE_P (XFRAME (KVAR (kb
, Vdefault_minibuffer_frame
)))))
3410 kset_default_minibuffer_frame (kb
, frame
);
3412 /* All remaining specified parameters, which have not been "used"
3413 by x_get_arg and friends, now go in the misc. alist of the frame. */
3414 for (tem
= parms
; CONSP (tem
); tem
= XCDR (tem
))
3415 if (CONSP (XCAR (tem
)) && !NILP (XCAR (XCAR (tem
))))
3416 fset_param_alist (f
, Fcons (XCAR (tem
), f
->param_alist
));
3418 /* Make sure windows on this frame appear in calls to next-window
3419 and similar functions. */
3420 Vwindow_list
= Qnil
;
3422 return unbind_to (count
, frame
);
3426 /* FRAME is used only to get a handle on the X display. We don't pass the
3427 display info directly because we're called from frame.c, which doesn't
3428 know about that structure. */
3431 x_get_focus_frame (struct frame
*frame
)
3433 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (frame
);
3435 if (! dpyinfo
->x_focus_frame
)
3438 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
3443 /* In certain situations, when the window manager follows a
3444 click-to-focus policy, there seems to be no way around calling
3445 XSetInputFocus to give another frame the input focus .
3447 In an ideal world, XSetInputFocus should generally be avoided so
3448 that applications don't interfere with the window manager's focus
3449 policy. But I think it's okay to use when it's clearly done
3450 following a user-command. */
3453 x_focus_frame (struct frame
*f
)
3455 Display
*dpy
= FRAME_X_DISPLAY (f
);
3458 x_catch_errors (dpy
);
3460 if (FRAME_X_EMBEDDED_P (f
))
3462 /* For Xembedded frames, normally the embedder forwards key
3463 events. See XEmbed Protocol Specification at
3464 http://freedesktop.org/wiki/Specifications/xembed-spec */
3465 xembed_request_focus (f
);
3469 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3470 RevertToParent
, CurrentTime
);
3471 x_ewmh_activate_frame (f
);
3474 x_uncatch_errors ();
3479 DEFUN ("xw-color-defined-p", Fxw_color_defined_p
, Sxw_color_defined_p
, 1, 2, 0,
3480 doc
: /* Internal function called by `color-defined-p', which see.
3481 (Note that the Nextstep version of this function ignores FRAME.) */)
3482 (Lisp_Object color
, Lisp_Object frame
)
3485 struct frame
*f
= decode_window_system_frame (frame
);
3487 CHECK_STRING (color
);
3489 if (x_defined_color (f
, SSDATA (color
), &foo
, false))
3495 DEFUN ("xw-color-values", Fxw_color_values
, Sxw_color_values
, 1, 2, 0,
3496 doc
: /* Internal function called by `color-values', which see. */)
3497 (Lisp_Object color
, Lisp_Object frame
)
3500 struct frame
*f
= decode_window_system_frame (frame
);
3502 CHECK_STRING (color
);
3504 if (x_defined_color (f
, SSDATA (color
), &foo
, false))
3505 return list3i (foo
.red
, foo
.green
, foo
.blue
);
3510 DEFUN ("xw-display-color-p", Fxw_display_color_p
, Sxw_display_color_p
, 0, 1, 0,
3511 doc
: /* Internal function called by `display-color-p', which see. */)
3512 (Lisp_Object terminal
)
3514 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3516 if (dpyinfo
->n_planes
<= 2)
3519 switch (dpyinfo
->visual
->class)
3532 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
3534 doc
: /* Return t if the X display supports shades of gray.
3535 Note that color displays do support shades of gray.
3536 The optional argument TERMINAL specifies which display to ask about.
3537 TERMINAL should be a terminal object, a frame or a display name (a string).
3538 If omitted or nil, that stands for the selected frame's display. */)
3539 (Lisp_Object terminal
)
3541 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3543 if (dpyinfo
->n_planes
<= 1)
3546 switch (dpyinfo
->visual
->class)
3561 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
3563 doc
: /* Return the width in pixels of the X display TERMINAL.
3564 The optional argument TERMINAL specifies which display to ask about.
3565 TERMINAL should be a terminal object, a frame or a display name (a string).
3566 If omitted or nil, that stands for the selected frame's display.
3568 On \"multi-monitor\" setups this refers to the pixel width for all
3569 physical monitors associated with TERMINAL. To get information for
3570 each physical monitor, use `display-monitor-attributes-list'. */)
3571 (Lisp_Object terminal
)
3573 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3575 return make_number (x_display_pixel_width (dpyinfo
));
3578 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
3579 Sx_display_pixel_height
, 0, 1, 0,
3580 doc
: /* Return the height in pixels of the X display TERMINAL.
3581 The optional argument TERMINAL specifies which display to ask about.
3582 TERMINAL should be a terminal object, a frame or a display name (a string).
3583 If omitted or nil, that stands for the selected frame's display.
3585 On \"multi-monitor\" setups this refers to the pixel height for all
3586 physical monitors associated with TERMINAL. To get information for
3587 each physical monitor, use `display-monitor-attributes-list'. */)
3588 (Lisp_Object terminal
)
3590 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3592 return make_number (x_display_pixel_height (dpyinfo
));
3595 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
3597 doc
: /* Return the number of bitplanes of the X display TERMINAL.
3598 The optional argument TERMINAL specifies which display to ask about.
3599 TERMINAL should be a terminal object, a frame or a display name (a string).
3600 If omitted or nil, that stands for the selected frame's display. */)
3601 (Lisp_Object terminal
)
3603 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3605 return make_number (dpyinfo
->n_planes
);
3608 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
3610 doc
: /* Return the number of color cells of the X display TERMINAL.
3611 The optional argument TERMINAL specifies which display to ask about.
3612 TERMINAL should be a terminal object, a frame or a display name (a string).
3613 If omitted or nil, that stands for the selected frame's display. */)
3614 (Lisp_Object terminal
)
3616 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3618 int nr_planes
= DisplayPlanes (dpyinfo
->display
,
3619 XScreenNumberOfScreen (dpyinfo
->screen
));
3621 /* Truncate nr_planes to 24 to avoid integer overflow.
3622 Some displays says 32, but only 24 bits are actually significant.
3623 There are only very few and rare video cards that have more than
3624 24 significant bits. Also 24 bits is more than 16 million colors,
3625 it "should be enough for everyone". */
3626 if (nr_planes
> 24) nr_planes
= 24;
3628 return make_number (1 << nr_planes
);
3631 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
3632 Sx_server_max_request_size
,
3634 doc
: /* Return the maximum request size of the X server of display TERMINAL.
3635 The optional argument TERMINAL specifies which display to ask about.
3636 TERMINAL should be a terminal object, a frame or a display name (a string).
3637 If omitted or nil, that stands for the selected frame's display. */)
3638 (Lisp_Object terminal
)
3640 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3642 return make_number (MAXREQUEST (dpyinfo
->display
));
3645 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
3646 doc
: /* Return the "vendor ID" string of the GUI software on TERMINAL.
3648 (Labeling every distributor as a "vendor" embodies the false assumption
3649 that operating systems cannot be developed and distributed noncommercially.)
3650 The optional argument TERMINAL specifies which display to ask about.
3652 For GNU and Unix systems, this queries the X server software; for
3653 MS-Windows, this queries the OS.
3655 TERMINAL should be a terminal object, a frame or a display name (a string).
3656 If omitted or nil, that stands for the selected frame's display. */)
3657 (Lisp_Object terminal
)
3659 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3660 const char *vendor
= ServerVendor (dpyinfo
->display
);
3662 if (! vendor
) vendor
= "";
3663 return build_string (vendor
);
3666 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
3667 doc
: /* Return the version numbers of the GUI software on TERMINAL.
3668 The value is a list of three integers specifying the version of the GUI
3671 For GNU and Unix system, the first 2 numbers are the version of the X
3672 Protocol used on TERMINAL and the 3rd number is the distributor-specific
3673 release number. For MS-Windows, the 3 numbers report the version and
3674 the build number of the OS.
3676 See also the function `x-server-vendor'.
3678 The optional argument TERMINAL specifies which display to ask about.
3679 TERMINAL should be a terminal object, a frame or a display name (a string).
3680 If omitted or nil, that stands for the selected frame's display. */)
3681 (Lisp_Object terminal
)
3683 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3684 Display
*dpy
= dpyinfo
->display
;
3686 return list3i (ProtocolVersion (dpy
), ProtocolRevision (dpy
),
3687 VendorRelease (dpy
));
3690 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
3691 doc
: /* Return the number of screens on the X server of display TERMINAL.
3692 The optional argument TERMINAL specifies which display to ask about.
3693 TERMINAL should be a terminal object, a frame or a display name (a string).
3694 If omitted or nil, that stands for the selected frame's display. */)
3695 (Lisp_Object terminal
)
3697 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3699 return make_number (ScreenCount (dpyinfo
->display
));
3702 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
3703 doc
: /* Return the height in millimeters of the X display TERMINAL.
3704 The optional argument TERMINAL specifies which display to ask about.
3705 TERMINAL should be a terminal object, a frame or a display name (a string).
3706 If omitted or nil, that stands for the selected frame's display.
3708 On \"multi-monitor\" setups this refers to the height in millimeters for
3709 all physical monitors associated with TERMINAL. To get information
3710 for each physical monitor, use `display-monitor-attributes-list'. */)
3711 (Lisp_Object terminal
)
3713 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3715 return make_number (HeightMMOfScreen (dpyinfo
->screen
));
3718 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
3719 doc
: /* Return the width in millimeters of the X display TERMINAL.
3720 The optional argument TERMINAL specifies which display to ask about.
3721 TERMINAL should be a terminal object, a frame or a display name (a string).
3722 If omitted or nil, that stands for the selected frame's display.
3724 On \"multi-monitor\" setups this refers to the width in millimeters for
3725 all physical monitors associated with TERMINAL. To get information
3726 for each physical monitor, use `display-monitor-attributes-list'. */)
3727 (Lisp_Object terminal
)
3729 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3731 return make_number (WidthMMOfScreen (dpyinfo
->screen
));
3734 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
3735 Sx_display_backing_store
, 0, 1, 0,
3736 doc
: /* Return an indication of whether X display TERMINAL does backing store.
3737 The value may be `always', `when-mapped', or `not-useful'.
3738 The optional argument TERMINAL specifies which display to ask about.
3739 TERMINAL should be a terminal object, a frame or a display name (a string).
3740 If omitted or nil, that stands for the selected frame's display. */)
3741 (Lisp_Object terminal
)
3743 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3746 switch (DoesBackingStore (dpyinfo
->screen
))
3749 result
= intern ("always");
3753 result
= intern ("when-mapped");
3757 result
= intern ("not-useful");
3761 error ("Strange value for BackingStore parameter of screen");
3767 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
3768 Sx_display_visual_class
, 0, 1, 0,
3769 doc
: /* Return the visual class of the X display TERMINAL.
3770 The value is one of the symbols `static-gray', `gray-scale',
3771 `static-color', `pseudo-color', `true-color', or `direct-color'.
3773 The optional argument TERMINAL specifies which display to ask about.
3774 TERMINAL should a terminal object, a frame or a display name (a string).
3775 If omitted or nil, that stands for the selected frame's display. */)
3776 (Lisp_Object terminal
)
3778 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3781 switch (dpyinfo
->visual
->class)
3784 result
= intern ("static-gray");
3787 result
= intern ("gray-scale");
3790 result
= intern ("static-color");
3793 result
= intern ("pseudo-color");
3796 result
= intern ("true-color");
3799 result
= intern ("direct-color");
3802 error ("Display has an unknown visual class");
3808 DEFUN ("x-display-save-under", Fx_display_save_under
,
3809 Sx_display_save_under
, 0, 1, 0,
3810 doc
: /* Return t if the X display TERMINAL supports the save-under feature.
3811 The optional argument TERMINAL specifies which display to ask about.
3812 TERMINAL should be a terminal object, a frame or a display name (a string).
3813 If omitted or nil, that stands for the selected frame's display. */)
3814 (Lisp_Object terminal
)
3816 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3818 if (DoesSaveUnders (dpyinfo
->screen
) == True
)
3824 /* Store the geometry of the workarea on display DPYINFO into *RECT.
3825 Return false if and only if the workarea information cannot be
3826 obtained via the _NET_WORKAREA root window property. */
3828 #if ! GTK_CHECK_VERSION (3, 4, 0)
3830 x_get_net_workarea (struct x_display_info
*dpyinfo
, XRectangle
*rect
)
3832 Display
*dpy
= dpyinfo
->display
;
3833 long offset
, max_len
;
3834 Atom target_type
, actual_type
;
3835 unsigned long actual_size
, bytes_remaining
;
3836 int rc
, actual_format
;
3837 unsigned char *tmp_data
= NULL
;
3838 bool result
= false;
3840 x_catch_errors (dpy
);
3843 target_type
= XA_CARDINAL
;
3844 rc
= XGetWindowProperty (dpy
, dpyinfo
->root_window
,
3845 dpyinfo
->Xatom_net_current_desktop
,
3846 offset
, max_len
, False
, target_type
,
3847 &actual_type
, &actual_format
, &actual_size
,
3848 &bytes_remaining
, &tmp_data
);
3849 if (rc
== Success
&& actual_type
== target_type
&& !x_had_errors_p (dpy
)
3850 && actual_format
== 32 && actual_size
== max_len
)
3852 long current_desktop
= ((long *) tmp_data
)[0];
3857 offset
= 4 * current_desktop
;
3859 rc
= XGetWindowProperty (dpy
, dpyinfo
->root_window
,
3860 dpyinfo
->Xatom_net_workarea
,
3861 offset
, max_len
, False
, target_type
,
3862 &actual_type
, &actual_format
, &actual_size
,
3863 &bytes_remaining
, &tmp_data
);
3864 if (rc
== Success
&& actual_type
== target_type
&& !x_had_errors_p (dpy
)
3865 && actual_format
== 32 && actual_size
== max_len
)
3867 long *values
= (long *) tmp_data
;
3869 rect
->x
= values
[0];
3870 rect
->y
= values
[1];
3871 rect
->width
= values
[2];
3872 rect
->height
= values
[3];
3882 x_uncatch_errors ();
3890 /* Return monitor number where F is "most" or closest to. */
3892 x_get_monitor_for_frame (struct frame
*f
,
3893 struct MonitorInfo
*monitors
,
3897 int area
= 0, dist
= -1;
3898 int best_area
= -1, best_dist
= -1;
3901 if (n_monitors
== 1) return 0;
3902 frect
.x
= f
->left_pos
;
3903 frect
.y
= f
->top_pos
;
3904 frect
.width
= FRAME_PIXEL_WIDTH (f
);
3905 frect
.height
= FRAME_PIXEL_HEIGHT (f
);
3907 for (i
= 0; i
< n_monitors
; ++i
)
3909 struct MonitorInfo
*mi
= &monitors
[i
];
3913 if (mi
->geom
.width
== 0) continue;
3915 if (x_intersect_rectangles (&mi
->geom
, &frect
, &res
))
3917 a
= res
.width
* res
.height
;
3925 if (a
== 0 && area
== 0)
3928 if (frect
.x
+ frect
.width
< mi
->geom
.x
)
3929 dx
= mi
->geom
.x
- frect
.x
+ frect
.width
;
3930 else if (frect
.x
> mi
->geom
.x
+ mi
->geom
.width
)
3931 dx
= frect
.x
- mi
->geom
.x
+ mi
->geom
.width
;
3934 if (frect
.y
+ frect
.height
< mi
->geom
.y
)
3935 dy
= mi
->geom
.y
- frect
.y
+ frect
.height
;
3936 else if (frect
.y
> mi
->geom
.y
+ mi
->geom
.height
)
3937 dy
= frect
.y
- mi
->geom
.y
+ mi
->geom
.height
;
3942 if (dist
== -1 || dist
> d
)
3950 return best_area
!= -1 ? best_area
: (best_dist
!= -1 ? best_dist
: 0);
3954 x_make_monitor_attribute_list (struct MonitorInfo
*monitors
,
3956 int primary_monitor
,
3957 struct x_display_info
*dpyinfo
,
3960 Lisp_Object monitor_frames
= Fmake_vector (make_number (n_monitors
), Qnil
);
3961 Lisp_Object frame
, rest
;
3963 FOR_EACH_FRAME (rest
, frame
)
3965 struct frame
*f
= XFRAME (frame
);
3967 if (FRAME_X_P (f
) && FRAME_DISPLAY_INFO (f
) == dpyinfo
3968 && !EQ (frame
, tip_frame
))
3970 int i
= x_get_monitor_for_frame (f
, monitors
, n_monitors
);
3971 ASET (monitor_frames
, i
, Fcons (frame
, AREF (monitor_frames
, i
)));
3975 return make_monitor_attribute_list (monitors
, n_monitors
, primary_monitor
,
3976 monitor_frames
, source
);
3980 x_get_monitor_attributes_fallback (struct x_display_info
*dpyinfo
)
3982 struct MonitorInfo monitor
;
3983 XRectangle workarea_r
;
3985 /* Fallback: treat (possibly) multiple physical monitors as if they
3986 formed a single monitor as a whole. This should provide a
3987 consistent result at least on single monitor environments. */
3988 monitor
.geom
.x
= monitor
.geom
.y
= 0;
3989 monitor
.geom
.width
= x_display_pixel_width (dpyinfo
);
3990 monitor
.geom
.height
= x_display_pixel_height (dpyinfo
);
3991 monitor
.mm_width
= WidthMMOfScreen (dpyinfo
->screen
);
3992 monitor
.mm_height
= HeightMMOfScreen (dpyinfo
->screen
);
3993 monitor
.name
= xstrdup ("combined screen");
3995 if (x_get_net_workarea (dpyinfo
, &workarea_r
))
3996 monitor
.work
= workarea_r
;
3998 monitor
.work
= monitor
.geom
;
3999 return x_make_monitor_attribute_list (&monitor
, 1, 0, dpyinfo
, "fallback");
4003 #ifdef HAVE_XINERAMA
4005 x_get_monitor_attributes_xinerama (struct x_display_info
*dpyinfo
)
4008 Lisp_Object attributes_list
= Qnil
;
4009 Display
*dpy
= dpyinfo
->display
;
4010 XineramaScreenInfo
*info
= XineramaQueryScreens (dpy
, &n_monitors
);
4011 struct MonitorInfo
*monitors
;
4012 double mm_width_per_pixel
, mm_height_per_pixel
;
4014 if (! info
|| n_monitors
== 0)
4018 return attributes_list
;
4021 mm_width_per_pixel
= ((double) WidthMMOfScreen (dpyinfo
->screen
)
4022 / x_display_pixel_width (dpyinfo
));
4023 mm_height_per_pixel
= ((double) HeightMMOfScreen (dpyinfo
->screen
)
4024 / x_display_pixel_height (dpyinfo
));
4025 monitors
= xzalloc (n_monitors
* sizeof *monitors
);
4026 for (i
= 0; i
< n_monitors
; ++i
)
4028 struct MonitorInfo
*mi
= &monitors
[i
];
4029 XRectangle workarea_r
;
4031 mi
->geom
.x
= info
[i
].x_org
;
4032 mi
->geom
.y
= info
[i
].y_org
;
4033 mi
->geom
.width
= info
[i
].width
;
4034 mi
->geom
.height
= info
[i
].height
;
4035 mi
->mm_width
= mi
->geom
.width
* mm_width_per_pixel
+ 0.5;
4036 mi
->mm_height
= mi
->geom
.height
* mm_height_per_pixel
+ 0.5;
4039 /* Xinerama usually have primary monitor first, just use that. */
4040 if (i
== 0 && x_get_net_workarea (dpyinfo
, &workarea_r
))
4042 mi
->work
= workarea_r
;
4043 if (! x_intersect_rectangles (&mi
->geom
, &mi
->work
, &mi
->work
))
4044 mi
->work
= mi
->geom
;
4047 mi
->work
= mi
->geom
;
4051 attributes_list
= x_make_monitor_attribute_list (monitors
,
4056 free_monitors (monitors
, n_monitors
);
4057 return attributes_list
;
4059 #endif /* HAVE_XINERAMA */
4064 x_get_monitor_attributes_xrandr (struct x_display_info
*dpyinfo
)
4066 Lisp_Object attributes_list
= Qnil
;
4067 XRRScreenResources
*resources
;
4068 Display
*dpy
= dpyinfo
->display
;
4069 int i
, n_monitors
, primary
= -1;
4070 RROutput pxid
= None
;
4071 struct MonitorInfo
*monitors
;
4073 #ifdef HAVE_XRRGETSCREENRESOURCESCURRENT
4074 resources
= XRRGetScreenResourcesCurrent (dpy
, dpyinfo
->root_window
);
4076 resources
= XRRGetScreenResources (dpy
, dpyinfo
->root_window
);
4078 if (! resources
|| resources
->noutput
== 0)
4081 XRRFreeScreenResources (resources
);
4084 n_monitors
= resources
->noutput
;
4085 monitors
= xzalloc (n_monitors
* sizeof *monitors
);
4087 #ifdef HAVE_XRRGETOUTPUTPRIMARY
4088 pxid
= XRRGetOutputPrimary (dpy
, dpyinfo
->root_window
);
4091 for (i
= 0; i
< n_monitors
; ++i
)
4093 XRROutputInfo
*info
= XRRGetOutputInfo (dpy
, resources
,
4094 resources
->outputs
[i
]);
4095 Connection conn
= info
? info
->connection
: RR_Disconnected
;
4096 RRCrtc id
= info
? info
->crtc
: None
;
4098 if (strcmp (info
->name
, "default") == 0)
4100 /* Non XRandr 1.2 driver, does not give useful data. */
4101 XRRFreeOutputInfo (info
);
4102 XRRFreeScreenResources (resources
);
4103 free_monitors (monitors
, n_monitors
);
4107 if (conn
!= RR_Disconnected
&& id
!= None
)
4109 XRRCrtcInfo
*crtc
= XRRGetCrtcInfo (dpy
, resources
, id
);
4110 struct MonitorInfo
*mi
= &monitors
[i
];
4111 XRectangle workarea_r
;
4115 XRRFreeOutputInfo (info
);
4119 mi
->geom
.x
= crtc
->x
;
4120 mi
->geom
.y
= crtc
->y
;
4121 mi
->geom
.width
= crtc
->width
;
4122 mi
->geom
.height
= crtc
->height
;
4123 mi
->mm_width
= info
->mm_width
;
4124 mi
->mm_height
= info
->mm_height
;
4125 mi
->name
= xstrdup (info
->name
);
4127 if (pxid
!= None
&& pxid
== resources
->outputs
[i
])
4129 else if (primary
== -1 && strcmp (info
->name
, "LVDS") == 0)
4132 if (i
== primary
&& x_get_net_workarea (dpyinfo
, &workarea_r
))
4134 mi
->work
= workarea_r
;
4135 if (! x_intersect_rectangles (&mi
->geom
, &mi
->work
, &mi
->work
))
4136 mi
->work
= mi
->geom
;
4139 mi
->work
= mi
->geom
;
4141 XRRFreeCrtcInfo (crtc
);
4143 XRRFreeOutputInfo (info
);
4145 XRRFreeScreenResources (resources
);
4147 attributes_list
= x_make_monitor_attribute_list (monitors
,
4152 free_monitors (monitors
, n_monitors
);
4153 return attributes_list
;
4155 #endif /* HAVE_XRANDR */
4158 x_get_monitor_attributes (struct x_display_info
*dpyinfo
)
4160 Lisp_Object attributes_list
= Qnil
;
4161 Display
*dpy
= dpyinfo
->display
;
4163 (void) dpy
; /* Suppress unused variable warning. */
4166 int xrr_event_base
, xrr_error_base
;
4167 bool xrr_ok
= false;
4168 xrr_ok
= XRRQueryExtension (dpy
, &xrr_event_base
, &xrr_error_base
);
4171 int xrr_major
, xrr_minor
;
4172 XRRQueryVersion (dpy
, &xrr_major
, &xrr_minor
);
4173 xrr_ok
= (xrr_major
== 1 && xrr_minor
>= 2) || xrr_major
> 1;
4177 attributes_list
= x_get_monitor_attributes_xrandr (dpyinfo
);
4178 #endif /* HAVE_XRANDR */
4180 #ifdef HAVE_XINERAMA
4181 if (NILP (attributes_list
))
4183 int xin_event_base
, xin_error_base
;
4184 bool xin_ok
= false;
4185 xin_ok
= XineramaQueryExtension (dpy
, &xin_event_base
, &xin_error_base
);
4186 if (xin_ok
&& XineramaIsActive (dpy
))
4187 attributes_list
= x_get_monitor_attributes_xinerama (dpyinfo
);
4189 #endif /* HAVE_XINERAMA */
4191 if (NILP (attributes_list
))
4192 attributes_list
= x_get_monitor_attributes_fallback (dpyinfo
);
4194 return attributes_list
;
4197 #endif /* !USE_GTK */
4199 DEFUN ("x-display-monitor-attributes-list", Fx_display_monitor_attributes_list
,
4200 Sx_display_monitor_attributes_list
,
4202 doc
: /* Return a list of physical monitor attributes on the X display TERMINAL.
4204 The optional argument TERMINAL specifies which display to ask about.
4205 TERMINAL should be a terminal object, a frame or a display name (a string).
4206 If omitted or nil, that stands for the selected frame's display.
4208 In addition to the standard attribute keys listed in
4209 `display-monitor-attributes-list', the following keys are contained in
4212 source -- String describing the source from which multi-monitor
4213 information is obtained, one of \"Gdk\", \"XRandr\",
4214 \"Xinerama\", or \"fallback\"
4216 Internal use only, use `display-monitor-attributes-list' instead. */)
4217 (Lisp_Object terminal
)
4219 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4220 Lisp_Object attributes_list
= Qnil
;
4223 double mm_width_per_pixel
, mm_height_per_pixel
;
4226 gint primary_monitor
= 0, n_monitors
, i
;
4227 Lisp_Object monitor_frames
, rest
, frame
;
4228 static const char *source
= "Gdk";
4229 struct MonitorInfo
*monitors
;
4232 mm_width_per_pixel
= ((double) WidthMMOfScreen (dpyinfo
->screen
)
4233 / x_display_pixel_width (dpyinfo
));
4234 mm_height_per_pixel
= ((double) HeightMMOfScreen (dpyinfo
->screen
)
4235 / x_display_pixel_height (dpyinfo
));
4236 gdpy
= gdk_x11_lookup_xdisplay (dpyinfo
->display
);
4237 gscreen
= gdk_display_get_default_screen (gdpy
);
4238 #if GTK_CHECK_VERSION (2, 20, 0)
4239 primary_monitor
= gdk_screen_get_primary_monitor (gscreen
);
4241 n_monitors
= gdk_screen_get_n_monitors (gscreen
);
4242 monitor_frames
= Fmake_vector (make_number (n_monitors
), Qnil
);
4243 monitors
= xzalloc (n_monitors
* sizeof *monitors
);
4245 FOR_EACH_FRAME (rest
, frame
)
4247 struct frame
*f
= XFRAME (frame
);
4249 if (FRAME_X_P (f
) && FRAME_DISPLAY_INFO (f
) == dpyinfo
4250 && !EQ (frame
, tip_frame
))
4252 GdkWindow
*gwin
= gtk_widget_get_window (FRAME_GTK_WIDGET (f
));
4254 i
= gdk_screen_get_monitor_at_window (gscreen
, gwin
);
4255 ASET (monitor_frames
, i
, Fcons (frame
, AREF (monitor_frames
, i
)));
4259 for (i
= 0; i
< n_monitors
; ++i
)
4261 gint width_mm
= -1, height_mm
= -1;
4262 GdkRectangle rec
, work
;
4263 struct MonitorInfo
*mi
= &monitors
[i
];
4265 gdk_screen_get_monitor_geometry (gscreen
, i
, &rec
);
4267 #if GTK_CHECK_VERSION (2, 14, 0)
4268 width_mm
= gdk_screen_get_monitor_width_mm (gscreen
, i
);
4269 height_mm
= gdk_screen_get_monitor_height_mm (gscreen
, i
);
4272 width_mm
= rec
.width
* mm_width_per_pixel
+ 0.5;
4274 height_mm
= rec
.height
* mm_height_per_pixel
+ 0.5;
4276 #if GTK_CHECK_VERSION (3, 4, 0)
4277 gdk_screen_get_monitor_workarea (gscreen
, i
, &work
);
4279 /* Emulate the behavior of GTK+ 3.4. */
4281 XRectangle workarea_r
;
4283 if (i
== primary_monitor
&& x_get_net_workarea (dpyinfo
, &workarea_r
))
4285 work
.x
= workarea_r
.x
;
4286 work
.y
= workarea_r
.y
;
4287 work
.width
= workarea_r
.width
;
4288 work
.height
= workarea_r
.height
;
4289 if (! gdk_rectangle_intersect (&rec
, &work
, &work
))
4300 mi
->geom
.width
= rec
.width
;
4301 mi
->geom
.height
= rec
.height
;
4302 mi
->work
.x
= work
.x
;
4303 mi
->work
.y
= work
.y
;
4304 mi
->work
.width
= work
.width
;
4305 mi
->work
.height
= work
.height
;
4306 mi
->mm_width
= width_mm
;
4307 mi
->mm_height
= height_mm
;
4309 #if GTK_CHECK_VERSION (2, 14, 0)
4310 mi
->name
= gdk_screen_get_monitor_plug_name (gscreen
, i
);
4314 attributes_list
= make_monitor_attribute_list (monitors
,
4320 #else /* not USE_GTK */
4323 attributes_list
= x_get_monitor_attributes (dpyinfo
);
4326 #endif /* not USE_GTK */
4328 return attributes_list
;
4331 /* Return geometric attributes of FRAME. According to the value of
4332 ATTRIBUTES return the outer edges of FRAME (Qouter_edges), the native
4333 edges of FRAME (Qnative_edges), or the inner edges of frame
4334 (Qinner_edges). Any other value means to return the geometry as
4335 returned by Fx_frame_geometry. */
4337 frame_geometry (Lisp_Object frame
, Lisp_Object attribute
)
4339 struct frame
*f
= decode_live_frame (frame
);
4340 /** XWindowAttributes atts; **/
4342 unsigned int ign
, native_width
, native_height
;
4343 int xy_ign
, xptr
, yptr
;
4344 int left_off
, right_off
, top_off
, bottom_off
;
4345 int outer_left
, outer_top
, outer_right
, outer_bottom
;
4346 int native_left
, native_top
, native_right
, native_bottom
;
4347 int inner_left
, inner_top
, inner_right
, inner_bottom
;
4348 int internal_border_width
;
4349 bool menu_bar_external
= false, tool_bar_external
= false;
4350 int menu_bar_height
= 0, menu_bar_width
= 0;
4351 int tool_bar_height
= 0, tool_bar_width
= 0;
4353 if (FRAME_INITIAL_P (f
) || !FRAME_X_P (f
))
4357 XGetGeometry (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
4358 &rootw
, &xy_ign
, &xy_ign
, &native_width
, &native_height
,
4360 /** XGetWindowAttributes (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &atts); **/
4361 x_real_pos_and_offsets (f
, &left_off
, &right_off
, &top_off
, &bottom_off
,
4362 NULL
, NULL
, &xptr
, &yptr
, NULL
);
4365 /** native_width = atts.width; **/
4366 /** native_height = atts.height; **/
4370 outer_right
= outer_left
+ left_off
+ native_width
+ right_off
;
4371 outer_bottom
= outer_top
+ top_off
+ native_height
+ bottom_off
;
4373 native_left
= outer_left
+ left_off
;
4374 native_top
= outer_top
+ top_off
;
4375 native_right
= native_left
+ native_width
;
4376 native_bottom
= native_top
+ native_height
;
4378 internal_border_width
= FRAME_INTERNAL_BORDER_WIDTH (f
);
4379 inner_left
= native_left
+ internal_border_width
;
4380 inner_top
= native_top
+ internal_border_width
;
4381 inner_right
= native_right
- internal_border_width
;
4382 inner_bottom
= native_bottom
- internal_border_width
;
4384 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
4385 menu_bar_external
= true;
4386 menu_bar_height
= FRAME_MENUBAR_HEIGHT (f
);
4387 native_top
+= menu_bar_height
;
4388 inner_top
+= menu_bar_height
;
4390 menu_bar_height
= FRAME_MENU_BAR_HEIGHT (f
);
4391 inner_top
+= menu_bar_height
;
4393 menu_bar_width
= menu_bar_height
? native_width
: 0;
4395 #if defined (USE_GTK)
4396 tool_bar_external
= true;
4397 if (EQ (FRAME_TOOL_BAR_POSITION (f
), Qleft
))
4399 tool_bar_width
= FRAME_TOOLBAR_WIDTH (f
);
4400 native_left
+= tool_bar_width
;
4401 inner_left
+= tool_bar_width
;
4403 = tool_bar_width
? native_height
- menu_bar_height
: 0;
4405 else if (EQ (FRAME_TOOL_BAR_POSITION (f
), Qtop
))
4407 tool_bar_height
= FRAME_TOOLBAR_HEIGHT (f
);
4408 native_top
+= tool_bar_height
;
4409 inner_top
+= tool_bar_height
;
4410 tool_bar_width
= tool_bar_height
? native_width
: 0;
4412 else if (EQ (FRAME_TOOL_BAR_POSITION (f
), Qright
))
4414 tool_bar_width
= FRAME_TOOLBAR_WIDTH (f
);
4415 native_right
-= tool_bar_width
;
4416 inner_right
-= tool_bar_width
;
4418 = tool_bar_width
? native_height
- menu_bar_height
: 0;
4422 tool_bar_height
= FRAME_TOOLBAR_HEIGHT (f
);
4423 native_bottom
-= tool_bar_height
;
4424 inner_bottom
-= tool_bar_height
;
4425 tool_bar_width
= tool_bar_height
? native_width
: 0;
4428 tool_bar_height
= FRAME_TOOL_BAR_HEIGHT (f
);
4429 tool_bar_width
= tool_bar_height
? native_width
: 0;
4430 inner_top
+= tool_bar_height
;
4433 /* Construct list. */
4434 if (EQ (attribute
, Qouter_edges
))
4435 return list4 (make_number (outer_left
), make_number (outer_top
),
4436 make_number (outer_right
), make_number (outer_bottom
));
4437 else if (EQ (attribute
, Qnative_edges
))
4438 return list4 (make_number (native_left
), make_number (native_top
),
4439 make_number (native_right
), make_number (native_bottom
));
4440 else if (EQ (attribute
, Qinner_edges
))
4441 return list4 (make_number (inner_left
), make_number (inner_top
),
4442 make_number (inner_right
), make_number (inner_bottom
));
4445 listn (CONSTYPE_HEAP
, 10,
4446 Fcons (Qouter_position
,
4447 Fcons (make_number (outer_left
),
4448 make_number (outer_top
))),
4450 Fcons (make_number (outer_right
- outer_left
),
4451 make_number (outer_bottom
- outer_top
))),
4453 Fcons (Qexternal_border_size
,
4454 Fcons (make_number (right_off
),
4455 make_number (bottom_off
))),
4457 Fcons (Qtitle_bar_size
,
4458 Fcons (make_number (0),
4459 make_number (top_off
- bottom_off
))),
4460 Fcons (Qmenu_bar_external
, menu_bar_external
? Qt
: Qnil
),
4461 Fcons (Qmenu_bar_size
,
4462 Fcons (make_number (menu_bar_width
),
4463 make_number (menu_bar_height
))),
4464 Fcons (Qtool_bar_external
, tool_bar_external
? Qt
: Qnil
),
4465 Fcons (Qtool_bar_position
, FRAME_TOOL_BAR_POSITION (f
)),
4466 Fcons (Qtool_bar_size
,
4467 Fcons (make_number (tool_bar_width
),
4468 make_number (tool_bar_height
))),
4469 Fcons (Qinternal_border_width
,
4470 make_number (internal_border_width
)));
4473 DEFUN ("x-frame-geometry", Fx_frame_geometry
, Sx_frame_geometry
, 0, 1, 0,
4474 doc
: /* Return geometric attributes of FRAME.
4475 FRAME must be a live frame and defaults to the selected one. The return
4476 value is an association list of the attributes listed below. All height
4477 and width values are in pixels.
4479 `outer-position' is a cons of the outer left and top edges of FRAME
4480 relative to the origin - the position (0, 0) - of FRAME's display.
4482 `outer-size' is a cons of the outer width and height of FRAME. The
4483 outer size includes the title bar and the external borders as well as
4484 any menu and/or tool bar of frame.
4486 `external-border-size' is a cons of the horizontal and vertical width of
4487 FRAME's external borders as supplied by the window manager.
4489 `title-bar-size' is a cons of the width and height of the title bar of
4490 FRAME as supplied by the window manager. If both of them are zero,
4491 FRAME has no title bar. If only the width is zero, Emacs was not
4492 able to retrieve the width information.
4494 `menu-bar-external', if non-nil, means the menu bar is external (never
4495 included in the inner edges of FRAME).
4497 `menu-bar-size' is a cons of the width and height of the menu bar of
4500 `tool-bar-external', if non-nil, means the tool bar is external (never
4501 included in the inner edges of FRAME).
4503 `tool-bar-position' tells on which side the tool bar on FRAME is and can
4504 be one of `left', `top', `right' or `bottom'. If this is nil, FRAME
4507 `tool-bar-size' is a cons of the width and height of the tool bar of
4510 `internal-border-width' is the width of the internal border of
4514 return frame_geometry (frame
, Qnil
);
4517 DEFUN ("x-frame-edges", Fx_frame_edges
, Sx_frame_edges
, 0, 2, 0,
4518 doc
: /* Return edge coordinates of FRAME.
4519 FRAME must be a live frame and defaults to the selected one. The return
4520 value is a list of the form (LEFT, TOP, RIGHT, BOTTOM). All values are
4521 in pixels relative to the origin - the position (0, 0) - of FRAME's
4524 If optional argument TYPE is the symbol `outer-edges', return the outer
4525 edges of FRAME. The outer edges comprise the decorations of the window
4526 manager (like the title bar or external borders) as well as any external
4527 menu or tool bar of FRAME. If optional argument TYPE is the symbol
4528 `native-edges' or nil, return the native edges of FRAME. The native
4529 edges exclude the decorations of the window manager and any external
4530 menu or tool bar of FRAME. If TYPE is the symbol `inner-edges', return
4531 the inner edges of FRAME. These edges exclude title bar, any borders,
4532 menu bar or tool bar of FRAME. */)
4533 (Lisp_Object frame
, Lisp_Object type
)
4535 return frame_geometry (frame
, ((EQ (type
, Qouter_edges
)
4536 || EQ (type
, Qinner_edges
))
4541 DEFUN ("x-mouse-absolute-pixel-position", Fx_mouse_absolute_pixel_position
,
4542 Sx_mouse_absolute_pixel_position
, 0, 0, 0,
4543 doc
: /* Return absolute position of mouse cursor in pixels.
4544 The position is returned as a cons cell (X . Y) of the coordinates of
4545 the mouse cursor position in pixels relative to a position (0, 0) of the
4546 selected frame's display. */)
4549 struct frame
*f
= SELECTED_FRAME ();
4550 Window root
, dummy_window
;
4553 if (FRAME_INITIAL_P (f
) || !FRAME_X_P (f
))
4557 XQueryPointer (FRAME_X_DISPLAY (f
),
4558 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
4559 &root
, &dummy_window
, &x
, &y
, &dummy
, &dummy
,
4560 (unsigned int *) &dummy
);
4563 return Fcons (make_number (x
), make_number (y
));
4566 DEFUN ("x-set-mouse-absolute-pixel-position", Fx_set_mouse_absolute_pixel_position
,
4567 Sx_set_mouse_absolute_pixel_position
, 2, 2, 0,
4568 doc
: /* Move mouse pointer to absolute pixel position (X, Y).
4569 The coordinates X and Y are interpreted in pixels relative to a position
4570 (0, 0) of the selected frame's display. */)
4571 (Lisp_Object x
, Lisp_Object y
)
4573 struct frame
*f
= SELECTED_FRAME ();
4575 if (FRAME_INITIAL_P (f
) || !FRAME_X_P (f
))
4578 CHECK_TYPE_RANGED_INTEGER (int, x
);
4579 CHECK_TYPE_RANGED_INTEGER (int, y
);
4582 XWarpPointer (FRAME_X_DISPLAY (f
), None
, DefaultRootWindow (FRAME_X_DISPLAY (f
)),
4583 0, 0, 0, 0, XINT (x
), XINT (y
));
4589 /************************************************************************
4591 ************************************************************************/
4594 /* Mapping visual names to visuals. */
4596 static struct visual_class
4603 {"StaticGray", StaticGray
},
4604 {"GrayScale", GrayScale
},
4605 {"StaticColor", StaticColor
},
4606 {"PseudoColor", PseudoColor
},
4607 {"TrueColor", TrueColor
},
4608 {"DirectColor", DirectColor
},
4613 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4615 /* Value is the screen number of screen SCR. This is a substitute for
4616 the X function with the same name when that doesn't exist. */
4619 XScreenNumberOfScreen (scr
)
4620 register Screen
*scr
;
4622 Display
*dpy
= scr
->display
;
4625 for (i
= 0; i
< dpy
->nscreens
; ++i
)
4626 if (scr
== dpy
->screens
+ i
)
4632 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4635 /* Select the visual that should be used on display DPYINFO. Set
4636 members of DPYINFO appropriately. Called from x_term_init. */
4639 select_visual (struct x_display_info
*dpyinfo
)
4641 Display
*dpy
= dpyinfo
->display
;
4642 Screen
*screen
= dpyinfo
->screen
;
4644 /* See if a visual is specified. */
4645 AUTO_STRING (visualClass
, "visualClass");
4646 AUTO_STRING (VisualClass
, "VisualClass");
4647 Lisp_Object value
= display_x_get_resource (dpyinfo
, visualClass
,
4648 VisualClass
, Qnil
, Qnil
);
4650 if (STRINGP (value
))
4652 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
4653 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
4654 depth, a decimal number. NAME is compared with case ignored. */
4655 char *s
= alloca (SBYTES (value
) + 1);
4660 lispstpcpy (s
, value
);
4661 dash
= strchr (s
, '-');
4664 dpyinfo
->n_planes
= atoi (dash
+ 1);
4668 /* We won't find a matching visual with depth 0, so that
4669 an error will be printed below. */
4670 dpyinfo
->n_planes
= 0;
4672 /* Determine the visual class. */
4673 for (i
= 0; visual_classes
[i
].name
; ++i
)
4674 if (xstrcasecmp (s
, visual_classes
[i
].name
) == 0)
4676 class = visual_classes
[i
].class;
4680 /* Look up a matching visual for the specified class. */
4682 || !XMatchVisualInfo (dpy
, XScreenNumberOfScreen (screen
),
4683 dpyinfo
->n_planes
, class, &vinfo
))
4684 fatal ("Invalid visual specification '%s'",
4685 SSDATA (ENCODE_SYSTEM (value
)));
4687 dpyinfo
->visual
= vinfo
.visual
;
4692 XVisualInfo
*vinfo
, vinfo_template
;
4694 dpyinfo
->visual
= DefaultVisualOfScreen (screen
);
4696 vinfo_template
.visualid
= XVisualIDFromVisual (dpyinfo
->visual
);
4697 vinfo_template
.screen
= XScreenNumberOfScreen (screen
);
4698 vinfo
= XGetVisualInfo (dpy
, VisualIDMask
| VisualScreenMask
,
4699 &vinfo_template
, &n_visuals
);
4701 fatal ("Can't get proper X visual info");
4703 dpyinfo
->n_planes
= vinfo
->depth
;
4709 /* Return the X display structure for the display named NAME.
4710 Open a new connection if necessary. */
4712 static struct x_display_info
*
4713 x_display_info_for_name (Lisp_Object name
)
4715 struct x_display_info
*dpyinfo
;
4717 CHECK_STRING (name
);
4719 for (dpyinfo
= x_display_list
; dpyinfo
; dpyinfo
= dpyinfo
->next
)
4720 if (!NILP (Fstring_equal (XCAR (dpyinfo
->name_list_element
), name
)))
4723 /* Use this general default value to start with. */
4724 Vx_resource_name
= Vinvocation_name
;
4726 validate_x_resource_name ();
4728 dpyinfo
= x_term_init (name
, 0, SSDATA (Vx_resource_name
));
4731 error ("Cannot connect to X server %s", SDATA (name
));
4733 XSETFASTINT (Vwindow_system_version
, 11);
4739 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
4741 doc
: /* Open a connection to a display server.
4742 DISPLAY is the name of the display to connect to.
4743 Optional second arg XRM-STRING is a string of resources in xrdb format.
4744 If the optional third arg MUST-SUCCEED is non-nil,
4745 terminate Emacs if we can't open the connection.
4746 (In the Nextstep version, the last two arguments are currently ignored.) */)
4747 (Lisp_Object display
, Lisp_Object xrm_string
, Lisp_Object must_succeed
)
4750 struct x_display_info
*dpyinfo
;
4752 CHECK_STRING (display
);
4753 if (! NILP (xrm_string
))
4754 CHECK_STRING (xrm_string
);
4756 xrm_option
= NILP (xrm_string
) ? 0 : SSDATA (xrm_string
);
4758 validate_x_resource_name ();
4760 /* This is what opens the connection and sets x_current_display.
4761 This also initializes many symbols, such as those used for input. */
4762 dpyinfo
= x_term_init (display
, xrm_option
,
4763 SSDATA (Vx_resource_name
));
4767 if (!NILP (must_succeed
))
4768 fatal ("Cannot connect to X server %s.\n\
4769 Check the DISPLAY environment variable or use `-d'.\n\
4770 Also use the `xauth' program to verify that you have the proper\n\
4771 authorization information needed to connect the X server.\n\
4772 An insecure way to solve the problem may be to use `xhost'.\n",
4775 error ("Cannot connect to X server %s", SDATA (display
));
4778 XSETFASTINT (Vwindow_system_version
, 11);
4782 DEFUN ("x-close-connection", Fx_close_connection
,
4783 Sx_close_connection
, 1, 1, 0,
4784 doc
: /* Close the connection to TERMINAL's X server.
4785 For TERMINAL, specify a terminal object, a frame or a display name (a
4786 string). If TERMINAL is nil, that stands for the selected frame's
4788 (Lisp_Object terminal
)
4790 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4792 if (dpyinfo
->reference_count
> 0)
4793 error ("Display still has frames on it");
4795 x_delete_terminal (dpyinfo
->terminal
);
4800 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
4801 doc
: /* Return the list of display names that Emacs has connections to. */)
4804 Lisp_Object result
= Qnil
;
4805 struct x_display_info
*xdi
;
4807 for (xdi
= x_display_list
; xdi
; xdi
= xdi
->next
)
4808 result
= Fcons (XCAR (xdi
->name_list_element
), result
);
4813 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
4814 doc
: /* If ON is non-nil, report X errors as soon as the erring request is made.
4815 This function only has an effect on X Windows. With MS Windows, it is
4816 defined but does nothing.
4818 If ON is nil, allow buffering of requests.
4819 Turning on synchronization prohibits the Xlib routines from buffering
4820 requests and seriously degrades performance, but makes debugging much
4822 The optional second argument TERMINAL specifies which display to act on.
4823 TERMINAL should be a terminal object, a frame or a display name (a string).
4824 If TERMINAL is omitted or nil, that stands for the selected frame's display. */)
4825 (Lisp_Object on
, Lisp_Object terminal
)
4827 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4829 XSynchronize (dpyinfo
->display
, !EQ (on
, Qnil
));
4834 /* Wait for responses to all X commands issued so far for frame F. */
4837 x_sync (struct frame
*f
)
4840 XSync (FRAME_X_DISPLAY (f
), False
);
4845 /***********************************************************************
4847 ***********************************************************************/
4849 DEFUN ("x-change-window-property", Fx_change_window_property
,
4850 Sx_change_window_property
, 2, 6, 0,
4851 doc
: /* Change window property PROP to VALUE on the X window of FRAME.
4852 PROP must be a string. VALUE may be a string or a list of conses,
4853 numbers and/or strings. If an element in the list is a string, it is
4854 converted to an atom and the value of the atom is used. If an element
4855 is a cons, it is converted to a 32 bit number where the car is the 16
4856 top bits and the cdr is the lower 16 bits.
4858 FRAME nil or omitted means use the selected frame.
4859 If TYPE is given and non-nil, it is the name of the type of VALUE.
4860 If TYPE is not given or nil, the type is STRING.
4861 FORMAT gives the size in bits of each element if VALUE is a list.
4862 It must be one of 8, 16 or 32.
4863 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
4864 If OUTER-P is non-nil, the property is changed for the outer X window of
4865 FRAME. Default is to change on the edit X window. */)
4866 (Lisp_Object prop
, Lisp_Object value
, Lisp_Object frame
,
4867 Lisp_Object type
, Lisp_Object format
, Lisp_Object outer_p
)
4869 struct frame
*f
= decode_window_system_frame (frame
);
4871 Atom target_type
= XA_STRING
;
4872 int element_format
= 8;
4873 unsigned char *data
;
4877 CHECK_STRING (prop
);
4879 if (! NILP (format
))
4881 CHECK_NUMBER (format
);
4883 if (XINT (format
) != 8 && XINT (format
) != 16
4884 && XINT (format
) != 32)
4885 error ("FORMAT must be one of 8, 16 or 32");
4886 element_format
= XINT (format
);
4893 nelements
= x_check_property_data (value
);
4894 if (nelements
== -1)
4895 error ("Bad data in VALUE, must be number, string or cons");
4897 /* The man page for XChangeProperty:
4898 "If the specified format is 32, the property data must be a
4900 This applies even if long is more than 32 bits. The X library
4901 converts to 32 bits before sending to the X server. */
4902 elsize
= element_format
== 32 ? sizeof (long) : element_format
>> 3;
4903 data
= xnmalloc (nelements
, elsize
);
4905 x_fill_property_data (FRAME_X_DISPLAY (f
), value
, data
, element_format
);
4909 CHECK_STRING (value
);
4910 data
= SDATA (value
);
4911 if (INT_MAX
< SBYTES (value
))
4912 error ("VALUE too long");
4913 nelements
= SBYTES (value
);
4917 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (prop
), False
);
4920 CHECK_STRING (type
);
4921 target_type
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (type
), False
);
4924 if (! NILP (outer_p
)) w
= FRAME_OUTER_WINDOW (f
);
4925 else w
= FRAME_X_WINDOW (f
);
4927 XChangeProperty (FRAME_X_DISPLAY (f
), w
,
4928 prop_atom
, target_type
, element_format
, PropModeReplace
,
4931 if (CONSP (value
)) xfree (data
);
4933 /* Make sure the property is set when we return. */
4934 XFlush (FRAME_X_DISPLAY (f
));
4941 DEFUN ("x-delete-window-property", Fx_delete_window_property
,
4942 Sx_delete_window_property
, 1, 2, 0,
4943 doc
: /* Remove window property PROP from X window of FRAME.
4944 FRAME nil or omitted means use the selected frame. Value is PROP. */)
4945 (Lisp_Object prop
, Lisp_Object frame
)
4947 struct frame
*f
= decode_window_system_frame (frame
);
4950 CHECK_STRING (prop
);
4952 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (prop
), False
);
4953 XDeleteProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), prop_atom
);
4955 /* Make sure the property is removed when we return. */
4956 XFlush (FRAME_X_DISPLAY (f
));
4964 x_window_property_intern (struct frame
*f
,
4965 Window target_window
,
4968 Lisp_Object delete_p
,
4969 Lisp_Object vector_ret_p
,
4972 unsigned char *tmp_data
= NULL
;
4973 Lisp_Object prop_value
= Qnil
;
4976 unsigned long actual_size
, bytes_remaining
;
4979 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), target_window
,
4980 prop_atom
, 0, 0, False
, target_type
,
4981 &actual_type
, &actual_format
, &actual_size
,
4982 &bytes_remaining
, &tmp_data
);
4984 *found
= actual_format
!= 0;
4986 if (rc
== Success
&& *found
)
4991 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), target_window
,
4992 prop_atom
, 0, bytes_remaining
,
4993 ! NILP (delete_p
), target_type
,
4994 &actual_type
, &actual_format
,
4995 &actual_size
, &bytes_remaining
,
4997 if (rc
== Success
&& tmp_data
)
4999 /* The man page for XGetWindowProperty says:
5000 "If the returned format is 32, the returned data is represented
5001 as a long array and should be cast to that type to obtain the
5003 This applies even if long is more than 32 bits, the X library
5004 converts from 32 bit elements received from the X server to long
5005 and passes the long array to us. Thus, for that case memcpy can not
5006 be used. We convert to a 32 bit type here, because so much code
5009 The bytes and offsets passed to XGetWindowProperty refers to the
5010 property and those are indeed in 32 bit quantities if format is
5013 if (BITS_PER_LONG
> 32 && actual_format
== 32)
5016 int *idata
= (int *) tmp_data
;
5017 long *ldata
= (long *) tmp_data
;
5019 for (i
= 0; i
< actual_size
; ++i
)
5020 idata
[i
] = (int) ldata
[i
];
5023 if (NILP (vector_ret_p
))
5024 prop_value
= make_string ((char *) tmp_data
, actual_size
);
5026 prop_value
= x_property_data_to_lisp (f
,
5033 if (tmp_data
) XFree (tmp_data
);
5039 DEFUN ("x-window-property", Fx_window_property
, Sx_window_property
,
5041 doc
: /* Value is the value of window property PROP on FRAME.
5042 If FRAME is nil or omitted, use the selected frame.
5044 On X Windows, the following optional arguments are also accepted:
5045 If TYPE is nil or omitted, get the property as a string.
5046 Otherwise TYPE is the name of the atom that denotes the type expected.
5047 If SOURCE is non-nil, get the property on that window instead of from
5048 FRAME. The number 0 denotes the root window.
5049 If DELETE-P is non-nil, delete the property after retrieving it.
5050 If VECTOR-RET-P is non-nil, don't return a string but a vector of values.
5052 On MS Windows, this function accepts but ignores those optional arguments.
5054 Value is nil if FRAME hasn't a property with name PROP or if PROP has
5055 no value of TYPE (always string in the MS Windows case). */)
5056 (Lisp_Object prop
, Lisp_Object frame
, Lisp_Object type
,
5057 Lisp_Object source
, Lisp_Object delete_p
, Lisp_Object vector_ret_p
)
5059 struct frame
*f
= decode_window_system_frame (frame
);
5061 Lisp_Object prop_value
= Qnil
;
5062 Atom target_type
= XA_STRING
;
5063 Window target_window
= FRAME_X_WINDOW (f
);
5066 CHECK_STRING (prop
);
5068 if (! NILP (source
))
5070 CONS_TO_INTEGER (source
, Window
, target_window
);
5071 if (! target_window
)
5072 target_window
= FRAME_DISPLAY_INFO (f
)->root_window
;
5078 if (strcmp ("AnyPropertyType", SSDATA (type
)) == 0)
5079 target_type
= AnyPropertyType
;
5081 target_type
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (type
), False
);
5084 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (prop
), False
);
5085 prop_value
= x_window_property_intern (f
,
5092 if (NILP (prop_value
)
5095 && target_window
!= FRAME_OUTER_WINDOW (f
))
5097 prop_value
= x_window_property_intern (f
,
5098 FRAME_OUTER_WINDOW (f
),
5111 /***********************************************************************
5113 ***********************************************************************/
5115 static Lisp_Object
x_create_tip_frame (struct x_display_info
*,
5116 Lisp_Object
, Lisp_Object
);
5117 static void compute_tip_xy (struct frame
*, Lisp_Object
, Lisp_Object
,
5118 Lisp_Object
, int, int, int *, int *);
5120 /* The frame of a currently visible tooltip. */
5122 Lisp_Object tip_frame
;
5124 /* If non-nil, a timer started that hides the last tooltip when it
5127 static Lisp_Object tip_timer
;
5130 /* If non-nil, a vector of 3 elements containing the last args
5131 with which x-show-tip was called. See there. */
5133 static Lisp_Object last_show_tip_args
;
5137 unwind_create_tip_frame (Lisp_Object frame
)
5139 Lisp_Object deleted
;
5141 deleted
= unwind_create_frame (frame
);
5142 if (EQ (deleted
, Qt
))
5150 /* Create a frame for a tooltip on the display described by DPYINFO.
5151 PARMS is a list of frame parameters. TEXT is the string to
5152 display in the tip frame. Value is the frame.
5154 Note that functions called here, esp. x_default_parameter can
5155 signal errors, for instance when a specified color name is
5156 undefined. We have to make sure that we're in a consistent state
5157 when this happens. */
5160 x_create_tip_frame (struct x_display_info
*dpyinfo
,
5168 ptrdiff_t count
= SPECPDL_INDEX ();
5169 bool face_change_before
= face_change
;
5171 struct buffer
*old_buffer
;
5172 int x_width
= 0, x_height
= 0;
5174 if (!dpyinfo
->terminal
->name
)
5175 error ("Terminal is not live, can't create new frames on it");
5177 parms
= Fcopy_alist (parms
);
5179 /* Get the name of the frame to use for resource lookup. */
5180 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
5182 && !EQ (name
, Qunbound
)
5184 error ("Invalid frame name--not a string or nil");
5187 f
= make_frame (true);
5188 XSETFRAME (frame
, f
);
5190 AUTO_STRING (tip
, " *tip*");
5191 buffer
= Fget_buffer_create (tip
);
5192 /* Use set_window_buffer instead of Fset_window_buffer (see
5193 discussion of bug#11984, bug#12025, bug#12026). */
5194 set_window_buffer (FRAME_ROOT_WINDOW (f
), buffer
, false, false);
5195 old_buffer
= current_buffer
;
5196 set_buffer_internal_1 (XBUFFER (buffer
));
5197 bset_truncate_lines (current_buffer
, Qnil
);
5198 specbind (Qinhibit_read_only
, Qt
);
5199 specbind (Qinhibit_modification_hooks
, Qt
);
5202 set_buffer_internal_1 (old_buffer
);
5204 record_unwind_protect (unwind_create_tip_frame
, frame
);
5206 f
->terminal
= dpyinfo
->terminal
;
5208 /* By setting the output method, we're essentially saying that
5209 the frame is live, as per FRAME_LIVE_P. If we get a signal
5210 from this point on, x_destroy_window might screw up reference
5212 f
->output_method
= output_x_window
;
5213 f
->output_data
.x
= xzalloc (sizeof *f
->output_data
.x
);
5214 f
->output_data
.x
->icon_bitmap
= -1;
5215 FRAME_FONTSET (f
) = -1;
5216 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
5217 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
5218 #if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
5219 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
5220 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
5221 #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
5222 f
->output_data
.x
->white_relief
.pixel
= -1;
5223 f
->output_data
.x
->black_relief
.pixel
= -1;
5225 fset_icon_name (f
, Qnil
);
5226 FRAME_DISPLAY_INFO (f
) = dpyinfo
;
5227 f
->output_data
.x
->parent_desc
= FRAME_DISPLAY_INFO (f
)->root_window
;
5228 f
->output_data
.x
->explicit_parent
= false;
5230 /* These colors will be set anyway later, but it's important
5231 to get the color reference counts right, so initialize them! */
5235 /* Function x_decode_color can signal an error. Make
5236 sure to initialize color slots so that we won't try
5237 to free colors we haven't allocated. */
5238 FRAME_FOREGROUND_PIXEL (f
) = -1;
5239 FRAME_BACKGROUND_PIXEL (f
) = -1;
5240 f
->output_data
.x
->cursor_pixel
= -1;
5241 f
->output_data
.x
->cursor_foreground_pixel
= -1;
5242 f
->output_data
.x
->border_pixel
= -1;
5243 f
->output_data
.x
->mouse_pixel
= -1;
5245 black
= build_string ("black");
5246 FRAME_FOREGROUND_PIXEL (f
)
5247 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
5248 FRAME_BACKGROUND_PIXEL (f
)
5249 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
5250 f
->output_data
.x
->cursor_pixel
5251 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
5252 f
->output_data
.x
->cursor_foreground_pixel
5253 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
5254 f
->output_data
.x
->border_pixel
5255 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
5256 f
->output_data
.x
->mouse_pixel
5257 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
5260 /* Set the name; the functions to which we pass f expect the name to
5262 if (EQ (name
, Qunbound
) || NILP (name
))
5264 fset_name (f
, build_string (dpyinfo
->x_id_name
));
5265 f
->explicit_name
= false;
5269 fset_name (f
, name
);
5270 f
->explicit_name
= true;
5271 /* use the frame's title when getting resources for this frame. */
5272 specbind (Qx_resource_name
, name
);
5276 register_font_driver (&ftcrfont_driver
, f
);
5278 register_font_driver (&xfont_driver
, f
);
5279 #ifdef HAVE_FREETYPE
5281 register_font_driver (&xftfont_driver
, f
);
5282 #else /* not HAVE_XFT */
5283 register_font_driver (&ftxfont_driver
, f
);
5284 #endif /* not HAVE_XFT */
5285 #endif /* HAVE_FREETYPE */
5286 #endif /* not USE_CAIRO */
5288 image_cache_refcount
=
5289 FRAME_IMAGE_CACHE (f
) ? FRAME_IMAGE_CACHE (f
)->refcount
: 0;
5291 dpyinfo_refcount
= dpyinfo
->reference_count
;
5292 #endif /* GLYPH_DEBUG */
5294 x_default_parameter (f
, parms
, Qfont_backend
, Qnil
,
5295 "fontBackend", "FontBackend", RES_TYPE_STRING
);
5297 /* Extract the window parameters from the supplied values that are
5298 needed to determine window geometry. */
5299 x_default_font_parameter (f
, parms
);
5301 x_default_parameter (f
, parms
, Qborder_width
, make_number (0),
5302 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
5304 /* This defaults to 2 in order to match xterm. We recognize either
5305 internalBorderWidth or internalBorder (which is what xterm calls
5307 if (NILP (Fassq (Qinternal_border_width
, parms
)))
5311 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
5312 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
5313 if (! EQ (value
, Qunbound
))
5314 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
5318 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
5319 "internalBorderWidth", "internalBorderWidth",
5321 x_default_parameter (f
, parms
, Qright_divider_width
, make_number (0),
5322 NULL
, NULL
, RES_TYPE_NUMBER
);
5323 x_default_parameter (f
, parms
, Qbottom_divider_width
, make_number (0),
5324 NULL
, NULL
, RES_TYPE_NUMBER
);
5326 /* Also do the stuff which must be set before the window exists. */
5327 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
5328 "foreground", "Foreground", RES_TYPE_STRING
);
5329 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
5330 "background", "Background", RES_TYPE_STRING
);
5331 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
5332 "pointerColor", "Foreground", RES_TYPE_STRING
);
5333 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
5334 "cursorColor", "Foreground", RES_TYPE_STRING
);
5335 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
5336 "borderColor", "BorderColor", RES_TYPE_STRING
);
5338 /* Init faces before x_default_parameter is called for the
5339 scroll-bar-width parameter because otherwise we end up in
5340 init_iterator with a null face cache, which should not happen. */
5341 init_frame_faces (f
);
5343 f
->output_data
.x
->parent_desc
= FRAME_DISPLAY_INFO (f
)->root_window
;
5345 x_figure_window_size (f
, parms
, false, &x_width
, &x_height
);
5348 XSetWindowAttributes attrs
;
5350 Atom type
= FRAME_DISPLAY_INFO (f
)->Xatom_net_window_type_tooltip
;
5353 mask
= CWBackPixel
| CWOverrideRedirect
| CWEventMask
| CWCursor
;
5354 if (DoesSaveUnders (dpyinfo
->screen
))
5355 mask
|= CWSaveUnder
;
5357 /* Window managers look at the override-redirect flag to determine
5358 whether or net to give windows a decoration (Xlib spec, chapter
5360 attrs
.override_redirect
= True
;
5361 attrs
.save_under
= True
;
5362 attrs
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
5364 f
->output_data
.x
->current_cursor
5365 = f
->output_data
.x
->text_cursor
;
5366 /* Arrange for getting MapNotify and UnmapNotify events. */
5367 attrs
.event_mask
= StructureNotifyMask
;
5369 = FRAME_X_WINDOW (f
)
5370 = XCreateWindow (FRAME_X_DISPLAY (f
),
5371 FRAME_DISPLAY_INFO (f
)->root_window
,
5372 /* x, y, width, height */
5376 CopyFromParent
, InputOutput
, CopyFromParent
,
5378 XChangeProperty (FRAME_X_DISPLAY (f
), tip_window
,
5379 FRAME_DISPLAY_INFO (f
)->Xatom_net_window_type
,
5380 XA_ATOM
, 32, PropModeReplace
,
5381 (unsigned char *)&type
, 1);
5387 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
5388 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
5389 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
5390 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
5391 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
5392 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
5394 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
5395 Change will not be effected unless different from the current
5397 width
= FRAME_COLS (f
);
5398 height
= FRAME_LINES (f
);
5399 SET_FRAME_COLS (f
, 0);
5400 SET_FRAME_LINES (f
, 0);
5401 change_frame_size (f
, width
, height
, true, false, false, false);
5403 /* Add `tooltip' frame parameter's default value. */
5404 if (NILP (Fframe_parameter (frame
, Qtooltip
)))
5406 AUTO_FRAME_ARG (arg
, Qtooltip
, Qt
);
5407 Fmodify_frame_parameters (frame
, arg
);
5410 /* FIXME - can this be done in a similar way to normal frames?
5411 http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
5413 /* Set the `display-type' frame parameter before setting up faces. */
5415 Lisp_Object disptype
;
5417 if (FRAME_DISPLAY_INFO (f
)->n_planes
== 1)
5419 else if (FRAME_DISPLAY_INFO (f
)->visual
->class == GrayScale
5420 || FRAME_DISPLAY_INFO (f
)->visual
->class == StaticGray
)
5421 disptype
= intern ("grayscale");
5423 disptype
= intern ("color");
5425 if (NILP (Fframe_parameter (frame
, Qdisplay_type
)))
5427 AUTO_FRAME_ARG (arg
, Qdisplay_type
, disptype
);
5428 Fmodify_frame_parameters (frame
, arg
);
5432 /* Set up faces after all frame parameters are known. This call
5433 also merges in face attributes specified for new frames.
5435 Frame parameters may be changed if .Xdefaults contains
5436 specifications for the default font. For example, if there is an
5437 `Emacs.default.attributeBackground: pink', the `background-color'
5438 attribute of the frame get's set, which let's the internal border
5439 of the tooltip frame appear in pink. Prevent this. */
5441 Lisp_Object bg
= Fframe_parameter (frame
, Qbackground_color
);
5443 /* Set tip_frame here, so that */
5445 call2 (Qface_set_after_frame_default
, frame
, Qnil
);
5447 if (!EQ (bg
, Fframe_parameter (frame
, Qbackground_color
)))
5449 AUTO_FRAME_ARG (arg
, Qbackground_color
, bg
);
5450 Fmodify_frame_parameters (frame
, arg
);
5456 /* Now that the frame will be official, it counts as a reference to
5457 its display and terminal. */
5458 FRAME_DISPLAY_INFO (f
)->reference_count
++;
5459 f
->terminal
->reference_count
++;
5461 /* It is now ok to make the frame official even if we get an error
5462 below. And the frame needs to be on Vframe_list or making it
5463 visible won't work. */
5464 Vframe_list
= Fcons (frame
, Vframe_list
);
5465 f
->can_x_set_window_size
= true;
5467 /* Setting attributes of faces of the tooltip frame from resources
5468 and similar will set face_change, which leads to the clearing of
5469 all current matrices. Since this isn't necessary here, avoid it
5470 by resetting face_change to the value it had before we created
5472 face_change
= face_change_before
;
5474 /* Discard the unwind_protect. */
5475 return unbind_to (count
, frame
);
5479 /* Compute where to display tip frame F. PARMS is the list of frame
5480 parameters for F. DX and DY are specified offsets from the current
5481 location of the mouse. WIDTH and HEIGHT are the width and height
5482 of the tooltip. Return coordinates relative to the root window of
5483 the display in *ROOT_X, and *ROOT_Y. */
5486 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
)
5488 Lisp_Object left
, top
, right
, bottom
;
5493 /* User-specified position? */
5494 left
= Fcdr (Fassq (Qleft
, parms
));
5495 top
= Fcdr (Fassq (Qtop
, parms
));
5496 right
= Fcdr (Fassq (Qright
, parms
));
5497 bottom
= Fcdr (Fassq (Qbottom
, parms
));
5499 /* Move the tooltip window where the mouse pointer is. Resize and
5501 if ((!INTEGERP (left
) && !INTEGERP (right
))
5502 || (!INTEGERP (top
) && !INTEGERP (bottom
)))
5505 XQueryPointer (FRAME_X_DISPLAY (f
), FRAME_DISPLAY_INFO (f
)->root_window
,
5506 &root
, &child
, root_x
, root_y
, &win_x
, &win_y
, &pmask
);
5511 *root_y
= XINT (top
);
5512 else if (INTEGERP (bottom
))
5513 *root_y
= XINT (bottom
) - height
;
5514 else if (*root_y
+ XINT (dy
) <= 0)
5515 *root_y
= 0; /* Can happen for negative dy */
5516 else if (*root_y
+ XINT (dy
) + height
5517 <= x_display_pixel_height (FRAME_DISPLAY_INFO (f
)))
5518 /* It fits below the pointer */
5519 *root_y
+= XINT (dy
);
5520 else if (height
+ XINT (dy
) <= *root_y
)
5521 /* It fits above the pointer. */
5522 *root_y
-= height
+ XINT (dy
);
5524 /* Put it on the top. */
5527 if (INTEGERP (left
))
5528 *root_x
= XINT (left
);
5529 else if (INTEGERP (right
))
5530 *root_y
= XINT (right
) - width
;
5531 else if (*root_x
+ XINT (dx
) <= 0)
5532 *root_x
= 0; /* Can happen for negative dx */
5533 else if (*root_x
+ XINT (dx
) + width
5534 <= x_display_pixel_width (FRAME_DISPLAY_INFO (f
)))
5535 /* It fits to the right of the pointer. */
5536 *root_x
+= XINT (dx
);
5537 else if (width
+ XINT (dx
) <= *root_x
)
5538 /* It fits to the left of the pointer. */
5539 *root_x
-= width
+ XINT (dx
);
5541 /* Put it left-justified on the screen--it ought to fit that way. */
5546 DEFUN ("x-show-tip", Fx_show_tip
, Sx_show_tip
, 1, 6, 0,
5547 doc
: /* Show STRING in a "tooltip" window on frame FRAME.
5548 A tooltip window is a small X window displaying a string.
5550 This is an internal function; Lisp code should call `tooltip-show'.
5552 FRAME nil or omitted means use the selected frame.
5554 PARMS is an optional list of frame parameters which can be used to
5555 change the tooltip's appearance.
5557 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
5558 means use the default timeout of 5 seconds.
5560 If the list of frame parameters PARMS contains a `left' parameter,
5561 display the tooltip at that x-position. If the list of frame parameters
5562 PARMS contains no `left' but a `right' parameter, display the tooltip
5563 right-adjusted at that x-position. Otherwise display it at the
5564 x-position of the mouse, with offset DX added (default is 5 if DX isn't
5567 Likewise for the y-position: If a `top' frame parameter is specified, it
5568 determines the position of the upper edge of the tooltip window. If a
5569 `bottom' parameter but no `top' frame parameter is specified, it
5570 determines the position of the lower edge of the tooltip window.
5571 Otherwise display the tooltip window at the y-position of the mouse,
5572 with offset DY added (default is -10).
5574 A tooltip's maximum size is specified by `x-max-tooltip-size'.
5575 Text larger than the specified size is clipped. */)
5576 (Lisp_Object string
, Lisp_Object frame
, Lisp_Object parms
, Lisp_Object timeout
, Lisp_Object dx
, Lisp_Object dy
)
5581 struct buffer
*old_buffer
;
5582 struct text_pos pos
;
5583 int i
, width
, height
;
5584 bool seen_reversed_p
;
5585 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
5586 ptrdiff_t count
= SPECPDL_INDEX ();
5588 specbind (Qinhibit_redisplay
, Qt
);
5590 CHECK_STRING (string
);
5591 if (SCHARS (string
) == 0)
5592 string
= make_unibyte_string (" ", 1);
5594 f
= decode_window_system_frame (frame
);
5596 timeout
= make_number (5);
5598 CHECK_NATNUM (timeout
);
5601 dx
= make_number (5);
5606 dy
= make_number (-10);
5611 if (x_gtk_use_system_tooltips
)
5615 /* Hide a previous tip, if any. */
5619 ok
= xg_prepare_tooltip (f
, string
, &width
, &height
);
5622 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, &root_x
, &root_y
);
5623 xg_show_tooltip (f
, root_x
, root_y
);
5624 /* This is used in Fx_hide_tip. */
5625 XSETFRAME (tip_frame
, f
);
5628 if (ok
) goto start_timer
;
5630 #endif /* USE_GTK */
5632 if (NILP (last_show_tip_args
))
5633 last_show_tip_args
= Fmake_vector (make_number (3), Qnil
);
5635 if (!NILP (tip_frame
))
5637 Lisp_Object last_string
= AREF (last_show_tip_args
, 0);
5638 Lisp_Object last_frame
= AREF (last_show_tip_args
, 1);
5639 Lisp_Object last_parms
= AREF (last_show_tip_args
, 2);
5641 if (EQ (frame
, last_frame
)
5642 && !NILP (Fequal (last_string
, string
))
5643 && !NILP (Fequal (last_parms
, parms
)))
5645 struct frame
*tip_f
= XFRAME (tip_frame
);
5647 /* Only DX and DY have changed. */
5648 if (!NILP (tip_timer
))
5650 Lisp_Object timer
= tip_timer
;
5652 call1 (Qcancel_timer
, timer
);
5656 compute_tip_xy (tip_f
, parms
, dx
, dy
, FRAME_PIXEL_WIDTH (tip_f
),
5657 FRAME_PIXEL_HEIGHT (tip_f
), &root_x
, &root_y
);
5658 XMoveWindow (FRAME_X_DISPLAY (tip_f
), FRAME_X_WINDOW (tip_f
),
5665 /* Hide a previous tip, if any. */
5668 ASET (last_show_tip_args
, 0, string
);
5669 ASET (last_show_tip_args
, 1, frame
);
5670 ASET (last_show_tip_args
, 2, parms
);
5672 /* Add default values to frame parameters. */
5673 if (NILP (Fassq (Qname
, parms
)))
5674 parms
= Fcons (Fcons (Qname
, build_string ("tooltip")), parms
);
5675 if (NILP (Fassq (Qinternal_border_width
, parms
)))
5676 parms
= Fcons (Fcons (Qinternal_border_width
, make_number (3)), parms
);
5677 if (NILP (Fassq (Qborder_width
, parms
)))
5678 parms
= Fcons (Fcons (Qborder_width
, make_number (1)), parms
);
5679 if (NILP (Fassq (Qbottom_divider_width
, parms
)))
5680 parms
= Fcons (Fcons (Qbottom_divider_width
, make_number (0)), parms
);
5681 if (NILP (Fassq (Qright_divider_width
, parms
)))
5682 parms
= Fcons (Fcons (Qright_divider_width
, make_number (0)), parms
);
5683 if (NILP (Fassq (Qborder_color
, parms
)))
5684 parms
= Fcons (Fcons (Qborder_color
, build_string ("lightyellow")), parms
);
5685 if (NILP (Fassq (Qbackground_color
, parms
)))
5686 parms
= Fcons (Fcons (Qbackground_color
, build_string ("lightyellow")),
5689 /* Create a frame for the tooltip, and record it in the global
5690 variable tip_frame. */
5691 frame
= x_create_tip_frame (FRAME_DISPLAY_INFO (f
), parms
, string
);
5694 /* Set up the frame's root window. */
5695 w
= XWINDOW (FRAME_ROOT_WINDOW (f
));
5701 if (CONSP (Vx_max_tooltip_size
)
5702 && RANGED_INTEGERP (1, XCAR (Vx_max_tooltip_size
), INT_MAX
)
5703 && RANGED_INTEGERP (1, XCDR (Vx_max_tooltip_size
), INT_MAX
))
5705 w
->total_cols
= XFASTINT (XCAR (Vx_max_tooltip_size
));
5706 w
->total_lines
= XFASTINT (XCDR (Vx_max_tooltip_size
));
5711 w
->total_lines
= 40;
5714 w
->pixel_width
= w
->total_cols
* FRAME_COLUMN_WIDTH (f
);
5715 w
->pixel_height
= w
->total_lines
* FRAME_LINE_HEIGHT (f
);
5717 FRAME_TOTAL_COLS (f
) = w
->total_cols
;
5718 adjust_frame_glyphs (f
);
5719 w
->pseudo_window_p
= true;
5721 /* Display the tooltip text in a temporary buffer. */
5722 old_buffer
= current_buffer
;
5723 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f
))->contents
));
5724 bset_truncate_lines (current_buffer
, Qnil
);
5725 clear_glyph_matrix (w
->desired_matrix
);
5726 clear_glyph_matrix (w
->current_matrix
);
5727 SET_TEXT_POS (pos
, BEGV
, BEGV_BYTE
);
5728 try_window (FRAME_ROOT_WINDOW (f
), pos
, TRY_WINDOW_IGNORE_FONTS_CHANGE
);
5730 /* Compute width and height of the tooltip. */
5732 seen_reversed_p
= false;
5733 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
5735 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
5739 /* Stop at the first empty row at the end. */
5740 if (!row
->enabled_p
|| !MATRIX_ROW_DISPLAYS_TEXT_P (row
))
5743 /* Let the row go over the full width of the frame. */
5744 row
->full_width_p
= true;
5746 row_width
= row
->pixel_width
;
5747 if (row
->used
[TEXT_AREA
])
5749 /* There's a glyph at the end of rows that is used to place
5750 the cursor there. Don't include the width of this glyph. */
5751 if (!row
->reversed_p
)
5753 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
5754 if (NILP (last
->object
))
5755 row_width
-= last
->pixel_width
;
5759 /* There could be a stretch glyph at the beginning of R2L
5760 rows that is produced by extend_face_to_end_of_line.
5761 Don't count that glyph. */
5762 struct glyph
*g
= row
->glyphs
[TEXT_AREA
];
5764 if (g
->type
== STRETCH_GLYPH
&& NILP (g
->object
))
5766 row_width
-= g
->pixel_width
;
5767 seen_reversed_p
= true;
5772 height
+= row
->height
;
5773 width
= max (width
, row_width
);
5776 /* If we've seen partial-length R2L rows, we need to re-adjust the
5777 tool-tip frame width and redisplay it again, to avoid over-wide
5778 tips due to the stretch glyph that extends R2L lines to full
5779 width of the frame. */
5780 if (seen_reversed_p
)
5782 /* w->total_cols and FRAME_TOTAL_COLS want the width in columns,
5784 w
->pixel_width
= width
;
5785 width
/= WINDOW_FRAME_COLUMN_WIDTH (w
);
5786 w
->total_cols
= width
;
5787 FRAME_TOTAL_COLS (f
) = width
;
5788 SET_FRAME_WIDTH (f
, width
);
5789 adjust_frame_glyphs (f
);
5790 clear_glyph_matrix (w
->desired_matrix
);
5791 clear_glyph_matrix (w
->current_matrix
);
5792 try_window (FRAME_ROOT_WINDOW (f
), pos
, 0);
5794 /* Recompute width and height of the tooltip. */
5795 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
5797 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
5801 if (!row
->enabled_p
|| !MATRIX_ROW_DISPLAYS_TEXT_P (row
))
5803 row
->full_width_p
= true;
5804 row_width
= row
->pixel_width
;
5805 if (row
->used
[TEXT_AREA
] && !row
->reversed_p
)
5807 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
5808 if (NILP (last
->object
))
5809 row_width
-= last
->pixel_width
;
5812 height
+= row
->height
;
5813 width
= max (width
, row_width
);
5817 /* Add the frame's internal border to the width and height the X
5818 window should have. */
5819 height
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
5820 width
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
5822 /* Move the tooltip window where the mouse pointer is. Resize and
5824 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, &root_x
, &root_y
);
5827 XMoveResizeWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5828 root_x
, root_y
, width
, height
);
5829 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
5832 /* Draw into the window. */
5833 w
->must_be_updated_p
= true;
5834 update_single_window (w
);
5836 /* Restore original current buffer. */
5837 set_buffer_internal_1 (old_buffer
);
5838 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
5841 /* Let the tip disappear after timeout seconds. */
5842 tip_timer
= call3 (intern ("run-at-time"), timeout
, Qnil
,
5843 intern ("x-hide-tip"));
5845 return unbind_to (count
, Qnil
);
5849 DEFUN ("x-hide-tip", Fx_hide_tip
, Sx_hide_tip
, 0, 0, 0,
5850 doc
: /* Hide the current tooltip window, if there is any.
5851 Value is t if tooltip was open, nil otherwise. */)
5855 Lisp_Object deleted
, frame
, timer
;
5857 /* Return quickly if nothing to do. */
5858 if (NILP (tip_timer
) && NILP (tip_frame
))
5863 tip_frame
= tip_timer
= deleted
= Qnil
;
5865 count
= SPECPDL_INDEX ();
5866 specbind (Qinhibit_redisplay
, Qt
);
5867 specbind (Qinhibit_quit
, Qt
);
5870 call1 (Qcancel_timer
, timer
);
5874 /* When using system tooltip, tip_frame is the Emacs frame on which
5875 the tip is shown. */
5876 struct frame
*f
= XFRAME (frame
);
5877 if (FRAME_LIVE_P (f
) && xg_hide_tooltip (f
))
5884 delete_frame (frame
, Qnil
);
5888 /* Bloodcurdling hack alert: The Lucid menu bar widget's
5889 redisplay procedure is not called when a tip frame over menu
5890 items is unmapped. Redisplay the menu manually... */
5893 struct frame
*f
= SELECTED_FRAME ();
5894 w
= f
->output_data
.x
->menubar_widget
;
5896 if (!DoesSaveUnders (FRAME_DISPLAY_INFO (f
)->screen
)
5900 xlwmenu_redisplay (w
);
5904 #endif /* USE_LUCID */
5907 return unbind_to (count
, deleted
);
5912 /***********************************************************************
5913 File selection dialog
5914 ***********************************************************************/
5916 DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog
,
5917 Sx_uses_old_gtk_dialog
,
5919 doc
: /* Return t if the old Gtk+ file selection dialog is used. */)
5925 && window_system_available (SELECTED_FRAME ())
5926 && xg_uses_old_file_dialog ())
5934 /* Callback for "OK" and "Cancel" on file selection dialog. */
5937 file_dialog_cb (Widget widget
, XtPointer client_data
, XtPointer call_data
)
5939 int *result
= client_data
;
5940 XmAnyCallbackStruct
*cb
= call_data
;
5941 *result
= cb
->reason
;
5945 /* Callback for unmapping a file selection dialog. This is used to
5946 capture the case where a dialog is closed via a window manager's
5947 closer button, for example. Using a XmNdestroyCallback didn't work
5951 file_dialog_unmap_cb (Widget widget
, XtPointer client_data
, XtPointer call_data
)
5953 int *result
= client_data
;
5954 *result
= XmCR_CANCEL
;
5958 clean_up_file_dialog (void *arg
)
5960 Widget dialog
= arg
;
5964 XtUnmanageChild (dialog
);
5965 XtDestroyWidget (dialog
);
5966 x_menu_set_in_use (false);
5971 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 5, 0,
5972 doc
: /* Read file name, prompting with PROMPT in directory DIR.
5973 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5974 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5975 or directory must exist.
5977 This function is only defined on NS, MS Windows, and X Windows with the
5978 Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
5979 Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.
5980 On Windows 7 and later, the file selection dialog "remembers" the last
5981 directory where the user selected a file, and will open that directory
5982 instead of DIR on subsequent invocations of this function with the same
5983 value of DIR as in previous invocations; this is standard Windows behavior. */)
5984 (Lisp_Object prompt
, Lisp_Object dir
, Lisp_Object default_filename
,
5985 Lisp_Object mustmatch
, Lisp_Object only_dir_p
)
5988 struct frame
*f
= SELECTED_FRAME ();
5989 Lisp_Object file
= Qnil
;
5990 Lisp_Object decoded_file
;
5991 Widget dialog
, text
, help
;
5994 XmString dir_xmstring
, pattern_xmstring
;
5995 ptrdiff_t count
= SPECPDL_INDEX ();
5997 check_window_system (f
);
5999 if (popup_activated ())
6000 error ("Trying to use a menu from within a menu-entry");
6002 CHECK_STRING (prompt
);
6005 /* Prevent redisplay. */
6006 specbind (Qinhibit_redisplay
, Qt
);
6010 /* Create the dialog with PROMPT as title, using DIR as initial
6011 directory and using "*" as pattern. */
6012 dir
= Fexpand_file_name (dir
, Qnil
);
6013 dir_xmstring
= XmStringCreateLocalized (SSDATA (dir
));
6014 pattern_xmstring
= XmStringCreateLocalized ("*");
6016 XtSetArg (al
[ac
], XmNtitle
, SDATA (prompt
)); ++ac
;
6017 XtSetArg (al
[ac
], XmNdirectory
, dir_xmstring
); ++ac
;
6018 XtSetArg (al
[ac
], XmNpattern
, pattern_xmstring
); ++ac
;
6019 XtSetArg (al
[ac
], XmNresizePolicy
, XmRESIZE_GROW
); ++ac
;
6020 XtSetArg (al
[ac
], XmNdialogStyle
, XmDIALOG_APPLICATION_MODAL
); ++ac
;
6021 dialog
= XmCreateFileSelectionDialog (f
->output_data
.x
->widget
,
6023 XmStringFree (dir_xmstring
);
6024 XmStringFree (pattern_xmstring
);
6026 /* Add callbacks for OK and Cancel. */
6027 XtAddCallback (dialog
, XmNokCallback
, file_dialog_cb
,
6028 (XtPointer
) &result
);
6029 XtAddCallback (dialog
, XmNcancelCallback
, file_dialog_cb
,
6030 (XtPointer
) &result
);
6031 XtAddCallback (dialog
, XmNunmapCallback
, file_dialog_unmap_cb
,
6032 (XtPointer
) &result
);
6034 /* Remove the help button since we can't display help. */
6035 help
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_HELP_BUTTON
);
6036 XtUnmanageChild (help
);
6038 /* Mark OK button as default. */
6039 XtVaSetValues (XmFileSelectionBoxGetChild (dialog
, XmDIALOG_OK_BUTTON
),
6040 XmNshowAsDefault
, True
, NULL
);
6042 /* If MUSTMATCH is non-nil, disable the file entry field of the
6043 dialog, so that the user must select a file from the files list
6044 box. We can't remove it because we wouldn't have a way to get at
6045 the result file name, then. */
6046 text
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
6047 if (!NILP (mustmatch
))
6050 label
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_SELECTION_LABEL
);
6051 XtSetSensitive (text
, False
);
6052 XtSetSensitive (label
, False
);
6055 /* Manage the dialog, so that list boxes get filled. */
6056 XtManageChild (dialog
);
6058 if (STRINGP (default_filename
))
6060 XmString default_xmstring
;
6061 Widget wtext
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
6062 Widget list
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_LIST
);
6064 XmTextPosition last_pos
= XmTextFieldGetLastPosition (wtext
);
6065 XmTextFieldReplace (wtext
, 0, last_pos
,
6066 (SSDATA (Ffile_name_nondirectory (default_filename
))));
6068 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
6069 must include the path for this to work. */
6071 default_xmstring
= XmStringCreateLocalized (SSDATA (default_filename
));
6073 if (XmListItemExists (list
, default_xmstring
))
6075 int item_pos
= XmListItemPos (list
, default_xmstring
);
6076 /* Select the item and scroll it into view. */
6077 XmListSelectPos (list
, item_pos
, True
);
6078 XmListSetPos (list
, item_pos
);
6081 XmStringFree (default_xmstring
);
6084 record_unwind_protect_ptr (clean_up_file_dialog
, dialog
);
6086 /* Process events until the user presses Cancel or OK. */
6087 x_menu_set_in_use (true);
6092 x_menu_wait_for_event (0);
6093 XtAppNextEvent (Xt_app_con
, &event
);
6094 if (event
.type
== KeyPress
6095 && FRAME_X_DISPLAY (f
) == event
.xkey
.display
)
6097 KeySym keysym
= XLookupKeysym (&event
.xkey
, 0);
6099 /* Pop down on C-g. */
6100 if (keysym
== XK_g
&& (event
.xkey
.state
& ControlMask
) != 0)
6101 XtUnmanageChild (dialog
);
6104 (void) x_dispatch_event (&event
, FRAME_X_DISPLAY (f
));
6107 /* Get the result. */
6108 if (result
== XmCR_OK
)
6110 XmString text_string
;
6113 XtVaGetValues (dialog
, XmNtextString
, &text_string
, NULL
);
6114 XmStringGetLtoR (text_string
, XmFONTLIST_DEFAULT_TAG
, &data
);
6115 XmStringFree (text_string
);
6116 file
= build_string (data
);
6124 /* Make "Cancel" equivalent to C-g. */
6126 Fsignal (Qquit
, Qnil
);
6128 decoded_file
= DECODE_FILE (file
);
6130 return unbind_to (count
, decoded_file
);
6133 #endif /* USE_MOTIF */
6138 clean_up_dialog (void)
6140 x_menu_set_in_use (false);
6143 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 5, 0,
6144 doc
: /* Read file name, prompting with PROMPT in directory DIR.
6145 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
6146 selection box, if specified. If MUSTMATCH is non-nil, the returned file
6147 or directory must exist.
6149 This function is only defined on NS, MS Windows, and X Windows with the
6150 Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
6151 Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.
6152 On Windows 7 and later, the file selection dialog "remembers" the last
6153 directory where the user selected a file, and will open that directory
6154 instead of DIR on subsequent invocations of this function with the same
6155 value of DIR as in previous invocations; this is standard Windows behavior. */)
6156 (Lisp_Object prompt
, Lisp_Object dir
, Lisp_Object default_filename
, Lisp_Object mustmatch
, Lisp_Object only_dir_p
)
6158 struct frame
*f
= SELECTED_FRAME ();
6160 Lisp_Object file
= Qnil
;
6161 Lisp_Object decoded_file
;
6162 ptrdiff_t count
= SPECPDL_INDEX ();
6165 check_window_system (f
);
6167 if (popup_activated ())
6168 error ("Trying to use a menu from within a menu-entry");
6170 CHECK_STRING (prompt
);
6173 /* Prevent redisplay. */
6174 specbind (Qinhibit_redisplay
, Qt
);
6175 record_unwind_protect_void (clean_up_dialog
);
6179 if (STRINGP (default_filename
))
6180 cdef_file
= SSDATA (default_filename
);
6182 cdef_file
= SSDATA (dir
);
6184 fn
= xg_get_file_name (f
, SSDATA (prompt
), cdef_file
,
6186 ! NILP (only_dir_p
));
6190 file
= build_string (fn
);
6196 /* Make "Cancel" equivalent to C-g. */
6198 Fsignal (Qquit
, Qnil
);
6200 decoded_file
= DECODE_FILE (file
);
6202 return unbind_to (count
, decoded_file
);
6206 #ifdef HAVE_FREETYPE
6208 DEFUN ("x-select-font", Fx_select_font
, Sx_select_font
, 0, 2, 0,
6209 doc
: /* Read a font using a GTK dialog.
6210 Return either a font spec (for GTK versions >= 3.2) or a string
6211 containing a GTK-style font name.
6213 FRAME is the frame on which to pop up the font chooser. If omitted or
6214 nil, it defaults to the selected frame. */)
6215 (Lisp_Object frame
, Lisp_Object ignored
)
6217 struct frame
*f
= decode_window_system_frame (frame
);
6219 Lisp_Object font_param
;
6220 char *default_name
= NULL
;
6221 ptrdiff_t count
= SPECPDL_INDEX ();
6223 if (popup_activated ())
6224 error ("Trying to use a menu from within a menu-entry");
6226 /* Prevent redisplay. */
6227 specbind (Qinhibit_redisplay
, Qt
);
6228 record_unwind_protect_void (clean_up_dialog
);
6232 XSETFONT (font
, FRAME_FONT (f
));
6233 font_param
= Ffont_get (font
, QCname
);
6234 if (STRINGP (font_param
))
6235 default_name
= xlispstrdup (font_param
);
6238 font_param
= Fframe_parameter (frame
, Qfont_param
);
6239 if (STRINGP (font_param
))
6240 default_name
= xlispstrdup (font_param
);
6243 font
= xg_get_font (f
, default_name
);
6244 xfree (default_name
);
6249 Fsignal (Qquit
, Qnil
);
6251 return unbind_to (count
, font
);
6253 #endif /* HAVE_FREETYPE */
6255 #endif /* USE_GTK */
6258 /***********************************************************************
6260 ***********************************************************************/
6263 #include <X11/XKBlib.h>
6264 #include <X11/keysym.h>
6267 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p
,
6268 Sx_backspace_delete_keys_p
, 0, 1, 0,
6269 doc
: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
6270 FRAME nil means use the selected frame.
6271 Value is t if we know that both keys are present, and are mapped to the
6272 usual X keysyms. Value is `lambda' if we cannot determine if both keys are
6273 present and mapped to the usual X keysyms. */)
6280 struct frame
*f
= decode_window_system_frame (frame
);
6281 Display
*dpy
= FRAME_X_DISPLAY (f
);
6282 Lisp_Object have_keys
;
6283 int major
, minor
, op
, event
, error_code
;
6287 /* Check library version in case we're dynamically linked. */
6288 major
= XkbMajorVersion
;
6289 minor
= XkbMinorVersion
;
6290 if (!XkbLibraryVersion (&major
, &minor
))
6296 /* Check that the server supports XKB. */
6297 major
= XkbMajorVersion
;
6298 minor
= XkbMinorVersion
;
6299 if (!XkbQueryExtension (dpy
, &op
, &event
, &error_code
, &major
, &minor
))
6305 /* In this code we check that the keyboard has physical keys with names
6306 that start with BKSP (Backspace) and DELE (Delete), and that they
6307 generate keysym XK_BackSpace and XK_Delete respectively.
6308 This function is used to test if normal-erase-is-backspace should be
6310 An alternative approach would be to just check if XK_BackSpace and
6311 XK_Delete are mapped to any key. But if any of those are mapped to
6312 some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the
6313 user doesn't know about it, it is better to return false here.
6314 It is more obvious to the user what to do if she/he has two keys
6315 clearly marked with names/symbols and one key does something not
6316 expected (i.e. she/he then tries the other).
6317 The cases where Backspace/Delete is mapped to some other key combination
6318 are rare, and in those cases, normal-erase-is-backspace can be turned on
6322 kb
= XkbGetMap (dpy
, XkbAllMapComponentsMask
, XkbUseCoreKbd
);
6325 int delete_keycode
= 0, backspace_keycode
= 0, i
;
6327 if (XkbGetNames (dpy
, XkbAllNamesMask
, kb
) == Success
)
6329 for (i
= kb
->min_key_code
;
6330 (i
< kb
->max_key_code
6331 && (delete_keycode
== 0 || backspace_keycode
== 0));
6334 /* The XKB symbolic key names can be seen most easily in
6335 the PS file generated by `xkbprint -label name
6337 if (memcmp ("DELE", kb
->names
->keys
[i
].name
, 4) == 0)
6339 else if (memcmp ("BKSP", kb
->names
->keys
[i
].name
, 4) == 0)
6340 backspace_keycode
= i
;
6343 XkbFreeNames (kb
, 0, True
);
6346 /* As of libX11-1.6.2, XkbGetMap manual says that you should use
6347 XkbFreeClientMap to free the data returned by XkbGetMap. But
6348 this function just frees the data referenced from KB and not
6349 KB itself. To free KB as well, call XkbFreeKeyboard. */
6350 XkbFreeKeyboard (kb
, XkbAllMapComponentsMask
, True
);
6353 && backspace_keycode
6354 && XKeysymToKeycode (dpy
, XK_Delete
) == delete_keycode
6355 && XKeysymToKeycode (dpy
, XK_BackSpace
) == backspace_keycode
)
6365 /***********************************************************************
6367 ***********************************************************************/
6370 DEFUN ("x-export-frames", Fx_export_frames
, Sx_export_frames
, 0, 2, 0,
6371 doc
: /* XXX Experimental. Return image data of FRAMES in TYPE format.
6372 FRAMES should be nil (the selected frame), a frame, or a list of
6373 frames (each of which corresponds to one page). Optional arg TYPE
6374 should be either `pdf' (default), `png', `ps', or `svg'. Supported
6375 types are determined by the compile-time configuration of cairo. */)
6376 (Lisp_Object frames
, Lisp_Object type
)
6378 Lisp_Object result
, rest
, tmp
;
6379 cairo_surface_type_t surface_type
;
6382 frames
= selected_frame
;
6383 if (!CONSP (frames
))
6384 frames
= list1 (frames
);
6387 for (rest
= frames
; CONSP (rest
); rest
= XCDR (rest
))
6389 struct frame
*f
= XFRAME (XCAR (rest
));
6391 if (! FRAME_LIVE_P (f
) || ! FRAME_X_P (f
) || ! FRAME_LIVE_P (f
))
6392 error ("Invalid frame");
6396 XSETFRAME (frame
, f
);
6397 tmp
= Fcons (frame
, tmp
);
6399 frames
= Fnreverse (tmp
);
6401 #ifdef CAIRO_HAS_PDF_SURFACE
6402 if (NILP (type
) || EQ (type
, intern ("pdf"))) /* XXX: Qpdf */
6403 surface_type
= CAIRO_SURFACE_TYPE_PDF
;
6406 #ifdef CAIRO_HAS_PNG_FUNCTIONS
6407 if (EQ (type
, intern ("png")))
6409 if (!NILP (XCDR (frames
)))
6410 error ("PNG export cannot handle multiple frames.");
6411 surface_type
= CAIRO_SURFACE_TYPE_IMAGE
;
6415 #ifdef CAIRO_HAS_PS_SURFACE
6416 if (EQ (type
, intern ("ps")))
6417 surface_type
= CAIRO_SURFACE_TYPE_PS
;
6420 #ifdef CAIRO_HAS_SVG_SURFACE
6421 if (EQ (type
, intern ("svg")))
6423 /* For now, we stick to SVG 1.1. */
6424 if (!NILP (XCDR (frames
)))
6425 error ("SVG export cannot handle multiple frames.");
6426 surface_type
= CAIRO_SURFACE_TYPE_SVG
;
6430 error ("Unsupported export type");
6432 result
= x_cr_export_frames (frames
, surface_type
);
6438 DEFUN ("x-page-setup-dialog", Fx_page_setup_dialog
, Sx_page_setup_dialog
, 0, 0, 0,
6439 doc
: /* Pop up a page setup dialog.
6440 The current page setup can be obtained using `x-get-page-setup'. */)
6444 xg_page_setup_dialog ();
6450 DEFUN ("x-get-page-setup", Fx_get_page_setup
, Sx_get_page_setup
, 0, 0, 0,
6451 doc
: /* Return the value of the current page setup.
6452 The return value is an alist containing the following keys:
6454 orientation: page orientation (symbol `portrait', `landscape',
6455 `reverse-portrait', or `reverse-landscape').
6456 width, height: page width/height in points not including margins.
6457 left-margin, right-margin, top-margin, bottom-margin: print margins,
6458 which is the parts of the page that the printer cannot print
6461 The paper width can be obtained as the sum of width, left-margin, and
6462 right-margin values. Likewise, the paper height is the sum of height,
6463 top-margin, and bottom-margin values. */)
6469 result
= xg_get_page_setup ();
6475 DEFUN ("x-print-frames-dialog", Fx_print_frames_dialog
, Sx_print_frames_dialog
, 0, 1, "",
6476 doc
: /* Pop up a print dialog to print the current contents of FRAMES.
6477 FRAMES should be nil (the selected frame), a frame, or a list of
6478 frames (each of which corresponds to one page). Each frame should be
6480 (Lisp_Object frames
)
6482 Lisp_Object rest
, tmp
;
6485 frames
= selected_frame
;
6486 if (!CONSP (frames
))
6487 frames
= list1 (frames
);
6490 for (rest
= frames
; CONSP (rest
); rest
= XCDR (rest
))
6492 struct frame
*f
= XFRAME (XCAR (rest
));
6493 if (! FRAME_LIVE_P (f
) || ! FRAME_X_P (f
) || ! FRAME_LIVE_P (f
))
6494 error ("Invalid frame");
6497 XSETFRAME (frame
, f
);
6498 if (!EQ (Fframe_visible_p (frame
), Qt
))
6499 error ("Frames to be printed must be visible.");
6500 tmp
= Fcons (frame
, tmp
);
6502 frames
= Fnreverse (tmp
);
6504 /* Make sure the current matrices are up-to-date. */
6508 xg_print_frames_dialog (frames
);
6513 #endif /* USE_GTK */
6514 #endif /* USE_CAIRO */
6517 /***********************************************************************
6519 ***********************************************************************/
6521 /* Keep this list in the same order as frame_parms in frame.c.
6522 Use 0 for unsupported frame parameters. */
6524 frame_parm_handler x_frame_parm_handlers
[] =
6528 x_set_background_color
,
6534 x_set_foreground_color
,
6537 x_set_internal_border_width
,
6538 x_set_right_divider_width
,
6539 x_set_bottom_divider_width
,
6540 x_set_menu_bar_lines
,
6542 x_explicitly_set_name
,
6543 x_set_scroll_bar_width
,
6544 x_set_scroll_bar_height
,
6547 x_set_vertical_scroll_bars
,
6548 x_set_horizontal_scroll_bars
,
6550 x_set_tool_bar_lines
,
6551 x_set_scroll_bar_foreground
,
6552 x_set_scroll_bar_background
,
6562 x_set_tool_bar_position
,
6568 DEFSYM (Qundefined_color
, "undefined-color");
6569 DEFSYM (Qcompound_text
, "compound-text");
6570 DEFSYM (Qcancel_timer
, "cancel-timer");
6571 DEFSYM (Qfont_param
, "font-parameter");
6572 DEFSYM (Qmono
, "mono");
6575 DEFSYM (Qorientation
, "orientation");
6576 DEFSYM (Qtop_margin
, "top-margin");
6577 DEFSYM (Qbottom_margin
, "bottom-margin");
6578 DEFSYM (Qportrait
, "portrait");
6579 DEFSYM (Qlandscape
, "landscape");
6580 DEFSYM (Qreverse_portrait
, "reverse-portrait");
6581 DEFSYM (Qreverse_landscape
, "reverse-landscape");
6584 Fput (Qundefined_color
, Qerror_conditions
,
6585 listn (CONSTYPE_PURE
, 2, Qundefined_color
, Qerror
));
6586 Fput (Qundefined_color
, Qerror_message
,
6587 build_pure_c_string ("Undefined color"));
6589 DEFVAR_LISP ("x-pointer-shape", Vx_pointer_shape
,
6590 doc
: /* The shape of the pointer when over text.
6591 Changing the value does not affect existing frames
6592 unless you set the mouse color. */);
6593 Vx_pointer_shape
= Qnil
;
6595 #if false /* This doesn't really do anything. */
6596 DEFVAR_LISP ("x-nontext-pointer-shape", Vx_nontext_pointer_shape
,
6597 doc
: /* The shape of the pointer when not over text.
6598 This variable takes effect when you create a new frame
6599 or when you set the mouse color. */);
6601 Vx_nontext_pointer_shape
= Qnil
;
6603 DEFVAR_LISP ("x-hourglass-pointer-shape", Vx_hourglass_pointer_shape
,
6604 doc
: /* The shape of the pointer when Emacs is busy.
6605 This variable takes effect when you create a new frame
6606 or when you set the mouse color. */);
6607 Vx_hourglass_pointer_shape
= Qnil
;
6609 #if false /* This doesn't really do anything. */
6610 DEFVAR_LISP ("x-mode-pointer-shape", Vx_mode_pointer_shape
,
6611 doc
: /* The shape of the pointer when over the mode line.
6612 This variable takes effect when you create a new frame
6613 or when you set the mouse color. */);
6615 Vx_mode_pointer_shape
= Qnil
;
6617 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
6618 Vx_sensitive_text_pointer_shape
,
6619 doc
: /* The shape of the pointer when over mouse-sensitive text.
6620 This variable takes effect when you create a new frame
6621 or when you set the mouse color. */);
6622 Vx_sensitive_text_pointer_shape
= Qnil
;
6624 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
6625 Vx_window_horizontal_drag_shape
,
6626 doc
: /* Pointer shape to use for indicating a window can be dragged horizontally.
6627 This variable takes effect when you create a new frame
6628 or when you set the mouse color. */);
6629 Vx_window_horizontal_drag_shape
= Qnil
;
6631 DEFVAR_LISP ("x-window-vertical-drag-cursor",
6632 Vx_window_vertical_drag_shape
,
6633 doc
: /* Pointer shape to use for indicating a window can be dragged vertically.
6634 This variable takes effect when you create a new frame
6635 or when you set the mouse color. */);
6636 Vx_window_vertical_drag_shape
= Qnil
;
6638 DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel
,
6639 doc
: /* A string indicating the foreground color of the cursor box. */);
6640 Vx_cursor_fore_pixel
= Qnil
;
6642 DEFVAR_LISP ("x-max-tooltip-size", Vx_max_tooltip_size
,
6643 doc
: /* Maximum size for tooltips.
6644 Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */);
6645 Vx_max_tooltip_size
= Fcons (make_number (80), make_number (40));
6647 DEFVAR_LISP ("x-no-window-manager", Vx_no_window_manager
,
6648 doc
: /* Non-nil if no X window manager is in use.
6649 Emacs doesn't try to figure this out; this is always nil
6650 unless you set it to something else. */);
6651 /* We don't have any way to find this out, so set it to nil
6652 and maybe the user would like to set it to t. */
6653 Vx_no_window_manager
= Qnil
;
6655 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
6656 Vx_pixel_size_width_font_regexp
,
6657 doc
: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
6659 Since Emacs gets width of a font matching with this regexp from
6660 PIXEL_SIZE field of the name, font finding mechanism gets faster for
6661 such a font. This is especially effective for such large fonts as
6662 Chinese, Japanese, and Korean. */);
6663 Vx_pixel_size_width_font_regexp
= Qnil
;
6665 /* This is not ifdef:ed, so other builds than GTK can customize it. */
6666 DEFVAR_BOOL ("x-gtk-use-old-file-dialog", x_gtk_use_old_file_dialog
,
6667 doc
: /* Non-nil means prompt with the old GTK file selection dialog.
6668 If nil or if the file selection dialog is not available, the new GTK file
6669 chooser is used instead. To turn off all file dialogs set the
6670 variable `use-file-dialog'. */);
6671 x_gtk_use_old_file_dialog
= false;
6673 DEFVAR_BOOL ("x-gtk-show-hidden-files", x_gtk_show_hidden_files
,
6674 doc
: /* If non-nil, the GTK file chooser will by default show hidden files.
6675 Note that this is just the default, there is a toggle button on the file
6676 chooser to show or not show hidden files on a case by case basis. */);
6677 x_gtk_show_hidden_files
= false;
6679 DEFVAR_BOOL ("x-gtk-file-dialog-help-text", x_gtk_file_dialog_help_text
,
6680 doc
: /* If non-nil, the GTK file chooser will show additional help text.
6681 If more space for files in the file chooser dialog is wanted, set this to nil
6682 to turn the additional text off. */);
6683 x_gtk_file_dialog_help_text
= true;
6685 DEFVAR_BOOL ("x-gtk-use-system-tooltips", x_gtk_use_system_tooltips
,
6686 doc
: /* If non-nil with a Gtk+ built Emacs, the Gtk+ tooltip is used.
6687 Otherwise use Emacs own tooltip implementation.
6688 When using Gtk+ tooltips, the tooltip face is not used. */);
6689 x_gtk_use_system_tooltips
= true;
6691 /* Tell Emacs about this window system. */
6692 Fprovide (Qx
, Qnil
);
6694 #ifdef USE_X_TOOLKIT
6695 Fprovide (intern_c_string ("x-toolkit"), Qnil
);
6697 Fprovide (intern_c_string ("motif"), Qnil
);
6699 DEFVAR_LISP ("motif-version-string", Vmotif_version_string
,
6700 doc
: /* Version info for LessTif/Motif. */);
6701 Vmotif_version_string
= build_string (XmVERSION_STRING
);
6702 #endif /* USE_MOTIF */
6703 #endif /* USE_X_TOOLKIT */
6706 /* Provide x-toolkit also for GTK. Internally GTK does not use Xt so it
6707 is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
6708 But for a user it is a toolkit for X, and indeed, configure
6709 accepts --with-x-toolkit=gtk. */
6710 Fprovide (intern_c_string ("x-toolkit"), Qnil
);
6711 Fprovide (intern_c_string ("gtk"), Qnil
);
6712 Fprovide (intern_c_string ("move-toolbar"), Qnil
);
6714 DEFVAR_LISP ("gtk-version-string", Vgtk_version_string
,
6715 doc
: /* Version info for GTK+. */);
6717 char gtk_version
[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
6718 int len
= sprintf (gtk_version
, "%d.%d.%d",
6719 GTK_MAJOR_VERSION
, GTK_MINOR_VERSION
, GTK_MICRO_VERSION
);
6720 Vgtk_version_string
= make_pure_string (gtk_version
, len
, len
, false);
6722 #endif /* USE_GTK */
6725 Fprovide (intern_c_string ("cairo"), Qnil
);
6727 DEFVAR_LISP ("cairo-version-string", Vcairo_version_string
,
6728 doc
: /* Version info for cairo. */);
6730 char cairo_version
[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
6731 int len
= sprintf (cairo_version
, "%d.%d.%d",
6732 CAIRO_VERSION_MAJOR
, CAIRO_VERSION_MINOR
,
6733 CAIRO_VERSION_MICRO
);
6734 Vcairo_version_string
= make_pure_string (cairo_version
, len
, len
, false);
6738 /* X window properties. */
6739 defsubr (&Sx_change_window_property
);
6740 defsubr (&Sx_delete_window_property
);
6741 defsubr (&Sx_window_property
);
6743 defsubr (&Sxw_display_color_p
);
6744 defsubr (&Sx_display_grayscale_p
);
6745 defsubr (&Sxw_color_defined_p
);
6746 defsubr (&Sxw_color_values
);
6747 defsubr (&Sx_server_max_request_size
);
6748 defsubr (&Sx_server_vendor
);
6749 defsubr (&Sx_server_version
);
6750 defsubr (&Sx_display_pixel_width
);
6751 defsubr (&Sx_display_pixel_height
);
6752 defsubr (&Sx_display_mm_width
);
6753 defsubr (&Sx_display_mm_height
);
6754 defsubr (&Sx_display_screens
);
6755 defsubr (&Sx_display_planes
);
6756 defsubr (&Sx_display_color_cells
);
6757 defsubr (&Sx_display_visual_class
);
6758 defsubr (&Sx_display_backing_store
);
6759 defsubr (&Sx_display_save_under
);
6760 defsubr (&Sx_display_monitor_attributes_list
);
6761 defsubr (&Sx_frame_geometry
);
6762 defsubr (&Sx_frame_edges
);
6763 defsubr (&Sx_mouse_absolute_pixel_position
);
6764 defsubr (&Sx_set_mouse_absolute_pixel_position
);
6765 defsubr (&Sx_wm_set_size_hint
);
6766 defsubr (&Sx_create_frame
);
6767 defsubr (&Sx_open_connection
);
6768 defsubr (&Sx_close_connection
);
6769 defsubr (&Sx_display_list
);
6770 defsubr (&Sx_synchronize
);
6771 defsubr (&Sx_backspace_delete_keys_p
);
6773 defsubr (&Sx_show_tip
);
6774 defsubr (&Sx_hide_tip
);
6776 staticpro (&tip_timer
);
6778 staticpro (&tip_frame
);
6780 last_show_tip_args
= Qnil
;
6781 staticpro (&last_show_tip_args
);
6783 defsubr (&Sx_uses_old_gtk_dialog
);
6784 #if defined (USE_MOTIF) || defined (USE_GTK)
6785 defsubr (&Sx_file_dialog
);
6788 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
6789 defsubr (&Sx_select_font
);
6793 defsubr (&Sx_export_frames
);
6795 defsubr (&Sx_page_setup_dialog
);
6796 defsubr (&Sx_get_page_setup
);
6797 defsubr (&Sx_print_frames_dialog
);