1 /* Functions for the X window system.
2 Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996 Free Software Foundation.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 /* Completely rewritten by Richard Stallman. */
23 /* Rewritten for X11 by Joseph Arceneaux */
28 /* This makes the fields of a Display accessible, in Xlib header files. */
29 #define XLIB_ILLEGAL_ACCESS
36 #include "dispextern.h"
38 #include "blockinput.h"
46 /* On some systems, the character-composition stuff is broken in X11R5. */
47 #if defined (HAVE_X11R5) && ! defined (HAVE_X11R6)
48 #ifdef X11R5_INHIBIT_I18N
49 #define X_I18N_INHIBITED
54 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */
55 #include "bitmaps/gray.xbm"
57 #include <X11/bitmaps/gray>
60 #include "[.bitmaps]gray.xbm"
64 #include <X11/Shell.h>
67 #include <X11/Xaw/Paned.h>
68 #include <X11/Xaw/Label.h>
69 #endif /* USE_MOTIF */
72 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
81 #include "../lwlib/lwlib.h"
83 /* Do the EDITRES protocol if running X11R5
84 Exception: HP-UX (at least version A.09.05) has X11R5 without EditRes */
85 #if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES)
87 extern void _XEditResCheckMessages ();
88 #endif /* R5 + Athena */
90 /* Unique id counter for widgets created by the Lucid Widget
92 extern LWLIB_ID widget_id_tick
;
95 /* This is part of a kludge--see lwlib/xlwmenu.c. */
96 extern XFontStruct
*xlwmenu_default_font
;
99 extern void free_frame_menubar ();
100 #endif /* USE_X_TOOLKIT */
102 #define min(a,b) ((a) < (b) ? (a) : (b))
103 #define max(a,b) ((a) > (b) ? (a) : (b))
106 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
108 #define MAXREQUEST(dpy) ((dpy)->max_request_size)
111 /* The name we're using in resource queries. Most often "emacs". */
112 Lisp_Object Vx_resource_name
;
114 /* The application class we're using in resource queries.
116 Lisp_Object Vx_resource_class
;
118 /* The background and shape of the mouse pointer, and shape when not
119 over text or in the modeline. */
120 Lisp_Object Vx_pointer_shape
, Vx_nontext_pointer_shape
, Vx_mode_pointer_shape
;
121 /* The shape when over mouse-sensitive text. */
122 Lisp_Object Vx_sensitive_text_pointer_shape
;
124 /* Color of chars displayed in cursor box. */
125 Lisp_Object Vx_cursor_fore_pixel
;
127 /* Nonzero if using X. */
130 /* Non nil if no window manager is in use. */
131 Lisp_Object Vx_no_window_manager
;
133 /* Search path for bitmap files. */
134 Lisp_Object Vx_bitmap_file_path
;
136 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
137 Lisp_Object Vx_pixel_size_width_font_regexp
;
139 /* Evaluate this expression to rebuild the section of syms_of_xfns
140 that initializes and staticpros the symbols declared below. Note
141 that Emacs 18 has a bug that keeps C-x C-e from being able to
142 evaluate this expression.
145 ;; Accumulate a list of the symbols we want to initialize from the
146 ;; declarations at the top of the file.
147 (goto-char (point-min))
148 (search-forward "/\*&&& symbols declared here &&&*\/\n")
150 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
152 (cons (buffer-substring (match-beginning 1) (match-end 1))
155 (setq symbol-list (nreverse symbol-list))
156 ;; Delete the section of syms_of_... where we initialize the symbols.
157 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
158 (let ((start (point)))
159 (while (looking-at "^ Q")
161 (kill-region start (point)))
162 ;; Write a new symbol initialization section.
164 (insert (format " %s = intern (\"" (car symbol-list)))
165 (let ((start (point)))
166 (insert (substring (car symbol-list) 1))
167 (subst-char-in-region start (point) ?_ ?-))
168 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
169 (setq symbol-list (cdr symbol-list)))))
173 /*&&& symbols declared here &&&*/
174 Lisp_Object Qauto_raise
;
175 Lisp_Object Qauto_lower
;
176 Lisp_Object Qbackground_color
;
178 Lisp_Object Qborder_color
;
179 Lisp_Object Qborder_width
;
181 Lisp_Object Qcursor_color
;
182 Lisp_Object Qcursor_type
;
183 Lisp_Object Qforeground_color
;
184 Lisp_Object Qgeometry
;
185 Lisp_Object Qicon_left
;
186 Lisp_Object Qicon_top
;
187 Lisp_Object Qicon_type
;
188 Lisp_Object Qicon_name
;
189 Lisp_Object Qinternal_border_width
;
192 Lisp_Object Qmouse_color
;
194 Lisp_Object Qparent_id
;
195 Lisp_Object Qscroll_bar_width
;
196 Lisp_Object Qsuppress_icon
;
198 Lisp_Object Qundefined_color
;
199 Lisp_Object Qvertical_scroll_bars
;
200 Lisp_Object Qvisibility
;
201 Lisp_Object Qwindow_id
;
202 Lisp_Object Qx_frame_parameter
;
203 Lisp_Object Qx_resource_name
;
204 Lisp_Object Quser_position
;
205 Lisp_Object Quser_size
;
206 Lisp_Object Qdisplay
;
208 /* The below are defined in frame.c. */
209 extern Lisp_Object Qheight
, Qminibuffer
, Qname
, Qonly
, Qwidth
;
210 extern Lisp_Object Qunsplittable
, Qmenu_bar_lines
, Qbuffer_predicate
, Qtitle
;
212 extern Lisp_Object Vwindow_system_version
;
215 /* Error if we are not connected to X. */
220 error ("X windows are not in use or not initialized");
223 /* Nonzero if we can use mouse menus.
224 You should not call this unless HAVE_MENUS is defined. */
232 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
233 and checking validity for X. */
236 check_x_frame (frame
)
245 CHECK_LIVE_FRAME (frame
, 0);
249 error ("Non-X frame used");
253 /* Let the user specify an X display with a frame.
254 nil stands for the selected frame--or, if that is not an X frame,
255 the first X display on the list. */
257 static struct x_display_info
*
258 check_x_display_info (frame
)
263 if (FRAME_X_P (selected_frame
))
264 return FRAME_X_DISPLAY_INFO (selected_frame
);
265 else if (x_display_list
!= 0)
266 return x_display_list
;
268 error ("X windows are not in use or not initialized");
270 else if (STRINGP (frame
))
271 return x_display_info_for_name (frame
);
276 CHECK_LIVE_FRAME (frame
, 0);
279 error ("Non-X frame used");
280 return FRAME_X_DISPLAY_INFO (f
);
284 /* Return the Emacs frame-object corresponding to an X window.
285 It could be the frame's main window or an icon window. */
287 /* This function can be called during GC, so use GC_xxx type test macros. */
290 x_window_to_frame (dpyinfo
, wdesc
)
291 struct x_display_info
*dpyinfo
;
294 Lisp_Object tail
, frame
;
297 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
299 frame
= XCONS (tail
)->car
;
300 if (!GC_FRAMEP (frame
))
303 if (f
->output_data
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
306 if ((f
->output_data
.x
->edit_widget
307 && XtWindow (f
->output_data
.x
->edit_widget
) == wdesc
)
308 || f
->output_data
.x
->icon_desc
== wdesc
)
310 #else /* not USE_X_TOOLKIT */
311 if (FRAME_X_WINDOW (f
) == wdesc
312 || f
->output_data
.x
->icon_desc
== wdesc
)
314 #endif /* not USE_X_TOOLKIT */
320 /* Like x_window_to_frame but also compares the window with the widget's
324 x_any_window_to_frame (dpyinfo
, wdesc
)
325 struct x_display_info
*dpyinfo
;
328 Lisp_Object tail
, frame
;
332 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
334 frame
= XCONS (tail
)->car
;
335 if (!GC_FRAMEP (frame
))
338 if (f
->output_data
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
340 x
= f
->output_data
.x
;
341 /* This frame matches if the window is any of its widgets. */
342 if (wdesc
== XtWindow (x
->widget
)
343 || wdesc
== XtWindow (x
->column_widget
)
344 || wdesc
== XtWindow (x
->edit_widget
))
346 /* Match if the window is this frame's menubar. */
347 if (lw_window_is_in_menubar (wdesc
, x
->menubar_widget
))
353 /* Likewise, but exclude the menu bar widget. */
356 x_non_menubar_window_to_frame (dpyinfo
, wdesc
)
357 struct x_display_info
*dpyinfo
;
360 Lisp_Object tail
, frame
;
364 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
366 frame
= XCONS (tail
)->car
;
367 if (!GC_FRAMEP (frame
))
370 if (f
->output_data
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
372 x
= f
->output_data
.x
;
373 /* This frame matches if the window is any of its widgets. */
374 if (wdesc
== XtWindow (x
->widget
)
375 || wdesc
== XtWindow (x
->column_widget
)
376 || wdesc
== XtWindow (x
->edit_widget
))
382 /* Likewise, but consider only the menu bar widget. */
385 x_menubar_window_to_frame (dpyinfo
, wdesc
)
386 struct x_display_info
*dpyinfo
;
389 Lisp_Object tail
, frame
;
393 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
395 frame
= XCONS (tail
)->car
;
396 if (!GC_FRAMEP (frame
))
399 if (f
->output_data
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
401 x
= f
->output_data
.x
;
402 /* Match if the window is this frame's menubar. */
403 if (lw_window_is_in_menubar (wdesc
, x
->menubar_widget
))
409 /* Return the frame whose principal (outermost) window is WDESC.
410 If WDESC is some other (smaller) window, we return 0. */
413 x_top_window_to_frame (dpyinfo
, wdesc
)
414 struct x_display_info
*dpyinfo
;
417 Lisp_Object tail
, frame
;
421 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
423 frame
= XCONS (tail
)->car
;
424 if (!GC_FRAMEP (frame
))
427 if (f
->output_data
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
429 x
= f
->output_data
.x
;
430 /* This frame matches if the window is its topmost widget. */
431 if (wdesc
== XtWindow (x
->widget
))
433 #if 0 /* I don't know why it did this,
434 but it seems logically wrong,
435 and it causes trouble for MapNotify events. */
436 /* Match if the window is this frame's menubar. */
437 if (x
->menubar_widget
438 && wdesc
== XtWindow (x
->menubar_widget
))
444 #endif /* USE_X_TOOLKIT */
448 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
449 id, which is just an int that this section returns. Bitmaps are
450 reference counted so they can be shared among frames.
452 Bitmap indices are guaranteed to be > 0, so a negative number can
453 be used to indicate no bitmap.
455 If you use x_create_bitmap_from_data, then you must keep track of
456 the bitmaps yourself. That is, creating a bitmap from the same
457 data more than once will not be caught. */
460 /* Functions to access the contents of a bitmap, given an id. */
463 x_bitmap_height (f
, id
)
467 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].height
;
471 x_bitmap_width (f
, id
)
475 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].width
;
479 x_bitmap_pixmap (f
, id
)
483 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].pixmap
;
487 /* Allocate a new bitmap record. Returns index of new record. */
490 x_allocate_bitmap_record (f
)
493 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
496 if (dpyinfo
->bitmaps
== NULL
)
498 dpyinfo
->bitmaps_size
= 10;
500 = (struct x_bitmap_record
*) xmalloc (dpyinfo
->bitmaps_size
* sizeof (struct x_bitmap_record
));
501 dpyinfo
->bitmaps_last
= 1;
505 if (dpyinfo
->bitmaps_last
< dpyinfo
->bitmaps_size
)
506 return ++dpyinfo
->bitmaps_last
;
508 for (i
= 0; i
< dpyinfo
->bitmaps_size
; ++i
)
509 if (dpyinfo
->bitmaps
[i
].refcount
== 0)
512 dpyinfo
->bitmaps_size
*= 2;
514 = (struct x_bitmap_record
*) xrealloc (dpyinfo
->bitmaps
,
515 dpyinfo
->bitmaps_size
* sizeof (struct x_bitmap_record
));
516 return ++dpyinfo
->bitmaps_last
;
519 /* Add one reference to the reference count of the bitmap with id ID. */
522 x_reference_bitmap (f
, id
)
526 ++FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].refcount
;
529 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
532 x_create_bitmap_from_data (f
, bits
, width
, height
)
535 unsigned int width
, height
;
537 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
541 bitmap
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
542 bits
, width
, height
);
547 id
= x_allocate_bitmap_record (f
);
548 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
549 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
550 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
551 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
552 dpyinfo
->bitmaps
[id
- 1].height
= height
;
553 dpyinfo
->bitmaps
[id
- 1].width
= width
;
558 /* Create bitmap from file FILE for frame F. */
561 x_create_bitmap_from_file (f
, file
)
565 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
566 unsigned int width
, height
;
568 int xhot
, yhot
, result
, id
;
573 /* Look for an existing bitmap with the same name. */
574 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
576 if (dpyinfo
->bitmaps
[id
].refcount
577 && dpyinfo
->bitmaps
[id
].file
578 && !strcmp (dpyinfo
->bitmaps
[id
].file
, (char *) XSTRING (file
)->data
))
580 ++dpyinfo
->bitmaps
[id
].refcount
;
585 /* Search bitmap-file-path for the file, if appropriate. */
586 fd
= openp (Vx_bitmap_file_path
, file
, "", &found
, 0);
591 filename
= (char *) XSTRING (found
)->data
;
593 result
= XReadBitmapFile (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
594 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
595 if (result
!= BitmapSuccess
)
598 id
= x_allocate_bitmap_record (f
);
599 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
600 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
601 dpyinfo
->bitmaps
[id
- 1].file
= (char *) xmalloc (XSTRING (file
)->size
+ 1);
602 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
603 dpyinfo
->bitmaps
[id
- 1].height
= height
;
604 dpyinfo
->bitmaps
[id
- 1].width
= width
;
605 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, XSTRING (file
)->data
);
610 /* Remove reference to bitmap with id number ID. */
613 x_destroy_bitmap (f
, id
)
617 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
621 --dpyinfo
->bitmaps
[id
- 1].refcount
;
622 if (dpyinfo
->bitmaps
[id
- 1].refcount
== 0)
625 XFreePixmap (FRAME_X_DISPLAY (f
), dpyinfo
->bitmaps
[id
- 1].pixmap
);
626 if (dpyinfo
->bitmaps
[id
- 1].file
)
628 free (dpyinfo
->bitmaps
[id
- 1].file
);
629 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
636 /* Free all the bitmaps for the display specified by DPYINFO. */
639 x_destroy_all_bitmaps (dpyinfo
)
640 struct x_display_info
*dpyinfo
;
643 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++)
644 if (dpyinfo
->bitmaps
[i
].refcount
> 0)
646 XFreePixmap (dpyinfo
->display
, dpyinfo
->bitmaps
[i
].pixmap
);
647 if (dpyinfo
->bitmaps
[i
].file
)
648 free (dpyinfo
->bitmaps
[i
].file
);
650 dpyinfo
->bitmaps_last
= 0;
653 /* Connect the frame-parameter names for X frames
654 to the ways of passing the parameter values to the window system.
656 The name of a parameter, as a Lisp symbol,
657 has an `x-frame-parameter' property which is an integer in Lisp
658 that is an index in this table. */
660 struct x_frame_parm_table
663 void (*setter
)( /* struct frame *frame, Lisp_Object val, oldval */ );
666 void x_set_foreground_color ();
667 void x_set_background_color ();
668 void x_set_mouse_color ();
669 void x_set_cursor_color ();
670 void x_set_border_color ();
671 void x_set_cursor_type ();
672 void x_set_icon_type ();
673 void x_set_icon_name ();
675 void x_set_border_width ();
676 void x_set_internal_border_width ();
677 void x_explicitly_set_name ();
678 void x_set_autoraise ();
679 void x_set_autolower ();
680 void x_set_vertical_scroll_bars ();
681 void x_set_visibility ();
682 void x_set_menu_bar_lines ();
683 void x_set_scroll_bar_width ();
685 void x_set_unsplittable ();
687 static struct x_frame_parm_table x_frame_parms
[] =
689 "auto-raise", x_set_autoraise
,
690 "auto-lower", x_set_autolower
,
691 "background-color", x_set_background_color
,
692 "border-color", x_set_border_color
,
693 "border-width", x_set_border_width
,
694 "cursor-color", x_set_cursor_color
,
695 "cursor-type", x_set_cursor_type
,
697 "foreground-color", x_set_foreground_color
,
698 "icon-name", x_set_icon_name
,
699 "icon-type", x_set_icon_type
,
700 "internal-border-width", x_set_internal_border_width
,
701 "menu-bar-lines", x_set_menu_bar_lines
,
702 "mouse-color", x_set_mouse_color
,
703 "name", x_explicitly_set_name
,
704 "scroll-bar-width", x_set_scroll_bar_width
,
705 "title", x_set_title
,
706 "unsplittable", x_set_unsplittable
,
707 "vertical-scroll-bars", x_set_vertical_scroll_bars
,
708 "visibility", x_set_visibility
,
711 /* Attach the `x-frame-parameter' properties to
712 the Lisp symbol names of parameters relevant to X. */
714 init_x_parm_symbols ()
718 for (i
= 0; i
< sizeof (x_frame_parms
) / sizeof (x_frame_parms
[0]); i
++)
719 Fput (intern (x_frame_parms
[i
].name
), Qx_frame_parameter
,
723 /* Change the parameters of FRAME as specified by ALIST.
724 If a parameter is not specially recognized, do nothing;
725 otherwise call the `x_set_...' function for that parameter. */
728 x_set_frame_parameters (f
, alist
)
734 /* If both of these parameters are present, it's more efficient to
735 set them both at once. So we wait until we've looked at the
736 entire list before we set them. */
740 Lisp_Object left
, top
;
742 /* Same with these. */
743 Lisp_Object icon_left
, icon_top
;
745 /* Record in these vectors all the parms specified. */
749 int left_no_change
= 0, top_no_change
= 0;
750 int icon_left_no_change
= 0, icon_top_no_change
= 0;
753 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
756 parms
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
757 values
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
759 /* Extract parm names and values into those vectors. */
762 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
764 Lisp_Object elt
, prop
, val
;
767 parms
[i
] = Fcar (elt
);
768 values
[i
] = Fcdr (elt
);
772 top
= left
= Qunbound
;
773 icon_left
= icon_top
= Qunbound
;
775 /* Provide default values for HEIGHT and WIDTH. */
776 if (FRAME_NEW_WIDTH (f
))
777 width
= FRAME_NEW_WIDTH (f
);
779 width
= FRAME_WIDTH (f
);
781 if (FRAME_NEW_HEIGHT (f
))
782 height
= FRAME_NEW_HEIGHT (f
);
784 height
= FRAME_HEIGHT (f
);
786 /* Now process them in reverse of specified order. */
787 for (i
--; i
>= 0; i
--)
789 Lisp_Object prop
, val
;
794 if (EQ (prop
, Qwidth
) && NUMBERP (val
))
795 width
= XFASTINT (val
);
796 else if (EQ (prop
, Qheight
) && NUMBERP (val
))
797 height
= XFASTINT (val
);
798 else if (EQ (prop
, Qtop
))
800 else if (EQ (prop
, Qleft
))
802 else if (EQ (prop
, Qicon_top
))
804 else if (EQ (prop
, Qicon_left
))
808 register Lisp_Object param_index
, old_value
;
810 param_index
= Fget (prop
, Qx_frame_parameter
);
811 old_value
= get_frame_param (f
, prop
);
812 store_frame_param (f
, prop
, val
);
813 if (NATNUMP (param_index
)
814 && (XFASTINT (param_index
)
815 < sizeof (x_frame_parms
)/sizeof (x_frame_parms
[0])))
816 (*x_frame_parms
[XINT (param_index
)].setter
)(f
, val
, old_value
);
820 /* Don't die if just one of these was set. */
821 if (EQ (left
, Qunbound
))
824 if (f
->output_data
.x
->left_pos
< 0)
825 left
= Fcons (Qplus
, Fcons (make_number (f
->output_data
.x
->left_pos
), Qnil
));
827 XSETINT (left
, f
->output_data
.x
->left_pos
);
829 if (EQ (top
, Qunbound
))
832 if (f
->output_data
.x
->top_pos
< 0)
833 top
= Fcons (Qplus
, Fcons (make_number (f
->output_data
.x
->top_pos
), Qnil
));
835 XSETINT (top
, f
->output_data
.x
->top_pos
);
838 /* If one of the icon positions was not set, preserve or default it. */
839 if (EQ (icon_left
, Qunbound
) || ! INTEGERP (icon_left
))
841 icon_left_no_change
= 1;
842 icon_left
= Fcdr (Fassq (Qicon_left
, f
->param_alist
));
843 if (NILP (icon_left
))
844 XSETINT (icon_left
, 0);
846 if (EQ (icon_top
, Qunbound
) || ! INTEGERP (icon_top
))
848 icon_top_no_change
= 1;
849 icon_top
= Fcdr (Fassq (Qicon_top
, f
->param_alist
));
851 XSETINT (icon_top
, 0);
854 /* Don't set these parameters unless they've been explicitly
855 specified. The window might be mapped or resized while we're in
856 this function, and we don't want to override that unless the lisp
857 code has asked for it.
859 Don't set these parameters unless they actually differ from the
860 window's current parameters; the window may not actually exist
865 check_frame_size (f
, &height
, &width
);
867 XSETFRAME (frame
, f
);
869 if (width
!= FRAME_WIDTH (f
)
870 || height
!= FRAME_HEIGHT (f
)
871 || FRAME_NEW_HEIGHT (f
) || FRAME_NEW_WIDTH (f
))
872 Fset_frame_size (frame
, make_number (width
), make_number (height
));
874 if ((!NILP (left
) || !NILP (top
))
875 && ! (left_no_change
&& top_no_change
)
876 && ! (NUMBERP (left
) && XINT (left
) == f
->output_data
.x
->left_pos
877 && NUMBERP (top
) && XINT (top
) == f
->output_data
.x
->top_pos
))
882 /* Record the signs. */
883 f
->output_data
.x
->size_hint_flags
&= ~ (XNegative
| YNegative
);
884 if (EQ (left
, Qminus
))
885 f
->output_data
.x
->size_hint_flags
|= XNegative
;
886 else if (INTEGERP (left
))
888 leftpos
= XINT (left
);
890 f
->output_data
.x
->size_hint_flags
|= XNegative
;
892 else if (CONSP (left
) && EQ (XCONS (left
)->car
, Qminus
)
893 && CONSP (XCONS (left
)->cdr
)
894 && INTEGERP (XCONS (XCONS (left
)->cdr
)->car
))
896 leftpos
= - XINT (XCONS (XCONS (left
)->cdr
)->car
);
897 f
->output_data
.x
->size_hint_flags
|= XNegative
;
899 else if (CONSP (left
) && EQ (XCONS (left
)->car
, Qplus
)
900 && CONSP (XCONS (left
)->cdr
)
901 && INTEGERP (XCONS (XCONS (left
)->cdr
)->car
))
903 leftpos
= XINT (XCONS (XCONS (left
)->cdr
)->car
);
906 if (EQ (top
, Qminus
))
907 f
->output_data
.x
->size_hint_flags
|= YNegative
;
908 else if (INTEGERP (top
))
912 f
->output_data
.x
->size_hint_flags
|= YNegative
;
914 else if (CONSP (top
) && EQ (XCONS (top
)->car
, Qminus
)
915 && CONSP (XCONS (top
)->cdr
)
916 && INTEGERP (XCONS (XCONS (top
)->cdr
)->car
))
918 toppos
= - XINT (XCONS (XCONS (top
)->cdr
)->car
);
919 f
->output_data
.x
->size_hint_flags
|= YNegative
;
921 else if (CONSP (top
) && EQ (XCONS (top
)->car
, Qplus
)
922 && CONSP (XCONS (top
)->cdr
)
923 && INTEGERP (XCONS (XCONS (top
)->cdr
)->car
))
925 toppos
= XINT (XCONS (XCONS (top
)->cdr
)->car
);
929 /* Store the numeric value of the position. */
930 f
->output_data
.x
->top_pos
= toppos
;
931 f
->output_data
.x
->left_pos
= leftpos
;
933 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
935 /* Actually set that position, and convert to absolute. */
936 x_set_offset (f
, leftpos
, toppos
, -1);
939 if ((!NILP (icon_left
) || !NILP (icon_top
))
940 && ! (icon_left_no_change
&& icon_top_no_change
))
941 x_wm_set_icon_position (f
, XINT (icon_left
), XINT (icon_top
));
945 /* Store the screen positions of frame F into XPTR and YPTR.
946 These are the positions of the containing window manager window,
947 not Emacs's own window. */
950 x_real_positions (f
, xptr
, yptr
)
957 /* This is pretty gross, but seems to be the easiest way out of
958 the problem that arises when restarting window-managers. */
961 Window outer
= XtWindow (f
->output_data
.x
->widget
);
963 Window outer
= f
->output_data
.x
->window_desc
;
965 Window tmp_root_window
;
966 Window
*tmp_children
;
971 x_catch_errors (FRAME_X_DISPLAY (f
));
973 XQueryTree (FRAME_X_DISPLAY (f
), outer
, &tmp_root_window
,
974 &f
->output_data
.x
->parent_desc
,
975 &tmp_children
, &tmp_nchildren
);
976 XFree ((char *) tmp_children
);
980 /* Find the position of the outside upper-left corner of
981 the inner window, with respect to the outer window. */
982 if (f
->output_data
.x
->parent_desc
!= FRAME_X_DISPLAY_INFO (f
)->root_window
)
984 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
986 /* From-window, to-window. */
988 XtWindow (f
->output_data
.x
->widget
),
990 f
->output_data
.x
->window_desc
,
992 f
->output_data
.x
->parent_desc
,
994 /* From-position, to-position. */
995 0, 0, &win_x
, &win_y
,
1000 #if 0 /* The values seem to be right without this and wrong with. */
1001 win_x
+= f
->output_data
.x
->border_width
;
1002 win_y
+= f
->output_data
.x
->border_width
;
1006 /* It is possible for the window returned by the XQueryNotify
1007 to become invalid by the time we call XTranslateCoordinates.
1008 That can happen when you restart some window managers.
1009 If so, we get an error in XTranslateCoordinates.
1010 Detect that and try the whole thing over. */
1011 if (! x_had_errors_p (FRAME_X_DISPLAY (f
)))
1013 x_uncatch_errors (FRAME_X_DISPLAY (f
));
1017 x_uncatch_errors (FRAME_X_DISPLAY (f
));
1020 *xptr
= f
->output_data
.x
->left_pos
- win_x
;
1021 *yptr
= f
->output_data
.x
->top_pos
- win_y
;
1024 /* Insert a description of internally-recorded parameters of frame X
1025 into the parameter alist *ALISTPTR that is to be given to the user.
1026 Only parameters that are specific to the X window system
1027 and whose values are not correctly recorded in the frame's
1028 param_alist need to be considered here. */
1030 x_report_frame_params (f
, alistptr
)
1032 Lisp_Object
*alistptr
;
1037 /* Represent negative positions (off the top or left screen edge)
1038 in a way that Fmodify_frame_parameters will understand correctly. */
1039 XSETINT (tem
, f
->output_data
.x
->left_pos
);
1040 if (f
->output_data
.x
->left_pos
>= 0)
1041 store_in_alist (alistptr
, Qleft
, tem
);
1043 store_in_alist (alistptr
, Qleft
, Fcons (Qplus
, Fcons (tem
, Qnil
)));
1045 XSETINT (tem
, f
->output_data
.x
->top_pos
);
1046 if (f
->output_data
.x
->top_pos
>= 0)
1047 store_in_alist (alistptr
, Qtop
, tem
);
1049 store_in_alist (alistptr
, Qtop
, Fcons (Qplus
, Fcons (tem
, Qnil
)));
1051 store_in_alist (alistptr
, Qborder_width
,
1052 make_number (f
->output_data
.x
->border_width
));
1053 store_in_alist (alistptr
, Qinternal_border_width
,
1054 make_number (f
->output_data
.x
->internal_border_width
));
1055 sprintf (buf
, "%ld", (long) FRAME_X_WINDOW (f
));
1056 store_in_alist (alistptr
, Qwindow_id
,
1057 build_string (buf
));
1058 store_in_alist (alistptr
, Qicon_name
, f
->icon_name
);
1059 FRAME_SAMPLE_VISIBILITY (f
);
1060 store_in_alist (alistptr
, Qvisibility
,
1061 (FRAME_VISIBLE_P (f
) ? Qt
1062 : FRAME_ICONIFIED_P (f
) ? Qicon
: Qnil
));
1063 store_in_alist (alistptr
, Qdisplay
,
1064 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->car
);
1066 store_in_alist (alistptr
, Qparent_id
,
1067 (f
->output_data
.x
->parent_desc
== FRAME_X_DISPLAY_INFO (f
)->root_window
1068 ? Qnil
: f
->output_data
.x
->parent_desc
));
1072 /* Decide if color named COLOR is valid for the display associated with
1073 the selected frame; if so, return the rgb values in COLOR_DEF.
1074 If ALLOC is nonzero, allocate a new colormap cell. */
1077 defined_color (f
, color
, color_def
, alloc
)
1083 register int status
;
1084 Colormap screen_colormap
;
1085 Display
*display
= FRAME_X_DISPLAY (f
);
1088 screen_colormap
= DefaultColormap (display
, XDefaultScreen (display
));
1090 status
= XParseColor (display
, screen_colormap
, color
, color_def
);
1091 if (status
&& alloc
)
1093 status
= XAllocColor (display
, screen_colormap
, color_def
);
1096 /* If we got to this point, the colormap is full, so we're
1097 going to try and get the next closest color.
1098 The algorithm used is a least-squares matching, which is
1099 what X uses for closest color matching with StaticColor visuals. */
1104 long nearest_delta
, trial_delta
;
1107 no_cells
= XDisplayCells (display
, XDefaultScreen (display
));
1108 cells
= (XColor
*) alloca (sizeof (XColor
) * no_cells
);
1110 for (x
= 0; x
< no_cells
; x
++)
1113 XQueryColors (display
, screen_colormap
, cells
, no_cells
);
1115 /* I'm assuming CSE so I'm not going to condense this. */
1116 nearest_delta
= ((((color_def
->red
>> 8) - (cells
[0].red
>> 8))
1117 * ((color_def
->red
>> 8) - (cells
[0].red
>> 8)))
1119 (((color_def
->green
>> 8) - (cells
[0].green
>> 8))
1120 * ((color_def
->green
>> 8) - (cells
[0].green
>> 8)))
1122 (((color_def
->blue
>> 8) - (cells
[0].blue
>> 8))
1123 * ((color_def
->blue
>> 8) - (cells
[0].blue
>> 8))));
1124 for (x
= 1; x
< no_cells
; x
++)
1126 trial_delta
= ((((color_def
->red
>> 8) - (cells
[x
].red
>> 8))
1127 * ((color_def
->red
>> 8) - (cells
[x
].red
>> 8)))
1129 (((color_def
->green
>> 8) - (cells
[x
].green
>> 8))
1130 * ((color_def
->green
>> 8) - (cells
[x
].green
>> 8)))
1132 (((color_def
->blue
>> 8) - (cells
[x
].blue
>> 8))
1133 * ((color_def
->blue
>> 8) - (cells
[x
].blue
>> 8))));
1134 if (trial_delta
< nearest_delta
)
1137 temp
.red
= cells
[x
].red
;
1138 temp
.green
= cells
[x
].green
;
1139 temp
.blue
= cells
[x
].blue
;
1140 status
= XAllocColor (display
, screen_colormap
, &temp
);
1144 nearest_delta
= trial_delta
;
1148 color_def
->red
= cells
[nearest
].red
;
1149 color_def
->green
= cells
[nearest
].green
;
1150 color_def
->blue
= cells
[nearest
].blue
;
1151 status
= XAllocColor (display
, screen_colormap
, color_def
);
1162 /* Given a string ARG naming a color, compute a pixel value from it
1163 suitable for screen F.
1164 If F is not a color screen, return DEF (default) regardless of what
1168 x_decode_color (f
, arg
, def
)
1175 CHECK_STRING (arg
, 0);
1177 if (strcmp (XSTRING (arg
)->data
, "black") == 0)
1178 return BLACK_PIX_DEFAULT (f
);
1179 else if (strcmp (XSTRING (arg
)->data
, "white") == 0)
1180 return WHITE_PIX_DEFAULT (f
);
1182 if (FRAME_X_DISPLAY_INFO (f
)->n_planes
== 1)
1185 /* defined_color is responsible for coping with failures
1186 by looking for a near-miss. */
1187 if (defined_color (f
, XSTRING (arg
)->data
, &cdef
, 1))
1190 Fsignal (Qerror
, Fcons (build_string ("undefined color"),
1191 Fcons (arg
, Qnil
)));
1194 /* Functions called only from `x_set_frame_param'
1195 to set individual parameters.
1197 If FRAME_X_WINDOW (f) is 0,
1198 the frame is being created and its X-window does not exist yet.
1199 In that case, just record the parameter's new value
1200 in the standard place; do not attempt to change the window. */
1203 x_set_foreground_color (f
, arg
, oldval
)
1205 Lisp_Object arg
, oldval
;
1207 f
->output_data
.x
->foreground_pixel
1208 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1209 if (FRAME_X_WINDOW (f
) != 0)
1212 XSetForeground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->normal_gc
,
1213 f
->output_data
.x
->foreground_pixel
);
1214 XSetBackground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->reverse_gc
,
1215 f
->output_data
.x
->foreground_pixel
);
1217 recompute_basic_faces (f
);
1218 if (FRAME_VISIBLE_P (f
))
1224 x_set_background_color (f
, arg
, oldval
)
1226 Lisp_Object arg
, oldval
;
1231 f
->output_data
.x
->background_pixel
1232 = x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
1234 if (FRAME_X_WINDOW (f
) != 0)
1237 /* The main frame area. */
1238 XSetBackground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->normal_gc
,
1239 f
->output_data
.x
->background_pixel
);
1240 XSetForeground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->reverse_gc
,
1241 f
->output_data
.x
->background_pixel
);
1242 XSetForeground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->cursor_gc
,
1243 f
->output_data
.x
->background_pixel
);
1244 XSetWindowBackground (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1245 f
->output_data
.x
->background_pixel
);
1248 for (bar
= FRAME_SCROLL_BARS (f
); !NILP (bar
);
1249 bar
= XSCROLL_BAR (bar
)->next
)
1250 XSetWindowBackground (FRAME_X_DISPLAY (f
),
1251 SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
)),
1252 f
->output_data
.x
->background_pixel
);
1256 recompute_basic_faces (f
);
1258 if (FRAME_VISIBLE_P (f
))
1264 x_set_mouse_color (f
, arg
, oldval
)
1266 Lisp_Object arg
, oldval
;
1268 Cursor cursor
, nontext_cursor
, mode_cursor
, cross_cursor
;
1271 if (!EQ (Qnil
, arg
))
1272 f
->output_data
.x
->mouse_pixel
1273 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1274 mask_color
= f
->output_data
.x
->background_pixel
;
1275 /* No invisible pointers. */
1276 if (mask_color
== f
->output_data
.x
->mouse_pixel
1277 && mask_color
== f
->output_data
.x
->background_pixel
)
1278 f
->output_data
.x
->mouse_pixel
= f
->output_data
.x
->foreground_pixel
;
1282 /* It's not okay to crash if the user selects a screwy cursor. */
1283 x_catch_errors (FRAME_X_DISPLAY (f
));
1285 if (!EQ (Qnil
, Vx_pointer_shape
))
1287 CHECK_NUMBER (Vx_pointer_shape
, 0);
1288 cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XINT (Vx_pointer_shape
));
1291 cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_xterm
);
1292 x_check_errors (FRAME_X_DISPLAY (f
), "bad text pointer cursor: %s");
1294 if (!EQ (Qnil
, Vx_nontext_pointer_shape
))
1296 CHECK_NUMBER (Vx_nontext_pointer_shape
, 0);
1297 nontext_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
),
1298 XINT (Vx_nontext_pointer_shape
));
1301 nontext_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_left_ptr
);
1302 x_check_errors (FRAME_X_DISPLAY (f
), "bad nontext pointer cursor: %s");
1304 if (!EQ (Qnil
, Vx_mode_pointer_shape
))
1306 CHECK_NUMBER (Vx_mode_pointer_shape
, 0);
1307 mode_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
),
1308 XINT (Vx_mode_pointer_shape
));
1311 mode_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_xterm
);
1312 x_check_errors (FRAME_X_DISPLAY (f
), "bad modeline pointer cursor: %s");
1314 if (!EQ (Qnil
, Vx_sensitive_text_pointer_shape
))
1316 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
, 0);
1318 = XCreateFontCursor (FRAME_X_DISPLAY (f
),
1319 XINT (Vx_sensitive_text_pointer_shape
));
1322 cross_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_crosshair
);
1324 /* Check and report errors with the above calls. */
1325 x_check_errors (FRAME_X_DISPLAY (f
), "can't set cursor shape: %s");
1326 x_uncatch_errors (FRAME_X_DISPLAY (f
));
1329 XColor fore_color
, back_color
;
1331 fore_color
.pixel
= f
->output_data
.x
->mouse_pixel
;
1332 back_color
.pixel
= mask_color
;
1333 XQueryColor (FRAME_X_DISPLAY (f
),
1334 DefaultColormap (FRAME_X_DISPLAY (f
),
1335 DefaultScreen (FRAME_X_DISPLAY (f
))),
1337 XQueryColor (FRAME_X_DISPLAY (f
),
1338 DefaultColormap (FRAME_X_DISPLAY (f
),
1339 DefaultScreen (FRAME_X_DISPLAY (f
))),
1341 XRecolorCursor (FRAME_X_DISPLAY (f
), cursor
,
1342 &fore_color
, &back_color
);
1343 XRecolorCursor (FRAME_X_DISPLAY (f
), nontext_cursor
,
1344 &fore_color
, &back_color
);
1345 XRecolorCursor (FRAME_X_DISPLAY (f
), mode_cursor
,
1346 &fore_color
, &back_color
);
1347 XRecolorCursor (FRAME_X_DISPLAY (f
), cross_cursor
,
1348 &fore_color
, &back_color
);
1351 if (FRAME_X_WINDOW (f
) != 0)
1353 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
1356 if (cursor
!= f
->output_data
.x
->text_cursor
&& f
->output_data
.x
->text_cursor
!= 0)
1357 XFreeCursor (FRAME_X_DISPLAY (f
), f
->output_data
.x
->text_cursor
);
1358 f
->output_data
.x
->text_cursor
= cursor
;
1360 if (nontext_cursor
!= f
->output_data
.x
->nontext_cursor
1361 && f
->output_data
.x
->nontext_cursor
!= 0)
1362 XFreeCursor (FRAME_X_DISPLAY (f
), f
->output_data
.x
->nontext_cursor
);
1363 f
->output_data
.x
->nontext_cursor
= nontext_cursor
;
1365 if (mode_cursor
!= f
->output_data
.x
->modeline_cursor
1366 && f
->output_data
.x
->modeline_cursor
!= 0)
1367 XFreeCursor (FRAME_X_DISPLAY (f
), f
->output_data
.x
->modeline_cursor
);
1368 f
->output_data
.x
->modeline_cursor
= mode_cursor
;
1369 if (cross_cursor
!= f
->output_data
.x
->cross_cursor
1370 && f
->output_data
.x
->cross_cursor
!= 0)
1371 XFreeCursor (FRAME_X_DISPLAY (f
), f
->output_data
.x
->cross_cursor
);
1372 f
->output_data
.x
->cross_cursor
= cross_cursor
;
1374 XFlush (FRAME_X_DISPLAY (f
));
1379 x_set_cursor_color (f
, arg
, oldval
)
1381 Lisp_Object arg
, oldval
;
1383 unsigned long fore_pixel
;
1385 if (!EQ (Vx_cursor_fore_pixel
, Qnil
))
1386 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
1387 WHITE_PIX_DEFAULT (f
));
1389 fore_pixel
= f
->output_data
.x
->background_pixel
;
1390 f
->output_data
.x
->cursor_pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1392 /* Make sure that the cursor color differs from the background color. */
1393 if (f
->output_data
.x
->cursor_pixel
== f
->output_data
.x
->background_pixel
)
1395 f
->output_data
.x
->cursor_pixel
= f
->output_data
.x
->mouse_pixel
;
1396 if (f
->output_data
.x
->cursor_pixel
== fore_pixel
)
1397 fore_pixel
= f
->output_data
.x
->background_pixel
;
1399 f
->output_data
.x
->cursor_foreground_pixel
= fore_pixel
;
1401 if (FRAME_X_WINDOW (f
) != 0)
1404 XSetBackground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->cursor_gc
,
1405 f
->output_data
.x
->cursor_pixel
);
1406 XSetForeground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->cursor_gc
,
1410 if (FRAME_VISIBLE_P (f
))
1412 x_update_cursor (f
, 0);
1413 x_update_cursor (f
, 1);
1418 /* Set the border-color of frame F to value described by ARG.
1419 ARG can be a string naming a color.
1420 The border-color is used for the border that is drawn by the X server.
1421 Note that this does not fully take effect if done before
1422 F has an x-window; it must be redone when the window is created.
1424 Note: this is done in two routines because of the way X10 works.
1426 Note: under X11, this is normally the province of the window manager,
1427 and so emacs' border colors may be overridden. */
1430 x_set_border_color (f
, arg
, oldval
)
1432 Lisp_Object arg
, oldval
;
1437 CHECK_STRING (arg
, 0);
1438 str
= XSTRING (arg
)->data
;
1440 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1442 x_set_border_pixel (f
, pix
);
1445 /* Set the border-color of frame F to pixel value PIX.
1446 Note that this does not fully take effect if done before
1447 F has an x-window. */
1449 x_set_border_pixel (f
, pix
)
1453 f
->output_data
.x
->border_pixel
= pix
;
1455 if (FRAME_X_WINDOW (f
) != 0 && f
->output_data
.x
->border_width
> 0)
1461 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1462 (unsigned long)pix
);
1465 if (FRAME_VISIBLE_P (f
))
1471 x_set_cursor_type (f
, arg
, oldval
)
1473 Lisp_Object arg
, oldval
;
1477 FRAME_DESIRED_CURSOR (f
) = bar_cursor
;
1478 f
->output_data
.x
->cursor_width
= 2;
1480 else if (CONSP (arg
) && EQ (XCONS (arg
)->car
, Qbar
)
1481 && INTEGERP (XCONS (arg
)->cdr
))
1483 FRAME_DESIRED_CURSOR (f
) = bar_cursor
;
1484 f
->output_data
.x
->cursor_width
= XINT (XCONS (arg
)->cdr
);
1487 /* Treat anything unknown as "box cursor".
1488 It was bad to signal an error; people have trouble fixing
1489 .Xdefaults with Emacs, when it has something bad in it. */
1490 FRAME_DESIRED_CURSOR (f
) = filled_box_cursor
;
1492 /* Make sure the cursor gets redrawn. This is overkill, but how
1493 often do people change cursor types? */
1494 update_mode_lines
++;
1498 x_set_icon_type (f
, arg
, oldval
)
1500 Lisp_Object arg
, oldval
;
1507 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1510 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1515 result
= x_text_icon (f
,
1516 (char *) XSTRING ((!NILP (f
->icon_name
)
1520 result
= x_bitmap_icon (f
, arg
);
1525 error ("No icon window available");
1528 XFlush (FRAME_X_DISPLAY (f
));
1532 /* Return non-nil if frame F wants a bitmap icon. */
1540 tem
= assq_no_quit (Qicon_type
, f
->param_alist
);
1542 return XCONS (tem
)->cdr
;
1548 x_set_icon_name (f
, arg
, oldval
)
1550 Lisp_Object arg
, oldval
;
1557 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1560 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1565 if (f
->output_data
.x
->icon_bitmap
!= 0)
1570 result
= x_text_icon (f
,
1571 (char *) XSTRING ((!NILP (f
->icon_name
)
1580 error ("No icon window available");
1583 XFlush (FRAME_X_DISPLAY (f
));
1587 extern Lisp_Object
x_new_font ();
1590 x_set_font (f
, arg
, oldval
)
1592 Lisp_Object arg
, oldval
;
1595 Lisp_Object fontset_name
;
1597 CHECK_STRING (arg
, 1);
1599 fontset_name
= Fquery_fontset (arg
);
1602 result
= (STRINGP (fontset_name
)
1603 ? x_new_fontset (f
, XSTRING (fontset_name
)->data
)
1604 : x_new_font (f
, XSTRING (arg
)->data
));
1607 if (EQ (result
, Qnil
))
1608 error ("Font `%s' is not defined", XSTRING (arg
)->data
);
1609 else if (EQ (result
, Qt
))
1610 error ("the characters of the given font have varying widths");
1611 else if (STRINGP (result
))
1613 recompute_basic_faces (f
);
1614 store_frame_param (f
, Qfont
, result
);
1621 x_set_border_width (f
, arg
, oldval
)
1623 Lisp_Object arg
, oldval
;
1625 CHECK_NUMBER (arg
, 0);
1627 if (XINT (arg
) == f
->output_data
.x
->border_width
)
1630 if (FRAME_X_WINDOW (f
) != 0)
1631 error ("Cannot change the border width of a window");
1633 f
->output_data
.x
->border_width
= XINT (arg
);
1637 x_set_internal_border_width (f
, arg
, oldval
)
1639 Lisp_Object arg
, oldval
;
1642 int old
= f
->output_data
.x
->internal_border_width
;
1644 CHECK_NUMBER (arg
, 0);
1645 f
->output_data
.x
->internal_border_width
= XINT (arg
);
1646 if (f
->output_data
.x
->internal_border_width
< 0)
1647 f
->output_data
.x
->internal_border_width
= 0;
1649 #ifdef USE_X_TOOLKIT
1650 if (f
->output_data
.x
->edit_widget
)
1651 widget_store_internal_border (f
->output_data
.x
->edit_widget
,
1652 f
->output_data
.x
->internal_border_width
);
1655 if (f
->output_data
.x
->internal_border_width
== old
)
1658 if (FRAME_X_WINDOW (f
) != 0)
1661 x_set_window_size (f
, 0, f
->width
, f
->height
);
1663 x_set_resize_hint (f
);
1665 XFlush (FRAME_X_DISPLAY (f
));
1667 SET_FRAME_GARBAGED (f
);
1672 x_set_visibility (f
, value
, oldval
)
1674 Lisp_Object value
, oldval
;
1677 XSETFRAME (frame
, f
);
1680 Fmake_frame_invisible (frame
, Qt
);
1681 else if (EQ (value
, Qicon
))
1682 Ficonify_frame (frame
);
1684 Fmake_frame_visible (frame
);
1688 x_set_menu_bar_lines_1 (window
, n
)
1692 struct window
*w
= XWINDOW (window
);
1694 XSETFASTINT (w
->top
, XFASTINT (w
->top
) + n
);
1695 XSETFASTINT (w
->height
, XFASTINT (w
->height
) - n
);
1697 /* Handle just the top child in a vertical split. */
1698 if (!NILP (w
->vchild
))
1699 x_set_menu_bar_lines_1 (w
->vchild
, n
);
1701 /* Adjust all children in a horizontal split. */
1702 for (window
= w
->hchild
; !NILP (window
); window
= w
->next
)
1704 w
= XWINDOW (window
);
1705 x_set_menu_bar_lines_1 (window
, n
);
1710 x_set_menu_bar_lines (f
, value
, oldval
)
1712 Lisp_Object value
, oldval
;
1715 int olines
= FRAME_MENU_BAR_LINES (f
);
1717 /* Right now, menu bars don't work properly in minibuf-only frames;
1718 most of the commands try to apply themselves to the minibuffer
1719 frame itslef, and get an error because you can't switch buffers
1720 in or split the minibuffer window. */
1721 if (FRAME_MINIBUF_ONLY_P (f
))
1724 if (INTEGERP (value
))
1725 nlines
= XINT (value
);
1729 #ifdef USE_X_TOOLKIT
1730 FRAME_MENU_BAR_LINES (f
) = 0;
1733 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
1734 if (FRAME_X_P (f
) && f
->output_data
.x
->menubar_widget
== 0)
1735 /* Make sure next redisplay shows the menu bar. */
1736 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= Qt
;
1740 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
1741 free_frame_menubar (f
);
1742 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
1744 f
->output_data
.x
->menubar_widget
= 0;
1746 #else /* not USE_X_TOOLKIT */
1747 FRAME_MENU_BAR_LINES (f
) = nlines
;
1748 x_set_menu_bar_lines_1 (f
->root_window
, nlines
- olines
);
1749 #endif /* not USE_X_TOOLKIT */
1752 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1755 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1756 name; if NAME is a string, set F's name to NAME and set
1757 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1759 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1760 suggesting a new name, which lisp code should override; if
1761 F->explicit_name is set, ignore the new name; otherwise, set it. */
1764 x_set_name (f
, name
, explicit)
1769 /* Make sure that requests from lisp code override requests from
1770 Emacs redisplay code. */
1773 /* If we're switching from explicit to implicit, we had better
1774 update the mode lines and thereby update the title. */
1775 if (f
->explicit_name
&& NILP (name
))
1776 update_mode_lines
= 1;
1778 f
->explicit_name
= ! NILP (name
);
1780 else if (f
->explicit_name
)
1783 /* If NAME is nil, set the name to the x_id_name. */
1786 /* Check for no change needed in this very common case
1787 before we do any consing. */
1788 if (!strcmp (FRAME_X_DISPLAY_INFO (f
)->x_id_name
,
1789 XSTRING (f
->name
)->data
))
1791 name
= build_string (FRAME_X_DISPLAY_INFO (f
)->x_id_name
);
1794 CHECK_STRING (name
, 0);
1796 /* Don't change the name if it's already NAME. */
1797 if (! NILP (Fstring_equal (name
, f
->name
)))
1802 /* For setting the frame title, the title parameter should override
1803 the name parameter. */
1804 if (! NILP (f
->title
))
1807 if (FRAME_X_WINDOW (f
))
1812 XTextProperty text
, icon
;
1813 Lisp_Object icon_name
;
1815 text
.value
= XSTRING (name
)->data
;
1816 text
.encoding
= XA_STRING
;
1818 text
.nitems
= XSTRING (name
)->size
;
1820 icon_name
= (!NILP (f
->icon_name
) ? f
->icon_name
: name
);
1822 icon
.value
= XSTRING (icon_name
)->data
;
1823 icon
.encoding
= XA_STRING
;
1825 icon
.nitems
= XSTRING (icon_name
)->size
;
1826 #ifdef USE_X_TOOLKIT
1827 XSetWMName (FRAME_X_DISPLAY (f
),
1828 XtWindow (f
->output_data
.x
->widget
), &text
);
1829 XSetWMIconName (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
),
1831 #else /* not USE_X_TOOLKIT */
1832 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &text
);
1833 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &icon
);
1834 #endif /* not USE_X_TOOLKIT */
1836 #else /* not HAVE_X11R4 */
1837 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1838 XSTRING (name
)->data
);
1839 XStoreName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1840 XSTRING (name
)->data
);
1841 #endif /* not HAVE_X11R4 */
1846 /* This function should be called when the user's lisp code has
1847 specified a name for the frame; the name will override any set by the
1850 x_explicitly_set_name (f
, arg
, oldval
)
1852 Lisp_Object arg
, oldval
;
1854 x_set_name (f
, arg
, 1);
1857 /* This function should be called by Emacs redisplay code to set the
1858 name; names set this way will never override names set by the user's
1861 x_implicitly_set_name (f
, arg
, oldval
)
1863 Lisp_Object arg
, oldval
;
1865 x_set_name (f
, arg
, 0);
1868 /* Change the title of frame F to NAME.
1869 If NAME is nil, use the frame name as the title.
1871 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1872 name; if NAME is a string, set F's name to NAME and set
1873 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1875 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1876 suggesting a new name, which lisp code should override; if
1877 F->explicit_name is set, ignore the new name; otherwise, set it. */
1880 x_set_title (f
, name
)
1884 /* Don't change the title if it's already NAME. */
1885 if (EQ (name
, f
->title
))
1888 update_mode_lines
= 1;
1895 CHECK_STRING (name
, 0);
1897 if (FRAME_X_WINDOW (f
))
1902 XTextProperty text
, icon
;
1903 Lisp_Object icon_name
;
1905 text
.value
= XSTRING (name
)->data
;
1906 text
.encoding
= XA_STRING
;
1908 text
.nitems
= XSTRING (name
)->size
;
1910 icon_name
= (!NILP (f
->icon_name
) ? f
->icon_name
: name
);
1912 icon
.value
= XSTRING (icon_name
)->data
;
1913 icon
.encoding
= XA_STRING
;
1915 icon
.nitems
= XSTRING (icon_name
)->size
;
1916 #ifdef USE_X_TOOLKIT
1917 XSetWMName (FRAME_X_DISPLAY (f
),
1918 XtWindow (f
->output_data
.x
->widget
), &text
);
1919 XSetWMIconName (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
),
1921 #else /* not USE_X_TOOLKIT */
1922 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &text
);
1923 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &icon
);
1924 #endif /* not USE_X_TOOLKIT */
1926 #else /* not HAVE_X11R4 */
1927 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1928 XSTRING (name
)->data
);
1929 XStoreName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1930 XSTRING (name
)->data
);
1931 #endif /* not HAVE_X11R4 */
1937 x_set_autoraise (f
, arg
, oldval
)
1939 Lisp_Object arg
, oldval
;
1941 f
->auto_raise
= !EQ (Qnil
, arg
);
1945 x_set_autolower (f
, arg
, oldval
)
1947 Lisp_Object arg
, oldval
;
1949 f
->auto_lower
= !EQ (Qnil
, arg
);
1953 x_set_unsplittable (f
, arg
, oldval
)
1955 Lisp_Object arg
, oldval
;
1957 f
->no_split
= !NILP (arg
);
1961 x_set_vertical_scroll_bars (f
, arg
, oldval
)
1963 Lisp_Object arg
, oldval
;
1965 if ((EQ (arg
, Qleft
) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
1966 || (EQ (arg
, Qright
) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f
))
1967 || (NILP (arg
) && FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
1968 || (!NILP (arg
) && ! FRAME_HAS_VERTICAL_SCROLL_BARS (f
)))
1970 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
)
1972 ? vertical_scroll_bar_none
1974 ? vertical_scroll_bar_right
1975 : vertical_scroll_bar_left
);
1977 /* We set this parameter before creating the X window for the
1978 frame, so we can get the geometry right from the start.
1979 However, if the window hasn't been created yet, we shouldn't
1980 call x_set_window_size. */
1981 if (FRAME_X_WINDOW (f
))
1982 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
1987 x_set_scroll_bar_width (f
, arg
, oldval
)
1989 Lisp_Object arg
, oldval
;
1993 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = 0;
1994 FRAME_SCROLL_BAR_COLS (f
) = 3;
1995 if (FRAME_X_WINDOW (f
))
1996 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
1998 else if (INTEGERP (arg
) && XINT (arg
) > 0
1999 && XFASTINT (arg
) != FRAME_SCROLL_BAR_PIXEL_WIDTH (f
))
2001 int wid
= FONT_WIDTH (f
->output_data
.x
->font
);
2003 if (XFASTINT (arg
) < 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM
)
2004 Fsignal (Qargs_out_of_range
, Fcons (arg
, Qnil
));
2006 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = XFASTINT (arg
);
2007 FRAME_SCROLL_BAR_COLS (f
) = (XFASTINT (arg
) + wid
-1) / wid
;
2008 if (FRAME_X_WINDOW (f
))
2009 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
2012 change_frame_size (f
, 0, FRAME_WIDTH (f
), 0, 0);
2013 FRAME_CURSOR_X (f
) = FRAME_LEFT_SCROLL_BAR_WIDTH (f
);
2016 /* Subroutines of creating an X frame. */
2018 /* Make sure that Vx_resource_name is set to a reasonable value.
2019 Fix it up, or set it to `emacs' if it is too hopeless. */
2022 validate_x_resource_name ()
2025 /* Number of valid characters in the resource name. */
2027 /* Number of invalid characters in the resource name. */
2032 if (!STRINGP (Vx_resource_class
))
2033 Vx_resource_class
= build_string (EMACS_CLASS
);
2035 if (STRINGP (Vx_resource_name
))
2037 unsigned char *p
= XSTRING (Vx_resource_name
)->data
;
2040 len
= XSTRING (Vx_resource_name
)->size
;
2042 /* Only letters, digits, - and _ are valid in resource names.
2043 Count the valid characters and count the invalid ones. */
2044 for (i
= 0; i
< len
; i
++)
2047 if (! ((c
>= 'a' && c
<= 'z')
2048 || (c
>= 'A' && c
<= 'Z')
2049 || (c
>= '0' && c
<= '9')
2050 || c
== '-' || c
== '_'))
2057 /* Not a string => completely invalid. */
2058 bad_count
= 5, good_count
= 0;
2060 /* If name is valid already, return. */
2064 /* If name is entirely invalid, or nearly so, use `emacs'. */
2066 || (good_count
== 1 && bad_count
> 0))
2068 Vx_resource_name
= build_string ("emacs");
2072 /* Name is partly valid. Copy it and replace the invalid characters
2073 with underscores. */
2075 Vx_resource_name
= new = Fcopy_sequence (Vx_resource_name
);
2077 for (i
= 0; i
< len
; i
++)
2079 int c
= XSTRING (new)->data
[i
];
2080 if (! ((c
>= 'a' && c
<= 'z')
2081 || (c
>= 'A' && c
<= 'Z')
2082 || (c
>= '0' && c
<= '9')
2083 || c
== '-' || c
== '_'))
2084 XSTRING (new)->data
[i
] = '_';
2089 extern char *x_get_string_resource ();
2091 DEFUN ("x-get-resource", Fx_get_resource
, Sx_get_resource
, 2, 4, 0,
2092 "Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.\n\
2093 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the\n\
2094 class, where INSTANCE is the name under which Emacs was invoked, or\n\
2095 the name specified by the `-name' or `-rn' command-line arguments.\n\
2097 The optional arguments COMPONENT and SUBCLASS add to the key and the\n\
2098 class, respectively. You must specify both of them or neither.\n\
2099 If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'\n\
2100 and the class is `Emacs.CLASS.SUBCLASS'.")
2101 (attribute
, class, component
, subclass
)
2102 Lisp_Object attribute
, class, component
, subclass
;
2104 register char *value
;
2110 CHECK_STRING (attribute
, 0);
2111 CHECK_STRING (class, 0);
2113 if (!NILP (component
))
2114 CHECK_STRING (component
, 1);
2115 if (!NILP (subclass
))
2116 CHECK_STRING (subclass
, 2);
2117 if (NILP (component
) != NILP (subclass
))
2118 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
2120 validate_x_resource_name ();
2122 /* Allocate space for the components, the dots which separate them,
2123 and the final '\0'. Make them big enough for the worst case. */
2124 name_key
= (char *) alloca (XSTRING (Vx_resource_name
)->size
2125 + (STRINGP (component
)
2126 ? XSTRING (component
)->size
: 0)
2127 + XSTRING (attribute
)->size
2130 class_key
= (char *) alloca (XSTRING (Vx_resource_class
)->size
2131 + XSTRING (class)->size
2132 + (STRINGP (subclass
)
2133 ? XSTRING (subclass
)->size
: 0)
2136 /* Start with emacs.FRAMENAME for the name (the specific one)
2137 and with `Emacs' for the class key (the general one). */
2138 strcpy (name_key
, XSTRING (Vx_resource_name
)->data
);
2139 strcpy (class_key
, XSTRING (Vx_resource_class
)->data
);
2141 strcat (class_key
, ".");
2142 strcat (class_key
, XSTRING (class)->data
);
2144 if (!NILP (component
))
2146 strcat (class_key
, ".");
2147 strcat (class_key
, XSTRING (subclass
)->data
);
2149 strcat (name_key
, ".");
2150 strcat (name_key
, XSTRING (component
)->data
);
2153 strcat (name_key
, ".");
2154 strcat (name_key
, XSTRING (attribute
)->data
);
2156 value
= x_get_string_resource (check_x_display_info (Qnil
)->xrdb
,
2157 name_key
, class_key
);
2159 if (value
!= (char *) 0)
2160 return build_string (value
);
2165 /* Used when C code wants a resource value. */
2168 x_get_resource_string (attribute
, class)
2169 char *attribute
, *class;
2171 register char *value
;
2175 /* Allocate space for the components, the dots which separate them,
2176 and the final '\0'. */
2177 name_key
= (char *) alloca (XSTRING (Vinvocation_name
)->size
2178 + strlen (attribute
) + 2);
2179 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
2180 + strlen (class) + 2);
2182 sprintf (name_key
, "%s.%s",
2183 XSTRING (Vinvocation_name
)->data
,
2185 sprintf (class_key
, "%s.%s", EMACS_CLASS
, class);
2187 return x_get_string_resource (FRAME_X_DISPLAY_INFO (selected_frame
)->xrdb
,
2188 name_key
, class_key
);
2191 /* Types we might convert a resource string into. */
2194 number
, boolean
, string
, symbol
2197 /* Return the value of parameter PARAM.
2199 First search ALIST, then Vdefault_frame_alist, then the X defaults
2200 database, using ATTRIBUTE as the attribute name and CLASS as its class.
2202 Convert the resource to the type specified by desired_type.
2204 If no default is specified, return Qunbound. If you call
2205 x_get_arg, make sure you deal with Qunbound in a reasonable way,
2206 and don't let it get stored in any Lisp-visible variables! */
2209 x_get_arg (alist
, param
, attribute
, class, type
)
2210 Lisp_Object alist
, param
;
2213 enum resource_types type
;
2215 register Lisp_Object tem
;
2217 tem
= Fassq (param
, alist
);
2219 tem
= Fassq (param
, Vdefault_frame_alist
);
2225 tem
= Fx_get_resource (build_string (attribute
),
2226 build_string (class),
2235 return make_number (atoi (XSTRING (tem
)->data
));
2238 tem
= Fdowncase (tem
);
2239 if (!strcmp (XSTRING (tem
)->data
, "on")
2240 || !strcmp (XSTRING (tem
)->data
, "true"))
2249 /* As a special case, we map the values `true' and `on'
2250 to Qt, and `false' and `off' to Qnil. */
2253 lower
= Fdowncase (tem
);
2254 if (!strcmp (XSTRING (lower
)->data
, "on")
2255 || !strcmp (XSTRING (lower
)->data
, "true"))
2257 else if (!strcmp (XSTRING (lower
)->data
, "off")
2258 || !strcmp (XSTRING (lower
)->data
, "false"))
2261 return Fintern (tem
, Qnil
);
2274 /* Like x_get_arg, but also record the value in f->param_alist. */
2277 x_get_and_record_arg (f
, alist
, param
, attribute
, class, type
)
2279 Lisp_Object alist
, param
;
2282 enum resource_types type
;
2286 value
= x_get_arg (alist
, param
, attribute
, class, type
);
2288 store_frame_param (f
, param
, value
);
2293 /* Record in frame F the specified or default value according to ALIST
2294 of the parameter named PARAM (a Lisp symbol).
2295 If no value is specified for PARAM, look for an X default for XPROP
2296 on the frame named NAME.
2297 If that is not found either, use the value DEFLT. */
2300 x_default_parameter (f
, alist
, prop
, deflt
, xprop
, xclass
, type
)
2307 enum resource_types type
;
2311 tem
= x_get_arg (alist
, prop
, xprop
, xclass
, type
);
2312 if (EQ (tem
, Qunbound
))
2314 x_set_frame_parameters (f
, Fcons (Fcons (prop
, tem
), Qnil
));
2318 DEFUN ("x-parse-geometry", Fx_parse_geometry
, Sx_parse_geometry
, 1, 1, 0,
2319 "Parse an X-style geometry string STRING.\n\
2320 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).\n\
2321 The properties returned may include `top', `left', `height', and `width'.\n\
2322 The value of `left' or `top' may be an integer,\n\
2323 or a list (+ N) meaning N pixels relative to top/left corner,\n\
2324 or a list (- N) meaning -N pixels relative to bottom/right corner.")
2329 unsigned int width
, height
;
2332 CHECK_STRING (string
, 0);
2334 geometry
= XParseGeometry ((char *) XSTRING (string
)->data
,
2335 &x
, &y
, &width
, &height
);
2338 if (!!(geometry
& XValue
) != !!(geometry
& YValue
))
2339 error ("Must specify both x and y position, or neither");
2343 if (geometry
& XValue
)
2345 Lisp_Object element
;
2347 if (x
>= 0 && (geometry
& XNegative
))
2348 element
= Fcons (Qleft
, Fcons (Qminus
, Fcons (make_number (-x
), Qnil
)));
2349 else if (x
< 0 && ! (geometry
& XNegative
))
2350 element
= Fcons (Qleft
, Fcons (Qplus
, Fcons (make_number (x
), Qnil
)));
2352 element
= Fcons (Qleft
, make_number (x
));
2353 result
= Fcons (element
, result
);
2356 if (geometry
& YValue
)
2358 Lisp_Object element
;
2360 if (y
>= 0 && (geometry
& YNegative
))
2361 element
= Fcons (Qtop
, Fcons (Qminus
, Fcons (make_number (-y
), Qnil
)));
2362 else if (y
< 0 && ! (geometry
& YNegative
))
2363 element
= Fcons (Qtop
, Fcons (Qplus
, Fcons (make_number (y
), Qnil
)));
2365 element
= Fcons (Qtop
, make_number (y
));
2366 result
= Fcons (element
, result
);
2369 if (geometry
& WidthValue
)
2370 result
= Fcons (Fcons (Qwidth
, make_number (width
)), result
);
2371 if (geometry
& HeightValue
)
2372 result
= Fcons (Fcons (Qheight
, make_number (height
)), result
);
2377 /* Calculate the desired size and position of this window,
2378 and return the flags saying which aspects were specified.
2380 This function does not make the coordinates positive. */
2382 #define DEFAULT_ROWS 40
2383 #define DEFAULT_COLS 80
2386 x_figure_window_size (f
, parms
)
2390 register Lisp_Object tem0
, tem1
, tem2
;
2391 int height
, width
, left
, top
;
2392 register int geometry
;
2393 long window_prompting
= 0;
2395 /* Default values if we fall through.
2396 Actually, if that happens we should get
2397 window manager prompting. */
2398 SET_FRAME_WIDTH (f
, DEFAULT_COLS
);
2399 f
->height
= DEFAULT_ROWS
;
2400 /* Window managers expect that if program-specified
2401 positions are not (0,0), they're intentional, not defaults. */
2402 f
->output_data
.x
->top_pos
= 0;
2403 f
->output_data
.x
->left_pos
= 0;
2405 tem0
= x_get_arg (parms
, Qheight
, 0, 0, number
);
2406 tem1
= x_get_arg (parms
, Qwidth
, 0, 0, number
);
2407 tem2
= x_get_arg (parms
, Quser_size
, 0, 0, number
);
2408 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
2410 if (!EQ (tem0
, Qunbound
))
2412 CHECK_NUMBER (tem0
, 0);
2413 f
->height
= XINT (tem0
);
2415 if (!EQ (tem1
, Qunbound
))
2417 CHECK_NUMBER (tem1
, 0);
2418 SET_FRAME_WIDTH (f
, XINT (tem1
));
2420 if (!NILP (tem2
) && !EQ (tem2
, Qunbound
))
2421 window_prompting
|= USSize
;
2423 window_prompting
|= PSize
;
2426 f
->output_data
.x
->vertical_scroll_bar_extra
2427 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
2429 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0
2430 ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f
)
2431 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.x
->font
)));
2432 f
->output_data
.x
->pixel_width
= CHAR_TO_PIXEL_WIDTH (f
, f
->width
);
2433 f
->output_data
.x
->pixel_height
= CHAR_TO_PIXEL_HEIGHT (f
, f
->height
);
2435 tem0
= x_get_arg (parms
, Qtop
, 0, 0, number
);
2436 tem1
= x_get_arg (parms
, Qleft
, 0, 0, number
);
2437 tem2
= x_get_arg (parms
, Quser_position
, 0, 0, number
);
2438 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
2440 if (EQ (tem0
, Qminus
))
2442 f
->output_data
.x
->top_pos
= 0;
2443 window_prompting
|= YNegative
;
2445 else if (CONSP (tem0
) && EQ (XCONS (tem0
)->car
, Qminus
)
2446 && CONSP (XCONS (tem0
)->cdr
)
2447 && INTEGERP (XCONS (XCONS (tem0
)->cdr
)->car
))
2449 f
->output_data
.x
->top_pos
= - XINT (XCONS (XCONS (tem0
)->cdr
)->car
);
2450 window_prompting
|= YNegative
;
2452 else if (CONSP (tem0
) && EQ (XCONS (tem0
)->car
, Qplus
)
2453 && CONSP (XCONS (tem0
)->cdr
)
2454 && INTEGERP (XCONS (XCONS (tem0
)->cdr
)->car
))
2456 f
->output_data
.x
->top_pos
= XINT (XCONS (XCONS (tem0
)->cdr
)->car
);
2458 else if (EQ (tem0
, Qunbound
))
2459 f
->output_data
.x
->top_pos
= 0;
2462 CHECK_NUMBER (tem0
, 0);
2463 f
->output_data
.x
->top_pos
= XINT (tem0
);
2464 if (f
->output_data
.x
->top_pos
< 0)
2465 window_prompting
|= YNegative
;
2468 if (EQ (tem1
, Qminus
))
2470 f
->output_data
.x
->left_pos
= 0;
2471 window_prompting
|= XNegative
;
2473 else if (CONSP (tem1
) && EQ (XCONS (tem1
)->car
, Qminus
)
2474 && CONSP (XCONS (tem1
)->cdr
)
2475 && INTEGERP (XCONS (XCONS (tem1
)->cdr
)->car
))
2477 f
->output_data
.x
->left_pos
= - XINT (XCONS (XCONS (tem1
)->cdr
)->car
);
2478 window_prompting
|= XNegative
;
2480 else if (CONSP (tem1
) && EQ (XCONS (tem1
)->car
, Qplus
)
2481 && CONSP (XCONS (tem1
)->cdr
)
2482 && INTEGERP (XCONS (XCONS (tem1
)->cdr
)->car
))
2484 f
->output_data
.x
->left_pos
= XINT (XCONS (XCONS (tem1
)->cdr
)->car
);
2486 else if (EQ (tem1
, Qunbound
))
2487 f
->output_data
.x
->left_pos
= 0;
2490 CHECK_NUMBER (tem1
, 0);
2491 f
->output_data
.x
->left_pos
= XINT (tem1
);
2492 if (f
->output_data
.x
->left_pos
< 0)
2493 window_prompting
|= XNegative
;
2496 if (!NILP (tem2
) && ! EQ (tem2
, Qunbound
))
2497 window_prompting
|= USPosition
;
2499 window_prompting
|= PPosition
;
2502 return window_prompting
;
2505 #if !defined (HAVE_X11R4) && !defined (HAVE_XSETWMPROTOCOLS)
2508 XSetWMProtocols (dpy
, w
, protocols
, count
)
2515 prop
= XInternAtom (dpy
, "WM_PROTOCOLS", False
);
2516 if (prop
== None
) return False
;
2517 XChangeProperty (dpy
, w
, prop
, XA_ATOM
, 32, PropModeReplace
,
2518 (unsigned char *) protocols
, count
);
2521 #endif /* not HAVE_X11R4 && not HAVE_XSETWMPROTOCOLS */
2523 #ifdef USE_X_TOOLKIT
2525 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
2526 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
2527 already be present because of the toolkit (Motif adds some of them,
2528 for example, but Xt doesn't). */
2531 hack_wm_protocols (f
, widget
)
2535 Display
*dpy
= XtDisplay (widget
);
2536 Window w
= XtWindow (widget
);
2537 int need_delete
= 1;
2543 Atom type
, *atoms
= 0;
2545 unsigned long nitems
= 0;
2546 unsigned long bytes_after
;
2548 if ((XGetWindowProperty (dpy
, w
,
2549 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2550 (long)0, (long)100, False
, XA_ATOM
,
2551 &type
, &format
, &nitems
, &bytes_after
,
2552 (unsigned char **) &atoms
)
2554 && format
== 32 && type
== XA_ATOM
)
2558 if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
)
2560 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
)
2562 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
)
2565 if (atoms
) XFree ((char *) atoms
);
2571 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2573 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
;
2575 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2577 XChangeProperty (dpy
, w
, FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2578 XA_ATOM
, 32, PropModeAppend
,
2579 (unsigned char *) props
, count
);
2585 #ifdef USE_X_TOOLKIT
2587 /* Create and set up the X widget for frame F. */
2590 x_window (f
, window_prompting
, minibuffer_only
)
2592 long window_prompting
;
2593 int minibuffer_only
;
2595 XClassHint class_hints
;
2596 XSetWindowAttributes attributes
;
2597 unsigned long attribute_mask
;
2599 Widget shell_widget
;
2601 Widget frame_widget
;
2607 /* Use the resource name as the top-level widget name
2608 for looking up resources. Make a non-Lisp copy
2609 for the window manager, so GC relocation won't bother it.
2611 Elsewhere we specify the window name for the window manager. */
2614 char *str
= (char *) XSTRING (Vx_resource_name
)->data
;
2615 f
->namebuf
= (char *) xmalloc (strlen (str
) + 1);
2616 strcpy (f
->namebuf
, str
);
2620 XtSetArg (al
[ac
], XtNallowShellResize
, 1); ac
++;
2621 XtSetArg (al
[ac
], XtNinput
, 1); ac
++;
2622 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2623 XtSetArg (al
[ac
], XtNborderWidth
, f
->output_data
.x
->border_width
); ac
++;
2624 shell_widget
= XtAppCreateShell (f
->namebuf
, EMACS_CLASS
,
2625 applicationShellWidgetClass
,
2626 FRAME_X_DISPLAY (f
), al
, ac
);
2628 f
->output_data
.x
->widget
= shell_widget
;
2629 /* maybe_set_screen_title_format (shell_widget); */
2631 pane_widget
= lw_create_widget ("main", "pane", widget_id_tick
++,
2632 (widget_value
*) NULL
,
2633 shell_widget
, False
,
2636 (lw_callback
) NULL
);
2638 f
->output_data
.x
->column_widget
= pane_widget
;
2640 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2641 the emacs screen when changing menubar. This reduces flickering. */
2644 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2645 XtSetArg (al
[ac
], XtNshowGrip
, 0); ac
++;
2646 XtSetArg (al
[ac
], XtNallowResize
, 1); ac
++;
2647 XtSetArg (al
[ac
], XtNresizeToPreferred
, 1); ac
++;
2648 XtSetArg (al
[ac
], XtNemacsFrame
, f
); ac
++;
2649 frame_widget
= XtCreateWidget (f
->namebuf
,
2651 pane_widget
, al
, ac
);
2653 f
->output_data
.x
->edit_widget
= frame_widget
;
2655 XtManageChild (frame_widget
);
2657 /* Do some needed geometry management. */
2660 char *tem
, shell_position
[32];
2663 int extra_borders
= 0;
2665 = (f
->output_data
.x
->menubar_widget
2666 ? (f
->output_data
.x
->menubar_widget
->core
.height
2667 + f
->output_data
.x
->menubar_widget
->core
.border_width
)
2669 extern char *lwlib_toolkit_type
;
2671 #if 0 /* Experimentally, we now get the right results
2672 for -geometry -0-0 without this. 24 Aug 96, rms. */
2673 if (FRAME_EXTERNAL_MENU_BAR (f
))
2676 XtVaGetValues (pane_widget
, XtNinternalBorderWidth
, &ibw
, NULL
);
2677 menubar_size
+= ibw
;
2681 f
->output_data
.x
->menubar_height
= menubar_size
;
2684 /* Motif seems to need this amount added to the sizes
2685 specified for the shell widget. The Athena/Lucid widgets don't.
2686 Both conclusions reached experimentally. -- rms. */
2687 XtVaGetValues (f
->output_data
.x
->edit_widget
, XtNinternalBorderWidth
,
2688 &extra_borders
, NULL
);
2692 /* Convert our geometry parameters into a geometry string
2694 Note that we do not specify here whether the position
2695 is a user-specified or program-specified one.
2696 We pass that information later, in x_wm_set_size_hints. */
2698 int left
= f
->output_data
.x
->left_pos
;
2699 int xneg
= window_prompting
& XNegative
;
2700 int top
= f
->output_data
.x
->top_pos
;
2701 int yneg
= window_prompting
& YNegative
;
2707 if (window_prompting
& USPosition
)
2708 sprintf (shell_position
, "=%dx%d%c%d%c%d",
2709 PIXEL_WIDTH (f
) + extra_borders
,
2710 PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
,
2711 (xneg
? '-' : '+'), left
,
2712 (yneg
? '-' : '+'), top
);
2714 sprintf (shell_position
, "=%dx%d",
2715 PIXEL_WIDTH (f
) + extra_borders
,
2716 PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
);
2719 len
= strlen (shell_position
) + 1;
2720 tem
= (char *) xmalloc (len
);
2721 strncpy (tem
, shell_position
, len
);
2722 XtSetArg (al
[ac
], XtNgeometry
, tem
); ac
++;
2723 XtSetValues (shell_widget
, al
, ac
);
2726 XtManageChild (pane_widget
);
2727 XtRealizeWidget (shell_widget
);
2729 FRAME_X_WINDOW (f
) = XtWindow (frame_widget
);
2731 validate_x_resource_name ();
2733 class_hints
.res_name
= (char *) XSTRING (Vx_resource_name
)->data
;
2734 class_hints
.res_class
= (char *) XSTRING (Vx_resource_class
)->data
;
2735 XSetClassHint (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
), &class_hints
);
2738 #ifndef X_I18N_INHIBITED
2743 xim
= XOpenIM (FRAME_X_DISPLAY (f
), NULL
, NULL
, NULL
);
2747 xic
= XCreateIC (xim
,
2748 XNInputStyle
, XIMPreeditNothing
| XIMStatusNothing
,
2749 XNClientWindow
, FRAME_X_WINDOW(f
),
2750 XNFocusWindow
, FRAME_X_WINDOW(f
),
2759 FRAME_XIM (f
) = xim
;
2760 FRAME_XIC (f
) = xic
;
2762 #else /* X_I18N_INHIBITED */
2765 #endif /* X_I18N_INHIBITED */
2766 #endif /* HAVE_X_I18N */
2768 f
->output_data
.x
->wm_hints
.input
= True
;
2769 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2770 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2771 &f
->output_data
.x
->wm_hints
);
2773 hack_wm_protocols (f
, shell_widget
);
2776 XtAddEventHandler (shell_widget
, 0, True
, _XEditResCheckMessages
, 0);
2779 /* Do a stupid property change to force the server to generate a
2780 propertyNotify event so that the event_stream server timestamp will
2781 be initialized to something relevant to the time we created the window.
2783 XChangeProperty (XtDisplay (frame_widget
), XtWindow (frame_widget
),
2784 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2785 XA_ATOM
, 32, PropModeAppend
,
2786 (unsigned char*) NULL
, 0);
2788 /* Make all the standard events reach the Emacs frame. */
2789 attributes
.event_mask
= STANDARD_EVENT_SET
;
2790 attribute_mask
= CWEventMask
;
2791 XChangeWindowAttributes (XtDisplay (shell_widget
), XtWindow (shell_widget
),
2792 attribute_mask
, &attributes
);
2794 XtMapWidget (frame_widget
);
2796 /* x_set_name normally ignores requests to set the name if the
2797 requested name is the same as the current name. This is the one
2798 place where that assumption isn't correct; f->name is set, but
2799 the X server hasn't been told. */
2802 int explicit = f
->explicit_name
;
2804 f
->explicit_name
= 0;
2807 x_set_name (f
, name
, explicit);
2810 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2811 f
->output_data
.x
->text_cursor
);
2815 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
2816 initialize_frame_menubar (f
);
2817 lw_set_main_areas (pane_widget
, f
->output_data
.x
->menubar_widget
, frame_widget
);
2819 if (FRAME_X_WINDOW (f
) == 0)
2820 error ("Unable to create window");
2823 #else /* not USE_X_TOOLKIT */
2825 /* Create and set up the X window for frame F. */
2831 XClassHint class_hints
;
2832 XSetWindowAttributes attributes
;
2833 unsigned long attribute_mask
;
2835 attributes
.background_pixel
= f
->output_data
.x
->background_pixel
;
2836 attributes
.border_pixel
= f
->output_data
.x
->border_pixel
;
2837 attributes
.bit_gravity
= StaticGravity
;
2838 attributes
.backing_store
= NotUseful
;
2839 attributes
.save_under
= True
;
2840 attributes
.event_mask
= STANDARD_EVENT_SET
;
2841 attribute_mask
= (CWBackPixel
| CWBorderPixel
| CWBitGravity
2843 | CWBackingStore
| CWSaveUnder
2849 = XCreateWindow (FRAME_X_DISPLAY (f
),
2850 f
->output_data
.x
->parent_desc
,
2851 f
->output_data
.x
->left_pos
,
2852 f
->output_data
.x
->top_pos
,
2853 PIXEL_WIDTH (f
), PIXEL_HEIGHT (f
),
2854 f
->output_data
.x
->border_width
,
2855 CopyFromParent
, /* depth */
2856 InputOutput
, /* class */
2857 FRAME_X_DISPLAY_INFO (f
)->visual
,
2858 attribute_mask
, &attributes
);
2860 #ifndef X_I18N_INHIBITED
2865 xim
= XOpenIM (FRAME_X_DISPLAY(f
), NULL
, NULL
, NULL
);
2869 xic
= XCreateIC (xim
,
2870 XNInputStyle
, XIMPreeditNothing
| XIMStatusNothing
,
2871 XNClientWindow
, FRAME_X_WINDOW(f
),
2872 XNFocusWindow
, FRAME_X_WINDOW(f
),
2882 FRAME_XIM (f
) = xim
;
2883 FRAME_XIC (f
) = xic
;
2885 #else /* X_I18N_INHIBITED */
2888 #endif /* X_I18N_INHIBITED */
2889 #endif /* HAVE_X_I18N */
2891 validate_x_resource_name ();
2893 class_hints
.res_name
= (char *) XSTRING (Vx_resource_name
)->data
;
2894 class_hints
.res_class
= (char *) XSTRING (Vx_resource_class
)->data
;
2895 XSetClassHint (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &class_hints
);
2897 /* The menubar is part of the ordinary display;
2898 it does not count in addition to the height of the window. */
2899 f
->output_data
.x
->menubar_height
= 0;
2901 /* This indicates that we use the "Passive Input" input model.
2902 Unless we do this, we don't get the Focus{In,Out} events that we
2903 need to draw the cursor correctly. Accursed bureaucrats.
2904 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2906 f
->output_data
.x
->wm_hints
.input
= True
;
2907 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2908 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2909 &f
->output_data
.x
->wm_hints
);
2910 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
2912 /* Request "save yourself" and "delete window" commands from wm. */
2915 protocols
[0] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2916 protocols
[1] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2917 XSetWMProtocols (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), protocols
, 2);
2920 /* x_set_name normally ignores requests to set the name if the
2921 requested name is the same as the current name. This is the one
2922 place where that assumption isn't correct; f->name is set, but
2923 the X server hasn't been told. */
2926 int explicit = f
->explicit_name
;
2928 f
->explicit_name
= 0;
2931 x_set_name (f
, name
, explicit);
2934 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2935 f
->output_data
.x
->text_cursor
);
2939 if (FRAME_X_WINDOW (f
) == 0)
2940 error ("Unable to create window");
2943 #endif /* not USE_X_TOOLKIT */
2945 /* Handle the icon stuff for this window. Perhaps later we might
2946 want an x_set_icon_position which can be called interactively as
2954 Lisp_Object icon_x
, icon_y
;
2956 /* Set the position of the icon. Note that twm groups all
2957 icons in an icon window. */
2958 icon_x
= x_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, number
);
2959 icon_y
= x_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, number
);
2960 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2962 CHECK_NUMBER (icon_x
, 0);
2963 CHECK_NUMBER (icon_y
, 0);
2965 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2966 error ("Both left and top icon corners of icon must be specified");
2970 if (! EQ (icon_x
, Qunbound
))
2971 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
2973 /* Start up iconic or window? */
2974 x_wm_set_window_state
2975 (f
, (EQ (x_get_arg (parms
, Qvisibility
, 0, 0, symbol
), Qicon
)
2979 x_text_icon (f
, (char *) XSTRING ((!NILP (f
->icon_name
)
2986 /* Make the GC's needed for this window, setting the
2987 background, border and mouse colors; also create the
2988 mouse cursor and the gray border tile. */
2990 static char cursor_bits
[] =
2992 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2993 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2994 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2995 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3002 XGCValues gc_values
;
3008 /* Create the GC's of this frame.
3009 Note that many default values are used. */
3012 gc_values
.font
= f
->output_data
.x
->font
->fid
;
3013 gc_values
.foreground
= f
->output_data
.x
->foreground_pixel
;
3014 gc_values
.background
= f
->output_data
.x
->background_pixel
;
3015 gc_values
.line_width
= 0; /* Means 1 using fast algorithm. */
3016 f
->output_data
.x
->normal_gc
= XCreateGC (FRAME_X_DISPLAY (f
),
3018 GCLineWidth
| GCFont
3019 | GCForeground
| GCBackground
,
3022 /* Reverse video style. */
3023 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
3024 gc_values
.background
= f
->output_data
.x
->foreground_pixel
;
3025 f
->output_data
.x
->reverse_gc
= XCreateGC (FRAME_X_DISPLAY (f
),
3027 GCFont
| GCForeground
| GCBackground
3031 /* Cursor has cursor-color background, background-color foreground. */
3032 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
3033 gc_values
.background
= f
->output_data
.x
->cursor_pixel
;
3034 gc_values
.fill_style
= FillOpaqueStippled
;
3036 = XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
3037 FRAME_X_DISPLAY_INFO (f
)->root_window
,
3038 cursor_bits
, 16, 16);
3039 f
->output_data
.x
->cursor_gc
3040 = XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3041 (GCFont
| GCForeground
| GCBackground
3042 | GCFillStyle
| GCStipple
| GCLineWidth
),
3045 /* Create the gray border tile used when the pointer is not in
3046 the frame. Since this depends on the frame's pixel values,
3047 this must be done on a per-frame basis. */
3048 f
->output_data
.x
->border_tile
3049 = (XCreatePixmapFromBitmapData
3050 (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
3051 gray_bits
, gray_width
, gray_height
,
3052 f
->output_data
.x
->foreground_pixel
,
3053 f
->output_data
.x
->background_pixel
,
3054 DefaultDepth (FRAME_X_DISPLAY (f
),
3055 XScreenNumberOfScreen (FRAME_X_SCREEN (f
)))));
3060 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
3062 "Make a new X window, which is called a \"frame\" in Emacs terms.\n\
3063 Returns an Emacs frame object.\n\
3064 ALIST is an alist of frame parameters.\n\
3065 If the parameters specify that the frame should not have a minibuffer,\n\
3066 and do not specify a specific minibuffer window to use,\n\
3067 then `default-minibuffer-frame' must be a frame whose minibuffer can\n\
3068 be shared by the new frame.\n\
3070 This function is an internal primitive--use `make-frame' instead.")
3075 Lisp_Object frame
, tem
;
3077 int minibuffer_only
= 0;
3078 long window_prompting
= 0;
3080 int count
= specpdl_ptr
- specpdl
;
3081 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
3082 Lisp_Object display
;
3083 struct x_display_info
*dpyinfo
;
3089 /* Use this general default value to start with
3090 until we know if this frame has a specified name. */
3091 Vx_resource_name
= Vinvocation_name
;
3093 display
= x_get_arg (parms
, Qdisplay
, 0, 0, string
);
3094 if (EQ (display
, Qunbound
))
3096 dpyinfo
= check_x_display_info (display
);
3098 kb
= dpyinfo
->kboard
;
3100 kb
= &the_only_kboard
;
3103 name
= x_get_arg (parms
, Qname
, "name", "Name", string
);
3105 && ! EQ (name
, Qunbound
)
3107 error ("Invalid frame name--not a string or nil");
3110 Vx_resource_name
= name
;
3112 /* See if parent window is specified. */
3113 parent
= x_get_arg (parms
, Qparent_id
, NULL
, NULL
, number
);
3114 if (EQ (parent
, Qunbound
))
3116 if (! NILP (parent
))
3117 CHECK_NUMBER (parent
, 0);
3119 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
3120 /* No need to protect DISPLAY because that's not used after passing
3121 it to make_frame_without_minibuffer. */
3123 GCPRO4 (parms
, parent
, name
, frame
);
3124 tem
= x_get_arg (parms
, Qminibuffer
, "minibuffer", "Minibuffer", symbol
);
3125 if (EQ (tem
, Qnone
) || NILP (tem
))
3126 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
3127 else if (EQ (tem
, Qonly
))
3129 f
= make_minibuffer_frame ();
3130 minibuffer_only
= 1;
3132 else if (WINDOWP (tem
))
3133 f
= make_frame_without_minibuffer (tem
, kb
, display
);
3137 XSETFRAME (frame
, f
);
3139 /* Note that X Windows does support scroll bars. */
3140 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
3142 f
->output_method
= output_x_window
;
3143 f
->output_data
.x
= (struct x_output
*) xmalloc (sizeof (struct x_output
));
3144 bzero (f
->output_data
.x
, sizeof (struct x_output
));
3145 f
->output_data
.x
->icon_bitmap
= -1;
3148 = x_get_arg (parms
, Qicon_name
, "iconName", "Title", string
);
3149 if (! STRINGP (f
->icon_name
))
3150 f
->icon_name
= Qnil
;
3152 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
3154 FRAME_KBOARD (f
) = kb
;
3157 /* Specify the parent under which to make this X window. */
3161 f
->output_data
.x
->parent_desc
= parent
;
3162 f
->output_data
.x
->explicit_parent
= 1;
3166 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3167 f
->output_data
.x
->explicit_parent
= 0;
3170 /* Note that the frame has no physical cursor right now. */
3171 f
->phys_cursor_x
= -1;
3173 /* Set the name; the functions to which we pass f expect the name to
3175 if (EQ (name
, Qunbound
) || NILP (name
))
3177 f
->name
= build_string (dpyinfo
->x_id_name
);
3178 f
->explicit_name
= 0;
3183 f
->explicit_name
= 1;
3184 /* use the frame's title when getting resources for this frame. */
3185 specbind (Qx_resource_name
, name
);
3188 /* Create fontsets from `global_fontset_alist' before handling fonts. */
3189 for (tem
= Vglobal_fontset_alist
; CONSP (tem
); tem
= XCONS (tem
)->cdr
)
3190 fs_register_fontset (f
, XCONS (tem
)->car
);
3192 /* Extract the window parameters from the supplied values
3193 that are needed to determine window geometry. */
3197 font
= x_get_arg (parms
, Qfont
, "font", "Font", string
);
3198 if (!STRINGP (font
))
3199 font
= x_get_arg (parms
, Qfontset
, "fontset", "Fontset", string
);
3201 /* First, try whatever font the caller has specified. */
3204 Lisp_Object fontset
= Fquery_fontset (font
);
3205 if (STRINGP (fontset
))
3206 font
= x_new_fontset (f
, XSTRING (fontset
)->data
);
3208 font
= x_new_font (f
, XSTRING (font
)->data
);
3210 /* Try out a font which we hope has bold and italic variations. */
3211 if (!STRINGP (font
))
3212 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3213 if (! STRINGP (font
))
3214 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3215 if (! STRINGP (font
))
3216 /* This was formerly the first thing tried, but it finds too many fonts
3217 and takes too long. */
3218 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
3219 /* If those didn't work, look for something which will at least work. */
3220 if (! STRINGP (font
))
3221 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
3223 if (! STRINGP (font
))
3224 font
= build_string ("fixed");
3226 x_default_parameter (f
, parms
, Qfont
, font
,
3227 "font", "Font", string
);
3231 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
3232 whereby it fails to get any font. */
3233 xlwmenu_default_font
= f
->output_data
.x
->font
;
3236 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
3237 "borderwidth", "BorderWidth", number
);
3238 /* This defaults to 2 in order to match xterm. We recognize either
3239 internalBorderWidth or internalBorder (which is what xterm calls
3241 if (NILP (Fassq (Qinternal_border_width
, parms
)))
3245 value
= x_get_arg (parms
, Qinternal_border_width
,
3246 "internalBorder", "internalBorder", number
);
3247 if (! EQ (value
, Qunbound
))
3248 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
3251 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
3252 "internalBorderWidth", "internalBorderWidth", number
);
3253 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qleft
,
3254 "verticalScrollBars", "ScrollBars", boolean
);
3256 /* Also do the stuff which must be set before the window exists. */
3257 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
3258 "foreground", "Foreground", string
);
3259 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
3260 "background", "Background", string
);
3261 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
3262 "pointerColor", "Foreground", string
);
3263 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
3264 "cursorColor", "Foreground", string
);
3265 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
3266 "borderColor", "BorderColor", string
);
3268 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
3269 "menuBar", "MenuBar", number
);
3270 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
3271 "scrollBarWidth", "ScrollBarWidth", number
);
3272 x_default_parameter (f
, parms
, Qbuffer_predicate
, Qnil
,
3273 "bufferPredicate", "BufferPredicate", symbol
);
3274 x_default_parameter (f
, parms
, Qtitle
, Qnil
,
3275 "title", "Title", string
);
3277 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3278 window_prompting
= x_figure_window_size (f
, parms
);
3280 if (window_prompting
& XNegative
)
3282 if (window_prompting
& YNegative
)
3283 f
->output_data
.x
->win_gravity
= SouthEastGravity
;
3285 f
->output_data
.x
->win_gravity
= NorthEastGravity
;
3289 if (window_prompting
& YNegative
)
3290 f
->output_data
.x
->win_gravity
= SouthWestGravity
;
3292 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
3295 f
->output_data
.x
->size_hint_flags
= window_prompting
;
3297 #ifdef USE_X_TOOLKIT
3298 x_window (f
, window_prompting
, minibuffer_only
);
3304 init_frame_faces (f
);
3306 /* We need to do this after creating the X window, so that the
3307 icon-creation functions can say whose icon they're describing. */
3308 x_default_parameter (f
, parms
, Qicon_type
, Qnil
,
3309 "bitmapIcon", "BitmapIcon", symbol
);
3311 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
3312 "autoRaise", "AutoRaiseLower", boolean
);
3313 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
3314 "autoLower", "AutoRaiseLower", boolean
);
3315 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
3316 "cursorType", "CursorType", symbol
);
3318 /* Dimensions, especially f->height, must be done via change_frame_size.
3319 Change will not be effected unless different from the current
3324 SET_FRAME_WIDTH (f
, 0);
3325 change_frame_size (f
, height
, width
, 1, 0);
3327 /* Tell the server what size and position, etc, we want,
3328 and how badly we want them. */
3330 x_wm_set_size_hint (f
, window_prompting
, 0);
3333 tem
= x_get_arg (parms
, Qunsplittable
, 0, 0, boolean
);
3334 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
3338 /* It is now ok to make the frame official
3339 even if we get an error below.
3340 And the frame needs to be on Vframe_list
3341 or making it visible won't work. */
3342 Vframe_list
= Fcons (frame
, Vframe_list
);
3344 /* Now that the frame is official, it counts as a reference to
3346 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
3348 /* Make the window appear on the frame and enable display,
3349 unless the caller says not to. However, with explicit parent,
3350 Emacs cannot control visibility, so don't try. */
3351 if (! f
->output_data
.x
->explicit_parent
)
3353 Lisp_Object visibility
;
3355 visibility
= x_get_arg (parms
, Qvisibility
, 0, 0, symbol
);
3356 if (EQ (visibility
, Qunbound
))
3359 if (EQ (visibility
, Qicon
))
3360 x_iconify_frame (f
);
3361 else if (! NILP (visibility
))
3362 x_make_frame_visible (f
);
3364 /* Must have been Qnil. */
3368 return unbind_to (count
, frame
);
3371 /* FRAME is used only to get a handle on the X display. We don't pass the
3372 display info directly because we're called from frame.c, which doesn't
3373 know about that structure. */
3376 x_get_focus_frame (frame
)
3377 struct frame
*frame
;
3379 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (frame
);
3381 if (! dpyinfo
->x_focus_frame
)
3384 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
3389 #include "x-list-font.c"
3391 DEFUN ("x-list-fonts", Fx_list_fonts
, Sx_list_fonts
, 1, 4, 0,
3392 "Return a list of the names of available fonts matching PATTERN.\n\
3393 If optional arguments FACE and FRAME are specified, return only fonts\n\
3394 the same size as FACE on FRAME.\n\
3396 PATTERN is a string, perhaps with wildcard characters;\n\
3397 the * character matches any substring, and\n\
3398 the ? character matches any single character.\n\
3399 PATTERN is case-insensitive.\n\
3400 FACE is a face name--a symbol.\n\
3402 The return value is a list of strings, suitable as arguments to\n\
3405 Fonts Emacs can't use (i.e. proportional fonts) may or may not be excluded\n\
3406 even if they match PATTERN and FACE.\n\
3408 The optional fourth argument MAXIMUM sets a limit on how many\n\
3409 fonts to match. The first MAXIMUM fonts are reported.")
3410 (pattern
, face
, frame
, maximum
)
3411 Lisp_Object pattern
, face
, frame
, maximum
;
3415 #ifndef BROKEN_XLISTFONTSWITHINFO
3418 XFontStruct
*size_ref
;
3425 CHECK_STRING (pattern
, 0);
3427 CHECK_SYMBOL (face
, 1);
3433 CHECK_NATNUM (maximum
, 0);
3434 maxnames
= XINT (maximum
);
3437 f
= check_x_frame (frame
);
3439 /* Determine the width standard for comparison with the fonts we find. */
3447 /* Don't die if we get called with a terminal frame. */
3448 if (! FRAME_X_P (f
))
3449 error ("Non-X frame used in `x-list-fonts'");
3451 face_id
= face_name_id_number (f
, face
);
3453 if (face_id
< 0 || face_id
>= FRAME_N_PARAM_FACES (f
)
3454 || FRAME_PARAM_FACES (f
) [face_id
] == 0)
3455 size_ref
= f
->output_data
.x
->font
;
3458 size_ref
= FRAME_PARAM_FACES (f
) [face_id
]->font
;
3459 if (size_ref
== (XFontStruct
*) (~0))
3460 size_ref
= f
->output_data
.x
->font
;
3464 /* See if we cached the result for this particular query. */
3465 key
= Fcons (pattern
, maximum
);
3467 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
);
3469 /* We have info in the cache for this PATTERN. */
3472 Lisp_Object tem
, newlist
;
3474 /* We have info about this pattern. */
3475 list
= XCONS (list
)->cdr
;
3482 /* Filter the cached info and return just the fonts that match FACE. */
3484 for (tem
= list
; CONSP (tem
); tem
= XCONS (tem
)->cdr
)
3486 XFontStruct
*thisinfo
;
3488 x_catch_errors (FRAME_X_DISPLAY (f
));
3490 thisinfo
= XLoadQueryFont (FRAME_X_DISPLAY (f
),
3491 XSTRING (XCONS (tem
)->car
)->data
);
3493 x_check_errors (FRAME_X_DISPLAY (f
), "XLoadQueryFont failure: %s");
3494 x_uncatch_errors (FRAME_X_DISPLAY (f
));
3496 if (thisinfo
&& same_size_fonts (thisinfo
, size_ref
))
3497 newlist
= Fcons (XCONS (tem
)->car
, newlist
);
3500 XFreeFont (FRAME_X_DISPLAY (f
), thisinfo
);
3510 x_catch_errors (FRAME_X_DISPLAY (f
));
3512 /* Solaris 2.3 has a bug in XListFontsWithInfo. */
3513 #ifndef BROKEN_XLISTFONTSWITHINFO
3515 names
= XListFontsWithInfo (FRAME_X_DISPLAY (f
),
3516 XSTRING (pattern
)->data
,
3518 &num_fonts
, /* count_return */
3519 &info
); /* info_return */
3522 names
= XListFonts (FRAME_X_DISPLAY (f
),
3523 XSTRING (pattern
)->data
,
3525 &num_fonts
); /* count_return */
3527 x_check_errors (FRAME_X_DISPLAY (f
), "XListFonts failure: %s");
3528 x_uncatch_errors (FRAME_X_DISPLAY (f
));
3537 Lisp_Object full_list
;
3539 /* Make a list of all the fonts we got back.
3540 Store that in the font cache for the display. */
3542 for (i
= 0; i
< num_fonts
; i
++)
3543 full_list
= Fcons (build_string (names
[i
]), full_list
);
3544 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
3545 = Fcons (Fcons (key
, full_list
),
3546 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
);
3548 /* Make a list of the fonts that have the right width. */
3550 for (i
= 0; i
< num_fonts
; i
++)
3558 #ifdef BROKEN_XLISTFONTSWITHINFO
3559 XFontStruct
*thisinfo
;
3563 x_catch_errors (FRAME_X_DISPLAY (f
));
3564 thisinfo
= XLoadQueryFont (FRAME_X_DISPLAY (f
), names
[i
]);
3565 x_check_errors (FRAME_X_DISPLAY (f
),
3566 "XLoadQueryFont failure: %s");
3567 x_uncatch_errors (FRAME_X_DISPLAY (f
));
3571 keeper
= thisinfo
&& same_size_fonts (thisinfo
, size_ref
);
3573 if (thisinfo
&& ! keeper
)
3574 XFreeFont (FRAME_X_DISPLAY (f
), thisinfo
);
3576 XFreeFontInfo (NULL
, thisinfo
, 1);
3579 keeper
= same_size_fonts (&info
[i
], size_ref
);
3583 list
= Fcons (build_string (names
[i
]), list
);
3585 list
= Fnreverse (list
);
3588 #ifndef BROKEN_XLISTFONTSWITHINFO
3590 XFreeFontInfo (names
, info
, num_fonts
);
3593 XFreeFontNames (names
);
3602 DEFUN ("x-color-defined-p", Fx_color_defined_p
, Sx_color_defined_p
, 1, 2, 0,
3603 "Return non-nil if color COLOR is supported on frame FRAME.\n\
3604 If FRAME is omitted or nil, use the selected frame.")
3606 Lisp_Object color
, frame
;
3609 FRAME_PTR f
= check_x_frame (frame
);
3611 CHECK_STRING (color
, 1);
3613 if (defined_color (f
, XSTRING (color
)->data
, &foo
, 0))
3619 DEFUN ("x-color-values", Fx_color_values
, Sx_color_values
, 1, 2, 0,
3620 "Return a description of the color named COLOR on frame FRAME.\n\
3621 The value is a list of integer RGB values--(RED GREEN BLUE).\n\
3622 These values appear to range from 0 to 65280 or 65535, depending\n\
3623 on the system; white is (65280 65280 65280) or (65535 65535 65535).\n\
3624 If FRAME is omitted or nil, use the selected frame.")
3626 Lisp_Object color
, frame
;
3629 FRAME_PTR f
= check_x_frame (frame
);
3631 CHECK_STRING (color
, 1);
3633 if (defined_color (f
, XSTRING (color
)->data
, &foo
, 0))
3637 rgb
[0] = make_number (foo
.red
);
3638 rgb
[1] = make_number (foo
.green
);
3639 rgb
[2] = make_number (foo
.blue
);
3640 return Flist (3, rgb
);
3646 DEFUN ("x-display-color-p", Fx_display_color_p
, Sx_display_color_p
, 0, 1, 0,
3647 "Return t if the X display supports color.\n\
3648 The optional argument DISPLAY specifies which display to ask about.\n\
3649 DISPLAY should be either a frame or a display name (a string).\n\
3650 If omitted or nil, that stands for the selected frame's display.")
3652 Lisp_Object display
;
3654 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3656 if (dpyinfo
->n_planes
<= 2)
3659 switch (dpyinfo
->visual
->class)
3672 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
3674 "Return t if the X display supports shades of gray.\n\
3675 Note that color displays do support shades of gray.\n\
3676 The optional argument DISPLAY specifies which display to ask about.\n\
3677 DISPLAY should be either a frame or a display name (a string).\n\
3678 If omitted or nil, that stands for the selected frame's display.")
3680 Lisp_Object display
;
3682 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3684 if (dpyinfo
->n_planes
<= 1)
3687 switch (dpyinfo
->visual
->class)
3702 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
3704 "Returns the width in pixels of the X display DISPLAY.\n\
3705 The optional argument DISPLAY specifies which display to ask about.\n\
3706 DISPLAY should be either a frame or a display name (a string).\n\
3707 If omitted or nil, that stands for the selected frame's display.")
3709 Lisp_Object display
;
3711 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3713 return make_number (dpyinfo
->width
);
3716 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
3717 Sx_display_pixel_height
, 0, 1, 0,
3718 "Returns the height in pixels of the X display DISPLAY.\n\
3719 The optional argument DISPLAY specifies which display to ask about.\n\
3720 DISPLAY should be either a frame or a display name (a string).\n\
3721 If omitted or nil, that stands for the selected frame's display.")
3723 Lisp_Object display
;
3725 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3727 return make_number (dpyinfo
->height
);
3730 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
3732 "Returns the number of bitplanes of the X display DISPLAY.\n\
3733 The optional argument DISPLAY specifies which display to ask about.\n\
3734 DISPLAY should be either a frame or a display name (a string).\n\
3735 If omitted or nil, that stands for the selected frame's display.")
3737 Lisp_Object display
;
3739 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3741 return make_number (dpyinfo
->n_planes
);
3744 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
3746 "Returns the number of color cells of the X display DISPLAY.\n\
3747 The optional argument DISPLAY specifies which display to ask about.\n\
3748 DISPLAY should be either a frame or a display name (a string).\n\
3749 If omitted or nil, that stands for the selected frame's display.")
3751 Lisp_Object display
;
3753 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3755 return make_number (DisplayCells (dpyinfo
->display
,
3756 XScreenNumberOfScreen (dpyinfo
->screen
)));
3759 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
3760 Sx_server_max_request_size
,
3762 "Returns the maximum request size of the X server of display DISPLAY.\n\
3763 The optional argument DISPLAY specifies which display to ask about.\n\
3764 DISPLAY should be either a frame or a display name (a string).\n\
3765 If omitted or nil, that stands for the selected frame's display.")
3767 Lisp_Object display
;
3769 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3771 return make_number (MAXREQUEST (dpyinfo
->display
));
3774 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
3775 "Returns the vendor ID string of the X server of display DISPLAY.\n\
3776 The optional argument DISPLAY specifies which display to ask about.\n\
3777 DISPLAY should be either a frame or a display name (a string).\n\
3778 If omitted or nil, that stands for the selected frame's display.")
3780 Lisp_Object display
;
3782 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3783 char *vendor
= ServerVendor (dpyinfo
->display
);
3785 if (! vendor
) vendor
= "";
3786 return build_string (vendor
);
3789 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
3790 "Returns the version numbers of the X server of display DISPLAY.\n\
3791 The value is a list of three integers: the major and minor\n\
3792 version numbers of the X Protocol in use, and the vendor-specific release\n\
3793 number. See also the function `x-server-vendor'.\n\n\
3794 The optional argument DISPLAY specifies which display to ask about.\n\
3795 DISPLAY should be either a frame or a display name (a string).\n\
3796 If omitted or nil, that stands for the selected frame's display.")
3798 Lisp_Object display
;
3800 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3801 Display
*dpy
= dpyinfo
->display
;
3803 return Fcons (make_number (ProtocolVersion (dpy
)),
3804 Fcons (make_number (ProtocolRevision (dpy
)),
3805 Fcons (make_number (VendorRelease (dpy
)), Qnil
)));
3808 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
3809 "Returns the number of screens on the X server of display DISPLAY.\n\
3810 The optional argument DISPLAY specifies which display to ask about.\n\
3811 DISPLAY should be either a frame or a display name (a string).\n\
3812 If omitted or nil, that stands for the selected frame's display.")
3814 Lisp_Object display
;
3816 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3818 return make_number (ScreenCount (dpyinfo
->display
));
3821 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
3822 "Returns the height in millimeters of the X display DISPLAY.\n\
3823 The optional argument DISPLAY specifies which display to ask about.\n\
3824 DISPLAY should be either a frame or a display name (a string).\n\
3825 If omitted or nil, that stands for the selected frame's display.")
3827 Lisp_Object display
;
3829 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3831 return make_number (HeightMMOfScreen (dpyinfo
->screen
));
3834 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
3835 "Returns the width in millimeters of the X display DISPLAY.\n\
3836 The optional argument DISPLAY specifies which display to ask about.\n\
3837 DISPLAY should be either a frame or a display name (a string).\n\
3838 If omitted or nil, that stands for the selected frame's display.")
3840 Lisp_Object display
;
3842 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3844 return make_number (WidthMMOfScreen (dpyinfo
->screen
));
3847 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
3848 Sx_display_backing_store
, 0, 1, 0,
3849 "Returns an indication of whether X display DISPLAY does backing store.\n\
3850 The value may be `always', `when-mapped', or `not-useful'.\n\
3851 The optional argument DISPLAY specifies which display to ask about.\n\
3852 DISPLAY should be either a frame or a display name (a string).\n\
3853 If omitted or nil, that stands for the selected frame's display.")
3855 Lisp_Object display
;
3857 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3859 switch (DoesBackingStore (dpyinfo
->screen
))
3862 return intern ("always");
3865 return intern ("when-mapped");
3868 return intern ("not-useful");
3871 error ("Strange value for BackingStore parameter of screen");
3875 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
3876 Sx_display_visual_class
, 0, 1, 0,
3877 "Returns the visual class of the X display DISPLAY.\n\
3878 The value is one of the symbols `static-gray', `gray-scale',\n\
3879 `static-color', `pseudo-color', `true-color', or `direct-color'.\n\n\
3880 The optional argument DISPLAY specifies which display to ask about.\n\
3881 DISPLAY should be either a frame or a display name (a string).\n\
3882 If omitted or nil, that stands for the selected frame's display.")
3884 Lisp_Object display
;
3886 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3888 switch (dpyinfo
->visual
->class)
3890 case StaticGray
: return (intern ("static-gray"));
3891 case GrayScale
: return (intern ("gray-scale"));
3892 case StaticColor
: return (intern ("static-color"));
3893 case PseudoColor
: return (intern ("pseudo-color"));
3894 case TrueColor
: return (intern ("true-color"));
3895 case DirectColor
: return (intern ("direct-color"));
3897 error ("Display has an unknown visual class");
3901 DEFUN ("x-display-save-under", Fx_display_save_under
,
3902 Sx_display_save_under
, 0, 1, 0,
3903 "Returns t if the X display DISPLAY supports the save-under feature.\n\
3904 The optional argument DISPLAY specifies which display to ask about.\n\
3905 DISPLAY should be either a frame or a display name (a string).\n\
3906 If omitted or nil, that stands for the selected frame's display.")
3908 Lisp_Object display
;
3910 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3912 if (DoesSaveUnders (dpyinfo
->screen
) == True
)
3920 register struct frame
*f
;
3922 return PIXEL_WIDTH (f
);
3927 register struct frame
*f
;
3929 return PIXEL_HEIGHT (f
);
3934 register struct frame
*f
;
3936 return FONT_WIDTH (f
->output_data
.x
->font
);
3941 register struct frame
*f
;
3943 return f
->output_data
.x
->line_height
;
3947 x_screen_planes (frame
)
3950 return FRAME_X_DISPLAY_INFO (XFRAME (frame
))->n_planes
;
3953 #if 0 /* These no longer seem like the right way to do things. */
3955 /* Draw a rectangle on the frame with left top corner including
3956 the character specified by LEFT_CHAR and TOP_CHAR. The rectangle is
3957 CHARS by LINES wide and long and is the color of the cursor. */
3960 x_rectangle (f
, gc
, left_char
, top_char
, chars
, lines
)
3961 register struct frame
*f
;
3963 register int top_char
, left_char
, chars
, lines
;
3967 int left
= (left_char
* FONT_WIDTH (f
->output_data
.x
->font
)
3968 + f
->output_data
.x
->internal_border_width
);
3969 int top
= (top_char
* f
->output_data
.x
->line_height
3970 + f
->output_data
.x
->internal_border_width
);
3973 width
= FONT_WIDTH (f
->output_data
.x
->font
) / 2;
3975 width
= FONT_WIDTH (f
->output_data
.x
->font
) * chars
;
3977 height
= f
->output_data
.x
->line_height
/ 2;
3979 height
= f
->output_data
.x
->line_height
* lines
;
3981 XDrawRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3982 gc
, left
, top
, width
, height
);
3985 DEFUN ("x-draw-rectangle", Fx_draw_rectangle
, Sx_draw_rectangle
, 5, 5, 0,
3986 "Draw a rectangle on FRAME between coordinates specified by\n\
3987 numbers X0, Y0, X1, Y1 in the cursor pixel.")
3988 (frame
, X0
, Y0
, X1
, Y1
)
3989 register Lisp_Object frame
, X0
, X1
, Y0
, Y1
;
3991 register int x0
, y0
, x1
, y1
, top
, left
, n_chars
, n_lines
;
3993 CHECK_LIVE_FRAME (frame
, 0);
3994 CHECK_NUMBER (X0
, 0);
3995 CHECK_NUMBER (Y0
, 1);
3996 CHECK_NUMBER (X1
, 2);
3997 CHECK_NUMBER (Y1
, 3);
4007 n_lines
= y1
- y0
+ 1;
4012 n_lines
= y0
- y1
+ 1;
4018 n_chars
= x1
- x0
+ 1;
4023 n_chars
= x0
- x1
+ 1;
4027 x_rectangle (XFRAME (frame
), XFRAME (frame
)->output_data
.x
->cursor_gc
,
4028 left
, top
, n_chars
, n_lines
);
4034 DEFUN ("x-erase-rectangle", Fx_erase_rectangle
, Sx_erase_rectangle
, 5, 5, 0,
4035 "Draw a rectangle drawn on FRAME between coordinates\n\
4036 X0, Y0, X1, Y1 in the regular background-pixel.")
4037 (frame
, X0
, Y0
, X1
, Y1
)
4038 register Lisp_Object frame
, X0
, Y0
, X1
, Y1
;
4040 register int x0
, y0
, x1
, y1
, top
, left
, n_chars
, n_lines
;
4042 CHECK_LIVE_FRAME (frame
, 0);
4043 CHECK_NUMBER (X0
, 0);
4044 CHECK_NUMBER (Y0
, 1);
4045 CHECK_NUMBER (X1
, 2);
4046 CHECK_NUMBER (Y1
, 3);
4056 n_lines
= y1
- y0
+ 1;
4061 n_lines
= y0
- y1
+ 1;
4067 n_chars
= x1
- x0
+ 1;
4072 n_chars
= x0
- x1
+ 1;
4076 x_rectangle (XFRAME (frame
), XFRAME (frame
)->output_data
.x
->reverse_gc
,
4077 left
, top
, n_chars
, n_lines
);
4083 /* Draw lines around the text region beginning at the character position
4084 TOP_X, TOP_Y and ending at BOTTOM_X and BOTTOM_Y. GC specifies the
4085 pixel and line characteristics. */
4087 #define line_len(line) (FRAME_CURRENT_GLYPHS (f)->used[(line)])
4090 outline_region (f
, gc
, top_x
, top_y
, bottom_x
, bottom_y
)
4091 register struct frame
*f
;
4093 int top_x
, top_y
, bottom_x
, bottom_y
;
4095 register int ibw
= f
->output_data
.x
->internal_border_width
;
4096 register int font_w
= FONT_WIDTH (f
->output_data
.x
->font
);
4097 register int font_h
= f
->output_data
.x
->line_height
;
4099 int x
= line_len (y
);
4100 XPoint
*pixel_points
4101 = (XPoint
*) alloca (((bottom_y
- top_y
+ 2) * 4) * sizeof (XPoint
));
4102 register XPoint
*this_point
= pixel_points
;
4104 /* Do the horizontal top line/lines */
4107 this_point
->x
= ibw
;
4108 this_point
->y
= ibw
+ (font_h
* top_y
);
4111 this_point
->x
= ibw
+ (font_w
/ 2); /* Half-size for newline chars. */
4113 this_point
->x
= ibw
+ (font_w
* x
);
4114 this_point
->y
= (this_point
- 1)->y
;
4118 this_point
->x
= ibw
;
4119 this_point
->y
= ibw
+ (font_h
* (top_y
+ 1));
4121 this_point
->x
= ibw
+ (font_w
* top_x
);
4122 this_point
->y
= (this_point
- 1)->y
;
4124 this_point
->x
= (this_point
- 1)->x
;
4125 this_point
->y
= ibw
+ (font_h
* top_y
);
4127 this_point
->x
= ibw
+ (font_w
* x
);
4128 this_point
->y
= (this_point
- 1)->y
;
4131 /* Now do the right side. */
4132 while (y
< bottom_y
)
4133 { /* Right vertical edge */
4135 this_point
->x
= (this_point
- 1)->x
;
4136 this_point
->y
= ibw
+ (font_h
* (y
+ 1));
4139 y
++; /* Horizontal connection to next line */
4142 this_point
->x
= ibw
+ (font_w
/ 2);
4144 this_point
->x
= ibw
+ (font_w
* x
);
4146 this_point
->y
= (this_point
- 1)->y
;
4149 /* Now do the bottom and connect to the top left point. */
4150 this_point
->x
= ibw
+ (font_w
* (bottom_x
+ 1));
4153 this_point
->x
= (this_point
- 1)->x
;
4154 this_point
->y
= ibw
+ (font_h
* (bottom_y
+ 1));
4156 this_point
->x
= ibw
;
4157 this_point
->y
= (this_point
- 1)->y
;
4159 this_point
->x
= pixel_points
->x
;
4160 this_point
->y
= pixel_points
->y
;
4162 XDrawLines (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4164 (this_point
- pixel_points
+ 1), CoordModeOrigin
);
4167 DEFUN ("x-contour-region", Fx_contour_region
, Sx_contour_region
, 1, 1, 0,
4168 "Highlight the region between point and the character under the mouse\n\
4171 register Lisp_Object event
;
4173 register int x0
, y0
, x1
, y1
;
4174 register struct frame
*f
= selected_frame
;
4175 register int p1
, p2
;
4177 CHECK_CONS (event
, 0);
4180 x0
= XINT (Fcar (Fcar (event
)));
4181 y0
= XINT (Fcar (Fcdr (Fcar (event
))));
4183 /* If the mouse is past the end of the line, don't that area. */
4184 /* ReWrite this... */
4189 if (y1
> y0
) /* point below mouse */
4190 outline_region (f
, f
->output_data
.x
->cursor_gc
,
4192 else if (y1
< y0
) /* point above mouse */
4193 outline_region (f
, f
->output_data
.x
->cursor_gc
,
4195 else /* same line: draw horizontal rectangle */
4198 x_rectangle (f
, f
->output_data
.x
->cursor_gc
,
4199 x0
, y0
, (x1
- x0
+ 1), 1);
4201 x_rectangle (f
, f
->output_data
.x
->cursor_gc
,
4202 x1
, y1
, (x0
- x1
+ 1), 1);
4205 XFlush (FRAME_X_DISPLAY (f
));
4211 DEFUN ("x-uncontour-region", Fx_uncontour_region
, Sx_uncontour_region
, 1, 1, 0,
4212 "Erase any highlighting of the region between point and the character\n\
4213 at X, Y on the selected frame.")
4215 register Lisp_Object event
;
4217 register int x0
, y0
, x1
, y1
;
4218 register struct frame
*f
= selected_frame
;
4221 x0
= XINT (Fcar (Fcar (event
)));
4222 y0
= XINT (Fcar (Fcdr (Fcar (event
))));
4226 if (y1
> y0
) /* point below mouse */
4227 outline_region (f
, f
->output_data
.x
->reverse_gc
,
4229 else if (y1
< y0
) /* point above mouse */
4230 outline_region (f
, f
->output_data
.x
->reverse_gc
,
4232 else /* same line: draw horizontal rectangle */
4235 x_rectangle (f
, f
->output_data
.x
->reverse_gc
,
4236 x0
, y0
, (x1
- x0
+ 1), 1);
4238 x_rectangle (f
, f
->output_data
.x
->reverse_gc
,
4239 x1
, y1
, (x0
- x1
+ 1), 1);
4247 int contour_begin_x
, contour_begin_y
;
4248 int contour_end_x
, contour_end_y
;
4249 int contour_npoints
;
4251 /* Clip the top part of the contour lines down (and including) line Y_POS.
4252 If X_POS is in the middle (rather than at the end) of the line, drop
4253 down a line at that character. */
4256 clip_contour_top (y_pos
, x_pos
)
4258 register XPoint
*begin
= contour_lines
[y_pos
].top_left
;
4259 register XPoint
*end
;
4260 register int npoints
;
4261 register struct display_line
*line
= selected_frame
->phys_lines
[y_pos
+ 1];
4263 if (x_pos
>= line
->len
- 1) /* Draw one, straight horizontal line. */
4265 end
= contour_lines
[y_pos
].top_right
;
4266 npoints
= (end
- begin
+ 1);
4267 XDrawLines (x_current_display
, contour_window
,
4268 contour_erase_gc
, begin_erase
, npoints
, CoordModeOrigin
);
4270 bcopy (end
, begin
+ 1, contour_last_point
- end
+ 1);
4271 contour_last_point
-= (npoints
- 2);
4272 XDrawLines (x_current_display
, contour_window
,
4273 contour_erase_gc
, begin
, 2, CoordModeOrigin
);
4274 XFlush (x_current_display
);
4276 /* Now, update contour_lines structure. */
4281 register XPoint
*p
= begin
+ 1;
4282 end
= contour_lines
[y_pos
].bottom_right
;
4283 npoints
= (end
- begin
+ 1);
4284 XDrawLines (x_current_display
, contour_window
,
4285 contour_erase_gc
, begin_erase
, npoints
, CoordModeOrigin
);
4288 p
->x
= ibw
+ (font_w
* (x_pos
+ 1));
4290 p
->y
= begin
->y
+ font_h
;
4292 bcopy (end
, begin
+ 3, contour_last_point
- end
+ 1);
4293 contour_last_point
-= (npoints
- 5);
4294 XDrawLines (x_current_display
, contour_window
,
4295 contour_erase_gc
, begin
, 4, CoordModeOrigin
);
4296 XFlush (x_current_display
);
4298 /* Now, update contour_lines structure. */
4302 /* Erase the top horizontal lines of the contour, and then extend
4303 the contour upwards. */
4306 extend_contour_top (line
)
4311 clip_contour_bottom (x_pos
, y_pos
)
4317 extend_contour_bottom (x_pos
, y_pos
)
4321 DEFUN ("x-select-region", Fx_select_region
, Sx_select_region
, 1, 1, "e",
4326 register struct frame
*f
= selected_frame
;
4327 register int point_x
= f
->cursor_x
;
4328 register int point_y
= f
->cursor_y
;
4329 register int mouse_below_point
;
4330 register Lisp_Object obj
;
4331 register int x_contour_x
, x_contour_y
;
4333 x_contour_x
= x_mouse_x
;
4334 x_contour_y
= x_mouse_y
;
4335 if (x_contour_y
> point_y
|| (x_contour_y
== point_y
4336 && x_contour_x
> point_x
))
4338 mouse_below_point
= 1;
4339 outline_region (f
, f
->output_data
.x
->cursor_gc
, point_x
, point_y
,
4340 x_contour_x
, x_contour_y
);
4344 mouse_below_point
= 0;
4345 outline_region (f
, f
->output_data
.x
->cursor_gc
, x_contour_x
, x_contour_y
,
4351 obj
= read_char (-1, 0, 0, Qnil
, 0);
4355 if (mouse_below_point
)
4357 if (x_mouse_y
<= point_y
) /* Flipped. */
4359 mouse_below_point
= 0;
4361 outline_region (f
, f
->output_data
.x
->reverse_gc
, point_x
, point_y
,
4362 x_contour_x
, x_contour_y
);
4363 outline_region (f
, f
->output_data
.x
->cursor_gc
, x_mouse_x
, x_mouse_y
,
4366 else if (x_mouse_y
< x_contour_y
) /* Bottom clipped. */
4368 clip_contour_bottom (x_mouse_y
);
4370 else if (x_mouse_y
> x_contour_y
) /* Bottom extended. */
4372 extend_bottom_contour (x_mouse_y
);
4375 x_contour_x
= x_mouse_x
;
4376 x_contour_y
= x_mouse_y
;
4378 else /* mouse above or same line as point */
4380 if (x_mouse_y
>= point_y
) /* Flipped. */
4382 mouse_below_point
= 1;
4384 outline_region (f
, f
->output_data
.x
->reverse_gc
,
4385 x_contour_x
, x_contour_y
, point_x
, point_y
);
4386 outline_region (f
, f
->output_data
.x
->cursor_gc
, point_x
, point_y
,
4387 x_mouse_x
, x_mouse_y
);
4389 else if (x_mouse_y
> x_contour_y
) /* Top clipped. */
4391 clip_contour_top (x_mouse_y
);
4393 else if (x_mouse_y
< x_contour_y
) /* Top extended. */
4395 extend_contour_top (x_mouse_y
);
4400 unread_command_event
= obj
;
4401 if (mouse_below_point
)
4403 contour_begin_x
= point_x
;
4404 contour_begin_y
= point_y
;
4405 contour_end_x
= x_contour_x
;
4406 contour_end_y
= x_contour_y
;
4410 contour_begin_x
= x_contour_x
;
4411 contour_begin_y
= x_contour_y
;
4412 contour_end_x
= point_x
;
4413 contour_end_y
= point_y
;
4418 DEFUN ("x-horizontal-line", Fx_horizontal_line
, Sx_horizontal_line
, 1, 1, "e",
4423 register Lisp_Object obj
;
4424 struct frame
*f
= selected_frame
;
4425 register struct window
*w
= XWINDOW (selected_window
);
4426 register GC line_gc
= f
->output_data
.x
->cursor_gc
;
4427 register GC erase_gc
= f
->output_data
.x
->reverse_gc
;
4429 char dash_list
[] = {6, 4, 6, 4};
4431 XGCValues gc_values
;
4433 register int previous_y
;
4434 register int line
= (x_mouse_y
+ 1) * f
->output_data
.x
->line_height
4435 + f
->output_data
.x
->internal_border_width
;
4436 register int left
= f
->output_data
.x
->internal_border_width
4437 + (WINDOW_LEFT_MARGIN (w
)
4438 * FONT_WIDTH (f
->output_data
.x
->font
));
4439 register int right
= left
+ (w
->width
4440 * FONT_WIDTH (f
->output_data
.x
->font
))
4441 - f
->output_data
.x
->internal_border_width
;
4445 gc_values
.foreground
= f
->output_data
.x
->cursor_pixel
;
4446 gc_values
.background
= f
->output_data
.x
->background_pixel
;
4447 gc_values
.line_width
= 1;
4448 gc_values
.line_style
= LineOnOffDash
;
4449 gc_values
.cap_style
= CapRound
;
4450 gc_values
.join_style
= JoinRound
;
4452 line_gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4453 GCLineStyle
| GCJoinStyle
| GCCapStyle
4454 | GCLineWidth
| GCForeground
| GCBackground
,
4456 XSetDashes (FRAME_X_DISPLAY (f
), line_gc
, 0, dash_list
, dashes
);
4457 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
4458 gc_values
.background
= f
->output_data
.x
->foreground_pixel
;
4459 erase_gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4460 GCLineStyle
| GCJoinStyle
| GCCapStyle
4461 | GCLineWidth
| GCForeground
| GCBackground
,
4463 XSetDashes (FRAME_X_DISPLAY (f
), erase_gc
, 0, dash_list
, dashes
);
4470 if (x_mouse_y
>= XINT (w
->top
)
4471 && x_mouse_y
< XINT (w
->top
) + XINT (w
->height
) - 1)
4473 previous_y
= x_mouse_y
;
4474 line
= (x_mouse_y
+ 1) * f
->output_data
.x
->line_height
4475 + f
->output_data
.x
->internal_border_width
;
4476 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4477 line_gc
, left
, line
, right
, line
);
4479 XFlush (FRAME_X_DISPLAY (f
));
4484 obj
= read_char (-1, 0, 0, Qnil
, 0);
4486 || (! EQ (Fcar (Fcdr (Fcdr (obj
))),
4487 Qvertical_scroll_bar
))
4491 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4492 erase_gc
, left
, line
, right
, line
);
4493 unread_command_event
= obj
;
4495 XFreeGC (FRAME_X_DISPLAY (f
), line_gc
);
4496 XFreeGC (FRAME_X_DISPLAY (f
), erase_gc
);
4502 while (x_mouse_y
== previous_y
);
4505 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4506 erase_gc
, left
, line
, right
, line
);
4513 /* These keep track of the rectangle following the pointer. */
4514 int mouse_track_top
, mouse_track_left
, mouse_track_width
;
4516 /* Offset in buffer of character under the pointer, or 0. */
4517 int mouse_buffer_offset
;
4519 DEFUN ("x-track-pointer", Fx_track_pointer
, Sx_track_pointer
, 0, 0, 0,
4520 "Track the pointer.")
4523 static Cursor current_pointer_shape
;
4524 FRAME_PTR f
= x_mouse_frame
;
4527 if (EQ (Vmouse_frame_part
, Qtext_part
)
4528 && (current_pointer_shape
!= f
->output_data
.x
->nontext_cursor
))
4533 current_pointer_shape
= f
->output_data
.x
->nontext_cursor
;
4534 XDefineCursor (FRAME_X_DISPLAY (f
),
4536 current_pointer_shape
);
4538 buf
= XBUFFER (XWINDOW (Vmouse_window
)->buffer
);
4539 c
= *(BUF_CHAR_ADDRESS (buf
, mouse_buffer_offset
));
4541 else if (EQ (Vmouse_frame_part
, Qmodeline_part
)
4542 && (current_pointer_shape
!= f
->output_data
.x
->modeline_cursor
))
4544 current_pointer_shape
= f
->output_data
.x
->modeline_cursor
;
4545 XDefineCursor (FRAME_X_DISPLAY (f
),
4547 current_pointer_shape
);
4550 XFlush (FRAME_X_DISPLAY (f
));
4556 DEFUN ("x-track-pointer", Fx_track_pointer
, Sx_track_pointer
, 1, 1, "e",
4557 "Draw rectangle around character under mouse pointer, if there is one.")
4561 struct window
*w
= XWINDOW (Vmouse_window
);
4562 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4563 struct buffer
*b
= XBUFFER (w
->buffer
);
4566 if (! EQ (Vmouse_window
, selected_window
))
4569 if (EQ (event
, Qnil
))
4573 x_read_mouse_position (selected_frame
, &x
, &y
);
4577 mouse_track_width
= 0;
4578 mouse_track_left
= mouse_track_top
= -1;
4582 if ((x_mouse_x
!= mouse_track_left
4583 && (x_mouse_x
< mouse_track_left
4584 || x_mouse_x
> (mouse_track_left
+ mouse_track_width
)))
4585 || x_mouse_y
!= mouse_track_top
)
4587 int hp
= 0; /* Horizontal position */
4588 int len
= FRAME_CURRENT_GLYPHS (f
)->used
[x_mouse_y
];
4589 int p
= FRAME_CURRENT_GLYPHS (f
)->bufp
[x_mouse_y
];
4590 int tab_width
= XINT (b
->tab_width
);
4591 int ctl_arrow_p
= !NILP (b
->ctl_arrow
);
4593 int mode_line_vpos
= XFASTINT (w
->height
) + XFASTINT (w
->top
) - 1;
4594 int in_mode_line
= 0;
4596 if (! FRAME_CURRENT_GLYPHS (f
)->enable
[x_mouse_y
])
4599 /* Erase previous rectangle. */
4600 if (mouse_track_width
)
4602 x_rectangle (f
, f
->output_data
.x
->reverse_gc
,
4603 mouse_track_left
, mouse_track_top
,
4604 mouse_track_width
, 1);
4606 if ((mouse_track_left
== f
->phys_cursor_x
4607 || mouse_track_left
== f
->phys_cursor_x
- 1)
4608 && mouse_track_top
== f
->phys_cursor_y
)
4610 x_display_cursor (f
, 1);
4614 mouse_track_left
= x_mouse_x
;
4615 mouse_track_top
= x_mouse_y
;
4616 mouse_track_width
= 0;
4618 if (mouse_track_left
> len
) /* Past the end of line. */
4621 if (mouse_track_top
== mode_line_vpos
)
4627 if (tab_width
<= 0 || tab_width
> 20) tab_width
= 8;
4631 if (len
== f
->width
&& hp
== len
- 1 && c
!= '\n')
4637 mouse_track_width
= tab_width
- (hp
% tab_width
);
4639 hp
+= mouse_track_width
;
4642 mouse_track_left
= hp
- mouse_track_width
;
4648 mouse_track_width
= -1;
4652 if (ctl_arrow_p
&& (c
< 040 || c
== 0177))
4657 mouse_track_width
= 2;
4662 mouse_track_left
= hp
- mouse_track_width
;
4668 mouse_track_width
= 1;
4675 while (hp
<= x_mouse_x
);
4678 if (mouse_track_width
) /* Over text; use text pointer shape. */
4680 XDefineCursor (FRAME_X_DISPLAY (f
),
4682 f
->output_data
.x
->text_cursor
);
4683 x_rectangle (f
, f
->output_data
.x
->cursor_gc
,
4684 mouse_track_left
, mouse_track_top
,
4685 mouse_track_width
, 1);
4687 else if (in_mode_line
)
4688 XDefineCursor (FRAME_X_DISPLAY (f
),
4690 f
->output_data
.x
->modeline_cursor
);
4692 XDefineCursor (FRAME_X_DISPLAY (f
),
4694 f
->output_data
.x
->nontext_cursor
);
4697 XFlush (FRAME_X_DISPLAY (f
));
4700 obj
= read_char (-1, 0, 0, Qnil
, 0);
4703 while (CONSP (obj
) /* Mouse event */
4704 && EQ (Fcar (Fcdr (Fcdr (obj
))), Qnil
) /* Not scroll bar */
4705 && EQ (Vmouse_depressed
, Qnil
) /* Only motion events */
4706 && EQ (Vmouse_window
, selected_window
) /* In this window */
4709 unread_command_event
= obj
;
4711 if (mouse_track_width
)
4713 x_rectangle (f
, f
->output_data
.x
->reverse_gc
,
4714 mouse_track_left
, mouse_track_top
,
4715 mouse_track_width
, 1);
4716 mouse_track_width
= 0;
4717 if ((mouse_track_left
== f
->phys_cursor_x
4718 || mouse_track_left
- 1 == f
->phys_cursor_x
)
4719 && mouse_track_top
== f
->phys_cursor_y
)
4721 x_display_cursor (f
, 1);
4724 XDefineCursor (FRAME_X_DISPLAY (f
),
4726 f
->output_data
.x
->nontext_cursor
);
4727 XFlush (FRAME_X_DISPLAY (f
));
4737 /* Draw a pixmap specified by IMAGE_DATA of dimensions WIDTH and HEIGHT
4738 on the frame F at position X, Y. */
4740 x_draw_pixmap (f
, x
, y
, image_data
, width
, height
)
4742 int x
, y
, width
, height
;
4747 image
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
4748 FRAME_X_WINDOW (f
), image_data
,
4750 XCopyPlane (FRAME_X_DISPLAY (f
), image
, FRAME_X_WINDOW (f
),
4751 f
->output_data
.x
->normal_gc
, 0, 0, width
, height
, x
, y
);
4755 #if 0 /* I'm told these functions are superfluous
4756 given the ability to bind function keys. */
4759 DEFUN ("x-rebind-key", Fx_rebind_key
, Sx_rebind_key
, 3, 3, 0,
4760 "Rebind X keysym KEYSYM, with MODIFIERS, to generate NEWSTRING.\n\
4761 KEYSYM is a string which conforms to the X keysym definitions found\n\
4762 in X11/keysymdef.h, sans the initial XK_. MODIFIERS is nil or a\n\
4763 list of strings specifying modifier keys such as Control_L, which must\n\
4764 also be depressed for NEWSTRING to appear.")
4765 (x_keysym
, modifiers
, newstring
)
4766 register Lisp_Object x_keysym
;
4767 register Lisp_Object modifiers
;
4768 register Lisp_Object newstring
;
4771 register KeySym keysym
;
4772 KeySym modifier_list
[16];
4775 CHECK_STRING (x_keysym
, 1);
4776 CHECK_STRING (newstring
, 3);
4778 keysym
= XStringToKeysym ((char *) XSTRING (x_keysym
)->data
);
4779 if (keysym
== NoSymbol
)
4780 error ("Keysym does not exist");
4782 if (NILP (modifiers
))
4783 XRebindKeysym (x_current_display
, keysym
, modifier_list
, 0,
4784 XSTRING (newstring
)->data
, XSTRING (newstring
)->size
);
4787 register Lisp_Object rest
, mod
;
4790 for (rest
= modifiers
; !NILP (rest
); rest
= Fcdr (rest
))
4793 error ("Can't have more than 16 modifiers");
4796 CHECK_STRING (mod
, 3);
4797 modifier_list
[i
] = XStringToKeysym ((char *) XSTRING (mod
)->data
);
4799 if (modifier_list
[i
] == NoSymbol
4800 || !(IsModifierKey (modifier_list
[i
])
4801 || ((unsigned)(modifier_list
[i
]) == XK_Mode_switch
)
4802 || ((unsigned)(modifier_list
[i
]) == XK_Num_Lock
)))
4804 if (modifier_list
[i
] == NoSymbol
4805 || !IsModifierKey (modifier_list
[i
]))
4807 error ("Element is not a modifier keysym");
4811 XRebindKeysym (x_current_display
, keysym
, modifier_list
, i
,
4812 XSTRING (newstring
)->data
, XSTRING (newstring
)->size
);
4818 DEFUN ("x-rebind-keys", Fx_rebind_keys
, Sx_rebind_keys
, 2, 2, 0,
4819 "Rebind KEYCODE to list of strings STRINGS.\n\
4820 STRINGS should be a list of 16 elements, one for each shift combination.\n\
4821 nil as element means don't change.\n\
4822 See the documentation of `x-rebind-key' for more information.")
4824 register Lisp_Object keycode
;
4825 register Lisp_Object strings
;
4827 register Lisp_Object item
;
4828 register unsigned char *rawstring
;
4829 KeySym rawkey
, modifier
[1];
4831 register unsigned i
;
4834 CHECK_NUMBER (keycode
, 1);
4835 CHECK_CONS (strings
, 2);
4836 rawkey
= (KeySym
) ((unsigned) (XINT (keycode
))) & 255;
4837 for (i
= 0; i
<= 15; strings
= Fcdr (strings
), i
++)
4839 item
= Fcar (strings
);
4842 CHECK_STRING (item
, 2);
4843 strsize
= XSTRING (item
)->size
;
4844 rawstring
= (unsigned char *) xmalloc (strsize
);
4845 bcopy (XSTRING (item
)->data
, rawstring
, strsize
);
4846 modifier
[1] = 1 << i
;
4847 XRebindKeysym (x_current_display
, rawkey
, modifier
, 1,
4848 rawstring
, strsize
);
4853 #endif /* HAVE_X11 */
4856 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4858 XScreenNumberOfScreen (scr
)
4859 register Screen
*scr
;
4861 register Display
*dpy
;
4862 register Screen
*dpyscr
;
4866 dpyscr
= dpy
->screens
;
4868 for (i
= 0; i
< dpy
->nscreens
; i
++, dpyscr
++)
4874 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4877 select_visual (dpy
, screen
, depth
)
4880 unsigned int *depth
;
4883 XVisualInfo
*vinfo
, vinfo_template
;
4886 v
= DefaultVisualOfScreen (screen
);
4889 vinfo_template
.visualid
= XVisualIDFromVisual (v
);
4891 vinfo_template
.visualid
= v
->visualid
;
4894 vinfo_template
.screen
= XScreenNumberOfScreen (screen
);
4896 vinfo
= XGetVisualInfo (dpy
,
4897 VisualIDMask
| VisualScreenMask
, &vinfo_template
,
4900 fatal ("Can't get proper X visual info");
4902 if ((1 << vinfo
->depth
) == vinfo
->colormap_size
)
4903 *depth
= vinfo
->depth
;
4907 int n
= vinfo
->colormap_size
- 1;
4916 XFree ((char *) vinfo
);
4920 /* Return the X display structure for the display named NAME.
4921 Open a new connection if necessary. */
4923 struct x_display_info
*
4924 x_display_info_for_name (name
)
4928 struct x_display_info
*dpyinfo
;
4930 CHECK_STRING (name
, 0);
4932 if (! EQ (Vwindow_system
, intern ("x")))
4933 error ("Not using X Windows");
4935 for (dpyinfo
= x_display_list
, names
= x_display_name_list
;
4937 dpyinfo
= dpyinfo
->next
, names
= XCONS (names
)->cdr
)
4940 tem
= Fstring_equal (XCONS (XCONS (names
)->car
)->car
, name
);
4945 /* Use this general default value to start with. */
4946 Vx_resource_name
= Vinvocation_name
;
4948 validate_x_resource_name ();
4950 dpyinfo
= x_term_init (name
, (unsigned char *)0,
4951 (char *) XSTRING (Vx_resource_name
)->data
);
4954 error ("Cannot connect to X server %s", XSTRING (name
)->data
);
4957 XSETFASTINT (Vwindow_system_version
, 11);
4962 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
4963 1, 3, 0, "Open a connection to an X server.\n\
4964 DISPLAY is the name of the display to connect to.\n\
4965 Optional second arg XRM-STRING is a string of resources in xrdb format.\n\
4966 If the optional third arg MUST-SUCCEED is non-nil,\n\
4967 terminate Emacs if we can't open the connection.")
4968 (display
, xrm_string
, must_succeed
)
4969 Lisp_Object display
, xrm_string
, must_succeed
;
4971 unsigned int n_planes
;
4972 unsigned char *xrm_option
;
4973 struct x_display_info
*dpyinfo
;
4975 CHECK_STRING (display
, 0);
4976 if (! NILP (xrm_string
))
4977 CHECK_STRING (xrm_string
, 1);
4979 if (! EQ (Vwindow_system
, intern ("x")))
4980 error ("Not using X Windows");
4982 if (! NILP (xrm_string
))
4983 xrm_option
= (unsigned char *) XSTRING (xrm_string
)->data
;
4985 xrm_option
= (unsigned char *) 0;
4987 validate_x_resource_name ();
4989 /* This is what opens the connection and sets x_current_display.
4990 This also initializes many symbols, such as those used for input. */
4991 dpyinfo
= x_term_init (display
, xrm_option
,
4992 (char *) XSTRING (Vx_resource_name
)->data
);
4996 if (!NILP (must_succeed
))
4997 fatal ("Cannot connect to X server %s.\n\
4998 Check the DISPLAY environment variable or use `-d'.\n\
4999 Also use the `xhost' program to verify that it is set to permit\n\
5000 connections from your machine.\n",
5001 XSTRING (display
)->data
);
5003 error ("Cannot connect to X server %s", XSTRING (display
)->data
);
5008 XSETFASTINT (Vwindow_system_version
, 11);
5012 DEFUN ("x-close-connection", Fx_close_connection
,
5013 Sx_close_connection
, 1, 1, 0,
5014 "Close the connection to DISPLAY's X server.\n\
5015 For DISPLAY, specify either a frame or a display name (a string).\n\
5016 If DISPLAY is nil, that stands for the selected frame's display.")
5018 Lisp_Object display
;
5020 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
5021 struct x_display_info
*tail
;
5024 if (dpyinfo
->reference_count
> 0)
5025 error ("Display still has frames on it");
5028 /* Free the fonts in the font table. */
5029 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
5031 if (dpyinfo
->font_table
[i
].name
)
5032 free (dpyinfo
->font_table
[i
].name
);
5033 /* Don't free the full_name string;
5034 it is always shared with something else. */
5035 XFreeFont (dpyinfo
->display
, dpyinfo
->font_table
[i
].font
);
5037 x_destroy_all_bitmaps (dpyinfo
);
5038 XSetCloseDownMode (dpyinfo
->display
, DestroyAll
);
5040 #ifdef USE_X_TOOLKIT
5041 XtCloseDisplay (dpyinfo
->display
);
5043 XCloseDisplay (dpyinfo
->display
);
5046 x_delete_display (dpyinfo
);
5052 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
5053 "Return the list of display names that Emacs has connections to.")
5056 Lisp_Object tail
, result
;
5059 for (tail
= x_display_name_list
; ! NILP (tail
); tail
= XCONS (tail
)->cdr
)
5060 result
= Fcons (XCONS (XCONS (tail
)->car
)->car
, result
);
5065 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
5066 "If ON is non-nil, report X errors as soon as the erring request is made.\n\
5067 If ON is nil, allow buffering of requests.\n\
5068 Turning on synchronization prohibits the Xlib routines from buffering\n\
5069 requests and seriously degrades performance, but makes debugging much\n\
5071 The optional second argument DISPLAY specifies which display to act on.\n\
5072 DISPLAY should be either a frame or a display name (a string).\n\
5073 If DISPLAY is omitted or nil, that stands for the selected frame's display.")
5075 Lisp_Object display
, on
;
5077 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
5079 XSynchronize (dpyinfo
->display
, !EQ (on
, Qnil
));
5084 /* Wait for responses to all X commands issued so far for frame F. */
5091 XSync (FRAME_X_DISPLAY (f
), False
);
5097 /* This is zero if not using X windows. */
5100 /* The section below is built by the lisp expression at the top of the file,
5101 just above where these variables are declared. */
5102 /*&&& init symbols here &&&*/
5103 Qauto_raise
= intern ("auto-raise");
5104 staticpro (&Qauto_raise
);
5105 Qauto_lower
= intern ("auto-lower");
5106 staticpro (&Qauto_lower
);
5107 Qbackground_color
= intern ("background-color");
5108 staticpro (&Qbackground_color
);
5109 Qbar
= intern ("bar");
5111 Qborder_color
= intern ("border-color");
5112 staticpro (&Qborder_color
);
5113 Qborder_width
= intern ("border-width");
5114 staticpro (&Qborder_width
);
5115 Qbox
= intern ("box");
5117 Qcursor_color
= intern ("cursor-color");
5118 staticpro (&Qcursor_color
);
5119 Qcursor_type
= intern ("cursor-type");
5120 staticpro (&Qcursor_type
);
5121 Qforeground_color
= intern ("foreground-color");
5122 staticpro (&Qforeground_color
);
5123 Qgeometry
= intern ("geometry");
5124 staticpro (&Qgeometry
);
5125 Qicon_left
= intern ("icon-left");
5126 staticpro (&Qicon_left
);
5127 Qicon_top
= intern ("icon-top");
5128 staticpro (&Qicon_top
);
5129 Qicon_type
= intern ("icon-type");
5130 staticpro (&Qicon_type
);
5131 Qicon_name
= intern ("icon-name");
5132 staticpro (&Qicon_name
);
5133 Qinternal_border_width
= intern ("internal-border-width");
5134 staticpro (&Qinternal_border_width
);
5135 Qleft
= intern ("left");
5137 Qright
= intern ("right");
5138 staticpro (&Qright
);
5139 Qmouse_color
= intern ("mouse-color");
5140 staticpro (&Qmouse_color
);
5141 Qnone
= intern ("none");
5143 Qparent_id
= intern ("parent-id");
5144 staticpro (&Qparent_id
);
5145 Qscroll_bar_width
= intern ("scroll-bar-width");
5146 staticpro (&Qscroll_bar_width
);
5147 Qsuppress_icon
= intern ("suppress-icon");
5148 staticpro (&Qsuppress_icon
);
5149 Qtop
= intern ("top");
5151 Qundefined_color
= intern ("undefined-color");
5152 staticpro (&Qundefined_color
);
5153 Qvertical_scroll_bars
= intern ("vertical-scroll-bars");
5154 staticpro (&Qvertical_scroll_bars
);
5155 Qvisibility
= intern ("visibility");
5156 staticpro (&Qvisibility
);
5157 Qwindow_id
= intern ("window-id");
5158 staticpro (&Qwindow_id
);
5159 Qx_frame_parameter
= intern ("x-frame-parameter");
5160 staticpro (&Qx_frame_parameter
);
5161 Qx_resource_name
= intern ("x-resource-name");
5162 staticpro (&Qx_resource_name
);
5163 Quser_position
= intern ("user-position");
5164 staticpro (&Quser_position
);
5165 Quser_size
= intern ("user-size");
5166 staticpro (&Quser_size
);
5167 Qdisplay
= intern ("display");
5168 staticpro (&Qdisplay
);
5169 /* This is the end of symbol initialization. */
5171 Fput (Qundefined_color
, Qerror_conditions
,
5172 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
5173 Fput (Qundefined_color
, Qerror_message
,
5174 build_string ("Undefined color"));
5176 init_x_parm_symbols ();
5178 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path
,
5179 "List of directories to search for bitmap files for X.");
5180 Vx_bitmap_file_path
= decode_env_path ((char *) 0, PATH_BITMAPS
);
5182 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
5183 "The shape of the pointer when over text.\n\
5184 Changing the value does not affect existing frames\n\
5185 unless you set the mouse color.");
5186 Vx_pointer_shape
= Qnil
;
5188 DEFVAR_LISP ("x-resource-name", &Vx_resource_name
,
5189 "The name Emacs uses to look up X resources.\n\
5190 `x-get-resource' uses this as the first component of the instance name\n\
5191 when requesting resource values.\n\
5192 Emacs initially sets `x-resource-name' to the name under which Emacs\n\
5193 was invoked, or to the value specified with the `-name' or `-rn'\n\
5194 switches, if present.\n\
5196 It may be useful to bind this variable locally around a call\n\
5197 to `x-get-resource'. See also the variable `x-resource-class'.");
5198 Vx_resource_name
= Qnil
;
5200 DEFVAR_LISP ("x-resource-class", &Vx_resource_class
,
5201 "The class Emacs uses to look up X resources.\n\
5202 `x-get-resource' uses this as the first component of the instance class\n\
5203 when requesting resource values.\n\
5204 Emacs initially sets `x-resource-class' to \"Emacs\".\n\
5206 Setting this variable permanently is not a reasonable thing to do,\n\
5207 but binding this variable locally around a call to `x-get-resource'\n\
5208 is a reasonabvle practice. See also the variable `x-resource-name'.");
5209 Vx_resource_class
= build_string (EMACS_CLASS
);
5211 #if 0 /* This doesn't really do anything. */
5212 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape
,
5213 "The shape of the pointer when not over text.\n\
5214 This variable takes effect when you create a new frame\n\
5215 or when you set the mouse color.");
5217 Vx_nontext_pointer_shape
= Qnil
;
5219 #if 0 /* This doesn't really do anything. */
5220 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape
,
5221 "The shape of the pointer when over the mode line.\n\
5222 This variable takes effect when you create a new frame\n\
5223 or when you set the mouse color.");
5225 Vx_mode_pointer_shape
= Qnil
;
5227 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
5228 &Vx_sensitive_text_pointer_shape
,
5229 "The shape of the pointer when over mouse-sensitive text.\n\
5230 This variable takes effect when you create a new frame\n\
5231 or when you set the mouse color.");
5232 Vx_sensitive_text_pointer_shape
= Qnil
;
5234 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
5235 "A string indicating the foreground color of the cursor box.");
5236 Vx_cursor_fore_pixel
= Qnil
;
5238 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
5239 "Non-nil if no X window manager is in use.\n\
5240 Emacs doesn't try to figure this out; this is always nil\n\
5241 unless you set it to something else.");
5242 /* We don't have any way to find this out, so set it to nil
5243 and maybe the user would like to set it to t. */
5244 Vx_no_window_manager
= Qnil
;
5246 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
5247 &Vx_pixel_size_width_font_regexp
,
5248 "Regexp matching a font name whose width is the same as `PIXEL_SIZE'.\n\
5250 Since Emacs gets width of a font matching with this regexp from\n\
5251 PIXEL_SIZE field of the name, font finding mechanism gets faster for\n\
5252 such a font. This is especially effective for such large fonts as\n\
5253 Chinese, Japanese, and Korean.");
5254 Vx_pixel_size_width_font_regexp
= Qnil
;
5256 #ifdef USE_X_TOOLKIT
5257 Fprovide (intern ("x-toolkit"));
5260 Fprovide (intern ("motif"));
5263 defsubr (&Sx_get_resource
);
5265 defsubr (&Sx_draw_rectangle
);
5266 defsubr (&Sx_erase_rectangle
);
5267 defsubr (&Sx_contour_region
);
5268 defsubr (&Sx_uncontour_region
);
5270 defsubr (&Sx_list_fonts
);
5271 defsubr (&Sx_display_color_p
);
5272 defsubr (&Sx_display_grayscale_p
);
5273 defsubr (&Sx_color_defined_p
);
5274 defsubr (&Sx_color_values
);
5275 defsubr (&Sx_server_max_request_size
);
5276 defsubr (&Sx_server_vendor
);
5277 defsubr (&Sx_server_version
);
5278 defsubr (&Sx_display_pixel_width
);
5279 defsubr (&Sx_display_pixel_height
);
5280 defsubr (&Sx_display_mm_width
);
5281 defsubr (&Sx_display_mm_height
);
5282 defsubr (&Sx_display_screens
);
5283 defsubr (&Sx_display_planes
);
5284 defsubr (&Sx_display_color_cells
);
5285 defsubr (&Sx_display_visual_class
);
5286 defsubr (&Sx_display_backing_store
);
5287 defsubr (&Sx_display_save_under
);
5289 defsubr (&Sx_rebind_key
);
5290 defsubr (&Sx_rebind_keys
);
5291 defsubr (&Sx_track_pointer
);
5292 defsubr (&Sx_grab_pointer
);
5293 defsubr (&Sx_ungrab_pointer
);
5295 defsubr (&Sx_parse_geometry
);
5296 defsubr (&Sx_create_frame
);
5298 defsubr (&Sx_horizontal_line
);
5300 defsubr (&Sx_open_connection
);
5301 defsubr (&Sx_close_connection
);
5302 defsubr (&Sx_display_list
);
5303 defsubr (&Sx_synchronize
);
5305 /* Setting callback functions for fontset handler. */
5306 get_font_info_func
= x_get_font_info
;
5307 list_fonts_func
= x_list_fonts
;
5308 load_font_func
= x_load_font
;
5309 query_font_func
= x_query_font
;
5310 set_frame_fontset_func
= x_set_font
;
5311 check_window_system_func
= check_x
;
5314 #endif /* HAVE_X_WINDOWS */