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 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
5323 "pointerColor", "Foreground", RES_TYPE_STRING
);
5324 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
5325 "cursorColor", "Foreground", RES_TYPE_STRING
);
5326 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
5327 "borderColor", "BorderColor", RES_TYPE_STRING
);
5329 /* Init faces before x_default_parameter is called for the
5330 scroll-bar-width parameter because otherwise we end up in
5331 init_iterator with a null face cache, which should not happen. */
5332 init_frame_faces (f
);
5334 f
->output_data
.x
->parent_desc
= FRAME_DISPLAY_INFO (f
)->root_window
;
5336 x_figure_window_size (f
, parms
, false);
5339 XSetWindowAttributes attrs
;
5341 Atom type
= FRAME_DISPLAY_INFO (f
)->Xatom_net_window_type_tooltip
;
5344 mask
= CWBackPixel
| CWOverrideRedirect
| CWEventMask
| CWCursor
;
5345 if (DoesSaveUnders (dpyinfo
->screen
))
5346 mask
|= CWSaveUnder
;
5348 /* Window managers look at the override-redirect flag to determine
5349 whether or net to give windows a decoration (Xlib spec, chapter
5351 attrs
.override_redirect
= True
;
5352 attrs
.save_under
= True
;
5353 attrs
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
5355 f
->output_data
.x
->current_cursor
5356 = f
->output_data
.x
->text_cursor
;
5357 /* Arrange for getting MapNotify and UnmapNotify events. */
5358 attrs
.event_mask
= StructureNotifyMask
;
5360 = FRAME_X_WINDOW (f
)
5361 = XCreateWindow (FRAME_X_DISPLAY (f
),
5362 FRAME_DISPLAY_INFO (f
)->root_window
,
5363 /* x, y, width, height */
5367 CopyFromParent
, InputOutput
, CopyFromParent
,
5369 XChangeProperty (FRAME_X_DISPLAY (f
), tip_window
,
5370 FRAME_DISPLAY_INFO (f
)->Xatom_net_window_type
,
5371 XA_ATOM
, 32, PropModeReplace
,
5372 (unsigned char *)&type
, 1);
5378 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
5379 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
5380 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
5381 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
5382 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
5383 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
5385 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
5386 Change will not be effected unless different from the current
5388 width
= FRAME_COLS (f
);
5389 height
= FRAME_LINES (f
);
5390 SET_FRAME_COLS (f
, 0);
5391 SET_FRAME_LINES (f
, 0);
5392 change_frame_size (f
, width
, height
, true, false, false, false);
5394 /* Add `tooltip' frame parameter's default value. */
5395 if (NILP (Fframe_parameter (frame
, Qtooltip
)))
5397 AUTO_FRAME_ARG (arg
, Qtooltip
, Qt
);
5398 Fmodify_frame_parameters (frame
, arg
);
5401 /* FIXME - can this be done in a similar way to normal frames?
5402 http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
5404 /* Set the `display-type' frame parameter before setting up faces. */
5406 Lisp_Object disptype
;
5408 if (FRAME_DISPLAY_INFO (f
)->n_planes
== 1)
5410 else if (FRAME_DISPLAY_INFO (f
)->visual
->class == GrayScale
5411 || FRAME_DISPLAY_INFO (f
)->visual
->class == StaticGray
)
5412 disptype
= intern ("grayscale");
5414 disptype
= intern ("color");
5416 if (NILP (Fframe_parameter (frame
, Qdisplay_type
)))
5418 AUTO_FRAME_ARG (arg
, Qdisplay_type
, disptype
);
5419 Fmodify_frame_parameters (frame
, arg
);
5423 /* Set up faces after all frame parameters are known. This call
5424 also merges in face attributes specified for new frames.
5426 Frame parameters may be changed if .Xdefaults contains
5427 specifications for the default font. For example, if there is an
5428 `Emacs.default.attributeBackground: pink', the `background-color'
5429 attribute of the frame get's set, which let's the internal border
5430 of the tooltip frame appear in pink. Prevent this. */
5432 Lisp_Object bg
= Fframe_parameter (frame
, Qbackground_color
);
5434 /* Set tip_frame here, so that */
5436 call2 (Qface_set_after_frame_default
, frame
, Qnil
);
5438 if (!EQ (bg
, Fframe_parameter (frame
, Qbackground_color
)))
5440 AUTO_FRAME_ARG (arg
, Qbackground_color
, bg
);
5441 Fmodify_frame_parameters (frame
, arg
);
5447 /* Now that the frame will be official, it counts as a reference to
5448 its display and terminal. */
5449 FRAME_DISPLAY_INFO (f
)->reference_count
++;
5450 f
->terminal
->reference_count
++;
5452 /* It is now ok to make the frame official even if we get an error
5453 below. And the frame needs to be on Vframe_list or making it
5454 visible won't work. */
5455 Vframe_list
= Fcons (frame
, Vframe_list
);
5456 f
->can_x_set_window_size
= true;
5458 /* Setting attributes of faces of the tooltip frame from resources
5459 and similar will set face_change, which leads to the clearing of
5460 all current matrices. Since this isn't necessary here, avoid it
5461 by resetting face_change to the value it had before we created
5463 face_change
= face_change_before
;
5465 /* Discard the unwind_protect. */
5466 return unbind_to (count
, frame
);
5470 /* Compute where to display tip frame F. PARMS is the list of frame
5471 parameters for F. DX and DY are specified offsets from the current
5472 location of the mouse. WIDTH and HEIGHT are the width and height
5473 of the tooltip. Return coordinates relative to the root window of
5474 the display in *ROOT_X, and *ROOT_Y. */
5477 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
)
5479 Lisp_Object left
, top
, right
, bottom
;
5484 /* User-specified position? */
5485 left
= Fcdr (Fassq (Qleft
, parms
));
5486 top
= Fcdr (Fassq (Qtop
, parms
));
5487 right
= Fcdr (Fassq (Qright
, parms
));
5488 bottom
= Fcdr (Fassq (Qbottom
, parms
));
5490 /* Move the tooltip window where the mouse pointer is. Resize and
5492 if ((!INTEGERP (left
) && !INTEGERP (right
))
5493 || (!INTEGERP (top
) && !INTEGERP (bottom
)))
5496 XQueryPointer (FRAME_X_DISPLAY (f
), FRAME_DISPLAY_INFO (f
)->root_window
,
5497 &root
, &child
, root_x
, root_y
, &win_x
, &win_y
, &pmask
);
5502 *root_y
= XINT (top
);
5503 else if (INTEGERP (bottom
))
5504 *root_y
= XINT (bottom
) - height
;
5505 else if (*root_y
+ XINT (dy
) <= 0)
5506 *root_y
= 0; /* Can happen for negative dy */
5507 else if (*root_y
+ XINT (dy
) + height
5508 <= x_display_pixel_height (FRAME_DISPLAY_INFO (f
)))
5509 /* It fits below the pointer */
5510 *root_y
+= XINT (dy
);
5511 else if (height
+ XINT (dy
) <= *root_y
)
5512 /* It fits above the pointer. */
5513 *root_y
-= height
+ XINT (dy
);
5515 /* Put it on the top. */
5518 if (INTEGERP (left
))
5519 *root_x
= XINT (left
);
5520 else if (INTEGERP (right
))
5521 *root_y
= XINT (right
) - width
;
5522 else if (*root_x
+ XINT (dx
) <= 0)
5523 *root_x
= 0; /* Can happen for negative dx */
5524 else if (*root_x
+ XINT (dx
) + width
5525 <= x_display_pixel_width (FRAME_DISPLAY_INFO (f
)))
5526 /* It fits to the right of the pointer. */
5527 *root_x
+= XINT (dx
);
5528 else if (width
+ XINT (dx
) <= *root_x
)
5529 /* It fits to the left of the pointer. */
5530 *root_x
-= width
+ XINT (dx
);
5532 /* Put it left-justified on the screen--it ought to fit that way. */
5537 DEFUN ("x-show-tip", Fx_show_tip
, Sx_show_tip
, 1, 6, 0,
5538 doc
: /* Show STRING in a "tooltip" window on frame FRAME.
5539 A tooltip window is a small X window displaying a string.
5541 This is an internal function; Lisp code should call `tooltip-show'.
5543 FRAME nil or omitted means use the selected frame.
5545 PARMS is an optional list of frame parameters which can be used to
5546 change the tooltip's appearance.
5548 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
5549 means use the default timeout of 5 seconds.
5551 If the list of frame parameters PARMS contains a `left' parameter,
5552 display the tooltip at that x-position. If the list of frame parameters
5553 PARMS contains no `left' but a `right' parameter, display the tooltip
5554 right-adjusted at that x-position. Otherwise display it at the
5555 x-position of the mouse, with offset DX added (default is 5 if DX isn't
5558 Likewise for the y-position: If a `top' frame parameter is specified, it
5559 determines the position of the upper edge of the tooltip window. If a
5560 `bottom' parameter but no `top' frame parameter is specified, it
5561 determines the position of the lower edge of the tooltip window.
5562 Otherwise display the tooltip window at the y-position of the mouse,
5563 with offset DY added (default is -10).
5565 A tooltip's maximum size is specified by `x-max-tooltip-size'.
5566 Text larger than the specified size is clipped. */)
5567 (Lisp_Object string
, Lisp_Object frame
, Lisp_Object parms
, Lisp_Object timeout
, Lisp_Object dx
, Lisp_Object dy
)
5572 struct buffer
*old_buffer
;
5573 struct text_pos pos
;
5574 int i
, width
, height
;
5575 bool seen_reversed_p
;
5576 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
5577 ptrdiff_t count
= SPECPDL_INDEX ();
5579 specbind (Qinhibit_redisplay
, Qt
);
5581 CHECK_STRING (string
);
5582 if (SCHARS (string
) == 0)
5583 string
= make_unibyte_string (" ", 1);
5585 f
= decode_window_system_frame (frame
);
5587 timeout
= make_number (5);
5589 CHECK_NATNUM (timeout
);
5592 dx
= make_number (5);
5597 dy
= make_number (-10);
5602 if (x_gtk_use_system_tooltips
)
5606 /* Hide a previous tip, if any. */
5610 ok
= xg_prepare_tooltip (f
, string
, &width
, &height
);
5613 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, &root_x
, &root_y
);
5614 xg_show_tooltip (f
, root_x
, root_y
);
5615 /* This is used in Fx_hide_tip. */
5616 XSETFRAME (tip_frame
, f
);
5619 if (ok
) goto start_timer
;
5621 #endif /* USE_GTK */
5623 if (NILP (last_show_tip_args
))
5624 last_show_tip_args
= Fmake_vector (make_number (3), Qnil
);
5626 if (!NILP (tip_frame
))
5628 Lisp_Object last_string
= AREF (last_show_tip_args
, 0);
5629 Lisp_Object last_frame
= AREF (last_show_tip_args
, 1);
5630 Lisp_Object last_parms
= AREF (last_show_tip_args
, 2);
5632 if (EQ (frame
, last_frame
)
5633 && !NILP (Fequal (last_string
, string
))
5634 && !NILP (Fequal (last_parms
, parms
)))
5636 struct frame
*tip_f
= XFRAME (tip_frame
);
5638 /* Only DX and DY have changed. */
5639 if (!NILP (tip_timer
))
5641 Lisp_Object timer
= tip_timer
;
5643 call1 (Qcancel_timer
, timer
);
5647 compute_tip_xy (tip_f
, parms
, dx
, dy
, FRAME_PIXEL_WIDTH (tip_f
),
5648 FRAME_PIXEL_HEIGHT (tip_f
), &root_x
, &root_y
);
5649 XMoveWindow (FRAME_X_DISPLAY (tip_f
), FRAME_X_WINDOW (tip_f
),
5656 /* Hide a previous tip, if any. */
5659 ASET (last_show_tip_args
, 0, string
);
5660 ASET (last_show_tip_args
, 1, frame
);
5661 ASET (last_show_tip_args
, 2, parms
);
5663 /* Add default values to frame parameters. */
5664 if (NILP (Fassq (Qname
, parms
)))
5665 parms
= Fcons (Fcons (Qname
, build_string ("tooltip")), parms
);
5666 if (NILP (Fassq (Qinternal_border_width
, parms
)))
5667 parms
= Fcons (Fcons (Qinternal_border_width
, make_number (3)), parms
);
5668 if (NILP (Fassq (Qborder_width
, parms
)))
5669 parms
= Fcons (Fcons (Qborder_width
, make_number (1)), parms
);
5670 if (NILP (Fassq (Qbottom_divider_width
, parms
)))
5671 parms
= Fcons (Fcons (Qbottom_divider_width
, make_number (0)), parms
);
5672 if (NILP (Fassq (Qright_divider_width
, parms
)))
5673 parms
= Fcons (Fcons (Qright_divider_width
, make_number (0)), parms
);
5674 if (NILP (Fassq (Qborder_color
, parms
)))
5675 parms
= Fcons (Fcons (Qborder_color
, build_string ("lightyellow")), parms
);
5676 if (NILP (Fassq (Qbackground_color
, parms
)))
5677 parms
= Fcons (Fcons (Qbackground_color
, build_string ("lightyellow")),
5680 /* Create a frame for the tooltip, and record it in the global
5681 variable tip_frame. */
5682 frame
= x_create_tip_frame (FRAME_DISPLAY_INFO (f
), parms
, string
);
5685 /* Set up the frame's root window. */
5686 w
= XWINDOW (FRAME_ROOT_WINDOW (f
));
5692 if (CONSP (Vx_max_tooltip_size
)
5693 && RANGED_INTEGERP (1, XCAR (Vx_max_tooltip_size
), INT_MAX
)
5694 && RANGED_INTEGERP (1, XCDR (Vx_max_tooltip_size
), INT_MAX
))
5696 w
->total_cols
= XFASTINT (XCAR (Vx_max_tooltip_size
));
5697 w
->total_lines
= XFASTINT (XCDR (Vx_max_tooltip_size
));
5702 w
->total_lines
= 40;
5705 w
->pixel_width
= w
->total_cols
* FRAME_COLUMN_WIDTH (f
);
5706 w
->pixel_height
= w
->total_lines
* FRAME_LINE_HEIGHT (f
);
5708 FRAME_TOTAL_COLS (f
) = w
->total_cols
;
5709 adjust_frame_glyphs (f
);
5710 w
->pseudo_window_p
= true;
5712 /* Display the tooltip text in a temporary buffer. */
5713 old_buffer
= current_buffer
;
5714 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f
))->contents
));
5715 bset_truncate_lines (current_buffer
, Qnil
);
5716 clear_glyph_matrix (w
->desired_matrix
);
5717 clear_glyph_matrix (w
->current_matrix
);
5718 SET_TEXT_POS (pos
, BEGV
, BEGV_BYTE
);
5719 try_window (FRAME_ROOT_WINDOW (f
), pos
, TRY_WINDOW_IGNORE_FONTS_CHANGE
);
5721 /* Compute width and height of the tooltip. */
5723 seen_reversed_p
= false;
5724 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
5726 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
5730 /* Stop at the first empty row at the end. */
5731 if (!row
->enabled_p
|| !MATRIX_ROW_DISPLAYS_TEXT_P (row
))
5734 /* Let the row go over the full width of the frame. */
5735 row
->full_width_p
= true;
5737 row_width
= row
->pixel_width
;
5738 if (row
->used
[TEXT_AREA
])
5740 /* There's a glyph at the end of rows that is used to place
5741 the cursor there. Don't include the width of this glyph. */
5742 if (!row
->reversed_p
)
5744 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
5745 if (NILP (last
->object
))
5746 row_width
-= last
->pixel_width
;
5750 /* There could be a stretch glyph at the beginning of R2L
5751 rows that is produced by extend_face_to_end_of_line.
5752 Don't count that glyph. */
5753 struct glyph
*g
= row
->glyphs
[TEXT_AREA
];
5755 if (g
->type
== STRETCH_GLYPH
&& NILP (g
->object
))
5757 row_width
-= g
->pixel_width
;
5758 seen_reversed_p
= true;
5763 height
+= row
->height
;
5764 width
= max (width
, row_width
);
5767 /* If we've seen partial-length R2L rows, we need to re-adjust the
5768 tool-tip frame width and redisplay it again, to avoid over-wide
5769 tips due to the stretch glyph that extends R2L lines to full
5770 width of the frame. */
5771 if (seen_reversed_p
)
5773 /* w->total_cols and FRAME_TOTAL_COLS want the width in columns,
5775 w
->pixel_width
= width
;
5776 width
/= WINDOW_FRAME_COLUMN_WIDTH (w
);
5777 w
->total_cols
= width
;
5778 FRAME_TOTAL_COLS (f
) = width
;
5779 SET_FRAME_WIDTH (f
, width
);
5780 adjust_frame_glyphs (f
);
5781 clear_glyph_matrix (w
->desired_matrix
);
5782 clear_glyph_matrix (w
->current_matrix
);
5783 try_window (FRAME_ROOT_WINDOW (f
), pos
, 0);
5785 /* Recompute width and height of the tooltip. */
5786 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
5788 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
5792 if (!row
->enabled_p
|| !MATRIX_ROW_DISPLAYS_TEXT_P (row
))
5794 row
->full_width_p
= true;
5795 row_width
= row
->pixel_width
;
5796 if (row
->used
[TEXT_AREA
] && !row
->reversed_p
)
5798 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
5799 if (NILP (last
->object
))
5800 row_width
-= last
->pixel_width
;
5803 height
+= row
->height
;
5804 width
= max (width
, row_width
);
5808 /* Add the frame's internal border to the width and height the X
5809 window should have. */
5810 height
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
5811 width
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
5813 /* Move the tooltip window where the mouse pointer is. Resize and
5815 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, &root_x
, &root_y
);
5818 XMoveResizeWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5819 root_x
, root_y
, width
, height
);
5820 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
5823 /* Draw into the window. */
5824 w
->must_be_updated_p
= true;
5825 update_single_window (w
);
5827 /* Restore original current buffer. */
5828 set_buffer_internal_1 (old_buffer
);
5829 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
5832 /* Let the tip disappear after timeout seconds. */
5833 tip_timer
= call3 (intern ("run-at-time"), timeout
, Qnil
,
5834 intern ("x-hide-tip"));
5836 return unbind_to (count
, Qnil
);
5840 DEFUN ("x-hide-tip", Fx_hide_tip
, Sx_hide_tip
, 0, 0, 0,
5841 doc
: /* Hide the current tooltip window, if there is any.
5842 Value is t if tooltip was open, nil otherwise. */)
5846 Lisp_Object deleted
, frame
, timer
;
5848 /* Return quickly if nothing to do. */
5849 if (NILP (tip_timer
) && NILP (tip_frame
))
5854 tip_frame
= tip_timer
= deleted
= Qnil
;
5856 count
= SPECPDL_INDEX ();
5857 specbind (Qinhibit_redisplay
, Qt
);
5858 specbind (Qinhibit_quit
, Qt
);
5861 call1 (Qcancel_timer
, timer
);
5865 /* When using system tooltip, tip_frame is the Emacs frame on which
5866 the tip is shown. */
5867 struct frame
*f
= XFRAME (frame
);
5868 if (FRAME_LIVE_P (f
) && xg_hide_tooltip (f
))
5875 delete_frame (frame
, Qnil
);
5879 /* Bloodcurdling hack alert: The Lucid menu bar widget's
5880 redisplay procedure is not called when a tip frame over menu
5881 items is unmapped. Redisplay the menu manually... */
5884 struct frame
*f
= SELECTED_FRAME ();
5885 w
= f
->output_data
.x
->menubar_widget
;
5887 if (!DoesSaveUnders (FRAME_DISPLAY_INFO (f
)->screen
)
5891 xlwmenu_redisplay (w
);
5895 #endif /* USE_LUCID */
5898 return unbind_to (count
, deleted
);
5903 /***********************************************************************
5904 File selection dialog
5905 ***********************************************************************/
5907 DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog
,
5908 Sx_uses_old_gtk_dialog
,
5910 doc
: /* Return t if the old Gtk+ file selection dialog is used. */)
5916 && window_system_available (SELECTED_FRAME ())
5917 && xg_uses_old_file_dialog ())
5925 /* Callback for "OK" and "Cancel" on file selection dialog. */
5928 file_dialog_cb (Widget widget
, XtPointer client_data
, XtPointer call_data
)
5930 int *result
= client_data
;
5931 XmAnyCallbackStruct
*cb
= call_data
;
5932 *result
= cb
->reason
;
5936 /* Callback for unmapping a file selection dialog. This is used to
5937 capture the case where a dialog is closed via a window manager's
5938 closer button, for example. Using a XmNdestroyCallback didn't work
5942 file_dialog_unmap_cb (Widget widget
, XtPointer client_data
, XtPointer call_data
)
5944 int *result
= client_data
;
5945 *result
= XmCR_CANCEL
;
5949 clean_up_file_dialog (void *arg
)
5951 Widget dialog
= arg
;
5955 XtUnmanageChild (dialog
);
5956 XtDestroyWidget (dialog
);
5957 x_menu_set_in_use (false);
5962 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 5, 0,
5963 doc
: /* Read file name, prompting with PROMPT in directory DIR.
5964 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5965 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5966 or directory must exist.
5968 This function is only defined on NS, MS Windows, and X Windows with the
5969 Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
5970 Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.
5971 On Windows 7 and later, the file selection dialog "remembers" the last
5972 directory where the user selected a file, and will open that directory
5973 instead of DIR on subsequent invocations of this function with the same
5974 value of DIR as in previous invocations; this is standard Windows behavior. */)
5975 (Lisp_Object prompt
, Lisp_Object dir
, Lisp_Object default_filename
,
5976 Lisp_Object mustmatch
, Lisp_Object only_dir_p
)
5979 struct frame
*f
= SELECTED_FRAME ();
5980 Lisp_Object file
= Qnil
;
5981 Lisp_Object decoded_file
;
5982 Widget dialog
, text
, help
;
5985 XmString dir_xmstring
, pattern_xmstring
;
5986 ptrdiff_t count
= SPECPDL_INDEX ();
5988 check_window_system (f
);
5990 if (popup_activated ())
5991 error ("Trying to use a menu from within a menu-entry");
5993 CHECK_STRING (prompt
);
5996 /* Prevent redisplay. */
5997 specbind (Qinhibit_redisplay
, Qt
);
6001 /* Create the dialog with PROMPT as title, using DIR as initial
6002 directory and using "*" as pattern. */
6003 dir
= Fexpand_file_name (dir
, Qnil
);
6004 dir_xmstring
= XmStringCreateLocalized (SSDATA (dir
));
6005 pattern_xmstring
= XmStringCreateLocalized ("*");
6007 XtSetArg (al
[ac
], XmNtitle
, SDATA (prompt
)); ++ac
;
6008 XtSetArg (al
[ac
], XmNdirectory
, dir_xmstring
); ++ac
;
6009 XtSetArg (al
[ac
], XmNpattern
, pattern_xmstring
); ++ac
;
6010 XtSetArg (al
[ac
], XmNresizePolicy
, XmRESIZE_GROW
); ++ac
;
6011 XtSetArg (al
[ac
], XmNdialogStyle
, XmDIALOG_APPLICATION_MODAL
); ++ac
;
6012 dialog
= XmCreateFileSelectionDialog (f
->output_data
.x
->widget
,
6014 XmStringFree (dir_xmstring
);
6015 XmStringFree (pattern_xmstring
);
6017 /* Add callbacks for OK and Cancel. */
6018 XtAddCallback (dialog
, XmNokCallback
, file_dialog_cb
,
6019 (XtPointer
) &result
);
6020 XtAddCallback (dialog
, XmNcancelCallback
, file_dialog_cb
,
6021 (XtPointer
) &result
);
6022 XtAddCallback (dialog
, XmNunmapCallback
, file_dialog_unmap_cb
,
6023 (XtPointer
) &result
);
6025 /* Remove the help button since we can't display help. */
6026 help
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_HELP_BUTTON
);
6027 XtUnmanageChild (help
);
6029 /* Mark OK button as default. */
6030 XtVaSetValues (XmFileSelectionBoxGetChild (dialog
, XmDIALOG_OK_BUTTON
),
6031 XmNshowAsDefault
, True
, NULL
);
6033 /* If MUSTMATCH is non-nil, disable the file entry field of the
6034 dialog, so that the user must select a file from the files list
6035 box. We can't remove it because we wouldn't have a way to get at
6036 the result file name, then. */
6037 text
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
6038 if (!NILP (mustmatch
))
6041 label
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_SELECTION_LABEL
);
6042 XtSetSensitive (text
, False
);
6043 XtSetSensitive (label
, False
);
6046 /* Manage the dialog, so that list boxes get filled. */
6047 XtManageChild (dialog
);
6049 if (STRINGP (default_filename
))
6051 XmString default_xmstring
;
6052 Widget wtext
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
6053 Widget list
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_LIST
);
6055 XmTextPosition last_pos
= XmTextFieldGetLastPosition (wtext
);
6056 XmTextFieldReplace (wtext
, 0, last_pos
,
6057 (SSDATA (Ffile_name_nondirectory (default_filename
))));
6059 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
6060 must include the path for this to work. */
6062 default_xmstring
= XmStringCreateLocalized (SSDATA (default_filename
));
6064 if (XmListItemExists (list
, default_xmstring
))
6066 int item_pos
= XmListItemPos (list
, default_xmstring
);
6067 /* Select the item and scroll it into view. */
6068 XmListSelectPos (list
, item_pos
, True
);
6069 XmListSetPos (list
, item_pos
);
6072 XmStringFree (default_xmstring
);
6075 record_unwind_protect_ptr (clean_up_file_dialog
, dialog
);
6077 /* Process events until the user presses Cancel or OK. */
6078 x_menu_set_in_use (true);
6083 x_menu_wait_for_event (0);
6084 XtAppNextEvent (Xt_app_con
, &event
);
6085 if (event
.type
== KeyPress
6086 && FRAME_X_DISPLAY (f
) == event
.xkey
.display
)
6088 KeySym keysym
= XLookupKeysym (&event
.xkey
, 0);
6090 /* Pop down on C-g. */
6091 if (keysym
== XK_g
&& (event
.xkey
.state
& ControlMask
) != 0)
6092 XtUnmanageChild (dialog
);
6095 (void) x_dispatch_event (&event
, FRAME_X_DISPLAY (f
));
6098 /* Get the result. */
6099 if (result
== XmCR_OK
)
6101 XmString text_string
;
6104 XtVaGetValues (dialog
, XmNtextString
, &text_string
, NULL
);
6105 XmStringGetLtoR (text_string
, XmFONTLIST_DEFAULT_TAG
, &data
);
6106 XmStringFree (text_string
);
6107 file
= build_string (data
);
6115 /* Make "Cancel" equivalent to C-g. */
6117 Fsignal (Qquit
, Qnil
);
6119 decoded_file
= DECODE_FILE (file
);
6121 return unbind_to (count
, decoded_file
);
6124 #endif /* USE_MOTIF */
6129 clean_up_dialog (void)
6131 x_menu_set_in_use (false);
6134 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 5, 0,
6135 doc
: /* Read file name, prompting with PROMPT in directory DIR.
6136 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
6137 selection box, if specified. If MUSTMATCH is non-nil, the returned file
6138 or directory must exist.
6140 This function is only defined on NS, MS Windows, and X Windows with the
6141 Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
6142 Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.
6143 On Windows 7 and later, the file selection dialog "remembers" the last
6144 directory where the user selected a file, and will open that directory
6145 instead of DIR on subsequent invocations of this function with the same
6146 value of DIR as in previous invocations; this is standard Windows behavior. */)
6147 (Lisp_Object prompt
, Lisp_Object dir
, Lisp_Object default_filename
, Lisp_Object mustmatch
, Lisp_Object only_dir_p
)
6149 struct frame
*f
= SELECTED_FRAME ();
6151 Lisp_Object file
= Qnil
;
6152 Lisp_Object decoded_file
;
6153 ptrdiff_t count
= SPECPDL_INDEX ();
6156 check_window_system (f
);
6158 if (popup_activated ())
6159 error ("Trying to use a menu from within a menu-entry");
6161 CHECK_STRING (prompt
);
6164 /* Prevent redisplay. */
6165 specbind (Qinhibit_redisplay
, Qt
);
6166 record_unwind_protect_void (clean_up_dialog
);
6170 if (STRINGP (default_filename
))
6171 cdef_file
= SSDATA (default_filename
);
6173 cdef_file
= SSDATA (dir
);
6175 fn
= xg_get_file_name (f
, SSDATA (prompt
), cdef_file
,
6177 ! NILP (only_dir_p
));
6181 file
= build_string (fn
);
6187 /* Make "Cancel" equivalent to C-g. */
6189 Fsignal (Qquit
, Qnil
);
6191 decoded_file
= DECODE_FILE (file
);
6193 return unbind_to (count
, decoded_file
);
6197 #ifdef HAVE_FREETYPE
6199 DEFUN ("x-select-font", Fx_select_font
, Sx_select_font
, 0, 2, 0,
6200 doc
: /* Read a font using a GTK dialog.
6201 Return either a font spec (for GTK versions >= 3.2) or a string
6202 containing a GTK-style font name.
6204 FRAME is the frame on which to pop up the font chooser. If omitted or
6205 nil, it defaults to the selected frame. */)
6206 (Lisp_Object frame
, Lisp_Object ignored
)
6208 struct frame
*f
= decode_window_system_frame (frame
);
6210 Lisp_Object font_param
;
6211 char *default_name
= NULL
;
6212 ptrdiff_t count
= SPECPDL_INDEX ();
6214 if (popup_activated ())
6215 error ("Trying to use a menu from within a menu-entry");
6217 /* Prevent redisplay. */
6218 specbind (Qinhibit_redisplay
, Qt
);
6219 record_unwind_protect_void (clean_up_dialog
);
6223 XSETFONT (font
, FRAME_FONT (f
));
6224 font_param
= Ffont_get (font
, QCname
);
6225 if (STRINGP (font_param
))
6226 default_name
= xlispstrdup (font_param
);
6229 font_param
= Fframe_parameter (frame
, Qfont_param
);
6230 if (STRINGP (font_param
))
6231 default_name
= xlispstrdup (font_param
);
6234 font
= xg_get_font (f
, default_name
);
6235 xfree (default_name
);
6240 Fsignal (Qquit
, Qnil
);
6242 return unbind_to (count
, font
);
6244 #endif /* HAVE_FREETYPE */
6246 #endif /* USE_GTK */
6249 /***********************************************************************
6251 ***********************************************************************/
6254 #include <X11/XKBlib.h>
6255 #include <X11/keysym.h>
6258 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p
,
6259 Sx_backspace_delete_keys_p
, 0, 1, 0,
6260 doc
: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
6261 FRAME nil means use the selected frame.
6262 Value is t if we know that both keys are present, and are mapped to the
6263 usual X keysyms. Value is `lambda' if we cannot determine if both keys are
6264 present and mapped to the usual X keysyms. */)
6271 struct frame
*f
= decode_window_system_frame (frame
);
6272 Display
*dpy
= FRAME_X_DISPLAY (f
);
6273 Lisp_Object have_keys
;
6274 int major
, minor
, op
, event
, error_code
;
6278 /* Check library version in case we're dynamically linked. */
6279 major
= XkbMajorVersion
;
6280 minor
= XkbMinorVersion
;
6281 if (!XkbLibraryVersion (&major
, &minor
))
6287 /* Check that the server supports XKB. */
6288 major
= XkbMajorVersion
;
6289 minor
= XkbMinorVersion
;
6290 if (!XkbQueryExtension (dpy
, &op
, &event
, &error_code
, &major
, &minor
))
6296 /* In this code we check that the keyboard has physical keys with names
6297 that start with BKSP (Backspace) and DELE (Delete), and that they
6298 generate keysym XK_BackSpace and XK_Delete respectively.
6299 This function is used to test if normal-erase-is-backspace should be
6301 An alternative approach would be to just check if XK_BackSpace and
6302 XK_Delete are mapped to any key. But if any of those are mapped to
6303 some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the
6304 user doesn't know about it, it is better to return false here.
6305 It is more obvious to the user what to do if she/he has two keys
6306 clearly marked with names/symbols and one key does something not
6307 expected (i.e. she/he then tries the other).
6308 The cases where Backspace/Delete is mapped to some other key combination
6309 are rare, and in those cases, normal-erase-is-backspace can be turned on
6313 kb
= XkbGetMap (dpy
, XkbAllMapComponentsMask
, XkbUseCoreKbd
);
6316 int delete_keycode
= 0, backspace_keycode
= 0, i
;
6318 if (XkbGetNames (dpy
, XkbAllNamesMask
, kb
) == Success
)
6320 for (i
= kb
->min_key_code
;
6321 (i
< kb
->max_key_code
6322 && (delete_keycode
== 0 || backspace_keycode
== 0));
6325 /* The XKB symbolic key names can be seen most easily in
6326 the PS file generated by `xkbprint -label name
6328 if (memcmp ("DELE", kb
->names
->keys
[i
].name
, 4) == 0)
6330 else if (memcmp ("BKSP", kb
->names
->keys
[i
].name
, 4) == 0)
6331 backspace_keycode
= i
;
6334 XkbFreeNames (kb
, 0, True
);
6337 /* As of libX11-1.6.2, XkbGetMap manual says that you should use
6338 XkbFreeClientMap to free the data returned by XkbGetMap. But
6339 this function just frees the data referenced from KB and not
6340 KB itself. To free KB as well, call XkbFreeKeyboard. */
6341 XkbFreeKeyboard (kb
, XkbAllMapComponentsMask
, True
);
6344 && backspace_keycode
6345 && XKeysymToKeycode (dpy
, XK_Delete
) == delete_keycode
6346 && XKeysymToKeycode (dpy
, XK_BackSpace
) == backspace_keycode
)
6356 /***********************************************************************
6358 ***********************************************************************/
6361 DEFUN ("x-export-frames", Fx_export_frames
, Sx_export_frames
, 0, 2, 0,
6362 doc
: /* XXX Experimental. Return image data of FRAMES in TYPE format.
6363 FRAMES should be nil (the selected frame), a frame, or a list of
6364 frames (each of which corresponds to one page). Optional arg TYPE
6365 should be either `pdf' (default), `png', `ps', or `svg'. Supported
6366 types are determined by the compile-time configuration of cairo. */)
6367 (Lisp_Object frames
, Lisp_Object type
)
6369 Lisp_Object result
, rest
, tmp
;
6370 cairo_surface_type_t surface_type
;
6373 frames
= selected_frame
;
6374 if (!CONSP (frames
))
6375 frames
= list1 (frames
);
6378 for (rest
= frames
; CONSP (rest
); rest
= XCDR (rest
))
6380 struct frame
*f
= XFRAME (XCAR (rest
));
6382 if (! FRAME_LIVE_P (f
) || ! FRAME_X_P (f
) || ! FRAME_LIVE_P (f
))
6383 error ("Invalid frame");
6387 XSETFRAME (frame
, f
);
6388 tmp
= Fcons (frame
, tmp
);
6390 frames
= Fnreverse (tmp
);
6392 #ifdef CAIRO_HAS_PDF_SURFACE
6393 if (NILP (type
) || EQ (type
, intern ("pdf"))) /* XXX: Qpdf */
6394 surface_type
= CAIRO_SURFACE_TYPE_PDF
;
6397 #ifdef CAIRO_HAS_PNG_FUNCTIONS
6398 if (EQ (type
, intern ("png")))
6400 if (!NILP (XCDR (frames
)))
6401 error ("PNG export cannot handle multiple frames.");
6402 surface_type
= CAIRO_SURFACE_TYPE_IMAGE
;
6406 #ifdef CAIRO_HAS_PS_SURFACE
6407 if (EQ (type
, intern ("ps")))
6408 surface_type
= CAIRO_SURFACE_TYPE_PS
;
6411 #ifdef CAIRO_HAS_SVG_SURFACE
6412 if (EQ (type
, intern ("svg")))
6414 /* For now, we stick to SVG 1.1. */
6415 if (!NILP (XCDR (frames
)))
6416 error ("SVG export cannot handle multiple frames.");
6417 surface_type
= CAIRO_SURFACE_TYPE_SVG
;
6421 error ("Unsupported export type");
6423 result
= x_cr_export_frames (frames
, surface_type
);
6429 DEFUN ("x-page-setup-dialog", Fx_page_setup_dialog
, Sx_page_setup_dialog
, 0, 0, 0,
6430 doc
: /* Pop up a page setup dialog.
6431 The current page setup can be obtained using `x-get-page-setup'. */)
6435 xg_page_setup_dialog ();
6441 DEFUN ("x-get-page-setup", Fx_get_page_setup
, Sx_get_page_setup
, 0, 0, 0,
6442 doc
: /* Return the value of the current page setup.
6443 The return value is an alist containing the following keys:
6445 orientation: page orientation (symbol `portrait', `landscape',
6446 `reverse-portrait', or `reverse-landscape').
6447 width, height: page width/height in points not including margins.
6448 left-margin, right-margin, top-margin, bottom-margin: print margins,
6449 which is the parts of the page that the printer cannot print
6452 The paper width can be obtained as the sum of width, left-margin, and
6453 right-margin values. Likewise, the paper height is the sum of height,
6454 top-margin, and bottom-margin values. */)
6460 result
= xg_get_page_setup ();
6466 DEFUN ("x-print-frames-dialog", Fx_print_frames_dialog
, Sx_print_frames_dialog
, 0, 1, "",
6467 doc
: /* Pop up a print dialog to print the current contents of FRAMES.
6468 FRAMES should be nil (the selected frame), a frame, or a list of
6469 frames (each of which corresponds to one page). Each frame should be
6471 (Lisp_Object frames
)
6473 Lisp_Object rest
, tmp
;
6476 frames
= selected_frame
;
6477 if (!CONSP (frames
))
6478 frames
= list1 (frames
);
6481 for (rest
= frames
; CONSP (rest
); rest
= XCDR (rest
))
6483 struct frame
*f
= XFRAME (XCAR (rest
));
6484 if (! FRAME_LIVE_P (f
) || ! FRAME_X_P (f
) || ! FRAME_LIVE_P (f
))
6485 error ("Invalid frame");
6488 XSETFRAME (frame
, f
);
6489 if (!EQ (Fframe_visible_p (frame
), Qt
))
6490 error ("Frames to be printed must be visible.");
6491 tmp
= Fcons (frame
, tmp
);
6493 frames
= Fnreverse (tmp
);
6495 /* Make sure the current matrices are up-to-date. */
6499 xg_print_frames_dialog (frames
);
6504 #endif /* USE_GTK */
6505 #endif /* USE_CAIRO */
6508 /***********************************************************************
6510 ***********************************************************************/
6512 /* Keep this list in the same order as frame_parms in frame.c.
6513 Use 0 for unsupported frame parameters. */
6515 frame_parm_handler x_frame_parm_handlers
[] =
6519 x_set_background_color
,
6525 x_set_foreground_color
,
6528 x_set_internal_border_width
,
6529 x_set_right_divider_width
,
6530 x_set_bottom_divider_width
,
6531 x_set_menu_bar_lines
,
6533 x_explicitly_set_name
,
6534 x_set_scroll_bar_width
,
6535 x_set_scroll_bar_height
,
6538 x_set_vertical_scroll_bars
,
6539 x_set_horizontal_scroll_bars
,
6541 x_set_tool_bar_lines
,
6542 x_set_scroll_bar_foreground
,
6543 x_set_scroll_bar_background
,
6553 x_set_tool_bar_position
,
6559 DEFSYM (Qundefined_color
, "undefined-color");
6560 DEFSYM (Qcompound_text
, "compound-text");
6561 DEFSYM (Qcancel_timer
, "cancel-timer");
6562 DEFSYM (Qfont_param
, "font-parameter");
6563 DEFSYM (Qmono
, "mono");
6566 DEFSYM (Qorientation
, "orientation");
6567 DEFSYM (Qtop_margin
, "top-margin");
6568 DEFSYM (Qbottom_margin
, "bottom-margin");
6569 DEFSYM (Qportrait
, "portrait");
6570 DEFSYM (Qlandscape
, "landscape");
6571 DEFSYM (Qreverse_portrait
, "reverse-portrait");
6572 DEFSYM (Qreverse_landscape
, "reverse-landscape");
6575 Fput (Qundefined_color
, Qerror_conditions
,
6576 listn (CONSTYPE_PURE
, 2, Qundefined_color
, Qerror
));
6577 Fput (Qundefined_color
, Qerror_message
,
6578 build_pure_c_string ("Undefined color"));
6580 DEFVAR_LISP ("x-pointer-shape", Vx_pointer_shape
,
6581 doc
: /* The shape of the pointer when over text.
6582 Changing the value does not affect existing frames
6583 unless you set the mouse color. */);
6584 Vx_pointer_shape
= Qnil
;
6586 #if false /* This doesn't really do anything. */
6587 DEFVAR_LISP ("x-nontext-pointer-shape", Vx_nontext_pointer_shape
,
6588 doc
: /* The shape of the pointer when not over text.
6589 This variable takes effect when you create a new frame
6590 or when you set the mouse color. */);
6592 Vx_nontext_pointer_shape
= Qnil
;
6594 DEFVAR_LISP ("x-hourglass-pointer-shape", Vx_hourglass_pointer_shape
,
6595 doc
: /* The shape of the pointer when Emacs is busy.
6596 This variable takes effect when you create a new frame
6597 or when you set the mouse color. */);
6598 Vx_hourglass_pointer_shape
= Qnil
;
6600 #if false /* This doesn't really do anything. */
6601 DEFVAR_LISP ("x-mode-pointer-shape", Vx_mode_pointer_shape
,
6602 doc
: /* The shape of the pointer when over the mode line.
6603 This variable takes effect when you create a new frame
6604 or when you set the mouse color. */);
6606 Vx_mode_pointer_shape
= Qnil
;
6608 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
6609 Vx_sensitive_text_pointer_shape
,
6610 doc
: /* The shape of the pointer when over mouse-sensitive text.
6611 This variable takes effect when you create a new frame
6612 or when you set the mouse color. */);
6613 Vx_sensitive_text_pointer_shape
= Qnil
;
6615 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
6616 Vx_window_horizontal_drag_shape
,
6617 doc
: /* Pointer shape to use for indicating a window can be dragged horizontally.
6618 This variable takes effect when you create a new frame
6619 or when you set the mouse color. */);
6620 Vx_window_horizontal_drag_shape
= Qnil
;
6622 DEFVAR_LISP ("x-window-vertical-drag-cursor",
6623 Vx_window_vertical_drag_shape
,
6624 doc
: /* Pointer shape to use for indicating a window can be dragged vertically.
6625 This variable takes effect when you create a new frame
6626 or when you set the mouse color. */);
6627 Vx_window_vertical_drag_shape
= Qnil
;
6629 DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel
,
6630 doc
: /* A string indicating the foreground color of the cursor box. */);
6631 Vx_cursor_fore_pixel
= Qnil
;
6633 DEFVAR_LISP ("x-max-tooltip-size", Vx_max_tooltip_size
,
6634 doc
: /* Maximum size for tooltips.
6635 Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */);
6636 Vx_max_tooltip_size
= Fcons (make_number (80), make_number (40));
6638 DEFVAR_LISP ("x-no-window-manager", Vx_no_window_manager
,
6639 doc
: /* Non-nil if no X window manager is in use.
6640 Emacs doesn't try to figure this out; this is always nil
6641 unless you set it to something else. */);
6642 /* We don't have any way to find this out, so set it to nil
6643 and maybe the user would like to set it to t. */
6644 Vx_no_window_manager
= Qnil
;
6646 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
6647 Vx_pixel_size_width_font_regexp
,
6648 doc
: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
6650 Since Emacs gets width of a font matching with this regexp from
6651 PIXEL_SIZE field of the name, font finding mechanism gets faster for
6652 such a font. This is especially effective for such large fonts as
6653 Chinese, Japanese, and Korean. */);
6654 Vx_pixel_size_width_font_regexp
= Qnil
;
6656 /* This is not ifdef:ed, so other builds than GTK can customize it. */
6657 DEFVAR_BOOL ("x-gtk-use-old-file-dialog", x_gtk_use_old_file_dialog
,
6658 doc
: /* Non-nil means prompt with the old GTK file selection dialog.
6659 If nil or if the file selection dialog is not available, the new GTK file
6660 chooser is used instead. To turn off all file dialogs set the
6661 variable `use-file-dialog'. */);
6662 x_gtk_use_old_file_dialog
= false;
6664 DEFVAR_BOOL ("x-gtk-show-hidden-files", x_gtk_show_hidden_files
,
6665 doc
: /* If non-nil, the GTK file chooser will by default show hidden files.
6666 Note that this is just the default, there is a toggle button on the file
6667 chooser to show or not show hidden files on a case by case basis. */);
6668 x_gtk_show_hidden_files
= false;
6670 DEFVAR_BOOL ("x-gtk-file-dialog-help-text", x_gtk_file_dialog_help_text
,
6671 doc
: /* If non-nil, the GTK file chooser will show additional help text.
6672 If more space for files in the file chooser dialog is wanted, set this to nil
6673 to turn the additional text off. */);
6674 x_gtk_file_dialog_help_text
= true;
6676 DEFVAR_BOOL ("x-gtk-use-system-tooltips", x_gtk_use_system_tooltips
,
6677 doc
: /* If non-nil with a Gtk+ built Emacs, the Gtk+ tooltip is used.
6678 Otherwise use Emacs own tooltip implementation.
6679 When using Gtk+ tooltips, the tooltip face is not used. */);
6680 x_gtk_use_system_tooltips
= true;
6682 /* Tell Emacs about this window system. */
6683 Fprovide (Qx
, Qnil
);
6685 #ifdef USE_X_TOOLKIT
6686 Fprovide (intern_c_string ("x-toolkit"), Qnil
);
6688 Fprovide (intern_c_string ("motif"), Qnil
);
6690 DEFVAR_LISP ("motif-version-string", Vmotif_version_string
,
6691 doc
: /* Version info for LessTif/Motif. */);
6692 Vmotif_version_string
= build_string (XmVERSION_STRING
);
6693 #endif /* USE_MOTIF */
6694 #endif /* USE_X_TOOLKIT */
6697 /* Provide x-toolkit also for GTK. Internally GTK does not use Xt so it
6698 is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
6699 But for a user it is a toolkit for X, and indeed, configure
6700 accepts --with-x-toolkit=gtk. */
6701 Fprovide (intern_c_string ("x-toolkit"), Qnil
);
6702 Fprovide (intern_c_string ("gtk"), Qnil
);
6703 Fprovide (intern_c_string ("move-toolbar"), Qnil
);
6705 DEFVAR_LISP ("gtk-version-string", Vgtk_version_string
,
6706 doc
: /* Version info for GTK+. */);
6708 char gtk_version
[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
6709 int len
= sprintf (gtk_version
, "%d.%d.%d",
6710 GTK_MAJOR_VERSION
, GTK_MINOR_VERSION
, GTK_MICRO_VERSION
);
6711 Vgtk_version_string
= make_pure_string (gtk_version
, len
, len
, false);
6713 #endif /* USE_GTK */
6716 Fprovide (intern_c_string ("cairo"), Qnil
);
6718 DEFVAR_LISP ("cairo-version-string", Vcairo_version_string
,
6719 doc
: /* Version info for cairo. */);
6721 char cairo_version
[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
6722 int len
= sprintf (cairo_version
, "%d.%d.%d",
6723 CAIRO_VERSION_MAJOR
, CAIRO_VERSION_MINOR
,
6724 CAIRO_VERSION_MICRO
);
6725 Vcairo_version_string
= make_pure_string (cairo_version
, len
, len
, false);
6729 /* X window properties. */
6730 defsubr (&Sx_change_window_property
);
6731 defsubr (&Sx_delete_window_property
);
6732 defsubr (&Sx_window_property
);
6734 defsubr (&Sxw_display_color_p
);
6735 defsubr (&Sx_display_grayscale_p
);
6736 defsubr (&Sxw_color_defined_p
);
6737 defsubr (&Sxw_color_values
);
6738 defsubr (&Sx_server_max_request_size
);
6739 defsubr (&Sx_server_vendor
);
6740 defsubr (&Sx_server_version
);
6741 defsubr (&Sx_display_pixel_width
);
6742 defsubr (&Sx_display_pixel_height
);
6743 defsubr (&Sx_display_mm_width
);
6744 defsubr (&Sx_display_mm_height
);
6745 defsubr (&Sx_display_screens
);
6746 defsubr (&Sx_display_planes
);
6747 defsubr (&Sx_display_color_cells
);
6748 defsubr (&Sx_display_visual_class
);
6749 defsubr (&Sx_display_backing_store
);
6750 defsubr (&Sx_display_save_under
);
6751 defsubr (&Sx_display_monitor_attributes_list
);
6752 defsubr (&Sx_frame_geometry
);
6753 defsubr (&Sx_frame_edges
);
6754 defsubr (&Sx_mouse_absolute_pixel_position
);
6755 defsubr (&Sx_set_mouse_absolute_pixel_position
);
6756 defsubr (&Sx_wm_set_size_hint
);
6757 defsubr (&Sx_create_frame
);
6758 defsubr (&Sx_open_connection
);
6759 defsubr (&Sx_close_connection
);
6760 defsubr (&Sx_display_list
);
6761 defsubr (&Sx_synchronize
);
6762 defsubr (&Sx_backspace_delete_keys_p
);
6764 defsubr (&Sx_show_tip
);
6765 defsubr (&Sx_hide_tip
);
6767 staticpro (&tip_timer
);
6769 staticpro (&tip_frame
);
6771 last_show_tip_args
= Qnil
;
6772 staticpro (&last_show_tip_args
);
6774 defsubr (&Sx_uses_old_gtk_dialog
);
6775 #if defined (USE_MOTIF) || defined (USE_GTK)
6776 defsubr (&Sx_file_dialog
);
6779 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
6780 defsubr (&Sx_select_font
);
6784 defsubr (&Sx_export_frames
);
6786 defsubr (&Sx_page_setup_dialog
);
6787 defsubr (&Sx_get_page_setup
);
6788 defsubr (&Sx_print_frames_dialog
);