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 "character.h"
32 #include "intervals.h"
33 #include "dispextern.h"
35 #include "blockinput.h"
41 #include "termhooks.h"
46 #include <sys/types.h>
49 #include "bitmaps/gray.xbm"
50 #include "xsettings.h"
53 #include <X11/extensions/Xrandr.h>
56 #include <X11/extensions/Xinerama.h>
64 #include <X11/Shell.h>
68 #include <X11/Xaw3d/Paned.h>
69 #include <X11/Xaw3d/Label.h>
70 #else /* !HAVE_XAW3D */
71 #include <X11/Xaw/Paned.h>
72 #include <X11/Xaw/Label.h>
73 #endif /* HAVE_XAW3D */
74 #endif /* USE_MOTIF */
77 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
80 #ifdef USG /* Pacify gcc -Wunused-macros. */
88 #include "../lwlib/lwlib.h"
92 #include <Xm/DialogS.h>
93 #include <Xm/FileSB.h>
99 #include "../lwlib/xlwmenu.h"
102 #if !defined (NO_EDITRES)
104 extern void _XEditResCheckMessages (Widget
, XtPointer
, XEvent
*, Boolean
*);
105 #endif /* not defined NO_EDITRES */
107 /* Unique id counter for widgets created by the Lucid Widget Library. */
109 extern LWLIB_ID widget_id_tick
;
113 #endif /* USE_MOTIF */
115 #endif /* USE_X_TOOLKIT */
121 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
123 static ptrdiff_t image_cache_refcount
;
125 static int dpyinfo_refcount
;
128 static struct x_display_info
*x_display_info_for_name (Lisp_Object
);
130 /* Let the user specify an X display with a Lisp object.
131 OBJECT may be nil, a frame or a terminal object.
132 nil stands for the selected frame--or, if that is not an X frame,
133 the first X display on the list. */
135 struct x_display_info
*
136 check_x_display_info (Lisp_Object object
)
138 struct x_display_info
*dpyinfo
= NULL
;
142 struct frame
*sf
= XFRAME (selected_frame
);
144 if (FRAME_X_P (sf
) && FRAME_LIVE_P (sf
))
145 dpyinfo
= FRAME_DISPLAY_INFO (sf
);
146 else if (x_display_list
!= 0)
147 dpyinfo
= x_display_list
;
149 error ("X windows are not in use or not initialized");
151 else if (TERMINALP (object
))
153 struct terminal
*t
= decode_live_terminal (object
);
155 if (t
->type
!= output_x_window
)
156 error ("Terminal %d is not an X display", t
->id
);
158 dpyinfo
= t
->display_info
.x
;
160 else if (STRINGP (object
))
161 dpyinfo
= x_display_info_for_name (object
);
164 struct frame
*f
= decode_window_system_frame (object
);
165 dpyinfo
= FRAME_DISPLAY_INFO (f
);
171 /* Return the screen positions and offsets of frame F.
172 Store the offsets between FRAME_OUTER_WINDOW and the containing
173 window manager window into LEFT_OFFSET_X, RIGHT_OFFSET_X,
174 TOP_OFFSET_Y and BOTTOM_OFFSET_Y.
175 Store the offsets between FRAME_X_WINDOW and the containing
176 window manager window into X_PIXELS_DIFF and Y_PIXELS_DIFF.
177 Store the screen positions of frame F into XPTR and YPTR.
178 These are the positions of the containing window manager window,
179 not Emacs's own window. */
181 x_real_pos_and_offsets (struct frame
*f
,
185 int *bottom_offset_y
,
192 int win_x
, win_y
, outer_x
IF_LINT (= 0), outer_y
IF_LINT (= 0);
193 int real_x
= 0, real_y
= 0;
194 bool had_errors
= false;
195 Window win
= f
->output_data
.x
->parent_desc
;
197 unsigned long actual_size
, bytes_remaining
;
198 int rc
, actual_format
;
199 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
201 Display
*dpy
= FRAME_X_DISPLAY (f
);
202 unsigned char *tmp_data
= NULL
;
203 Atom target_type
= XA_CARDINAL
;
204 unsigned int ow
IF_LINT (= 0), oh
IF_LINT (= 0);
208 x_catch_errors (dpy
);
210 if (x_pixels_diff
) *x_pixels_diff
= 0;
211 if (y_pixels_diff
) *y_pixels_diff
= 0;
212 if (left_offset_x
) *left_offset_x
= 0;
213 if (top_offset_y
) *top_offset_y
= 0;
214 if (right_offset_x
) *right_offset_x
= 0;
215 if (bottom_offset_y
) *bottom_offset_y
= 0;
218 if (outer_border
) *outer_border
= 0;
220 if (win
== dpyinfo
->root_window
)
221 win
= FRAME_OUTER_WINDOW (f
);
223 /* This loop traverses up the containment tree until we hit the root
224 window. Window managers may intersect many windows between our window
225 and the root window. The window we find just before the root window
226 should be the outer WM window. */
229 Window wm_window
, rootw
;
230 Window
*tmp_children
;
231 unsigned int tmp_nchildren
;
234 success
= XQueryTree (FRAME_X_DISPLAY (f
), win
, &rootw
,
235 &wm_window
, &tmp_children
, &tmp_nchildren
);
237 had_errors
= x_had_errors_p (FRAME_X_DISPLAY (f
));
239 /* Don't free tmp_children if XQueryTree failed. */
243 XFree (tmp_children
);
245 if (wm_window
== rootw
|| had_errors
)
253 unsigned int bw
, ign
;
256 /* Get the real coordinates for the WM window upper left corner */
257 XGetGeometry (FRAME_X_DISPLAY (f
), win
,
258 &rootw
, &real_x
, &real_y
, &ow
, &oh
, &bw
, &ign
);
263 /* Translate real coordinates to coordinates relative to our
264 window. For our window, the upper left corner is 0, 0.
265 Since the upper left corner of the WM window is outside
266 our window, win_x and win_y will be negative:
268 ------------------ ---> x
270 | ----------------- v y
273 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
275 /* From-window, to-window. */
276 FRAME_DISPLAY_INFO (f
)->root_window
,
279 /* From-position, to-position. */
280 real_x
, real_y
, &win_x
, &win_y
,
285 if (FRAME_X_WINDOW (f
) == FRAME_OUTER_WINDOW (f
))
292 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
294 /* From-window, to-window. */
295 FRAME_DISPLAY_INFO (f
)->root_window
,
296 FRAME_OUTER_WINDOW (f
),
298 /* From-position, to-position. */
299 real_x
, real_y
, &outer_x
, &outer_y
,
305 had_errors
= x_had_errors_p (FRAME_X_DISPLAY (f
));
308 if (!had_errors
&& dpyinfo
->root_window
== f
->output_data
.x
->parent_desc
)
310 /* Try _NET_FRAME_EXTENTS if our parent is the root window. */
311 rc
= XGetWindowProperty (dpy
, win
, dpyinfo
->Xatom_net_frame_extents
,
312 0, max_len
, False
, target_type
,
313 &actual_type
, &actual_format
, &actual_size
,
314 &bytes_remaining
, &tmp_data
);
316 if (rc
== Success
&& actual_type
== target_type
&& !x_had_errors_p (dpy
)
317 && actual_size
== 4 && actual_format
== 32)
319 long *fe
= (long *)tmp_data
;
327 if (tmp_data
) XFree (tmp_data
);
334 if (had_errors
) return;
336 if (x_pixels_diff
) *x_pixels_diff
= -win_x
;
337 if (y_pixels_diff
) *y_pixels_diff
= -win_y
;
339 if (left_offset_x
) *left_offset_x
= -outer_x
;
340 if (top_offset_y
) *top_offset_y
= -outer_y
;
342 if (xptr
) *xptr
= real_x
;
343 if (yptr
) *yptr
= real_y
;
345 if (right_offset_x
|| bottom_offset_y
)
348 unsigned int ign
, fw
, fh
;
351 XGetGeometry (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
352 &rootw
, &xy_ign
, &xy_ign
, &fw
, &fh
, &ign
, &ign
);
353 if (right_offset_x
) *right_offset_x
= ow
- fw
+ outer_x
;
354 if (bottom_offset_y
) *bottom_offset_y
= oh
- fh
+ outer_y
;
358 /* Store the screen positions of frame F into XPTR and YPTR.
359 These are the positions of the containing window manager window,
360 not Emacs's own window. */
363 x_real_positions (struct frame
*f
, int *xptr
, int *yptr
)
365 x_real_pos_and_offsets (f
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, xptr
, yptr
,
370 /* Get the mouse position in frame relative coordinates. */
373 x_relative_mouse_position (struct frame
*f
, int *x
, int *y
)
375 Window root
, dummy_window
;
378 eassert (FRAME_X_P (f
));
382 XQueryPointer (FRAME_X_DISPLAY (f
),
383 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
385 /* The root window which contains the pointer. */
388 /* Window pointer is on, not used */
391 /* The position on that root window. */
394 /* x/y in dummy_window coordinates, not used. */
397 /* Modifier keys and pointer buttons, about which
399 (unsigned int *) &dummy
);
401 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
403 /* From-window, to-window. */
404 FRAME_DISPLAY_INFO (f
)->root_window
,
407 /* From-position, to-position. */
416 /* Gamma-correct COLOR on frame F. */
419 gamma_correct (struct frame
*f
, XColor
*color
)
423 color
->red
= pow (color
->red
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
424 color
->green
= pow (color
->green
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
425 color
->blue
= pow (color
->blue
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
430 /* Decide if color named COLOR_NAME is valid for use on frame F. If
431 so, return the RGB values in COLOR. If ALLOC_P,
432 allocate the color. Value is false if COLOR_NAME is invalid, or
433 no color could be allocated. */
436 x_defined_color (struct frame
*f
, const char *color_name
,
437 XColor
*color
, bool alloc_p
)
439 bool success_p
= false;
440 Colormap cmap
= FRAME_X_COLORMAP (f
);
444 success_p
= xg_check_special_colors (f
, color_name
, color
);
447 success_p
= x_parse_color (f
, color_name
, color
) != 0;
448 if (success_p
&& alloc_p
)
449 success_p
= x_alloc_nearest_color (f
, cmap
, color
);
456 /* Return the pixel color value for color COLOR_NAME on frame F. If F
457 is a monochrome frame, return MONO_COLOR regardless of what ARG says.
458 Signal an error if color can't be allocated. */
461 x_decode_color (struct frame
*f
, Lisp_Object color_name
, int mono_color
)
465 CHECK_STRING (color_name
);
467 #if false /* Don't do this. It's wrong when we're not using the default
468 colormap, it makes freeing difficult, and it's probably not
469 an important optimization. */
470 if (strcmp (SDATA (color_name
), "black") == 0)
471 return BLACK_PIX_DEFAULT (f
);
472 else if (strcmp (SDATA (color_name
), "white") == 0)
473 return WHITE_PIX_DEFAULT (f
);
476 /* Return MONO_COLOR for monochrome frames. */
477 if (FRAME_DISPLAY_INFO (f
)->n_planes
== 1)
480 /* x_defined_color is responsible for coping with failures
481 by looking for a near-miss. */
482 if (x_defined_color (f
, SSDATA (color_name
), &cdef
, true))
485 signal_error ("Undefined color", color_name
);
490 /* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
491 the previous value of that parameter, NEW_VALUE is the new value.
492 See also the comment of wait_for_wm in struct x_output. */
495 x_set_wait_for_wm (struct frame
*f
, Lisp_Object new_value
, Lisp_Object old_value
)
497 f
->output_data
.x
->wait_for_wm
= !NILP (new_value
);
501 x_set_tool_bar_position (struct frame
*f
,
502 Lisp_Object new_value
,
503 Lisp_Object old_value
)
505 Lisp_Object choice
= list4 (Qleft
, Qright
, Qtop
, Qbottom
);
507 if (!NILP (Fmemq (new_value
, choice
)))
510 if (!EQ (new_value
, old_value
))
512 xg_change_toolbar_position (f
, new_value
);
513 fset_tool_bar_position (f
, new_value
);
516 if (!EQ (new_value
, Qtop
))
517 error ("The only supported tool bar position is top");
521 wrong_choice (choice
, new_value
);
526 /* Set icon from FILE for frame F. By using GTK functions the icon
527 may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
530 xg_set_icon (struct frame
*f
, Lisp_Object file
)
535 found
= x_find_image_file (file
);
541 char *filename
= SSDATA (ENCODE_FILE (found
));
544 pixbuf
= gdk_pixbuf_new_from_file (filename
, &err
);
548 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
550 g_object_unref (pixbuf
);
564 xg_set_icon_from_xpm_data (struct frame
*f
, const char **data
)
566 GdkPixbuf
*pixbuf
= gdk_pixbuf_new_from_xpm_data (data
);
571 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)), pixbuf
);
572 g_object_unref (pixbuf
);
578 /* Functions called only from `x_set_frame_param'
579 to set individual parameters.
581 If FRAME_X_WINDOW (f) is 0,
582 the frame is being created and its X-window does not exist yet.
583 In that case, just record the parameter's new value
584 in the standard place; do not attempt to change the window. */
587 x_set_foreground_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
589 struct x_output
*x
= f
->output_data
.x
;
590 unsigned long fg
, old_fg
;
592 fg
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
593 old_fg
= FRAME_FOREGROUND_PIXEL (f
);
594 FRAME_FOREGROUND_PIXEL (f
) = fg
;
596 if (FRAME_X_WINDOW (f
) != 0)
598 Display
*dpy
= FRAME_X_DISPLAY (f
);
601 XSetForeground (dpy
, x
->normal_gc
, fg
);
602 XSetBackground (dpy
, x
->reverse_gc
, fg
);
604 if (x
->cursor_pixel
== old_fg
)
606 unload_color (f
, x
->cursor_pixel
);
607 x
->cursor_pixel
= x_copy_color (f
, fg
);
608 XSetBackground (dpy
, x
->cursor_gc
, x
->cursor_pixel
);
613 update_face_from_frame_parameter (f
, Qforeground_color
, arg
);
615 if (FRAME_VISIBLE_P (f
))
619 unload_color (f
, old_fg
);
623 x_set_background_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
625 struct x_output
*x
= f
->output_data
.x
;
628 bg
= x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
629 unload_color (f
, FRAME_BACKGROUND_PIXEL (f
));
630 FRAME_BACKGROUND_PIXEL (f
) = bg
;
632 if (FRAME_X_WINDOW (f
) != 0)
634 Display
*dpy
= FRAME_X_DISPLAY (f
);
637 XSetBackground (dpy
, x
->normal_gc
, bg
);
638 XSetForeground (dpy
, x
->reverse_gc
, bg
);
639 XSetWindowBackground (dpy
, FRAME_X_WINDOW (f
), bg
);
640 XSetForeground (dpy
, x
->cursor_gc
, bg
);
643 xg_set_background_color (f
, bg
);
646 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
647 toolkit scroll bars. */
650 for (bar
= FRAME_SCROLL_BARS (f
);
652 bar
= XSCROLL_BAR (bar
)->next
)
654 Window window
= XSCROLL_BAR (bar
)->x_window
;
655 XSetWindowBackground (dpy
, window
, bg
);
658 #endif /* USE_TOOLKIT_SCROLL_BARS */
661 update_face_from_frame_parameter (f
, Qbackground_color
, arg
);
663 if (FRAME_VISIBLE_P (f
))
668 /* This array must stay in sync with the mouse_cursor_types array below! */
671 mouse_cursor_nontext
,
672 mouse_cursor_hourglass
,
675 mouse_cursor_horizontal_drag
,
676 mouse_cursor_vertical_drag
,
680 struct mouse_cursor_types
{
681 /* Printable name for error messages (optional). */
684 /* Lisp variable controlling the cursor shape. */
685 /* FIXME: A couple of these variables are defined in the C code but
686 are not actually accessible from Lisp. They should probably be
687 made accessible or removed. */
688 Lisp_Object
*shape_var_ptr
;
690 /* The default shape. */
694 /* This array must stay in sync with enum mouse_cursor above! */
695 static const struct mouse_cursor_types mouse_cursor_types
[] = {
696 { "text", &Vx_pointer_shape
, XC_xterm
},
697 { "nontext", &Vx_nontext_pointer_shape
, XC_left_ptr
},
698 { "hourglass", &Vx_hourglass_pointer_shape
, XC_watch
},
699 { "modeline", &Vx_mode_pointer_shape
, XC_xterm
},
700 { NULL
, &Vx_sensitive_text_pointer_shape
, XC_hand2
},
701 { NULL
, &Vx_window_horizontal_drag_shape
, XC_sb_h_double_arrow
},
702 { NULL
, &Vx_window_vertical_drag_shape
, XC_sb_v_double_arrow
},
705 struct mouse_cursor_data
{
706 /* Last index for which XCreateFontCursor has been called, and thus
707 the last index for which x_request_serial[] is valid. */
708 int last_cursor_create_request
;
710 /* Last index for which an X error event was received in response to
711 attempting to create the cursor. */
714 /* Cursor numbers chosen. */
715 unsigned int cursor_num
[mouse_cursor_max
];
717 /* Allocated Cursor values, or zero for failed attempts. */
718 Cursor cursor
[mouse_cursor_max
];
720 /* X serial numbers for the first request sent by XCreateFontCursor.
721 Note that there may be more than one request sent. */
722 unsigned long x_request_serial
[mouse_cursor_max
];
724 /* If an error has been received, a pointer to where the current
725 error-message text is stored. */
730 x_set_mouse_color_handler (Display
*dpy
, XErrorEvent
*event
,
731 char *error_string
, void *data
)
733 struct mouse_cursor_data
*cursor_data
= data
;
736 cursor_data
->error_cursor
= -1;
737 cursor_data
->error_string
= error_string
;
738 for (i
= 0; i
< cursor_data
->last_cursor_create_request
; i
++)
740 if (event
->serial
>= cursor_data
->x_request_serial
[i
])
741 cursor_data
->error_cursor
= i
;
743 if (cursor_data
->error_cursor
>= 0)
744 /* If we failed to allocate it, don't try to free it. */
745 cursor_data
->cursor
[cursor_data
->error_cursor
] = 0;
749 x_set_mouse_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
751 struct x_output
*x
= f
->output_data
.x
;
752 Display
*dpy
= FRAME_X_DISPLAY (f
);
753 struct mouse_cursor_data cursor_data
= { -1, -1 };
754 unsigned long pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
755 unsigned long mask_color
= FRAME_BACKGROUND_PIXEL (f
);
758 /* Don't let pointers be invisible. */
759 if (mask_color
== pixel
)
761 x_free_colors (f
, &pixel
, 1);
762 pixel
= x_copy_color (f
, FRAME_FOREGROUND_PIXEL (f
));
765 unload_color (f
, x
->mouse_pixel
);
766 x
->mouse_pixel
= pixel
;
768 for (i
= 0; i
< mouse_cursor_max
; i
++)
770 Lisp_Object shape_var
= *mouse_cursor_types
[i
].shape_var_ptr
;
771 if (!NILP (shape_var
))
773 CHECK_TYPE_RANGED_INTEGER (unsigned, shape_var
);
774 cursor_data
.cursor_num
[i
] = XINT (shape_var
);
777 cursor_data
.cursor_num
[i
] = mouse_cursor_types
[i
].default_shape
;
782 /* It's not okay to crash if the user selects a screwy cursor. */
783 x_catch_errors_with_handler (dpy
, x_set_mouse_color_handler
, &cursor_data
);
785 for (i
= 0; i
< mouse_cursor_max
; i
++)
787 cursor_data
.x_request_serial
[i
] = XNextRequest (dpy
);
788 cursor_data
.last_cursor_create_request
= i
;
789 cursor_data
.cursor
[i
] = XCreateFontCursor (dpy
,
790 cursor_data
.cursor_num
[i
]);
793 /* Now sync up and process all received errors from cursor
795 if (x_had_errors_p (dpy
))
797 const char *bad_cursor_name
= NULL
;
798 /* Bounded by X_ERROR_MESSAGE_SIZE in xterm.c. */
799 size_t message_length
= strlen (cursor_data
.error_string
);
800 char *xmessage
= alloca (1 + message_length
);
801 memcpy (xmessage
, cursor_data
.error_string
, message_length
);
805 /* Free any successfully created cursors. */
806 for (i
= 0; i
< mouse_cursor_max
; i
++)
807 if (cursor_data
.cursor
[i
] != 0)
808 XFreeCursor (dpy
, cursor_data
.cursor
[i
]);
810 /* This should only be able to fail if the server's serial
811 number tracking is broken. */
812 if (cursor_data
.error_cursor
>= 0)
813 bad_cursor_name
= mouse_cursor_types
[cursor_data
.error_cursor
].name
;
815 error ("bad %s pointer cursor: %s", bad_cursor_name
, xmessage
);
817 error ("can't set cursor shape: %s", xmessage
);
820 x_uncatch_errors_after_check ();
823 XColor colors
[2]; /* 0=foreground, 1=background */
825 colors
[0].pixel
= x
->mouse_pixel
;
826 colors
[1].pixel
= mask_color
;
827 x_query_colors (f
, colors
, 2);
829 for (i
= 0; i
< mouse_cursor_max
; i
++)
830 XRecolorCursor (dpy
, cursor_data
.cursor
[i
], &colors
[0], &colors
[1]);
833 if (FRAME_X_WINDOW (f
) != 0)
835 f
->output_data
.x
->current_cursor
= cursor_data
.cursor
[mouse_cursor_text
];
836 XDefineCursor (dpy
, FRAME_X_WINDOW (f
),
837 f
->output_data
.x
->current_cursor
);
840 #define INSTALL_CURSOR(FIELD, SHORT_INDEX) \
841 eassert (x->FIELD != cursor_data.cursor[mouse_cursor_ ## SHORT_INDEX]); \
843 XFreeCursor (dpy, x->FIELD); \
844 x->FIELD = cursor_data.cursor[mouse_cursor_ ## SHORT_INDEX];
846 INSTALL_CURSOR (text_cursor
, text
);
847 INSTALL_CURSOR (nontext_cursor
, nontext
);
848 INSTALL_CURSOR (hourglass_cursor
, hourglass
);
849 INSTALL_CURSOR (modeline_cursor
, mode
);
850 INSTALL_CURSOR (hand_cursor
, hand
);
851 INSTALL_CURSOR (horizontal_drag_cursor
, horizontal_drag
);
852 INSTALL_CURSOR (vertical_drag_cursor
, vertical_drag
);
854 #undef INSTALL_CURSOR
859 update_face_from_frame_parameter (f
, Qmouse_color
, arg
);
863 x_set_cursor_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
865 unsigned long fore_pixel
, pixel
;
866 bool fore_pixel_allocated_p
= false, pixel_allocated_p
= false;
867 struct x_output
*x
= f
->output_data
.x
;
869 if (!NILP (Vx_cursor_fore_pixel
))
871 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
872 WHITE_PIX_DEFAULT (f
));
873 fore_pixel_allocated_p
= true;
876 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
878 pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
879 pixel_allocated_p
= true;
881 /* Make sure that the cursor color differs from the background color. */
882 if (pixel
== FRAME_BACKGROUND_PIXEL (f
))
884 if (pixel_allocated_p
)
886 x_free_colors (f
, &pixel
, 1);
887 pixel_allocated_p
= false;
890 pixel
= x
->mouse_pixel
;
891 if (pixel
== fore_pixel
)
893 if (fore_pixel_allocated_p
)
895 x_free_colors (f
, &fore_pixel
, 1);
896 fore_pixel_allocated_p
= false;
898 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
902 unload_color (f
, x
->cursor_foreground_pixel
);
903 if (!fore_pixel_allocated_p
)
904 fore_pixel
= x_copy_color (f
, fore_pixel
);
905 x
->cursor_foreground_pixel
= fore_pixel
;
907 unload_color (f
, x
->cursor_pixel
);
908 if (!pixel_allocated_p
)
909 pixel
= x_copy_color (f
, pixel
);
910 x
->cursor_pixel
= pixel
;
912 if (FRAME_X_WINDOW (f
) != 0)
915 XSetBackground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, x
->cursor_pixel
);
916 XSetForeground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, fore_pixel
);
919 if (FRAME_VISIBLE_P (f
))
921 x_update_cursor (f
, false);
922 x_update_cursor (f
, true);
926 update_face_from_frame_parameter (f
, Qcursor_color
, arg
);
929 /* Set the border-color of frame F to pixel value PIX.
930 Note that this does not fully take effect if done before
931 F has an x-window. */
934 x_set_border_pixel (struct frame
*f
, int pix
)
936 unload_color (f
, f
->output_data
.x
->border_pixel
);
937 f
->output_data
.x
->border_pixel
= pix
;
939 if (FRAME_X_WINDOW (f
) != 0 && f
->border_width
> 0)
942 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), pix
);
945 if (FRAME_VISIBLE_P (f
))
950 /* Set the border-color of frame F to value described by ARG.
951 ARG can be a string naming a color.
952 The border-color is used for the border that is drawn by the X server.
953 Note that this does not fully take effect if done before
954 F has an x-window; it must be redone when the window is created.
956 Note: this is done in two routines because of the way X10 works.
958 Note: under X11, this is normally the province of the window manager,
959 and so emacs's border colors may be overridden. */
962 x_set_border_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
967 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
968 x_set_border_pixel (f
, pix
);
969 update_face_from_frame_parameter (f
, Qborder_color
, arg
);
974 x_set_cursor_type (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
976 set_frame_cursor_types (f
, arg
);
980 x_set_icon_type (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
986 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
989 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
994 result
= x_text_icon (f
,
995 SSDATA ((!NILP (f
->icon_name
)
999 result
= x_bitmap_icon (f
, arg
);
1004 error ("No icon window available");
1007 XFlush (FRAME_X_DISPLAY (f
));
1012 x_set_icon_name (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1018 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1021 else if (!NILP (arg
) || NILP (oldval
))
1024 fset_icon_name (f
, arg
);
1026 if (f
->output_data
.x
->icon_bitmap
!= 0)
1031 result
= x_text_icon (f
,
1032 SSDATA ((!NILP (f
->icon_name
)
1041 error ("No icon window available");
1044 XFlush (FRAME_X_DISPLAY (f
));
1050 x_set_menu_bar_lines (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
1053 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
1054 int olines
= FRAME_MENU_BAR_LINES (f
);
1057 /* Right now, menu bars don't work properly in minibuf-only frames;
1058 most of the commands try to apply themselves to the minibuffer
1059 frame itself, and get an error because you can't switch buffers
1060 in or split the minibuffer window. */
1061 if (FRAME_MINIBUF_ONLY_P (f
))
1064 if (TYPE_RANGED_INTEGERP (int, value
))
1065 nlines
= XINT (value
);
1069 /* Make sure we redisplay all windows in this frame. */
1072 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1073 FRAME_MENU_BAR_LINES (f
) = 0;
1074 FRAME_MENU_BAR_HEIGHT (f
) = 0;
1077 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
1078 if (FRAME_X_P (f
) && f
->output_data
.x
->menubar_widget
== 0)
1079 /* Make sure next redisplay shows the menu bar. */
1080 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= true;
1084 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
1085 free_frame_menubar (f
);
1086 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
1088 f
->output_data
.x
->menubar_widget
= 0;
1090 #else /* not USE_X_TOOLKIT && not USE_GTK */
1091 FRAME_MENU_BAR_LINES (f
) = nlines
;
1092 FRAME_MENU_BAR_HEIGHT (f
) = nlines
* FRAME_LINE_HEIGHT (f
);
1093 adjust_frame_size (f
, -1, -1, 2, true, Qmenu_bar_lines
);
1094 if (FRAME_X_WINDOW (f
))
1095 x_clear_under_internal_border (f
);
1097 /* If the menu bar height gets changed, the internal border below
1098 the top margin has to be cleared. Also, if the menu bar gets
1099 larger, the area for the added lines has to be cleared except for
1100 the first menu bar line that is to be drawn later. */
1101 if (nlines
!= olines
)
1103 int height
= FRAME_INTERNAL_BORDER_WIDTH (f
);
1104 int width
= FRAME_PIXEL_WIDTH (f
);
1107 /* height can be zero here. */
1108 if (FRAME_X_WINDOW (f
) && height
> 0 && width
> 0)
1110 y
= FRAME_TOP_MARGIN_HEIGHT (f
);
1113 x_clear_area (f
, 0, y
, width
, height
);
1117 if (nlines
> 1 && nlines
> olines
)
1119 y
= (olines
== 0 ? 1 : olines
) * FRAME_LINE_HEIGHT (f
);
1120 height
= nlines
* FRAME_LINE_HEIGHT (f
) - y
;
1123 x_clear_area (f
, 0, y
, width
, height
);
1127 if (nlines
== 0 && WINDOWP (f
->menu_bar_window
))
1128 clear_glyph_matrix (XWINDOW (f
->menu_bar_window
)->current_matrix
);
1130 #endif /* not USE_X_TOOLKIT && not USE_GTK */
1131 adjust_frame_glyphs (f
);
1132 run_window_configuration_change_hook (f
);
1136 /* Set the number of lines used for the tool bar of frame F to VALUE.
1137 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1138 is the old number of tool bar lines. This function changes the
1139 height of all windows on frame F to match the new tool bar height.
1140 The frame's height doesn't change. */
1143 x_set_tool_bar_lines (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
1147 /* Treat tool bars like menu bars. */
1148 if (FRAME_MINIBUF_ONLY_P (f
))
1151 /* Use VALUE only if an int >= 0. */
1152 if (RANGED_INTEGERP (0, value
, INT_MAX
))
1153 nlines
= XFASTINT (value
);
1157 x_change_tool_bar_height (f
, nlines
* FRAME_LINE_HEIGHT (f
));
1161 /* Set the pixel height of the tool bar of frame F to HEIGHT. */
1163 x_change_tool_bar_height (struct frame
*f
, int height
)
1166 FRAME_TOOL_BAR_LINES (f
) = 0;
1167 FRAME_TOOL_BAR_HEIGHT (f
) = 0;
1170 FRAME_EXTERNAL_TOOL_BAR (f
) = true;
1171 if (FRAME_X_P (f
) && f
->output_data
.x
->toolbar_widget
== 0)
1172 /* Make sure next redisplay shows the tool bar. */
1173 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= true;
1174 update_frame_tool_bar (f
);
1178 if (FRAME_EXTERNAL_TOOL_BAR (f
))
1179 free_frame_tool_bar (f
);
1180 FRAME_EXTERNAL_TOOL_BAR (f
) = false;
1182 #else /* !USE_GTK */
1183 int unit
= FRAME_LINE_HEIGHT (f
);
1184 int old_height
= FRAME_TOOL_BAR_HEIGHT (f
);
1185 int lines
= (height
+ unit
- 1) / unit
;
1186 Lisp_Object fullscreen
;
1188 /* Make sure we redisplay all windows in this frame. */
1191 /* Recalculate tool bar and frame text sizes. */
1192 FRAME_TOOL_BAR_HEIGHT (f
) = height
;
1193 FRAME_TOOL_BAR_LINES (f
) = lines
;
1194 /* Store the `tool-bar-lines' and `height' frame parameters. */
1195 store_frame_param (f
, Qtool_bar_lines
, make_number (lines
));
1196 store_frame_param (f
, Qheight
, make_number (FRAME_LINES (f
)));
1198 /* We also have to make sure that the internal border at the top of
1199 the frame, below the menu bar or tool bar, is redrawn when the
1200 tool bar disappears. This is so because the internal border is
1201 below the tool bar if one is displayed, but is below the menu bar
1202 if there isn't a tool bar. The tool bar draws into the area
1203 below the menu bar. */
1204 if (FRAME_X_WINDOW (f
) && FRAME_TOOL_BAR_HEIGHT (f
) == 0)
1207 clear_current_matrices (f
);
1210 if ((height
< old_height
) && WINDOWP (f
->tool_bar_window
))
1211 clear_glyph_matrix (XWINDOW (f
->tool_bar_window
)->current_matrix
);
1213 /* Recalculate toolbar height. */
1214 f
->n_tool_bar_rows
= 0;
1216 adjust_frame_size (f
, -1, -1,
1217 ((NILP (fullscreen
= get_frame_param (f
, Qfullscreen
))
1218 || EQ (fullscreen
, Qfullwidth
)) ? 1
1219 : (old_height
== 0 || height
== 0) ? 2
1221 false, Qtool_bar_lines
);
1223 /* adjust_frame_size might not have done anything, garbage frame
1225 adjust_frame_glyphs (f
);
1226 SET_FRAME_GARBAGED (f
);
1227 if (FRAME_X_WINDOW (f
))
1228 x_clear_under_internal_border (f
);
1230 #endif /* USE_GTK */
1235 x_set_internal_border_width (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1239 CHECK_TYPE_RANGED_INTEGER (int, arg
);
1240 border
= max (XINT (arg
), 0);
1242 if (border
!= FRAME_INTERNAL_BORDER_WIDTH (f
))
1244 FRAME_INTERNAL_BORDER_WIDTH (f
) = border
;
1246 #ifdef USE_X_TOOLKIT
1247 if (FRAME_X_OUTPUT (f
)->edit_widget
)
1248 widget_store_internal_border (FRAME_X_OUTPUT (f
)->edit_widget
);
1251 if (FRAME_X_WINDOW (f
) != 0)
1253 adjust_frame_size (f
, -1, -1, 3, false, Qinternal_border_width
);
1256 xg_clear_under_internal_border (f
);
1258 x_clear_under_internal_border (f
);
1266 /* Set the foreground color for scroll bars on frame F to VALUE.
1267 VALUE should be a string, a color name. If it isn't a string or
1268 isn't a valid color name, do nothing. OLDVAL is the old value of
1269 the frame parameter. */
1272 x_set_scroll_bar_foreground (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
1274 unsigned long pixel
;
1276 if (STRINGP (value
))
1277 pixel
= x_decode_color (f
, value
, BLACK_PIX_DEFAULT (f
));
1281 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
1282 unload_color (f
, f
->output_data
.x
->scroll_bar_foreground_pixel
);
1284 f
->output_data
.x
->scroll_bar_foreground_pixel
= pixel
;
1285 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1287 /* Remove all scroll bars because they have wrong colors. */
1288 if (FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
)
1289 (*FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
) (f
);
1290 if (FRAME_TERMINAL (f
)->judge_scroll_bars_hook
)
1291 (*FRAME_TERMINAL (f
)->judge_scroll_bars_hook
) (f
);
1293 update_face_from_frame_parameter (f
, Qscroll_bar_foreground
, value
);
1299 /* Set the background color for scroll bars on frame F to VALUE VALUE
1300 should be a string, a color name. If it isn't a string or isn't a
1301 valid color name, do nothing. OLDVAL is the old value of the frame
1305 x_set_scroll_bar_background (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
1307 unsigned long pixel
;
1309 if (STRINGP (value
))
1310 pixel
= x_decode_color (f
, value
, WHITE_PIX_DEFAULT (f
));
1314 if (f
->output_data
.x
->scroll_bar_background_pixel
!= -1)
1315 unload_color (f
, f
->output_data
.x
->scroll_bar_background_pixel
);
1317 #if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
1318 /* Scrollbar shadow colors. */
1319 if (f
->output_data
.x
->scroll_bar_top_shadow_pixel
!= -1)
1321 unload_color (f
, f
->output_data
.x
->scroll_bar_top_shadow_pixel
);
1322 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
1324 if (f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
!= -1)
1326 unload_color (f
, f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
);
1327 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
1329 #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
1331 f
->output_data
.x
->scroll_bar_background_pixel
= pixel
;
1332 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1334 /* Remove all scroll bars because they have wrong colors. */
1335 if (FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
)
1336 (*FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
) (f
);
1337 if (FRAME_TERMINAL (f
)->judge_scroll_bars_hook
)
1338 (*FRAME_TERMINAL (f
)->judge_scroll_bars_hook
) (f
);
1340 update_face_from_frame_parameter (f
, Qscroll_bar_background
, value
);
1346 /* Encode Lisp string STRING as a text in a format appropriate for
1347 XICCC (X Inter Client Communication Conventions).
1349 If STRING contains only ASCII characters, do no conversion and
1350 return the string data of STRING. Otherwise, encode the text by
1351 CODING_SYSTEM, and return a newly allocated memory area which
1352 should be freed by `xfree' by a caller.
1354 Store the byte length of resulting text in *TEXT_BYTES.
1356 If the text contains only ASCII and Latin-1, store true in *STRING_P,
1357 which means that the `encoding' of the result can be `STRING'.
1358 Otherwise store false in *STRINGP, which means that the `encoding' of
1359 the result should be `COMPOUND_TEXT'. */
1361 static unsigned char *
1362 x_encode_text (Lisp_Object string
, Lisp_Object coding_system
,
1363 ptrdiff_t *text_bytes
, bool *stringp
, bool *freep
)
1365 int result
= string_xstring_p (string
);
1366 struct coding_system coding
;
1370 /* No multibyte character in OBJ. We need not encode it. */
1371 *text_bytes
= SBYTES (string
);
1374 return SDATA (string
);
1377 setup_coding_system (coding_system
, &coding
);
1378 coding
.mode
|= (CODING_MODE_SAFE_ENCODING
| CODING_MODE_LAST_BLOCK
);
1379 /* We suppress producing escape sequences for composition. */
1380 coding
.common_flags
&= ~CODING_ANNOTATION_MASK
;
1381 coding
.destination
= xnmalloc (SCHARS (string
), 2);
1382 coding
.dst_bytes
= SCHARS (string
) * 2;
1383 encode_coding_object (&coding
, string
, 0, 0,
1384 SCHARS (string
), SBYTES (string
), Qnil
);
1385 *text_bytes
= coding
.produced
;
1386 *stringp
= (result
== 1 || !EQ (coding_system
, Qcompound_text
));
1388 return coding
.destination
;
1392 /* Set the WM name to NAME for frame F. Also set the icon name.
1393 If the frame already has an icon name, use that, otherwise set the
1394 icon name to NAME. */
1397 x_set_name_internal (struct frame
*f
, Lisp_Object name
)
1399 if (FRAME_X_WINDOW (f
))
1403 XTextProperty text
, icon
;
1406 bool do_free_icon_value
= false, do_free_text_value
= false;
1407 Lisp_Object coding_system
;
1408 Lisp_Object encoded_name
;
1409 Lisp_Object encoded_icon_name
;
1411 /* As ENCODE_UTF_8 may cause GC and relocation of string data,
1412 we use it before x_encode_text that may return string data. */
1413 encoded_name
= ENCODE_UTF_8 (name
);
1415 coding_system
= Qcompound_text
;
1416 /* Note: Encoding strategy
1418 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1419 text.encoding. But, there are non-internationalized window
1420 managers which don't support that encoding. So, if NAME
1421 contains only ASCII and 8859-1 characters, encode it by
1422 iso-latin-1, and use "STRING" in text.encoding hoping that
1423 such window managers at least analyze this format correctly,
1424 i.e. treat 8-bit bytes as 8859-1 characters.
1426 We may also be able to use "UTF8_STRING" in text.encoding
1427 in the future which can encode all Unicode characters.
1428 But, for the moment, there's no way to know that the
1429 current window manager supports it or not.
1431 Either way, we also set the _NET_WM_NAME and _NET_WM_ICON_NAME
1432 properties. Per the EWMH specification, those two properties
1433 are always UTF8_STRING. This matches what gtk_window_set_title()
1434 does in the USE_GTK case. */
1435 text
.value
= x_encode_text (name
, coding_system
, &bytes
,
1436 &stringp
, &do_free_text_value
);
1437 text
.encoding
= (stringp
? XA_STRING
1438 : FRAME_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1440 text
.nitems
= bytes
;
1442 if (!STRINGP (f
->icon_name
))
1445 encoded_icon_name
= encoded_name
;
1449 /* See the above comment "Note: Encoding strategy". */
1450 icon
.value
= x_encode_text (f
->icon_name
, coding_system
, &bytes
,
1451 &stringp
, &do_free_icon_value
);
1452 icon
.encoding
= (stringp
? XA_STRING
1453 : FRAME_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1455 icon
.nitems
= bytes
;
1457 encoded_icon_name
= ENCODE_UTF_8 (f
->icon_name
);
1461 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
1462 SSDATA (encoded_name
));
1463 #else /* not USE_GTK */
1464 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &text
);
1465 XChangeProperty (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
1466 FRAME_DISPLAY_INFO (f
)->Xatom_net_wm_name
,
1467 FRAME_DISPLAY_INFO (f
)->Xatom_UTF8_STRING
,
1469 SDATA (encoded_name
),
1470 SBYTES (encoded_name
));
1471 #endif /* not USE_GTK */
1473 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &icon
);
1474 XChangeProperty (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
1475 FRAME_DISPLAY_INFO (f
)->Xatom_net_wm_icon_name
,
1476 FRAME_DISPLAY_INFO (f
)->Xatom_UTF8_STRING
,
1478 SDATA (encoded_icon_name
),
1479 SBYTES (encoded_icon_name
));
1481 if (do_free_icon_value
)
1483 if (do_free_text_value
)
1490 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1493 If EXPLICIT is true, that indicates that lisp code is setting the
1494 name; if NAME is a string, set F's name to NAME and set
1495 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1497 If EXPLICIT is false, that indicates that Emacs redisplay code is
1498 suggesting a new name, which lisp code should override; if
1499 F->explicit_name is set, ignore the new name; otherwise, set it. */
1502 x_set_name (struct frame
*f
, Lisp_Object name
, bool explicit)
1504 /* Make sure that requests from lisp code override requests from
1505 Emacs redisplay code. */
1508 /* If we're switching from explicit to implicit, we had better
1509 update the mode lines and thereby update the title. */
1510 if (f
->explicit_name
&& NILP (name
))
1511 update_mode_lines
= 37;
1513 f
->explicit_name
= ! NILP (name
);
1515 else if (f
->explicit_name
)
1518 /* If NAME is nil, set the name to the x_id_name. */
1521 /* Check for no change needed in this very common case
1522 before we do any consing. */
1523 if (!strcmp (FRAME_DISPLAY_INFO (f
)->x_id_name
,
1526 name
= build_string (FRAME_DISPLAY_INFO (f
)->x_id_name
);
1529 CHECK_STRING (name
);
1531 /* Don't change the name if it's already NAME. */
1532 if (! NILP (Fstring_equal (name
, f
->name
)))
1535 fset_name (f
, name
);
1537 /* For setting the frame title, the title parameter should override
1538 the name parameter. */
1539 if (! NILP (f
->title
))
1542 x_set_name_internal (f
, name
);
1545 /* This function should be called when the user's lisp code has
1546 specified a name for the frame; the name will override any set by the
1549 x_explicitly_set_name (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1551 x_set_name (f
, arg
, true);
1554 /* This function should be called by Emacs redisplay code to set the
1555 name; names set this way will never override names set by the user's
1558 x_implicitly_set_name (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1560 x_set_name (f
, arg
, false);
1563 /* Change the title of frame F to NAME.
1564 If NAME is nil, use the frame name as the title. */
1567 x_set_title (struct frame
*f
, Lisp_Object name
, Lisp_Object old_name
)
1569 /* Don't change the title if it's already NAME. */
1570 if (EQ (name
, f
->title
))
1573 update_mode_lines
= 38;
1575 fset_title (f
, name
);
1580 CHECK_STRING (name
);
1582 x_set_name_internal (f
, name
);
1586 x_set_scroll_bar_default_width (struct frame
*f
)
1588 int unit
= FRAME_COLUMN_WIDTH (f
);
1589 #ifdef USE_TOOLKIT_SCROLL_BARS
1591 int minw
= xg_get_default_scrollbar_width ();
1595 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
1596 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (minw
+ unit
- 1) / unit
;
1597 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = minw
;
1599 /* The width of a non-toolkit scrollbar is 14 pixels. */
1600 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + unit
- 1) / unit
;
1601 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
)
1602 = FRAME_CONFIG_SCROLL_BAR_COLS (f
) * unit
;
1607 x_set_scroll_bar_default_height (struct frame
*f
)
1609 int height
= FRAME_LINE_HEIGHT (f
);
1610 #ifdef USE_TOOLKIT_SCROLL_BARS
1612 int min_height
= xg_get_default_scrollbar_height ();
1614 int min_height
= 16;
1616 /* A minimum height of 14 doesn't look good for toolkit scroll bars. */
1617 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f
) = min_height
;
1618 FRAME_CONFIG_SCROLL_BAR_LINES (f
) = (min_height
+ height
- 1) / height
;
1620 /* The height of a non-toolkit scrollbar is 14 pixels. */
1621 FRAME_CONFIG_SCROLL_BAR_LINES (f
) = (14 + height
- 1) / height
;
1623 /* Use all of that space (aside from required margins) for the
1625 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f
) = 14;
1630 /* Record in frame F the specified or default value according to ALIST
1631 of the parameter named PROP (a Lisp symbol). If no value is
1632 specified for PROP, look for an X default for XPROP on the frame
1633 named NAME. If that is not found either, use the value DEFLT. */
1636 x_default_scroll_bar_color_parameter (struct frame
*f
,
1637 Lisp_Object alist
, Lisp_Object prop
,
1638 const char *xprop
, const char *xclass
,
1641 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
1644 tem
= x_get_arg (dpyinfo
, alist
, prop
, xprop
, xclass
, RES_TYPE_STRING
);
1645 if (EQ (tem
, Qunbound
))
1647 #ifdef USE_TOOLKIT_SCROLL_BARS
1649 /* See if an X resource for the scroll bar color has been
1651 AUTO_STRING (foreground
, "foreground");
1652 AUTO_STRING (background
, "foreground");
1653 AUTO_STRING (verticalScrollBar
, "verticalScrollBar");
1654 tem
= (display_x_get_resource
1655 (dpyinfo
, foreground_p
? foreground
: background
,
1656 empty_unibyte_string
,
1658 empty_unibyte_string
));
1661 /* If nothing has been specified, scroll bars will use a
1662 toolkit-dependent default. Because these defaults are
1663 difficult to get at without actually creating a scroll
1664 bar, use nil to indicate that no color has been
1669 #else /* not USE_TOOLKIT_SCROLL_BARS */
1673 #endif /* not USE_TOOLKIT_SCROLL_BARS */
1676 AUTO_FRAME_ARG (arg
, prop
, tem
);
1677 x_set_frame_parameters (f
, arg
);
1684 #ifdef USE_X_TOOLKIT
1686 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
1687 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
1688 already be present because of the toolkit (Motif adds some of them,
1689 for example, but Xt doesn't). */
1692 hack_wm_protocols (struct frame
*f
, Widget widget
)
1694 Display
*dpy
= XtDisplay (widget
);
1695 Window w
= XtWindow (widget
);
1696 bool need_delete
= true;
1697 bool need_focus
= true;
1698 bool need_save
= true;
1703 unsigned char *catoms
;
1705 unsigned long nitems
= 0;
1706 unsigned long bytes_after
;
1708 if ((XGetWindowProperty (dpy
, w
,
1709 FRAME_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
1710 0, 100, False
, XA_ATOM
,
1711 &type
, &format
, &nitems
, &bytes_after
,
1714 && format
== 32 && type
== XA_ATOM
)
1716 Atom
*atoms
= (Atom
*) catoms
;
1721 == FRAME_DISPLAY_INFO (f
)->Xatom_wm_delete_window
)
1722 need_delete
= false;
1723 else if (atoms
[nitems
]
1724 == FRAME_DISPLAY_INFO (f
)->Xatom_wm_take_focus
)
1726 else if (atoms
[nitems
]
1727 == FRAME_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
)
1738 props
[count
++] = FRAME_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
1740 props
[count
++] = FRAME_DISPLAY_INFO (f
)->Xatom_wm_take_focus
;
1742 props
[count
++] = FRAME_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
1744 XChangeProperty (dpy
, w
, FRAME_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
1745 XA_ATOM
, 32, PropModeAppend
,
1746 (unsigned char *) props
, count
);
1754 /* Support routines for XIC (X Input Context). */
1758 static XFontSet
xic_create_xfontset (struct frame
*);
1759 static XIMStyle
best_xim_style (XIMStyles
*);
1762 /* Supported XIM styles, ordered by preference. */
1764 static const XIMStyle supported_xim_styles
[] =
1766 XIMPreeditPosition
| XIMStatusArea
,
1767 XIMPreeditPosition
| XIMStatusNothing
,
1768 XIMPreeditPosition
| XIMStatusNone
,
1769 XIMPreeditNothing
| XIMStatusArea
,
1770 XIMPreeditNothing
| XIMStatusNothing
,
1771 XIMPreeditNothing
| XIMStatusNone
,
1772 XIMPreeditNone
| XIMStatusArea
,
1773 XIMPreeditNone
| XIMStatusNothing
,
1774 XIMPreeditNone
| XIMStatusNone
,
1779 #if defined HAVE_X_WINDOWS && defined USE_X_TOOLKIT
1780 /* Create an X fontset on frame F with base font name BASE_FONTNAME. */
1782 static const char xic_default_fontset
[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
1784 /* Create an Xt fontset spec from the name of a base font.
1785 If `motif' is True use the Motif syntax. */
1787 xic_create_fontsetname (const char *base_fontname
, bool motif
)
1789 const char *sep
= motif
? ";" : ",";
1793 /* Make a fontset name from the base font name. */
1794 if (xic_default_fontset
== base_fontname
)
1796 /* There is no base font name, use the default. */
1797 fontsetname
= xmalloc (strlen (base_fontname
) + 2);
1798 z
= stpcpy (fontsetname
, base_fontname
);
1802 /* Make a fontset name from the base font name.
1803 The font set will be made of the following elements:
1805 - the base font where the charset spec is replaced by -*-*.
1806 - the same but with the family also replaced with -*-*-. */
1807 const char *p
= base_fontname
;
1810 for (i
= 0; *p
; p
++)
1814 /* As the font name doesn't conform to XLFD, we can't
1815 modify it to generalize it to allcs and allfamilies.
1816 Use the specified font plus the default. */
1817 fontsetname
= xmalloc (strlen (base_fontname
)
1818 + strlen (xic_default_fontset
) + 3);
1819 z
= stpcpy (fontsetname
, base_fontname
);
1820 z
= stpcpy (z
, sep
);
1821 z
= stpcpy (z
, xic_default_fontset
);
1826 const char *p1
= NULL
, *p2
= NULL
, *p3
= NULL
;
1827 char *font_allcs
= NULL
;
1828 char *font_allfamilies
= NULL
;
1829 char *font_all
= NULL
;
1830 const char *allcs
= "*-*-*-*-*-*-*";
1831 const char *allfamilies
= "-*-*-";
1832 const char *all
= "*-*-*-*-";
1835 for (i
= 0, p
= base_fontname
; i
< 8; p
++)
1848 /* If base_fontname specifies ADSTYLE, make it a
1852 ptrdiff_t diff
= (p2
- p3
) - 2;
1854 base
= alloca (strlen (base_fontname
) + 1);
1855 memcpy (base
, base_fontname
, p3
- base_fontname
);
1856 base
[p3
- base_fontname
] = '*';
1857 base
[(p3
- base_fontname
) + 1] = '-';
1858 strcpy (base
+ (p3
- base_fontname
) + 2, p2
);
1859 p
= base
+ (p
- base_fontname
) - diff
;
1860 p1
= base
+ (p1
- base_fontname
);
1861 p2
= base
+ (p2
- base_fontname
) - diff
;
1862 base_fontname
= base
;
1865 /* Build the font spec that matches all charsets. */
1866 len
= p
- base_fontname
+ strlen (allcs
) + 1;
1867 font_allcs
= alloca (len
);
1868 memcpy (font_allcs
, base_fontname
, p
- base_fontname
);
1869 strcpy (font_allcs
+ (p
- base_fontname
), allcs
);
1871 /* Build the font spec that matches all families and
1873 len
= p
- p1
+ strlen (allcs
) + strlen (allfamilies
) + 1;
1874 font_allfamilies
= alloca (len
);
1875 strcpy (font_allfamilies
, allfamilies
);
1876 memcpy (font_allfamilies
+ strlen (allfamilies
), p1
, p
- p1
);
1877 strcpy (font_allfamilies
+ strlen (allfamilies
) + (p
- p1
), allcs
);
1879 /* Build the font spec that matches all. */
1880 len
= p
- p2
+ strlen (allcs
) + strlen (all
) + strlen (allfamilies
) + 1;
1881 font_all
= alloca (len
);
1882 z
= stpcpy (font_all
, allfamilies
);
1883 z
= stpcpy (z
, all
);
1884 memcpy (z
, p2
, p
- p2
);
1885 strcpy (z
+ (p
- p2
), allcs
);
1887 /* Build the actual font set name. */
1888 len
= strlen (base_fontname
) + strlen (font_allcs
)
1889 + strlen (font_allfamilies
) + strlen (font_all
) + 5;
1890 fontsetname
= xmalloc (len
);
1891 z
= stpcpy (fontsetname
, base_fontname
);
1892 z
= stpcpy (z
, sep
);
1893 z
= stpcpy (z
, font_allcs
);
1894 z
= stpcpy (z
, sep
);
1895 z
= stpcpy (z
, font_allfamilies
);
1896 z
= stpcpy (z
, sep
);
1897 z
= stpcpy (z
, font_all
);
1904 #endif /* HAVE_X_WINDOWS && USE_X_TOOLKIT */
1906 #ifdef DEBUG_XIC_FONTSET
1908 print_fontset_result (XFontSet xfs
, char *name
, char **missing_list
,
1912 fprintf (stderr
, "XIC Fontset created: %s\n", name
);
1915 fprintf (stderr
, "XIC Fontset failed: %s\n", name
);
1916 while (missing_count
-- > 0)
1918 fprintf (stderr
, " missing: %s\n", *missing_list
);
1927 xic_create_xfontset (struct frame
*f
)
1929 XFontSet xfs
= NULL
;
1930 struct font
*font
= FRAME_FONT (f
);
1931 int pixel_size
= font
->pixel_size
;
1932 Lisp_Object rest
, frame
;
1934 /* See if there is another frame already using same fontset. */
1935 FOR_EACH_FRAME (rest
, frame
)
1937 struct frame
*cf
= XFRAME (frame
);
1939 if (cf
!= f
&& FRAME_LIVE_P (f
) && FRAME_X_P (cf
)
1940 && FRAME_DISPLAY_INFO (cf
) == FRAME_DISPLAY_INFO (f
)
1942 && FRAME_FONT (f
)->pixel_size
== pixel_size
)
1944 xfs
= FRAME_XIC_FONTSET (cf
);
1952 char **missing_list
;
1955 const char *xlfd_format
= "-*-*-medium-r-normal--%d-*-*-*-*-*";
1957 sprintf (buf
, xlfd_format
, pixel_size
);
1958 missing_list
= NULL
;
1959 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
), buf
,
1960 &missing_list
, &missing_count
, &def_string
);
1961 #ifdef DEBUG_XIC_FONTSET
1962 print_fontset_result (xfs
, buf
, missing_list
, missing_count
);
1965 XFreeStringList (missing_list
);
1968 /* List of pixel sizes most likely available. Find one that
1969 is closest to pixel_size. */
1970 int sizes
[] = {0, 8, 10, 11, 12, 14, 17, 18, 20, 24, 26, 34, 0};
1971 int *smaller
, *larger
;
1973 for (smaller
= sizes
; smaller
[1]; smaller
++)
1974 if (smaller
[1] >= pixel_size
)
1976 larger
= smaller
+ 1;
1977 if (*larger
== pixel_size
)
1979 while (*smaller
|| *larger
)
1984 this_size
= *smaller
--;
1985 else if (! *smaller
)
1986 this_size
= *larger
++;
1987 else if (pixel_size
- *smaller
< *larger
- pixel_size
)
1988 this_size
= *smaller
--;
1990 this_size
= *larger
++;
1991 sprintf (buf
, xlfd_format
, this_size
);
1992 missing_list
= NULL
;
1993 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
), buf
,
1994 &missing_list
, &missing_count
, &def_string
);
1995 #ifdef DEBUG_XIC_FONTSET
1996 print_fontset_result (xfs
, buf
, missing_list
, missing_count
);
1999 XFreeStringList (missing_list
);
2006 const char *last_resort
= "-*-*-*-r-normal--*-*-*-*-*-*";
2008 missing_list
= NULL
;
2009 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
), last_resort
,
2010 &missing_list
, &missing_count
, &def_string
);
2011 #ifdef DEBUG_XIC_FONTSET
2012 print_fontset_result (xfs
, last_resort
, missing_list
, missing_count
);
2015 XFreeStringList (missing_list
);
2023 /* Free the X fontset of frame F if it is the last frame using it. */
2026 xic_free_xfontset (struct frame
*f
)
2028 Lisp_Object rest
, frame
;
2029 bool shared_p
= false;
2031 if (!FRAME_XIC_FONTSET (f
))
2034 /* See if there is another frame sharing the same fontset. */
2035 FOR_EACH_FRAME (rest
, frame
)
2037 struct frame
*cf
= XFRAME (frame
);
2038 if (cf
!= f
&& FRAME_LIVE_P (f
) && FRAME_X_P (cf
)
2039 && FRAME_DISPLAY_INFO (cf
) == FRAME_DISPLAY_INFO (f
)
2040 && FRAME_XIC_FONTSET (cf
) == FRAME_XIC_FONTSET (f
))
2048 /* The fontset is not used anymore. It is safe to free it. */
2049 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
2051 FRAME_XIC_FONTSET (f
) = NULL
;
2055 /* Value is the best input style, given user preferences USER (already
2056 checked to be supported by Emacs), and styles supported by the
2057 input method XIM. */
2060 best_xim_style (XIMStyles
*xim
)
2063 int nr_supported
= ARRAYELTS (supported_xim_styles
);
2065 for (i
= 0; i
< nr_supported
; ++i
)
2066 for (j
= 0; j
< xim
->count_styles
; ++j
)
2067 if (supported_xim_styles
[i
] == xim
->supported_styles
[j
])
2068 return supported_xim_styles
[i
];
2070 /* Return the default style. */
2071 return XIMPreeditNothing
| XIMStatusNothing
;
2074 /* Create XIC for frame F. */
2077 create_frame_xic (struct frame
*f
)
2081 XFontSet xfs
= NULL
;
2082 XVaNestedList status_attr
= NULL
;
2083 XVaNestedList preedit_attr
= NULL
;
2091 xim
= FRAME_X_XIM (f
);
2095 /* Determine XIC style. */
2096 xic_style
= best_xim_style (FRAME_X_XIM_STYLES (f
));
2098 /* Create X fontset. */
2099 if (xic_style
& (XIMPreeditPosition
| XIMStatusArea
))
2101 xfs
= xic_create_xfontset (f
);
2105 FRAME_XIC_FONTSET (f
) = xfs
;
2108 if (xic_style
& XIMPreeditPosition
)
2110 spot
.x
= 0; spot
.y
= 1;
2111 preedit_attr
= XVaCreateNestedList (0,
2114 FRAME_FOREGROUND_PIXEL (f
),
2116 FRAME_BACKGROUND_PIXEL (f
),
2117 (xic_style
& XIMPreeditPosition
2127 if (xic_style
& XIMStatusArea
)
2129 s_area
.x
= 0; s_area
.y
= 0; s_area
.width
= 1; s_area
.height
= 1;
2130 status_attr
= XVaCreateNestedList (0,
2136 FRAME_FOREGROUND_PIXEL (f
),
2138 FRAME_BACKGROUND_PIXEL (f
),
2145 if (preedit_attr
&& status_attr
)
2146 xic
= XCreateIC (xim
,
2147 XNInputStyle
, xic_style
,
2148 XNClientWindow
, FRAME_X_WINDOW (f
),
2149 XNFocusWindow
, FRAME_X_WINDOW (f
),
2150 XNStatusAttributes
, status_attr
,
2151 XNPreeditAttributes
, preedit_attr
,
2153 else if (preedit_attr
)
2154 xic
= XCreateIC (xim
,
2155 XNInputStyle
, xic_style
,
2156 XNClientWindow
, FRAME_X_WINDOW (f
),
2157 XNFocusWindow
, FRAME_X_WINDOW (f
),
2158 XNPreeditAttributes
, preedit_attr
,
2160 else if (status_attr
)
2161 xic
= XCreateIC (xim
,
2162 XNInputStyle
, xic_style
,
2163 XNClientWindow
, FRAME_X_WINDOW (f
),
2164 XNFocusWindow
, FRAME_X_WINDOW (f
),
2165 XNStatusAttributes
, status_attr
,
2168 xic
= XCreateIC (xim
,
2169 XNInputStyle
, xic_style
,
2170 XNClientWindow
, FRAME_X_WINDOW (f
),
2171 XNFocusWindow
, FRAME_X_WINDOW (f
),
2177 FRAME_XIC (f
) = xic
;
2178 FRAME_XIC_STYLE (f
) = xic_style
;
2179 xfs
= NULL
; /* Don't free below. */
2187 XFree (preedit_attr
);
2190 XFree (status_attr
);
2194 /* Destroy XIC and free XIC fontset of frame F, if any. */
2197 free_frame_xic (struct frame
*f
)
2199 if (FRAME_XIC (f
) == NULL
)
2202 XDestroyIC (FRAME_XIC (f
));
2203 xic_free_xfontset (f
);
2205 FRAME_XIC (f
) = NULL
;
2209 /* Place preedit area for XIC of window W's frame to specified
2210 pixel position X/Y. X and Y are relative to window W. */
2213 xic_set_preeditarea (struct window
*w
, int x
, int y
)
2215 struct frame
*f
= XFRAME (w
->frame
);
2219 spot
.x
= WINDOW_TO_FRAME_PIXEL_X (w
, x
) + WINDOW_LEFT_FRINGE_WIDTH (w
);
2220 spot
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, y
) + FONT_BASE (FRAME_FONT (f
));
2221 attr
= XVaCreateNestedList (0, XNSpotLocation
, &spot
, NULL
);
2222 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2227 /* Place status area for XIC in bottom right corner of frame F.. */
2230 xic_set_statusarea (struct frame
*f
)
2232 XIC xic
= FRAME_XIC (f
);
2237 /* Negotiate geometry of status area. If input method has existing
2238 status area, use its current size. */
2239 area
.x
= area
.y
= area
.width
= area
.height
= 0;
2240 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &area
, NULL
);
2241 XSetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2244 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &needed
, NULL
);
2245 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2248 if (needed
->width
== 0) /* Use XNArea instead of XNAreaNeeded */
2250 attr
= XVaCreateNestedList (0, XNArea
, &needed
, NULL
);
2251 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2255 area
.width
= needed
->width
;
2256 area
.height
= needed
->height
;
2257 area
.x
= FRAME_PIXEL_WIDTH (f
) - area
.width
- FRAME_INTERNAL_BORDER_WIDTH (f
);
2258 area
.y
= (FRAME_PIXEL_HEIGHT (f
) - area
.height
2259 - FRAME_MENUBAR_HEIGHT (f
)
2260 - FRAME_TOOLBAR_TOP_HEIGHT (f
)
2261 - FRAME_INTERNAL_BORDER_WIDTH (f
));
2264 attr
= XVaCreateNestedList (0, XNArea
, &area
, NULL
);
2265 XSetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2270 /* Set X fontset for XIC of frame F, using base font name
2271 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2274 xic_set_xfontset (struct frame
*f
, const char *base_fontname
)
2279 xic_free_xfontset (f
);
2281 xfs
= xic_create_xfontset (f
);
2283 attr
= XVaCreateNestedList (0, XNFontSet
, xfs
, NULL
);
2284 if (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
)
2285 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2286 if (FRAME_XIC_STYLE (f
) & XIMStatusArea
)
2287 XSetICValues (FRAME_XIC (f
), XNStatusAttributes
, attr
, NULL
);
2290 FRAME_XIC_FONTSET (f
) = xfs
;
2293 #endif /* HAVE_X_I18N */
2297 #ifdef USE_X_TOOLKIT
2299 /* Create and set up the X widget for frame F. */
2302 x_window (struct frame
*f
, long window_prompting
)
2304 XClassHint class_hints
;
2305 XSetWindowAttributes attributes
;
2306 unsigned long attribute_mask
;
2307 Widget shell_widget
;
2309 Widget frame_widget
;
2315 /* Use the resource name as the top-level widget name
2316 for looking up resources. Make a non-Lisp copy
2317 for the window manager, so GC relocation won't bother it.
2319 Elsewhere we specify the window name for the window manager. */
2320 f
->namebuf
= xlispstrdup (Vx_resource_name
);
2323 XtSetArg (al
[ac
], XtNallowShellResize
, 1); ac
++;
2324 XtSetArg (al
[ac
], XtNinput
, 1); ac
++;
2325 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2326 XtSetArg (al
[ac
], XtNborderWidth
, f
->border_width
); ac
++;
2327 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2328 XtSetArg (al
[ac
], XtNdepth
, FRAME_DISPLAY_INFO (f
)->n_planes
); ac
++;
2329 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2330 shell_widget
= XtAppCreateShell (f
->namebuf
, EMACS_CLASS
,
2331 applicationShellWidgetClass
,
2332 FRAME_X_DISPLAY (f
), al
, ac
);
2334 f
->output_data
.x
->widget
= shell_widget
;
2335 /* maybe_set_screen_title_format (shell_widget); */
2337 pane_widget
= lw_create_widget ("main", "pane", widget_id_tick
++,
2338 NULL
, shell_widget
, False
,
2339 NULL
, NULL
, NULL
, NULL
);
2342 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2343 XtSetArg (al
[ac
], XtNdepth
, FRAME_DISPLAY_INFO (f
)->n_planes
); ac
++;
2344 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2345 XtSetArg (al
[ac
], XtNborderWidth
, 0); ac
++;
2346 XtSetValues (pane_widget
, al
, ac
);
2347 f
->output_data
.x
->column_widget
= pane_widget
;
2349 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2350 the emacs screen when changing menubar. This reduces flickering. */
2353 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2354 XtSetArg (al
[ac
], XtNshowGrip
, 0); ac
++;
2355 XtSetArg (al
[ac
], XtNallowResize
, 1); ac
++;
2356 XtSetArg (al
[ac
], XtNresizeToPreferred
, 1); ac
++;
2357 XtSetArg (al
[ac
], XtNemacsFrame
, f
); ac
++;
2358 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2359 XtSetArg (al
[ac
], XtNdepth
, FRAME_DISPLAY_INFO (f
)->n_planes
); ac
++;
2360 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2361 XtSetArg (al
[ac
], XtNborderWidth
, 0); ac
++;
2362 frame_widget
= XtCreateWidget (f
->namebuf
, emacsFrameClass
, pane_widget
,
2365 f
->output_data
.x
->edit_widget
= frame_widget
;
2367 XtManageChild (frame_widget
);
2369 /* Do some needed geometry management. */
2373 int extra_borders
= 0;
2375 = (f
->output_data
.x
->menubar_widget
2376 ? (f
->output_data
.x
->menubar_widget
->core
.height
2377 + f
->output_data
.x
->menubar_widget
->core
.border_width
)
2380 #if false /* Experimentally, we now get the right results
2381 for -geometry -0-0 without this. 24 Aug 96, rms. */
2382 if (FRAME_EXTERNAL_MENU_BAR (f
))
2385 XtVaGetValues (pane_widget
, XtNinternalBorderWidth
, &ibw
, NULL
);
2386 menubar_size
+= ibw
;
2390 FRAME_MENUBAR_HEIGHT (f
) = menubar_size
;
2393 /* Motif seems to need this amount added to the sizes
2394 specified for the shell widget. The Athena/Lucid widgets don't.
2395 Both conclusions reached experimentally. -- rms. */
2396 XtVaGetValues (f
->output_data
.x
->edit_widget
, XtNinternalBorderWidth
,
2397 &extra_borders
, NULL
);
2401 f
->shell_position
= xmalloc (sizeof "=x++" + 4 * INT_STRLEN_BOUND (int));
2403 /* Convert our geometry parameters into a geometry string
2405 Note that we do not specify here whether the position
2406 is a user-specified or program-specified one.
2407 We pass that information later, in x_wm_set_size_hints. */
2409 int left
= f
->left_pos
;
2410 bool xneg
= (window_prompting
& XNegative
) != 0;
2411 int top
= f
->top_pos
;
2412 bool yneg
= (window_prompting
& YNegative
) != 0;
2418 if (window_prompting
& USPosition
)
2419 sprintf (f
->shell_position
, "=%dx%d%c%d%c%d",
2420 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2421 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
,
2422 (xneg
? '-' : '+'), left
,
2423 (yneg
? '-' : '+'), top
);
2426 sprintf (f
->shell_position
, "=%dx%d",
2427 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2428 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
);
2430 /* Setting x and y when the position is not specified in
2431 the geometry string will set program position in the WM hints.
2432 If Emacs had just one program position, we could set it in
2433 fallback resources, but since each make-frame call can specify
2434 different program positions, this is easier. */
2435 XtSetArg (gal
[gac
], XtNx
, left
); gac
++;
2436 XtSetArg (gal
[gac
], XtNy
, top
); gac
++;
2440 XtSetArg (gal
[gac
], XtNgeometry
, f
->shell_position
); gac
++;
2441 XtSetValues (shell_widget
, gal
, gac
);
2444 XtManageChild (pane_widget
);
2445 XtRealizeWidget (shell_widget
);
2447 if (FRAME_X_EMBEDDED_P (f
))
2448 XReparentWindow (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
),
2449 f
->output_data
.x
->parent_desc
, 0, 0);
2451 FRAME_X_WINDOW (f
) = XtWindow (frame_widget
);
2453 validate_x_resource_name ();
2455 class_hints
.res_name
= SSDATA (Vx_resource_name
);
2456 class_hints
.res_class
= SSDATA (Vx_resource_class
);
2457 XSetClassHint (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
), &class_hints
);
2460 FRAME_XIC (f
) = NULL
;
2462 create_frame_xic (f
);
2465 f
->output_data
.x
->wm_hints
.input
= True
;
2466 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2467 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2468 &f
->output_data
.x
->wm_hints
);
2470 hack_wm_protocols (f
, shell_widget
);
2473 XtAddEventHandler (shell_widget
, 0, True
, _XEditResCheckMessages
, 0);
2476 /* Do a stupid property change to force the server to generate a
2477 PropertyNotify event so that the event_stream server timestamp will
2478 be initialized to something relevant to the time we created the window.
2480 XChangeProperty (XtDisplay (frame_widget
), XtWindow (frame_widget
),
2481 FRAME_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2482 XA_ATOM
, 32, PropModeAppend
, NULL
, 0);
2484 /* Make all the standard events reach the Emacs frame. */
2485 attributes
.event_mask
= STANDARD_EVENT_SET
;
2490 /* XIM server might require some X events. */
2491 unsigned long fevent
= NoEventMask
;
2492 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2493 attributes
.event_mask
|= fevent
;
2495 #endif /* HAVE_X_I18N */
2497 attribute_mask
= CWEventMask
;
2498 XChangeWindowAttributes (XtDisplay (shell_widget
), XtWindow (shell_widget
),
2499 attribute_mask
, &attributes
);
2501 XtMapWidget (frame_widget
);
2503 /* x_set_name normally ignores requests to set the name if the
2504 requested name is the same as the current name. This is the one
2505 place where that assumption isn't correct; f->name is set, but
2506 the X server hasn't been told. */
2509 bool explicit = f
->explicit_name
;
2511 f
->explicit_name
= false;
2513 fset_name (f
, Qnil
);
2514 x_set_name (f
, name
, explicit);
2517 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2518 f
->output_data
.x
->current_cursor
2519 = f
->output_data
.x
->text_cursor
);
2523 /* This is a no-op, except under Motif. Make sure main areas are
2524 set to something reasonable, in case we get an error later. */
2525 lw_set_main_areas (pane_widget
, 0, frame_widget
);
2528 #else /* not USE_X_TOOLKIT */
2531 x_window (struct frame
*f
)
2533 if (! xg_create_frame_widgets (f
))
2534 error ("Unable to create window");
2537 FRAME_XIC (f
) = NULL
;
2541 create_frame_xic (f
);
2544 /* XIM server might require some X events. */
2545 unsigned long fevent
= NoEventMask
;
2546 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2548 if (fevent
!= NoEventMask
)
2550 XSetWindowAttributes attributes
;
2551 XWindowAttributes wattr
;
2552 unsigned long attribute_mask
;
2554 XGetWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2556 attributes
.event_mask
= wattr
.your_event_mask
| fevent
;
2557 attribute_mask
= CWEventMask
;
2558 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2559 attribute_mask
, &attributes
);
2567 #else /*! USE_GTK */
2568 /* Create and set up the X window for frame F. */
2571 x_window (struct frame
*f
)
2573 XClassHint class_hints
;
2574 XSetWindowAttributes attributes
;
2575 unsigned long attribute_mask
;
2577 attributes
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
2578 attributes
.border_pixel
= f
->output_data
.x
->border_pixel
;
2579 attributes
.bit_gravity
= StaticGravity
;
2580 attributes
.backing_store
= NotUseful
;
2581 attributes
.save_under
= True
;
2582 attributes
.event_mask
= STANDARD_EVENT_SET
;
2583 attributes
.colormap
= FRAME_X_COLORMAP (f
);
2584 attribute_mask
= (CWBackPixel
| CWBorderPixel
| CWBitGravity
| CWEventMask
2589 = XCreateWindow (FRAME_X_DISPLAY (f
),
2590 f
->output_data
.x
->parent_desc
,
2593 FRAME_PIXEL_WIDTH (f
), FRAME_PIXEL_HEIGHT (f
),
2595 CopyFromParent
, /* depth */
2596 InputOutput
, /* class */
2598 attribute_mask
, &attributes
);
2603 create_frame_xic (f
);
2606 /* XIM server might require some X events. */
2607 unsigned long fevent
= NoEventMask
;
2608 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2609 attributes
.event_mask
|= fevent
;
2610 attribute_mask
= CWEventMask
;
2611 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2612 attribute_mask
, &attributes
);
2615 #endif /* HAVE_X_I18N */
2617 validate_x_resource_name ();
2619 class_hints
.res_name
= SSDATA (Vx_resource_name
);
2620 class_hints
.res_class
= SSDATA (Vx_resource_class
);
2621 XSetClassHint (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &class_hints
);
2623 /* This indicates that we use the "Passive Input" input model.
2624 Unless we do this, we don't get the Focus{In,Out} events that we
2625 need to draw the cursor correctly. Accursed bureaucrats.
2626 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2628 f
->output_data
.x
->wm_hints
.input
= True
;
2629 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2630 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2631 &f
->output_data
.x
->wm_hints
);
2632 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
2634 /* Request "save yourself" and "delete window" commands from wm. */
2637 protocols
[0] = FRAME_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2638 protocols
[1] = FRAME_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2639 XSetWMProtocols (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), protocols
, 2);
2642 /* x_set_name normally ignores requests to set the name if the
2643 requested name is the same as the current name. This is the one
2644 place where that assumption isn't correct; f->name is set, but
2645 the X server hasn't been told. */
2648 bool explicit = f
->explicit_name
;
2650 f
->explicit_name
= false;
2652 fset_name (f
, Qnil
);
2653 x_set_name (f
, name
, explicit);
2656 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2657 f
->output_data
.x
->current_cursor
2658 = f
->output_data
.x
->text_cursor
);
2662 if (FRAME_X_WINDOW (f
) == 0)
2663 error ("Unable to create window");
2666 #endif /* not USE_GTK */
2667 #endif /* not USE_X_TOOLKIT */
2669 /* Verify that the icon position args for this window are valid. */
2672 x_icon_verify (struct frame
*f
, Lisp_Object parms
)
2674 Lisp_Object icon_x
, icon_y
;
2676 /* Set the position of the icon. Note that twm groups all
2677 icons in an icon window. */
2678 icon_x
= x_frame_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
2679 icon_y
= x_frame_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
2680 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2682 CHECK_NUMBER (icon_x
);
2683 CHECK_NUMBER (icon_y
);
2685 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2686 error ("Both left and top icon corners of icon must be specified");
2689 /* Handle the icon stuff for this window. Perhaps later we might
2690 want an x_set_icon_position which can be called interactively as
2694 x_icon (struct frame
*f
, Lisp_Object parms
)
2696 /* Set the position of the icon. Note that twm groups all
2697 icons in an icon window. */
2699 = x_frame_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
2701 = x_frame_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
2702 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2704 CHECK_TYPE_RANGED_INTEGER (int, icon_x
);
2705 CHECK_TYPE_RANGED_INTEGER (int, icon_y
);
2707 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2708 error ("Both left and top icon corners of icon must be specified");
2712 if (! EQ (icon_x
, Qunbound
))
2713 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
2715 #if false /* x_get_arg removes the visibility parameter as a side effect,
2716 but x_create_frame still needs it. */
2717 /* Start up iconic or window? */
2718 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
2719 x_wm_set_window_state
2720 (f
, (EQ (x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
),
2726 x_text_icon (f
, SSDATA ((!NILP (f
->icon_name
)
2733 /* Make the GCs needed for this window, setting the
2734 background, border and mouse colors; also create the
2735 mouse cursor and the gray border tile. */
2738 x_make_gc (struct frame
*f
)
2740 XGCValues gc_values
;
2744 /* Create the GCs of this frame.
2745 Note that many default values are used. */
2747 gc_values
.foreground
= FRAME_FOREGROUND_PIXEL (f
);
2748 gc_values
.background
= FRAME_BACKGROUND_PIXEL (f
);
2749 gc_values
.line_width
= 0; /* Means 1 using fast algorithm. */
2750 f
->output_data
.x
->normal_gc
2751 = XCreateGC (FRAME_X_DISPLAY (f
),
2753 GCLineWidth
| GCForeground
| GCBackground
,
2756 /* Reverse video style. */
2757 gc_values
.foreground
= FRAME_BACKGROUND_PIXEL (f
);
2758 gc_values
.background
= FRAME_FOREGROUND_PIXEL (f
);
2759 f
->output_data
.x
->reverse_gc
2760 = XCreateGC (FRAME_X_DISPLAY (f
),
2762 GCForeground
| GCBackground
| GCLineWidth
,
2765 /* Cursor has cursor-color background, background-color foreground. */
2766 gc_values
.foreground
= FRAME_BACKGROUND_PIXEL (f
);
2767 gc_values
.background
= f
->output_data
.x
->cursor_pixel
;
2768 gc_values
.fill_style
= FillOpaqueStippled
;
2769 f
->output_data
.x
->cursor_gc
2770 = XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2771 (GCForeground
| GCBackground
2772 | GCFillStyle
| GCLineWidth
),
2775 /* Create the gray border tile used when the pointer is not in
2776 the frame. Since this depends on the frame's pixel values,
2777 this must be done on a per-frame basis. */
2778 f
->output_data
.x
->border_tile
2779 = (XCreatePixmapFromBitmapData
2780 (FRAME_X_DISPLAY (f
), FRAME_DISPLAY_INFO (f
)->root_window
,
2781 gray_bits
, gray_width
, gray_height
,
2782 FRAME_FOREGROUND_PIXEL (f
),
2783 FRAME_BACKGROUND_PIXEL (f
),
2784 DefaultDepth (FRAME_X_DISPLAY (f
), FRAME_X_SCREEN_NUMBER (f
))));
2790 /* Free what was allocated in x_make_gc. */
2793 x_free_gcs (struct frame
*f
)
2795 Display
*dpy
= FRAME_X_DISPLAY (f
);
2799 if (f
->output_data
.x
->normal_gc
)
2801 XFreeGC (dpy
, f
->output_data
.x
->normal_gc
);
2802 f
->output_data
.x
->normal_gc
= 0;
2805 if (f
->output_data
.x
->reverse_gc
)
2807 XFreeGC (dpy
, f
->output_data
.x
->reverse_gc
);
2808 f
->output_data
.x
->reverse_gc
= 0;
2811 if (f
->output_data
.x
->cursor_gc
)
2813 XFreeGC (dpy
, f
->output_data
.x
->cursor_gc
);
2814 f
->output_data
.x
->cursor_gc
= 0;
2817 if (f
->output_data
.x
->border_tile
)
2819 XFreePixmap (dpy
, f
->output_data
.x
->border_tile
);
2820 f
->output_data
.x
->border_tile
= 0;
2827 /* Handler for signals raised during x_create_frame and
2828 x_create_tip_frame. FRAME is the frame which is partially
2832 unwind_create_frame (Lisp_Object frame
)
2834 struct frame
*f
= XFRAME (frame
);
2836 /* If frame is already dead, nothing to do. This can happen if the
2837 display is disconnected after the frame has become official, but
2838 before x_create_frame removes the unwind protect. */
2839 if (!FRAME_LIVE_P (f
))
2842 /* If frame is ``official'', nothing to do. */
2843 if (NILP (Fmemq (frame
, Vframe_list
)))
2845 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2846 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
2849 /* If the frame's image cache refcount is still the same as our
2850 private shadow variable, it means we are unwinding a frame
2851 for which we didn't yet call init_frame_faces, where the
2852 refcount is incremented. Therefore, we increment it here, so
2853 that free_frame_faces, called in x_free_frame_resources
2854 below, will not mistakenly decrement the counter that was not
2855 incremented yet to account for this new frame. */
2856 if (FRAME_IMAGE_CACHE (f
) != NULL
2857 && FRAME_IMAGE_CACHE (f
)->refcount
== image_cache_refcount
)
2858 FRAME_IMAGE_CACHE (f
)->refcount
++;
2860 x_free_frame_resources (f
);
2863 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2864 /* Check that reference counts are indeed correct. */
2865 eassert (dpyinfo
->reference_count
== dpyinfo_refcount
);
2866 eassert (dpyinfo
->terminal
->image_cache
->refcount
== image_cache_refcount
);
2875 do_unwind_create_frame (Lisp_Object frame
)
2877 unwind_create_frame (frame
);
2881 x_default_font_parameter (struct frame
*f
, Lisp_Object parms
)
2883 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
2884 Lisp_Object font_param
= x_get_arg (dpyinfo
, parms
, Qfont
, NULL
, NULL
,
2886 Lisp_Object font
= Qnil
;
2887 if (EQ (font_param
, Qunbound
))
2890 if (NILP (font_param
))
2892 /* System font should take precedence over X resources. We suggest this
2893 regardless of font-use-system-font because .emacs may not have been
2895 const char *system_font
= xsettings_get_system_font ();
2897 font
= font_open_by_name (f
, build_unibyte_string (system_font
));
2901 font
= !NILP (font_param
) ? font_param
2902 : x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
2904 if (! FONTP (font
) && ! STRINGP (font
))
2909 /* This will find the normal Xft font. */
2912 "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
2913 "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
2914 "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
2915 /* This was formerly the first thing tried, but it finds
2916 too many fonts and takes too long. */
2917 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
2918 /* If those didn't work, look for something which will
2920 "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
2925 for (i
= 0; names
[i
]; i
++)
2927 font
= font_open_by_name (f
, build_unibyte_string (names
[i
]));
2932 error ("No suitable font was found");
2934 else if (!NILP (font_param
))
2936 /* Remember the explicit font parameter, so we can re-apply it after
2937 we've applied the `default' face settings. */
2938 AUTO_FRAME_ARG (arg
, Qfont_param
, font_param
);
2939 x_set_frame_parameters (f
, arg
);
2942 /* This call will make X resources override any system font setting. */
2943 x_default_parameter (f
, parms
, Qfont
, font
, "font", "Font", RES_TYPE_STRING
);
2947 DEFUN ("x-wm-set-size-hint", Fx_wm_set_size_hint
, Sx_wm_set_size_hint
,
2949 doc
: /* Send the size hints for frame FRAME to the window manager.
2950 If FRAME is omitted or nil, use the selected frame.
2951 Signal error if FRAME is not an X frame. */)
2954 struct frame
*f
= decode_window_system_frame (frame
);
2957 x_wm_set_size_hint (f
, 0, false);
2963 set_machine_and_pid_properties (struct frame
*f
)
2965 /* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME. */
2966 XSetWMProperties (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), NULL
, NULL
,
2967 NULL
, 0, NULL
, NULL
, NULL
);
2968 pid_t pid
= getpid ();
2969 if (pid
<= 0xffffffffu
)
2971 unsigned long xpid
= pid
;
2972 XChangeProperty (FRAME_X_DISPLAY (f
),
2973 FRAME_OUTER_WINDOW (f
),
2974 XInternAtom (FRAME_X_DISPLAY (f
),
2977 XA_CARDINAL
, 32, PropModeReplace
,
2978 (unsigned char *) &xpid
, 1);
2982 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
2984 doc
: /* Make a new X window, which is called a "frame" in Emacs terms.
2985 Return an Emacs frame object. PARMS is an alist of frame parameters.
2986 If the parameters specify that the frame should not have a minibuffer,
2987 and do not specify a specific minibuffer window to use, then
2988 `default-minibuffer-frame' must be a frame whose minibuffer can be
2989 shared by the new frame.
2991 This function is an internal primitive--use `make-frame' instead. */)
2995 Lisp_Object frame
, tem
;
2997 bool minibuffer_only
= false;
2998 long window_prompting
= 0;
2999 ptrdiff_t count
= SPECPDL_INDEX ();
3000 Lisp_Object display
;
3001 struct x_display_info
*dpyinfo
= NULL
;
3005 parms
= Fcopy_alist (parms
);
3007 /* Use this general default value to start with
3008 until we know if this frame has a specified name. */
3009 Vx_resource_name
= Vinvocation_name
;
3011 display
= x_get_arg (dpyinfo
, parms
, Qterminal
, 0, 0, RES_TYPE_NUMBER
);
3012 if (EQ (display
, Qunbound
))
3013 display
= x_get_arg (dpyinfo
, parms
, Qdisplay
, 0, 0, RES_TYPE_STRING
);
3014 if (EQ (display
, Qunbound
))
3016 dpyinfo
= check_x_display_info (display
);
3017 kb
= dpyinfo
->terminal
->kboard
;
3019 if (!dpyinfo
->terminal
->name
)
3020 error ("Terminal is not live, can't create new frames on it");
3022 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
3024 && ! EQ (name
, Qunbound
)
3026 error ("Invalid frame name--not a string or nil");
3029 Vx_resource_name
= name
;
3031 /* See if parent window is specified. */
3032 parent
= x_get_arg (dpyinfo
, parms
, Qparent_id
, NULL
, NULL
, RES_TYPE_NUMBER
);
3033 if (EQ (parent
, Qunbound
))
3035 if (! NILP (parent
))
3036 CHECK_NUMBER (parent
);
3039 tem
= x_get_arg (dpyinfo
, parms
, Qminibuffer
, "minibuffer", "Minibuffer",
3041 if (EQ (tem
, Qnone
) || NILP (tem
))
3042 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
3043 else if (EQ (tem
, Qonly
))
3045 f
= make_minibuffer_frame ();
3046 minibuffer_only
= true;
3048 else if (WINDOWP (tem
))
3049 f
= make_frame_without_minibuffer (tem
, kb
, display
);
3051 f
= make_frame (true);
3053 XSETFRAME (frame
, f
);
3055 f
->terminal
= dpyinfo
->terminal
;
3057 f
->output_method
= output_x_window
;
3058 f
->output_data
.x
= xzalloc (sizeof *f
->output_data
.x
);
3059 f
->output_data
.x
->icon_bitmap
= -1;
3060 FRAME_FONTSET (f
) = -1;
3061 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
3062 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
3063 #if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
3064 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
3065 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
3066 #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
3067 f
->output_data
.x
->white_relief
.pixel
= -1;
3068 f
->output_data
.x
->black_relief
.pixel
= -1;
3071 x_get_arg (dpyinfo
, parms
, Qicon_name
, "iconName", "Title",
3073 if (! STRINGP (f
->icon_name
))
3074 fset_icon_name (f
, Qnil
);
3076 FRAME_DISPLAY_INFO (f
) = dpyinfo
;
3078 /* With FRAME_DISPLAY_INFO set up, this unwind-protect is safe. */
3079 record_unwind_protect (do_unwind_create_frame
, frame
);
3081 /* These colors will be set anyway later, but it's important
3082 to get the color reference counts right, so initialize them! */
3086 /* Function x_decode_color can signal an error. Make
3087 sure to initialize color slots so that we won't try
3088 to free colors we haven't allocated. */
3089 FRAME_FOREGROUND_PIXEL (f
) = -1;
3090 FRAME_BACKGROUND_PIXEL (f
) = -1;
3091 f
->output_data
.x
->cursor_pixel
= -1;
3092 f
->output_data
.x
->cursor_foreground_pixel
= -1;
3093 f
->output_data
.x
->border_pixel
= -1;
3094 f
->output_data
.x
->mouse_pixel
= -1;
3096 black
= build_string ("black");
3097 FRAME_FOREGROUND_PIXEL (f
)
3098 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3099 FRAME_BACKGROUND_PIXEL (f
)
3100 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3101 f
->output_data
.x
->cursor_pixel
3102 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3103 f
->output_data
.x
->cursor_foreground_pixel
3104 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3105 f
->output_data
.x
->border_pixel
3106 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3107 f
->output_data
.x
->mouse_pixel
3108 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3111 /* Specify the parent under which to make this X window. */
3114 f
->output_data
.x
->parent_desc
= (Window
) XFASTINT (parent
);
3115 f
->output_data
.x
->explicit_parent
= true;
3119 f
->output_data
.x
->parent_desc
= FRAME_DISPLAY_INFO (f
)->root_window
;
3120 f
->output_data
.x
->explicit_parent
= false;
3123 /* Set the name; the functions to which we pass f expect the name to
3125 if (EQ (name
, Qunbound
) || NILP (name
))
3127 fset_name (f
, build_string (dpyinfo
->x_id_name
));
3128 f
->explicit_name
= false;
3132 fset_name (f
, name
);
3133 f
->explicit_name
= true;
3134 /* Use the frame's title when getting resources for this frame. */
3135 specbind (Qx_resource_name
, name
);
3139 register_font_driver (&ftcrfont_driver
, f
);
3141 #ifdef HAVE_FREETYPE
3143 register_font_driver (&xftfont_driver
, f
);
3144 #else /* not HAVE_XFT */
3145 register_font_driver (&ftxfont_driver
, f
);
3146 #endif /* not HAVE_XFT */
3147 #endif /* HAVE_FREETYPE */
3148 register_font_driver (&xfont_driver
, f
);
3149 #endif /* not USE_CAIRO */
3151 image_cache_refcount
=
3152 FRAME_IMAGE_CACHE (f
) ? FRAME_IMAGE_CACHE (f
)->refcount
: 0;
3154 dpyinfo_refcount
= dpyinfo
->reference_count
;
3155 #endif /* GLYPH_DEBUG */
3157 x_default_parameter (f
, parms
, Qfont_backend
, Qnil
,
3158 "fontBackend", "FontBackend", RES_TYPE_STRING
);
3160 /* Extract the window parameters from the supplied values
3161 that are needed to determine window geometry. */
3162 x_default_font_parameter (f
, parms
);
3163 if (!FRAME_FONT (f
))
3165 delete_frame (frame
, Qnoelisp
);
3166 error ("Invalid frame font");
3169 /* Frame contents get displaced if an embedded X window has a border. */
3170 if (! FRAME_X_EMBEDDED_P (f
))
3171 x_default_parameter (f
, parms
, Qborder_width
, make_number (0),
3172 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
3174 /* This defaults to 1 in order to match xterm. We recognize either
3175 internalBorderWidth or internalBorder (which is what xterm calls
3177 if (NILP (Fassq (Qinternal_border_width
, parms
)))
3181 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
3182 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
3183 if (! EQ (value
, Qunbound
))
3184 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
3187 x_default_parameter (f
, parms
, Qinternal_border_width
,
3188 #ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */
3193 "internalBorderWidth", "internalBorderWidth",
3195 x_default_parameter (f
, parms
, Qright_divider_width
, make_number (0),
3196 NULL
, NULL
, RES_TYPE_NUMBER
);
3197 x_default_parameter (f
, parms
, Qbottom_divider_width
, make_number (0),
3198 NULL
, NULL
, RES_TYPE_NUMBER
);
3199 x_default_parameter (f
, parms
, Qvertical_scroll_bars
,
3200 #if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
3205 "verticalScrollBars", "ScrollBars",
3207 x_default_parameter (f
, parms
, Qhorizontal_scroll_bars
, Qnil
,
3208 "horizontalScrollBars", "ScrollBars",
3210 /* Also do the stuff which must be set before the window exists. */
3211 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
3212 "foreground", "Foreground", RES_TYPE_STRING
);
3213 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
3214 "background", "Background", RES_TYPE_STRING
);
3215 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
3216 "pointerColor", "Foreground", RES_TYPE_STRING
);
3217 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
3218 "borderColor", "BorderColor", RES_TYPE_STRING
);
3219 x_default_parameter (f
, parms
, Qscreen_gamma
, Qnil
,
3220 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT
);
3221 x_default_parameter (f
, parms
, Qline_spacing
, Qnil
,
3222 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER
);
3223 x_default_parameter (f
, parms
, Qleft_fringe
, Qnil
,
3224 "leftFringe", "LeftFringe", RES_TYPE_NUMBER
);
3225 x_default_parameter (f
, parms
, Qright_fringe
, Qnil
,
3226 "rightFringe", "RightFringe", RES_TYPE_NUMBER
);
3228 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_foreground
,
3229 "scrollBarForeground",
3230 "ScrollBarForeground", true);
3231 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_background
,
3232 "scrollBarBackground",
3233 "ScrollBarBackground", false);
3235 /* Init faces before x_default_parameter is called for the
3236 scroll-bar-width parameter because otherwise we end up in
3237 init_iterator with a null face cache, which should not happen. */
3238 init_frame_faces (f
);
3240 /* The following call of change_frame_size is needed since otherwise
3241 x_set_tool_bar_lines will already work with the character sizes
3242 installed by init_frame_faces while the frame's pixel size is
3243 still calculated from a character size of 1 and we subsequently
3244 hit the (height >= 0) assertion in window_box_height.
3246 The non-pixelwise code apparently worked around this because it
3247 had one frame line vs one toolbar line which left us with a zero
3248 root window height which was obviously wrong as well ... */
3249 adjust_frame_size (f
, FRAME_COLS (f
) * FRAME_COLUMN_WIDTH (f
),
3250 FRAME_LINES (f
) * FRAME_LINE_HEIGHT (f
), 5, true,
3253 /* Set the menu-bar-lines and tool-bar-lines parameters. We don't
3254 look up the X resources controlling the menu-bar and tool-bar
3255 here; they are processed specially at startup, and reflected in
3256 the values of the mode variables. */
3258 x_default_parameter (f
, parms
, Qmenu_bar_lines
,
3259 NILP (Vmenu_bar_mode
)
3260 ? make_number (0) : make_number (1),
3261 NULL
, NULL
, RES_TYPE_NUMBER
);
3262 x_default_parameter (f
, parms
, Qtool_bar_lines
,
3263 NILP (Vtool_bar_mode
)
3264 ? make_number (0) : make_number (1),
3265 NULL
, NULL
, RES_TYPE_NUMBER
);
3267 x_default_parameter (f
, parms
, Qbuffer_predicate
, Qnil
,
3268 "bufferPredicate", "BufferPredicate",
3270 x_default_parameter (f
, parms
, Qtitle
, Qnil
,
3271 "title", "Title", RES_TYPE_STRING
);
3272 x_default_parameter (f
, parms
, Qwait_for_wm
, Qt
,
3273 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN
);
3274 x_default_parameter (f
, parms
, Qtool_bar_position
,
3275 FRAME_TOOL_BAR_POSITION (f
), 0, 0, RES_TYPE_SYMBOL
);
3277 /* Compute the size of the X window. */
3278 window_prompting
= x_figure_window_size (f
, parms
, true);
3280 tem
= x_get_arg (dpyinfo
, parms
, Qunsplittable
, 0, 0, RES_TYPE_BOOLEAN
);
3281 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
3283 x_icon_verify (f
, parms
);
3285 /* Create the X widget or window. */
3286 #ifdef USE_X_TOOLKIT
3287 x_window (f
, window_prompting
);
3295 /* Now consider the frame official. */
3296 f
->terminal
->reference_count
++;
3297 FRAME_DISPLAY_INFO (f
)->reference_count
++;
3298 Vframe_list
= Fcons (frame
, Vframe_list
);
3300 /* We need to do this after creating the X window, so that the
3301 icon-creation functions can say whose icon they're describing. */
3302 x_default_parameter (f
, parms
, Qicon_type
, Qt
,
3303 "bitmapIcon", "BitmapIcon", RES_TYPE_BOOLEAN
);
3305 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
3306 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3307 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
3308 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3309 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
3310 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
3311 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
3312 "scrollBarWidth", "ScrollBarWidth",
3314 x_default_parameter (f
, parms
, Qscroll_bar_height
, Qnil
,
3315 "scrollBarHeight", "ScrollBarHeight",
3317 x_default_parameter (f
, parms
, Qalpha
, Qnil
,
3318 "alpha", "Alpha", RES_TYPE_NUMBER
);
3320 /* Consider frame official, now. */
3321 f
->can_x_set_window_size
= true;
3323 adjust_frame_size (f
, FRAME_TEXT_WIDTH (f
), FRAME_TEXT_HEIGHT (f
), 0, true,
3326 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3327 /* Create the menu bar. */
3328 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
3330 /* If this signals an error, we haven't set size hints for the
3331 frame and we didn't make it visible. */
3332 initialize_frame_menubar (f
);
3335 /* This is a no-op, except under Motif where it arranges the
3336 main window for the widgets on it. */
3337 lw_set_main_areas (f
->output_data
.x
->column_widget
,
3338 f
->output_data
.x
->menubar_widget
,
3339 f
->output_data
.x
->edit_widget
);
3340 #endif /* not USE_GTK */
3342 #endif /* USE_X_TOOLKIT || USE_GTK */
3344 /* Tell the server what size and position, etc, we want, and how
3345 badly we want them. This should be done after we have the menu
3346 bar so that its size can be taken into account. */
3348 x_wm_set_size_hint (f
, window_prompting
, false);
3351 /* Process fullscreen parameter here in the hope that normalizing a
3352 fullheight/fullwidth frame will produce the size set by the last
3353 adjust_frame_size call. */
3354 x_default_parameter (f
, parms
, Qfullscreen
, Qnil
,
3355 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL
);
3357 /* Make the window appear on the frame and enable display, unless
3358 the caller says not to. However, with explicit parent, Emacs
3359 cannot control visibility, so don't try. */
3360 if (! f
->output_data
.x
->explicit_parent
)
3362 Lisp_Object visibility
;
3364 visibility
= x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0,
3366 if (EQ (visibility
, Qunbound
))
3369 if (EQ (visibility
, Qicon
))
3370 x_iconify_frame (f
);
3371 else if (! NILP (visibility
))
3372 x_make_frame_visible (f
);
3375 /* Must have been Qnil. */
3381 /* Set machine name and pid for the purpose of window managers. */
3382 set_machine_and_pid_properties (f
);
3384 /* Set the WM leader property. GTK does this itself, so this is not
3385 needed when using GTK. */
3386 if (dpyinfo
->client_leader_window
!= 0)
3388 XChangeProperty (FRAME_X_DISPLAY (f
),
3389 FRAME_OUTER_WINDOW (f
),
3390 dpyinfo
->Xatom_wm_client_leader
,
3391 XA_WINDOW
, 32, PropModeReplace
,
3392 (unsigned char *) &dpyinfo
->client_leader_window
, 1);
3397 /* Initialize `default-minibuffer-frame' in case this is the first
3398 frame on this terminal. */
3399 if (FRAME_HAS_MINIBUF_P (f
)
3400 && (!FRAMEP (KVAR (kb
, Vdefault_minibuffer_frame
))
3401 || !FRAME_LIVE_P (XFRAME (KVAR (kb
, Vdefault_minibuffer_frame
)))))
3402 kset_default_minibuffer_frame (kb
, frame
);
3404 /* All remaining specified parameters, which have not been "used"
3405 by x_get_arg and friends, now go in the misc. alist of the frame. */
3406 for (tem
= parms
; CONSP (tem
); tem
= XCDR (tem
))
3407 if (CONSP (XCAR (tem
)) && !NILP (XCAR (XCAR (tem
))))
3408 fset_param_alist (f
, Fcons (XCAR (tem
), f
->param_alist
));
3410 /* Make sure windows on this frame appear in calls to next-window
3411 and similar functions. */
3412 Vwindow_list
= Qnil
;
3414 return unbind_to (count
, frame
);
3418 /* FRAME is used only to get a handle on the X display. We don't pass the
3419 display info directly because we're called from frame.c, which doesn't
3420 know about that structure. */
3423 x_get_focus_frame (struct frame
*frame
)
3425 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (frame
);
3427 if (! dpyinfo
->x_focus_frame
)
3430 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
3435 /* In certain situations, when the window manager follows a
3436 click-to-focus policy, there seems to be no way around calling
3437 XSetInputFocus to give another frame the input focus .
3439 In an ideal world, XSetInputFocus should generally be avoided so
3440 that applications don't interfere with the window manager's focus
3441 policy. But I think it's okay to use when it's clearly done
3442 following a user-command. */
3445 x_focus_frame (struct frame
*f
)
3447 Display
*dpy
= FRAME_X_DISPLAY (f
);
3450 x_catch_errors (dpy
);
3452 if (FRAME_X_EMBEDDED_P (f
))
3454 /* For Xembedded frames, normally the embedder forwards key
3455 events. See XEmbed Protocol Specification at
3456 http://freedesktop.org/wiki/Specifications/xembed-spec */
3457 xembed_request_focus (f
);
3461 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3462 RevertToParent
, CurrentTime
);
3463 x_ewmh_activate_frame (f
);
3466 x_uncatch_errors ();
3471 DEFUN ("xw-color-defined-p", Fxw_color_defined_p
, Sxw_color_defined_p
, 1, 2, 0,
3472 doc
: /* Internal function called by `color-defined-p', which see.
3473 (Note that the Nextstep version of this function ignores FRAME.) */)
3474 (Lisp_Object color
, Lisp_Object frame
)
3477 struct frame
*f
= decode_window_system_frame (frame
);
3479 CHECK_STRING (color
);
3481 if (x_defined_color (f
, SSDATA (color
), &foo
, false))
3487 DEFUN ("xw-color-values", Fxw_color_values
, Sxw_color_values
, 1, 2, 0,
3488 doc
: /* Internal function called by `color-values', which see. */)
3489 (Lisp_Object color
, Lisp_Object frame
)
3492 struct frame
*f
= decode_window_system_frame (frame
);
3494 CHECK_STRING (color
);
3496 if (x_defined_color (f
, SSDATA (color
), &foo
, false))
3497 return list3i (foo
.red
, foo
.green
, foo
.blue
);
3502 DEFUN ("xw-display-color-p", Fxw_display_color_p
, Sxw_display_color_p
, 0, 1, 0,
3503 doc
: /* Internal function called by `display-color-p', which see. */)
3504 (Lisp_Object terminal
)
3506 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3508 if (dpyinfo
->n_planes
<= 2)
3511 switch (dpyinfo
->visual
->class)
3524 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
3526 doc
: /* Return t if the X display supports shades of gray.
3527 Note that color displays do support shades of gray.
3528 The optional argument TERMINAL specifies which display to ask about.
3529 TERMINAL should be a terminal object, a frame or a display name (a string).
3530 If omitted or nil, that stands for the selected frame's display. */)
3531 (Lisp_Object terminal
)
3533 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3535 if (dpyinfo
->n_planes
<= 1)
3538 switch (dpyinfo
->visual
->class)
3553 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
3555 doc
: /* Return the width in pixels of the X display TERMINAL.
3556 The optional argument TERMINAL specifies which display to ask about.
3557 TERMINAL should be a terminal object, a frame or a display name (a string).
3558 If omitted or nil, that stands for the selected frame's display.
3560 On \"multi-monitor\" setups this refers to the pixel width for all
3561 physical monitors associated with TERMINAL. To get information for
3562 each physical monitor, use `display-monitor-attributes-list'. */)
3563 (Lisp_Object terminal
)
3565 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3567 return make_number (x_display_pixel_width (dpyinfo
));
3570 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
3571 Sx_display_pixel_height
, 0, 1, 0,
3572 doc
: /* Return the height in pixels of the X display TERMINAL.
3573 The optional argument TERMINAL specifies which display to ask about.
3574 TERMINAL should be a terminal object, a frame or a display name (a string).
3575 If omitted or nil, that stands for the selected frame's display.
3577 On \"multi-monitor\" setups this refers to the pixel height for all
3578 physical monitors associated with TERMINAL. To get information for
3579 each physical monitor, use `display-monitor-attributes-list'. */)
3580 (Lisp_Object terminal
)
3582 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3584 return make_number (x_display_pixel_height (dpyinfo
));
3587 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
3589 doc
: /* Return the number of bitplanes of the X display TERMINAL.
3590 The optional argument TERMINAL specifies which display to ask about.
3591 TERMINAL should be a terminal object, a frame or a display name (a string).
3592 If omitted or nil, that stands for the selected frame's display. */)
3593 (Lisp_Object terminal
)
3595 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3597 return make_number (dpyinfo
->n_planes
);
3600 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
3602 doc
: /* Return the number of color cells of the X display TERMINAL.
3603 The optional argument TERMINAL specifies which display to ask about.
3604 TERMINAL should be a terminal object, a frame or a display name (a string).
3605 If omitted or nil, that stands for the selected frame's display. */)
3606 (Lisp_Object terminal
)
3608 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3610 int nr_planes
= DisplayPlanes (dpyinfo
->display
,
3611 XScreenNumberOfScreen (dpyinfo
->screen
));
3613 /* Truncate nr_planes to 24 to avoid integer overflow.
3614 Some displays says 32, but only 24 bits are actually significant.
3615 There are only very few and rare video cards that have more than
3616 24 significant bits. Also 24 bits is more than 16 million colors,
3617 it "should be enough for everyone". */
3618 if (nr_planes
> 24) nr_planes
= 24;
3620 return make_number (1 << nr_planes
);
3623 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
3624 Sx_server_max_request_size
,
3626 doc
: /* Return the maximum request size of the X server of display TERMINAL.
3627 The optional argument TERMINAL specifies which display to ask about.
3628 TERMINAL should be a terminal object, a frame or a display name (a string).
3629 If omitted or nil, that stands for the selected frame's display. */)
3630 (Lisp_Object terminal
)
3632 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3634 return make_number (MAXREQUEST (dpyinfo
->display
));
3637 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
3638 doc
: /* Return the "vendor ID" string of the GUI software on TERMINAL.
3640 (Labeling every distributor as a "vendor" embodies the false assumption
3641 that operating systems cannot be developed and distributed noncommercially.)
3642 The optional argument TERMINAL specifies which display to ask about.
3644 For GNU and Unix systems, this queries the X server software; for
3645 MS-Windows, this queries the OS.
3647 TERMINAL should be a terminal object, a frame or a display name (a string).
3648 If omitted or nil, that stands for the selected frame's display. */)
3649 (Lisp_Object terminal
)
3651 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3652 const char *vendor
= ServerVendor (dpyinfo
->display
);
3654 if (! vendor
) vendor
= "";
3655 return build_string (vendor
);
3658 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
3659 doc
: /* Return the version numbers of the GUI software on TERMINAL.
3660 The value is a list of three integers specifying the version of the GUI
3663 For GNU and Unix system, the first 2 numbers are the version of the X
3664 Protocol used on TERMINAL and the 3rd number is the distributor-specific
3665 release number. For MS-Windows, the 3 numbers report the version and
3666 the build number of the OS.
3668 See also the function `x-server-vendor'.
3670 The optional argument TERMINAL specifies which display to ask about.
3671 TERMINAL should be a terminal object, a frame or a display name (a string).
3672 If omitted or nil, that stands for the selected frame's display. */)
3673 (Lisp_Object terminal
)
3675 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3676 Display
*dpy
= dpyinfo
->display
;
3678 return list3i (ProtocolVersion (dpy
), ProtocolRevision (dpy
),
3679 VendorRelease (dpy
));
3682 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
3683 doc
: /* Return the number of screens on the X server of display TERMINAL.
3684 The optional argument TERMINAL specifies which display to ask about.
3685 TERMINAL should be a terminal object, a frame or a display name (a string).
3686 If omitted or nil, that stands for the selected frame's display. */)
3687 (Lisp_Object terminal
)
3689 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3691 return make_number (ScreenCount (dpyinfo
->display
));
3694 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
3695 doc
: /* Return the height in millimeters of the X display TERMINAL.
3696 The optional argument TERMINAL specifies which display to ask about.
3697 TERMINAL should be a terminal object, a frame or a display name (a string).
3698 If omitted or nil, that stands for the selected frame's display.
3700 On \"multi-monitor\" setups this refers to the height in millimeters for
3701 all physical monitors associated with TERMINAL. To get information
3702 for each physical monitor, use `display-monitor-attributes-list'. */)
3703 (Lisp_Object terminal
)
3705 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3707 return make_number (HeightMMOfScreen (dpyinfo
->screen
));
3710 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
3711 doc
: /* Return the width in millimeters of the X display TERMINAL.
3712 The optional argument TERMINAL specifies which display to ask about.
3713 TERMINAL should be a terminal object, a frame or a display name (a string).
3714 If omitted or nil, that stands for the selected frame's display.
3716 On \"multi-monitor\" setups this refers to the width in millimeters for
3717 all physical monitors associated with TERMINAL. To get information
3718 for each physical monitor, use `display-monitor-attributes-list'. */)
3719 (Lisp_Object terminal
)
3721 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3723 return make_number (WidthMMOfScreen (dpyinfo
->screen
));
3726 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
3727 Sx_display_backing_store
, 0, 1, 0,
3728 doc
: /* Return an indication of whether X display TERMINAL does backing store.
3729 The value may be `always', `when-mapped', or `not-useful'.
3730 The optional argument TERMINAL specifies which display to ask about.
3731 TERMINAL should be a terminal object, a frame or a display name (a string).
3732 If omitted or nil, that stands for the selected frame's display. */)
3733 (Lisp_Object terminal
)
3735 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3738 switch (DoesBackingStore (dpyinfo
->screen
))
3741 result
= intern ("always");
3745 result
= intern ("when-mapped");
3749 result
= intern ("not-useful");
3753 error ("Strange value for BackingStore parameter of screen");
3759 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
3760 Sx_display_visual_class
, 0, 1, 0,
3761 doc
: /* Return the visual class of the X display TERMINAL.
3762 The value is one of the symbols `static-gray', `gray-scale',
3763 `static-color', `pseudo-color', `true-color', or `direct-color'.
3765 The optional argument TERMINAL specifies which display to ask about.
3766 TERMINAL should a terminal object, a frame or a display name (a string).
3767 If omitted or nil, that stands for the selected frame's display. */)
3768 (Lisp_Object terminal
)
3770 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3773 switch (dpyinfo
->visual
->class)
3776 result
= intern ("static-gray");
3779 result
= intern ("gray-scale");
3782 result
= intern ("static-color");
3785 result
= intern ("pseudo-color");
3788 result
= intern ("true-color");
3791 result
= intern ("direct-color");
3794 error ("Display has an unknown visual class");
3800 DEFUN ("x-display-save-under", Fx_display_save_under
,
3801 Sx_display_save_under
, 0, 1, 0,
3802 doc
: /* Return t if the X display TERMINAL supports the save-under feature.
3803 The optional argument TERMINAL specifies which display to ask about.
3804 TERMINAL should be a terminal object, a frame or a display name (a string).
3805 If omitted or nil, that stands for the selected frame's display. */)
3806 (Lisp_Object terminal
)
3808 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3810 if (DoesSaveUnders (dpyinfo
->screen
) == True
)
3816 /* Store the geometry of the workarea on display DPYINFO into *RECT.
3817 Return false if and only if the workarea information cannot be
3818 obtained via the _NET_WORKAREA root window property. */
3820 #if ! GTK_CHECK_VERSION (3, 4, 0)
3822 x_get_net_workarea (struct x_display_info
*dpyinfo
, XRectangle
*rect
)
3824 Display
*dpy
= dpyinfo
->display
;
3825 long offset
, max_len
;
3826 Atom target_type
, actual_type
;
3827 unsigned long actual_size
, bytes_remaining
;
3828 int rc
, actual_format
;
3829 unsigned char *tmp_data
= NULL
;
3830 bool result
= false;
3832 x_catch_errors (dpy
);
3835 target_type
= XA_CARDINAL
;
3836 rc
= XGetWindowProperty (dpy
, dpyinfo
->root_window
,
3837 dpyinfo
->Xatom_net_current_desktop
,
3838 offset
, max_len
, False
, target_type
,
3839 &actual_type
, &actual_format
, &actual_size
,
3840 &bytes_remaining
, &tmp_data
);
3841 if (rc
== Success
&& actual_type
== target_type
&& !x_had_errors_p (dpy
)
3842 && actual_format
== 32 && actual_size
== max_len
)
3844 long current_desktop
= ((long *) tmp_data
)[0];
3849 offset
= 4 * current_desktop
;
3851 rc
= XGetWindowProperty (dpy
, dpyinfo
->root_window
,
3852 dpyinfo
->Xatom_net_workarea
,
3853 offset
, max_len
, False
, target_type
,
3854 &actual_type
, &actual_format
, &actual_size
,
3855 &bytes_remaining
, &tmp_data
);
3856 if (rc
== Success
&& actual_type
== target_type
&& !x_had_errors_p (dpy
)
3857 && actual_format
== 32 && actual_size
== max_len
)
3859 long *values
= (long *) tmp_data
;
3861 rect
->x
= values
[0];
3862 rect
->y
= values
[1];
3863 rect
->width
= values
[2];
3864 rect
->height
= values
[3];
3874 x_uncatch_errors ();
3882 /* Return monitor number where F is "most" or closest to. */
3884 x_get_monitor_for_frame (struct frame
*f
,
3885 struct MonitorInfo
*monitors
,
3889 int area
= 0, dist
= -1;
3890 int best_area
= -1, best_dist
= -1;
3893 if (n_monitors
== 1) return 0;
3894 frect
.x
= f
->left_pos
;
3895 frect
.y
= f
->top_pos
;
3896 frect
.width
= FRAME_PIXEL_WIDTH (f
);
3897 frect
.height
= FRAME_PIXEL_HEIGHT (f
);
3899 for (i
= 0; i
< n_monitors
; ++i
)
3901 struct MonitorInfo
*mi
= &monitors
[i
];
3905 if (mi
->geom
.width
== 0) continue;
3907 if (x_intersect_rectangles (&mi
->geom
, &frect
, &res
))
3909 a
= res
.width
* res
.height
;
3917 if (a
== 0 && area
== 0)
3920 if (frect
.x
+ frect
.width
< mi
->geom
.x
)
3921 dx
= mi
->geom
.x
- frect
.x
+ frect
.width
;
3922 else if (frect
.x
> mi
->geom
.x
+ mi
->geom
.width
)
3923 dx
= frect
.x
- mi
->geom
.x
+ mi
->geom
.width
;
3926 if (frect
.y
+ frect
.height
< mi
->geom
.y
)
3927 dy
= mi
->geom
.y
- frect
.y
+ frect
.height
;
3928 else if (frect
.y
> mi
->geom
.y
+ mi
->geom
.height
)
3929 dy
= frect
.y
- mi
->geom
.y
+ mi
->geom
.height
;
3934 if (dist
== -1 || dist
> d
)
3942 return best_area
!= -1 ? best_area
: (best_dist
!= -1 ? best_dist
: 0);
3946 x_make_monitor_attribute_list (struct MonitorInfo
*monitors
,
3948 int primary_monitor
,
3949 struct x_display_info
*dpyinfo
,
3952 Lisp_Object monitor_frames
= Fmake_vector (make_number (n_monitors
), Qnil
);
3953 Lisp_Object frame
, rest
;
3955 FOR_EACH_FRAME (rest
, frame
)
3957 struct frame
*f
= XFRAME (frame
);
3959 if (FRAME_X_P (f
) && FRAME_DISPLAY_INFO (f
) == dpyinfo
3960 && !EQ (frame
, tip_frame
))
3962 int i
= x_get_monitor_for_frame (f
, monitors
, n_monitors
);
3963 ASET (monitor_frames
, i
, Fcons (frame
, AREF (monitor_frames
, i
)));
3967 return make_monitor_attribute_list (monitors
, n_monitors
, primary_monitor
,
3968 monitor_frames
, source
);
3972 x_get_monitor_attributes_fallback (struct x_display_info
*dpyinfo
)
3974 struct MonitorInfo monitor
;
3975 XRectangle workarea_r
;
3977 /* Fallback: treat (possibly) multiple physical monitors as if they
3978 formed a single monitor as a whole. This should provide a
3979 consistent result at least on single monitor environments. */
3980 monitor
.geom
.x
= monitor
.geom
.y
= 0;
3981 monitor
.geom
.width
= x_display_pixel_width (dpyinfo
);
3982 monitor
.geom
.height
= x_display_pixel_height (dpyinfo
);
3983 monitor
.mm_width
= WidthMMOfScreen (dpyinfo
->screen
);
3984 monitor
.mm_height
= HeightMMOfScreen (dpyinfo
->screen
);
3985 monitor
.name
= xstrdup ("combined screen");
3987 if (x_get_net_workarea (dpyinfo
, &workarea_r
))
3988 monitor
.work
= workarea_r
;
3990 monitor
.work
= monitor
.geom
;
3991 return x_make_monitor_attribute_list (&monitor
, 1, 0, dpyinfo
, "fallback");
3995 #ifdef HAVE_XINERAMA
3997 x_get_monitor_attributes_xinerama (struct x_display_info
*dpyinfo
)
4000 Lisp_Object attributes_list
= Qnil
;
4001 Display
*dpy
= dpyinfo
->display
;
4002 XineramaScreenInfo
*info
= XineramaQueryScreens (dpy
, &n_monitors
);
4003 struct MonitorInfo
*monitors
;
4004 double mm_width_per_pixel
, mm_height_per_pixel
;
4006 if (! info
|| n_monitors
== 0)
4010 return attributes_list
;
4013 mm_width_per_pixel
= ((double) WidthMMOfScreen (dpyinfo
->screen
)
4014 / x_display_pixel_width (dpyinfo
));
4015 mm_height_per_pixel
= ((double) HeightMMOfScreen (dpyinfo
->screen
)
4016 / x_display_pixel_height (dpyinfo
));
4017 monitors
= xzalloc (n_monitors
* sizeof *monitors
);
4018 for (i
= 0; i
< n_monitors
; ++i
)
4020 struct MonitorInfo
*mi
= &monitors
[i
];
4021 XRectangle workarea_r
;
4023 mi
->geom
.x
= info
[i
].x_org
;
4024 mi
->geom
.y
= info
[i
].y_org
;
4025 mi
->geom
.width
= info
[i
].width
;
4026 mi
->geom
.height
= info
[i
].height
;
4027 mi
->mm_width
= mi
->geom
.width
* mm_width_per_pixel
+ 0.5;
4028 mi
->mm_height
= mi
->geom
.height
* mm_height_per_pixel
+ 0.5;
4031 /* Xinerama usually have primary monitor first, just use that. */
4032 if (i
== 0 && x_get_net_workarea (dpyinfo
, &workarea_r
))
4034 mi
->work
= workarea_r
;
4035 if (! x_intersect_rectangles (&mi
->geom
, &mi
->work
, &mi
->work
))
4036 mi
->work
= mi
->geom
;
4039 mi
->work
= mi
->geom
;
4043 attributes_list
= x_make_monitor_attribute_list (monitors
,
4048 free_monitors (monitors
, n_monitors
);
4049 return attributes_list
;
4051 #endif /* HAVE_XINERAMA */
4056 x_get_monitor_attributes_xrandr (struct x_display_info
*dpyinfo
)
4058 Lisp_Object attributes_list
= Qnil
;
4059 XRRScreenResources
*resources
;
4060 Display
*dpy
= dpyinfo
->display
;
4061 int i
, n_monitors
, primary
= -1;
4062 RROutput pxid
= None
;
4063 struct MonitorInfo
*monitors
;
4065 #ifdef HAVE_XRRGETSCREENRESOURCESCURRENT
4066 resources
= XRRGetScreenResourcesCurrent (dpy
, dpyinfo
->root_window
);
4068 resources
= XRRGetScreenResources (dpy
, dpyinfo
->root_window
);
4070 if (! resources
|| resources
->noutput
== 0)
4073 XRRFreeScreenResources (resources
);
4076 n_monitors
= resources
->noutput
;
4077 monitors
= xzalloc (n_monitors
* sizeof *monitors
);
4079 #ifdef HAVE_XRRGETOUTPUTPRIMARY
4080 pxid
= XRRGetOutputPrimary (dpy
, dpyinfo
->root_window
);
4083 for (i
= 0; i
< n_monitors
; ++i
)
4085 XRROutputInfo
*info
= XRRGetOutputInfo (dpy
, resources
,
4086 resources
->outputs
[i
]);
4087 Connection conn
= info
? info
->connection
: RR_Disconnected
;
4088 RRCrtc id
= info
? info
->crtc
: None
;
4090 if (strcmp (info
->name
, "default") == 0)
4092 /* Non XRandr 1.2 driver, does not give useful data. */
4093 XRRFreeOutputInfo (info
);
4094 XRRFreeScreenResources (resources
);
4095 free_monitors (monitors
, n_monitors
);
4099 if (conn
!= RR_Disconnected
&& id
!= None
)
4101 XRRCrtcInfo
*crtc
= XRRGetCrtcInfo (dpy
, resources
, id
);
4102 struct MonitorInfo
*mi
= &monitors
[i
];
4103 XRectangle workarea_r
;
4107 XRRFreeOutputInfo (info
);
4111 mi
->geom
.x
= crtc
->x
;
4112 mi
->geom
.y
= crtc
->y
;
4113 mi
->geom
.width
= crtc
->width
;
4114 mi
->geom
.height
= crtc
->height
;
4115 mi
->mm_width
= info
->mm_width
;
4116 mi
->mm_height
= info
->mm_height
;
4117 mi
->name
= xstrdup (info
->name
);
4119 if (pxid
!= None
&& pxid
== resources
->outputs
[i
])
4121 else if (primary
== -1 && strcmp (info
->name
, "LVDS") == 0)
4124 if (i
== primary
&& x_get_net_workarea (dpyinfo
, &workarea_r
))
4126 mi
->work
= workarea_r
;
4127 if (! x_intersect_rectangles (&mi
->geom
, &mi
->work
, &mi
->work
))
4128 mi
->work
= mi
->geom
;
4131 mi
->work
= mi
->geom
;
4133 XRRFreeCrtcInfo (crtc
);
4135 XRRFreeOutputInfo (info
);
4137 XRRFreeScreenResources (resources
);
4139 attributes_list
= x_make_monitor_attribute_list (monitors
,
4144 free_monitors (monitors
, n_monitors
);
4145 return attributes_list
;
4147 #endif /* HAVE_XRANDR */
4150 x_get_monitor_attributes (struct x_display_info
*dpyinfo
)
4152 Lisp_Object attributes_list
= Qnil
;
4153 Display
*dpy
= dpyinfo
->display
;
4155 (void) dpy
; /* Suppress unused variable warning. */
4158 int xrr_event_base
, xrr_error_base
;
4159 bool xrr_ok
= false;
4160 xrr_ok
= XRRQueryExtension (dpy
, &xrr_event_base
, &xrr_error_base
);
4163 int xrr_major
, xrr_minor
;
4164 XRRQueryVersion (dpy
, &xrr_major
, &xrr_minor
);
4165 xrr_ok
= (xrr_major
== 1 && xrr_minor
>= 2) || xrr_major
> 1;
4169 attributes_list
= x_get_monitor_attributes_xrandr (dpyinfo
);
4170 #endif /* HAVE_XRANDR */
4172 #ifdef HAVE_XINERAMA
4173 if (NILP (attributes_list
))
4175 int xin_event_base
, xin_error_base
;
4176 bool xin_ok
= false;
4177 xin_ok
= XineramaQueryExtension (dpy
, &xin_event_base
, &xin_error_base
);
4178 if (xin_ok
&& XineramaIsActive (dpy
))
4179 attributes_list
= x_get_monitor_attributes_xinerama (dpyinfo
);
4181 #endif /* HAVE_XINERAMA */
4183 if (NILP (attributes_list
))
4184 attributes_list
= x_get_monitor_attributes_fallback (dpyinfo
);
4186 return attributes_list
;
4189 #endif /* !USE_GTK */
4191 DEFUN ("x-display-monitor-attributes-list", Fx_display_monitor_attributes_list
,
4192 Sx_display_monitor_attributes_list
,
4194 doc
: /* Return a list of physical monitor attributes on the X display TERMINAL.
4196 The optional argument TERMINAL specifies which display to ask about.
4197 TERMINAL should be a terminal object, a frame or a display name (a string).
4198 If omitted or nil, that stands for the selected frame's display.
4200 In addition to the standard attribute keys listed in
4201 `display-monitor-attributes-list', the following keys are contained in
4204 source -- String describing the source from which multi-monitor
4205 information is obtained, one of \"Gdk\", \"XRandr\",
4206 \"Xinerama\", or \"fallback\"
4208 Internal use only, use `display-monitor-attributes-list' instead. */)
4209 (Lisp_Object terminal
)
4211 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4212 Lisp_Object attributes_list
= Qnil
;
4215 double mm_width_per_pixel
, mm_height_per_pixel
;
4218 gint primary_monitor
= 0, n_monitors
, i
;
4219 Lisp_Object monitor_frames
, rest
, frame
;
4220 static const char *source
= "Gdk";
4221 struct MonitorInfo
*monitors
;
4224 mm_width_per_pixel
= ((double) WidthMMOfScreen (dpyinfo
->screen
)
4225 / x_display_pixel_width (dpyinfo
));
4226 mm_height_per_pixel
= ((double) HeightMMOfScreen (dpyinfo
->screen
)
4227 / x_display_pixel_height (dpyinfo
));
4228 gdpy
= gdk_x11_lookup_xdisplay (dpyinfo
->display
);
4229 gscreen
= gdk_display_get_default_screen (gdpy
);
4230 #if GTK_CHECK_VERSION (2, 20, 0)
4231 primary_monitor
= gdk_screen_get_primary_monitor (gscreen
);
4233 n_monitors
= gdk_screen_get_n_monitors (gscreen
);
4234 monitor_frames
= Fmake_vector (make_number (n_monitors
), Qnil
);
4235 monitors
= xzalloc (n_monitors
* sizeof *monitors
);
4237 FOR_EACH_FRAME (rest
, frame
)
4239 struct frame
*f
= XFRAME (frame
);
4241 if (FRAME_X_P (f
) && FRAME_DISPLAY_INFO (f
) == dpyinfo
4242 && !EQ (frame
, tip_frame
))
4244 GdkWindow
*gwin
= gtk_widget_get_window (FRAME_GTK_WIDGET (f
));
4246 i
= gdk_screen_get_monitor_at_window (gscreen
, gwin
);
4247 ASET (monitor_frames
, i
, Fcons (frame
, AREF (monitor_frames
, i
)));
4251 for (i
= 0; i
< n_monitors
; ++i
)
4253 gint width_mm
= -1, height_mm
= -1;
4254 GdkRectangle rec
, work
;
4255 struct MonitorInfo
*mi
= &monitors
[i
];
4257 gdk_screen_get_monitor_geometry (gscreen
, i
, &rec
);
4259 #if GTK_CHECK_VERSION (2, 14, 0)
4260 width_mm
= gdk_screen_get_monitor_width_mm (gscreen
, i
);
4261 height_mm
= gdk_screen_get_monitor_height_mm (gscreen
, i
);
4264 width_mm
= rec
.width
* mm_width_per_pixel
+ 0.5;
4266 height_mm
= rec
.height
* mm_height_per_pixel
+ 0.5;
4268 #if GTK_CHECK_VERSION (3, 4, 0)
4269 gdk_screen_get_monitor_workarea (gscreen
, i
, &work
);
4271 /* Emulate the behavior of GTK+ 3.4. */
4273 XRectangle workarea_r
;
4275 if (i
== primary_monitor
&& x_get_net_workarea (dpyinfo
, &workarea_r
))
4277 work
.x
= workarea_r
.x
;
4278 work
.y
= workarea_r
.y
;
4279 work
.width
= workarea_r
.width
;
4280 work
.height
= workarea_r
.height
;
4281 if (! gdk_rectangle_intersect (&rec
, &work
, &work
))
4292 mi
->geom
.width
= rec
.width
;
4293 mi
->geom
.height
= rec
.height
;
4294 mi
->work
.x
= work
.x
;
4295 mi
->work
.y
= work
.y
;
4296 mi
->work
.width
= work
.width
;
4297 mi
->work
.height
= work
.height
;
4298 mi
->mm_width
= width_mm
;
4299 mi
->mm_height
= height_mm
;
4301 #if GTK_CHECK_VERSION (2, 14, 0)
4302 mi
->name
= gdk_screen_get_monitor_plug_name (gscreen
, i
);
4306 attributes_list
= make_monitor_attribute_list (monitors
,
4312 #else /* not USE_GTK */
4315 attributes_list
= x_get_monitor_attributes (dpyinfo
);
4318 #endif /* not USE_GTK */
4320 return attributes_list
;
4323 /* Return geometric attributes of FRAME. According to the value of
4324 ATTRIBUTES return the outer edges of FRAME (Qouter_edges), the native
4325 edges of FRAME (Qnative_edges), or the inner edges of frame
4326 (Qinner_edges). Any other value means to return the geometry as
4327 returned by Fx_frame_geometry. */
4329 frame_geometry (Lisp_Object frame
, Lisp_Object attribute
)
4331 struct frame
*f
= decode_live_frame (frame
);
4332 /** XWindowAttributes atts; **/
4334 unsigned int ign
, native_width
, native_height
;
4335 int xy_ign
, xptr
, yptr
;
4336 int left_off
, right_off
, top_off
, bottom_off
;
4337 int outer_left
, outer_top
, outer_right
, outer_bottom
;
4338 int native_left
, native_top
, native_right
, native_bottom
;
4339 int inner_left
, inner_top
, inner_right
, inner_bottom
;
4340 int internal_border_width
;
4341 bool menu_bar_external
= false, tool_bar_external
= false;
4342 int menu_bar_height
= 0, menu_bar_width
= 0;
4343 int tool_bar_height
= 0, tool_bar_width
= 0;
4345 if (FRAME_INITIAL_P (f
) || !FRAME_X_P (f
))
4349 XGetGeometry (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
4350 &rootw
, &xy_ign
, &xy_ign
, &native_width
, &native_height
,
4352 /** XGetWindowAttributes (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &atts); **/
4353 x_real_pos_and_offsets (f
, &left_off
, &right_off
, &top_off
, &bottom_off
,
4354 NULL
, NULL
, &xptr
, &yptr
, NULL
);
4357 /** native_width = atts.width; **/
4358 /** native_height = atts.height; **/
4362 outer_right
= outer_left
+ left_off
+ native_width
+ right_off
;
4363 outer_bottom
= outer_top
+ top_off
+ native_height
+ bottom_off
;
4365 native_left
= outer_left
+ left_off
;
4366 native_top
= outer_top
+ top_off
;
4367 native_right
= native_left
+ native_width
;
4368 native_bottom
= native_top
+ native_height
;
4370 internal_border_width
= FRAME_INTERNAL_BORDER_WIDTH (f
);
4371 inner_left
= native_left
+ internal_border_width
;
4372 inner_top
= native_top
+ internal_border_width
;
4373 inner_right
= native_right
- internal_border_width
;
4374 inner_bottom
= native_bottom
- internal_border_width
;
4376 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
4377 menu_bar_external
= true;
4378 menu_bar_height
= FRAME_MENUBAR_HEIGHT (f
);
4379 native_top
+= menu_bar_height
;
4380 inner_top
+= menu_bar_height
;
4382 menu_bar_height
= FRAME_MENU_BAR_HEIGHT (f
);
4383 inner_top
+= menu_bar_height
;
4385 menu_bar_width
= menu_bar_height
? native_width
: 0;
4387 #if defined (USE_GTK)
4388 tool_bar_external
= true;
4389 if (EQ (FRAME_TOOL_BAR_POSITION (f
), Qleft
))
4391 tool_bar_width
= FRAME_TOOLBAR_WIDTH (f
);
4392 native_left
+= tool_bar_width
;
4393 inner_left
+= tool_bar_width
;
4395 = tool_bar_width
? native_height
- menu_bar_height
: 0;
4397 else if (EQ (FRAME_TOOL_BAR_POSITION (f
), Qtop
))
4399 tool_bar_height
= FRAME_TOOLBAR_HEIGHT (f
);
4400 native_top
+= tool_bar_height
;
4401 inner_top
+= tool_bar_height
;
4402 tool_bar_width
= tool_bar_height
? native_width
: 0;
4404 else if (EQ (FRAME_TOOL_BAR_POSITION (f
), Qright
))
4406 tool_bar_width
= FRAME_TOOLBAR_WIDTH (f
);
4407 native_right
-= tool_bar_width
;
4408 inner_right
-= tool_bar_width
;
4410 = tool_bar_width
? native_height
- menu_bar_height
: 0;
4414 tool_bar_height
= FRAME_TOOLBAR_HEIGHT (f
);
4415 native_bottom
-= tool_bar_height
;
4416 inner_bottom
-= tool_bar_height
;
4417 tool_bar_width
= tool_bar_height
? native_width
: 0;
4420 tool_bar_height
= FRAME_TOOL_BAR_HEIGHT (f
);
4421 tool_bar_width
= tool_bar_height
? native_width
: 0;
4422 inner_top
+= tool_bar_height
;
4425 /* Construct list. */
4426 if (EQ (attribute
, Qouter_edges
))
4427 return list4 (make_number (outer_left
), make_number (outer_top
),
4428 make_number (outer_right
), make_number (outer_bottom
));
4429 else if (EQ (attribute
, Qnative_edges
))
4430 return list4 (make_number (native_left
), make_number (native_top
),
4431 make_number (native_right
), make_number (native_bottom
));
4432 else if (EQ (attribute
, Qinner_edges
))
4433 return list4 (make_number (inner_left
), make_number (inner_top
),
4434 make_number (inner_right
), make_number (inner_bottom
));
4437 listn (CONSTYPE_HEAP
, 10,
4438 Fcons (Qouter_position
,
4439 Fcons (make_number (outer_left
),
4440 make_number (outer_top
))),
4442 Fcons (make_number (outer_right
- outer_left
),
4443 make_number (outer_bottom
- outer_top
))),
4445 Fcons (Qexternal_border_size
,
4446 Fcons (make_number (right_off
),
4447 make_number (bottom_off
))),
4449 Fcons (Qtitle_bar_size
,
4450 Fcons (make_number (0),
4451 make_number (top_off
- bottom_off
))),
4452 Fcons (Qmenu_bar_external
, menu_bar_external
? Qt
: Qnil
),
4453 Fcons (Qmenu_bar_size
,
4454 Fcons (make_number (menu_bar_width
),
4455 make_number (menu_bar_height
))),
4456 Fcons (Qtool_bar_external
, tool_bar_external
? Qt
: Qnil
),
4457 Fcons (Qtool_bar_position
, FRAME_TOOL_BAR_POSITION (f
)),
4458 Fcons (Qtool_bar_size
,
4459 Fcons (make_number (tool_bar_width
),
4460 make_number (tool_bar_height
))),
4461 Fcons (Qinternal_border_width
,
4462 make_number (internal_border_width
)));
4465 DEFUN ("x-frame-geometry", Fx_frame_geometry
, Sx_frame_geometry
, 0, 1, 0,
4466 doc
: /* Return geometric attributes of FRAME.
4467 FRAME must be a live frame and defaults to the selected one. The return
4468 value is an association list of the attributes listed below. All height
4469 and width values are in pixels.
4471 `outer-position' is a cons of the outer left and top edges of FRAME
4472 relative to the origin - the position (0, 0) - of FRAME's display.
4474 `outer-size' is a cons of the outer width and height of FRAME. The
4475 outer size includes the title bar and the external borders as well as
4476 any menu and/or tool bar of frame.
4478 `external-border-size' is a cons of the horizontal and vertical width of
4479 FRAME's external borders as supplied by the window manager.
4481 `title-bar-size' is a cons of the width and height of the title bar of
4482 FRAME as supplied by the window manager. If both of them are zero,
4483 FRAME has no title bar. If only the width is zero, Emacs was not
4484 able to retrieve the width information.
4486 `menu-bar-external', if non-nil, means the menu bar is external (never
4487 included in the inner edges of FRAME).
4489 `menu-bar-size' is a cons of the width and height of the menu bar of
4492 `tool-bar-external', if non-nil, means the tool bar is external (never
4493 included in the inner edges of FRAME).
4495 `tool-bar-position' tells on which side the tool bar on FRAME is and can
4496 be one of `left', `top', `right' or `bottom'. If this is nil, FRAME
4499 `tool-bar-size' is a cons of the width and height of the tool bar of
4502 `internal-border-width' is the width of the internal border of
4506 return frame_geometry (frame
, Qnil
);
4509 DEFUN ("x-frame-edges", Fx_frame_edges
, Sx_frame_edges
, 0, 2, 0,
4510 doc
: /* Return edge coordinates of FRAME.
4511 FRAME must be a live frame and defaults to the selected one. The return
4512 value is a list of the form (LEFT, TOP, RIGHT, BOTTOM). All values are
4513 in pixels relative to the origin - the position (0, 0) - of FRAME's
4516 If optional argument TYPE is the symbol `outer-edges', return the outer
4517 edges of FRAME. The outer edges comprise the decorations of the window
4518 manager (like the title bar or external borders) as well as any external
4519 menu or tool bar of FRAME. If optional argument TYPE is the symbol
4520 `native-edges' or nil, return the native edges of FRAME. The native
4521 edges exclude the decorations of the window manager and any external
4522 menu or tool bar of FRAME. If TYPE is the symbol `inner-edges', return
4523 the inner edges of FRAME. These edges exclude title bar, any borders,
4524 menu bar or tool bar of FRAME. */)
4525 (Lisp_Object frame
, Lisp_Object type
)
4527 return frame_geometry (frame
, ((EQ (type
, Qouter_edges
)
4528 || EQ (type
, Qinner_edges
))
4533 DEFUN ("x-mouse-absolute-pixel-position", Fx_mouse_absolute_pixel_position
,
4534 Sx_mouse_absolute_pixel_position
, 0, 0, 0,
4535 doc
: /* Return absolute position of mouse cursor in pixels.
4536 The position is returned as a cons cell (X . Y) of the coordinates of
4537 the mouse cursor position in pixels relative to a position (0, 0) of the
4538 selected frame's display. */)
4541 struct frame
*f
= SELECTED_FRAME ();
4542 Window root
, dummy_window
;
4545 if (FRAME_INITIAL_P (f
) || !FRAME_X_P (f
))
4549 XQueryPointer (FRAME_X_DISPLAY (f
),
4550 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
4551 &root
, &dummy_window
, &x
, &y
, &dummy
, &dummy
,
4552 (unsigned int *) &dummy
);
4555 return Fcons (make_number (x
), make_number (y
));
4558 DEFUN ("x-set-mouse-absolute-pixel-position", Fx_set_mouse_absolute_pixel_position
,
4559 Sx_set_mouse_absolute_pixel_position
, 2, 2, 0,
4560 doc
: /* Move mouse pointer to absolute pixel position (X, Y).
4561 The coordinates X and Y are interpreted in pixels relative to a position
4562 (0, 0) of the selected frame's display. */)
4563 (Lisp_Object x
, Lisp_Object y
)
4565 struct frame
*f
= SELECTED_FRAME ();
4567 if (FRAME_INITIAL_P (f
) || !FRAME_X_P (f
))
4570 CHECK_TYPE_RANGED_INTEGER (int, x
);
4571 CHECK_TYPE_RANGED_INTEGER (int, y
);
4574 XWarpPointer (FRAME_X_DISPLAY (f
), None
, DefaultRootWindow (FRAME_X_DISPLAY (f
)),
4575 0, 0, 0, 0, XINT (x
), XINT (y
));
4581 /************************************************************************
4583 ************************************************************************/
4586 /* Mapping visual names to visuals. */
4588 static struct visual_class
4595 {"StaticGray", StaticGray
},
4596 {"GrayScale", GrayScale
},
4597 {"StaticColor", StaticColor
},
4598 {"PseudoColor", PseudoColor
},
4599 {"TrueColor", TrueColor
},
4600 {"DirectColor", DirectColor
},
4605 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4607 /* Value is the screen number of screen SCR. This is a substitute for
4608 the X function with the same name when that doesn't exist. */
4611 XScreenNumberOfScreen (scr
)
4612 register Screen
*scr
;
4614 Display
*dpy
= scr
->display
;
4617 for (i
= 0; i
< dpy
->nscreens
; ++i
)
4618 if (scr
== dpy
->screens
+ i
)
4624 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4627 /* Select the visual that should be used on display DPYINFO. Set
4628 members of DPYINFO appropriately. Called from x_term_init. */
4631 select_visual (struct x_display_info
*dpyinfo
)
4633 Display
*dpy
= dpyinfo
->display
;
4634 Screen
*screen
= dpyinfo
->screen
;
4636 /* See if a visual is specified. */
4637 AUTO_STRING (visualClass
, "visualClass");
4638 AUTO_STRING (VisualClass
, "VisualClass");
4639 Lisp_Object value
= display_x_get_resource (dpyinfo
, visualClass
,
4640 VisualClass
, Qnil
, Qnil
);
4642 if (STRINGP (value
))
4644 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
4645 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
4646 depth, a decimal number. NAME is compared with case ignored. */
4647 char *s
= alloca (SBYTES (value
) + 1);
4652 lispstpcpy (s
, value
);
4653 dash
= strchr (s
, '-');
4656 dpyinfo
->n_planes
= atoi (dash
+ 1);
4660 /* We won't find a matching visual with depth 0, so that
4661 an error will be printed below. */
4662 dpyinfo
->n_planes
= 0;
4664 /* Determine the visual class. */
4665 for (i
= 0; visual_classes
[i
].name
; ++i
)
4666 if (xstrcasecmp (s
, visual_classes
[i
].name
) == 0)
4668 class = visual_classes
[i
].class;
4672 /* Look up a matching visual for the specified class. */
4674 || !XMatchVisualInfo (dpy
, XScreenNumberOfScreen (screen
),
4675 dpyinfo
->n_planes
, class, &vinfo
))
4676 fatal ("Invalid visual specification '%s'",
4677 SSDATA (ENCODE_SYSTEM (value
)));
4679 dpyinfo
->visual
= vinfo
.visual
;
4684 XVisualInfo
*vinfo
, vinfo_template
;
4686 dpyinfo
->visual
= DefaultVisualOfScreen (screen
);
4688 vinfo_template
.visualid
= XVisualIDFromVisual (dpyinfo
->visual
);
4689 vinfo_template
.screen
= XScreenNumberOfScreen (screen
);
4690 vinfo
= XGetVisualInfo (dpy
, VisualIDMask
| VisualScreenMask
,
4691 &vinfo_template
, &n_visuals
);
4693 fatal ("Can't get proper X visual info");
4695 dpyinfo
->n_planes
= vinfo
->depth
;
4701 /* Return the X display structure for the display named NAME.
4702 Open a new connection if necessary. */
4704 static struct x_display_info
*
4705 x_display_info_for_name (Lisp_Object name
)
4707 struct x_display_info
*dpyinfo
;
4709 CHECK_STRING (name
);
4711 for (dpyinfo
= x_display_list
; dpyinfo
; dpyinfo
= dpyinfo
->next
)
4712 if (!NILP (Fstring_equal (XCAR (dpyinfo
->name_list_element
), name
)))
4715 /* Use this general default value to start with. */
4716 Vx_resource_name
= Vinvocation_name
;
4718 validate_x_resource_name ();
4720 dpyinfo
= x_term_init (name
, 0, SSDATA (Vx_resource_name
));
4723 error ("Cannot connect to X server %s", SDATA (name
));
4725 XSETFASTINT (Vwindow_system_version
, 11);
4731 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
4733 doc
: /* Open a connection to a display server.
4734 DISPLAY is the name of the display to connect to.
4735 Optional second arg XRM-STRING is a string of resources in xrdb format.
4736 If the optional third arg MUST-SUCCEED is non-nil,
4737 terminate Emacs if we can't open the connection.
4738 (In the Nextstep version, the last two arguments are currently ignored.) */)
4739 (Lisp_Object display
, Lisp_Object xrm_string
, Lisp_Object must_succeed
)
4742 struct x_display_info
*dpyinfo
;
4744 CHECK_STRING (display
);
4745 if (! NILP (xrm_string
))
4746 CHECK_STRING (xrm_string
);
4748 xrm_option
= NILP (xrm_string
) ? 0 : SSDATA (xrm_string
);
4750 validate_x_resource_name ();
4752 /* This is what opens the connection and sets x_current_display.
4753 This also initializes many symbols, such as those used for input. */
4754 dpyinfo
= x_term_init (display
, xrm_option
,
4755 SSDATA (Vx_resource_name
));
4759 if (!NILP (must_succeed
))
4760 fatal ("Cannot connect to X server %s.\n\
4761 Check the DISPLAY environment variable or use `-d'.\n\
4762 Also use the `xauth' program to verify that you have the proper\n\
4763 authorization information needed to connect the X server.\n\
4764 An insecure way to solve the problem may be to use `xhost'.\n",
4767 error ("Cannot connect to X server %s", SDATA (display
));
4770 XSETFASTINT (Vwindow_system_version
, 11);
4774 DEFUN ("x-close-connection", Fx_close_connection
,
4775 Sx_close_connection
, 1, 1, 0,
4776 doc
: /* Close the connection to TERMINAL's X server.
4777 For TERMINAL, specify a terminal object, a frame or a display name (a
4778 string). If TERMINAL is nil, that stands for the selected frame's
4780 (Lisp_Object terminal
)
4782 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4784 if (dpyinfo
->reference_count
> 0)
4785 error ("Display still has frames on it");
4787 x_delete_terminal (dpyinfo
->terminal
);
4792 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
4793 doc
: /* Return the list of display names that Emacs has connections to. */)
4796 Lisp_Object result
= Qnil
;
4797 struct x_display_info
*xdi
;
4799 for (xdi
= x_display_list
; xdi
; xdi
= xdi
->next
)
4800 result
= Fcons (XCAR (xdi
->name_list_element
), result
);
4805 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
4806 doc
: /* If ON is non-nil, report X errors as soon as the erring request is made.
4807 This function only has an effect on X Windows. With MS Windows, it is
4808 defined but does nothing.
4810 If ON is nil, allow buffering of requests.
4811 Turning on synchronization prohibits the Xlib routines from buffering
4812 requests and seriously degrades performance, but makes debugging much
4814 The optional second argument TERMINAL specifies which display to act on.
4815 TERMINAL should be a terminal object, a frame or a display name (a string).
4816 If TERMINAL is omitted or nil, that stands for the selected frame's display. */)
4817 (Lisp_Object on
, Lisp_Object terminal
)
4819 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4821 XSynchronize (dpyinfo
->display
, !EQ (on
, Qnil
));
4826 /* Wait for responses to all X commands issued so far for frame F. */
4829 x_sync (struct frame
*f
)
4832 XSync (FRAME_X_DISPLAY (f
), False
);
4837 /***********************************************************************
4839 ***********************************************************************/
4841 DEFUN ("x-change-window-property", Fx_change_window_property
,
4842 Sx_change_window_property
, 2, 6, 0,
4843 doc
: /* Change window property PROP to VALUE on the X window of FRAME.
4844 PROP must be a string. VALUE may be a string or a list of conses,
4845 numbers and/or strings. If an element in the list is a string, it is
4846 converted to an atom and the value of the atom is used. If an element
4847 is a cons, it is converted to a 32 bit number where the car is the 16
4848 top bits and the cdr is the lower 16 bits.
4850 FRAME nil or omitted means use the selected frame.
4851 If TYPE is given and non-nil, it is the name of the type of VALUE.
4852 If TYPE is not given or nil, the type is STRING.
4853 FORMAT gives the size in bits of each element if VALUE is a list.
4854 It must be one of 8, 16 or 32.
4855 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
4856 If OUTER-P is non-nil, the property is changed for the outer X window of
4857 FRAME. Default is to change on the edit X window. */)
4858 (Lisp_Object prop
, Lisp_Object value
, Lisp_Object frame
,
4859 Lisp_Object type
, Lisp_Object format
, Lisp_Object outer_p
)
4861 struct frame
*f
= decode_window_system_frame (frame
);
4863 Atom target_type
= XA_STRING
;
4864 int element_format
= 8;
4865 unsigned char *data
;
4869 CHECK_STRING (prop
);
4871 if (! NILP (format
))
4873 CHECK_NUMBER (format
);
4875 if (XINT (format
) != 8 && XINT (format
) != 16
4876 && XINT (format
) != 32)
4877 error ("FORMAT must be one of 8, 16 or 32");
4878 element_format
= XINT (format
);
4885 nelements
= x_check_property_data (value
);
4886 if (nelements
== -1)
4887 error ("Bad data in VALUE, must be number, string or cons");
4889 /* The man page for XChangeProperty:
4890 "If the specified format is 32, the property data must be a
4892 This applies even if long is more than 32 bits. The X library
4893 converts to 32 bits before sending to the X server. */
4894 elsize
= element_format
== 32 ? sizeof (long) : element_format
>> 3;
4895 data
= xnmalloc (nelements
, elsize
);
4897 x_fill_property_data (FRAME_X_DISPLAY (f
), value
, data
, element_format
);
4901 CHECK_STRING (value
);
4902 data
= SDATA (value
);
4903 if (INT_MAX
< SBYTES (value
))
4904 error ("VALUE too long");
4905 nelements
= SBYTES (value
);
4909 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (prop
), False
);
4912 CHECK_STRING (type
);
4913 target_type
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (type
), False
);
4916 if (! NILP (outer_p
)) w
= FRAME_OUTER_WINDOW (f
);
4917 else w
= FRAME_X_WINDOW (f
);
4919 XChangeProperty (FRAME_X_DISPLAY (f
), w
,
4920 prop_atom
, target_type
, element_format
, PropModeReplace
,
4923 if (CONSP (value
)) xfree (data
);
4925 /* Make sure the property is set when we return. */
4926 XFlush (FRAME_X_DISPLAY (f
));
4933 DEFUN ("x-delete-window-property", Fx_delete_window_property
,
4934 Sx_delete_window_property
, 1, 2, 0,
4935 doc
: /* Remove window property PROP from X window of FRAME.
4936 FRAME nil or omitted means use the selected frame. Value is PROP. */)
4937 (Lisp_Object prop
, Lisp_Object frame
)
4939 struct frame
*f
= decode_window_system_frame (frame
);
4942 CHECK_STRING (prop
);
4944 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (prop
), False
);
4945 XDeleteProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), prop_atom
);
4947 /* Make sure the property is removed when we return. */
4948 XFlush (FRAME_X_DISPLAY (f
));
4956 x_window_property_intern (struct frame
*f
,
4957 Window target_window
,
4960 Lisp_Object delete_p
,
4961 Lisp_Object vector_ret_p
,
4964 unsigned char *tmp_data
= NULL
;
4965 Lisp_Object prop_value
= Qnil
;
4968 unsigned long actual_size
, bytes_remaining
;
4971 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), target_window
,
4972 prop_atom
, 0, 0, False
, target_type
,
4973 &actual_type
, &actual_format
, &actual_size
,
4974 &bytes_remaining
, &tmp_data
);
4976 *found
= actual_format
!= 0;
4978 if (rc
== Success
&& *found
)
4983 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), target_window
,
4984 prop_atom
, 0, bytes_remaining
,
4985 ! NILP (delete_p
), target_type
,
4986 &actual_type
, &actual_format
,
4987 &actual_size
, &bytes_remaining
,
4989 if (rc
== Success
&& tmp_data
)
4991 /* The man page for XGetWindowProperty says:
4992 "If the returned format is 32, the returned data is represented
4993 as a long array and should be cast to that type to obtain the
4995 This applies even if long is more than 32 bits, the X library
4996 converts from 32 bit elements received from the X server to long
4997 and passes the long array to us. Thus, for that case memcpy can not
4998 be used. We convert to a 32 bit type here, because so much code
5001 The bytes and offsets passed to XGetWindowProperty refers to the
5002 property and those are indeed in 32 bit quantities if format is
5005 if (BITS_PER_LONG
> 32 && actual_format
== 32)
5008 int *idata
= (int *) tmp_data
;
5009 long *ldata
= (long *) tmp_data
;
5011 for (i
= 0; i
< actual_size
; ++i
)
5012 idata
[i
] = (int) ldata
[i
];
5015 if (NILP (vector_ret_p
))
5016 prop_value
= make_string ((char *) tmp_data
, actual_size
);
5018 prop_value
= x_property_data_to_lisp (f
,
5025 if (tmp_data
) XFree (tmp_data
);
5031 DEFUN ("x-window-property", Fx_window_property
, Sx_window_property
,
5033 doc
: /* Value is the value of window property PROP on FRAME.
5034 If FRAME is nil or omitted, use the selected frame.
5036 On X Windows, the following optional arguments are also accepted:
5037 If TYPE is nil or omitted, get the property as a string.
5038 Otherwise TYPE is the name of the atom that denotes the type expected.
5039 If SOURCE is non-nil, get the property on that window instead of from
5040 FRAME. The number 0 denotes the root window.
5041 If DELETE-P is non-nil, delete the property after retrieving it.
5042 If VECTOR-RET-P is non-nil, don't return a string but a vector of values.
5044 On MS Windows, this function accepts but ignores those optional arguments.
5046 Value is nil if FRAME hasn't a property with name PROP or if PROP has
5047 no value of TYPE (always string in the MS Windows case). */)
5048 (Lisp_Object prop
, Lisp_Object frame
, Lisp_Object type
,
5049 Lisp_Object source
, Lisp_Object delete_p
, Lisp_Object vector_ret_p
)
5051 struct frame
*f
= decode_window_system_frame (frame
);
5053 Lisp_Object prop_value
= Qnil
;
5054 Atom target_type
= XA_STRING
;
5055 Window target_window
= FRAME_X_WINDOW (f
);
5058 CHECK_STRING (prop
);
5060 if (! NILP (source
))
5062 CONS_TO_INTEGER (source
, Window
, target_window
);
5063 if (! target_window
)
5064 target_window
= FRAME_DISPLAY_INFO (f
)->root_window
;
5070 if (strcmp ("AnyPropertyType", SSDATA (type
)) == 0)
5071 target_type
= AnyPropertyType
;
5073 target_type
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (type
), False
);
5076 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (prop
), False
);
5077 prop_value
= x_window_property_intern (f
,
5084 if (NILP (prop_value
)
5087 && target_window
!= FRAME_OUTER_WINDOW (f
))
5089 prop_value
= x_window_property_intern (f
,
5090 FRAME_OUTER_WINDOW (f
),
5103 /***********************************************************************
5105 ***********************************************************************/
5107 static Lisp_Object
x_create_tip_frame (struct x_display_info
*,
5108 Lisp_Object
, Lisp_Object
);
5109 static void compute_tip_xy (struct frame
*, Lisp_Object
, Lisp_Object
,
5110 Lisp_Object
, int, int, int *, int *);
5112 /* The frame of a currently visible tooltip. */
5114 Lisp_Object tip_frame
;
5116 /* If non-nil, a timer started that hides the last tooltip when it
5119 static Lisp_Object tip_timer
;
5122 /* If non-nil, a vector of 3 elements containing the last args
5123 with which x-show-tip was called. See there. */
5125 static Lisp_Object last_show_tip_args
;
5129 unwind_create_tip_frame (Lisp_Object frame
)
5131 Lisp_Object deleted
;
5133 deleted
= unwind_create_frame (frame
);
5134 if (EQ (deleted
, Qt
))
5142 /* Create a frame for a tooltip on the display described by DPYINFO.
5143 PARMS is a list of frame parameters. TEXT is the string to
5144 display in the tip frame. Value is the frame.
5146 Note that functions called here, esp. x_default_parameter can
5147 signal errors, for instance when a specified color name is
5148 undefined. We have to make sure that we're in a consistent state
5149 when this happens. */
5152 x_create_tip_frame (struct x_display_info
*dpyinfo
,
5160 ptrdiff_t count
= SPECPDL_INDEX ();
5161 bool face_change_before
= face_change
;
5163 struct buffer
*old_buffer
;
5165 if (!dpyinfo
->terminal
->name
)
5166 error ("Terminal is not live, can't create new frames on it");
5168 parms
= Fcopy_alist (parms
);
5170 /* Get the name of the frame to use for resource lookup. */
5171 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
5173 && !EQ (name
, Qunbound
)
5175 error ("Invalid frame name--not a string or nil");
5178 f
= make_frame (true);
5179 XSETFRAME (frame
, f
);
5181 AUTO_STRING (tip
, " *tip*");
5182 buffer
= Fget_buffer_create (tip
);
5183 /* Use set_window_buffer instead of Fset_window_buffer (see
5184 discussion of bug#11984, bug#12025, bug#12026). */
5185 set_window_buffer (FRAME_ROOT_WINDOW (f
), buffer
, false, false);
5186 old_buffer
= current_buffer
;
5187 set_buffer_internal_1 (XBUFFER (buffer
));
5188 bset_truncate_lines (current_buffer
, Qnil
);
5189 specbind (Qinhibit_read_only
, Qt
);
5190 specbind (Qinhibit_modification_hooks
, Qt
);
5193 set_buffer_internal_1 (old_buffer
);
5195 record_unwind_protect (unwind_create_tip_frame
, frame
);
5197 f
->terminal
= dpyinfo
->terminal
;
5199 /* By setting the output method, we're essentially saying that
5200 the frame is live, as per FRAME_LIVE_P. If we get a signal
5201 from this point on, x_destroy_window might screw up reference
5203 f
->output_method
= output_x_window
;
5204 f
->output_data
.x
= xzalloc (sizeof *f
->output_data
.x
);
5205 f
->output_data
.x
->icon_bitmap
= -1;
5206 FRAME_FONTSET (f
) = -1;
5207 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
5208 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
5209 #if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
5210 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
5211 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
5212 #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
5213 f
->output_data
.x
->white_relief
.pixel
= -1;
5214 f
->output_data
.x
->black_relief
.pixel
= -1;
5216 fset_icon_name (f
, Qnil
);
5217 FRAME_DISPLAY_INFO (f
) = dpyinfo
;
5218 f
->output_data
.x
->parent_desc
= FRAME_DISPLAY_INFO (f
)->root_window
;
5219 f
->output_data
.x
->explicit_parent
= false;
5221 /* These colors will be set anyway later, but it's important
5222 to get the color reference counts right, so initialize them! */
5226 /* Function x_decode_color can signal an error. Make
5227 sure to initialize color slots so that we won't try
5228 to free colors we haven't allocated. */
5229 FRAME_FOREGROUND_PIXEL (f
) = -1;
5230 FRAME_BACKGROUND_PIXEL (f
) = -1;
5231 f
->output_data
.x
->cursor_pixel
= -1;
5232 f
->output_data
.x
->cursor_foreground_pixel
= -1;
5233 f
->output_data
.x
->border_pixel
= -1;
5234 f
->output_data
.x
->mouse_pixel
= -1;
5236 black
= build_string ("black");
5237 FRAME_FOREGROUND_PIXEL (f
)
5238 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
5239 FRAME_BACKGROUND_PIXEL (f
)
5240 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
5241 f
->output_data
.x
->cursor_pixel
5242 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
5243 f
->output_data
.x
->cursor_foreground_pixel
5244 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
5245 f
->output_data
.x
->border_pixel
5246 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
5247 f
->output_data
.x
->mouse_pixel
5248 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
5251 /* Set the name; the functions to which we pass f expect the name to
5253 if (EQ (name
, Qunbound
) || NILP (name
))
5255 fset_name (f
, build_string (dpyinfo
->x_id_name
));
5256 f
->explicit_name
= false;
5260 fset_name (f
, name
);
5261 f
->explicit_name
= true;
5262 /* use the frame's title when getting resources for this frame. */
5263 specbind (Qx_resource_name
, name
);
5267 register_font_driver (&ftcrfont_driver
, f
);
5269 register_font_driver (&xfont_driver
, f
);
5270 #ifdef HAVE_FREETYPE
5272 register_font_driver (&xftfont_driver
, f
);
5273 #else /* not HAVE_XFT */
5274 register_font_driver (&ftxfont_driver
, f
);
5275 #endif /* not HAVE_XFT */
5276 #endif /* HAVE_FREETYPE */
5277 #endif /* not USE_CAIRO */
5279 image_cache_refcount
=
5280 FRAME_IMAGE_CACHE (f
) ? FRAME_IMAGE_CACHE (f
)->refcount
: 0;
5282 dpyinfo_refcount
= dpyinfo
->reference_count
;
5283 #endif /* GLYPH_DEBUG */
5285 x_default_parameter (f
, parms
, Qfont_backend
, Qnil
,
5286 "fontBackend", "FontBackend", RES_TYPE_STRING
);
5288 /* Extract the window parameters from the supplied values that are
5289 needed to determine window geometry. */
5290 x_default_font_parameter (f
, parms
);
5292 x_default_parameter (f
, parms
, Qborder_width
, make_number (0),
5293 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
5295 /* This defaults to 2 in order to match xterm. We recognize either
5296 internalBorderWidth or internalBorder (which is what xterm calls
5298 if (NILP (Fassq (Qinternal_border_width
, parms
)))
5302 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
5303 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
5304 if (! EQ (value
, Qunbound
))
5305 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
5309 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
5310 "internalBorderWidth", "internalBorderWidth",
5312 x_default_parameter (f
, parms
, Qright_divider_width
, make_number (0),
5313 NULL
, NULL
, RES_TYPE_NUMBER
);
5314 x_default_parameter (f
, parms
, Qbottom_divider_width
, make_number (0),
5315 NULL
, NULL
, RES_TYPE_NUMBER
);
5317 /* Also do the stuff which must be set before the window exists. */
5318 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
5319 "foreground", "Foreground", RES_TYPE_STRING
);
5320 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
5321 "background", "Background", RES_TYPE_STRING
);
5322 #if 0 /* This code currently doesn't work for tooltip frames; the
5323 cursor being set doesn't seem to get used. The call generates
5324 a bit of traffic, so skip it for now. */
5325 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
5326 "pointerColor", "Foreground", RES_TYPE_STRING
);
5328 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
5329 "cursorColor", "Foreground", RES_TYPE_STRING
);
5330 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
5331 "borderColor", "BorderColor", RES_TYPE_STRING
);
5333 /* Init faces before x_default_parameter is called for the
5334 scroll-bar-width parameter because otherwise we end up in
5335 init_iterator with a null face cache, which should not happen. */
5336 init_frame_faces (f
);
5338 f
->output_data
.x
->parent_desc
= FRAME_DISPLAY_INFO (f
)->root_window
;
5340 x_figure_window_size (f
, parms
, false);
5343 XSetWindowAttributes attrs
;
5345 Atom type
= FRAME_DISPLAY_INFO (f
)->Xatom_net_window_type_tooltip
;
5348 mask
= CWBackPixel
| CWOverrideRedirect
| CWEventMask
;
5349 if (DoesSaveUnders (dpyinfo
->screen
))
5350 mask
|= CWSaveUnder
;
5352 /* Window managers look at the override-redirect flag to determine
5353 whether or net to give windows a decoration (Xlib spec, chapter
5355 attrs
.override_redirect
= True
;
5356 attrs
.save_under
= True
;
5357 attrs
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
5358 /* Arrange for getting MapNotify and UnmapNotify events. */
5359 attrs
.event_mask
= StructureNotifyMask
;
5361 = FRAME_X_WINDOW (f
)
5362 = XCreateWindow (FRAME_X_DISPLAY (f
),
5363 FRAME_DISPLAY_INFO (f
)->root_window
,
5364 /* x, y, width, height */
5368 CopyFromParent
, InputOutput
, CopyFromParent
,
5370 XChangeProperty (FRAME_X_DISPLAY (f
), tip_window
,
5371 FRAME_DISPLAY_INFO (f
)->Xatom_net_window_type
,
5372 XA_ATOM
, 32, PropModeReplace
,
5373 (unsigned char *)&type
, 1);
5379 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
5380 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
5381 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
5382 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
5383 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
5384 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
5386 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
5387 Change will not be effected unless different from the current
5389 width
= FRAME_COLS (f
);
5390 height
= FRAME_LINES (f
);
5391 SET_FRAME_COLS (f
, 0);
5392 SET_FRAME_LINES (f
, 0);
5393 change_frame_size (f
, width
, height
, true, false, false, false);
5395 /* Add `tooltip' frame parameter's default value. */
5396 if (NILP (Fframe_parameter (frame
, Qtooltip
)))
5398 AUTO_FRAME_ARG (arg
, Qtooltip
, Qt
);
5399 Fmodify_frame_parameters (frame
, arg
);
5402 /* FIXME - can this be done in a similar way to normal frames?
5403 http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
5405 /* Set the `display-type' frame parameter before setting up faces. */
5407 Lisp_Object disptype
;
5409 if (FRAME_DISPLAY_INFO (f
)->n_planes
== 1)
5411 else if (FRAME_DISPLAY_INFO (f
)->visual
->class == GrayScale
5412 || FRAME_DISPLAY_INFO (f
)->visual
->class == StaticGray
)
5413 disptype
= intern ("grayscale");
5415 disptype
= intern ("color");
5417 if (NILP (Fframe_parameter (frame
, Qdisplay_type
)))
5419 AUTO_FRAME_ARG (arg
, Qdisplay_type
, disptype
);
5420 Fmodify_frame_parameters (frame
, arg
);
5424 /* Set up faces after all frame parameters are known. This call
5425 also merges in face attributes specified for new frames.
5427 Frame parameters may be changed if .Xdefaults contains
5428 specifications for the default font. For example, if there is an
5429 `Emacs.default.attributeBackground: pink', the `background-color'
5430 attribute of the frame get's set, which let's the internal border
5431 of the tooltip frame appear in pink. Prevent this. */
5433 Lisp_Object bg
= Fframe_parameter (frame
, Qbackground_color
);
5435 /* Set tip_frame here, so that */
5437 call2 (Qface_set_after_frame_default
, frame
, Qnil
);
5439 if (!EQ (bg
, Fframe_parameter (frame
, Qbackground_color
)))
5441 AUTO_FRAME_ARG (arg
, Qbackground_color
, bg
);
5442 Fmodify_frame_parameters (frame
, arg
);
5448 /* Now that the frame will be official, it counts as a reference to
5449 its display and terminal. */
5450 FRAME_DISPLAY_INFO (f
)->reference_count
++;
5451 f
->terminal
->reference_count
++;
5453 /* It is now ok to make the frame official even if we get an error
5454 below. And the frame needs to be on Vframe_list or making it
5455 visible won't work. */
5456 Vframe_list
= Fcons (frame
, Vframe_list
);
5457 f
->can_x_set_window_size
= true;
5459 /* Setting attributes of faces of the tooltip frame from resources
5460 and similar will set face_change, which leads to the clearing of
5461 all current matrices. Since this isn't necessary here, avoid it
5462 by resetting face_change to the value it had before we created
5464 face_change
= face_change_before
;
5466 /* Discard the unwind_protect. */
5467 return unbind_to (count
, frame
);
5471 /* Compute where to display tip frame F. PARMS is the list of frame
5472 parameters for F. DX and DY are specified offsets from the current
5473 location of the mouse. WIDTH and HEIGHT are the width and height
5474 of the tooltip. Return coordinates relative to the root window of
5475 the display in *ROOT_X, and *ROOT_Y. */
5478 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
)
5480 Lisp_Object left
, top
, right
, bottom
;
5485 /* User-specified position? */
5486 left
= Fcdr (Fassq (Qleft
, parms
));
5487 top
= Fcdr (Fassq (Qtop
, parms
));
5488 right
= Fcdr (Fassq (Qright
, parms
));
5489 bottom
= Fcdr (Fassq (Qbottom
, parms
));
5491 /* Move the tooltip window where the mouse pointer is. Resize and
5493 if ((!INTEGERP (left
) && !INTEGERP (right
))
5494 || (!INTEGERP (top
) && !INTEGERP (bottom
)))
5497 XQueryPointer (FRAME_X_DISPLAY (f
), FRAME_DISPLAY_INFO (f
)->root_window
,
5498 &root
, &child
, root_x
, root_y
, &win_x
, &win_y
, &pmask
);
5503 *root_y
= XINT (top
);
5504 else if (INTEGERP (bottom
))
5505 *root_y
= XINT (bottom
) - height
;
5506 else if (*root_y
+ XINT (dy
) <= 0)
5507 *root_y
= 0; /* Can happen for negative dy */
5508 else if (*root_y
+ XINT (dy
) + height
5509 <= x_display_pixel_height (FRAME_DISPLAY_INFO (f
)))
5510 /* It fits below the pointer */
5511 *root_y
+= XINT (dy
);
5512 else if (height
+ XINT (dy
) <= *root_y
)
5513 /* It fits above the pointer. */
5514 *root_y
-= height
+ XINT (dy
);
5516 /* Put it on the top. */
5519 if (INTEGERP (left
))
5520 *root_x
= XINT (left
);
5521 else if (INTEGERP (right
))
5522 *root_y
= XINT (right
) - width
;
5523 else if (*root_x
+ XINT (dx
) <= 0)
5524 *root_x
= 0; /* Can happen for negative dx */
5525 else if (*root_x
+ XINT (dx
) + width
5526 <= x_display_pixel_width (FRAME_DISPLAY_INFO (f
)))
5527 /* It fits to the right of the pointer. */
5528 *root_x
+= XINT (dx
);
5529 else if (width
+ XINT (dx
) <= *root_x
)
5530 /* It fits to the left of the pointer. */
5531 *root_x
-= width
+ XINT (dx
);
5533 /* Put it left-justified on the screen--it ought to fit that way. */
5538 DEFUN ("x-show-tip", Fx_show_tip
, Sx_show_tip
, 1, 6, 0,
5539 doc
: /* Show STRING in a "tooltip" window on frame FRAME.
5540 A tooltip window is a small X window displaying a string.
5542 This is an internal function; Lisp code should call `tooltip-show'.
5544 FRAME nil or omitted means use the selected frame.
5546 PARMS is an optional list of frame parameters which can be used to
5547 change the tooltip's appearance.
5549 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
5550 means use the default timeout of 5 seconds.
5552 If the list of frame parameters PARMS contains a `left' parameter,
5553 display the tooltip at that x-position. If the list of frame parameters
5554 PARMS contains no `left' but a `right' parameter, display the tooltip
5555 right-adjusted at that x-position. Otherwise display it at the
5556 x-position of the mouse, with offset DX added (default is 5 if DX isn't
5559 Likewise for the y-position: If a `top' frame parameter is specified, it
5560 determines the position of the upper edge of the tooltip window. If a
5561 `bottom' parameter but no `top' frame parameter is specified, it
5562 determines the position of the lower edge of the tooltip window.
5563 Otherwise display the tooltip window at the y-position of the mouse,
5564 with offset DY added (default is -10).
5566 A tooltip's maximum size is specified by `x-max-tooltip-size'.
5567 Text larger than the specified size is clipped. */)
5568 (Lisp_Object string
, Lisp_Object frame
, Lisp_Object parms
, Lisp_Object timeout
, Lisp_Object dx
, Lisp_Object dy
)
5573 struct buffer
*old_buffer
;
5574 struct text_pos pos
;
5575 int i
, width
, height
;
5576 bool seen_reversed_p
;
5577 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
5578 ptrdiff_t count
= SPECPDL_INDEX ();
5580 specbind (Qinhibit_redisplay
, Qt
);
5582 CHECK_STRING (string
);
5583 if (SCHARS (string
) == 0)
5584 string
= make_unibyte_string (" ", 1);
5586 f
= decode_window_system_frame (frame
);
5588 timeout
= make_number (5);
5590 CHECK_NATNUM (timeout
);
5593 dx
= make_number (5);
5598 dy
= make_number (-10);
5603 if (x_gtk_use_system_tooltips
)
5607 /* Hide a previous tip, if any. */
5611 ok
= xg_prepare_tooltip (f
, string
, &width
, &height
);
5614 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, &root_x
, &root_y
);
5615 xg_show_tooltip (f
, root_x
, root_y
);
5616 /* This is used in Fx_hide_tip. */
5617 XSETFRAME (tip_frame
, f
);
5620 if (ok
) goto start_timer
;
5622 #endif /* USE_GTK */
5624 if (NILP (last_show_tip_args
))
5625 last_show_tip_args
= Fmake_vector (make_number (3), Qnil
);
5627 if (!NILP (tip_frame
))
5629 Lisp_Object last_string
= AREF (last_show_tip_args
, 0);
5630 Lisp_Object last_frame
= AREF (last_show_tip_args
, 1);
5631 Lisp_Object last_parms
= AREF (last_show_tip_args
, 2);
5633 if (EQ (frame
, last_frame
)
5634 && !NILP (Fequal (last_string
, string
))
5635 && !NILP (Fequal (last_parms
, parms
)))
5637 struct frame
*tip_f
= XFRAME (tip_frame
);
5639 /* Only DX and DY have changed. */
5640 if (!NILP (tip_timer
))
5642 Lisp_Object timer
= tip_timer
;
5644 call1 (Qcancel_timer
, timer
);
5648 compute_tip_xy (tip_f
, parms
, dx
, dy
, FRAME_PIXEL_WIDTH (tip_f
),
5649 FRAME_PIXEL_HEIGHT (tip_f
), &root_x
, &root_y
);
5650 XMoveWindow (FRAME_X_DISPLAY (tip_f
), FRAME_X_WINDOW (tip_f
),
5657 /* Hide a previous tip, if any. */
5660 ASET (last_show_tip_args
, 0, string
);
5661 ASET (last_show_tip_args
, 1, frame
);
5662 ASET (last_show_tip_args
, 2, parms
);
5664 /* Add default values to frame parameters. */
5665 if (NILP (Fassq (Qname
, parms
)))
5666 parms
= Fcons (Fcons (Qname
, build_string ("tooltip")), parms
);
5667 if (NILP (Fassq (Qinternal_border_width
, parms
)))
5668 parms
= Fcons (Fcons (Qinternal_border_width
, make_number (3)), parms
);
5669 if (NILP (Fassq (Qborder_width
, parms
)))
5670 parms
= Fcons (Fcons (Qborder_width
, make_number (1)), parms
);
5671 if (NILP (Fassq (Qbottom_divider_width
, parms
)))
5672 parms
= Fcons (Fcons (Qbottom_divider_width
, make_number (0)), parms
);
5673 if (NILP (Fassq (Qright_divider_width
, parms
)))
5674 parms
= Fcons (Fcons (Qright_divider_width
, make_number (0)), parms
);
5675 if (NILP (Fassq (Qborder_color
, parms
)))
5676 parms
= Fcons (Fcons (Qborder_color
, build_string ("lightyellow")), parms
);
5677 if (NILP (Fassq (Qbackground_color
, parms
)))
5678 parms
= Fcons (Fcons (Qbackground_color
, build_string ("lightyellow")),
5681 /* Create a frame for the tooltip, and record it in the global
5682 variable tip_frame. */
5683 frame
= x_create_tip_frame (FRAME_DISPLAY_INFO (f
), parms
, string
);
5686 /* Set up the frame's root window. */
5687 w
= XWINDOW (FRAME_ROOT_WINDOW (f
));
5693 if (CONSP (Vx_max_tooltip_size
)
5694 && RANGED_INTEGERP (1, XCAR (Vx_max_tooltip_size
), INT_MAX
)
5695 && RANGED_INTEGERP (1, XCDR (Vx_max_tooltip_size
), INT_MAX
))
5697 w
->total_cols
= XFASTINT (XCAR (Vx_max_tooltip_size
));
5698 w
->total_lines
= XFASTINT (XCDR (Vx_max_tooltip_size
));
5703 w
->total_lines
= 40;
5706 w
->pixel_width
= w
->total_cols
* FRAME_COLUMN_WIDTH (f
);
5707 w
->pixel_height
= w
->total_lines
* FRAME_LINE_HEIGHT (f
);
5709 FRAME_TOTAL_COLS (f
) = w
->total_cols
;
5710 adjust_frame_glyphs (f
);
5711 w
->pseudo_window_p
= true;
5713 /* Display the tooltip text in a temporary buffer. */
5714 old_buffer
= current_buffer
;
5715 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f
))->contents
));
5716 bset_truncate_lines (current_buffer
, Qnil
);
5717 clear_glyph_matrix (w
->desired_matrix
);
5718 clear_glyph_matrix (w
->current_matrix
);
5719 SET_TEXT_POS (pos
, BEGV
, BEGV_BYTE
);
5720 try_window (FRAME_ROOT_WINDOW (f
), pos
, TRY_WINDOW_IGNORE_FONTS_CHANGE
);
5722 /* Compute width and height of the tooltip. */
5724 seen_reversed_p
= false;
5725 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
5727 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
5731 /* Stop at the first empty row at the end. */
5732 if (!row
->enabled_p
|| !MATRIX_ROW_DISPLAYS_TEXT_P (row
))
5735 /* Let the row go over the full width of the frame. */
5736 row
->full_width_p
= true;
5738 row_width
= row
->pixel_width
;
5739 if (row
->used
[TEXT_AREA
])
5741 /* There's a glyph at the end of rows that is used to place
5742 the cursor there. Don't include the width of this glyph. */
5743 if (!row
->reversed_p
)
5745 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
5746 if (NILP (last
->object
))
5747 row_width
-= last
->pixel_width
;
5751 /* There could be a stretch glyph at the beginning of R2L
5752 rows that is produced by extend_face_to_end_of_line.
5753 Don't count that glyph. */
5754 struct glyph
*g
= row
->glyphs
[TEXT_AREA
];
5756 if (g
->type
== STRETCH_GLYPH
&& NILP (g
->object
))
5758 row_width
-= g
->pixel_width
;
5759 seen_reversed_p
= true;
5764 height
+= row
->height
;
5765 width
= max (width
, row_width
);
5768 /* If we've seen partial-length R2L rows, we need to re-adjust the
5769 tool-tip frame width and redisplay it again, to avoid over-wide
5770 tips due to the stretch glyph that extends R2L lines to full
5771 width of the frame. */
5772 if (seen_reversed_p
)
5774 /* w->total_cols and FRAME_TOTAL_COLS want the width in columns,
5776 w
->pixel_width
= width
;
5777 width
/= WINDOW_FRAME_COLUMN_WIDTH (w
);
5778 w
->total_cols
= width
;
5779 FRAME_TOTAL_COLS (f
) = width
;
5780 SET_FRAME_WIDTH (f
, width
);
5781 adjust_frame_glyphs (f
);
5782 clear_glyph_matrix (w
->desired_matrix
);
5783 clear_glyph_matrix (w
->current_matrix
);
5784 try_window (FRAME_ROOT_WINDOW (f
), pos
, 0);
5786 /* Recompute width and height of the tooltip. */
5787 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
5789 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
5793 if (!row
->enabled_p
|| !MATRIX_ROW_DISPLAYS_TEXT_P (row
))
5795 row
->full_width_p
= true;
5796 row_width
= row
->pixel_width
;
5797 if (row
->used
[TEXT_AREA
] && !row
->reversed_p
)
5799 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
5800 if (NILP (last
->object
))
5801 row_width
-= last
->pixel_width
;
5804 height
+= row
->height
;
5805 width
= max (width
, row_width
);
5809 /* Add the frame's internal border to the width and height the X
5810 window should have. */
5811 height
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
5812 width
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
5814 /* Move the tooltip window where the mouse pointer is. Resize and
5816 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, &root_x
, &root_y
);
5819 XMoveResizeWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5820 root_x
, root_y
, width
, height
);
5821 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
5824 /* Draw into the window. */
5825 w
->must_be_updated_p
= true;
5826 update_single_window (w
);
5828 /* Restore original current buffer. */
5829 set_buffer_internal_1 (old_buffer
);
5830 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
5833 /* Let the tip disappear after timeout seconds. */
5834 tip_timer
= call3 (intern ("run-at-time"), timeout
, Qnil
,
5835 intern ("x-hide-tip"));
5837 return unbind_to (count
, Qnil
);
5841 DEFUN ("x-hide-tip", Fx_hide_tip
, Sx_hide_tip
, 0, 0, 0,
5842 doc
: /* Hide the current tooltip window, if there is any.
5843 Value is t if tooltip was open, nil otherwise. */)
5847 Lisp_Object deleted
, frame
, timer
;
5849 /* Return quickly if nothing to do. */
5850 if (NILP (tip_timer
) && NILP (tip_frame
))
5855 tip_frame
= tip_timer
= deleted
= Qnil
;
5857 count
= SPECPDL_INDEX ();
5858 specbind (Qinhibit_redisplay
, Qt
);
5859 specbind (Qinhibit_quit
, Qt
);
5862 call1 (Qcancel_timer
, timer
);
5866 /* When using system tooltip, tip_frame is the Emacs frame on which
5867 the tip is shown. */
5868 struct frame
*f
= XFRAME (frame
);
5869 if (FRAME_LIVE_P (f
) && xg_hide_tooltip (f
))
5876 delete_frame (frame
, Qnil
);
5880 /* Bloodcurdling hack alert: The Lucid menu bar widget's
5881 redisplay procedure is not called when a tip frame over menu
5882 items is unmapped. Redisplay the menu manually... */
5885 struct frame
*f
= SELECTED_FRAME ();
5886 w
= f
->output_data
.x
->menubar_widget
;
5888 if (!DoesSaveUnders (FRAME_DISPLAY_INFO (f
)->screen
)
5892 xlwmenu_redisplay (w
);
5896 #endif /* USE_LUCID */
5899 return unbind_to (count
, deleted
);
5904 /***********************************************************************
5905 File selection dialog
5906 ***********************************************************************/
5908 DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog
,
5909 Sx_uses_old_gtk_dialog
,
5911 doc
: /* Return t if the old Gtk+ file selection dialog is used. */)
5917 && window_system_available (SELECTED_FRAME ())
5918 && xg_uses_old_file_dialog ())
5926 /* Callback for "OK" and "Cancel" on file selection dialog. */
5929 file_dialog_cb (Widget widget
, XtPointer client_data
, XtPointer call_data
)
5931 int *result
= client_data
;
5932 XmAnyCallbackStruct
*cb
= call_data
;
5933 *result
= cb
->reason
;
5937 /* Callback for unmapping a file selection dialog. This is used to
5938 capture the case where a dialog is closed via a window manager's
5939 closer button, for example. Using a XmNdestroyCallback didn't work
5943 file_dialog_unmap_cb (Widget widget
, XtPointer client_data
, XtPointer call_data
)
5945 int *result
= client_data
;
5946 *result
= XmCR_CANCEL
;
5950 clean_up_file_dialog (void *arg
)
5952 Widget dialog
= arg
;
5956 XtUnmanageChild (dialog
);
5957 XtDestroyWidget (dialog
);
5958 x_menu_set_in_use (false);
5963 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 5, 0,
5964 doc
: /* Read file name, prompting with PROMPT in directory DIR.
5965 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5966 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5967 or directory must exist.
5969 This function is only defined on NS, MS Windows, and X Windows with the
5970 Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
5971 Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.
5972 On Windows 7 and later, the file selection dialog "remembers" the last
5973 directory where the user selected a file, and will open that directory
5974 instead of DIR on subsequent invocations of this function with the same
5975 value of DIR as in previous invocations; this is standard Windows behavior. */)
5976 (Lisp_Object prompt
, Lisp_Object dir
, Lisp_Object default_filename
,
5977 Lisp_Object mustmatch
, Lisp_Object only_dir_p
)
5980 struct frame
*f
= SELECTED_FRAME ();
5981 Lisp_Object file
= Qnil
;
5982 Lisp_Object decoded_file
;
5983 Widget dialog
, text
, help
;
5986 XmString dir_xmstring
, pattern_xmstring
;
5987 ptrdiff_t count
= SPECPDL_INDEX ();
5989 check_window_system (f
);
5991 if (popup_activated ())
5992 error ("Trying to use a menu from within a menu-entry");
5994 CHECK_STRING (prompt
);
5997 /* Prevent redisplay. */
5998 specbind (Qinhibit_redisplay
, Qt
);
6002 /* Create the dialog with PROMPT as title, using DIR as initial
6003 directory and using "*" as pattern. */
6004 dir
= Fexpand_file_name (dir
, Qnil
);
6005 dir_xmstring
= XmStringCreateLocalized (SSDATA (dir
));
6006 pattern_xmstring
= XmStringCreateLocalized ("*");
6008 XtSetArg (al
[ac
], XmNtitle
, SDATA (prompt
)); ++ac
;
6009 XtSetArg (al
[ac
], XmNdirectory
, dir_xmstring
); ++ac
;
6010 XtSetArg (al
[ac
], XmNpattern
, pattern_xmstring
); ++ac
;
6011 XtSetArg (al
[ac
], XmNresizePolicy
, XmRESIZE_GROW
); ++ac
;
6012 XtSetArg (al
[ac
], XmNdialogStyle
, XmDIALOG_APPLICATION_MODAL
); ++ac
;
6013 dialog
= XmCreateFileSelectionDialog (f
->output_data
.x
->widget
,
6015 XmStringFree (dir_xmstring
);
6016 XmStringFree (pattern_xmstring
);
6018 /* Add callbacks for OK and Cancel. */
6019 XtAddCallback (dialog
, XmNokCallback
, file_dialog_cb
,
6020 (XtPointer
) &result
);
6021 XtAddCallback (dialog
, XmNcancelCallback
, file_dialog_cb
,
6022 (XtPointer
) &result
);
6023 XtAddCallback (dialog
, XmNunmapCallback
, file_dialog_unmap_cb
,
6024 (XtPointer
) &result
);
6026 /* Remove the help button since we can't display help. */
6027 help
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_HELP_BUTTON
);
6028 XtUnmanageChild (help
);
6030 /* Mark OK button as default. */
6031 XtVaSetValues (XmFileSelectionBoxGetChild (dialog
, XmDIALOG_OK_BUTTON
),
6032 XmNshowAsDefault
, True
, NULL
);
6034 /* If MUSTMATCH is non-nil, disable the file entry field of the
6035 dialog, so that the user must select a file from the files list
6036 box. We can't remove it because we wouldn't have a way to get at
6037 the result file name, then. */
6038 text
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
6039 if (!NILP (mustmatch
))
6042 label
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_SELECTION_LABEL
);
6043 XtSetSensitive (text
, False
);
6044 XtSetSensitive (label
, False
);
6047 /* Manage the dialog, so that list boxes get filled. */
6048 XtManageChild (dialog
);
6050 if (STRINGP (default_filename
))
6052 XmString default_xmstring
;
6053 Widget wtext
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
6054 Widget list
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_LIST
);
6056 XmTextPosition last_pos
= XmTextFieldGetLastPosition (wtext
);
6057 XmTextFieldReplace (wtext
, 0, last_pos
,
6058 (SSDATA (Ffile_name_nondirectory (default_filename
))));
6060 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
6061 must include the path for this to work. */
6063 default_xmstring
= XmStringCreateLocalized (SSDATA (default_filename
));
6065 if (XmListItemExists (list
, default_xmstring
))
6067 int item_pos
= XmListItemPos (list
, default_xmstring
);
6068 /* Select the item and scroll it into view. */
6069 XmListSelectPos (list
, item_pos
, True
);
6070 XmListSetPos (list
, item_pos
);
6073 XmStringFree (default_xmstring
);
6076 record_unwind_protect_ptr (clean_up_file_dialog
, dialog
);
6078 /* Process events until the user presses Cancel or OK. */
6079 x_menu_set_in_use (true);
6084 x_menu_wait_for_event (0);
6085 XtAppNextEvent (Xt_app_con
, &event
);
6086 if (event
.type
== KeyPress
6087 && FRAME_X_DISPLAY (f
) == event
.xkey
.display
)
6089 KeySym keysym
= XLookupKeysym (&event
.xkey
, 0);
6091 /* Pop down on C-g. */
6092 if (keysym
== XK_g
&& (event
.xkey
.state
& ControlMask
) != 0)
6093 XtUnmanageChild (dialog
);
6096 (void) x_dispatch_event (&event
, FRAME_X_DISPLAY (f
));
6099 /* Get the result. */
6100 if (result
== XmCR_OK
)
6102 XmString text_string
;
6105 XtVaGetValues (dialog
, XmNtextString
, &text_string
, NULL
);
6106 XmStringGetLtoR (text_string
, XmFONTLIST_DEFAULT_TAG
, &data
);
6107 XmStringFree (text_string
);
6108 file
= build_string (data
);
6116 /* Make "Cancel" equivalent to C-g. */
6118 Fsignal (Qquit
, Qnil
);
6120 decoded_file
= DECODE_FILE (file
);
6122 return unbind_to (count
, decoded_file
);
6125 #endif /* USE_MOTIF */
6130 clean_up_dialog (void)
6132 x_menu_set_in_use (false);
6135 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 5, 0,
6136 doc
: /* Read file name, prompting with PROMPT in directory DIR.
6137 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
6138 selection box, if specified. If MUSTMATCH is non-nil, the returned file
6139 or directory must exist.
6141 This function is only defined on NS, MS Windows, and X Windows with the
6142 Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
6143 Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.
6144 On Windows 7 and later, the file selection dialog "remembers" the last
6145 directory where the user selected a file, and will open that directory
6146 instead of DIR on subsequent invocations of this function with the same
6147 value of DIR as in previous invocations; this is standard Windows behavior. */)
6148 (Lisp_Object prompt
, Lisp_Object dir
, Lisp_Object default_filename
, Lisp_Object mustmatch
, Lisp_Object only_dir_p
)
6150 struct frame
*f
= SELECTED_FRAME ();
6152 Lisp_Object file
= Qnil
;
6153 Lisp_Object decoded_file
;
6154 ptrdiff_t count
= SPECPDL_INDEX ();
6157 check_window_system (f
);
6159 if (popup_activated ())
6160 error ("Trying to use a menu from within a menu-entry");
6162 CHECK_STRING (prompt
);
6165 /* Prevent redisplay. */
6166 specbind (Qinhibit_redisplay
, Qt
);
6167 record_unwind_protect_void (clean_up_dialog
);
6171 if (STRINGP (default_filename
))
6172 cdef_file
= SSDATA (default_filename
);
6174 cdef_file
= SSDATA (dir
);
6176 fn
= xg_get_file_name (f
, SSDATA (prompt
), cdef_file
,
6178 ! NILP (only_dir_p
));
6182 file
= build_string (fn
);
6188 /* Make "Cancel" equivalent to C-g. */
6190 Fsignal (Qquit
, Qnil
);
6192 decoded_file
= DECODE_FILE (file
);
6194 return unbind_to (count
, decoded_file
);
6198 #ifdef HAVE_FREETYPE
6200 DEFUN ("x-select-font", Fx_select_font
, Sx_select_font
, 0, 2, 0,
6201 doc
: /* Read a font using a GTK dialog.
6202 Return either a font spec (for GTK versions >= 3.2) or a string
6203 containing a GTK-style font name.
6205 FRAME is the frame on which to pop up the font chooser. If omitted or
6206 nil, it defaults to the selected frame. */)
6207 (Lisp_Object frame
, Lisp_Object ignored
)
6209 struct frame
*f
= decode_window_system_frame (frame
);
6211 Lisp_Object font_param
;
6212 char *default_name
= NULL
;
6213 ptrdiff_t count
= SPECPDL_INDEX ();
6215 if (popup_activated ())
6216 error ("Trying to use a menu from within a menu-entry");
6218 /* Prevent redisplay. */
6219 specbind (Qinhibit_redisplay
, Qt
);
6220 record_unwind_protect_void (clean_up_dialog
);
6224 XSETFONT (font
, FRAME_FONT (f
));
6225 font_param
= Ffont_get (font
, QCname
);
6226 if (STRINGP (font_param
))
6227 default_name
= xlispstrdup (font_param
);
6230 font_param
= Fframe_parameter (frame
, Qfont_param
);
6231 if (STRINGP (font_param
))
6232 default_name
= xlispstrdup (font_param
);
6235 font
= xg_get_font (f
, default_name
);
6236 xfree (default_name
);
6241 Fsignal (Qquit
, Qnil
);
6243 return unbind_to (count
, font
);
6245 #endif /* HAVE_FREETYPE */
6247 #endif /* USE_GTK */
6250 /***********************************************************************
6252 ***********************************************************************/
6255 #include <X11/XKBlib.h>
6256 #include <X11/keysym.h>
6259 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p
,
6260 Sx_backspace_delete_keys_p
, 0, 1, 0,
6261 doc
: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
6262 FRAME nil means use the selected frame.
6263 Value is t if we know that both keys are present, and are mapped to the
6264 usual X keysyms. Value is `lambda' if we cannot determine if both keys are
6265 present and mapped to the usual X keysyms. */)
6272 struct frame
*f
= decode_window_system_frame (frame
);
6273 Display
*dpy
= FRAME_X_DISPLAY (f
);
6274 Lisp_Object have_keys
;
6275 int major
, minor
, op
, event
, error_code
;
6279 /* Check library version in case we're dynamically linked. */
6280 major
= XkbMajorVersion
;
6281 minor
= XkbMinorVersion
;
6282 if (!XkbLibraryVersion (&major
, &minor
))
6288 /* Check that the server supports XKB. */
6289 major
= XkbMajorVersion
;
6290 minor
= XkbMinorVersion
;
6291 if (!XkbQueryExtension (dpy
, &op
, &event
, &error_code
, &major
, &minor
))
6297 /* In this code we check that the keyboard has physical keys with names
6298 that start with BKSP (Backspace) and DELE (Delete), and that they
6299 generate keysym XK_BackSpace and XK_Delete respectively.
6300 This function is used to test if normal-erase-is-backspace should be
6302 An alternative approach would be to just check if XK_BackSpace and
6303 XK_Delete are mapped to any key. But if any of those are mapped to
6304 some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the
6305 user doesn't know about it, it is better to return false here.
6306 It is more obvious to the user what to do if she/he has two keys
6307 clearly marked with names/symbols and one key does something not
6308 expected (i.e. she/he then tries the other).
6309 The cases where Backspace/Delete is mapped to some other key combination
6310 are rare, and in those cases, normal-erase-is-backspace can be turned on
6314 kb
= XkbGetMap (dpy
, XkbAllMapComponentsMask
, XkbUseCoreKbd
);
6317 int delete_keycode
= 0, backspace_keycode
= 0, i
;
6319 if (XkbGetNames (dpy
, XkbAllNamesMask
, kb
) == Success
)
6321 for (i
= kb
->min_key_code
;
6322 (i
< kb
->max_key_code
6323 && (delete_keycode
== 0 || backspace_keycode
== 0));
6326 /* The XKB symbolic key names can be seen most easily in
6327 the PS file generated by `xkbprint -label name
6329 if (memcmp ("DELE", kb
->names
->keys
[i
].name
, 4) == 0)
6331 else if (memcmp ("BKSP", kb
->names
->keys
[i
].name
, 4) == 0)
6332 backspace_keycode
= i
;
6335 XkbFreeNames (kb
, 0, True
);
6338 /* As of libX11-1.6.2, XkbGetMap manual says that you should use
6339 XkbFreeClientMap to free the data returned by XkbGetMap. But
6340 this function just frees the data referenced from KB and not
6341 KB itself. To free KB as well, call XkbFreeKeyboard. */
6342 XkbFreeKeyboard (kb
, XkbAllMapComponentsMask
, True
);
6345 && backspace_keycode
6346 && XKeysymToKeycode (dpy
, XK_Delete
) == delete_keycode
6347 && XKeysymToKeycode (dpy
, XK_BackSpace
) == backspace_keycode
)
6357 /***********************************************************************
6359 ***********************************************************************/
6362 DEFUN ("x-export-frames", Fx_export_frames
, Sx_export_frames
, 0, 2, 0,
6363 doc
: /* XXX Experimental. Return image data of FRAMES in TYPE format.
6364 FRAMES should be nil (the selected frame), a frame, or a list of
6365 frames (each of which corresponds to one page). Optional arg TYPE
6366 should be either `pdf' (default), `png', `ps', or `svg'. Supported
6367 types are determined by the compile-time configuration of cairo. */)
6368 (Lisp_Object frames
, Lisp_Object type
)
6370 Lisp_Object result
, rest
, tmp
;
6371 cairo_surface_type_t surface_type
;
6374 frames
= selected_frame
;
6375 if (!CONSP (frames
))
6376 frames
= list1 (frames
);
6379 for (rest
= frames
; CONSP (rest
); rest
= XCDR (rest
))
6381 struct frame
*f
= XFRAME (XCAR (rest
));
6383 if (! FRAME_LIVE_P (f
) || ! FRAME_X_P (f
) || ! FRAME_LIVE_P (f
))
6384 error ("Invalid frame");
6388 XSETFRAME (frame
, f
);
6389 tmp
= Fcons (frame
, tmp
);
6391 frames
= Fnreverse (tmp
);
6393 #ifdef CAIRO_HAS_PDF_SURFACE
6394 if (NILP (type
) || EQ (type
, intern ("pdf"))) /* XXX: Qpdf */
6395 surface_type
= CAIRO_SURFACE_TYPE_PDF
;
6398 #ifdef CAIRO_HAS_PNG_FUNCTIONS
6399 if (EQ (type
, intern ("png")))
6401 if (!NILP (XCDR (frames
)))
6402 error ("PNG export cannot handle multiple frames.");
6403 surface_type
= CAIRO_SURFACE_TYPE_IMAGE
;
6407 #ifdef CAIRO_HAS_PS_SURFACE
6408 if (EQ (type
, intern ("ps")))
6409 surface_type
= CAIRO_SURFACE_TYPE_PS
;
6412 #ifdef CAIRO_HAS_SVG_SURFACE
6413 if (EQ (type
, intern ("svg")))
6415 /* For now, we stick to SVG 1.1. */
6416 if (!NILP (XCDR (frames
)))
6417 error ("SVG export cannot handle multiple frames.");
6418 surface_type
= CAIRO_SURFACE_TYPE_SVG
;
6422 error ("Unsupported export type");
6424 result
= x_cr_export_frames (frames
, surface_type
);
6430 DEFUN ("x-page-setup-dialog", Fx_page_setup_dialog
, Sx_page_setup_dialog
, 0, 0, 0,
6431 doc
: /* Pop up a page setup dialog.
6432 The current page setup can be obtained using `x-get-page-setup'. */)
6436 xg_page_setup_dialog ();
6442 DEFUN ("x-get-page-setup", Fx_get_page_setup
, Sx_get_page_setup
, 0, 0, 0,
6443 doc
: /* Return the value of the current page setup.
6444 The return value is an alist containing the following keys:
6446 orientation: page orientation (symbol `portrait', `landscape',
6447 `reverse-portrait', or `reverse-landscape').
6448 width, height: page width/height in points not including margins.
6449 left-margin, right-margin, top-margin, bottom-margin: print margins,
6450 which is the parts of the page that the printer cannot print
6453 The paper width can be obtained as the sum of width, left-margin, and
6454 right-margin values. Likewise, the paper height is the sum of height,
6455 top-margin, and bottom-margin values. */)
6461 result
= xg_get_page_setup ();
6467 DEFUN ("x-print-frames-dialog", Fx_print_frames_dialog
, Sx_print_frames_dialog
, 0, 1, "",
6468 doc
: /* Pop up a print dialog to print the current contents of FRAMES.
6469 FRAMES should be nil (the selected frame), a frame, or a list of
6470 frames (each of which corresponds to one page). Each frame should be
6472 (Lisp_Object frames
)
6474 Lisp_Object rest
, tmp
;
6477 frames
= selected_frame
;
6478 if (!CONSP (frames
))
6479 frames
= list1 (frames
);
6482 for (rest
= frames
; CONSP (rest
); rest
= XCDR (rest
))
6484 struct frame
*f
= XFRAME (XCAR (rest
));
6485 if (! FRAME_LIVE_P (f
) || ! FRAME_X_P (f
) || ! FRAME_LIVE_P (f
))
6486 error ("Invalid frame");
6489 XSETFRAME (frame
, f
);
6490 if (!EQ (Fframe_visible_p (frame
), Qt
))
6491 error ("Frames to be printed must be visible.");
6492 tmp
= Fcons (frame
, tmp
);
6494 frames
= Fnreverse (tmp
);
6496 /* Make sure the current matrices are up-to-date. */
6500 xg_print_frames_dialog (frames
);
6505 #endif /* USE_GTK */
6506 #endif /* USE_CAIRO */
6509 /***********************************************************************
6511 ***********************************************************************/
6513 /* Keep this list in the same order as frame_parms in frame.c.
6514 Use 0 for unsupported frame parameters. */
6516 frame_parm_handler x_frame_parm_handlers
[] =
6520 x_set_background_color
,
6526 x_set_foreground_color
,
6529 x_set_internal_border_width
,
6530 x_set_right_divider_width
,
6531 x_set_bottom_divider_width
,
6532 x_set_menu_bar_lines
,
6534 x_explicitly_set_name
,
6535 x_set_scroll_bar_width
,
6536 x_set_scroll_bar_height
,
6539 x_set_vertical_scroll_bars
,
6540 x_set_horizontal_scroll_bars
,
6542 x_set_tool_bar_lines
,
6543 x_set_scroll_bar_foreground
,
6544 x_set_scroll_bar_background
,
6554 x_set_tool_bar_position
,
6560 DEFSYM (Qundefined_color
, "undefined-color");
6561 DEFSYM (Qcompound_text
, "compound-text");
6562 DEFSYM (Qcancel_timer
, "cancel-timer");
6563 DEFSYM (Qfont_param
, "font-parameter");
6564 DEFSYM (Qmono
, "mono");
6567 DEFSYM (Qorientation
, "orientation");
6568 DEFSYM (Qtop_margin
, "top-margin");
6569 DEFSYM (Qbottom_margin
, "bottom-margin");
6570 DEFSYM (Qportrait
, "portrait");
6571 DEFSYM (Qlandscape
, "landscape");
6572 DEFSYM (Qreverse_portrait
, "reverse-portrait");
6573 DEFSYM (Qreverse_landscape
, "reverse-landscape");
6576 Fput (Qundefined_color
, Qerror_conditions
,
6577 listn (CONSTYPE_PURE
, 2, Qundefined_color
, Qerror
));
6578 Fput (Qundefined_color
, Qerror_message
,
6579 build_pure_c_string ("Undefined color"));
6581 DEFVAR_LISP ("x-pointer-shape", Vx_pointer_shape
,
6582 doc
: /* The shape of the pointer when over text.
6583 Changing the value does not affect existing frames
6584 unless you set the mouse color. */);
6585 Vx_pointer_shape
= Qnil
;
6587 #if false /* This doesn't really do anything. */
6588 DEFVAR_LISP ("x-nontext-pointer-shape", Vx_nontext_pointer_shape
,
6589 doc
: /* The shape of the pointer when not over text.
6590 This variable takes effect when you create a new frame
6591 or when you set the mouse color. */);
6593 Vx_nontext_pointer_shape
= Qnil
;
6595 DEFVAR_LISP ("x-hourglass-pointer-shape", Vx_hourglass_pointer_shape
,
6596 doc
: /* The shape of the pointer when Emacs is busy.
6597 This variable takes effect when you create a new frame
6598 or when you set the mouse color. */);
6599 Vx_hourglass_pointer_shape
= Qnil
;
6601 #if false /* This doesn't really do anything. */
6602 DEFVAR_LISP ("x-mode-pointer-shape", Vx_mode_pointer_shape
,
6603 doc
: /* The shape of the pointer when over the mode line.
6604 This variable takes effect when you create a new frame
6605 or when you set the mouse color. */);
6607 Vx_mode_pointer_shape
= Qnil
;
6609 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
6610 Vx_sensitive_text_pointer_shape
,
6611 doc
: /* The shape of the pointer when over mouse-sensitive text.
6612 This variable takes effect when you create a new frame
6613 or when you set the mouse color. */);
6614 Vx_sensitive_text_pointer_shape
= Qnil
;
6616 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
6617 Vx_window_horizontal_drag_shape
,
6618 doc
: /* Pointer shape to use for indicating a window can be dragged horizontally.
6619 This variable takes effect when you create a new frame
6620 or when you set the mouse color. */);
6621 Vx_window_horizontal_drag_shape
= Qnil
;
6623 DEFVAR_LISP ("x-window-vertical-drag-cursor",
6624 Vx_window_vertical_drag_shape
,
6625 doc
: /* Pointer shape to use for indicating a window can be dragged vertically.
6626 This variable takes effect when you create a new frame
6627 or when you set the mouse color. */);
6628 Vx_window_vertical_drag_shape
= Qnil
;
6630 DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel
,
6631 doc
: /* A string indicating the foreground color of the cursor box. */);
6632 Vx_cursor_fore_pixel
= Qnil
;
6634 DEFVAR_LISP ("x-max-tooltip-size", Vx_max_tooltip_size
,
6635 doc
: /* Maximum size for tooltips.
6636 Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */);
6637 Vx_max_tooltip_size
= Fcons (make_number (80), make_number (40));
6639 DEFVAR_LISP ("x-no-window-manager", Vx_no_window_manager
,
6640 doc
: /* Non-nil if no X window manager is in use.
6641 Emacs doesn't try to figure this out; this is always nil
6642 unless you set it to something else. */);
6643 /* We don't have any way to find this out, so set it to nil
6644 and maybe the user would like to set it to t. */
6645 Vx_no_window_manager
= Qnil
;
6647 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
6648 Vx_pixel_size_width_font_regexp
,
6649 doc
: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
6651 Since Emacs gets width of a font matching with this regexp from
6652 PIXEL_SIZE field of the name, font finding mechanism gets faster for
6653 such a font. This is especially effective for such large fonts as
6654 Chinese, Japanese, and Korean. */);
6655 Vx_pixel_size_width_font_regexp
= Qnil
;
6657 /* This is not ifdef:ed, so other builds than GTK can customize it. */
6658 DEFVAR_BOOL ("x-gtk-use-old-file-dialog", x_gtk_use_old_file_dialog
,
6659 doc
: /* Non-nil means prompt with the old GTK file selection dialog.
6660 If nil or if the file selection dialog is not available, the new GTK file
6661 chooser is used instead. To turn off all file dialogs set the
6662 variable `use-file-dialog'. */);
6663 x_gtk_use_old_file_dialog
= false;
6665 DEFVAR_BOOL ("x-gtk-show-hidden-files", x_gtk_show_hidden_files
,
6666 doc
: /* If non-nil, the GTK file chooser will by default show hidden files.
6667 Note that this is just the default, there is a toggle button on the file
6668 chooser to show or not show hidden files on a case by case basis. */);
6669 x_gtk_show_hidden_files
= false;
6671 DEFVAR_BOOL ("x-gtk-file-dialog-help-text", x_gtk_file_dialog_help_text
,
6672 doc
: /* If non-nil, the GTK file chooser will show additional help text.
6673 If more space for files in the file chooser dialog is wanted, set this to nil
6674 to turn the additional text off. */);
6675 x_gtk_file_dialog_help_text
= true;
6677 DEFVAR_BOOL ("x-gtk-use-system-tooltips", x_gtk_use_system_tooltips
,
6678 doc
: /* If non-nil with a Gtk+ built Emacs, the Gtk+ tooltip is used.
6679 Otherwise use Emacs own tooltip implementation.
6680 When using Gtk+ tooltips, the tooltip face is not used. */);
6681 x_gtk_use_system_tooltips
= true;
6683 /* Tell Emacs about this window system. */
6684 Fprovide (Qx
, Qnil
);
6686 #ifdef USE_X_TOOLKIT
6687 Fprovide (intern_c_string ("x-toolkit"), Qnil
);
6689 Fprovide (intern_c_string ("motif"), Qnil
);
6691 DEFVAR_LISP ("motif-version-string", Vmotif_version_string
,
6692 doc
: /* Version info for LessTif/Motif. */);
6693 Vmotif_version_string
= build_string (XmVERSION_STRING
);
6694 #endif /* USE_MOTIF */
6695 #endif /* USE_X_TOOLKIT */
6698 /* Provide x-toolkit also for GTK. Internally GTK does not use Xt so it
6699 is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
6700 But for a user it is a toolkit for X, and indeed, configure
6701 accepts --with-x-toolkit=gtk. */
6702 Fprovide (intern_c_string ("x-toolkit"), Qnil
);
6703 Fprovide (intern_c_string ("gtk"), Qnil
);
6704 Fprovide (intern_c_string ("move-toolbar"), Qnil
);
6706 DEFVAR_LISP ("gtk-version-string", Vgtk_version_string
,
6707 doc
: /* Version info for GTK+. */);
6709 char gtk_version
[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
6710 int len
= sprintf (gtk_version
, "%d.%d.%d",
6711 GTK_MAJOR_VERSION
, GTK_MINOR_VERSION
, GTK_MICRO_VERSION
);
6712 Vgtk_version_string
= make_pure_string (gtk_version
, len
, len
, false);
6714 #endif /* USE_GTK */
6717 Fprovide (intern_c_string ("cairo"), Qnil
);
6719 DEFVAR_LISP ("cairo-version-string", Vcairo_version_string
,
6720 doc
: /* Version info for cairo. */);
6722 char cairo_version
[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
6723 int len
= sprintf (cairo_version
, "%d.%d.%d",
6724 CAIRO_VERSION_MAJOR
, CAIRO_VERSION_MINOR
,
6725 CAIRO_VERSION_MICRO
);
6726 Vcairo_version_string
= make_pure_string (cairo_version
, len
, len
, false);
6730 /* X window properties. */
6731 defsubr (&Sx_change_window_property
);
6732 defsubr (&Sx_delete_window_property
);
6733 defsubr (&Sx_window_property
);
6735 defsubr (&Sxw_display_color_p
);
6736 defsubr (&Sx_display_grayscale_p
);
6737 defsubr (&Sxw_color_defined_p
);
6738 defsubr (&Sxw_color_values
);
6739 defsubr (&Sx_server_max_request_size
);
6740 defsubr (&Sx_server_vendor
);
6741 defsubr (&Sx_server_version
);
6742 defsubr (&Sx_display_pixel_width
);
6743 defsubr (&Sx_display_pixel_height
);
6744 defsubr (&Sx_display_mm_width
);
6745 defsubr (&Sx_display_mm_height
);
6746 defsubr (&Sx_display_screens
);
6747 defsubr (&Sx_display_planes
);
6748 defsubr (&Sx_display_color_cells
);
6749 defsubr (&Sx_display_visual_class
);
6750 defsubr (&Sx_display_backing_store
);
6751 defsubr (&Sx_display_save_under
);
6752 defsubr (&Sx_display_monitor_attributes_list
);
6753 defsubr (&Sx_frame_geometry
);
6754 defsubr (&Sx_frame_edges
);
6755 defsubr (&Sx_mouse_absolute_pixel_position
);
6756 defsubr (&Sx_set_mouse_absolute_pixel_position
);
6757 defsubr (&Sx_wm_set_size_hint
);
6758 defsubr (&Sx_create_frame
);
6759 defsubr (&Sx_open_connection
);
6760 defsubr (&Sx_close_connection
);
6761 defsubr (&Sx_display_list
);
6762 defsubr (&Sx_synchronize
);
6763 defsubr (&Sx_backspace_delete_keys_p
);
6765 defsubr (&Sx_show_tip
);
6766 defsubr (&Sx_hide_tip
);
6768 staticpro (&tip_timer
);
6770 staticpro (&tip_frame
);
6772 last_show_tip_args
= Qnil
;
6773 staticpro (&last_show_tip_args
);
6775 defsubr (&Sx_uses_old_gtk_dialog
);
6776 #if defined (USE_MOTIF) || defined (USE_GTK)
6777 defsubr (&Sx_file_dialog
);
6780 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
6781 defsubr (&Sx_select_font
);
6785 defsubr (&Sx_export_frames
);
6787 defsubr (&Sx_page_setup_dialog
);
6788 defsubr (&Sx_get_page_setup
);
6789 defsubr (&Sx_print_frames_dialog
);