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
)
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
, &ign
, &ign
);
262 XWindowAttributes atts
;
263 XGetWindowAttributes (FRAME_X_DISPLAY (f
), win
, &atts
);
264 *outer_border
= atts
.border_width
;
267 /* Translate real coordinates to coordinates relative to our
268 window. For our window, the upper left corner is 0, 0.
269 Since the upper left corner of the WM window is outside
270 our window, win_x and win_y will be negative:
272 ------------------ ---> x
274 | ----------------- v y
277 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
279 /* From-window, to-window. */
280 FRAME_DISPLAY_INFO (f
)->root_window
,
283 /* From-position, to-position. */
284 real_x
, real_y
, &win_x
, &win_y
,
289 if (FRAME_X_WINDOW (f
) == FRAME_OUTER_WINDOW (f
))
296 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
298 /* From-window, to-window. */
299 FRAME_DISPLAY_INFO (f
)->root_window
,
300 FRAME_OUTER_WINDOW (f
),
302 /* From-position, to-position. */
303 real_x
, real_y
, &outer_x
, &outer_y
,
309 had_errors
= x_had_errors_p (FRAME_X_DISPLAY (f
));
313 if (dpyinfo
->root_window
== f
->output_data
.x
->parent_desc
)
315 /* Try _NET_FRAME_EXTENTS if our parent is the root window. */
316 rc
= XGetWindowProperty (dpy
, win
, dpyinfo
->Xatom_net_frame_extents
,
317 0, max_len
, False
, target_type
,
318 &actual_type
, &actual_format
, &actual_size
,
319 &bytes_remaining
, &tmp_data
);
321 if (rc
== Success
&& actual_type
== target_type
&& !x_had_errors_p (dpy
)
322 && actual_size
== 4 && actual_format
== 32)
326 long *fe
= (long *)tmp_data
;
328 XGetGeometry (FRAME_X_DISPLAY (f
), win
,
329 &rootw
, &real_x
, &real_y
, &ign
, &ign
, &ign
, &ign
);
337 if (tmp_data
) XFree (tmp_data
);
343 if (had_errors
) return;
345 if (x_pixels_diff
) *x_pixels_diff
= -win_x
;
346 if (y_pixels_diff
) *y_pixels_diff
= -win_y
;
348 if (left_offset_x
) *left_offset_x
= -outer_x
;
349 if (top_offset_y
) *top_offset_y
= -outer_y
;
351 if (xptr
) *xptr
= real_x
;
352 if (yptr
) *yptr
= real_y
;
354 if (right_offset_x
|| bottom_offset_y
)
357 unsigned int ign
, fw
, fh
;
360 XGetGeometry (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
361 &rootw
, &xy_ign
, &xy_ign
, &fw
, &fh
, &ign
, &ign
);
362 if (right_offset_x
) *right_offset_x
= ow
- fw
+ outer_x
;
363 if (bottom_offset_y
) *bottom_offset_y
= oh
- fh
+ outer_y
;
367 /* Store the screen positions of frame F into XPTR and YPTR.
368 These are the positions of the containing window manager window,
369 not Emacs's own window. */
372 x_real_positions (struct frame
*f
, int *xptr
, int *yptr
)
374 x_real_pos_and_offsets (f
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, xptr
, yptr
,
379 /* Get the mouse position in frame relative coordinates. */
382 x_relative_mouse_position (struct frame
*f
, int *x
, int *y
)
384 Window root
, dummy_window
;
387 eassert (FRAME_X_P (f
));
391 XQueryPointer (FRAME_X_DISPLAY (f
),
392 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
394 /* The root window which contains the pointer. */
397 /* Window pointer is on, not used */
400 /* The position on that root window. */
403 /* x/y in dummy_window coordinates, not used. */
406 /* Modifier keys and pointer buttons, about which
408 (unsigned int *) &dummy
);
410 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
412 /* From-window, to-window. */
413 FRAME_DISPLAY_INFO (f
)->root_window
,
416 /* From-position, to-position. */
425 /* Gamma-correct COLOR on frame F. */
428 gamma_correct (struct frame
*f
, XColor
*color
)
432 color
->red
= pow (color
->red
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
433 color
->green
= pow (color
->green
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
434 color
->blue
= pow (color
->blue
/ 65535.0, f
->gamma
) * 65535.0 + 0.5;
439 /* Decide if color named COLOR_NAME is valid for use on frame F. If
440 so, return the RGB values in COLOR. If ALLOC_P,
441 allocate the color. Value is false if COLOR_NAME is invalid, or
442 no color could be allocated. */
445 x_defined_color (struct frame
*f
, const char *color_name
,
446 XColor
*color
, bool alloc_p
)
448 bool success_p
= false;
449 Display
*dpy
= FRAME_X_DISPLAY (f
);
450 Colormap cmap
= FRAME_X_COLORMAP (f
);
454 success_p
= xg_check_special_colors (f
, color_name
, color
);
457 success_p
= XParseColor (dpy
, cmap
, color_name
, color
) != 0;
458 if (success_p
&& alloc_p
)
459 success_p
= x_alloc_nearest_color (f
, cmap
, color
);
466 /* Return the pixel color value for color COLOR_NAME on frame F. If F
467 is a monochrome frame, return MONO_COLOR regardless of what ARG says.
468 Signal an error if color can't be allocated. */
471 x_decode_color (struct frame
*f
, Lisp_Object color_name
, int mono_color
)
475 CHECK_STRING (color_name
);
477 #if false /* Don't do this. It's wrong when we're not using the default
478 colormap, it makes freeing difficult, and it's probably not
479 an important optimization. */
480 if (strcmp (SDATA (color_name
), "black") == 0)
481 return BLACK_PIX_DEFAULT (f
);
482 else if (strcmp (SDATA (color_name
), "white") == 0)
483 return WHITE_PIX_DEFAULT (f
);
486 /* Return MONO_COLOR for monochrome frames. */
487 if (FRAME_DISPLAY_INFO (f
)->n_planes
== 1)
490 /* x_defined_color is responsible for coping with failures
491 by looking for a near-miss. */
492 if (x_defined_color (f
, SSDATA (color_name
), &cdef
, true))
495 signal_error ("Undefined color", color_name
);
500 /* Change the `wait-for-wm' frame parameter of frame F. OLD_VALUE is
501 the previous value of that parameter, NEW_VALUE is the new value.
502 See also the comment of wait_for_wm in struct x_output. */
505 x_set_wait_for_wm (struct frame
*f
, Lisp_Object new_value
, Lisp_Object old_value
)
507 f
->output_data
.x
->wait_for_wm
= !NILP (new_value
);
511 x_set_tool_bar_position (struct frame
*f
,
512 Lisp_Object new_value
,
513 Lisp_Object old_value
)
515 Lisp_Object choice
= list4 (Qleft
, Qright
, Qtop
, Qbottom
);
517 if (!NILP (Fmemq (new_value
, choice
)))
520 if (!EQ (new_value
, old_value
))
522 xg_change_toolbar_position (f
, new_value
);
523 fset_tool_bar_position (f
, new_value
);
526 if (!EQ (new_value
, Qtop
))
527 error ("The only supported tool bar position is top");
531 wrong_choice (choice
, new_value
);
536 /* Set icon from FILE for frame F. By using GTK functions the icon
537 may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
540 xg_set_icon (struct frame
*f
, Lisp_Object file
)
545 found
= x_find_image_file (file
);
551 char *filename
= SSDATA (ENCODE_FILE (found
));
554 pixbuf
= gdk_pixbuf_new_from_file (filename
, &err
);
558 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
560 g_object_unref (pixbuf
);
574 xg_set_icon_from_xpm_data (struct frame
*f
, const char **data
)
576 GdkPixbuf
*pixbuf
= gdk_pixbuf_new_from_xpm_data (data
);
581 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)), pixbuf
);
582 g_object_unref (pixbuf
);
588 /* Functions called only from `x_set_frame_param'
589 to set individual parameters.
591 If FRAME_X_WINDOW (f) is 0,
592 the frame is being created and its X-window does not exist yet.
593 In that case, just record the parameter's new value
594 in the standard place; do not attempt to change the window. */
597 x_set_foreground_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
599 struct x_output
*x
= f
->output_data
.x
;
600 unsigned long fg
, old_fg
;
602 fg
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
603 old_fg
= FRAME_FOREGROUND_PIXEL (f
);
604 FRAME_FOREGROUND_PIXEL (f
) = fg
;
606 if (FRAME_X_WINDOW (f
) != 0)
608 Display
*dpy
= FRAME_X_DISPLAY (f
);
611 XSetForeground (dpy
, x
->normal_gc
, fg
);
612 XSetBackground (dpy
, x
->reverse_gc
, fg
);
614 if (x
->cursor_pixel
== old_fg
)
616 unload_color (f
, x
->cursor_pixel
);
617 x
->cursor_pixel
= x_copy_color (f
, fg
);
618 XSetBackground (dpy
, x
->cursor_gc
, x
->cursor_pixel
);
623 update_face_from_frame_parameter (f
, Qforeground_color
, arg
);
625 if (FRAME_VISIBLE_P (f
))
629 unload_color (f
, old_fg
);
633 x_set_background_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
635 struct x_output
*x
= f
->output_data
.x
;
638 bg
= x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
639 unload_color (f
, FRAME_BACKGROUND_PIXEL (f
));
640 FRAME_BACKGROUND_PIXEL (f
) = bg
;
642 if (FRAME_X_WINDOW (f
) != 0)
644 Display
*dpy
= FRAME_X_DISPLAY (f
);
647 XSetBackground (dpy
, x
->normal_gc
, bg
);
648 XSetForeground (dpy
, x
->reverse_gc
, bg
);
649 XSetWindowBackground (dpy
, FRAME_X_WINDOW (f
), bg
);
650 XSetForeground (dpy
, x
->cursor_gc
, bg
);
653 xg_set_background_color (f
, bg
);
656 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
657 toolkit scroll bars. */
660 for (bar
= FRAME_SCROLL_BARS (f
);
662 bar
= XSCROLL_BAR (bar
)->next
)
664 Window window
= XSCROLL_BAR (bar
)->x_window
;
665 XSetWindowBackground (dpy
, window
, bg
);
668 #endif /* USE_TOOLKIT_SCROLL_BARS */
671 update_face_from_frame_parameter (f
, Qbackground_color
, arg
);
673 if (FRAME_VISIBLE_P (f
))
679 x_set_mouse_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
681 struct x_output
*x
= f
->output_data
.x
;
682 Display
*dpy
= FRAME_X_DISPLAY (f
);
683 Cursor cursor
, nontext_cursor
, mode_cursor
, hand_cursor
;
684 Cursor hourglass_cursor
, horizontal_drag_cursor
, vertical_drag_cursor
;
685 unsigned long pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
686 unsigned long mask_color
= FRAME_BACKGROUND_PIXEL (f
);
688 /* Don't let pointers be invisible. */
689 if (mask_color
== pixel
)
691 x_free_colors (f
, &pixel
, 1);
692 pixel
= x_copy_color (f
, FRAME_FOREGROUND_PIXEL (f
));
695 unload_color (f
, x
->mouse_pixel
);
696 x
->mouse_pixel
= pixel
;
700 /* It's not okay to crash if the user selects a screwy cursor. */
701 x_catch_errors (dpy
);
703 if (!NILP (Vx_pointer_shape
))
705 CHECK_NUMBER (Vx_pointer_shape
);
706 cursor
= XCreateFontCursor (dpy
, XINT (Vx_pointer_shape
));
709 cursor
= XCreateFontCursor (dpy
, XC_xterm
);
710 x_check_errors (dpy
, "bad text pointer cursor: %s");
712 if (!NILP (Vx_nontext_pointer_shape
))
714 CHECK_NUMBER (Vx_nontext_pointer_shape
);
716 = XCreateFontCursor (dpy
, XINT (Vx_nontext_pointer_shape
));
719 nontext_cursor
= XCreateFontCursor (dpy
, XC_left_ptr
);
720 x_check_errors (dpy
, "bad nontext pointer cursor: %s");
722 if (!NILP (Vx_hourglass_pointer_shape
))
724 CHECK_NUMBER (Vx_hourglass_pointer_shape
);
726 = XCreateFontCursor (dpy
, XINT (Vx_hourglass_pointer_shape
));
729 hourglass_cursor
= XCreateFontCursor (dpy
, XC_watch
);
730 x_check_errors (dpy
, "bad hourglass pointer cursor: %s");
732 if (!NILP (Vx_mode_pointer_shape
))
734 CHECK_NUMBER (Vx_mode_pointer_shape
);
735 mode_cursor
= XCreateFontCursor (dpy
, XINT (Vx_mode_pointer_shape
));
738 mode_cursor
= XCreateFontCursor (dpy
, XC_xterm
);
739 x_check_errors (dpy
, "bad modeline pointer cursor: %s");
741 if (!NILP (Vx_sensitive_text_pointer_shape
))
743 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
);
745 = XCreateFontCursor (dpy
, XINT (Vx_sensitive_text_pointer_shape
));
748 hand_cursor
= XCreateFontCursor (dpy
, XC_hand2
);
750 if (!NILP (Vx_window_horizontal_drag_shape
))
752 CHECK_TYPE_RANGED_INTEGER (unsigned, Vx_window_horizontal_drag_shape
);
753 horizontal_drag_cursor
754 = XCreateFontCursor (dpy
, XINT (Vx_window_horizontal_drag_shape
));
757 horizontal_drag_cursor
758 = XCreateFontCursor (dpy
, XC_sb_h_double_arrow
);
760 if (!NILP (Vx_window_vertical_drag_shape
))
762 CHECK_NUMBER (Vx_window_vertical_drag_shape
);
764 = XCreateFontCursor (dpy
, XINT (Vx_window_vertical_drag_shape
));
768 = XCreateFontCursor (dpy
, XC_sb_v_double_arrow
);
770 /* Check and report errors with the above calls. */
771 x_check_errors (dpy
, "can't set cursor shape: %s");
775 XColor fore_color
, back_color
;
777 fore_color
.pixel
= x
->mouse_pixel
;
778 x_query_color (f
, &fore_color
);
779 back_color
.pixel
= mask_color
;
780 x_query_color (f
, &back_color
);
782 XRecolorCursor (dpy
, cursor
, &fore_color
, &back_color
);
783 XRecolorCursor (dpy
, nontext_cursor
, &fore_color
, &back_color
);
784 XRecolorCursor (dpy
, mode_cursor
, &fore_color
, &back_color
);
785 XRecolorCursor (dpy
, hand_cursor
, &fore_color
, &back_color
);
786 XRecolorCursor (dpy
, hourglass_cursor
, &fore_color
, &back_color
);
787 XRecolorCursor (dpy
, horizontal_drag_cursor
, &fore_color
, &back_color
);
788 XRecolorCursor (dpy
, vertical_drag_cursor
, &fore_color
, &back_color
);
791 if (FRAME_X_WINDOW (f
) != 0)
792 XDefineCursor (dpy
, FRAME_X_WINDOW (f
),
793 f
->output_data
.x
->current_cursor
= cursor
);
795 if (cursor
!= x
->text_cursor
796 && x
->text_cursor
!= 0)
797 XFreeCursor (dpy
, x
->text_cursor
);
798 x
->text_cursor
= cursor
;
800 if (nontext_cursor
!= x
->nontext_cursor
801 && x
->nontext_cursor
!= 0)
802 XFreeCursor (dpy
, x
->nontext_cursor
);
803 x
->nontext_cursor
= nontext_cursor
;
805 if (hourglass_cursor
!= x
->hourglass_cursor
806 && x
->hourglass_cursor
!= 0)
807 XFreeCursor (dpy
, x
->hourglass_cursor
);
808 x
->hourglass_cursor
= hourglass_cursor
;
810 if (mode_cursor
!= x
->modeline_cursor
811 && x
->modeline_cursor
!= 0)
812 XFreeCursor (dpy
, f
->output_data
.x
->modeline_cursor
);
813 x
->modeline_cursor
= mode_cursor
;
815 if (hand_cursor
!= x
->hand_cursor
816 && x
->hand_cursor
!= 0)
817 XFreeCursor (dpy
, x
->hand_cursor
);
818 x
->hand_cursor
= hand_cursor
;
820 if (horizontal_drag_cursor
!= x
->horizontal_drag_cursor
821 && x
->horizontal_drag_cursor
!= 0)
822 XFreeCursor (dpy
, x
->horizontal_drag_cursor
);
823 x
->horizontal_drag_cursor
= horizontal_drag_cursor
;
825 if (vertical_drag_cursor
!= x
->vertical_drag_cursor
826 && x
->vertical_drag_cursor
!= 0)
827 XFreeCursor (dpy
, x
->vertical_drag_cursor
);
828 x
->vertical_drag_cursor
= vertical_drag_cursor
;
833 update_face_from_frame_parameter (f
, Qmouse_color
, arg
);
837 x_set_cursor_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
839 unsigned long fore_pixel
, pixel
;
840 bool fore_pixel_allocated_p
= false, pixel_allocated_p
= false;
841 struct x_output
*x
= f
->output_data
.x
;
843 if (!NILP (Vx_cursor_fore_pixel
))
845 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
846 WHITE_PIX_DEFAULT (f
));
847 fore_pixel_allocated_p
= true;
850 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
852 pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
853 pixel_allocated_p
= true;
855 /* Make sure that the cursor color differs from the background color. */
856 if (pixel
== FRAME_BACKGROUND_PIXEL (f
))
858 if (pixel_allocated_p
)
860 x_free_colors (f
, &pixel
, 1);
861 pixel_allocated_p
= false;
864 pixel
= x
->mouse_pixel
;
865 if (pixel
== fore_pixel
)
867 if (fore_pixel_allocated_p
)
869 x_free_colors (f
, &fore_pixel
, 1);
870 fore_pixel_allocated_p
= false;
872 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
876 unload_color (f
, x
->cursor_foreground_pixel
);
877 if (!fore_pixel_allocated_p
)
878 fore_pixel
= x_copy_color (f
, fore_pixel
);
879 x
->cursor_foreground_pixel
= fore_pixel
;
881 unload_color (f
, x
->cursor_pixel
);
882 if (!pixel_allocated_p
)
883 pixel
= x_copy_color (f
, pixel
);
884 x
->cursor_pixel
= pixel
;
886 if (FRAME_X_WINDOW (f
) != 0)
889 XSetBackground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, x
->cursor_pixel
);
890 XSetForeground (FRAME_X_DISPLAY (f
), x
->cursor_gc
, fore_pixel
);
893 if (FRAME_VISIBLE_P (f
))
895 x_update_cursor (f
, false);
896 x_update_cursor (f
, true);
900 update_face_from_frame_parameter (f
, Qcursor_color
, arg
);
903 /* Set the border-color of frame F to pixel value PIX.
904 Note that this does not fully take effect if done before
905 F has an x-window. */
908 x_set_border_pixel (struct frame
*f
, int pix
)
910 unload_color (f
, f
->output_data
.x
->border_pixel
);
911 f
->output_data
.x
->border_pixel
= pix
;
913 if (FRAME_X_WINDOW (f
) != 0 && f
->border_width
> 0)
916 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), pix
);
919 if (FRAME_VISIBLE_P (f
))
924 /* Set the border-color of frame F to value described by ARG.
925 ARG can be a string naming a color.
926 The border-color is used for the border that is drawn by the X server.
927 Note that this does not fully take effect if done before
928 F has an x-window; it must be redone when the window is created.
930 Note: this is done in two routines because of the way X10 works.
932 Note: under X11, this is normally the province of the window manager,
933 and so emacs's border colors may be overridden. */
936 x_set_border_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
941 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
942 x_set_border_pixel (f
, pix
);
943 update_face_from_frame_parameter (f
, Qborder_color
, arg
);
948 x_set_cursor_type (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
950 set_frame_cursor_types (f
, arg
);
954 x_set_icon_type (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
960 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
963 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
968 result
= x_text_icon (f
,
969 SSDATA ((!NILP (f
->icon_name
)
973 result
= x_bitmap_icon (f
, arg
);
978 error ("No icon window available");
981 XFlush (FRAME_X_DISPLAY (f
));
986 x_set_icon_name (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
992 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
995 else if (!NILP (arg
) || NILP (oldval
))
998 fset_icon_name (f
, arg
);
1000 if (f
->output_data
.x
->icon_bitmap
!= 0)
1005 result
= x_text_icon (f
,
1006 SSDATA ((!NILP (f
->icon_name
)
1015 error ("No icon window available");
1018 XFlush (FRAME_X_DISPLAY (f
));
1024 x_set_menu_bar_lines (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
1027 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
1028 int olines
= FRAME_MENU_BAR_LINES (f
);
1031 /* Right now, menu bars don't work properly in minibuf-only frames;
1032 most of the commands try to apply themselves to the minibuffer
1033 frame itself, and get an error because you can't switch buffers
1034 in or split the minibuffer window. */
1035 if (FRAME_MINIBUF_ONLY_P (f
))
1038 if (TYPE_RANGED_INTEGERP (int, value
))
1039 nlines
= XINT (value
);
1043 /* Make sure we redisplay all windows in this frame. */
1046 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1047 FRAME_MENU_BAR_LINES (f
) = 0;
1048 FRAME_MENU_BAR_HEIGHT (f
) = 0;
1051 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
1052 if (FRAME_X_P (f
) && f
->output_data
.x
->menubar_widget
== 0)
1053 /* Make sure next redisplay shows the menu bar. */
1054 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= true;
1058 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
1059 free_frame_menubar (f
);
1060 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
1062 f
->output_data
.x
->menubar_widget
= 0;
1064 #else /* not USE_X_TOOLKIT && not USE_GTK */
1065 FRAME_MENU_BAR_LINES (f
) = nlines
;
1066 FRAME_MENU_BAR_HEIGHT (f
) = nlines
* FRAME_LINE_HEIGHT (f
);
1067 adjust_frame_size (f
, -1, -1, 2, true, Qmenu_bar_lines
);
1068 if (FRAME_X_WINDOW (f
))
1069 x_clear_under_internal_border (f
);
1071 /* If the menu bar height gets changed, the internal border below
1072 the top margin has to be cleared. Also, if the menu bar gets
1073 larger, the area for the added lines has to be cleared except for
1074 the first menu bar line that is to be drawn later. */
1075 if (nlines
!= olines
)
1077 int height
= FRAME_INTERNAL_BORDER_WIDTH (f
);
1078 int width
= FRAME_PIXEL_WIDTH (f
);
1081 /* height can be zero here. */
1082 if (FRAME_X_WINDOW (f
) && height
> 0 && width
> 0)
1084 y
= FRAME_TOP_MARGIN_HEIGHT (f
);
1087 x_clear_area (f
, 0, y
, width
, height
);
1091 if (nlines
> 1 && nlines
> olines
)
1093 y
= (olines
== 0 ? 1 : olines
) * FRAME_LINE_HEIGHT (f
);
1094 height
= nlines
* FRAME_LINE_HEIGHT (f
) - y
;
1097 x_clear_area (f
, 0, y
, width
, height
);
1101 if (nlines
== 0 && WINDOWP (f
->menu_bar_window
))
1102 clear_glyph_matrix (XWINDOW (f
->menu_bar_window
)->current_matrix
);
1104 #endif /* not USE_X_TOOLKIT && not USE_GTK */
1105 adjust_frame_glyphs (f
);
1106 run_window_configuration_change_hook (f
);
1110 /* Set the number of lines used for the tool bar of frame F to VALUE.
1111 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
1112 is the old number of tool bar lines. This function changes the
1113 height of all windows on frame F to match the new tool bar height.
1114 The frame's height doesn't change. */
1117 x_set_tool_bar_lines (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
1121 /* Treat tool bars like menu bars. */
1122 if (FRAME_MINIBUF_ONLY_P (f
))
1125 /* Use VALUE only if an int >= 0. */
1126 if (RANGED_INTEGERP (0, value
, INT_MAX
))
1127 nlines
= XFASTINT (value
);
1131 x_change_tool_bar_height (f
, nlines
* FRAME_LINE_HEIGHT (f
));
1135 /* Set the pixel height of the tool bar of frame F to HEIGHT. */
1137 x_change_tool_bar_height (struct frame
*f
, int height
)
1140 FRAME_TOOL_BAR_LINES (f
) = 0;
1141 FRAME_TOOL_BAR_HEIGHT (f
) = 0;
1144 FRAME_EXTERNAL_TOOL_BAR (f
) = true;
1145 if (FRAME_X_P (f
) && f
->output_data
.x
->toolbar_widget
== 0)
1146 /* Make sure next redisplay shows the tool bar. */
1147 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= true;
1148 update_frame_tool_bar (f
);
1152 if (FRAME_EXTERNAL_TOOL_BAR (f
))
1153 free_frame_tool_bar (f
);
1154 FRAME_EXTERNAL_TOOL_BAR (f
) = false;
1156 #else /* !USE_GTK */
1157 int unit
= FRAME_LINE_HEIGHT (f
);
1158 int old_height
= FRAME_TOOL_BAR_HEIGHT (f
);
1159 int lines
= (height
+ unit
- 1) / unit
;
1160 Lisp_Object fullscreen
;
1162 /* Make sure we redisplay all windows in this frame. */
1165 /* Recalculate tool bar and frame text sizes. */
1166 FRAME_TOOL_BAR_HEIGHT (f
) = height
;
1167 FRAME_TOOL_BAR_LINES (f
) = lines
;
1168 /* Store the `tool-bar-lines' and `height' frame parameters. */
1169 store_frame_param (f
, Qtool_bar_lines
, make_number (lines
));
1170 store_frame_param (f
, Qheight
, make_number (FRAME_LINES (f
)));
1172 /* We also have to make sure that the internal border at the top of
1173 the frame, below the menu bar or tool bar, is redrawn when the
1174 tool bar disappears. This is so because the internal border is
1175 below the tool bar if one is displayed, but is below the menu bar
1176 if there isn't a tool bar. The tool bar draws into the area
1177 below the menu bar. */
1178 if (FRAME_X_WINDOW (f
) && FRAME_TOOL_BAR_HEIGHT (f
) == 0)
1181 clear_current_matrices (f
);
1184 if ((height
< old_height
) && WINDOWP (f
->tool_bar_window
))
1185 clear_glyph_matrix (XWINDOW (f
->tool_bar_window
)->current_matrix
);
1187 /* Recalculate toolbar height. */
1188 f
->n_tool_bar_rows
= 0;
1190 adjust_frame_size (f
, -1, -1,
1191 ((NILP (fullscreen
= get_frame_param (f
, Qfullscreen
))
1192 || EQ (fullscreen
, Qfullwidth
)) ? 1
1193 : (old_height
== 0 || height
== 0) ? 2
1195 false, Qtool_bar_lines
);
1197 /* adjust_frame_size might not have done anything, garbage frame
1199 adjust_frame_glyphs (f
);
1200 SET_FRAME_GARBAGED (f
);
1201 if (FRAME_X_WINDOW (f
))
1202 x_clear_under_internal_border (f
);
1204 #endif /* USE_GTK */
1209 x_set_internal_border_width (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1213 CHECK_TYPE_RANGED_INTEGER (int, arg
);
1214 border
= max (XINT (arg
), 0);
1216 if (border
!= FRAME_INTERNAL_BORDER_WIDTH (f
))
1218 FRAME_INTERNAL_BORDER_WIDTH (f
) = border
;
1220 #ifdef USE_X_TOOLKIT
1221 if (FRAME_X_OUTPUT (f
)->edit_widget
)
1222 widget_store_internal_border (FRAME_X_OUTPUT (f
)->edit_widget
);
1225 if (FRAME_X_WINDOW (f
) != 0)
1227 adjust_frame_size (f
, -1, -1, 3, false, Qinternal_border_width
);
1230 xg_clear_under_internal_border (f
);
1232 x_clear_under_internal_border (f
);
1240 /* Set the foreground color for scroll bars on frame F to VALUE.
1241 VALUE should be a string, a color name. If it isn't a string or
1242 isn't a valid color name, do nothing. OLDVAL is the old value of
1243 the frame parameter. */
1246 x_set_scroll_bar_foreground (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
1248 unsigned long pixel
;
1250 if (STRINGP (value
))
1251 pixel
= x_decode_color (f
, value
, BLACK_PIX_DEFAULT (f
));
1255 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
1256 unload_color (f
, f
->output_data
.x
->scroll_bar_foreground_pixel
);
1258 f
->output_data
.x
->scroll_bar_foreground_pixel
= pixel
;
1259 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1261 /* Remove all scroll bars because they have wrong colors. */
1262 if (FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
)
1263 (*FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
) (f
);
1264 if (FRAME_TERMINAL (f
)->judge_scroll_bars_hook
)
1265 (*FRAME_TERMINAL (f
)->judge_scroll_bars_hook
) (f
);
1267 update_face_from_frame_parameter (f
, Qscroll_bar_foreground
, value
);
1273 /* Set the background color for scroll bars on frame F to VALUE VALUE
1274 should be a string, a color name. If it isn't a string or isn't a
1275 valid color name, do nothing. OLDVAL is the old value of the frame
1279 x_set_scroll_bar_background (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
1281 unsigned long pixel
;
1283 if (STRINGP (value
))
1284 pixel
= x_decode_color (f
, value
, WHITE_PIX_DEFAULT (f
));
1288 if (f
->output_data
.x
->scroll_bar_background_pixel
!= -1)
1289 unload_color (f
, f
->output_data
.x
->scroll_bar_background_pixel
);
1291 #if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
1292 /* Scrollbar shadow colors. */
1293 if (f
->output_data
.x
->scroll_bar_top_shadow_pixel
!= -1)
1295 unload_color (f
, f
->output_data
.x
->scroll_bar_top_shadow_pixel
);
1296 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
1298 if (f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
!= -1)
1300 unload_color (f
, f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
);
1301 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
1303 #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
1305 f
->output_data
.x
->scroll_bar_background_pixel
= pixel
;
1306 if (FRAME_X_WINDOW (f
) && FRAME_VISIBLE_P (f
))
1308 /* Remove all scroll bars because they have wrong colors. */
1309 if (FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
)
1310 (*FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
) (f
);
1311 if (FRAME_TERMINAL (f
)->judge_scroll_bars_hook
)
1312 (*FRAME_TERMINAL (f
)->judge_scroll_bars_hook
) (f
);
1314 update_face_from_frame_parameter (f
, Qscroll_bar_background
, value
);
1320 /* Encode Lisp string STRING as a text in a format appropriate for
1321 XICCC (X Inter Client Communication Conventions).
1323 If STRING contains only ASCII characters, do no conversion and
1324 return the string data of STRING. Otherwise, encode the text by
1325 CODING_SYSTEM, and return a newly allocated memory area which
1326 should be freed by `xfree' by a caller.
1328 Store the byte length of resulting text in *TEXT_BYTES.
1330 If the text contains only ASCII and Latin-1, store true in *STRING_P,
1331 which means that the `encoding' of the result can be `STRING'.
1332 Otherwise store false in *STRINGP, which means that the `encoding' of
1333 the result should be `COMPOUND_TEXT'. */
1335 static unsigned char *
1336 x_encode_text (Lisp_Object string
, Lisp_Object coding_system
,
1337 ptrdiff_t *text_bytes
, bool *stringp
, bool *freep
)
1339 int result
= string_xstring_p (string
);
1340 struct coding_system coding
;
1344 /* No multibyte character in OBJ. We need not encode it. */
1345 *text_bytes
= SBYTES (string
);
1348 return SDATA (string
);
1351 setup_coding_system (coding_system
, &coding
);
1352 coding
.mode
|= (CODING_MODE_SAFE_ENCODING
| CODING_MODE_LAST_BLOCK
);
1353 /* We suppress producing escape sequences for composition. */
1354 coding
.common_flags
&= ~CODING_ANNOTATION_MASK
;
1355 coding
.destination
= xnmalloc (SCHARS (string
), 2);
1356 coding
.dst_bytes
= SCHARS (string
) * 2;
1357 encode_coding_object (&coding
, string
, 0, 0,
1358 SCHARS (string
), SBYTES (string
), Qnil
);
1359 *text_bytes
= coding
.produced
;
1360 *stringp
= (result
== 1 || !EQ (coding_system
, Qcompound_text
));
1362 return coding
.destination
;
1366 /* Set the WM name to NAME for frame F. Also set the icon name.
1367 If the frame already has an icon name, use that, otherwise set the
1368 icon name to NAME. */
1371 x_set_name_internal (struct frame
*f
, Lisp_Object name
)
1373 if (FRAME_X_WINDOW (f
))
1377 XTextProperty text
, icon
;
1380 bool do_free_icon_value
= false, do_free_text_value
= false;
1381 Lisp_Object coding_system
;
1382 Lisp_Object encoded_name
;
1383 Lisp_Object encoded_icon_name
;
1385 /* As ENCODE_UTF_8 may cause GC and relocation of string data,
1386 we use it before x_encode_text that may return string data. */
1387 encoded_name
= ENCODE_UTF_8 (name
);
1389 coding_system
= Qcompound_text
;
1390 /* Note: Encoding strategy
1392 We encode NAME by compound-text and use "COMPOUND-TEXT" in
1393 text.encoding. But, there are non-internationalized window
1394 managers which don't support that encoding. So, if NAME
1395 contains only ASCII and 8859-1 characters, encode it by
1396 iso-latin-1, and use "STRING" in text.encoding hoping that
1397 such window managers at least analyze this format correctly,
1398 i.e. treat 8-bit bytes as 8859-1 characters.
1400 We may also be able to use "UTF8_STRING" in text.encoding
1401 in the future which can encode all Unicode characters.
1402 But, for the moment, there's no way to know that the
1403 current window manager supports it or not.
1405 Either way, we also set the _NET_WM_NAME and _NET_WM_ICON_NAME
1406 properties. Per the EWMH specification, those two properties
1407 are always UTF8_STRING. This matches what gtk_window_set_title()
1408 does in the USE_GTK case. */
1409 text
.value
= x_encode_text (name
, coding_system
, &bytes
,
1410 &stringp
, &do_free_text_value
);
1411 text
.encoding
= (stringp
? XA_STRING
1412 : FRAME_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1414 text
.nitems
= bytes
;
1416 if (!STRINGP (f
->icon_name
))
1419 encoded_icon_name
= encoded_name
;
1423 /* See the above comment "Note: Encoding strategy". */
1424 icon
.value
= x_encode_text (f
->icon_name
, coding_system
, &bytes
,
1425 &stringp
, &do_free_icon_value
);
1426 icon
.encoding
= (stringp
? XA_STRING
1427 : FRAME_DISPLAY_INFO (f
)->Xatom_COMPOUND_TEXT
);
1429 icon
.nitems
= bytes
;
1431 encoded_icon_name
= ENCODE_UTF_8 (f
->icon_name
);
1435 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f
)),
1436 SSDATA (encoded_name
));
1437 #else /* not USE_GTK */
1438 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &text
);
1439 XChangeProperty (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
1440 FRAME_DISPLAY_INFO (f
)->Xatom_net_wm_name
,
1441 FRAME_DISPLAY_INFO (f
)->Xatom_UTF8_STRING
,
1443 SDATA (encoded_name
),
1444 SBYTES (encoded_name
));
1445 #endif /* not USE_GTK */
1447 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), &icon
);
1448 XChangeProperty (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
1449 FRAME_DISPLAY_INFO (f
)->Xatom_net_wm_icon_name
,
1450 FRAME_DISPLAY_INFO (f
)->Xatom_UTF8_STRING
,
1452 SDATA (encoded_icon_name
),
1453 SBYTES (encoded_icon_name
));
1455 if (do_free_icon_value
)
1457 if (do_free_text_value
)
1464 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1467 If EXPLICIT is true, that indicates that lisp code is setting the
1468 name; if NAME is a string, set F's name to NAME and set
1469 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1471 If EXPLICIT is false, that indicates that Emacs redisplay code is
1472 suggesting a new name, which lisp code should override; if
1473 F->explicit_name is set, ignore the new name; otherwise, set it. */
1476 x_set_name (struct frame
*f
, Lisp_Object name
, bool explicit)
1478 /* Make sure that requests from lisp code override requests from
1479 Emacs redisplay code. */
1482 /* If we're switching from explicit to implicit, we had better
1483 update the mode lines and thereby update the title. */
1484 if (f
->explicit_name
&& NILP (name
))
1485 update_mode_lines
= 37;
1487 f
->explicit_name
= ! NILP (name
);
1489 else if (f
->explicit_name
)
1492 /* If NAME is nil, set the name to the x_id_name. */
1495 /* Check for no change needed in this very common case
1496 before we do any consing. */
1497 if (!strcmp (FRAME_DISPLAY_INFO (f
)->x_id_name
,
1500 name
= build_string (FRAME_DISPLAY_INFO (f
)->x_id_name
);
1503 CHECK_STRING (name
);
1505 /* Don't change the name if it's already NAME. */
1506 if (! NILP (Fstring_equal (name
, f
->name
)))
1509 fset_name (f
, name
);
1511 /* For setting the frame title, the title parameter should override
1512 the name parameter. */
1513 if (! NILP (f
->title
))
1516 x_set_name_internal (f
, name
);
1519 /* This function should be called when the user's lisp code has
1520 specified a name for the frame; the name will override any set by the
1523 x_explicitly_set_name (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1525 x_set_name (f
, arg
, true);
1528 /* This function should be called by Emacs redisplay code to set the
1529 name; names set this way will never override names set by the user's
1532 x_implicitly_set_name (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1534 x_set_name (f
, arg
, false);
1537 /* Change the title of frame F to NAME.
1538 If NAME is nil, use the frame name as the title. */
1541 x_set_title (struct frame
*f
, Lisp_Object name
, Lisp_Object old_name
)
1543 /* Don't change the title if it's already NAME. */
1544 if (EQ (name
, f
->title
))
1547 update_mode_lines
= 38;
1549 fset_title (f
, name
);
1554 CHECK_STRING (name
);
1556 x_set_name_internal (f
, name
);
1560 x_set_scroll_bar_default_width (struct frame
*f
)
1562 int unit
= FRAME_COLUMN_WIDTH (f
);
1563 #ifdef USE_TOOLKIT_SCROLL_BARS
1565 int minw
= xg_get_default_scrollbar_width ();
1569 /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
1570 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (minw
+ unit
- 1) / unit
;
1571 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = minw
;
1573 /* The width of a non-toolkit scrollbar is 14 pixels. */
1574 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + unit
- 1) / unit
;
1575 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
)
1576 = FRAME_CONFIG_SCROLL_BAR_COLS (f
) * unit
;
1581 x_set_scroll_bar_default_height (struct frame
*f
)
1583 int height
= FRAME_LINE_HEIGHT (f
);
1584 #ifdef USE_TOOLKIT_SCROLL_BARS
1586 int min_height
= xg_get_default_scrollbar_height ();
1588 int min_height
= 16;
1590 /* A minimum height of 14 doesn't look good for toolkit scroll bars. */
1591 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f
) = min_height
;
1592 FRAME_CONFIG_SCROLL_BAR_LINES (f
) = (min_height
+ height
- 1) / height
;
1594 /* The height of a non-toolkit scrollbar is 14 pixels. */
1595 FRAME_CONFIG_SCROLL_BAR_LINES (f
) = (14 + height
- 1) / height
;
1597 /* Use all of that space (aside from required margins) for the
1599 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f
) = 14;
1604 /* Record in frame F the specified or default value according to ALIST
1605 of the parameter named PROP (a Lisp symbol). If no value is
1606 specified for PROP, look for an X default for XPROP on the frame
1607 named NAME. If that is not found either, use the value DEFLT. */
1610 x_default_scroll_bar_color_parameter (struct frame
*f
,
1611 Lisp_Object alist
, Lisp_Object prop
,
1612 const char *xprop
, const char *xclass
,
1615 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
1618 tem
= x_get_arg (dpyinfo
, alist
, prop
, xprop
, xclass
, RES_TYPE_STRING
);
1619 if (EQ (tem
, Qunbound
))
1621 #ifdef USE_TOOLKIT_SCROLL_BARS
1623 /* See if an X resource for the scroll bar color has been
1625 AUTO_STRING (foreground
, "foreground");
1626 AUTO_STRING (background
, "foreground");
1627 AUTO_STRING (verticalScrollBar
, "verticalScrollBar");
1628 tem
= (display_x_get_resource
1629 (dpyinfo
, foreground_p
? foreground
: background
,
1630 empty_unibyte_string
,
1632 empty_unibyte_string
));
1635 /* If nothing has been specified, scroll bars will use a
1636 toolkit-dependent default. Because these defaults are
1637 difficult to get at without actually creating a scroll
1638 bar, use nil to indicate that no color has been
1643 #else /* not USE_TOOLKIT_SCROLL_BARS */
1647 #endif /* not USE_TOOLKIT_SCROLL_BARS */
1650 AUTO_FRAME_ARG (arg
, prop
, tem
);
1651 x_set_frame_parameters (f
, arg
);
1658 #ifdef USE_X_TOOLKIT
1660 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
1661 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
1662 already be present because of the toolkit (Motif adds some of them,
1663 for example, but Xt doesn't). */
1666 hack_wm_protocols (struct frame
*f
, Widget widget
)
1668 Display
*dpy
= XtDisplay (widget
);
1669 Window w
= XtWindow (widget
);
1670 bool need_delete
= true;
1671 bool need_focus
= true;
1672 bool need_save
= true;
1677 unsigned char *catoms
;
1679 unsigned long nitems
= 0;
1680 unsigned long bytes_after
;
1682 if ((XGetWindowProperty (dpy
, w
,
1683 FRAME_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
1684 0, 100, False
, XA_ATOM
,
1685 &type
, &format
, &nitems
, &bytes_after
,
1688 && format
== 32 && type
== XA_ATOM
)
1690 Atom
*atoms
= (Atom
*) catoms
;
1695 == FRAME_DISPLAY_INFO (f
)->Xatom_wm_delete_window
)
1696 need_delete
= false;
1697 else if (atoms
[nitems
]
1698 == FRAME_DISPLAY_INFO (f
)->Xatom_wm_take_focus
)
1700 else if (atoms
[nitems
]
1701 == FRAME_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
)
1712 props
[count
++] = FRAME_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
1714 props
[count
++] = FRAME_DISPLAY_INFO (f
)->Xatom_wm_take_focus
;
1716 props
[count
++] = FRAME_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
1718 XChangeProperty (dpy
, w
, FRAME_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
1719 XA_ATOM
, 32, PropModeAppend
,
1720 (unsigned char *) props
, count
);
1728 /* Support routines for XIC (X Input Context). */
1732 static XFontSet
xic_create_xfontset (struct frame
*);
1733 static XIMStyle
best_xim_style (XIMStyles
*);
1736 /* Supported XIM styles, ordered by preference. */
1738 static const XIMStyle supported_xim_styles
[] =
1740 XIMPreeditPosition
| XIMStatusArea
,
1741 XIMPreeditPosition
| XIMStatusNothing
,
1742 XIMPreeditPosition
| XIMStatusNone
,
1743 XIMPreeditNothing
| XIMStatusArea
,
1744 XIMPreeditNothing
| XIMStatusNothing
,
1745 XIMPreeditNothing
| XIMStatusNone
,
1746 XIMPreeditNone
| XIMStatusArea
,
1747 XIMPreeditNone
| XIMStatusNothing
,
1748 XIMPreeditNone
| XIMStatusNone
,
1753 #if defined HAVE_X_WINDOWS && defined USE_X_TOOLKIT
1754 /* Create an X fontset on frame F with base font name BASE_FONTNAME. */
1756 static const char xic_default_fontset
[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
1758 /* Create an Xt fontset spec from the name of a base font.
1759 If `motif' is True use the Motif syntax. */
1761 xic_create_fontsetname (const char *base_fontname
, bool motif
)
1763 const char *sep
= motif
? ";" : ",";
1767 /* Make a fontset name from the base font name. */
1768 if (xic_default_fontset
== base_fontname
)
1770 /* There is no base font name, use the default. */
1771 fontsetname
= xmalloc (strlen (base_fontname
) + 2);
1772 z
= stpcpy (fontsetname
, base_fontname
);
1776 /* Make a fontset name from the base font name.
1777 The font set will be made of the following elements:
1779 - the base font where the charset spec is replaced by -*-*.
1780 - the same but with the family also replaced with -*-*-. */
1781 const char *p
= base_fontname
;
1784 for (i
= 0; *p
; p
++)
1788 /* As the font name doesn't conform to XLFD, we can't
1789 modify it to generalize it to allcs and allfamilies.
1790 Use the specified font plus the default. */
1791 fontsetname
= xmalloc (strlen (base_fontname
)
1792 + strlen (xic_default_fontset
) + 3);
1793 z
= stpcpy (fontsetname
, base_fontname
);
1794 z
= stpcpy (z
, sep
);
1795 z
= stpcpy (z
, xic_default_fontset
);
1800 const char *p1
= NULL
, *p2
= NULL
, *p3
= NULL
;
1801 char *font_allcs
= NULL
;
1802 char *font_allfamilies
= NULL
;
1803 char *font_all
= NULL
;
1804 const char *allcs
= "*-*-*-*-*-*-*";
1805 const char *allfamilies
= "-*-*-";
1806 const char *all
= "*-*-*-*-";
1809 for (i
= 0, p
= base_fontname
; i
< 8; p
++)
1822 /* If base_fontname specifies ADSTYLE, make it a
1826 ptrdiff_t diff
= (p2
- p3
) - 2;
1828 base
= alloca (strlen (base_fontname
) + 1);
1829 memcpy (base
, base_fontname
, p3
- base_fontname
);
1830 base
[p3
- base_fontname
] = '*';
1831 base
[(p3
- base_fontname
) + 1] = '-';
1832 strcpy (base
+ (p3
- base_fontname
) + 2, p2
);
1833 p
= base
+ (p
- base_fontname
) - diff
;
1834 p1
= base
+ (p1
- base_fontname
);
1835 p2
= base
+ (p2
- base_fontname
) - diff
;
1836 base_fontname
= base
;
1839 /* Build the font spec that matches all charsets. */
1840 len
= p
- base_fontname
+ strlen (allcs
) + 1;
1841 font_allcs
= alloca (len
);
1842 memcpy (font_allcs
, base_fontname
, p
- base_fontname
);
1843 strcpy (font_allcs
+ (p
- base_fontname
), allcs
);
1845 /* Build the font spec that matches all families and
1847 len
= p
- p1
+ strlen (allcs
) + strlen (allfamilies
) + 1;
1848 font_allfamilies
= alloca (len
);
1849 strcpy (font_allfamilies
, allfamilies
);
1850 memcpy (font_allfamilies
+ strlen (allfamilies
), p1
, p
- p1
);
1851 strcpy (font_allfamilies
+ strlen (allfamilies
) + (p
- p1
), allcs
);
1853 /* Build the font spec that matches all. */
1854 len
= p
- p2
+ strlen (allcs
) + strlen (all
) + strlen (allfamilies
) + 1;
1855 font_all
= alloca (len
);
1856 z
= stpcpy (font_all
, allfamilies
);
1857 z
= stpcpy (z
, all
);
1858 memcpy (z
, p2
, p
- p2
);
1859 strcpy (z
+ (p
- p2
), allcs
);
1861 /* Build the actual font set name. */
1862 len
= strlen (base_fontname
) + strlen (font_allcs
)
1863 + strlen (font_allfamilies
) + strlen (font_all
) + 5;
1864 fontsetname
= xmalloc (len
);
1865 z
= stpcpy (fontsetname
, base_fontname
);
1866 z
= stpcpy (z
, sep
);
1867 z
= stpcpy (z
, font_allcs
);
1868 z
= stpcpy (z
, sep
);
1869 z
= stpcpy (z
, font_allfamilies
);
1870 z
= stpcpy (z
, sep
);
1871 z
= stpcpy (z
, font_all
);
1878 #endif /* HAVE_X_WINDOWS && USE_X_TOOLKIT */
1880 #ifdef DEBUG_XIC_FONTSET
1882 print_fontset_result (XFontSet xfs
, char *name
, char **missing_list
,
1886 fprintf (stderr
, "XIC Fontset created: %s\n", name
);
1889 fprintf (stderr
, "XIC Fontset failed: %s\n", name
);
1890 while (missing_count
-- > 0)
1892 fprintf (stderr
, " missing: %s\n", *missing_list
);
1901 xic_create_xfontset (struct frame
*f
)
1903 XFontSet xfs
= NULL
;
1904 struct font
*font
= FRAME_FONT (f
);
1905 int pixel_size
= font
->pixel_size
;
1906 Lisp_Object rest
, frame
;
1908 /* See if there is another frame already using same fontset. */
1909 FOR_EACH_FRAME (rest
, frame
)
1911 struct frame
*cf
= XFRAME (frame
);
1913 if (cf
!= f
&& FRAME_LIVE_P (f
) && FRAME_X_P (cf
)
1914 && FRAME_DISPLAY_INFO (cf
) == FRAME_DISPLAY_INFO (f
)
1916 && FRAME_FONT (f
)->pixel_size
== pixel_size
)
1918 xfs
= FRAME_XIC_FONTSET (cf
);
1926 char **missing_list
;
1929 const char *xlfd_format
= "-*-*-medium-r-normal--%d-*-*-*-*-*";
1931 sprintf (buf
, xlfd_format
, pixel_size
);
1932 missing_list
= NULL
;
1933 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
), buf
,
1934 &missing_list
, &missing_count
, &def_string
);
1935 #ifdef DEBUG_XIC_FONTSET
1936 print_fontset_result (xfs
, buf
, missing_list
, missing_count
);
1939 XFreeStringList (missing_list
);
1942 /* List of pixel sizes most likely available. Find one that
1943 is closest to pixel_size. */
1944 int sizes
[] = {0, 8, 10, 11, 12, 14, 17, 18, 20, 24, 26, 34, 0};
1945 int *smaller
, *larger
;
1947 for (smaller
= sizes
; smaller
[1]; smaller
++)
1948 if (smaller
[1] >= pixel_size
)
1950 larger
= smaller
+ 1;
1951 if (*larger
== pixel_size
)
1953 while (*smaller
|| *larger
)
1958 this_size
= *smaller
--;
1959 else if (! *smaller
)
1960 this_size
= *larger
++;
1961 else if (pixel_size
- *smaller
< *larger
- pixel_size
)
1962 this_size
= *smaller
--;
1964 this_size
= *larger
++;
1965 sprintf (buf
, xlfd_format
, this_size
);
1966 missing_list
= NULL
;
1967 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
), buf
,
1968 &missing_list
, &missing_count
, &def_string
);
1969 #ifdef DEBUG_XIC_FONTSET
1970 print_fontset_result (xfs
, buf
, missing_list
, missing_count
);
1973 XFreeStringList (missing_list
);
1980 const char *last_resort
= "-*-*-*-r-normal--*-*-*-*-*-*";
1982 missing_list
= NULL
;
1983 xfs
= XCreateFontSet (FRAME_X_DISPLAY (f
), last_resort
,
1984 &missing_list
, &missing_count
, &def_string
);
1985 #ifdef DEBUG_XIC_FONTSET
1986 print_fontset_result (xfs
, last_resort
, missing_list
, missing_count
);
1989 XFreeStringList (missing_list
);
1997 /* Free the X fontset of frame F if it is the last frame using it. */
2000 xic_free_xfontset (struct frame
*f
)
2002 Lisp_Object rest
, frame
;
2003 bool shared_p
= false;
2005 if (!FRAME_XIC_FONTSET (f
))
2008 /* See if there is another frame sharing the same fontset. */
2009 FOR_EACH_FRAME (rest
, frame
)
2011 struct frame
*cf
= XFRAME (frame
);
2012 if (cf
!= f
&& FRAME_LIVE_P (f
) && FRAME_X_P (cf
)
2013 && FRAME_DISPLAY_INFO (cf
) == FRAME_DISPLAY_INFO (f
)
2014 && FRAME_XIC_FONTSET (cf
) == FRAME_XIC_FONTSET (f
))
2022 /* The fontset is not used anymore. It is safe to free it. */
2023 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
2025 FRAME_XIC_FONTSET (f
) = NULL
;
2029 /* Value is the best input style, given user preferences USER (already
2030 checked to be supported by Emacs), and styles supported by the
2031 input method XIM. */
2034 best_xim_style (XIMStyles
*xim
)
2037 int nr_supported
= ARRAYELTS (supported_xim_styles
);
2039 for (i
= 0; i
< nr_supported
; ++i
)
2040 for (j
= 0; j
< xim
->count_styles
; ++j
)
2041 if (supported_xim_styles
[i
] == xim
->supported_styles
[j
])
2042 return supported_xim_styles
[i
];
2044 /* Return the default style. */
2045 return XIMPreeditNothing
| XIMStatusNothing
;
2048 /* Create XIC for frame F. */
2051 create_frame_xic (struct frame
*f
)
2055 XFontSet xfs
= NULL
;
2056 XVaNestedList status_attr
= NULL
;
2057 XVaNestedList preedit_attr
= NULL
;
2065 xim
= FRAME_X_XIM (f
);
2069 /* Determine XIC style. */
2070 xic_style
= best_xim_style (FRAME_X_XIM_STYLES (f
));
2072 /* Create X fontset. */
2073 if (xic_style
& (XIMPreeditPosition
| XIMStatusArea
))
2075 xfs
= xic_create_xfontset (f
);
2079 FRAME_XIC_FONTSET (f
) = xfs
;
2082 if (xic_style
& XIMPreeditPosition
)
2084 spot
.x
= 0; spot
.y
= 1;
2085 preedit_attr
= XVaCreateNestedList (0,
2088 FRAME_FOREGROUND_PIXEL (f
),
2090 FRAME_BACKGROUND_PIXEL (f
),
2091 (xic_style
& XIMPreeditPosition
2101 if (xic_style
& XIMStatusArea
)
2103 s_area
.x
= 0; s_area
.y
= 0; s_area
.width
= 1; s_area
.height
= 1;
2104 status_attr
= XVaCreateNestedList (0,
2110 FRAME_FOREGROUND_PIXEL (f
),
2112 FRAME_BACKGROUND_PIXEL (f
),
2119 if (preedit_attr
&& status_attr
)
2120 xic
= XCreateIC (xim
,
2121 XNInputStyle
, xic_style
,
2122 XNClientWindow
, FRAME_X_WINDOW (f
),
2123 XNFocusWindow
, FRAME_X_WINDOW (f
),
2124 XNStatusAttributes
, status_attr
,
2125 XNPreeditAttributes
, preedit_attr
,
2127 else if (preedit_attr
)
2128 xic
= XCreateIC (xim
,
2129 XNInputStyle
, xic_style
,
2130 XNClientWindow
, FRAME_X_WINDOW (f
),
2131 XNFocusWindow
, FRAME_X_WINDOW (f
),
2132 XNPreeditAttributes
, preedit_attr
,
2134 else if (status_attr
)
2135 xic
= XCreateIC (xim
,
2136 XNInputStyle
, xic_style
,
2137 XNClientWindow
, FRAME_X_WINDOW (f
),
2138 XNFocusWindow
, FRAME_X_WINDOW (f
),
2139 XNStatusAttributes
, status_attr
,
2142 xic
= XCreateIC (xim
,
2143 XNInputStyle
, xic_style
,
2144 XNClientWindow
, FRAME_X_WINDOW (f
),
2145 XNFocusWindow
, FRAME_X_WINDOW (f
),
2151 FRAME_XIC (f
) = xic
;
2152 FRAME_XIC_STYLE (f
) = xic_style
;
2153 xfs
= NULL
; /* Don't free below. */
2161 XFree (preedit_attr
);
2164 XFree (status_attr
);
2168 /* Destroy XIC and free XIC fontset of frame F, if any. */
2171 free_frame_xic (struct frame
*f
)
2173 if (FRAME_XIC (f
) == NULL
)
2176 XDestroyIC (FRAME_XIC (f
));
2177 xic_free_xfontset (f
);
2179 FRAME_XIC (f
) = NULL
;
2183 /* Place preedit area for XIC of window W's frame to specified
2184 pixel position X/Y. X and Y are relative to window W. */
2187 xic_set_preeditarea (struct window
*w
, int x
, int y
)
2189 struct frame
*f
= XFRAME (w
->frame
);
2193 spot
.x
= WINDOW_TO_FRAME_PIXEL_X (w
, x
) + WINDOW_LEFT_FRINGE_WIDTH (w
);
2194 spot
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, y
) + FONT_BASE (FRAME_FONT (f
));
2195 attr
= XVaCreateNestedList (0, XNSpotLocation
, &spot
, NULL
);
2196 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2201 /* Place status area for XIC in bottom right corner of frame F.. */
2204 xic_set_statusarea (struct frame
*f
)
2206 XIC xic
= FRAME_XIC (f
);
2211 /* Negotiate geometry of status area. If input method has existing
2212 status area, use its current size. */
2213 area
.x
= area
.y
= area
.width
= area
.height
= 0;
2214 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &area
, NULL
);
2215 XSetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2218 attr
= XVaCreateNestedList (0, XNAreaNeeded
, &needed
, NULL
);
2219 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2222 if (needed
->width
== 0) /* Use XNArea instead of XNAreaNeeded */
2224 attr
= XVaCreateNestedList (0, XNArea
, &needed
, NULL
);
2225 XGetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2229 area
.width
= needed
->width
;
2230 area
.height
= needed
->height
;
2231 area
.x
= FRAME_PIXEL_WIDTH (f
) - area
.width
- FRAME_INTERNAL_BORDER_WIDTH (f
);
2232 area
.y
= (FRAME_PIXEL_HEIGHT (f
) - area
.height
2233 - FRAME_MENUBAR_HEIGHT (f
)
2234 - FRAME_TOOLBAR_TOP_HEIGHT (f
)
2235 - FRAME_INTERNAL_BORDER_WIDTH (f
));
2238 attr
= XVaCreateNestedList (0, XNArea
, &area
, NULL
);
2239 XSetICValues (xic
, XNStatusAttributes
, attr
, NULL
);
2244 /* Set X fontset for XIC of frame F, using base font name
2245 BASE_FONTNAME. Called when a new Emacs fontset is chosen. */
2248 xic_set_xfontset (struct frame
*f
, const char *base_fontname
)
2253 xic_free_xfontset (f
);
2255 xfs
= xic_create_xfontset (f
);
2257 attr
= XVaCreateNestedList (0, XNFontSet
, xfs
, NULL
);
2258 if (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
)
2259 XSetICValues (FRAME_XIC (f
), XNPreeditAttributes
, attr
, NULL
);
2260 if (FRAME_XIC_STYLE (f
) & XIMStatusArea
)
2261 XSetICValues (FRAME_XIC (f
), XNStatusAttributes
, attr
, NULL
);
2264 FRAME_XIC_FONTSET (f
) = xfs
;
2267 #endif /* HAVE_X_I18N */
2271 #ifdef USE_X_TOOLKIT
2273 /* Create and set up the X widget for frame F. */
2276 x_window (struct frame
*f
, long window_prompting
)
2278 XClassHint class_hints
;
2279 XSetWindowAttributes attributes
;
2280 unsigned long attribute_mask
;
2281 Widget shell_widget
;
2283 Widget frame_widget
;
2289 /* Use the resource name as the top-level widget name
2290 for looking up resources. Make a non-Lisp copy
2291 for the window manager, so GC relocation won't bother it.
2293 Elsewhere we specify the window name for the window manager. */
2294 f
->namebuf
= xlispstrdup (Vx_resource_name
);
2297 XtSetArg (al
[ac
], XtNallowShellResize
, 1); ac
++;
2298 XtSetArg (al
[ac
], XtNinput
, 1); ac
++;
2299 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2300 XtSetArg (al
[ac
], XtNborderWidth
, f
->border_width
); ac
++;
2301 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2302 XtSetArg (al
[ac
], XtNdepth
, FRAME_DISPLAY_INFO (f
)->n_planes
); ac
++;
2303 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2304 shell_widget
= XtAppCreateShell (f
->namebuf
, EMACS_CLASS
,
2305 applicationShellWidgetClass
,
2306 FRAME_X_DISPLAY (f
), al
, ac
);
2308 f
->output_data
.x
->widget
= shell_widget
;
2309 /* maybe_set_screen_title_format (shell_widget); */
2311 pane_widget
= lw_create_widget ("main", "pane", widget_id_tick
++,
2312 NULL
, shell_widget
, False
,
2313 NULL
, NULL
, NULL
, NULL
);
2316 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2317 XtSetArg (al
[ac
], XtNdepth
, FRAME_DISPLAY_INFO (f
)->n_planes
); ac
++;
2318 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2319 XtSetArg (al
[ac
], XtNborderWidth
, 0); ac
++;
2320 XtSetValues (pane_widget
, al
, ac
);
2321 f
->output_data
.x
->column_widget
= pane_widget
;
2323 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2324 the emacs screen when changing menubar. This reduces flickering. */
2327 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2328 XtSetArg (al
[ac
], XtNshowGrip
, 0); ac
++;
2329 XtSetArg (al
[ac
], XtNallowResize
, 1); ac
++;
2330 XtSetArg (al
[ac
], XtNresizeToPreferred
, 1); ac
++;
2331 XtSetArg (al
[ac
], XtNemacsFrame
, f
); ac
++;
2332 XtSetArg (al
[ac
], XtNvisual
, FRAME_X_VISUAL (f
)); ac
++;
2333 XtSetArg (al
[ac
], XtNdepth
, FRAME_DISPLAY_INFO (f
)->n_planes
); ac
++;
2334 XtSetArg (al
[ac
], XtNcolormap
, FRAME_X_COLORMAP (f
)); ac
++;
2335 XtSetArg (al
[ac
], XtNborderWidth
, 0); ac
++;
2336 frame_widget
= XtCreateWidget (f
->namebuf
, emacsFrameClass
, pane_widget
,
2339 f
->output_data
.x
->edit_widget
= frame_widget
;
2341 XtManageChild (frame_widget
);
2343 /* Do some needed geometry management. */
2347 int extra_borders
= 0;
2349 = (f
->output_data
.x
->menubar_widget
2350 ? (f
->output_data
.x
->menubar_widget
->core
.height
2351 + f
->output_data
.x
->menubar_widget
->core
.border_width
)
2354 #if false /* Experimentally, we now get the right results
2355 for -geometry -0-0 without this. 24 Aug 96, rms. */
2356 if (FRAME_EXTERNAL_MENU_BAR (f
))
2359 XtVaGetValues (pane_widget
, XtNinternalBorderWidth
, &ibw
, NULL
);
2360 menubar_size
+= ibw
;
2364 FRAME_MENUBAR_HEIGHT (f
) = menubar_size
;
2367 /* Motif seems to need this amount added to the sizes
2368 specified for the shell widget. The Athena/Lucid widgets don't.
2369 Both conclusions reached experimentally. -- rms. */
2370 XtVaGetValues (f
->output_data
.x
->edit_widget
, XtNinternalBorderWidth
,
2371 &extra_borders
, NULL
);
2375 f
->shell_position
= xmalloc (sizeof "=x++" + 4 * INT_STRLEN_BOUND (int));
2377 /* Convert our geometry parameters into a geometry string
2379 Note that we do not specify here whether the position
2380 is a user-specified or program-specified one.
2381 We pass that information later, in x_wm_set_size_hints. */
2383 int left
= f
->left_pos
;
2384 bool xneg
= (window_prompting
& XNegative
) != 0;
2385 int top
= f
->top_pos
;
2386 bool yneg
= (window_prompting
& YNegative
) != 0;
2392 if (window_prompting
& USPosition
)
2393 sprintf (f
->shell_position
, "=%dx%d%c%d%c%d",
2394 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2395 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
,
2396 (xneg
? '-' : '+'), left
,
2397 (yneg
? '-' : '+'), top
);
2400 sprintf (f
->shell_position
, "=%dx%d",
2401 FRAME_PIXEL_WIDTH (f
) + extra_borders
,
2402 FRAME_PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
);
2404 /* Setting x and y when the position is not specified in
2405 the geometry string will set program position in the WM hints.
2406 If Emacs had just one program position, we could set it in
2407 fallback resources, but since each make-frame call can specify
2408 different program positions, this is easier. */
2409 XtSetArg (gal
[gac
], XtNx
, left
); gac
++;
2410 XtSetArg (gal
[gac
], XtNy
, top
); gac
++;
2414 XtSetArg (gal
[gac
], XtNgeometry
, f
->shell_position
); gac
++;
2415 XtSetValues (shell_widget
, gal
, gac
);
2418 XtManageChild (pane_widget
);
2419 XtRealizeWidget (shell_widget
);
2421 if (FRAME_X_EMBEDDED_P (f
))
2422 XReparentWindow (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
),
2423 f
->output_data
.x
->parent_desc
, 0, 0);
2425 FRAME_X_WINDOW (f
) = XtWindow (frame_widget
);
2427 validate_x_resource_name ();
2429 class_hints
.res_name
= SSDATA (Vx_resource_name
);
2430 class_hints
.res_class
= SSDATA (Vx_resource_class
);
2431 XSetClassHint (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
), &class_hints
);
2434 FRAME_XIC (f
) = NULL
;
2436 create_frame_xic (f
);
2439 f
->output_data
.x
->wm_hints
.input
= True
;
2440 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2441 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2442 &f
->output_data
.x
->wm_hints
);
2444 hack_wm_protocols (f
, shell_widget
);
2447 XtAddEventHandler (shell_widget
, 0, True
, _XEditResCheckMessages
, 0);
2450 /* Do a stupid property change to force the server to generate a
2451 PropertyNotify event so that the event_stream server timestamp will
2452 be initialized to something relevant to the time we created the window.
2454 XChangeProperty (XtDisplay (frame_widget
), XtWindow (frame_widget
),
2455 FRAME_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2456 XA_ATOM
, 32, PropModeAppend
, NULL
, 0);
2458 /* Make all the standard events reach the Emacs frame. */
2459 attributes
.event_mask
= STANDARD_EVENT_SET
;
2464 /* XIM server might require some X events. */
2465 unsigned long fevent
= NoEventMask
;
2466 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2467 attributes
.event_mask
|= fevent
;
2469 #endif /* HAVE_X_I18N */
2471 attribute_mask
= CWEventMask
;
2472 XChangeWindowAttributes (XtDisplay (shell_widget
), XtWindow (shell_widget
),
2473 attribute_mask
, &attributes
);
2475 XtMapWidget (frame_widget
);
2477 /* x_set_name normally ignores requests to set the name if the
2478 requested name is the same as the current name. This is the one
2479 place where that assumption isn't correct; f->name is set, but
2480 the X server hasn't been told. */
2483 bool explicit = f
->explicit_name
;
2485 f
->explicit_name
= false;
2487 fset_name (f
, Qnil
);
2488 x_set_name (f
, name
, explicit);
2491 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2492 f
->output_data
.x
->current_cursor
2493 = f
->output_data
.x
->text_cursor
);
2497 /* This is a no-op, except under Motif. Make sure main areas are
2498 set to something reasonable, in case we get an error later. */
2499 lw_set_main_areas (pane_widget
, 0, frame_widget
);
2502 #else /* not USE_X_TOOLKIT */
2505 x_window (struct frame
*f
)
2507 if (! xg_create_frame_widgets (f
))
2508 error ("Unable to create window");
2511 FRAME_XIC (f
) = NULL
;
2515 create_frame_xic (f
);
2518 /* XIM server might require some X events. */
2519 unsigned long fevent
= NoEventMask
;
2520 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2522 if (fevent
!= NoEventMask
)
2524 XSetWindowAttributes attributes
;
2525 XWindowAttributes wattr
;
2526 unsigned long attribute_mask
;
2528 XGetWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2530 attributes
.event_mask
= wattr
.your_event_mask
| fevent
;
2531 attribute_mask
= CWEventMask
;
2532 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2533 attribute_mask
, &attributes
);
2541 #else /*! USE_GTK */
2542 /* Create and set up the X window for frame F. */
2545 x_window (struct frame
*f
)
2547 XClassHint class_hints
;
2548 XSetWindowAttributes attributes
;
2549 unsigned long attribute_mask
;
2551 attributes
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
2552 attributes
.border_pixel
= f
->output_data
.x
->border_pixel
;
2553 attributes
.bit_gravity
= StaticGravity
;
2554 attributes
.backing_store
= NotUseful
;
2555 attributes
.save_under
= True
;
2556 attributes
.event_mask
= STANDARD_EVENT_SET
;
2557 attributes
.colormap
= FRAME_X_COLORMAP (f
);
2558 attribute_mask
= (CWBackPixel
| CWBorderPixel
| CWBitGravity
| CWEventMask
2563 = XCreateWindow (FRAME_X_DISPLAY (f
),
2564 f
->output_data
.x
->parent_desc
,
2567 FRAME_PIXEL_WIDTH (f
), FRAME_PIXEL_HEIGHT (f
),
2569 CopyFromParent
, /* depth */
2570 InputOutput
, /* class */
2572 attribute_mask
, &attributes
);
2577 create_frame_xic (f
);
2580 /* XIM server might require some X events. */
2581 unsigned long fevent
= NoEventMask
;
2582 XGetICValues (FRAME_XIC (f
), XNFilterEvents
, &fevent
, NULL
);
2583 attributes
.event_mask
|= fevent
;
2584 attribute_mask
= CWEventMask
;
2585 XChangeWindowAttributes (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2586 attribute_mask
, &attributes
);
2589 #endif /* HAVE_X_I18N */
2591 validate_x_resource_name ();
2593 class_hints
.res_name
= SSDATA (Vx_resource_name
);
2594 class_hints
.res_class
= SSDATA (Vx_resource_class
);
2595 XSetClassHint (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &class_hints
);
2597 /* This indicates that we use the "Passive Input" input model.
2598 Unless we do this, we don't get the Focus{In,Out} events that we
2599 need to draw the cursor correctly. Accursed bureaucrats.
2600 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2602 f
->output_data
.x
->wm_hints
.input
= True
;
2603 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2604 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2605 &f
->output_data
.x
->wm_hints
);
2606 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
2608 /* Request "save yourself" and "delete window" commands from wm. */
2611 protocols
[0] = FRAME_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2612 protocols
[1] = FRAME_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2613 XSetWMProtocols (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), protocols
, 2);
2616 /* x_set_name normally ignores requests to set the name if the
2617 requested name is the same as the current name. This is the one
2618 place where that assumption isn't correct; f->name is set, but
2619 the X server hasn't been told. */
2622 bool explicit = f
->explicit_name
;
2624 f
->explicit_name
= false;
2626 fset_name (f
, Qnil
);
2627 x_set_name (f
, name
, explicit);
2630 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2631 f
->output_data
.x
->current_cursor
2632 = f
->output_data
.x
->text_cursor
);
2636 if (FRAME_X_WINDOW (f
) == 0)
2637 error ("Unable to create window");
2640 #endif /* not USE_GTK */
2641 #endif /* not USE_X_TOOLKIT */
2643 /* Verify that the icon position args for this window are valid. */
2646 x_icon_verify (struct frame
*f
, Lisp_Object parms
)
2648 Lisp_Object icon_x
, icon_y
;
2650 /* Set the position of the icon. Note that twm groups all
2651 icons in an icon window. */
2652 icon_x
= x_frame_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
2653 icon_y
= x_frame_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
2654 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2656 CHECK_NUMBER (icon_x
);
2657 CHECK_NUMBER (icon_y
);
2659 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2660 error ("Both left and top icon corners of icon must be specified");
2663 /* Handle the icon stuff for this window. Perhaps later we might
2664 want an x_set_icon_position which can be called interactively as
2668 x_icon (struct frame
*f
, Lisp_Object parms
)
2670 /* Set the position of the icon. Note that twm groups all
2671 icons in an icon window. */
2673 = x_frame_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
2675 = x_frame_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
2676 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2678 CHECK_TYPE_RANGED_INTEGER (int, icon_x
);
2679 CHECK_TYPE_RANGED_INTEGER (int, icon_y
);
2681 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2682 error ("Both left and top icon corners of icon must be specified");
2686 if (! EQ (icon_x
, Qunbound
))
2687 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
2689 #if false /* x_get_arg removes the visibility parameter as a side effect,
2690 but x_create_frame still needs it. */
2691 /* Start up iconic or window? */
2692 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
2693 x_wm_set_window_state
2694 (f
, (EQ (x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
),
2700 x_text_icon (f
, SSDATA ((!NILP (f
->icon_name
)
2707 /* Make the GCs needed for this window, setting the
2708 background, border and mouse colors; also create the
2709 mouse cursor and the gray border tile. */
2712 x_make_gc (struct frame
*f
)
2714 XGCValues gc_values
;
2718 /* Create the GCs of this frame.
2719 Note that many default values are used. */
2721 gc_values
.foreground
= FRAME_FOREGROUND_PIXEL (f
);
2722 gc_values
.background
= FRAME_BACKGROUND_PIXEL (f
);
2723 gc_values
.line_width
= 0; /* Means 1 using fast algorithm. */
2724 f
->output_data
.x
->normal_gc
2725 = XCreateGC (FRAME_X_DISPLAY (f
),
2727 GCLineWidth
| GCForeground
| GCBackground
,
2730 /* Reverse video style. */
2731 gc_values
.foreground
= FRAME_BACKGROUND_PIXEL (f
);
2732 gc_values
.background
= FRAME_FOREGROUND_PIXEL (f
);
2733 f
->output_data
.x
->reverse_gc
2734 = XCreateGC (FRAME_X_DISPLAY (f
),
2736 GCForeground
| GCBackground
| GCLineWidth
,
2739 /* Cursor has cursor-color background, background-color foreground. */
2740 gc_values
.foreground
= FRAME_BACKGROUND_PIXEL (f
);
2741 gc_values
.background
= f
->output_data
.x
->cursor_pixel
;
2742 gc_values
.fill_style
= FillOpaqueStippled
;
2743 f
->output_data
.x
->cursor_gc
2744 = XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2745 (GCForeground
| GCBackground
2746 | GCFillStyle
| GCLineWidth
),
2749 /* Create the gray border tile used when the pointer is not in
2750 the frame. Since this depends on the frame's pixel values,
2751 this must be done on a per-frame basis. */
2752 f
->output_data
.x
->border_tile
2753 = (XCreatePixmapFromBitmapData
2754 (FRAME_X_DISPLAY (f
), FRAME_DISPLAY_INFO (f
)->root_window
,
2755 gray_bits
, gray_width
, gray_height
,
2756 FRAME_FOREGROUND_PIXEL (f
),
2757 FRAME_BACKGROUND_PIXEL (f
),
2758 DefaultDepth (FRAME_X_DISPLAY (f
), FRAME_X_SCREEN_NUMBER (f
))));
2764 /* Free what was allocated in x_make_gc. */
2767 x_free_gcs (struct frame
*f
)
2769 Display
*dpy
= FRAME_X_DISPLAY (f
);
2773 if (f
->output_data
.x
->normal_gc
)
2775 XFreeGC (dpy
, f
->output_data
.x
->normal_gc
);
2776 f
->output_data
.x
->normal_gc
= 0;
2779 if (f
->output_data
.x
->reverse_gc
)
2781 XFreeGC (dpy
, f
->output_data
.x
->reverse_gc
);
2782 f
->output_data
.x
->reverse_gc
= 0;
2785 if (f
->output_data
.x
->cursor_gc
)
2787 XFreeGC (dpy
, f
->output_data
.x
->cursor_gc
);
2788 f
->output_data
.x
->cursor_gc
= 0;
2791 if (f
->output_data
.x
->border_tile
)
2793 XFreePixmap (dpy
, f
->output_data
.x
->border_tile
);
2794 f
->output_data
.x
->border_tile
= 0;
2801 /* Handler for signals raised during x_create_frame and
2802 x_create_tip_frame. FRAME is the frame which is partially
2806 unwind_create_frame (Lisp_Object frame
)
2808 struct frame
*f
= XFRAME (frame
);
2810 /* If frame is already dead, nothing to do. This can happen if the
2811 display is disconnected after the frame has become official, but
2812 before x_create_frame removes the unwind protect. */
2813 if (!FRAME_LIVE_P (f
))
2816 /* If frame is ``official'', nothing to do. */
2817 if (NILP (Fmemq (frame
, Vframe_list
)))
2819 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2820 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
2823 /* If the frame's image cache refcount is still the same as our
2824 private shadow variable, it means we are unwinding a frame
2825 for which we didn't yet call init_frame_faces, where the
2826 refcount is incremented. Therefore, we increment it here, so
2827 that free_frame_faces, called in x_free_frame_resources
2828 below, will not mistakenly decrement the counter that was not
2829 incremented yet to account for this new frame. */
2830 if (FRAME_IMAGE_CACHE (f
) != NULL
2831 && FRAME_IMAGE_CACHE (f
)->refcount
== image_cache_refcount
)
2832 FRAME_IMAGE_CACHE (f
)->refcount
++;
2834 x_free_frame_resources (f
);
2837 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2838 /* Check that reference counts are indeed correct. */
2839 eassert (dpyinfo
->reference_count
== dpyinfo_refcount
);
2840 eassert (dpyinfo
->terminal
->image_cache
->refcount
== image_cache_refcount
);
2849 do_unwind_create_frame (Lisp_Object frame
)
2851 unwind_create_frame (frame
);
2855 x_default_font_parameter (struct frame
*f
, Lisp_Object parms
)
2857 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
2858 Lisp_Object font_param
= x_get_arg (dpyinfo
, parms
, Qfont
, NULL
, NULL
,
2860 Lisp_Object font
= Qnil
;
2861 if (EQ (font_param
, Qunbound
))
2864 if (NILP (font_param
))
2866 /* System font should take precedence over X resources. We suggest this
2867 regardless of font-use-system-font because .emacs may not have been
2869 const char *system_font
= xsettings_get_system_font ();
2871 font
= font_open_by_name (f
, build_unibyte_string (system_font
));
2875 font
= !NILP (font_param
) ? font_param
2876 : x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
2878 if (! FONTP (font
) && ! STRINGP (font
))
2883 /* This will find the normal Xft font. */
2886 "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
2887 "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
2888 "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
2889 /* This was formerly the first thing tried, but it finds
2890 too many fonts and takes too long. */
2891 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
2892 /* If those didn't work, look for something which will
2894 "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
2899 for (i
= 0; names
[i
]; i
++)
2901 font
= font_open_by_name (f
, build_unibyte_string (names
[i
]));
2906 error ("No suitable font was found");
2908 else if (!NILP (font_param
))
2910 /* Remember the explicit font parameter, so we can re-apply it after
2911 we've applied the `default' face settings. */
2912 AUTO_FRAME_ARG (arg
, Qfont_param
, font_param
);
2913 x_set_frame_parameters (f
, arg
);
2916 /* This call will make X resources override any system font setting. */
2917 x_default_parameter (f
, parms
, Qfont
, font
, "font", "Font", RES_TYPE_STRING
);
2921 DEFUN ("x-wm-set-size-hint", Fx_wm_set_size_hint
, Sx_wm_set_size_hint
,
2923 doc
: /* Send the size hints for frame FRAME to the window manager.
2924 If FRAME is omitted or nil, use the selected frame.
2925 Signal error if FRAME is not an X frame. */)
2928 struct frame
*f
= decode_window_system_frame (frame
);
2931 x_wm_set_size_hint (f
, 0, false);
2937 set_machine_and_pid_properties (struct frame
*f
)
2939 /* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME. */
2940 XSetWMProperties (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
), NULL
, NULL
,
2941 NULL
, 0, NULL
, NULL
, NULL
);
2942 pid_t pid
= getpid ();
2943 if (pid
<= 0xffffffffu
)
2945 unsigned long xpid
= pid
;
2946 XChangeProperty (FRAME_X_DISPLAY (f
),
2947 FRAME_OUTER_WINDOW (f
),
2948 XInternAtom (FRAME_X_DISPLAY (f
),
2951 XA_CARDINAL
, 32, PropModeReplace
,
2952 (unsigned char *) &xpid
, 1);
2956 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
2958 doc
: /* Make a new X window, which is called a "frame" in Emacs terms.
2959 Return an Emacs frame object. PARMS is an alist of frame parameters.
2960 If the parameters specify that the frame should not have a minibuffer,
2961 and do not specify a specific minibuffer window to use, then
2962 `default-minibuffer-frame' must be a frame whose minibuffer can be
2963 shared by the new frame.
2965 This function is an internal primitive--use `make-frame' instead. */)
2969 Lisp_Object frame
, tem
;
2971 bool minibuffer_only
= false;
2972 long window_prompting
= 0;
2973 ptrdiff_t count
= SPECPDL_INDEX ();
2974 Lisp_Object display
;
2975 struct x_display_info
*dpyinfo
= NULL
;
2979 parms
= Fcopy_alist (parms
);
2981 /* Use this general default value to start with
2982 until we know if this frame has a specified name. */
2983 Vx_resource_name
= Vinvocation_name
;
2985 display
= x_get_arg (dpyinfo
, parms
, Qterminal
, 0, 0, RES_TYPE_NUMBER
);
2986 if (EQ (display
, Qunbound
))
2987 display
= x_get_arg (dpyinfo
, parms
, Qdisplay
, 0, 0, RES_TYPE_STRING
);
2988 if (EQ (display
, Qunbound
))
2990 dpyinfo
= check_x_display_info (display
);
2991 kb
= dpyinfo
->terminal
->kboard
;
2993 if (!dpyinfo
->terminal
->name
)
2994 error ("Terminal is not live, can't create new frames on it");
2996 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
2998 && ! EQ (name
, Qunbound
)
3000 error ("Invalid frame name--not a string or nil");
3003 Vx_resource_name
= name
;
3005 /* See if parent window is specified. */
3006 parent
= x_get_arg (dpyinfo
, parms
, Qparent_id
, NULL
, NULL
, RES_TYPE_NUMBER
);
3007 if (EQ (parent
, Qunbound
))
3009 if (! NILP (parent
))
3010 CHECK_NUMBER (parent
);
3013 tem
= x_get_arg (dpyinfo
, parms
, Qminibuffer
, "minibuffer", "Minibuffer",
3015 if (EQ (tem
, Qnone
) || NILP (tem
))
3016 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
3017 else if (EQ (tem
, Qonly
))
3019 f
= make_minibuffer_frame ();
3020 minibuffer_only
= true;
3022 else if (WINDOWP (tem
))
3023 f
= make_frame_without_minibuffer (tem
, kb
, display
);
3025 f
= make_frame (true);
3027 XSETFRAME (frame
, f
);
3029 f
->terminal
= dpyinfo
->terminal
;
3031 f
->output_method
= output_x_window
;
3032 f
->output_data
.x
= xzalloc (sizeof *f
->output_data
.x
);
3033 f
->output_data
.x
->icon_bitmap
= -1;
3034 FRAME_FONTSET (f
) = -1;
3035 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
3036 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
3037 #if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
3038 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
3039 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
3040 #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
3041 f
->output_data
.x
->white_relief
.pixel
= -1;
3042 f
->output_data
.x
->black_relief
.pixel
= -1;
3045 x_get_arg (dpyinfo
, parms
, Qicon_name
, "iconName", "Title",
3047 if (! STRINGP (f
->icon_name
))
3048 fset_icon_name (f
, Qnil
);
3050 FRAME_DISPLAY_INFO (f
) = dpyinfo
;
3052 /* With FRAME_DISPLAY_INFO set up, this unwind-protect is safe. */
3053 record_unwind_protect (do_unwind_create_frame
, frame
);
3055 /* These colors will be set anyway later, but it's important
3056 to get the color reference counts right, so initialize them! */
3060 /* Function x_decode_color can signal an error. Make
3061 sure to initialize color slots so that we won't try
3062 to free colors we haven't allocated. */
3063 FRAME_FOREGROUND_PIXEL (f
) = -1;
3064 FRAME_BACKGROUND_PIXEL (f
) = -1;
3065 f
->output_data
.x
->cursor_pixel
= -1;
3066 f
->output_data
.x
->cursor_foreground_pixel
= -1;
3067 f
->output_data
.x
->border_pixel
= -1;
3068 f
->output_data
.x
->mouse_pixel
= -1;
3070 black
= build_string ("black");
3071 FRAME_FOREGROUND_PIXEL (f
)
3072 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3073 FRAME_BACKGROUND_PIXEL (f
)
3074 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3075 f
->output_data
.x
->cursor_pixel
3076 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3077 f
->output_data
.x
->cursor_foreground_pixel
3078 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3079 f
->output_data
.x
->border_pixel
3080 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3081 f
->output_data
.x
->mouse_pixel
3082 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
3085 /* Specify the parent under which to make this X window. */
3088 f
->output_data
.x
->parent_desc
= (Window
) XFASTINT (parent
);
3089 f
->output_data
.x
->explicit_parent
= true;
3093 f
->output_data
.x
->parent_desc
= FRAME_DISPLAY_INFO (f
)->root_window
;
3094 f
->output_data
.x
->explicit_parent
= false;
3097 /* Set the name; the functions to which we pass f expect the name to
3099 if (EQ (name
, Qunbound
) || NILP (name
))
3101 fset_name (f
, build_string (dpyinfo
->x_id_name
));
3102 f
->explicit_name
= false;
3106 fset_name (f
, name
);
3107 f
->explicit_name
= true;
3108 /* Use the frame's title when getting resources for this frame. */
3109 specbind (Qx_resource_name
, name
);
3113 register_font_driver (&ftcrfont_driver
, f
);
3115 #ifdef HAVE_FREETYPE
3117 register_font_driver (&xftfont_driver
, f
);
3118 #else /* not HAVE_XFT */
3119 register_font_driver (&ftxfont_driver
, f
);
3120 #endif /* not HAVE_XFT */
3121 #endif /* HAVE_FREETYPE */
3122 register_font_driver (&xfont_driver
, f
);
3123 #endif /* not USE_CAIRO */
3125 image_cache_refcount
=
3126 FRAME_IMAGE_CACHE (f
) ? FRAME_IMAGE_CACHE (f
)->refcount
: 0;
3128 dpyinfo_refcount
= dpyinfo
->reference_count
;
3129 #endif /* GLYPH_DEBUG */
3131 x_default_parameter (f
, parms
, Qfont_backend
, Qnil
,
3132 "fontBackend", "FontBackend", RES_TYPE_STRING
);
3134 /* Extract the window parameters from the supplied values
3135 that are needed to determine window geometry. */
3136 x_default_font_parameter (f
, parms
);
3137 if (!FRAME_FONT (f
))
3139 delete_frame (frame
, Qnoelisp
);
3140 error ("Invalid frame font");
3143 /* Frame contents get displaced if an embedded X window has a border. */
3144 if (! FRAME_X_EMBEDDED_P (f
))
3145 x_default_parameter (f
, parms
, Qborder_width
, make_number (0),
3146 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
3148 /* This defaults to 1 in order to match xterm. We recognize either
3149 internalBorderWidth or internalBorder (which is what xterm calls
3151 if (NILP (Fassq (Qinternal_border_width
, parms
)))
3155 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
3156 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
3157 if (! EQ (value
, Qunbound
))
3158 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
3161 x_default_parameter (f
, parms
, Qinternal_border_width
,
3162 #ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */
3167 "internalBorderWidth", "internalBorderWidth",
3169 x_default_parameter (f
, parms
, Qright_divider_width
, make_number (0),
3170 NULL
, NULL
, RES_TYPE_NUMBER
);
3171 x_default_parameter (f
, parms
, Qbottom_divider_width
, make_number (0),
3172 NULL
, NULL
, RES_TYPE_NUMBER
);
3173 x_default_parameter (f
, parms
, Qvertical_scroll_bars
,
3174 #if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
3179 "verticalScrollBars", "ScrollBars",
3181 x_default_parameter (f
, parms
, Qhorizontal_scroll_bars
, Qnil
,
3182 "horizontalScrollBars", "ScrollBars",
3184 /* Also do the stuff which must be set before the window exists. */
3185 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
3186 "foreground", "Foreground", RES_TYPE_STRING
);
3187 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
3188 "background", "Background", RES_TYPE_STRING
);
3189 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
3190 "pointerColor", "Foreground", RES_TYPE_STRING
);
3191 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
3192 "borderColor", "BorderColor", RES_TYPE_STRING
);
3193 x_default_parameter (f
, parms
, Qscreen_gamma
, Qnil
,
3194 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT
);
3195 x_default_parameter (f
, parms
, Qline_spacing
, Qnil
,
3196 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER
);
3197 x_default_parameter (f
, parms
, Qleft_fringe
, Qnil
,
3198 "leftFringe", "LeftFringe", RES_TYPE_NUMBER
);
3199 x_default_parameter (f
, parms
, Qright_fringe
, Qnil
,
3200 "rightFringe", "RightFringe", RES_TYPE_NUMBER
);
3202 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_foreground
,
3203 "scrollBarForeground",
3204 "ScrollBarForeground", true);
3205 x_default_scroll_bar_color_parameter (f
, parms
, Qscroll_bar_background
,
3206 "scrollBarBackground",
3207 "ScrollBarBackground", false);
3209 /* Init faces before x_default_parameter is called for the
3210 scroll-bar-width parameter because otherwise we end up in
3211 init_iterator with a null face cache, which should not happen. */
3212 init_frame_faces (f
);
3214 /* The following call of change_frame_size is needed since otherwise
3215 x_set_tool_bar_lines will already work with the character sizes
3216 installed by init_frame_faces while the frame's pixel size is
3217 still calculated from a character size of 1 and we subsequently
3218 hit the (height >= 0) assertion in window_box_height.
3220 The non-pixelwise code apparently worked around this because it
3221 had one frame line vs one toolbar line which left us with a zero
3222 root window height which was obviously wrong as well ... */
3223 adjust_frame_size (f
, FRAME_COLS (f
) * FRAME_COLUMN_WIDTH (f
),
3224 FRAME_LINES (f
) * FRAME_LINE_HEIGHT (f
), 5, true,
3227 /* Set the menu-bar-lines and tool-bar-lines parameters. We don't
3228 look up the X resources controlling the menu-bar and tool-bar
3229 here; they are processed specially at startup, and reflected in
3230 the values of the mode variables. */
3232 x_default_parameter (f
, parms
, Qmenu_bar_lines
,
3233 NILP (Vmenu_bar_mode
)
3234 ? make_number (0) : make_number (1),
3235 NULL
, NULL
, RES_TYPE_NUMBER
);
3236 x_default_parameter (f
, parms
, Qtool_bar_lines
,
3237 NILP (Vtool_bar_mode
)
3238 ? make_number (0) : make_number (1),
3239 NULL
, NULL
, RES_TYPE_NUMBER
);
3241 x_default_parameter (f
, parms
, Qbuffer_predicate
, Qnil
,
3242 "bufferPredicate", "BufferPredicate",
3244 x_default_parameter (f
, parms
, Qtitle
, Qnil
,
3245 "title", "Title", RES_TYPE_STRING
);
3246 x_default_parameter (f
, parms
, Qwait_for_wm
, Qt
,
3247 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN
);
3248 x_default_parameter (f
, parms
, Qtool_bar_position
,
3249 FRAME_TOOL_BAR_POSITION (f
), 0, 0, RES_TYPE_SYMBOL
);
3251 /* Compute the size of the X window. */
3252 window_prompting
= x_figure_window_size (f
, parms
, true);
3254 tem
= x_get_arg (dpyinfo
, parms
, Qunsplittable
, 0, 0, RES_TYPE_BOOLEAN
);
3255 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
3257 x_icon_verify (f
, parms
);
3259 /* Create the X widget or window. */
3260 #ifdef USE_X_TOOLKIT
3261 x_window (f
, window_prompting
);
3269 /* Now consider the frame official. */
3270 f
->terminal
->reference_count
++;
3271 FRAME_DISPLAY_INFO (f
)->reference_count
++;
3272 Vframe_list
= Fcons (frame
, Vframe_list
);
3274 /* We need to do this after creating the X window, so that the
3275 icon-creation functions can say whose icon they're describing. */
3276 x_default_parameter (f
, parms
, Qicon_type
, Qt
,
3277 "bitmapIcon", "BitmapIcon", RES_TYPE_BOOLEAN
);
3279 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
3280 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3281 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
3282 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
3283 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
3284 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
3285 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
3286 "scrollBarWidth", "ScrollBarWidth",
3288 x_default_parameter (f
, parms
, Qscroll_bar_height
, Qnil
,
3289 "scrollBarHeight", "ScrollBarHeight",
3291 x_default_parameter (f
, parms
, Qalpha
, Qnil
,
3292 "alpha", "Alpha", RES_TYPE_NUMBER
);
3294 /* Consider frame official, now. */
3295 f
->can_x_set_window_size
= true;
3297 adjust_frame_size (f
, FRAME_TEXT_WIDTH (f
), FRAME_TEXT_HEIGHT (f
), 0, true,
3300 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3301 /* Create the menu bar. */
3302 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
3304 /* If this signals an error, we haven't set size hints for the
3305 frame and we didn't make it visible. */
3306 initialize_frame_menubar (f
);
3309 /* This is a no-op, except under Motif where it arranges the
3310 main window for the widgets on it. */
3311 lw_set_main_areas (f
->output_data
.x
->column_widget
,
3312 f
->output_data
.x
->menubar_widget
,
3313 f
->output_data
.x
->edit_widget
);
3314 #endif /* not USE_GTK */
3316 #endif /* USE_X_TOOLKIT || USE_GTK */
3318 /* Tell the server what size and position, etc, we want, and how
3319 badly we want them. This should be done after we have the menu
3320 bar so that its size can be taken into account. */
3322 x_wm_set_size_hint (f
, window_prompting
, false);
3325 /* Process fullscreen parameter here in the hope that normalizing a
3326 fullheight/fullwidth frame will produce the size set by the last
3327 adjust_frame_size call. */
3328 x_default_parameter (f
, parms
, Qfullscreen
, Qnil
,
3329 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL
);
3331 /* Make the window appear on the frame and enable display, unless
3332 the caller says not to. However, with explicit parent, Emacs
3333 cannot control visibility, so don't try. */
3334 if (! f
->output_data
.x
->explicit_parent
)
3336 Lisp_Object visibility
;
3338 visibility
= x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0,
3340 if (EQ (visibility
, Qunbound
))
3343 if (EQ (visibility
, Qicon
))
3344 x_iconify_frame (f
);
3345 else if (! NILP (visibility
))
3346 x_make_frame_visible (f
);
3349 /* Must have been Qnil. */
3355 /* Set machine name and pid for the purpose of window managers. */
3356 set_machine_and_pid_properties (f
);
3358 /* Set the WM leader property. GTK does this itself, so this is not
3359 needed when using GTK. */
3360 if (dpyinfo
->client_leader_window
!= 0)
3362 XChangeProperty (FRAME_X_DISPLAY (f
),
3363 FRAME_OUTER_WINDOW (f
),
3364 dpyinfo
->Xatom_wm_client_leader
,
3365 XA_WINDOW
, 32, PropModeReplace
,
3366 (unsigned char *) &dpyinfo
->client_leader_window
, 1);
3371 /* Initialize `default-minibuffer-frame' in case this is the first
3372 frame on this terminal. */
3373 if (FRAME_HAS_MINIBUF_P (f
)
3374 && (!FRAMEP (KVAR (kb
, Vdefault_minibuffer_frame
))
3375 || !FRAME_LIVE_P (XFRAME (KVAR (kb
, Vdefault_minibuffer_frame
)))))
3376 kset_default_minibuffer_frame (kb
, frame
);
3378 /* All remaining specified parameters, which have not been "used"
3379 by x_get_arg and friends, now go in the misc. alist of the frame. */
3380 for (tem
= parms
; CONSP (tem
); tem
= XCDR (tem
))
3381 if (CONSP (XCAR (tem
)) && !NILP (XCAR (XCAR (tem
))))
3382 fset_param_alist (f
, Fcons (XCAR (tem
), f
->param_alist
));
3384 /* Make sure windows on this frame appear in calls to next-window
3385 and similar functions. */
3386 Vwindow_list
= Qnil
;
3388 return unbind_to (count
, frame
);
3392 /* FRAME is used only to get a handle on the X display. We don't pass the
3393 display info directly because we're called from frame.c, which doesn't
3394 know about that structure. */
3397 x_get_focus_frame (struct frame
*frame
)
3399 struct x_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (frame
);
3401 if (! dpyinfo
->x_focus_frame
)
3404 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
3409 /* In certain situations, when the window manager follows a
3410 click-to-focus policy, there seems to be no way around calling
3411 XSetInputFocus to give another frame the input focus .
3413 In an ideal world, XSetInputFocus should generally be avoided so
3414 that applications don't interfere with the window manager's focus
3415 policy. But I think it's okay to use when it's clearly done
3416 following a user-command. */
3419 x_focus_frame (struct frame
*f
)
3421 Display
*dpy
= FRAME_X_DISPLAY (f
);
3424 x_catch_errors (dpy
);
3426 if (FRAME_X_EMBEDDED_P (f
))
3428 /* For Xembedded frames, normally the embedder forwards key
3429 events. See XEmbed Protocol Specification at
3430 http://freedesktop.org/wiki/Specifications/xembed-spec */
3431 xembed_request_focus (f
);
3435 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3436 RevertToParent
, CurrentTime
);
3437 x_ewmh_activate_frame (f
);
3440 x_uncatch_errors ();
3445 DEFUN ("xw-color-defined-p", Fxw_color_defined_p
, Sxw_color_defined_p
, 1, 2, 0,
3446 doc
: /* Internal function called by `color-defined-p', which see.
3447 (Note that the Nextstep version of this function ignores FRAME.) */)
3448 (Lisp_Object color
, Lisp_Object frame
)
3451 struct frame
*f
= decode_window_system_frame (frame
);
3453 CHECK_STRING (color
);
3455 if (x_defined_color (f
, SSDATA (color
), &foo
, false))
3461 DEFUN ("xw-color-values", Fxw_color_values
, Sxw_color_values
, 1, 2, 0,
3462 doc
: /* Internal function called by `color-values', which see. */)
3463 (Lisp_Object color
, Lisp_Object frame
)
3466 struct frame
*f
= decode_window_system_frame (frame
);
3468 CHECK_STRING (color
);
3470 if (x_defined_color (f
, SSDATA (color
), &foo
, false))
3471 return list3i (foo
.red
, foo
.green
, foo
.blue
);
3476 DEFUN ("xw-display-color-p", Fxw_display_color_p
, Sxw_display_color_p
, 0, 1, 0,
3477 doc
: /* Internal function called by `display-color-p', which see. */)
3478 (Lisp_Object terminal
)
3480 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3482 if (dpyinfo
->n_planes
<= 2)
3485 switch (dpyinfo
->visual
->class)
3498 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
3500 doc
: /* Return t if the X display supports shades of gray.
3501 Note that color displays do support shades of gray.
3502 The optional argument TERMINAL specifies which display to ask about.
3503 TERMINAL should be a terminal object, a frame or a display name (a string).
3504 If omitted or nil, that stands for the selected frame's display. */)
3505 (Lisp_Object terminal
)
3507 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3509 if (dpyinfo
->n_planes
<= 1)
3512 switch (dpyinfo
->visual
->class)
3527 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
3529 doc
: /* Return the width in pixels of the X display TERMINAL.
3530 The optional argument TERMINAL specifies which display to ask about.
3531 TERMINAL should be a terminal object, a frame or a display name (a string).
3532 If omitted or nil, that stands for the selected frame's display.
3534 On \"multi-monitor\" setups this refers to the pixel width for all
3535 physical monitors associated with TERMINAL. To get information for
3536 each physical monitor, use `display-monitor-attributes-list'. */)
3537 (Lisp_Object terminal
)
3539 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3541 return make_number (x_display_pixel_width (dpyinfo
));
3544 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
3545 Sx_display_pixel_height
, 0, 1, 0,
3546 doc
: /* Return the height in pixels of the X display TERMINAL.
3547 The optional argument TERMINAL specifies which display to ask about.
3548 TERMINAL should be a terminal object, a frame or a display name (a string).
3549 If omitted or nil, that stands for the selected frame's display.
3551 On \"multi-monitor\" setups this refers to the pixel height for all
3552 physical monitors associated with TERMINAL. To get information for
3553 each physical monitor, use `display-monitor-attributes-list'. */)
3554 (Lisp_Object terminal
)
3556 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3558 return make_number (x_display_pixel_height (dpyinfo
));
3561 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
3563 doc
: /* Return the number of bitplanes of the X display TERMINAL.
3564 The optional argument TERMINAL specifies which display to ask about.
3565 TERMINAL should be a terminal object, a frame or a display name (a string).
3566 If omitted or nil, that stands for the selected frame's display. */)
3567 (Lisp_Object terminal
)
3569 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3571 return make_number (dpyinfo
->n_planes
);
3574 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
3576 doc
: /* Return the number of color cells of the X display TERMINAL.
3577 The optional argument TERMINAL specifies which display to ask about.
3578 TERMINAL should be a terminal object, a frame or a display name (a string).
3579 If omitted or nil, that stands for the selected frame's display. */)
3580 (Lisp_Object terminal
)
3582 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3584 int nr_planes
= DisplayPlanes (dpyinfo
->display
,
3585 XScreenNumberOfScreen (dpyinfo
->screen
));
3587 /* Truncate nr_planes to 24 to avoid integer overflow.
3588 Some displays says 32, but only 24 bits are actually significant.
3589 There are only very few and rare video cards that have more than
3590 24 significant bits. Also 24 bits is more than 16 million colors,
3591 it "should be enough for everyone". */
3592 if (nr_planes
> 24) nr_planes
= 24;
3594 return make_number (1 << nr_planes
);
3597 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
3598 Sx_server_max_request_size
,
3600 doc
: /* Return the maximum request size of the X server of display TERMINAL.
3601 The optional argument TERMINAL specifies which display to ask about.
3602 TERMINAL should be a terminal object, a frame or a display name (a string).
3603 If omitted or nil, that stands for the selected frame's display. */)
3604 (Lisp_Object terminal
)
3606 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3608 return make_number (MAXREQUEST (dpyinfo
->display
));
3611 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
3612 doc
: /* Return the "vendor ID" string of the GUI software on TERMINAL.
3614 (Labeling every distributor as a "vendor" embodies the false assumption
3615 that operating systems cannot be developed and distributed noncommercially.)
3616 The optional argument TERMINAL specifies which display to ask about.
3618 For GNU and Unix systems, this queries the X server software; for
3619 MS-Windows, this queries the OS.
3621 TERMINAL should be a terminal object, a frame or a display name (a string).
3622 If omitted or nil, that stands for the selected frame's display. */)
3623 (Lisp_Object terminal
)
3625 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3626 const char *vendor
= ServerVendor (dpyinfo
->display
);
3628 if (! vendor
) vendor
= "";
3629 return build_string (vendor
);
3632 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
3633 doc
: /* Return the version numbers of the GUI software on TERMINAL.
3634 The value is a list of three integers specifying the version of the GUI
3637 For GNU and Unix system, the first 2 numbers are the version of the X
3638 Protocol used on TERMINAL and the 3rd number is the distributor-specific
3639 release number. For MS-Windows, the 3 numbers report the version and
3640 the build number of the OS.
3642 See also the function `x-server-vendor'.
3644 The optional argument TERMINAL specifies which display to ask about.
3645 TERMINAL should be a terminal object, a frame or a display name (a string).
3646 If omitted or nil, that stands for the selected frame's display. */)
3647 (Lisp_Object terminal
)
3649 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3650 Display
*dpy
= dpyinfo
->display
;
3652 return list3i (ProtocolVersion (dpy
), ProtocolRevision (dpy
),
3653 VendorRelease (dpy
));
3656 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
3657 doc
: /* Return the number of screens on the X server of display TERMINAL.
3658 The optional argument TERMINAL specifies which display to ask about.
3659 TERMINAL should be a terminal object, a frame or a display name (a string).
3660 If omitted or nil, that stands for the selected frame's display. */)
3661 (Lisp_Object terminal
)
3663 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3665 return make_number (ScreenCount (dpyinfo
->display
));
3668 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
3669 doc
: /* Return the height in millimeters of the X display TERMINAL.
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.
3674 On \"multi-monitor\" setups this refers to the height in millimeters for
3675 all physical monitors associated with TERMINAL. To get information
3676 for each physical monitor, use `display-monitor-attributes-list'. */)
3677 (Lisp_Object terminal
)
3679 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3681 return make_number (HeightMMOfScreen (dpyinfo
->screen
));
3684 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
3685 doc
: /* Return the width in millimeters of the X display TERMINAL.
3686 The optional argument TERMINAL specifies which display to ask about.
3687 TERMINAL should be a terminal object, a frame or a display name (a string).
3688 If omitted or nil, that stands for the selected frame's display.
3690 On \"multi-monitor\" setups this refers to the width in millimeters for
3691 all physical monitors associated with TERMINAL. To get information
3692 for each physical monitor, use `display-monitor-attributes-list'. */)
3693 (Lisp_Object terminal
)
3695 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3697 return make_number (WidthMMOfScreen (dpyinfo
->screen
));
3700 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
3701 Sx_display_backing_store
, 0, 1, 0,
3702 doc
: /* Return an indication of whether X display TERMINAL does backing store.
3703 The value may be `always', `when-mapped', or `not-useful'.
3704 The optional argument TERMINAL specifies which display to ask about.
3705 TERMINAL should be a terminal object, a frame or a display name (a string).
3706 If omitted or nil, that stands for the selected frame's display. */)
3707 (Lisp_Object terminal
)
3709 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3712 switch (DoesBackingStore (dpyinfo
->screen
))
3715 result
= intern ("always");
3719 result
= intern ("when-mapped");
3723 result
= intern ("not-useful");
3727 error ("Strange value for BackingStore parameter of screen");
3733 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
3734 Sx_display_visual_class
, 0, 1, 0,
3735 doc
: /* Return the visual class of the X display TERMINAL.
3736 The value is one of the symbols `static-gray', `gray-scale',
3737 `static-color', `pseudo-color', `true-color', or `direct-color'.
3739 The optional argument TERMINAL specifies which display to ask about.
3740 TERMINAL should a terminal object, a frame or a display name (a string).
3741 If omitted or nil, that stands for the selected frame's display. */)
3742 (Lisp_Object terminal
)
3744 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3747 switch (dpyinfo
->visual
->class)
3750 result
= intern ("static-gray");
3753 result
= intern ("gray-scale");
3756 result
= intern ("static-color");
3759 result
= intern ("pseudo-color");
3762 result
= intern ("true-color");
3765 result
= intern ("direct-color");
3768 error ("Display has an unknown visual class");
3774 DEFUN ("x-display-save-under", Fx_display_save_under
,
3775 Sx_display_save_under
, 0, 1, 0,
3776 doc
: /* Return t if the X display TERMINAL supports the save-under feature.
3777 The optional argument TERMINAL specifies which display to ask about.
3778 TERMINAL should be a terminal object, a frame or a display name (a string).
3779 If omitted or nil, that stands for the selected frame's display. */)
3780 (Lisp_Object terminal
)
3782 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
3784 if (DoesSaveUnders (dpyinfo
->screen
) == True
)
3790 /* Store the geometry of the workarea on display DPYINFO into *RECT.
3791 Return false if and only if the workarea information cannot be
3792 obtained via the _NET_WORKAREA root window property. */
3794 #if ! GTK_CHECK_VERSION (3, 4, 0)
3796 x_get_net_workarea (struct x_display_info
*dpyinfo
, XRectangle
*rect
)
3798 Display
*dpy
= dpyinfo
->display
;
3799 long offset
, max_len
;
3800 Atom target_type
, actual_type
;
3801 unsigned long actual_size
, bytes_remaining
;
3802 int rc
, actual_format
;
3803 unsigned char *tmp_data
= NULL
;
3804 bool result
= false;
3806 x_catch_errors (dpy
);
3809 target_type
= XA_CARDINAL
;
3810 rc
= XGetWindowProperty (dpy
, dpyinfo
->root_window
,
3811 dpyinfo
->Xatom_net_current_desktop
,
3812 offset
, max_len
, False
, target_type
,
3813 &actual_type
, &actual_format
, &actual_size
,
3814 &bytes_remaining
, &tmp_data
);
3815 if (rc
== Success
&& actual_type
== target_type
&& !x_had_errors_p (dpy
)
3816 && actual_format
== 32 && actual_size
== max_len
)
3818 long current_desktop
= ((long *) tmp_data
)[0];
3823 offset
= 4 * current_desktop
;
3825 rc
= XGetWindowProperty (dpy
, dpyinfo
->root_window
,
3826 dpyinfo
->Xatom_net_workarea
,
3827 offset
, max_len
, False
, target_type
,
3828 &actual_type
, &actual_format
, &actual_size
,
3829 &bytes_remaining
, &tmp_data
);
3830 if (rc
== Success
&& actual_type
== target_type
&& !x_had_errors_p (dpy
)
3831 && actual_format
== 32 && actual_size
== max_len
)
3833 long *values
= (long *) tmp_data
;
3835 rect
->x
= values
[0];
3836 rect
->y
= values
[1];
3837 rect
->width
= values
[2];
3838 rect
->height
= values
[3];
3848 x_uncatch_errors ();
3856 /* Return monitor number where F is "most" or closest to. */
3858 x_get_monitor_for_frame (struct frame
*f
,
3859 struct MonitorInfo
*monitors
,
3863 int area
= 0, dist
= -1;
3864 int best_area
= -1, best_dist
= -1;
3867 if (n_monitors
== 1) return 0;
3868 frect
.x
= f
->left_pos
;
3869 frect
.y
= f
->top_pos
;
3870 frect
.width
= FRAME_PIXEL_WIDTH (f
);
3871 frect
.height
= FRAME_PIXEL_HEIGHT (f
);
3873 for (i
= 0; i
< n_monitors
; ++i
)
3875 struct MonitorInfo
*mi
= &monitors
[i
];
3879 if (mi
->geom
.width
== 0) continue;
3881 if (x_intersect_rectangles (&mi
->geom
, &frect
, &res
))
3883 a
= res
.width
* res
.height
;
3891 if (a
== 0 && area
== 0)
3894 if (frect
.x
+ frect
.width
< mi
->geom
.x
)
3895 dx
= mi
->geom
.x
- frect
.x
+ frect
.width
;
3896 else if (frect
.x
> mi
->geom
.x
+ mi
->geom
.width
)
3897 dx
= frect
.x
- mi
->geom
.x
+ mi
->geom
.width
;
3900 if (frect
.y
+ frect
.height
< mi
->geom
.y
)
3901 dy
= mi
->geom
.y
- frect
.y
+ frect
.height
;
3902 else if (frect
.y
> mi
->geom
.y
+ mi
->geom
.height
)
3903 dy
= frect
.y
- mi
->geom
.y
+ mi
->geom
.height
;
3908 if (dist
== -1 || dist
> d
)
3916 return best_area
!= -1 ? best_area
: (best_dist
!= -1 ? best_dist
: 0);
3920 x_make_monitor_attribute_list (struct MonitorInfo
*monitors
,
3922 int primary_monitor
,
3923 struct x_display_info
*dpyinfo
,
3926 Lisp_Object monitor_frames
= Fmake_vector (make_number (n_monitors
), Qnil
);
3927 Lisp_Object frame
, rest
;
3929 FOR_EACH_FRAME (rest
, frame
)
3931 struct frame
*f
= XFRAME (frame
);
3933 if (FRAME_X_P (f
) && FRAME_DISPLAY_INFO (f
) == dpyinfo
3934 && !EQ (frame
, tip_frame
))
3936 int i
= x_get_monitor_for_frame (f
, monitors
, n_monitors
);
3937 ASET (monitor_frames
, i
, Fcons (frame
, AREF (monitor_frames
, i
)));
3941 return make_monitor_attribute_list (monitors
, n_monitors
, primary_monitor
,
3942 monitor_frames
, source
);
3946 x_get_monitor_attributes_fallback (struct x_display_info
*dpyinfo
)
3948 struct MonitorInfo monitor
;
3949 XRectangle workarea_r
;
3951 /* Fallback: treat (possibly) multiple physical monitors as if they
3952 formed a single monitor as a whole. This should provide a
3953 consistent result at least on single monitor environments. */
3954 monitor
.geom
.x
= monitor
.geom
.y
= 0;
3955 monitor
.geom
.width
= x_display_pixel_width (dpyinfo
);
3956 monitor
.geom
.height
= x_display_pixel_height (dpyinfo
);
3957 monitor
.mm_width
= WidthMMOfScreen (dpyinfo
->screen
);
3958 monitor
.mm_height
= HeightMMOfScreen (dpyinfo
->screen
);
3959 monitor
.name
= xstrdup ("combined screen");
3961 if (x_get_net_workarea (dpyinfo
, &workarea_r
))
3962 monitor
.work
= workarea_r
;
3964 monitor
.work
= monitor
.geom
;
3965 return x_make_monitor_attribute_list (&monitor
, 1, 0, dpyinfo
, "fallback");
3969 #ifdef HAVE_XINERAMA
3971 x_get_monitor_attributes_xinerama (struct x_display_info
*dpyinfo
)
3974 Lisp_Object attributes_list
= Qnil
;
3975 Display
*dpy
= dpyinfo
->display
;
3976 XineramaScreenInfo
*info
= XineramaQueryScreens (dpy
, &n_monitors
);
3977 struct MonitorInfo
*monitors
;
3978 double mm_width_per_pixel
, mm_height_per_pixel
;
3980 if (! info
|| n_monitors
== 0)
3984 return attributes_list
;
3987 mm_width_per_pixel
= ((double) WidthMMOfScreen (dpyinfo
->screen
)
3988 / x_display_pixel_width (dpyinfo
));
3989 mm_height_per_pixel
= ((double) HeightMMOfScreen (dpyinfo
->screen
)
3990 / x_display_pixel_height (dpyinfo
));
3991 monitors
= xzalloc (n_monitors
* sizeof *monitors
);
3992 for (i
= 0; i
< n_monitors
; ++i
)
3994 struct MonitorInfo
*mi
= &monitors
[i
];
3995 XRectangle workarea_r
;
3997 mi
->geom
.x
= info
[i
].x_org
;
3998 mi
->geom
.y
= info
[i
].y_org
;
3999 mi
->geom
.width
= info
[i
].width
;
4000 mi
->geom
.height
= info
[i
].height
;
4001 mi
->mm_width
= mi
->geom
.width
* mm_width_per_pixel
+ 0.5;
4002 mi
->mm_height
= mi
->geom
.height
* mm_height_per_pixel
+ 0.5;
4005 /* Xinerama usually have primary monitor first, just use that. */
4006 if (i
== 0 && x_get_net_workarea (dpyinfo
, &workarea_r
))
4008 mi
->work
= workarea_r
;
4009 if (! x_intersect_rectangles (&mi
->geom
, &mi
->work
, &mi
->work
))
4010 mi
->work
= mi
->geom
;
4013 mi
->work
= mi
->geom
;
4017 attributes_list
= x_make_monitor_attribute_list (monitors
,
4022 free_monitors (monitors
, n_monitors
);
4023 return attributes_list
;
4025 #endif /* HAVE_XINERAMA */
4030 x_get_monitor_attributes_xrandr (struct x_display_info
*dpyinfo
)
4032 Lisp_Object attributes_list
= Qnil
;
4033 XRRScreenResources
*resources
;
4034 Display
*dpy
= dpyinfo
->display
;
4035 int i
, n_monitors
, primary
= -1;
4036 RROutput pxid
= None
;
4037 struct MonitorInfo
*monitors
;
4039 #ifdef HAVE_XRRGETSCREENRESOURCESCURRENT
4040 resources
= XRRGetScreenResourcesCurrent (dpy
, dpyinfo
->root_window
);
4042 resources
= XRRGetScreenResources (dpy
, dpyinfo
->root_window
);
4044 if (! resources
|| resources
->noutput
== 0)
4047 XRRFreeScreenResources (resources
);
4050 n_monitors
= resources
->noutput
;
4051 monitors
= xzalloc (n_monitors
* sizeof *monitors
);
4053 #ifdef HAVE_XRRGETOUTPUTPRIMARY
4054 pxid
= XRRGetOutputPrimary (dpy
, dpyinfo
->root_window
);
4057 for (i
= 0; i
< n_monitors
; ++i
)
4059 XRROutputInfo
*info
= XRRGetOutputInfo (dpy
, resources
,
4060 resources
->outputs
[i
]);
4061 Connection conn
= info
? info
->connection
: RR_Disconnected
;
4062 RRCrtc id
= info
? info
->crtc
: None
;
4064 if (strcmp (info
->name
, "default") == 0)
4066 /* Non XRandr 1.2 driver, does not give useful data. */
4067 XRRFreeOutputInfo (info
);
4068 XRRFreeScreenResources (resources
);
4069 free_monitors (monitors
, n_monitors
);
4073 if (conn
!= RR_Disconnected
&& id
!= None
)
4075 XRRCrtcInfo
*crtc
= XRRGetCrtcInfo (dpy
, resources
, id
);
4076 struct MonitorInfo
*mi
= &monitors
[i
];
4077 XRectangle workarea_r
;
4081 XRRFreeOutputInfo (info
);
4085 mi
->geom
.x
= crtc
->x
;
4086 mi
->geom
.y
= crtc
->y
;
4087 mi
->geom
.width
= crtc
->width
;
4088 mi
->geom
.height
= crtc
->height
;
4089 mi
->mm_width
= info
->mm_width
;
4090 mi
->mm_height
= info
->mm_height
;
4091 mi
->name
= xstrdup (info
->name
);
4093 if (pxid
!= None
&& pxid
== resources
->outputs
[i
])
4095 else if (primary
== -1 && strcmp (info
->name
, "LVDS") == 0)
4098 if (i
== primary
&& x_get_net_workarea (dpyinfo
, &workarea_r
))
4100 mi
->work
= workarea_r
;
4101 if (! x_intersect_rectangles (&mi
->geom
, &mi
->work
, &mi
->work
))
4102 mi
->work
= mi
->geom
;
4105 mi
->work
= mi
->geom
;
4107 XRRFreeCrtcInfo (crtc
);
4109 XRRFreeOutputInfo (info
);
4111 XRRFreeScreenResources (resources
);
4113 attributes_list
= x_make_monitor_attribute_list (monitors
,
4118 free_monitors (monitors
, n_monitors
);
4119 return attributes_list
;
4121 #endif /* HAVE_XRANDR */
4124 x_get_monitor_attributes (struct x_display_info
*dpyinfo
)
4126 Lisp_Object attributes_list
= Qnil
;
4127 Display
*dpy
= dpyinfo
->display
;
4129 (void) dpy
; /* Suppress unused variable warning. */
4132 int xrr_event_base
, xrr_error_base
;
4133 bool xrr_ok
= false;
4134 xrr_ok
= XRRQueryExtension (dpy
, &xrr_event_base
, &xrr_error_base
);
4137 int xrr_major
, xrr_minor
;
4138 XRRQueryVersion (dpy
, &xrr_major
, &xrr_minor
);
4139 xrr_ok
= (xrr_major
== 1 && xrr_minor
>= 2) || xrr_major
> 1;
4143 attributes_list
= x_get_monitor_attributes_xrandr (dpyinfo
);
4144 #endif /* HAVE_XRANDR */
4146 #ifdef HAVE_XINERAMA
4147 if (NILP (attributes_list
))
4149 int xin_event_base
, xin_error_base
;
4150 bool xin_ok
= false;
4151 xin_ok
= XineramaQueryExtension (dpy
, &xin_event_base
, &xin_error_base
);
4152 if (xin_ok
&& XineramaIsActive (dpy
))
4153 attributes_list
= x_get_monitor_attributes_xinerama (dpyinfo
);
4155 #endif /* HAVE_XINERAMA */
4157 if (NILP (attributes_list
))
4158 attributes_list
= x_get_monitor_attributes_fallback (dpyinfo
);
4160 return attributes_list
;
4163 #endif /* !USE_GTK */
4165 DEFUN ("x-display-monitor-attributes-list", Fx_display_monitor_attributes_list
,
4166 Sx_display_monitor_attributes_list
,
4168 doc
: /* Return a list of physical monitor attributes on the X display TERMINAL.
4170 The optional argument TERMINAL specifies which display to ask about.
4171 TERMINAL should be a terminal object, a frame or a display name (a string).
4172 If omitted or nil, that stands for the selected frame's display.
4174 In addition to the standard attribute keys listed in
4175 `display-monitor-attributes-list', the following keys are contained in
4178 source -- String describing the source from which multi-monitor
4179 information is obtained, one of \"Gdk\", \"XRandr\",
4180 \"Xinerama\", or \"fallback\"
4182 Internal use only, use `display-monitor-attributes-list' instead. */)
4183 (Lisp_Object terminal
)
4185 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4186 Lisp_Object attributes_list
= Qnil
;
4189 double mm_width_per_pixel
, mm_height_per_pixel
;
4192 gint primary_monitor
= 0, n_monitors
, i
;
4193 Lisp_Object monitor_frames
, rest
, frame
;
4194 static const char *source
= "Gdk";
4195 struct MonitorInfo
*monitors
;
4198 mm_width_per_pixel
= ((double) WidthMMOfScreen (dpyinfo
->screen
)
4199 / x_display_pixel_width (dpyinfo
));
4200 mm_height_per_pixel
= ((double) HeightMMOfScreen (dpyinfo
->screen
)
4201 / x_display_pixel_height (dpyinfo
));
4202 gdpy
= gdk_x11_lookup_xdisplay (dpyinfo
->display
);
4203 gscreen
= gdk_display_get_default_screen (gdpy
);
4204 #if GTK_CHECK_VERSION (2, 20, 0)
4205 primary_monitor
= gdk_screen_get_primary_monitor (gscreen
);
4207 n_monitors
= gdk_screen_get_n_monitors (gscreen
);
4208 monitor_frames
= Fmake_vector (make_number (n_monitors
), Qnil
);
4209 monitors
= xzalloc (n_monitors
* sizeof *monitors
);
4211 FOR_EACH_FRAME (rest
, frame
)
4213 struct frame
*f
= XFRAME (frame
);
4215 if (FRAME_X_P (f
) && FRAME_DISPLAY_INFO (f
) == dpyinfo
4216 && !EQ (frame
, tip_frame
))
4218 GdkWindow
*gwin
= gtk_widget_get_window (FRAME_GTK_WIDGET (f
));
4220 i
= gdk_screen_get_monitor_at_window (gscreen
, gwin
);
4221 ASET (monitor_frames
, i
, Fcons (frame
, AREF (monitor_frames
, i
)));
4225 for (i
= 0; i
< n_monitors
; ++i
)
4227 gint width_mm
= -1, height_mm
= -1;
4228 GdkRectangle rec
, work
;
4229 struct MonitorInfo
*mi
= &monitors
[i
];
4231 gdk_screen_get_monitor_geometry (gscreen
, i
, &rec
);
4233 #if GTK_CHECK_VERSION (2, 14, 0)
4234 width_mm
= gdk_screen_get_monitor_width_mm (gscreen
, i
);
4235 height_mm
= gdk_screen_get_monitor_height_mm (gscreen
, i
);
4238 width_mm
= rec
.width
* mm_width_per_pixel
+ 0.5;
4240 height_mm
= rec
.height
* mm_height_per_pixel
+ 0.5;
4242 #if GTK_CHECK_VERSION (3, 4, 0)
4243 gdk_screen_get_monitor_workarea (gscreen
, i
, &work
);
4245 /* Emulate the behavior of GTK+ 3.4. */
4247 XRectangle workarea_r
;
4249 if (i
== primary_monitor
&& x_get_net_workarea (dpyinfo
, &workarea_r
))
4251 work
.x
= workarea_r
.x
;
4252 work
.y
= workarea_r
.y
;
4253 work
.width
= workarea_r
.width
;
4254 work
.height
= workarea_r
.height
;
4255 if (! gdk_rectangle_intersect (&rec
, &work
, &work
))
4266 mi
->geom
.width
= rec
.width
;
4267 mi
->geom
.height
= rec
.height
;
4268 mi
->work
.x
= work
.x
;
4269 mi
->work
.y
= work
.y
;
4270 mi
->work
.width
= work
.width
;
4271 mi
->work
.height
= work
.height
;
4272 mi
->mm_width
= width_mm
;
4273 mi
->mm_height
= height_mm
;
4275 #if GTK_CHECK_VERSION (2, 14, 0)
4276 mi
->name
= gdk_screen_get_monitor_plug_name (gscreen
, i
);
4280 attributes_list
= make_monitor_attribute_list (monitors
,
4286 #else /* not USE_GTK */
4289 attributes_list
= x_get_monitor_attributes (dpyinfo
);
4292 #endif /* not USE_GTK */
4294 return attributes_list
;
4297 /* Return geometric attributes of FRAME. According to the value of
4298 ATTRIBUTES return the outer edges of FRAME (Qouter_edges), the native
4299 edges of FRAME (Qnative_edges), or the inner edges of frame
4300 (Qinner_edges). Any other value means to return the geometry as
4301 returned by Fx_frame_geometry. */
4303 frame_geometry (Lisp_Object frame
, Lisp_Object attribute
)
4305 struct frame
*f
= decode_live_frame (frame
);
4306 /** XWindowAttributes atts; **/
4308 unsigned int ign
, native_width
, native_height
;
4309 int xy_ign
, xptr
, yptr
;
4310 int left_off
, right_off
, top_off
, bottom_off
;
4311 int outer_left
, outer_top
, outer_right
, outer_bottom
;
4312 int native_left
, native_top
, native_right
, native_bottom
;
4313 int inner_left
, inner_top
, inner_right
, inner_bottom
;
4314 int internal_border_width
;
4315 bool menu_bar_external
= false, tool_bar_external
= false;
4316 int menu_bar_height
= 0, menu_bar_width
= 0;
4317 int tool_bar_height
= 0, tool_bar_width
= 0;
4319 if (FRAME_INITIAL_P (f
) || !FRAME_X_P (f
))
4323 XGetGeometry (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
4324 &rootw
, &xy_ign
, &xy_ign
, &native_width
, &native_height
,
4326 /** XGetWindowAttributes (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &atts); **/
4327 x_real_pos_and_offsets (f
, &left_off
, &right_off
, &top_off
, &bottom_off
,
4328 NULL
, NULL
, &xptr
, &yptr
, NULL
);
4331 /** native_width = atts.width; **/
4332 /** native_height = atts.height; **/
4336 outer_right
= outer_left
+ left_off
+ native_width
+ right_off
;
4337 outer_bottom
= outer_top
+ top_off
+ native_height
+ bottom_off
;
4339 native_left
= outer_left
+ left_off
;
4340 native_top
= outer_top
+ top_off
;
4341 native_right
= native_left
+ native_width
;
4342 native_bottom
= native_top
+ native_height
;
4344 internal_border_width
= FRAME_INTERNAL_BORDER_WIDTH (f
);
4345 inner_left
= native_left
+ internal_border_width
;
4346 inner_top
= native_top
+ internal_border_width
;
4347 inner_right
= native_right
- internal_border_width
;
4348 inner_bottom
= native_bottom
- internal_border_width
;
4350 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
4351 menu_bar_external
= true;
4352 menu_bar_height
= FRAME_MENUBAR_HEIGHT (f
);
4353 native_top
+= menu_bar_height
;
4354 inner_top
+= menu_bar_height
;
4356 menu_bar_height
= FRAME_MENU_BAR_HEIGHT (f
);
4357 inner_top
+= menu_bar_height
;
4359 menu_bar_width
= menu_bar_height
? native_width
: 0;
4361 #if defined (USE_GTK)
4362 tool_bar_external
= true;
4363 if (EQ (FRAME_TOOL_BAR_POSITION (f
), Qleft
))
4365 tool_bar_width
= FRAME_TOOLBAR_WIDTH (f
);
4366 native_left
+= tool_bar_width
;
4367 inner_left
+= tool_bar_width
;
4369 = tool_bar_width
? native_height
- menu_bar_height
: 0;
4371 else if (EQ (FRAME_TOOL_BAR_POSITION (f
), Qtop
))
4373 tool_bar_height
= FRAME_TOOLBAR_HEIGHT (f
);
4374 native_top
+= tool_bar_height
;
4375 inner_top
+= tool_bar_height
;
4376 tool_bar_width
= tool_bar_height
? native_width
: 0;
4378 else if (EQ (FRAME_TOOL_BAR_POSITION (f
), Qright
))
4380 tool_bar_width
= FRAME_TOOLBAR_WIDTH (f
);
4381 native_right
-= tool_bar_width
;
4382 inner_right
-= tool_bar_width
;
4384 = tool_bar_width
? native_height
- menu_bar_height
: 0;
4388 tool_bar_height
= FRAME_TOOLBAR_HEIGHT (f
);
4389 native_bottom
-= tool_bar_height
;
4390 inner_bottom
-= tool_bar_height
;
4391 tool_bar_width
= tool_bar_height
? native_width
: 0;
4394 tool_bar_height
= FRAME_TOOL_BAR_HEIGHT (f
);
4395 tool_bar_width
= tool_bar_height
? native_width
: 0;
4396 inner_top
+= tool_bar_height
;
4399 /* Construct list. */
4400 if (EQ (attribute
, Qouter_edges
))
4401 return list4 (make_number (outer_left
), make_number (outer_top
),
4402 make_number (outer_right
), make_number (outer_bottom
));
4403 else if (EQ (attribute
, Qnative_edges
))
4404 return list4 (make_number (native_left
), make_number (native_top
),
4405 make_number (native_right
), make_number (native_bottom
));
4406 else if (EQ (attribute
, Qinner_edges
))
4407 return list4 (make_number (inner_left
), make_number (inner_top
),
4408 make_number (inner_right
), make_number (inner_bottom
));
4411 listn (CONSTYPE_HEAP
, 10,
4412 Fcons (Qouter_position
,
4413 Fcons (make_number (outer_left
),
4414 make_number (outer_top
))),
4416 Fcons (make_number (outer_right
- outer_left
),
4417 make_number (outer_bottom
- outer_top
))),
4419 Fcons (Qexternal_border_size
,
4420 Fcons (make_number (right_off
),
4421 make_number (bottom_off
))),
4423 Fcons (Qtitle_bar_size
,
4424 Fcons (make_number (0),
4425 make_number (top_off
- bottom_off
))),
4426 Fcons (Qmenu_bar_external
, menu_bar_external
? Qt
: Qnil
),
4427 Fcons (Qmenu_bar_size
,
4428 Fcons (make_number (menu_bar_width
),
4429 make_number (menu_bar_height
))),
4430 Fcons (Qtool_bar_external
, tool_bar_external
? Qt
: Qnil
),
4431 Fcons (Qtool_bar_position
, FRAME_TOOL_BAR_POSITION (f
)),
4432 Fcons (Qtool_bar_size
,
4433 Fcons (make_number (tool_bar_width
),
4434 make_number (tool_bar_height
))),
4435 Fcons (Qinternal_border_width
,
4436 make_number (internal_border_width
)));
4439 DEFUN ("x-frame-geometry", Fx_frame_geometry
, Sx_frame_geometry
, 0, 1, 0,
4440 doc
: /* Return geometric attributes of FRAME.
4441 FRAME must be a live frame and defaults to the selected one. The return
4442 value is an association list of the attributes listed below. All height
4443 and width values are in pixels.
4445 `outer-position' is a cons of the outer left and top edges of FRAME
4446 relative to the origin - the position (0, 0) - of FRAME's display.
4448 `outer-size' is a cons of the outer width and height of FRAME. The
4449 outer size includes the title bar and the external borders as well as
4450 any menu and/or tool bar of frame.
4452 `external-border-size' is a cons of the horizontal and vertical width of
4453 FRAME's external borders as supplied by the window manager.
4455 `title-bar-size' is a cons of the width and height of the title bar of
4456 FRAME as supplied by the window manager. If both of them are zero,
4457 FRAME has no title bar. If only the width is zero, Emacs was not
4458 able to retrieve the width information.
4460 `menu-bar-external', if non-nil, means the menu bar is external (never
4461 included in the inner edges of FRAME).
4463 `menu-bar-size' is a cons of the width and height of the menu bar of
4466 `tool-bar-external', if non-nil, means the tool bar is external (never
4467 included in the inner edges of FRAME).
4469 `tool-bar-position' tells on which side the tool bar on FRAME is and can
4470 be one of `left', `top', `right' or `bottom'. If this is nil, FRAME
4473 `tool-bar-size' is a cons of the width and height of the tool bar of
4476 `internal-border-width' is the width of the internal border of
4480 return frame_geometry (frame
, Qnil
);
4483 DEFUN ("x-frame-edges", Fx_frame_edges
, Sx_frame_edges
, 0, 2, 0,
4484 doc
: /* Return edge coordinates of FRAME.
4485 FRAME must be a live frame and defaults to the selected one. The return
4486 value is a list of the form (LEFT, TOP, RIGHT, BOTTOM). All values are
4487 in pixels relative to the origin - the position (0, 0) - of FRAME's
4490 If optional argument TYPE is the symbol `outer-edges', return the outer
4491 edges of FRAME. The outer edges comprise the decorations of the window
4492 manager (like the title bar or external borders) as well as any external
4493 menu or tool bar of FRAME. If optional argument TYPE is the symbol
4494 `native-edges' or nil, return the native edges of FRAME. The native
4495 edges exclude the decorations of the window manager and any external
4496 menu or tool bar of FRAME. If TYPE is the symbol `inner-edges', return
4497 the inner edges of FRAME. These edges exclude title bar, any borders,
4498 menu bar or tool bar of FRAME. */)
4499 (Lisp_Object frame
, Lisp_Object type
)
4501 return frame_geometry (frame
, ((EQ (type
, Qouter_edges
)
4502 || EQ (type
, Qinner_edges
))
4507 DEFUN ("x-mouse-absolute-pixel-position", Fx_mouse_absolute_pixel_position
,
4508 Sx_mouse_absolute_pixel_position
, 0, 0, 0,
4509 doc
: /* Return absolute position of mouse cursor in pixels.
4510 The position is returned as a cons cell (X . Y) of the coordinates of
4511 the mouse cursor position in pixels relative to a position (0, 0) of the
4512 selected frame's display. */)
4515 struct frame
*f
= SELECTED_FRAME ();
4516 Window root
, dummy_window
;
4519 if (FRAME_INITIAL_P (f
) || !FRAME_X_P (f
))
4523 XQueryPointer (FRAME_X_DISPLAY (f
),
4524 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
4525 &root
, &dummy_window
, &x
, &y
, &dummy
, &dummy
,
4526 (unsigned int *) &dummy
);
4529 return Fcons (make_number (x
), make_number (y
));
4532 DEFUN ("x-set-mouse-absolute-pixel-position", Fx_set_mouse_absolute_pixel_position
,
4533 Sx_set_mouse_absolute_pixel_position
, 2, 2, 0,
4534 doc
: /* Move mouse pointer to absolute pixel position (X, Y).
4535 The coordinates X and Y are interpreted in pixels relative to a position
4536 (0, 0) of the selected frame's display. */)
4537 (Lisp_Object x
, Lisp_Object y
)
4539 struct frame
*f
= SELECTED_FRAME ();
4541 if (FRAME_INITIAL_P (f
) || !FRAME_X_P (f
))
4544 CHECK_TYPE_RANGED_INTEGER (int, x
);
4545 CHECK_TYPE_RANGED_INTEGER (int, y
);
4548 XWarpPointer (FRAME_X_DISPLAY (f
), None
, DefaultRootWindow (FRAME_X_DISPLAY (f
)),
4549 0, 0, 0, 0, XINT (x
), XINT (y
));
4555 /************************************************************************
4557 ************************************************************************/
4560 /* Mapping visual names to visuals. */
4562 static struct visual_class
4569 {"StaticGray", StaticGray
},
4570 {"GrayScale", GrayScale
},
4571 {"StaticColor", StaticColor
},
4572 {"PseudoColor", PseudoColor
},
4573 {"TrueColor", TrueColor
},
4574 {"DirectColor", DirectColor
},
4579 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4581 /* Value is the screen number of screen SCR. This is a substitute for
4582 the X function with the same name when that doesn't exist. */
4585 XScreenNumberOfScreen (scr
)
4586 register Screen
*scr
;
4588 Display
*dpy
= scr
->display
;
4591 for (i
= 0; i
< dpy
->nscreens
; ++i
)
4592 if (scr
== dpy
->screens
+ i
)
4598 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4601 /* Select the visual that should be used on display DPYINFO. Set
4602 members of DPYINFO appropriately. Called from x_term_init. */
4605 select_visual (struct x_display_info
*dpyinfo
)
4607 Display
*dpy
= dpyinfo
->display
;
4608 Screen
*screen
= dpyinfo
->screen
;
4610 /* See if a visual is specified. */
4611 AUTO_STRING (visualClass
, "visualClass");
4612 AUTO_STRING (VisualClass
, "VisualClass");
4613 Lisp_Object value
= display_x_get_resource (dpyinfo
, visualClass
,
4614 VisualClass
, Qnil
, Qnil
);
4616 if (STRINGP (value
))
4618 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
4619 of `PseudoColor', `TrueColor' etc. and DEPTH is the color
4620 depth, a decimal number. NAME is compared with case ignored. */
4621 char *s
= alloca (SBYTES (value
) + 1);
4626 lispstpcpy (s
, value
);
4627 dash
= strchr (s
, '-');
4630 dpyinfo
->n_planes
= atoi (dash
+ 1);
4634 /* We won't find a matching visual with depth 0, so that
4635 an error will be printed below. */
4636 dpyinfo
->n_planes
= 0;
4638 /* Determine the visual class. */
4639 for (i
= 0; visual_classes
[i
].name
; ++i
)
4640 if (xstrcasecmp (s
, visual_classes
[i
].name
) == 0)
4642 class = visual_classes
[i
].class;
4646 /* Look up a matching visual for the specified class. */
4648 || !XMatchVisualInfo (dpy
, XScreenNumberOfScreen (screen
),
4649 dpyinfo
->n_planes
, class, &vinfo
))
4650 fatal ("Invalid visual specification '%s'",
4651 SSDATA (ENCODE_SYSTEM (value
)));
4653 dpyinfo
->visual
= vinfo
.visual
;
4658 XVisualInfo
*vinfo
, vinfo_template
;
4660 dpyinfo
->visual
= DefaultVisualOfScreen (screen
);
4662 vinfo_template
.visualid
= XVisualIDFromVisual (dpyinfo
->visual
);
4663 vinfo_template
.screen
= XScreenNumberOfScreen (screen
);
4664 vinfo
= XGetVisualInfo (dpy
, VisualIDMask
| VisualScreenMask
,
4665 &vinfo_template
, &n_visuals
);
4667 fatal ("Can't get proper X visual info");
4669 dpyinfo
->n_planes
= vinfo
->depth
;
4675 /* Return the X display structure for the display named NAME.
4676 Open a new connection if necessary. */
4678 static struct x_display_info
*
4679 x_display_info_for_name (Lisp_Object name
)
4681 struct x_display_info
*dpyinfo
;
4683 CHECK_STRING (name
);
4685 for (dpyinfo
= x_display_list
; dpyinfo
; dpyinfo
= dpyinfo
->next
)
4686 if (!NILP (Fstring_equal (XCAR (dpyinfo
->name_list_element
), name
)))
4689 /* Use this general default value to start with. */
4690 Vx_resource_name
= Vinvocation_name
;
4692 validate_x_resource_name ();
4694 dpyinfo
= x_term_init (name
, 0, SSDATA (Vx_resource_name
));
4697 error ("Cannot connect to X server %s", SDATA (name
));
4699 XSETFASTINT (Vwindow_system_version
, 11);
4705 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
4707 doc
: /* Open a connection to a display server.
4708 DISPLAY is the name of the display to connect to.
4709 Optional second arg XRM-STRING is a string of resources in xrdb format.
4710 If the optional third arg MUST-SUCCEED is non-nil,
4711 terminate Emacs if we can't open the connection.
4712 (In the Nextstep version, the last two arguments are currently ignored.) */)
4713 (Lisp_Object display
, Lisp_Object xrm_string
, Lisp_Object must_succeed
)
4716 struct x_display_info
*dpyinfo
;
4718 CHECK_STRING (display
);
4719 if (! NILP (xrm_string
))
4720 CHECK_STRING (xrm_string
);
4722 xrm_option
= NILP (xrm_string
) ? 0 : SSDATA (xrm_string
);
4724 validate_x_resource_name ();
4726 /* This is what opens the connection and sets x_current_display.
4727 This also initializes many symbols, such as those used for input. */
4728 dpyinfo
= x_term_init (display
, xrm_option
,
4729 SSDATA (Vx_resource_name
));
4733 if (!NILP (must_succeed
))
4734 fatal ("Cannot connect to X server %s.\n\
4735 Check the DISPLAY environment variable or use `-d'.\n\
4736 Also use the `xauth' program to verify that you have the proper\n\
4737 authorization information needed to connect the X server.\n\
4738 An insecure way to solve the problem may be to use `xhost'.\n",
4741 error ("Cannot connect to X server %s", SDATA (display
));
4744 XSETFASTINT (Vwindow_system_version
, 11);
4748 DEFUN ("x-close-connection", Fx_close_connection
,
4749 Sx_close_connection
, 1, 1, 0,
4750 doc
: /* Close the connection to TERMINAL's X server.
4751 For TERMINAL, specify a terminal object, a frame or a display name (a
4752 string). If TERMINAL is nil, that stands for the selected frame's
4754 (Lisp_Object terminal
)
4756 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4758 if (dpyinfo
->reference_count
> 0)
4759 error ("Display still has frames on it");
4761 x_delete_terminal (dpyinfo
->terminal
);
4766 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
4767 doc
: /* Return the list of display names that Emacs has connections to. */)
4770 Lisp_Object result
= Qnil
;
4771 struct x_display_info
*xdi
;
4773 for (xdi
= x_display_list
; xdi
; xdi
= xdi
->next
)
4774 result
= Fcons (XCAR (xdi
->name_list_element
), result
);
4779 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
4780 doc
: /* If ON is non-nil, report X errors as soon as the erring request is made.
4781 This function only has an effect on X Windows. With MS Windows, it is
4782 defined but does nothing.
4784 If ON is nil, allow buffering of requests.
4785 Turning on synchronization prohibits the Xlib routines from buffering
4786 requests and seriously degrades performance, but makes debugging much
4788 The optional second argument TERMINAL specifies which display to act on.
4789 TERMINAL should be a terminal object, a frame or a display name (a string).
4790 If TERMINAL is omitted or nil, that stands for the selected frame's display. */)
4791 (Lisp_Object on
, Lisp_Object terminal
)
4793 struct x_display_info
*dpyinfo
= check_x_display_info (terminal
);
4795 XSynchronize (dpyinfo
->display
, !EQ (on
, Qnil
));
4800 /* Wait for responses to all X commands issued so far for frame F. */
4803 x_sync (struct frame
*f
)
4806 XSync (FRAME_X_DISPLAY (f
), False
);
4811 /***********************************************************************
4813 ***********************************************************************/
4815 DEFUN ("x-change-window-property", Fx_change_window_property
,
4816 Sx_change_window_property
, 2, 6, 0,
4817 doc
: /* Change window property PROP to VALUE on the X window of FRAME.
4818 PROP must be a string. VALUE may be a string or a list of conses,
4819 numbers and/or strings. If an element in the list is a string, it is
4820 converted to an atom and the value of the atom is used. If an element
4821 is a cons, it is converted to a 32 bit number where the car is the 16
4822 top bits and the cdr is the lower 16 bits.
4824 FRAME nil or omitted means use the selected frame.
4825 If TYPE is given and non-nil, it is the name of the type of VALUE.
4826 If TYPE is not given or nil, the type is STRING.
4827 FORMAT gives the size in bits of each element if VALUE is a list.
4828 It must be one of 8, 16 or 32.
4829 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
4830 If OUTER-P is non-nil, the property is changed for the outer X window of
4831 FRAME. Default is to change on the edit X window. */)
4832 (Lisp_Object prop
, Lisp_Object value
, Lisp_Object frame
,
4833 Lisp_Object type
, Lisp_Object format
, Lisp_Object outer_p
)
4835 struct frame
*f
= decode_window_system_frame (frame
);
4837 Atom target_type
= XA_STRING
;
4838 int element_format
= 8;
4839 unsigned char *data
;
4843 CHECK_STRING (prop
);
4845 if (! NILP (format
))
4847 CHECK_NUMBER (format
);
4849 if (XINT (format
) != 8 && XINT (format
) != 16
4850 && XINT (format
) != 32)
4851 error ("FORMAT must be one of 8, 16 or 32");
4852 element_format
= XINT (format
);
4859 nelements
= x_check_property_data (value
);
4860 if (nelements
== -1)
4861 error ("Bad data in VALUE, must be number, string or cons");
4863 /* The man page for XChangeProperty:
4864 "If the specified format is 32, the property data must be a
4866 This applies even if long is more than 32 bits. The X library
4867 converts to 32 bits before sending to the X server. */
4868 elsize
= element_format
== 32 ? sizeof (long) : element_format
>> 3;
4869 data
= xnmalloc (nelements
, elsize
);
4871 x_fill_property_data (FRAME_X_DISPLAY (f
), value
, data
, element_format
);
4875 CHECK_STRING (value
);
4876 data
= SDATA (value
);
4877 if (INT_MAX
< SBYTES (value
))
4878 error ("VALUE too long");
4879 nelements
= SBYTES (value
);
4883 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (prop
), False
);
4886 CHECK_STRING (type
);
4887 target_type
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (type
), False
);
4890 if (! NILP (outer_p
)) w
= FRAME_OUTER_WINDOW (f
);
4891 else w
= FRAME_X_WINDOW (f
);
4893 XChangeProperty (FRAME_X_DISPLAY (f
), w
,
4894 prop_atom
, target_type
, element_format
, PropModeReplace
,
4897 if (CONSP (value
)) xfree (data
);
4899 /* Make sure the property is set when we return. */
4900 XFlush (FRAME_X_DISPLAY (f
));
4907 DEFUN ("x-delete-window-property", Fx_delete_window_property
,
4908 Sx_delete_window_property
, 1, 2, 0,
4909 doc
: /* Remove window property PROP from X window of FRAME.
4910 FRAME nil or omitted means use the selected frame. Value is PROP. */)
4911 (Lisp_Object prop
, Lisp_Object frame
)
4913 struct frame
*f
= decode_window_system_frame (frame
);
4916 CHECK_STRING (prop
);
4918 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (prop
), False
);
4919 XDeleteProperty (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), prop_atom
);
4921 /* Make sure the property is removed when we return. */
4922 XFlush (FRAME_X_DISPLAY (f
));
4930 x_window_property_intern (struct frame
*f
,
4931 Window target_window
,
4934 Lisp_Object delete_p
,
4935 Lisp_Object vector_ret_p
,
4938 unsigned char *tmp_data
= NULL
;
4939 Lisp_Object prop_value
= Qnil
;
4942 unsigned long actual_size
, bytes_remaining
;
4945 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), target_window
,
4946 prop_atom
, 0, 0, False
, target_type
,
4947 &actual_type
, &actual_format
, &actual_size
,
4948 &bytes_remaining
, &tmp_data
);
4950 *found
= actual_format
!= 0;
4952 if (rc
== Success
&& *found
)
4957 rc
= XGetWindowProperty (FRAME_X_DISPLAY (f
), target_window
,
4958 prop_atom
, 0, bytes_remaining
,
4959 ! NILP (delete_p
), target_type
,
4960 &actual_type
, &actual_format
,
4961 &actual_size
, &bytes_remaining
,
4963 if (rc
== Success
&& tmp_data
)
4965 /* The man page for XGetWindowProperty says:
4966 "If the returned format is 32, the returned data is represented
4967 as a long array and should be cast to that type to obtain the
4969 This applies even if long is more than 32 bits, the X library
4970 converts from 32 bit elements received from the X server to long
4971 and passes the long array to us. Thus, for that case memcpy can not
4972 be used. We convert to a 32 bit type here, because so much code
4975 The bytes and offsets passed to XGetWindowProperty refers to the
4976 property and those are indeed in 32 bit quantities if format is
4979 if (BITS_PER_LONG
> 32 && actual_format
== 32)
4982 int *idata
= (int *) tmp_data
;
4983 long *ldata
= (long *) tmp_data
;
4985 for (i
= 0; i
< actual_size
; ++i
)
4986 idata
[i
] = (int) ldata
[i
];
4989 if (NILP (vector_ret_p
))
4990 prop_value
= make_string ((char *) tmp_data
, actual_size
);
4992 prop_value
= x_property_data_to_lisp (f
,
4999 if (tmp_data
) XFree (tmp_data
);
5005 DEFUN ("x-window-property", Fx_window_property
, Sx_window_property
,
5007 doc
: /* Value is the value of window property PROP on FRAME.
5008 If FRAME is nil or omitted, use the selected frame.
5010 On X Windows, the following optional arguments are also accepted:
5011 If TYPE is nil or omitted, get the property as a string.
5012 Otherwise TYPE is the name of the atom that denotes the type expected.
5013 If SOURCE is non-nil, get the property on that window instead of from
5014 FRAME. The number 0 denotes the root window.
5015 If DELETE-P is non-nil, delete the property after retrieving it.
5016 If VECTOR-RET-P is non-nil, don't return a string but a vector of values.
5018 On MS Windows, this function accepts but ignores those optional arguments.
5020 Value is nil if FRAME hasn't a property with name PROP or if PROP has
5021 no value of TYPE (always string in the MS Windows case). */)
5022 (Lisp_Object prop
, Lisp_Object frame
, Lisp_Object type
,
5023 Lisp_Object source
, Lisp_Object delete_p
, Lisp_Object vector_ret_p
)
5025 struct frame
*f
= decode_window_system_frame (frame
);
5027 Lisp_Object prop_value
= Qnil
;
5028 Atom target_type
= XA_STRING
;
5029 Window target_window
= FRAME_X_WINDOW (f
);
5032 CHECK_STRING (prop
);
5034 if (! NILP (source
))
5036 CONS_TO_INTEGER (source
, Window
, target_window
);
5037 if (! target_window
)
5038 target_window
= FRAME_DISPLAY_INFO (f
)->root_window
;
5044 if (strcmp ("AnyPropertyType", SSDATA (type
)) == 0)
5045 target_type
= AnyPropertyType
;
5047 target_type
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (type
), False
);
5050 prop_atom
= XInternAtom (FRAME_X_DISPLAY (f
), SSDATA (prop
), False
);
5051 prop_value
= x_window_property_intern (f
,
5058 if (NILP (prop_value
)
5061 && target_window
!= FRAME_OUTER_WINDOW (f
))
5063 prop_value
= x_window_property_intern (f
,
5064 FRAME_OUTER_WINDOW (f
),
5077 /***********************************************************************
5079 ***********************************************************************/
5081 static Lisp_Object
x_create_tip_frame (struct x_display_info
*,
5082 Lisp_Object
, Lisp_Object
);
5083 static void compute_tip_xy (struct frame
*, Lisp_Object
, Lisp_Object
,
5084 Lisp_Object
, int, int, int *, int *);
5086 /* The frame of a currently visible tooltip. */
5088 Lisp_Object tip_frame
;
5090 /* If non-nil, a timer started that hides the last tooltip when it
5093 static Lisp_Object tip_timer
;
5096 /* If non-nil, a vector of 3 elements containing the last args
5097 with which x-show-tip was called. See there. */
5099 static Lisp_Object last_show_tip_args
;
5103 unwind_create_tip_frame (Lisp_Object frame
)
5105 Lisp_Object deleted
;
5107 deleted
= unwind_create_frame (frame
);
5108 if (EQ (deleted
, Qt
))
5116 /* Create a frame for a tooltip on the display described by DPYINFO.
5117 PARMS is a list of frame parameters. TEXT is the string to
5118 display in the tip frame. Value is the frame.
5120 Note that functions called here, esp. x_default_parameter can
5121 signal errors, for instance when a specified color name is
5122 undefined. We have to make sure that we're in a consistent state
5123 when this happens. */
5126 x_create_tip_frame (struct x_display_info
*dpyinfo
,
5134 ptrdiff_t count
= SPECPDL_INDEX ();
5135 bool face_change_before
= face_change
;
5137 struct buffer
*old_buffer
;
5139 if (!dpyinfo
->terminal
->name
)
5140 error ("Terminal is not live, can't create new frames on it");
5142 parms
= Fcopy_alist (parms
);
5144 /* Get the name of the frame to use for resource lookup. */
5145 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
5147 && !EQ (name
, Qunbound
)
5149 error ("Invalid frame name--not a string or nil");
5152 f
= make_frame (true);
5153 XSETFRAME (frame
, f
);
5155 AUTO_STRING (tip
, " *tip*");
5156 buffer
= Fget_buffer_create (tip
);
5157 /* Use set_window_buffer instead of Fset_window_buffer (see
5158 discussion of bug#11984, bug#12025, bug#12026). */
5159 set_window_buffer (FRAME_ROOT_WINDOW (f
), buffer
, false, false);
5160 old_buffer
= current_buffer
;
5161 set_buffer_internal_1 (XBUFFER (buffer
));
5162 bset_truncate_lines (current_buffer
, Qnil
);
5163 specbind (Qinhibit_read_only
, Qt
);
5164 specbind (Qinhibit_modification_hooks
, Qt
);
5167 set_buffer_internal_1 (old_buffer
);
5169 record_unwind_protect (unwind_create_tip_frame
, frame
);
5171 f
->terminal
= dpyinfo
->terminal
;
5173 /* By setting the output method, we're essentially saying that
5174 the frame is live, as per FRAME_LIVE_P. If we get a signal
5175 from this point on, x_destroy_window might screw up reference
5177 f
->output_method
= output_x_window
;
5178 f
->output_data
.x
= xzalloc (sizeof *f
->output_data
.x
);
5179 f
->output_data
.x
->icon_bitmap
= -1;
5180 FRAME_FONTSET (f
) = -1;
5181 f
->output_data
.x
->scroll_bar_foreground_pixel
= -1;
5182 f
->output_data
.x
->scroll_bar_background_pixel
= -1;
5183 #if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
5184 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= -1;
5185 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= -1;
5186 #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
5187 f
->output_data
.x
->white_relief
.pixel
= -1;
5188 f
->output_data
.x
->black_relief
.pixel
= -1;
5190 fset_icon_name (f
, Qnil
);
5191 FRAME_DISPLAY_INFO (f
) = dpyinfo
;
5192 f
->output_data
.x
->parent_desc
= FRAME_DISPLAY_INFO (f
)->root_window
;
5193 f
->output_data
.x
->explicit_parent
= false;
5195 /* These colors will be set anyway later, but it's important
5196 to get the color reference counts right, so initialize them! */
5200 /* Function x_decode_color can signal an error. Make
5201 sure to initialize color slots so that we won't try
5202 to free colors we haven't allocated. */
5203 FRAME_FOREGROUND_PIXEL (f
) = -1;
5204 FRAME_BACKGROUND_PIXEL (f
) = -1;
5205 f
->output_data
.x
->cursor_pixel
= -1;
5206 f
->output_data
.x
->cursor_foreground_pixel
= -1;
5207 f
->output_data
.x
->border_pixel
= -1;
5208 f
->output_data
.x
->mouse_pixel
= -1;
5210 black
= build_string ("black");
5211 FRAME_FOREGROUND_PIXEL (f
)
5212 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
5213 FRAME_BACKGROUND_PIXEL (f
)
5214 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
5215 f
->output_data
.x
->cursor_pixel
5216 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
5217 f
->output_data
.x
->cursor_foreground_pixel
5218 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
5219 f
->output_data
.x
->border_pixel
5220 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
5221 f
->output_data
.x
->mouse_pixel
5222 = x_decode_color (f
, black
, BLACK_PIX_DEFAULT (f
));
5225 /* Set the name; the functions to which we pass f expect the name to
5227 if (EQ (name
, Qunbound
) || NILP (name
))
5229 fset_name (f
, build_string (dpyinfo
->x_id_name
));
5230 f
->explicit_name
= false;
5234 fset_name (f
, name
);
5235 f
->explicit_name
= true;
5236 /* use the frame's title when getting resources for this frame. */
5237 specbind (Qx_resource_name
, name
);
5241 register_font_driver (&ftcrfont_driver
, f
);
5243 register_font_driver (&xfont_driver
, f
);
5244 #ifdef HAVE_FREETYPE
5246 register_font_driver (&xftfont_driver
, f
);
5247 #else /* not HAVE_XFT */
5248 register_font_driver (&ftxfont_driver
, f
);
5249 #endif /* not HAVE_XFT */
5250 #endif /* HAVE_FREETYPE */
5251 #endif /* not USE_CAIRO */
5253 image_cache_refcount
=
5254 FRAME_IMAGE_CACHE (f
) ? FRAME_IMAGE_CACHE (f
)->refcount
: 0;
5256 dpyinfo_refcount
= dpyinfo
->reference_count
;
5257 #endif /* GLYPH_DEBUG */
5259 x_default_parameter (f
, parms
, Qfont_backend
, Qnil
,
5260 "fontBackend", "FontBackend", RES_TYPE_STRING
);
5262 /* Extract the window parameters from the supplied values that are
5263 needed to determine window geometry. */
5264 x_default_font_parameter (f
, parms
);
5266 x_default_parameter (f
, parms
, Qborder_width
, make_number (0),
5267 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
5269 /* This defaults to 2 in order to match xterm. We recognize either
5270 internalBorderWidth or internalBorder (which is what xterm calls
5272 if (NILP (Fassq (Qinternal_border_width
, parms
)))
5276 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
5277 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
5278 if (! EQ (value
, Qunbound
))
5279 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
5283 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
5284 "internalBorderWidth", "internalBorderWidth",
5286 x_default_parameter (f
, parms
, Qright_divider_width
, make_number (0),
5287 NULL
, NULL
, RES_TYPE_NUMBER
);
5288 x_default_parameter (f
, parms
, Qbottom_divider_width
, make_number (0),
5289 NULL
, NULL
, RES_TYPE_NUMBER
);
5291 /* Also do the stuff which must be set before the window exists. */
5292 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
5293 "foreground", "Foreground", RES_TYPE_STRING
);
5294 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
5295 "background", "Background", RES_TYPE_STRING
);
5296 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
5297 "pointerColor", "Foreground", RES_TYPE_STRING
);
5298 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
5299 "cursorColor", "Foreground", RES_TYPE_STRING
);
5300 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
5301 "borderColor", "BorderColor", RES_TYPE_STRING
);
5303 /* Init faces before x_default_parameter is called for the
5304 scroll-bar-width parameter because otherwise we end up in
5305 init_iterator with a null face cache, which should not happen. */
5306 init_frame_faces (f
);
5308 f
->output_data
.x
->parent_desc
= FRAME_DISPLAY_INFO (f
)->root_window
;
5310 x_figure_window_size (f
, parms
, false);
5313 XSetWindowAttributes attrs
;
5315 Atom type
= FRAME_DISPLAY_INFO (f
)->Xatom_net_window_type_tooltip
;
5318 mask
= CWBackPixel
| CWOverrideRedirect
| CWEventMask
;
5319 if (DoesSaveUnders (dpyinfo
->screen
))
5320 mask
|= CWSaveUnder
;
5322 /* Window managers look at the override-redirect flag to determine
5323 whether or net to give windows a decoration (Xlib spec, chapter
5325 attrs
.override_redirect
= True
;
5326 attrs
.save_under
= True
;
5327 attrs
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
5328 /* Arrange for getting MapNotify and UnmapNotify events. */
5329 attrs
.event_mask
= StructureNotifyMask
;
5331 = FRAME_X_WINDOW (f
)
5332 = XCreateWindow (FRAME_X_DISPLAY (f
),
5333 FRAME_DISPLAY_INFO (f
)->root_window
,
5334 /* x, y, width, height */
5338 CopyFromParent
, InputOutput
, CopyFromParent
,
5340 XChangeProperty (FRAME_X_DISPLAY (f
), tip_window
,
5341 FRAME_DISPLAY_INFO (f
)->Xatom_net_window_type
,
5342 XA_ATOM
, 32, PropModeReplace
,
5343 (unsigned char *)&type
, 1);
5349 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
5350 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
5351 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
5352 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
5353 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
5354 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
5356 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
5357 Change will not be effected unless different from the current
5359 width
= FRAME_COLS (f
);
5360 height
= FRAME_LINES (f
);
5361 SET_FRAME_COLS (f
, 0);
5362 SET_FRAME_LINES (f
, 0);
5363 change_frame_size (f
, width
, height
, true, false, false, false);
5365 /* Add `tooltip' frame parameter's default value. */
5366 if (NILP (Fframe_parameter (frame
, Qtooltip
)))
5368 AUTO_FRAME_ARG (arg
, Qtooltip
, Qt
);
5369 Fmodify_frame_parameters (frame
, arg
);
5372 /* FIXME - can this be done in a similar way to normal frames?
5373 http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
5375 /* Set the `display-type' frame parameter before setting up faces. */
5377 Lisp_Object disptype
;
5379 if (FRAME_DISPLAY_INFO (f
)->n_planes
== 1)
5381 else if (FRAME_DISPLAY_INFO (f
)->visual
->class == GrayScale
5382 || FRAME_DISPLAY_INFO (f
)->visual
->class == StaticGray
)
5383 disptype
= intern ("grayscale");
5385 disptype
= intern ("color");
5387 if (NILP (Fframe_parameter (frame
, Qdisplay_type
)))
5389 AUTO_FRAME_ARG (arg
, Qdisplay_type
, disptype
);
5390 Fmodify_frame_parameters (frame
, arg
);
5394 /* Set up faces after all frame parameters are known. This call
5395 also merges in face attributes specified for new frames.
5397 Frame parameters may be changed if .Xdefaults contains
5398 specifications for the default font. For example, if there is an
5399 `Emacs.default.attributeBackground: pink', the `background-color'
5400 attribute of the frame get's set, which let's the internal border
5401 of the tooltip frame appear in pink. Prevent this. */
5403 Lisp_Object bg
= Fframe_parameter (frame
, Qbackground_color
);
5405 /* Set tip_frame here, so that */
5407 call2 (Qface_set_after_frame_default
, frame
, Qnil
);
5409 if (!EQ (bg
, Fframe_parameter (frame
, Qbackground_color
)))
5411 AUTO_FRAME_ARG (arg
, Qbackground_color
, bg
);
5412 Fmodify_frame_parameters (frame
, arg
);
5418 /* Now that the frame will be official, it counts as a reference to
5419 its display and terminal. */
5420 FRAME_DISPLAY_INFO (f
)->reference_count
++;
5421 f
->terminal
->reference_count
++;
5423 /* It is now ok to make the frame official even if we get an error
5424 below. And the frame needs to be on Vframe_list or making it
5425 visible won't work. */
5426 Vframe_list
= Fcons (frame
, Vframe_list
);
5427 f
->can_x_set_window_size
= true;
5429 /* Setting attributes of faces of the tooltip frame from resources
5430 and similar will set face_change, which leads to the clearing of
5431 all current matrices. Since this isn't necessary here, avoid it
5432 by resetting face_change to the value it had before we created
5434 face_change
= face_change_before
;
5436 /* Discard the unwind_protect. */
5437 return unbind_to (count
, frame
);
5441 /* Compute where to display tip frame F. PARMS is the list of frame
5442 parameters for F. DX and DY are specified offsets from the current
5443 location of the mouse. WIDTH and HEIGHT are the width and height
5444 of the tooltip. Return coordinates relative to the root window of
5445 the display in *ROOT_X, and *ROOT_Y. */
5448 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
)
5450 Lisp_Object left
, top
, right
, bottom
;
5455 /* User-specified position? */
5456 left
= Fcdr (Fassq (Qleft
, parms
));
5457 top
= Fcdr (Fassq (Qtop
, parms
));
5458 right
= Fcdr (Fassq (Qright
, parms
));
5459 bottom
= Fcdr (Fassq (Qbottom
, parms
));
5461 /* Move the tooltip window where the mouse pointer is. Resize and
5463 if ((!INTEGERP (left
) && !INTEGERP (right
))
5464 || (!INTEGERP (top
) && !INTEGERP (bottom
)))
5467 XQueryPointer (FRAME_X_DISPLAY (f
), FRAME_DISPLAY_INFO (f
)->root_window
,
5468 &root
, &child
, root_x
, root_y
, &win_x
, &win_y
, &pmask
);
5473 *root_y
= XINT (top
);
5474 else if (INTEGERP (bottom
))
5475 *root_y
= XINT (bottom
) - height
;
5476 else if (*root_y
+ XINT (dy
) <= 0)
5477 *root_y
= 0; /* Can happen for negative dy */
5478 else if (*root_y
+ XINT (dy
) + height
5479 <= x_display_pixel_height (FRAME_DISPLAY_INFO (f
)))
5480 /* It fits below the pointer */
5481 *root_y
+= XINT (dy
);
5482 else if (height
+ XINT (dy
) <= *root_y
)
5483 /* It fits above the pointer. */
5484 *root_y
-= height
+ XINT (dy
);
5486 /* Put it on the top. */
5489 if (INTEGERP (left
))
5490 *root_x
= XINT (left
);
5491 else if (INTEGERP (right
))
5492 *root_y
= XINT (right
) - width
;
5493 else if (*root_x
+ XINT (dx
) <= 0)
5494 *root_x
= 0; /* Can happen for negative dx */
5495 else if (*root_x
+ XINT (dx
) + width
5496 <= x_display_pixel_width (FRAME_DISPLAY_INFO (f
)))
5497 /* It fits to the right of the pointer. */
5498 *root_x
+= XINT (dx
);
5499 else if (width
+ XINT (dx
) <= *root_x
)
5500 /* It fits to the left of the pointer. */
5501 *root_x
-= width
+ XINT (dx
);
5503 /* Put it left-justified on the screen--it ought to fit that way. */
5508 DEFUN ("x-show-tip", Fx_show_tip
, Sx_show_tip
, 1, 6, 0,
5509 doc
: /* Show STRING in a "tooltip" window on frame FRAME.
5510 A tooltip window is a small X window displaying a string.
5512 This is an internal function; Lisp code should call `tooltip-show'.
5514 FRAME nil or omitted means use the selected frame.
5516 PARMS is an optional list of frame parameters which can be used to
5517 change the tooltip's appearance.
5519 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
5520 means use the default timeout of 5 seconds.
5522 If the list of frame parameters PARMS contains a `left' parameter,
5523 display the tooltip at that x-position. If the list of frame parameters
5524 PARMS contains no `left' but a `right' parameter, display the tooltip
5525 right-adjusted at that x-position. Otherwise display it at the
5526 x-position of the mouse, with offset DX added (default is 5 if DX isn't
5529 Likewise for the y-position: If a `top' frame parameter is specified, it
5530 determines the position of the upper edge of the tooltip window. If a
5531 `bottom' parameter but no `top' frame parameter is specified, it
5532 determines the position of the lower edge of the tooltip window.
5533 Otherwise display the tooltip window at the y-position of the mouse,
5534 with offset DY added (default is -10).
5536 A tooltip's maximum size is specified by `x-max-tooltip-size'.
5537 Text larger than the specified size is clipped. */)
5538 (Lisp_Object string
, Lisp_Object frame
, Lisp_Object parms
, Lisp_Object timeout
, Lisp_Object dx
, Lisp_Object dy
)
5543 struct buffer
*old_buffer
;
5544 struct text_pos pos
;
5545 int i
, width
, height
;
5546 bool seen_reversed_p
;
5547 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
5548 ptrdiff_t count
= SPECPDL_INDEX ();
5550 specbind (Qinhibit_redisplay
, Qt
);
5552 CHECK_STRING (string
);
5553 if (SCHARS (string
) == 0)
5554 string
= make_unibyte_string (" ", 1);
5556 f
= decode_window_system_frame (frame
);
5558 timeout
= make_number (5);
5560 CHECK_NATNUM (timeout
);
5563 dx
= make_number (5);
5568 dy
= make_number (-10);
5573 if (x_gtk_use_system_tooltips
)
5577 /* Hide a previous tip, if any. */
5581 ok
= xg_prepare_tooltip (f
, string
, &width
, &height
);
5584 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, &root_x
, &root_y
);
5585 xg_show_tooltip (f
, root_x
, root_y
);
5586 /* This is used in Fx_hide_tip. */
5587 XSETFRAME (tip_frame
, f
);
5590 if (ok
) goto start_timer
;
5592 #endif /* USE_GTK */
5594 if (NILP (last_show_tip_args
))
5595 last_show_tip_args
= Fmake_vector (make_number (3), Qnil
);
5597 if (!NILP (tip_frame
))
5599 Lisp_Object last_string
= AREF (last_show_tip_args
, 0);
5600 Lisp_Object last_frame
= AREF (last_show_tip_args
, 1);
5601 Lisp_Object last_parms
= AREF (last_show_tip_args
, 2);
5603 if (EQ (frame
, last_frame
)
5604 && !NILP (Fequal (last_string
, string
))
5605 && !NILP (Fequal (last_parms
, parms
)))
5607 struct frame
*tip_f
= XFRAME (tip_frame
);
5609 /* Only DX and DY have changed. */
5610 if (!NILP (tip_timer
))
5612 Lisp_Object timer
= tip_timer
;
5614 call1 (Qcancel_timer
, timer
);
5618 compute_tip_xy (tip_f
, parms
, dx
, dy
, FRAME_PIXEL_WIDTH (tip_f
),
5619 FRAME_PIXEL_HEIGHT (tip_f
), &root_x
, &root_y
);
5620 XMoveWindow (FRAME_X_DISPLAY (tip_f
), FRAME_X_WINDOW (tip_f
),
5627 /* Hide a previous tip, if any. */
5630 ASET (last_show_tip_args
, 0, string
);
5631 ASET (last_show_tip_args
, 1, frame
);
5632 ASET (last_show_tip_args
, 2, parms
);
5634 /* Add default values to frame parameters. */
5635 if (NILP (Fassq (Qname
, parms
)))
5636 parms
= Fcons (Fcons (Qname
, build_string ("tooltip")), parms
);
5637 if (NILP (Fassq (Qinternal_border_width
, parms
)))
5638 parms
= Fcons (Fcons (Qinternal_border_width
, make_number (3)), parms
);
5639 if (NILP (Fassq (Qborder_width
, parms
)))
5640 parms
= Fcons (Fcons (Qborder_width
, make_number (1)), parms
);
5641 if (NILP (Fassq (Qbottom_divider_width
, parms
)))
5642 parms
= Fcons (Fcons (Qbottom_divider_width
, make_number (0)), parms
);
5643 if (NILP (Fassq (Qright_divider_width
, parms
)))
5644 parms
= Fcons (Fcons (Qright_divider_width
, make_number (0)), parms
);
5645 if (NILP (Fassq (Qborder_color
, parms
)))
5646 parms
= Fcons (Fcons (Qborder_color
, build_string ("lightyellow")), parms
);
5647 if (NILP (Fassq (Qbackground_color
, parms
)))
5648 parms
= Fcons (Fcons (Qbackground_color
, build_string ("lightyellow")),
5651 /* Create a frame for the tooltip, and record it in the global
5652 variable tip_frame. */
5653 frame
= x_create_tip_frame (FRAME_DISPLAY_INFO (f
), parms
, string
);
5656 /* Set up the frame's root window. */
5657 w
= XWINDOW (FRAME_ROOT_WINDOW (f
));
5663 if (CONSP (Vx_max_tooltip_size
)
5664 && RANGED_INTEGERP (1, XCAR (Vx_max_tooltip_size
), INT_MAX
)
5665 && RANGED_INTEGERP (1, XCDR (Vx_max_tooltip_size
), INT_MAX
))
5667 w
->total_cols
= XFASTINT (XCAR (Vx_max_tooltip_size
));
5668 w
->total_lines
= XFASTINT (XCDR (Vx_max_tooltip_size
));
5673 w
->total_lines
= 40;
5676 w
->pixel_width
= w
->total_cols
* FRAME_COLUMN_WIDTH (f
);
5677 w
->pixel_height
= w
->total_lines
* FRAME_LINE_HEIGHT (f
);
5679 FRAME_TOTAL_COLS (f
) = w
->total_cols
;
5680 adjust_frame_glyphs (f
);
5681 w
->pseudo_window_p
= true;
5683 /* Display the tooltip text in a temporary buffer. */
5684 old_buffer
= current_buffer
;
5685 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f
))->contents
));
5686 bset_truncate_lines (current_buffer
, Qnil
);
5687 clear_glyph_matrix (w
->desired_matrix
);
5688 clear_glyph_matrix (w
->current_matrix
);
5689 SET_TEXT_POS (pos
, BEGV
, BEGV_BYTE
);
5690 try_window (FRAME_ROOT_WINDOW (f
), pos
, TRY_WINDOW_IGNORE_FONTS_CHANGE
);
5692 /* Compute width and height of the tooltip. */
5694 seen_reversed_p
= false;
5695 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
5697 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
5701 /* Stop at the first empty row at the end. */
5702 if (!row
->enabled_p
|| !MATRIX_ROW_DISPLAYS_TEXT_P (row
))
5705 /* Let the row go over the full width of the frame. */
5706 row
->full_width_p
= true;
5708 row_width
= row
->pixel_width
;
5709 if (row
->used
[TEXT_AREA
])
5711 /* There's a glyph at the end of rows that is used to place
5712 the cursor there. Don't include the width of this glyph. */
5713 if (!row
->reversed_p
)
5715 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
5716 if (NILP (last
->object
))
5717 row_width
-= last
->pixel_width
;
5721 /* There could be a stretch glyph at the beginning of R2L
5722 rows that is produced by extend_face_to_end_of_line.
5723 Don't count that glyph. */
5724 struct glyph
*g
= row
->glyphs
[TEXT_AREA
];
5726 if (g
->type
== STRETCH_GLYPH
&& NILP (g
->object
))
5728 row_width
-= g
->pixel_width
;
5729 seen_reversed_p
= true;
5734 height
+= row
->height
;
5735 width
= max (width
, row_width
);
5738 /* If we've seen partial-length R2L rows, we need to re-adjust the
5739 tool-tip frame width and redisplay it again, to avoid over-wide
5740 tips due to the stretch glyph that extends R2L lines to full
5741 width of the frame. */
5742 if (seen_reversed_p
)
5744 /* w->total_cols and FRAME_TOTAL_COLS want the width in columns,
5746 w
->pixel_width
= width
;
5747 width
/= WINDOW_FRAME_COLUMN_WIDTH (w
);
5748 w
->total_cols
= width
;
5749 FRAME_TOTAL_COLS (f
) = width
;
5750 SET_FRAME_WIDTH (f
, width
);
5751 adjust_frame_glyphs (f
);
5752 clear_glyph_matrix (w
->desired_matrix
);
5753 clear_glyph_matrix (w
->current_matrix
);
5754 try_window (FRAME_ROOT_WINDOW (f
), pos
, 0);
5756 /* Recompute width and height of the tooltip. */
5757 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
5759 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
5763 if (!row
->enabled_p
|| !MATRIX_ROW_DISPLAYS_TEXT_P (row
))
5765 row
->full_width_p
= true;
5766 row_width
= row
->pixel_width
;
5767 if (row
->used
[TEXT_AREA
] && !row
->reversed_p
)
5769 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
5770 if (NILP (last
->object
))
5771 row_width
-= last
->pixel_width
;
5774 height
+= row
->height
;
5775 width
= max (width
, row_width
);
5779 /* Add the frame's internal border to the width and height the X
5780 window should have. */
5781 height
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
5782 width
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
5784 /* Move the tooltip window where the mouse pointer is. Resize and
5786 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, &root_x
, &root_y
);
5789 XMoveResizeWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5790 root_x
, root_y
, width
, height
);
5791 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
5794 /* Draw into the window. */
5795 w
->must_be_updated_p
= true;
5796 update_single_window (w
);
5798 /* Restore original current buffer. */
5799 set_buffer_internal_1 (old_buffer
);
5800 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
5803 /* Let the tip disappear after timeout seconds. */
5804 tip_timer
= call3 (intern ("run-at-time"), timeout
, Qnil
,
5805 intern ("x-hide-tip"));
5807 return unbind_to (count
, Qnil
);
5811 DEFUN ("x-hide-tip", Fx_hide_tip
, Sx_hide_tip
, 0, 0, 0,
5812 doc
: /* Hide the current tooltip window, if there is any.
5813 Value is t if tooltip was open, nil otherwise. */)
5817 Lisp_Object deleted
, frame
, timer
;
5819 /* Return quickly if nothing to do. */
5820 if (NILP (tip_timer
) && NILP (tip_frame
))
5825 tip_frame
= tip_timer
= deleted
= Qnil
;
5827 count
= SPECPDL_INDEX ();
5828 specbind (Qinhibit_redisplay
, Qt
);
5829 specbind (Qinhibit_quit
, Qt
);
5832 call1 (Qcancel_timer
, timer
);
5836 /* When using system tooltip, tip_frame is the Emacs frame on which
5837 the tip is shown. */
5838 struct frame
*f
= XFRAME (frame
);
5839 if (FRAME_LIVE_P (f
) && xg_hide_tooltip (f
))
5846 delete_frame (frame
, Qnil
);
5850 /* Bloodcurdling hack alert: The Lucid menu bar widget's
5851 redisplay procedure is not called when a tip frame over menu
5852 items is unmapped. Redisplay the menu manually... */
5855 struct frame
*f
= SELECTED_FRAME ();
5856 w
= f
->output_data
.x
->menubar_widget
;
5858 if (!DoesSaveUnders (FRAME_DISPLAY_INFO (f
)->screen
)
5862 xlwmenu_redisplay (w
);
5866 #endif /* USE_LUCID */
5869 return unbind_to (count
, deleted
);
5874 /***********************************************************************
5875 File selection dialog
5876 ***********************************************************************/
5878 DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog
,
5879 Sx_uses_old_gtk_dialog
,
5881 doc
: /* Return t if the old Gtk+ file selection dialog is used. */)
5887 && window_system_available (SELECTED_FRAME ())
5888 && xg_uses_old_file_dialog ())
5896 /* Callback for "OK" and "Cancel" on file selection dialog. */
5899 file_dialog_cb (Widget widget
, XtPointer client_data
, XtPointer call_data
)
5901 int *result
= client_data
;
5902 XmAnyCallbackStruct
*cb
= call_data
;
5903 *result
= cb
->reason
;
5907 /* Callback for unmapping a file selection dialog. This is used to
5908 capture the case where a dialog is closed via a window manager's
5909 closer button, for example. Using a XmNdestroyCallback didn't work
5913 file_dialog_unmap_cb (Widget widget
, XtPointer client_data
, XtPointer call_data
)
5915 int *result
= client_data
;
5916 *result
= XmCR_CANCEL
;
5920 clean_up_file_dialog (void *arg
)
5922 Widget dialog
= arg
;
5926 XtUnmanageChild (dialog
);
5927 XtDestroyWidget (dialog
);
5928 x_menu_set_in_use (false);
5933 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 5, 0,
5934 doc
: /* Read file name, prompting with PROMPT in directory DIR.
5935 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5936 selection box, if specified. If MUSTMATCH is non-nil, the returned file
5937 or directory must exist.
5939 This function is only defined on NS, MS Windows, and X Windows with the
5940 Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
5941 Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.
5942 On Windows 7 and later, the file selection dialog "remembers" the last
5943 directory where the user selected a file, and will open that directory
5944 instead of DIR on subsequent invocations of this function with the same
5945 value of DIR as in previous invocations; this is standard Windows behavior. */)
5946 (Lisp_Object prompt
, Lisp_Object dir
, Lisp_Object default_filename
,
5947 Lisp_Object mustmatch
, Lisp_Object only_dir_p
)
5950 struct frame
*f
= SELECTED_FRAME ();
5951 Lisp_Object file
= Qnil
;
5952 Lisp_Object decoded_file
;
5953 Widget dialog
, text
, help
;
5956 XmString dir_xmstring
, pattern_xmstring
;
5957 ptrdiff_t count
= SPECPDL_INDEX ();
5959 check_window_system (f
);
5961 if (popup_activated ())
5962 error ("Trying to use a menu from within a menu-entry");
5964 CHECK_STRING (prompt
);
5967 /* Prevent redisplay. */
5968 specbind (Qinhibit_redisplay
, Qt
);
5972 /* Create the dialog with PROMPT as title, using DIR as initial
5973 directory and using "*" as pattern. */
5974 dir
= Fexpand_file_name (dir
, Qnil
);
5975 dir_xmstring
= XmStringCreateLocalized (SSDATA (dir
));
5976 pattern_xmstring
= XmStringCreateLocalized ("*");
5978 XtSetArg (al
[ac
], XmNtitle
, SDATA (prompt
)); ++ac
;
5979 XtSetArg (al
[ac
], XmNdirectory
, dir_xmstring
); ++ac
;
5980 XtSetArg (al
[ac
], XmNpattern
, pattern_xmstring
); ++ac
;
5981 XtSetArg (al
[ac
], XmNresizePolicy
, XmRESIZE_GROW
); ++ac
;
5982 XtSetArg (al
[ac
], XmNdialogStyle
, XmDIALOG_APPLICATION_MODAL
); ++ac
;
5983 dialog
= XmCreateFileSelectionDialog (f
->output_data
.x
->widget
,
5985 XmStringFree (dir_xmstring
);
5986 XmStringFree (pattern_xmstring
);
5988 /* Add callbacks for OK and Cancel. */
5989 XtAddCallback (dialog
, XmNokCallback
, file_dialog_cb
,
5990 (XtPointer
) &result
);
5991 XtAddCallback (dialog
, XmNcancelCallback
, file_dialog_cb
,
5992 (XtPointer
) &result
);
5993 XtAddCallback (dialog
, XmNunmapCallback
, file_dialog_unmap_cb
,
5994 (XtPointer
) &result
);
5996 /* Remove the help button since we can't display help. */
5997 help
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_HELP_BUTTON
);
5998 XtUnmanageChild (help
);
6000 /* Mark OK button as default. */
6001 XtVaSetValues (XmFileSelectionBoxGetChild (dialog
, XmDIALOG_OK_BUTTON
),
6002 XmNshowAsDefault
, True
, NULL
);
6004 /* If MUSTMATCH is non-nil, disable the file entry field of the
6005 dialog, so that the user must select a file from the files list
6006 box. We can't remove it because we wouldn't have a way to get at
6007 the result file name, then. */
6008 text
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
6009 if (!NILP (mustmatch
))
6012 label
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_SELECTION_LABEL
);
6013 XtSetSensitive (text
, False
);
6014 XtSetSensitive (label
, False
);
6017 /* Manage the dialog, so that list boxes get filled. */
6018 XtManageChild (dialog
);
6020 if (STRINGP (default_filename
))
6022 XmString default_xmstring
;
6023 Widget wtext
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_TEXT
);
6024 Widget list
= XmFileSelectionBoxGetChild (dialog
, XmDIALOG_LIST
);
6026 XmTextPosition last_pos
= XmTextFieldGetLastPosition (wtext
);
6027 XmTextFieldReplace (wtext
, 0, last_pos
,
6028 (SSDATA (Ffile_name_nondirectory (default_filename
))));
6030 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
6031 must include the path for this to work. */
6033 default_xmstring
= XmStringCreateLocalized (SSDATA (default_filename
));
6035 if (XmListItemExists (list
, default_xmstring
))
6037 int item_pos
= XmListItemPos (list
, default_xmstring
);
6038 /* Select the item and scroll it into view. */
6039 XmListSelectPos (list
, item_pos
, True
);
6040 XmListSetPos (list
, item_pos
);
6043 XmStringFree (default_xmstring
);
6046 record_unwind_protect_ptr (clean_up_file_dialog
, dialog
);
6048 /* Process events until the user presses Cancel or OK. */
6049 x_menu_set_in_use (true);
6054 x_menu_wait_for_event (0);
6055 XtAppNextEvent (Xt_app_con
, &event
);
6056 if (event
.type
== KeyPress
6057 && FRAME_X_DISPLAY (f
) == event
.xkey
.display
)
6059 KeySym keysym
= XLookupKeysym (&event
.xkey
, 0);
6061 /* Pop down on C-g. */
6062 if (keysym
== XK_g
&& (event
.xkey
.state
& ControlMask
) != 0)
6063 XtUnmanageChild (dialog
);
6066 (void) x_dispatch_event (&event
, FRAME_X_DISPLAY (f
));
6069 /* Get the result. */
6070 if (result
== XmCR_OK
)
6072 XmString text_string
;
6075 XtVaGetValues (dialog
, XmNtextString
, &text_string
, NULL
);
6076 XmStringGetLtoR (text_string
, XmFONTLIST_DEFAULT_TAG
, &data
);
6077 XmStringFree (text_string
);
6078 file
= build_string (data
);
6086 /* Make "Cancel" equivalent to C-g. */
6088 Fsignal (Qquit
, Qnil
);
6090 decoded_file
= DECODE_FILE (file
);
6092 return unbind_to (count
, decoded_file
);
6095 #endif /* USE_MOTIF */
6100 clean_up_dialog (void)
6102 x_menu_set_in_use (false);
6105 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 5, 0,
6106 doc
: /* Read file name, prompting with PROMPT in directory DIR.
6107 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
6108 selection box, if specified. If MUSTMATCH is non-nil, the returned file
6109 or directory must exist.
6111 This function is only defined on NS, MS Windows, and X Windows with the
6112 Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
6113 Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.
6114 On Windows 7 and later, the file selection dialog "remembers" the last
6115 directory where the user selected a file, and will open that directory
6116 instead of DIR on subsequent invocations of this function with the same
6117 value of DIR as in previous invocations; this is standard Windows behavior. */)
6118 (Lisp_Object prompt
, Lisp_Object dir
, Lisp_Object default_filename
, Lisp_Object mustmatch
, Lisp_Object only_dir_p
)
6120 struct frame
*f
= SELECTED_FRAME ();
6122 Lisp_Object file
= Qnil
;
6123 Lisp_Object decoded_file
;
6124 ptrdiff_t count
= SPECPDL_INDEX ();
6127 check_window_system (f
);
6129 if (popup_activated ())
6130 error ("Trying to use a menu from within a menu-entry");
6132 CHECK_STRING (prompt
);
6135 /* Prevent redisplay. */
6136 specbind (Qinhibit_redisplay
, Qt
);
6137 record_unwind_protect_void (clean_up_dialog
);
6141 if (STRINGP (default_filename
))
6142 cdef_file
= SSDATA (default_filename
);
6144 cdef_file
= SSDATA (dir
);
6146 fn
= xg_get_file_name (f
, SSDATA (prompt
), cdef_file
,
6148 ! NILP (only_dir_p
));
6152 file
= build_string (fn
);
6158 /* Make "Cancel" equivalent to C-g. */
6160 Fsignal (Qquit
, Qnil
);
6162 decoded_file
= DECODE_FILE (file
);
6164 return unbind_to (count
, decoded_file
);
6168 #ifdef HAVE_FREETYPE
6170 DEFUN ("x-select-font", Fx_select_font
, Sx_select_font
, 0, 2, 0,
6171 doc
: /* Read a font using a GTK dialog.
6172 Return either a font spec (for GTK versions >= 3.2) or a string
6173 containing a GTK-style font name.
6175 FRAME is the frame on which to pop up the font chooser. If omitted or
6176 nil, it defaults to the selected frame. */)
6177 (Lisp_Object frame
, Lisp_Object ignored
)
6179 struct frame
*f
= decode_window_system_frame (frame
);
6181 Lisp_Object font_param
;
6182 char *default_name
= NULL
;
6183 ptrdiff_t count
= SPECPDL_INDEX ();
6185 if (popup_activated ())
6186 error ("Trying to use a menu from within a menu-entry");
6188 /* Prevent redisplay. */
6189 specbind (Qinhibit_redisplay
, Qt
);
6190 record_unwind_protect_void (clean_up_dialog
);
6194 XSETFONT (font
, FRAME_FONT (f
));
6195 font_param
= Ffont_get (font
, QCname
);
6196 if (STRINGP (font_param
))
6197 default_name
= xlispstrdup (font_param
);
6200 font_param
= Fframe_parameter (frame
, Qfont_param
);
6201 if (STRINGP (font_param
))
6202 default_name
= xlispstrdup (font_param
);
6205 font
= xg_get_font (f
, default_name
);
6206 xfree (default_name
);
6211 Fsignal (Qquit
, Qnil
);
6213 return unbind_to (count
, font
);
6215 #endif /* HAVE_FREETYPE */
6217 #endif /* USE_GTK */
6220 /***********************************************************************
6222 ***********************************************************************/
6225 #include <X11/XKBlib.h>
6226 #include <X11/keysym.h>
6229 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p
,
6230 Sx_backspace_delete_keys_p
, 0, 1, 0,
6231 doc
: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
6232 FRAME nil means use the selected frame.
6233 Value is t if we know that both keys are present, and are mapped to the
6234 usual X keysyms. Value is `lambda' if we cannot determine if both keys are
6235 present and mapped to the usual X keysyms. */)
6242 struct frame
*f
= decode_window_system_frame (frame
);
6243 Display
*dpy
= FRAME_X_DISPLAY (f
);
6244 Lisp_Object have_keys
;
6245 int major
, minor
, op
, event
, error_code
;
6249 /* Check library version in case we're dynamically linked. */
6250 major
= XkbMajorVersion
;
6251 minor
= XkbMinorVersion
;
6252 if (!XkbLibraryVersion (&major
, &minor
))
6258 /* Check that the server supports XKB. */
6259 major
= XkbMajorVersion
;
6260 minor
= XkbMinorVersion
;
6261 if (!XkbQueryExtension (dpy
, &op
, &event
, &error_code
, &major
, &minor
))
6267 /* In this code we check that the keyboard has physical keys with names
6268 that start with BKSP (Backspace) and DELE (Delete), and that they
6269 generate keysym XK_BackSpace and XK_Delete respectively.
6270 This function is used to test if normal-erase-is-backspace should be
6272 An alternative approach would be to just check if XK_BackSpace and
6273 XK_Delete are mapped to any key. But if any of those are mapped to
6274 some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the
6275 user doesn't know about it, it is better to return false here.
6276 It is more obvious to the user what to do if she/he has two keys
6277 clearly marked with names/symbols and one key does something not
6278 expected (i.e. she/he then tries the other).
6279 The cases where Backspace/Delete is mapped to some other key combination
6280 are rare, and in those cases, normal-erase-is-backspace can be turned on
6284 kb
= XkbGetMap (dpy
, XkbAllMapComponentsMask
, XkbUseCoreKbd
);
6287 int delete_keycode
= 0, backspace_keycode
= 0, i
;
6289 if (XkbGetNames (dpy
, XkbAllNamesMask
, kb
) == Success
)
6291 for (i
= kb
->min_key_code
;
6292 (i
< kb
->max_key_code
6293 && (delete_keycode
== 0 || backspace_keycode
== 0));
6296 /* The XKB symbolic key names can be seen most easily in
6297 the PS file generated by `xkbprint -label name
6299 if (memcmp ("DELE", kb
->names
->keys
[i
].name
, 4) == 0)
6301 else if (memcmp ("BKSP", kb
->names
->keys
[i
].name
, 4) == 0)
6302 backspace_keycode
= i
;
6305 XkbFreeNames (kb
, 0, True
);
6308 /* As of libX11-1.6.2, XkbGetMap manual says that you should use
6309 XkbFreeClientMap to free the data returned by XkbGetMap. But
6310 this function just frees the data referenced from KB and not
6311 KB itself. To free KB as well, call XkbFreeKeyboard. */
6312 XkbFreeKeyboard (kb
, XkbAllMapComponentsMask
, True
);
6315 && backspace_keycode
6316 && XKeysymToKeycode (dpy
, XK_Delete
) == delete_keycode
6317 && XKeysymToKeycode (dpy
, XK_BackSpace
) == backspace_keycode
)
6327 /***********************************************************************
6329 ***********************************************************************/
6332 DEFUN ("x-export-frames", Fx_export_frames
, Sx_export_frames
, 0, 2, 0,
6333 doc
: /* XXX Experimental. Return image data of FRAMES in TYPE format.
6334 FRAMES should be nil (the selected frame), a frame, or a list of
6335 frames (each of which corresponds to one page). Optional arg TYPE
6336 should be either `pdf' (default), `png', `ps', or `svg'. Supported
6337 types are determined by the compile-time configuration of cairo. */)
6338 (Lisp_Object frames
, Lisp_Object type
)
6340 Lisp_Object result
, rest
, tmp
;
6341 cairo_surface_type_t surface_type
;
6344 frames
= selected_frame
;
6345 if (!CONSP (frames
))
6346 frames
= list1 (frames
);
6349 for (rest
= frames
; CONSP (rest
); rest
= XCDR (rest
))
6351 struct frame
*f
= XFRAME (XCAR (rest
));
6353 if (! FRAME_LIVE_P (f
) || ! FRAME_X_P (f
) || ! FRAME_LIVE_P (f
))
6354 error ("Invalid frame");
6358 XSETFRAME (frame
, f
);
6359 tmp
= Fcons (frame
, tmp
);
6361 frames
= Fnreverse (tmp
);
6363 #ifdef CAIRO_HAS_PDF_SURFACE
6364 if (NILP (type
) || EQ (type
, intern ("pdf"))) /* XXX: Qpdf */
6365 surface_type
= CAIRO_SURFACE_TYPE_PDF
;
6368 #ifdef CAIRO_HAS_PNG_FUNCTIONS
6369 if (EQ (type
, intern ("png")))
6371 if (!NILP (XCDR (frames
)))
6372 error ("PNG export cannot handle multiple frames.");
6373 surface_type
= CAIRO_SURFACE_TYPE_IMAGE
;
6377 #ifdef CAIRO_HAS_PS_SURFACE
6378 if (EQ (type
, intern ("ps")))
6379 surface_type
= CAIRO_SURFACE_TYPE_PS
;
6382 #ifdef CAIRO_HAS_SVG_SURFACE
6383 if (EQ (type
, intern ("svg")))
6385 /* For now, we stick to SVG 1.1. */
6386 if (!NILP (XCDR (frames
)))
6387 error ("SVG export cannot handle multiple frames.");
6388 surface_type
= CAIRO_SURFACE_TYPE_SVG
;
6392 error ("Unsupported export type");
6394 result
= x_cr_export_frames (frames
, surface_type
);
6400 DEFUN ("x-page-setup-dialog", Fx_page_setup_dialog
, Sx_page_setup_dialog
, 0, 0, 0,
6401 doc
: /* Pop up a page setup dialog.
6402 The current page setup can be obtained using `x-get-page-setup'. */)
6406 xg_page_setup_dialog ();
6412 DEFUN ("x-get-page-setup", Fx_get_page_setup
, Sx_get_page_setup
, 0, 0, 0,
6413 doc
: /* Return the value of the current page setup.
6414 The return value is an alist containing the following keys:
6416 orientation: page orientation (symbol `portrait', `landscape',
6417 `reverse-portrait', or `reverse-landscape').
6418 width, height: page width/height in points not including margins.
6419 left-margin, right-margin, top-margin, bottom-margin: print margins,
6420 which is the parts of the page that the printer cannot print
6423 The paper width can be obtained as the sum of width, left-margin, and
6424 right-margin values. Likewise, the paper height is the sum of height,
6425 top-margin, and bottom-margin values. */)
6431 result
= xg_get_page_setup ();
6437 DEFUN ("x-print-frames-dialog", Fx_print_frames_dialog
, Sx_print_frames_dialog
, 0, 1, "",
6438 doc
: /* Pop up a print dialog to print the current contents of FRAMES.
6439 FRAMES should be nil (the selected frame), a frame, or a list of
6440 frames (each of which corresponds to one page). Each frame should be
6442 (Lisp_Object frames
)
6444 Lisp_Object rest
, tmp
;
6447 frames
= selected_frame
;
6448 if (!CONSP (frames
))
6449 frames
= list1 (frames
);
6452 for (rest
= frames
; CONSP (rest
); rest
= XCDR (rest
))
6454 struct frame
*f
= XFRAME (XCAR (rest
));
6455 if (! FRAME_LIVE_P (f
) || ! FRAME_X_P (f
) || ! FRAME_LIVE_P (f
))
6456 error ("Invalid frame");
6459 XSETFRAME (frame
, f
);
6460 if (!EQ (Fframe_visible_p (frame
), Qt
))
6461 error ("Frames to be printed must be visible.");
6462 tmp
= Fcons (frame
, tmp
);
6464 frames
= Fnreverse (tmp
);
6466 /* Make sure the current matrices are up-to-date. */
6470 xg_print_frames_dialog (frames
);
6475 #endif /* USE_GTK */
6476 #endif /* USE_CAIRO */
6479 /***********************************************************************
6481 ***********************************************************************/
6483 /* Keep this list in the same order as frame_parms in frame.c.
6484 Use 0 for unsupported frame parameters. */
6486 frame_parm_handler x_frame_parm_handlers
[] =
6490 x_set_background_color
,
6496 x_set_foreground_color
,
6499 x_set_internal_border_width
,
6500 x_set_right_divider_width
,
6501 x_set_bottom_divider_width
,
6502 x_set_menu_bar_lines
,
6504 x_explicitly_set_name
,
6505 x_set_scroll_bar_width
,
6506 x_set_scroll_bar_height
,
6509 x_set_vertical_scroll_bars
,
6510 x_set_horizontal_scroll_bars
,
6512 x_set_tool_bar_lines
,
6513 x_set_scroll_bar_foreground
,
6514 x_set_scroll_bar_background
,
6524 x_set_tool_bar_position
,
6530 DEFSYM (Qundefined_color
, "undefined-color");
6531 DEFSYM (Qcompound_text
, "compound-text");
6532 DEFSYM (Qcancel_timer
, "cancel-timer");
6533 DEFSYM (Qfont_param
, "font-parameter");
6534 DEFSYM (Qmono
, "mono");
6537 DEFSYM (Qorientation
, "orientation");
6538 DEFSYM (Qtop_margin
, "top-margin");
6539 DEFSYM (Qbottom_margin
, "bottom-margin");
6540 DEFSYM (Qportrait
, "portrait");
6541 DEFSYM (Qlandscape
, "landscape");
6542 DEFSYM (Qreverse_portrait
, "reverse-portrait");
6543 DEFSYM (Qreverse_landscape
, "reverse-landscape");
6546 Fput (Qundefined_color
, Qerror_conditions
,
6547 listn (CONSTYPE_PURE
, 2, Qundefined_color
, Qerror
));
6548 Fput (Qundefined_color
, Qerror_message
,
6549 build_pure_c_string ("Undefined color"));
6551 DEFVAR_LISP ("x-pointer-shape", Vx_pointer_shape
,
6552 doc
: /* The shape of the pointer when over text.
6553 Changing the value does not affect existing frames
6554 unless you set the mouse color. */);
6555 Vx_pointer_shape
= Qnil
;
6557 #if false /* This doesn't really do anything. */
6558 DEFVAR_LISP ("x-nontext-pointer-shape", Vx_nontext_pointer_shape
,
6559 doc
: /* The shape of the pointer when not over text.
6560 This variable takes effect when you create a new frame
6561 or when you set the mouse color. */);
6563 Vx_nontext_pointer_shape
= Qnil
;
6565 DEFVAR_LISP ("x-hourglass-pointer-shape", Vx_hourglass_pointer_shape
,
6566 doc
: /* The shape of the pointer when Emacs is busy.
6567 This variable takes effect when you create a new frame
6568 or when you set the mouse color. */);
6569 Vx_hourglass_pointer_shape
= Qnil
;
6571 #if false /* This doesn't really do anything. */
6572 DEFVAR_LISP ("x-mode-pointer-shape", Vx_mode_pointer_shape
,
6573 doc
: /* The shape of the pointer when over the mode line.
6574 This variable takes effect when you create a new frame
6575 or when you set the mouse color. */);
6577 Vx_mode_pointer_shape
= Qnil
;
6579 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
6580 Vx_sensitive_text_pointer_shape
,
6581 doc
: /* The shape of the pointer when over mouse-sensitive text.
6582 This variable takes effect when you create a new frame
6583 or when you set the mouse color. */);
6584 Vx_sensitive_text_pointer_shape
= Qnil
;
6586 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
6587 Vx_window_horizontal_drag_shape
,
6588 doc
: /* Pointer shape to use for indicating a window can be dragged horizontally.
6589 This variable takes effect when you create a new frame
6590 or when you set the mouse color. */);
6591 Vx_window_horizontal_drag_shape
= Qnil
;
6593 DEFVAR_LISP ("x-window-vertical-drag-cursor",
6594 Vx_window_vertical_drag_shape
,
6595 doc
: /* Pointer shape to use for indicating a window can be dragged vertically.
6596 This variable takes effect when you create a new frame
6597 or when you set the mouse color. */);
6598 Vx_window_vertical_drag_shape
= Qnil
;
6600 DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel
,
6601 doc
: /* A string indicating the foreground color of the cursor box. */);
6602 Vx_cursor_fore_pixel
= Qnil
;
6604 DEFVAR_LISP ("x-max-tooltip-size", Vx_max_tooltip_size
,
6605 doc
: /* Maximum size for tooltips.
6606 Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */);
6607 Vx_max_tooltip_size
= Fcons (make_number (80), make_number (40));
6609 DEFVAR_LISP ("x-no-window-manager", Vx_no_window_manager
,
6610 doc
: /* Non-nil if no X window manager is in use.
6611 Emacs doesn't try to figure this out; this is always nil
6612 unless you set it to something else. */);
6613 /* We don't have any way to find this out, so set it to nil
6614 and maybe the user would like to set it to t. */
6615 Vx_no_window_manager
= Qnil
;
6617 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
6618 Vx_pixel_size_width_font_regexp
,
6619 doc
: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
6621 Since Emacs gets width of a font matching with this regexp from
6622 PIXEL_SIZE field of the name, font finding mechanism gets faster for
6623 such a font. This is especially effective for such large fonts as
6624 Chinese, Japanese, and Korean. */);
6625 Vx_pixel_size_width_font_regexp
= Qnil
;
6627 /* This is not ifdef:ed, so other builds than GTK can customize it. */
6628 DEFVAR_BOOL ("x-gtk-use-old-file-dialog", x_gtk_use_old_file_dialog
,
6629 doc
: /* Non-nil means prompt with the old GTK file selection dialog.
6630 If nil or if the file selection dialog is not available, the new GTK file
6631 chooser is used instead. To turn off all file dialogs set the
6632 variable `use-file-dialog'. */);
6633 x_gtk_use_old_file_dialog
= false;
6635 DEFVAR_BOOL ("x-gtk-show-hidden-files", x_gtk_show_hidden_files
,
6636 doc
: /* If non-nil, the GTK file chooser will by default show hidden files.
6637 Note that this is just the default, there is a toggle button on the file
6638 chooser to show or not show hidden files on a case by case basis. */);
6639 x_gtk_show_hidden_files
= false;
6641 DEFVAR_BOOL ("x-gtk-file-dialog-help-text", x_gtk_file_dialog_help_text
,
6642 doc
: /* If non-nil, the GTK file chooser will show additional help text.
6643 If more space for files in the file chooser dialog is wanted, set this to nil
6644 to turn the additional text off. */);
6645 x_gtk_file_dialog_help_text
= true;
6647 DEFVAR_BOOL ("x-gtk-use-system-tooltips", x_gtk_use_system_tooltips
,
6648 doc
: /* If non-nil with a Gtk+ built Emacs, the Gtk+ tooltip is used.
6649 Otherwise use Emacs own tooltip implementation.
6650 When using Gtk+ tooltips, the tooltip face is not used. */);
6651 x_gtk_use_system_tooltips
= true;
6653 /* Tell Emacs about this window system. */
6654 Fprovide (Qx
, Qnil
);
6656 #ifdef USE_X_TOOLKIT
6657 Fprovide (intern_c_string ("x-toolkit"), Qnil
);
6659 Fprovide (intern_c_string ("motif"), Qnil
);
6661 DEFVAR_LISP ("motif-version-string", Vmotif_version_string
,
6662 doc
: /* Version info for LessTif/Motif. */);
6663 Vmotif_version_string
= build_string (XmVERSION_STRING
);
6664 #endif /* USE_MOTIF */
6665 #endif /* USE_X_TOOLKIT */
6668 /* Provide x-toolkit also for GTK. Internally GTK does not use Xt so it
6669 is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
6670 But for a user it is a toolkit for X, and indeed, configure
6671 accepts --with-x-toolkit=gtk. */
6672 Fprovide (intern_c_string ("x-toolkit"), Qnil
);
6673 Fprovide (intern_c_string ("gtk"), Qnil
);
6674 Fprovide (intern_c_string ("move-toolbar"), Qnil
);
6676 DEFVAR_LISP ("gtk-version-string", Vgtk_version_string
,
6677 doc
: /* Version info for GTK+. */);
6679 char gtk_version
[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
6680 int len
= sprintf (gtk_version
, "%d.%d.%d",
6681 GTK_MAJOR_VERSION
, GTK_MINOR_VERSION
, GTK_MICRO_VERSION
);
6682 Vgtk_version_string
= make_pure_string (gtk_version
, len
, len
, false);
6684 #endif /* USE_GTK */
6687 Fprovide (intern_c_string ("cairo"), Qnil
);
6689 DEFVAR_LISP ("cairo-version-string", Vcairo_version_string
,
6690 doc
: /* Version info for cairo. */);
6692 char cairo_version
[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
6693 int len
= sprintf (cairo_version
, "%d.%d.%d",
6694 CAIRO_VERSION_MAJOR
, CAIRO_VERSION_MINOR
,
6695 CAIRO_VERSION_MICRO
);
6696 Vcairo_version_string
= make_pure_string (cairo_version
, len
, len
, false);
6700 /* X window properties. */
6701 defsubr (&Sx_change_window_property
);
6702 defsubr (&Sx_delete_window_property
);
6703 defsubr (&Sx_window_property
);
6705 defsubr (&Sxw_display_color_p
);
6706 defsubr (&Sx_display_grayscale_p
);
6707 defsubr (&Sxw_color_defined_p
);
6708 defsubr (&Sxw_color_values
);
6709 defsubr (&Sx_server_max_request_size
);
6710 defsubr (&Sx_server_vendor
);
6711 defsubr (&Sx_server_version
);
6712 defsubr (&Sx_display_pixel_width
);
6713 defsubr (&Sx_display_pixel_height
);
6714 defsubr (&Sx_display_mm_width
);
6715 defsubr (&Sx_display_mm_height
);
6716 defsubr (&Sx_display_screens
);
6717 defsubr (&Sx_display_planes
);
6718 defsubr (&Sx_display_color_cells
);
6719 defsubr (&Sx_display_visual_class
);
6720 defsubr (&Sx_display_backing_store
);
6721 defsubr (&Sx_display_save_under
);
6722 defsubr (&Sx_display_monitor_attributes_list
);
6723 defsubr (&Sx_frame_geometry
);
6724 defsubr (&Sx_frame_edges
);
6725 defsubr (&Sx_mouse_absolute_pixel_position
);
6726 defsubr (&Sx_set_mouse_absolute_pixel_position
);
6727 defsubr (&Sx_wm_set_size_hint
);
6728 defsubr (&Sx_create_frame
);
6729 defsubr (&Sx_open_connection
);
6730 defsubr (&Sx_close_connection
);
6731 defsubr (&Sx_display_list
);
6732 defsubr (&Sx_synchronize
);
6733 defsubr (&Sx_backspace_delete_keys_p
);
6735 defsubr (&Sx_show_tip
);
6736 defsubr (&Sx_hide_tip
);
6738 staticpro (&tip_timer
);
6740 staticpro (&tip_frame
);
6742 last_show_tip_args
= Qnil
;
6743 staticpro (&last_show_tip_args
);
6745 defsubr (&Sx_uses_old_gtk_dialog
);
6746 #if defined (USE_MOTIF) || defined (USE_GTK)
6747 defsubr (&Sx_file_dialog
);
6750 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
6751 defsubr (&Sx_select_font
);
6755 defsubr (&Sx_export_frames
);
6757 defsubr (&Sx_page_setup_dialog
);
6758 defsubr (&Sx_get_page_setup
);
6759 defsubr (&Sx_print_frames_dialog
);