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 int count
= x_catch_errors (FRAME_X_DISPLAY (f
));
974 XQueryTree (FRAME_X_DISPLAY (f
), outer
, &tmp_root_window
,
975 &f
->output_data
.x
->parent_desc
,
976 &tmp_children
, &tmp_nchildren
);
977 XFree ((char *) tmp_children
);
981 /* Find the position of the outside upper-left corner of
982 the inner window, with respect to the outer window. */
983 if (f
->output_data
.x
->parent_desc
!= FRAME_X_DISPLAY_INFO (f
)->root_window
)
984 outer_window
= f
->output_data
.x
->parent_desc
;
986 outer_window
= outer
;
988 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
990 /* From-window, to-window. */
992 FRAME_X_DISPLAY_INFO (f
)->root_window
,
994 /* From-position, to-position. */
995 0, 0, &win_x
, &win_y
,
1000 /* It is possible for the window returned by the XQueryNotify
1001 to become invalid by the time we call XTranslateCoordinates.
1002 That can happen when you restart some window managers.
1003 If so, we get an error in XTranslateCoordinates.
1004 Detect that and try the whole thing over. */
1005 if (! x_had_errors_p (FRAME_X_DISPLAY (f
)))
1007 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
1011 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
1014 *xptr
= win_x
- f
->output_data
.x
->border_width
;
1015 *yptr
= win_y
- f
->output_data
.x
->border_width
;
1018 /* Insert a description of internally-recorded parameters of frame X
1019 into the parameter alist *ALISTPTR that is to be given to the user.
1020 Only parameters that are specific to the X window system
1021 and whose values are not correctly recorded in the frame's
1022 param_alist need to be considered here. */
1024 x_report_frame_params (f
, alistptr
)
1026 Lisp_Object
*alistptr
;
1031 /* Represent negative positions (off the top or left screen edge)
1032 in a way that Fmodify_frame_parameters will understand correctly. */
1033 XSETINT (tem
, f
->output_data
.x
->left_pos
);
1034 if (f
->output_data
.x
->left_pos
>= 0)
1035 store_in_alist (alistptr
, Qleft
, tem
);
1037 store_in_alist (alistptr
, Qleft
, Fcons (Qplus
, Fcons (tem
, Qnil
)));
1039 XSETINT (tem
, f
->output_data
.x
->top_pos
);
1040 if (f
->output_data
.x
->top_pos
>= 0)
1041 store_in_alist (alistptr
, Qtop
, tem
);
1043 store_in_alist (alistptr
, Qtop
, Fcons (Qplus
, Fcons (tem
, Qnil
)));
1045 store_in_alist (alistptr
, Qborder_width
,
1046 make_number (f
->output_data
.x
->border_width
));
1047 store_in_alist (alistptr
, Qinternal_border_width
,
1048 make_number (f
->output_data
.x
->internal_border_width
));
1049 sprintf (buf
, "%ld", (long) FRAME_X_WINDOW (f
));
1050 store_in_alist (alistptr
, Qwindow_id
,
1051 build_string (buf
));
1052 store_in_alist (alistptr
, Qicon_name
, f
->icon_name
);
1053 FRAME_SAMPLE_VISIBILITY (f
);
1054 store_in_alist (alistptr
, Qvisibility
,
1055 (FRAME_VISIBLE_P (f
) ? Qt
1056 : FRAME_ICONIFIED_P (f
) ? Qicon
: Qnil
));
1057 store_in_alist (alistptr
, Qdisplay
,
1058 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->car
);
1060 store_in_alist (alistptr
, Qparent_id
,
1061 (f
->output_data
.x
->parent_desc
== FRAME_X_DISPLAY_INFO (f
)->root_window
1062 ? Qnil
: f
->output_data
.x
->parent_desc
));
1066 /* Decide if color named COLOR is valid for the display associated with
1067 the selected frame; if so, return the rgb values in COLOR_DEF.
1068 If ALLOC is nonzero, allocate a new colormap cell. */
1071 defined_color (f
, color
, color_def
, alloc
)
1077 register int status
;
1078 Colormap screen_colormap
;
1079 Display
*display
= FRAME_X_DISPLAY (f
);
1082 screen_colormap
= DefaultColormap (display
, XDefaultScreen (display
));
1084 status
= XParseColor (display
, screen_colormap
, color
, color_def
);
1085 if (status
&& alloc
)
1087 status
= XAllocColor (display
, screen_colormap
, color_def
);
1090 /* If we got to this point, the colormap is full, so we're
1091 going to try and get the next closest color.
1092 The algorithm used is a least-squares matching, which is
1093 what X uses for closest color matching with StaticColor visuals. */
1098 long nearest_delta
, trial_delta
;
1101 no_cells
= XDisplayCells (display
, XDefaultScreen (display
));
1102 cells
= (XColor
*) alloca (sizeof (XColor
) * no_cells
);
1104 for (x
= 0; x
< no_cells
; x
++)
1107 XQueryColors (display
, screen_colormap
, cells
, no_cells
);
1109 /* I'm assuming CSE so I'm not going to condense this. */
1110 nearest_delta
= ((((color_def
->red
>> 8) - (cells
[0].red
>> 8))
1111 * ((color_def
->red
>> 8) - (cells
[0].red
>> 8)))
1113 (((color_def
->green
>> 8) - (cells
[0].green
>> 8))
1114 * ((color_def
->green
>> 8) - (cells
[0].green
>> 8)))
1116 (((color_def
->blue
>> 8) - (cells
[0].blue
>> 8))
1117 * ((color_def
->blue
>> 8) - (cells
[0].blue
>> 8))));
1118 for (x
= 1; x
< no_cells
; x
++)
1120 trial_delta
= ((((color_def
->red
>> 8) - (cells
[x
].red
>> 8))
1121 * ((color_def
->red
>> 8) - (cells
[x
].red
>> 8)))
1123 (((color_def
->green
>> 8) - (cells
[x
].green
>> 8))
1124 * ((color_def
->green
>> 8) - (cells
[x
].green
>> 8)))
1126 (((color_def
->blue
>> 8) - (cells
[x
].blue
>> 8))
1127 * ((color_def
->blue
>> 8) - (cells
[x
].blue
>> 8))));
1128 if (trial_delta
< nearest_delta
)
1131 temp
.red
= cells
[x
].red
;
1132 temp
.green
= cells
[x
].green
;
1133 temp
.blue
= cells
[x
].blue
;
1134 status
= XAllocColor (display
, screen_colormap
, &temp
);
1138 nearest_delta
= trial_delta
;
1142 color_def
->red
= cells
[nearest
].red
;
1143 color_def
->green
= cells
[nearest
].green
;
1144 color_def
->blue
= cells
[nearest
].blue
;
1145 status
= XAllocColor (display
, screen_colormap
, color_def
);
1156 /* Given a string ARG naming a color, compute a pixel value from it
1157 suitable for screen F.
1158 If F is not a color screen, return DEF (default) regardless of what
1162 x_decode_color (f
, arg
, def
)
1169 CHECK_STRING (arg
, 0);
1171 if (strcmp (XSTRING (arg
)->data
, "black") == 0)
1172 return BLACK_PIX_DEFAULT (f
);
1173 else if (strcmp (XSTRING (arg
)->data
, "white") == 0)
1174 return WHITE_PIX_DEFAULT (f
);
1176 if (FRAME_X_DISPLAY_INFO (f
)->n_planes
== 1)
1179 /* defined_color is responsible for coping with failures
1180 by looking for a near-miss. */
1181 if (defined_color (f
, XSTRING (arg
)->data
, &cdef
, 1))
1184 Fsignal (Qerror
, Fcons (build_string ("undefined color"),
1185 Fcons (arg
, Qnil
)));
1188 /* Functions called only from `x_set_frame_param'
1189 to set individual parameters.
1191 If FRAME_X_WINDOW (f) is 0,
1192 the frame is being created and its X-window does not exist yet.
1193 In that case, just record the parameter's new value
1194 in the standard place; do not attempt to change the window. */
1197 x_set_foreground_color (f
, arg
, oldval
)
1199 Lisp_Object arg
, oldval
;
1201 f
->output_data
.x
->foreground_pixel
1202 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1203 if (FRAME_X_WINDOW (f
) != 0)
1206 XSetForeground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->normal_gc
,
1207 f
->output_data
.x
->foreground_pixel
);
1208 XSetBackground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->reverse_gc
,
1209 f
->output_data
.x
->foreground_pixel
);
1211 recompute_basic_faces (f
);
1212 if (FRAME_VISIBLE_P (f
))
1218 x_set_background_color (f
, arg
, oldval
)
1220 Lisp_Object arg
, oldval
;
1225 f
->output_data
.x
->background_pixel
1226 = x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
1228 if (FRAME_X_WINDOW (f
) != 0)
1231 /* The main frame area. */
1232 XSetBackground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->normal_gc
,
1233 f
->output_data
.x
->background_pixel
);
1234 XSetForeground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->reverse_gc
,
1235 f
->output_data
.x
->background_pixel
);
1236 XSetForeground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->cursor_gc
,
1237 f
->output_data
.x
->background_pixel
);
1238 XSetWindowBackground (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1239 f
->output_data
.x
->background_pixel
);
1242 for (bar
= FRAME_SCROLL_BARS (f
); !NILP (bar
);
1243 bar
= XSCROLL_BAR (bar
)->next
)
1244 XSetWindowBackground (FRAME_X_DISPLAY (f
),
1245 SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
)),
1246 f
->output_data
.x
->background_pixel
);
1250 recompute_basic_faces (f
);
1252 if (FRAME_VISIBLE_P (f
))
1258 x_set_mouse_color (f
, arg
, oldval
)
1260 Lisp_Object arg
, oldval
;
1262 Cursor cursor
, nontext_cursor
, mode_cursor
, cross_cursor
;
1266 if (!EQ (Qnil
, arg
))
1267 f
->output_data
.x
->mouse_pixel
1268 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1269 mask_color
= f
->output_data
.x
->background_pixel
;
1270 /* No invisible pointers. */
1271 if (mask_color
== f
->output_data
.x
->mouse_pixel
1272 && mask_color
== f
->output_data
.x
->background_pixel
)
1273 f
->output_data
.x
->mouse_pixel
= f
->output_data
.x
->foreground_pixel
;
1277 /* It's not okay to crash if the user selects a screwy cursor. */
1278 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
1280 if (!EQ (Qnil
, Vx_pointer_shape
))
1282 CHECK_NUMBER (Vx_pointer_shape
, 0);
1283 cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XINT (Vx_pointer_shape
));
1286 cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_xterm
);
1287 x_check_errors (FRAME_X_DISPLAY (f
), "bad text pointer cursor: %s");
1289 if (!EQ (Qnil
, Vx_nontext_pointer_shape
))
1291 CHECK_NUMBER (Vx_nontext_pointer_shape
, 0);
1292 nontext_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
),
1293 XINT (Vx_nontext_pointer_shape
));
1296 nontext_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_left_ptr
);
1297 x_check_errors (FRAME_X_DISPLAY (f
), "bad nontext pointer cursor: %s");
1299 if (!EQ (Qnil
, Vx_mode_pointer_shape
))
1301 CHECK_NUMBER (Vx_mode_pointer_shape
, 0);
1302 mode_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
),
1303 XINT (Vx_mode_pointer_shape
));
1306 mode_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_xterm
);
1307 x_check_errors (FRAME_X_DISPLAY (f
), "bad modeline pointer cursor: %s");
1309 if (!EQ (Qnil
, Vx_sensitive_text_pointer_shape
))
1311 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
, 0);
1313 = XCreateFontCursor (FRAME_X_DISPLAY (f
),
1314 XINT (Vx_sensitive_text_pointer_shape
));
1317 cross_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_crosshair
);
1319 /* Check and report errors with the above calls. */
1320 x_check_errors (FRAME_X_DISPLAY (f
), "can't set cursor shape: %s");
1321 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
1324 XColor fore_color
, back_color
;
1326 fore_color
.pixel
= f
->output_data
.x
->mouse_pixel
;
1327 back_color
.pixel
= mask_color
;
1328 XQueryColor (FRAME_X_DISPLAY (f
),
1329 DefaultColormap (FRAME_X_DISPLAY (f
),
1330 DefaultScreen (FRAME_X_DISPLAY (f
))),
1332 XQueryColor (FRAME_X_DISPLAY (f
),
1333 DefaultColormap (FRAME_X_DISPLAY (f
),
1334 DefaultScreen (FRAME_X_DISPLAY (f
))),
1336 XRecolorCursor (FRAME_X_DISPLAY (f
), cursor
,
1337 &fore_color
, &back_color
);
1338 XRecolorCursor (FRAME_X_DISPLAY (f
), nontext_cursor
,
1339 &fore_color
, &back_color
);
1340 XRecolorCursor (FRAME_X_DISPLAY (f
), mode_cursor
,
1341 &fore_color
, &back_color
);
1342 XRecolorCursor (FRAME_X_DISPLAY (f
), cross_cursor
,
1343 &fore_color
, &back_color
);
1346 if (FRAME_X_WINDOW (f
) != 0)
1348 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
1351 if (cursor
!= f
->output_data
.x
->text_cursor
&& f
->output_data
.x
->text_cursor
!= 0)
1352 XFreeCursor (FRAME_X_DISPLAY (f
), f
->output_data
.x
->text_cursor
);
1353 f
->output_data
.x
->text_cursor
= cursor
;
1355 if (nontext_cursor
!= f
->output_data
.x
->nontext_cursor
1356 && f
->output_data
.x
->nontext_cursor
!= 0)
1357 XFreeCursor (FRAME_X_DISPLAY (f
), f
->output_data
.x
->nontext_cursor
);
1358 f
->output_data
.x
->nontext_cursor
= nontext_cursor
;
1360 if (mode_cursor
!= f
->output_data
.x
->modeline_cursor
1361 && f
->output_data
.x
->modeline_cursor
!= 0)
1362 XFreeCursor (FRAME_X_DISPLAY (f
), f
->output_data
.x
->modeline_cursor
);
1363 f
->output_data
.x
->modeline_cursor
= mode_cursor
;
1364 if (cross_cursor
!= f
->output_data
.x
->cross_cursor
1365 && f
->output_data
.x
->cross_cursor
!= 0)
1366 XFreeCursor (FRAME_X_DISPLAY (f
), f
->output_data
.x
->cross_cursor
);
1367 f
->output_data
.x
->cross_cursor
= cross_cursor
;
1369 XFlush (FRAME_X_DISPLAY (f
));
1374 x_set_cursor_color (f
, arg
, oldval
)
1376 Lisp_Object arg
, oldval
;
1378 unsigned long fore_pixel
;
1380 if (!EQ (Vx_cursor_fore_pixel
, Qnil
))
1381 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
1382 WHITE_PIX_DEFAULT (f
));
1384 fore_pixel
= f
->output_data
.x
->background_pixel
;
1385 f
->output_data
.x
->cursor_pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1387 /* Make sure that the cursor color differs from the background color. */
1388 if (f
->output_data
.x
->cursor_pixel
== f
->output_data
.x
->background_pixel
)
1390 f
->output_data
.x
->cursor_pixel
= f
->output_data
.x
->mouse_pixel
;
1391 if (f
->output_data
.x
->cursor_pixel
== fore_pixel
)
1392 fore_pixel
= f
->output_data
.x
->background_pixel
;
1394 f
->output_data
.x
->cursor_foreground_pixel
= fore_pixel
;
1396 if (FRAME_X_WINDOW (f
) != 0)
1399 XSetBackground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->cursor_gc
,
1400 f
->output_data
.x
->cursor_pixel
);
1401 XSetForeground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->cursor_gc
,
1405 if (FRAME_VISIBLE_P (f
))
1407 x_update_cursor (f
, 0);
1408 x_update_cursor (f
, 1);
1413 /* Set the border-color of frame F to value described by ARG.
1414 ARG can be a string naming a color.
1415 The border-color is used for the border that is drawn by the X server.
1416 Note that this does not fully take effect if done before
1417 F has an x-window; it must be redone when the window is created.
1419 Note: this is done in two routines because of the way X10 works.
1421 Note: under X11, this is normally the province of the window manager,
1422 and so emacs' border colors may be overridden. */
1425 x_set_border_color (f
, arg
, oldval
)
1427 Lisp_Object arg
, oldval
;
1432 CHECK_STRING (arg
, 0);
1433 str
= XSTRING (arg
)->data
;
1435 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1437 x_set_border_pixel (f
, pix
);
1440 /* Set the border-color of frame F to pixel value PIX.
1441 Note that this does not fully take effect if done before
1442 F has an x-window. */
1444 x_set_border_pixel (f
, pix
)
1448 f
->output_data
.x
->border_pixel
= pix
;
1450 if (FRAME_X_WINDOW (f
) != 0 && f
->output_data
.x
->border_width
> 0)
1456 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1457 (unsigned long)pix
);
1460 if (FRAME_VISIBLE_P (f
))
1466 x_set_cursor_type (f
, arg
, oldval
)
1468 Lisp_Object arg
, oldval
;
1472 FRAME_DESIRED_CURSOR (f
) = bar_cursor
;
1473 f
->output_data
.x
->cursor_width
= 2;
1475 else if (CONSP (arg
) && EQ (XCONS (arg
)->car
, Qbar
)
1476 && INTEGERP (XCONS (arg
)->cdr
))
1478 FRAME_DESIRED_CURSOR (f
) = bar_cursor
;
1479 f
->output_data
.x
->cursor_width
= XINT (XCONS (arg
)->cdr
);
1482 /* Treat anything unknown as "box cursor".
1483 It was bad to signal an error; people have trouble fixing
1484 .Xdefaults with Emacs, when it has something bad in it. */
1485 FRAME_DESIRED_CURSOR (f
) = filled_box_cursor
;
1487 /* Make sure the cursor gets redrawn. This is overkill, but how
1488 often do people change cursor types? */
1489 update_mode_lines
++;
1493 x_set_icon_type (f
, arg
, oldval
)
1495 Lisp_Object arg
, oldval
;
1502 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1505 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1510 result
= x_text_icon (f
,
1511 (char *) XSTRING ((!NILP (f
->icon_name
)
1515 result
= x_bitmap_icon (f
, arg
);
1520 error ("No icon window available");
1523 XFlush (FRAME_X_DISPLAY (f
));
1527 /* Return non-nil if frame F wants a bitmap icon. */
1535 tem
= assq_no_quit (Qicon_type
, f
->param_alist
);
1537 return XCONS (tem
)->cdr
;
1543 x_set_icon_name (f
, arg
, oldval
)
1545 Lisp_Object arg
, oldval
;
1552 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1555 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1560 if (f
->output_data
.x
->icon_bitmap
!= 0)
1565 result
= x_text_icon (f
,
1566 (char *) XSTRING ((!NILP (f
->icon_name
)
1575 error ("No icon window available");
1578 XFlush (FRAME_X_DISPLAY (f
));
1582 extern Lisp_Object
x_new_font ();
1585 x_set_font (f
, arg
, oldval
)
1587 Lisp_Object arg
, oldval
;
1590 Lisp_Object fontset_name
;
1592 CHECK_STRING (arg
, 1);
1594 fontset_name
= Fquery_fontset (arg
);
1597 result
= (STRINGP (fontset_name
)
1598 ? x_new_fontset (f
, XSTRING (fontset_name
)->data
)
1599 : x_new_font (f
, XSTRING (arg
)->data
));
1602 if (EQ (result
, Qnil
))
1603 error ("Font `%s' is not defined", XSTRING (arg
)->data
);
1604 else if (EQ (result
, Qt
))
1605 error ("the characters of the given font have varying widths");
1606 else if (STRINGP (result
))
1608 recompute_basic_faces (f
);
1609 store_frame_param (f
, Qfont
, result
);
1616 x_set_border_width (f
, arg
, oldval
)
1618 Lisp_Object arg
, oldval
;
1620 CHECK_NUMBER (arg
, 0);
1622 if (XINT (arg
) == f
->output_data
.x
->border_width
)
1625 if (FRAME_X_WINDOW (f
) != 0)
1626 error ("Cannot change the border width of a window");
1628 f
->output_data
.x
->border_width
= XINT (arg
);
1632 x_set_internal_border_width (f
, arg
, oldval
)
1634 Lisp_Object arg
, oldval
;
1637 int old
= f
->output_data
.x
->internal_border_width
;
1639 CHECK_NUMBER (arg
, 0);
1640 f
->output_data
.x
->internal_border_width
= XINT (arg
);
1641 if (f
->output_data
.x
->internal_border_width
< 0)
1642 f
->output_data
.x
->internal_border_width
= 0;
1644 #ifdef USE_X_TOOLKIT
1645 if (f
->output_data
.x
->edit_widget
)
1646 widget_store_internal_border (f
->output_data
.x
->edit_widget
,
1647 f
->output_data
.x
->internal_border_width
);
1650 if (f
->output_data
.x
->internal_border_width
== old
)
1653 if (FRAME_X_WINDOW (f
) != 0)
1656 x_set_window_size (f
, 0, f
->width
, f
->height
);
1658 x_set_resize_hint (f
);
1660 XFlush (FRAME_X_DISPLAY (f
));
1662 SET_FRAME_GARBAGED (f
);
1667 x_set_visibility (f
, value
, oldval
)
1669 Lisp_Object value
, oldval
;
1672 XSETFRAME (frame
, f
);
1675 Fmake_frame_invisible (frame
, Qt
);
1676 else if (EQ (value
, Qicon
))
1677 Ficonify_frame (frame
);
1679 Fmake_frame_visible (frame
);
1683 x_set_menu_bar_lines_1 (window
, n
)
1687 struct window
*w
= XWINDOW (window
);
1689 XSETFASTINT (w
->top
, XFASTINT (w
->top
) + n
);
1690 XSETFASTINT (w
->height
, XFASTINT (w
->height
) - n
);
1692 /* Handle just the top child in a vertical split. */
1693 if (!NILP (w
->vchild
))
1694 x_set_menu_bar_lines_1 (w
->vchild
, n
);
1696 /* Adjust all children in a horizontal split. */
1697 for (window
= w
->hchild
; !NILP (window
); window
= w
->next
)
1699 w
= XWINDOW (window
);
1700 x_set_menu_bar_lines_1 (window
, n
);
1705 x_set_menu_bar_lines (f
, value
, oldval
)
1707 Lisp_Object value
, oldval
;
1710 int olines
= FRAME_MENU_BAR_LINES (f
);
1712 /* Right now, menu bars don't work properly in minibuf-only frames;
1713 most of the commands try to apply themselves to the minibuffer
1714 frame itslef, and get an error because you can't switch buffers
1715 in or split the minibuffer window. */
1716 if (FRAME_MINIBUF_ONLY_P (f
))
1719 if (INTEGERP (value
))
1720 nlines
= XINT (value
);
1724 /* Make sure we redisplay all windows in this frame. */
1725 windows_or_buffers_changed
++;
1727 #ifdef USE_X_TOOLKIT
1728 FRAME_MENU_BAR_LINES (f
) = 0;
1731 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
1732 if (FRAME_X_P (f
) && f
->output_data
.x
->menubar_widget
== 0)
1733 /* Make sure next redisplay shows the menu bar. */
1734 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= Qt
;
1738 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
1739 free_frame_menubar (f
);
1740 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
1742 f
->output_data
.x
->menubar_widget
= 0;
1744 #else /* not USE_X_TOOLKIT */
1745 FRAME_MENU_BAR_LINES (f
) = nlines
;
1746 x_set_menu_bar_lines_1 (f
->root_window
, nlines
- olines
);
1747 #endif /* not USE_X_TOOLKIT */
1750 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1753 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1754 name; if NAME is a string, set F's name to NAME and set
1755 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1757 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1758 suggesting a new name, which lisp code should override; if
1759 F->explicit_name is set, ignore the new name; otherwise, set it. */
1762 x_set_name (f
, name
, explicit)
1767 /* Make sure that requests from lisp code override requests from
1768 Emacs redisplay code. */
1771 /* If we're switching from explicit to implicit, we had better
1772 update the mode lines and thereby update the title. */
1773 if (f
->explicit_name
&& NILP (name
))
1774 update_mode_lines
= 1;
1776 f
->explicit_name
= ! NILP (name
);
1778 else if (f
->explicit_name
)
1781 /* If NAME is nil, set the name to the x_id_name. */
1784 /* Check for no change needed in this very common case
1785 before we do any consing. */
1786 if (!strcmp (FRAME_X_DISPLAY_INFO (f
)->x_id_name
,
1787 XSTRING (f
->name
)->data
))
1789 name
= build_string (FRAME_X_DISPLAY_INFO (f
)->x_id_name
);
1792 CHECK_STRING (name
, 0);
1794 /* Don't change the name if it's already NAME. */
1795 if (! NILP (Fstring_equal (name
, f
->name
)))
1800 /* For setting the frame title, the title parameter should override
1801 the name parameter. */
1802 if (! NILP (f
->title
))
1805 if (FRAME_X_WINDOW (f
))
1810 XTextProperty text
, icon
;
1811 Lisp_Object icon_name
;
1813 text
.value
= XSTRING (name
)->data
;
1814 text
.encoding
= XA_STRING
;
1816 text
.nitems
= XSTRING (name
)->size
;
1818 icon_name
= (!NILP (f
->icon_name
) ? f
->icon_name
: name
);
1820 icon
.value
= XSTRING (icon_name
)->data
;
1821 icon
.encoding
= XA_STRING
;
1823 icon
.nitems
= XSTRING (icon_name
)->size
;
1824 #ifdef USE_X_TOOLKIT
1825 XSetWMName (FRAME_X_DISPLAY (f
),
1826 XtWindow (f
->output_data
.x
->widget
), &text
);
1827 XSetWMIconName (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
),
1829 #else /* not USE_X_TOOLKIT */
1830 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &text
);
1831 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &icon
);
1832 #endif /* not USE_X_TOOLKIT */
1834 #else /* not HAVE_X11R4 */
1835 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1836 XSTRING (name
)->data
);
1837 XStoreName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1838 XSTRING (name
)->data
);
1839 #endif /* not HAVE_X11R4 */
1844 /* This function should be called when the user's lisp code has
1845 specified a name for the frame; the name will override any set by the
1848 x_explicitly_set_name (f
, arg
, oldval
)
1850 Lisp_Object arg
, oldval
;
1852 x_set_name (f
, arg
, 1);
1855 /* This function should be called by Emacs redisplay code to set the
1856 name; names set this way will never override names set by the user's
1859 x_implicitly_set_name (f
, arg
, oldval
)
1861 Lisp_Object arg
, oldval
;
1863 x_set_name (f
, arg
, 0);
1866 /* Change the title of frame F to NAME.
1867 If NAME is nil, use the frame name as the title.
1869 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1870 name; if NAME is a string, set F's name to NAME and set
1871 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1873 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1874 suggesting a new name, which lisp code should override; if
1875 F->explicit_name is set, ignore the new name; otherwise, set it. */
1878 x_set_title (f
, name
)
1882 /* Don't change the title if it's already NAME. */
1883 if (EQ (name
, f
->title
))
1886 update_mode_lines
= 1;
1893 CHECK_STRING (name
, 0);
1895 if (FRAME_X_WINDOW (f
))
1900 XTextProperty text
, icon
;
1901 Lisp_Object icon_name
;
1903 text
.value
= XSTRING (name
)->data
;
1904 text
.encoding
= XA_STRING
;
1906 text
.nitems
= XSTRING (name
)->size
;
1908 icon_name
= (!NILP (f
->icon_name
) ? f
->icon_name
: name
);
1910 icon
.value
= XSTRING (icon_name
)->data
;
1911 icon
.encoding
= XA_STRING
;
1913 icon
.nitems
= XSTRING (icon_name
)->size
;
1914 #ifdef USE_X_TOOLKIT
1915 XSetWMName (FRAME_X_DISPLAY (f
),
1916 XtWindow (f
->output_data
.x
->widget
), &text
);
1917 XSetWMIconName (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
),
1919 #else /* not USE_X_TOOLKIT */
1920 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &text
);
1921 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &icon
);
1922 #endif /* not USE_X_TOOLKIT */
1924 #else /* not HAVE_X11R4 */
1925 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1926 XSTRING (name
)->data
);
1927 XStoreName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1928 XSTRING (name
)->data
);
1929 #endif /* not HAVE_X11R4 */
1935 x_set_autoraise (f
, arg
, oldval
)
1937 Lisp_Object arg
, oldval
;
1939 f
->auto_raise
= !EQ (Qnil
, arg
);
1943 x_set_autolower (f
, arg
, oldval
)
1945 Lisp_Object arg
, oldval
;
1947 f
->auto_lower
= !EQ (Qnil
, arg
);
1951 x_set_unsplittable (f
, arg
, oldval
)
1953 Lisp_Object arg
, oldval
;
1955 f
->no_split
= !NILP (arg
);
1959 x_set_vertical_scroll_bars (f
, arg
, oldval
)
1961 Lisp_Object arg
, oldval
;
1963 if ((EQ (arg
, Qleft
) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
1964 || (EQ (arg
, Qright
) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f
))
1965 || (NILP (arg
) && FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
1966 || (!NILP (arg
) && ! FRAME_HAS_VERTICAL_SCROLL_BARS (f
)))
1968 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
)
1970 ? vertical_scroll_bar_none
1972 ? vertical_scroll_bar_right
1973 : vertical_scroll_bar_left
);
1975 /* We set this parameter before creating the X window for the
1976 frame, so we can get the geometry right from the start.
1977 However, if the window hasn't been created yet, we shouldn't
1978 call x_set_window_size. */
1979 if (FRAME_X_WINDOW (f
))
1980 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
1985 x_set_scroll_bar_width (f
, arg
, oldval
)
1987 Lisp_Object arg
, oldval
;
1989 int wid
= FONT_WIDTH (f
->output_data
.x
->font
);
1993 /* Make the actual width at least 14 pixels
1994 and a multiple of a character width. */
1995 FRAME_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
1996 /* Use all of that space (aside from required margins)
1997 for the scroll bar. */
1998 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = 0;
2000 if (FRAME_X_WINDOW (f
))
2001 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
2003 else if (INTEGERP (arg
) && XINT (arg
) > 0
2004 && XFASTINT (arg
) != FRAME_SCROLL_BAR_PIXEL_WIDTH (f
))
2006 if (XFASTINT (arg
) <= 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM
)
2007 XSETINT (arg
, 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM
+ 1);
2009 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = XFASTINT (arg
);
2010 FRAME_SCROLL_BAR_COLS (f
) = (XFASTINT (arg
) + wid
-1) / wid
;
2011 if (FRAME_X_WINDOW (f
))
2012 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
2015 change_frame_size (f
, 0, FRAME_WIDTH (f
), 0, 0);
2016 FRAME_CURSOR_X (f
) = FRAME_LEFT_SCROLL_BAR_WIDTH (f
);
2019 /* Subroutines of creating an X frame. */
2021 /* Make sure that Vx_resource_name is set to a reasonable value.
2022 Fix it up, or set it to `emacs' if it is too hopeless. */
2025 validate_x_resource_name ()
2028 /* Number of valid characters in the resource name. */
2030 /* Number of invalid characters in the resource name. */
2035 if (!STRINGP (Vx_resource_class
))
2036 Vx_resource_class
= build_string (EMACS_CLASS
);
2038 if (STRINGP (Vx_resource_name
))
2040 unsigned char *p
= XSTRING (Vx_resource_name
)->data
;
2043 len
= XSTRING (Vx_resource_name
)->size
;
2045 /* Only letters, digits, - and _ are valid in resource names.
2046 Count the valid characters and count the invalid ones. */
2047 for (i
= 0; i
< len
; i
++)
2050 if (! ((c
>= 'a' && c
<= 'z')
2051 || (c
>= 'A' && c
<= 'Z')
2052 || (c
>= '0' && c
<= '9')
2053 || c
== '-' || c
== '_'))
2060 /* Not a string => completely invalid. */
2061 bad_count
= 5, good_count
= 0;
2063 /* If name is valid already, return. */
2067 /* If name is entirely invalid, or nearly so, use `emacs'. */
2069 || (good_count
== 1 && bad_count
> 0))
2071 Vx_resource_name
= build_string ("emacs");
2075 /* Name is partly valid. Copy it and replace the invalid characters
2076 with underscores. */
2078 Vx_resource_name
= new = Fcopy_sequence (Vx_resource_name
);
2080 for (i
= 0; i
< len
; i
++)
2082 int c
= XSTRING (new)->data
[i
];
2083 if (! ((c
>= 'a' && c
<= 'z')
2084 || (c
>= 'A' && c
<= 'Z')
2085 || (c
>= '0' && c
<= '9')
2086 || c
== '-' || c
== '_'))
2087 XSTRING (new)->data
[i
] = '_';
2092 extern char *x_get_string_resource ();
2094 DEFUN ("x-get-resource", Fx_get_resource
, Sx_get_resource
, 2, 4, 0,
2095 "Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.\n\
2096 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the\n\
2097 class, where INSTANCE is the name under which Emacs was invoked, or\n\
2098 the name specified by the `-name' or `-rn' command-line arguments.\n\
2100 The optional arguments COMPONENT and SUBCLASS add to the key and the\n\
2101 class, respectively. You must specify both of them or neither.\n\
2102 If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'\n\
2103 and the class is `Emacs.CLASS.SUBCLASS'.")
2104 (attribute
, class, component
, subclass
)
2105 Lisp_Object attribute
, class, component
, subclass
;
2107 register char *value
;
2113 CHECK_STRING (attribute
, 0);
2114 CHECK_STRING (class, 0);
2116 if (!NILP (component
))
2117 CHECK_STRING (component
, 1);
2118 if (!NILP (subclass
))
2119 CHECK_STRING (subclass
, 2);
2120 if (NILP (component
) != NILP (subclass
))
2121 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
2123 validate_x_resource_name ();
2125 /* Allocate space for the components, the dots which separate them,
2126 and the final '\0'. Make them big enough for the worst case. */
2127 name_key
= (char *) alloca (XSTRING (Vx_resource_name
)->size
2128 + (STRINGP (component
)
2129 ? XSTRING (component
)->size
: 0)
2130 + XSTRING (attribute
)->size
2133 class_key
= (char *) alloca (XSTRING (Vx_resource_class
)->size
2134 + XSTRING (class)->size
2135 + (STRINGP (subclass
)
2136 ? XSTRING (subclass
)->size
: 0)
2139 /* Start with emacs.FRAMENAME for the name (the specific one)
2140 and with `Emacs' for the class key (the general one). */
2141 strcpy (name_key
, XSTRING (Vx_resource_name
)->data
);
2142 strcpy (class_key
, XSTRING (Vx_resource_class
)->data
);
2144 strcat (class_key
, ".");
2145 strcat (class_key
, XSTRING (class)->data
);
2147 if (!NILP (component
))
2149 strcat (class_key
, ".");
2150 strcat (class_key
, XSTRING (subclass
)->data
);
2152 strcat (name_key
, ".");
2153 strcat (name_key
, XSTRING (component
)->data
);
2156 strcat (name_key
, ".");
2157 strcat (name_key
, XSTRING (attribute
)->data
);
2159 value
= x_get_string_resource (check_x_display_info (Qnil
)->xrdb
,
2160 name_key
, class_key
);
2162 if (value
!= (char *) 0)
2163 return build_string (value
);
2168 /* Get an X resource, like Fx_get_resource, but for display DPYINFO. */
2171 display_x_get_resource (dpyinfo
, attribute
, class, component
, subclass
)
2172 struct x_display_info
*dpyinfo
;
2173 Lisp_Object attribute
, class, component
, subclass
;
2175 register char *value
;
2181 CHECK_STRING (attribute
, 0);
2182 CHECK_STRING (class, 0);
2184 if (!NILP (component
))
2185 CHECK_STRING (component
, 1);
2186 if (!NILP (subclass
))
2187 CHECK_STRING (subclass
, 2);
2188 if (NILP (component
) != NILP (subclass
))
2189 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
2191 validate_x_resource_name ();
2193 /* Allocate space for the components, the dots which separate them,
2194 and the final '\0'. Make them big enough for the worst case. */
2195 name_key
= (char *) alloca (XSTRING (Vx_resource_name
)->size
2196 + (STRINGP (component
)
2197 ? XSTRING (component
)->size
: 0)
2198 + XSTRING (attribute
)->size
2201 class_key
= (char *) alloca (XSTRING (Vx_resource_class
)->size
2202 + XSTRING (class)->size
2203 + (STRINGP (subclass
)
2204 ? XSTRING (subclass
)->size
: 0)
2207 /* Start with emacs.FRAMENAME for the name (the specific one)
2208 and with `Emacs' for the class key (the general one). */
2209 strcpy (name_key
, XSTRING (Vx_resource_name
)->data
);
2210 strcpy (class_key
, XSTRING (Vx_resource_class
)->data
);
2212 strcat (class_key
, ".");
2213 strcat (class_key
, XSTRING (class)->data
);
2215 if (!NILP (component
))
2217 strcat (class_key
, ".");
2218 strcat (class_key
, XSTRING (subclass
)->data
);
2220 strcat (name_key
, ".");
2221 strcat (name_key
, XSTRING (component
)->data
);
2224 strcat (name_key
, ".");
2225 strcat (name_key
, XSTRING (attribute
)->data
);
2227 value
= x_get_string_resource (dpyinfo
->xrdb
, name_key
, class_key
);
2229 if (value
!= (char *) 0)
2230 return build_string (value
);
2235 /* Used when C code wants a resource value. */
2238 x_get_resource_string (attribute
, class)
2239 char *attribute
, *class;
2241 register char *value
;
2245 /* Allocate space for the components, the dots which separate them,
2246 and the final '\0'. */
2247 name_key
= (char *) alloca (XSTRING (Vinvocation_name
)->size
2248 + strlen (attribute
) + 2);
2249 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
2250 + strlen (class) + 2);
2252 sprintf (name_key
, "%s.%s",
2253 XSTRING (Vinvocation_name
)->data
,
2255 sprintf (class_key
, "%s.%s", EMACS_CLASS
, class);
2257 return x_get_string_resource (FRAME_X_DISPLAY_INFO (selected_frame
)->xrdb
,
2258 name_key
, class_key
);
2261 /* Types we might convert a resource string into. */
2264 number
, boolean
, string
, symbol
2267 /* Return the value of parameter PARAM.
2269 First search ALIST, then Vdefault_frame_alist, then the X defaults
2270 database, using ATTRIBUTE as the attribute name and CLASS as its class.
2272 Convert the resource to the type specified by desired_type.
2274 If no default is specified, return Qunbound. If you call
2275 x_get_arg, make sure you deal with Qunbound in a reasonable way,
2276 and don't let it get stored in any Lisp-visible variables! */
2279 x_get_arg (dpyinfo
, alist
, param
, attribute
, class, type
)
2280 struct x_display_info
*dpyinfo
;
2281 Lisp_Object alist
, param
;
2284 enum resource_types type
;
2286 register Lisp_Object tem
;
2288 tem
= Fassq (param
, alist
);
2290 tem
= Fassq (param
, Vdefault_frame_alist
);
2296 tem
= display_x_get_resource (dpyinfo
,
2297 build_string (attribute
),
2298 build_string (class),
2307 return make_number (atoi (XSTRING (tem
)->data
));
2310 tem
= Fdowncase (tem
);
2311 if (!strcmp (XSTRING (tem
)->data
, "on")
2312 || !strcmp (XSTRING (tem
)->data
, "true"))
2321 /* As a special case, we map the values `true' and `on'
2322 to Qt, and `false' and `off' to Qnil. */
2325 lower
= Fdowncase (tem
);
2326 if (!strcmp (XSTRING (lower
)->data
, "on")
2327 || !strcmp (XSTRING (lower
)->data
, "true"))
2329 else if (!strcmp (XSTRING (lower
)->data
, "off")
2330 || !strcmp (XSTRING (lower
)->data
, "false"))
2333 return Fintern (tem
, Qnil
);
2346 /* Like x_get_arg, but also record the value in f->param_alist. */
2349 x_get_and_record_arg (f
, alist
, param
, attribute
, class, type
)
2351 Lisp_Object alist
, param
;
2354 enum resource_types type
;
2358 value
= x_get_arg (FRAME_X_DISPLAY_INFO (f
), alist
, param
,
2359 attribute
, class, type
);
2361 store_frame_param (f
, param
, value
);
2366 /* Record in frame F the specified or default value according to ALIST
2367 of the parameter named PARAM (a Lisp symbol).
2368 If no value is specified for PARAM, look for an X default for XPROP
2369 on the frame named NAME.
2370 If that is not found either, use the value DEFLT. */
2373 x_default_parameter (f
, alist
, prop
, deflt
, xprop
, xclass
, type
)
2380 enum resource_types type
;
2384 tem
= x_get_arg (FRAME_X_DISPLAY_INFO (f
), alist
, prop
, xprop
, xclass
, type
);
2385 if (EQ (tem
, Qunbound
))
2387 x_set_frame_parameters (f
, Fcons (Fcons (prop
, tem
), Qnil
));
2391 DEFUN ("x-parse-geometry", Fx_parse_geometry
, Sx_parse_geometry
, 1, 1, 0,
2392 "Parse an X-style geometry string STRING.\n\
2393 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).\n\
2394 The properties returned may include `top', `left', `height', and `width'.\n\
2395 The value of `left' or `top' may be an integer,\n\
2396 or a list (+ N) meaning N pixels relative to top/left corner,\n\
2397 or a list (- N) meaning -N pixels relative to bottom/right corner.")
2402 unsigned int width
, height
;
2405 CHECK_STRING (string
, 0);
2407 geometry
= XParseGeometry ((char *) XSTRING (string
)->data
,
2408 &x
, &y
, &width
, &height
);
2411 if (!!(geometry
& XValue
) != !!(geometry
& YValue
))
2412 error ("Must specify both x and y position, or neither");
2416 if (geometry
& XValue
)
2418 Lisp_Object element
;
2420 if (x
>= 0 && (geometry
& XNegative
))
2421 element
= Fcons (Qleft
, Fcons (Qminus
, Fcons (make_number (-x
), Qnil
)));
2422 else if (x
< 0 && ! (geometry
& XNegative
))
2423 element
= Fcons (Qleft
, Fcons (Qplus
, Fcons (make_number (x
), Qnil
)));
2425 element
= Fcons (Qleft
, make_number (x
));
2426 result
= Fcons (element
, result
);
2429 if (geometry
& YValue
)
2431 Lisp_Object element
;
2433 if (y
>= 0 && (geometry
& YNegative
))
2434 element
= Fcons (Qtop
, Fcons (Qminus
, Fcons (make_number (-y
), Qnil
)));
2435 else if (y
< 0 && ! (geometry
& YNegative
))
2436 element
= Fcons (Qtop
, Fcons (Qplus
, Fcons (make_number (y
), Qnil
)));
2438 element
= Fcons (Qtop
, make_number (y
));
2439 result
= Fcons (element
, result
);
2442 if (geometry
& WidthValue
)
2443 result
= Fcons (Fcons (Qwidth
, make_number (width
)), result
);
2444 if (geometry
& HeightValue
)
2445 result
= Fcons (Fcons (Qheight
, make_number (height
)), result
);
2450 /* Calculate the desired size and position of this window,
2451 and return the flags saying which aspects were specified.
2453 This function does not make the coordinates positive. */
2455 #define DEFAULT_ROWS 40
2456 #define DEFAULT_COLS 80
2459 x_figure_window_size (f
, parms
)
2463 register Lisp_Object tem0
, tem1
, tem2
;
2464 int height
, width
, left
, top
;
2465 register int geometry
;
2466 long window_prompting
= 0;
2467 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
2469 /* Default values if we fall through.
2470 Actually, if that happens we should get
2471 window manager prompting. */
2472 SET_FRAME_WIDTH (f
, DEFAULT_COLS
);
2473 f
->height
= DEFAULT_ROWS
;
2474 /* Window managers expect that if program-specified
2475 positions are not (0,0), they're intentional, not defaults. */
2476 f
->output_data
.x
->top_pos
= 0;
2477 f
->output_data
.x
->left_pos
= 0;
2479 tem0
= x_get_arg (dpyinfo
, parms
, Qheight
, 0, 0, number
);
2480 tem1
= x_get_arg (dpyinfo
, parms
, Qwidth
, 0, 0, number
);
2481 tem2
= x_get_arg (dpyinfo
, parms
, Quser_size
, 0, 0, number
);
2482 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
2484 if (!EQ (tem0
, Qunbound
))
2486 CHECK_NUMBER (tem0
, 0);
2487 f
->height
= XINT (tem0
);
2489 if (!EQ (tem1
, Qunbound
))
2491 CHECK_NUMBER (tem1
, 0);
2492 SET_FRAME_WIDTH (f
, XINT (tem1
));
2494 if (!NILP (tem2
) && !EQ (tem2
, Qunbound
))
2495 window_prompting
|= USSize
;
2497 window_prompting
|= PSize
;
2500 f
->output_data
.x
->vertical_scroll_bar_extra
2501 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
2503 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0
2504 ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f
)
2505 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.x
->font
)));
2506 f
->output_data
.x
->pixel_width
= CHAR_TO_PIXEL_WIDTH (f
, f
->width
);
2507 f
->output_data
.x
->pixel_height
= CHAR_TO_PIXEL_HEIGHT (f
, f
->height
);
2509 tem0
= x_get_arg (dpyinfo
, parms
, Qtop
, 0, 0, number
);
2510 tem1
= x_get_arg (dpyinfo
, parms
, Qleft
, 0, 0, number
);
2511 tem2
= x_get_arg (dpyinfo
, parms
, Quser_position
, 0, 0, number
);
2512 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
2514 if (EQ (tem0
, Qminus
))
2516 f
->output_data
.x
->top_pos
= 0;
2517 window_prompting
|= YNegative
;
2519 else if (CONSP (tem0
) && EQ (XCONS (tem0
)->car
, Qminus
)
2520 && CONSP (XCONS (tem0
)->cdr
)
2521 && INTEGERP (XCONS (XCONS (tem0
)->cdr
)->car
))
2523 f
->output_data
.x
->top_pos
= - XINT (XCONS (XCONS (tem0
)->cdr
)->car
);
2524 window_prompting
|= YNegative
;
2526 else if (CONSP (tem0
) && EQ (XCONS (tem0
)->car
, Qplus
)
2527 && CONSP (XCONS (tem0
)->cdr
)
2528 && INTEGERP (XCONS (XCONS (tem0
)->cdr
)->car
))
2530 f
->output_data
.x
->top_pos
= XINT (XCONS (XCONS (tem0
)->cdr
)->car
);
2532 else if (EQ (tem0
, Qunbound
))
2533 f
->output_data
.x
->top_pos
= 0;
2536 CHECK_NUMBER (tem0
, 0);
2537 f
->output_data
.x
->top_pos
= XINT (tem0
);
2538 if (f
->output_data
.x
->top_pos
< 0)
2539 window_prompting
|= YNegative
;
2542 if (EQ (tem1
, Qminus
))
2544 f
->output_data
.x
->left_pos
= 0;
2545 window_prompting
|= XNegative
;
2547 else if (CONSP (tem1
) && EQ (XCONS (tem1
)->car
, Qminus
)
2548 && CONSP (XCONS (tem1
)->cdr
)
2549 && INTEGERP (XCONS (XCONS (tem1
)->cdr
)->car
))
2551 f
->output_data
.x
->left_pos
= - XINT (XCONS (XCONS (tem1
)->cdr
)->car
);
2552 window_prompting
|= XNegative
;
2554 else if (CONSP (tem1
) && EQ (XCONS (tem1
)->car
, Qplus
)
2555 && CONSP (XCONS (tem1
)->cdr
)
2556 && INTEGERP (XCONS (XCONS (tem1
)->cdr
)->car
))
2558 f
->output_data
.x
->left_pos
= XINT (XCONS (XCONS (tem1
)->cdr
)->car
);
2560 else if (EQ (tem1
, Qunbound
))
2561 f
->output_data
.x
->left_pos
= 0;
2564 CHECK_NUMBER (tem1
, 0);
2565 f
->output_data
.x
->left_pos
= XINT (tem1
);
2566 if (f
->output_data
.x
->left_pos
< 0)
2567 window_prompting
|= XNegative
;
2570 if (!NILP (tem2
) && ! EQ (tem2
, Qunbound
))
2571 window_prompting
|= USPosition
;
2573 window_prompting
|= PPosition
;
2576 return window_prompting
;
2579 #if !defined (HAVE_X11R4) && !defined (HAVE_XSETWMPROTOCOLS)
2582 XSetWMProtocols (dpy
, w
, protocols
, count
)
2589 prop
= XInternAtom (dpy
, "WM_PROTOCOLS", False
);
2590 if (prop
== None
) return False
;
2591 XChangeProperty (dpy
, w
, prop
, XA_ATOM
, 32, PropModeReplace
,
2592 (unsigned char *) protocols
, count
);
2595 #endif /* not HAVE_X11R4 && not HAVE_XSETWMPROTOCOLS */
2597 #ifdef USE_X_TOOLKIT
2599 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
2600 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
2601 already be present because of the toolkit (Motif adds some of them,
2602 for example, but Xt doesn't). */
2605 hack_wm_protocols (f
, widget
)
2609 Display
*dpy
= XtDisplay (widget
);
2610 Window w
= XtWindow (widget
);
2611 int need_delete
= 1;
2617 Atom type
, *atoms
= 0;
2619 unsigned long nitems
= 0;
2620 unsigned long bytes_after
;
2622 if ((XGetWindowProperty (dpy
, w
,
2623 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2624 (long)0, (long)100, False
, XA_ATOM
,
2625 &type
, &format
, &nitems
, &bytes_after
,
2626 (unsigned char **) &atoms
)
2628 && format
== 32 && type
== XA_ATOM
)
2632 if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
)
2634 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
)
2636 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
)
2639 if (atoms
) XFree ((char *) atoms
);
2645 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2647 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
;
2649 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2651 XChangeProperty (dpy
, w
, FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2652 XA_ATOM
, 32, PropModeAppend
,
2653 (unsigned char *) props
, count
);
2659 #ifdef USE_X_TOOLKIT
2661 /* Create and set up the X widget for frame F. */
2664 x_window (f
, window_prompting
, minibuffer_only
)
2666 long window_prompting
;
2667 int minibuffer_only
;
2669 XClassHint class_hints
;
2670 XSetWindowAttributes attributes
;
2671 unsigned long attribute_mask
;
2673 Widget shell_widget
;
2675 Widget frame_widget
;
2681 /* Use the resource name as the top-level widget name
2682 for looking up resources. Make a non-Lisp copy
2683 for the window manager, so GC relocation won't bother it.
2685 Elsewhere we specify the window name for the window manager. */
2688 char *str
= (char *) XSTRING (Vx_resource_name
)->data
;
2689 f
->namebuf
= (char *) xmalloc (strlen (str
) + 1);
2690 strcpy (f
->namebuf
, str
);
2694 XtSetArg (al
[ac
], XtNallowShellResize
, 1); ac
++;
2695 XtSetArg (al
[ac
], XtNinput
, 1); ac
++;
2696 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2697 XtSetArg (al
[ac
], XtNborderWidth
, f
->output_data
.x
->border_width
); ac
++;
2698 shell_widget
= XtAppCreateShell (f
->namebuf
, EMACS_CLASS
,
2699 applicationShellWidgetClass
,
2700 FRAME_X_DISPLAY (f
), al
, ac
);
2702 f
->output_data
.x
->widget
= shell_widget
;
2703 /* maybe_set_screen_title_format (shell_widget); */
2705 pane_widget
= lw_create_widget ("main", "pane", widget_id_tick
++,
2706 (widget_value
*) NULL
,
2707 shell_widget
, False
,
2710 (lw_callback
) NULL
);
2712 f
->output_data
.x
->column_widget
= pane_widget
;
2714 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2715 the emacs screen when changing menubar. This reduces flickering. */
2718 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2719 XtSetArg (al
[ac
], XtNshowGrip
, 0); ac
++;
2720 XtSetArg (al
[ac
], XtNallowResize
, 1); ac
++;
2721 XtSetArg (al
[ac
], XtNresizeToPreferred
, 1); ac
++;
2722 XtSetArg (al
[ac
], XtNemacsFrame
, f
); ac
++;
2723 frame_widget
= XtCreateWidget (f
->namebuf
,
2725 pane_widget
, al
, ac
);
2727 f
->output_data
.x
->edit_widget
= frame_widget
;
2729 XtManageChild (frame_widget
);
2731 /* Do some needed geometry management. */
2734 char *tem
, shell_position
[32];
2737 int extra_borders
= 0;
2739 = (f
->output_data
.x
->menubar_widget
2740 ? (f
->output_data
.x
->menubar_widget
->core
.height
2741 + f
->output_data
.x
->menubar_widget
->core
.border_width
)
2743 extern char *lwlib_toolkit_type
;
2745 #if 0 /* Experimentally, we now get the right results
2746 for -geometry -0-0 without this. 24 Aug 96, rms. */
2747 if (FRAME_EXTERNAL_MENU_BAR (f
))
2750 XtVaGetValues (pane_widget
, XtNinternalBorderWidth
, &ibw
, NULL
);
2751 menubar_size
+= ibw
;
2755 f
->output_data
.x
->menubar_height
= menubar_size
;
2758 /* Motif seems to need this amount added to the sizes
2759 specified for the shell widget. The Athena/Lucid widgets don't.
2760 Both conclusions reached experimentally. -- rms. */
2761 XtVaGetValues (f
->output_data
.x
->edit_widget
, XtNinternalBorderWidth
,
2762 &extra_borders
, NULL
);
2766 /* Convert our geometry parameters into a geometry string
2768 Note that we do not specify here whether the position
2769 is a user-specified or program-specified one.
2770 We pass that information later, in x_wm_set_size_hints. */
2772 int left
= f
->output_data
.x
->left_pos
;
2773 int xneg
= window_prompting
& XNegative
;
2774 int top
= f
->output_data
.x
->top_pos
;
2775 int yneg
= window_prompting
& YNegative
;
2781 if (window_prompting
& USPosition
)
2782 sprintf (shell_position
, "=%dx%d%c%d%c%d",
2783 PIXEL_WIDTH (f
) + extra_borders
,
2784 PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
,
2785 (xneg
? '-' : '+'), left
,
2786 (yneg
? '-' : '+'), top
);
2788 sprintf (shell_position
, "=%dx%d",
2789 PIXEL_WIDTH (f
) + extra_borders
,
2790 PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
);
2793 len
= strlen (shell_position
) + 1;
2794 /* We don't free this because we don't know whether
2795 it is safe to free it while the frame exists.
2796 It isn't worth the trouble of arranging to free it
2797 when the frame is deleted. */
2798 tem
= (char *) xmalloc (len
);
2799 strncpy (tem
, shell_position
, len
);
2800 XtSetArg (al
[ac
], XtNgeometry
, tem
); ac
++;
2801 XtSetValues (shell_widget
, al
, ac
);
2804 XtManageChild (pane_widget
);
2805 XtRealizeWidget (shell_widget
);
2807 FRAME_X_WINDOW (f
) = XtWindow (frame_widget
);
2809 validate_x_resource_name ();
2811 class_hints
.res_name
= (char *) XSTRING (Vx_resource_name
)->data
;
2812 class_hints
.res_class
= (char *) XSTRING (Vx_resource_class
)->data
;
2813 XSetClassHint (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
), &class_hints
);
2816 #ifndef X_I18N_INHIBITED
2821 xim
= XOpenIM (FRAME_X_DISPLAY (f
), NULL
, NULL
, NULL
);
2825 xic
= XCreateIC (xim
,
2826 XNInputStyle
, XIMPreeditNothing
| XIMStatusNothing
,
2827 XNClientWindow
, FRAME_X_WINDOW(f
),
2828 XNFocusWindow
, FRAME_X_WINDOW(f
),
2837 FRAME_XIM (f
) = xim
;
2838 FRAME_XIC (f
) = xic
;
2840 #else /* X_I18N_INHIBITED */
2843 #endif /* X_I18N_INHIBITED */
2844 #endif /* HAVE_X_I18N */
2846 f
->output_data
.x
->wm_hints
.input
= True
;
2847 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2848 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2849 &f
->output_data
.x
->wm_hints
);
2851 hack_wm_protocols (f
, shell_widget
);
2854 XtAddEventHandler (shell_widget
, 0, True
, _XEditResCheckMessages
, 0);
2857 /* Do a stupid property change to force the server to generate a
2858 propertyNotify event so that the event_stream server timestamp will
2859 be initialized to something relevant to the time we created the window.
2861 XChangeProperty (XtDisplay (frame_widget
), XtWindow (frame_widget
),
2862 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2863 XA_ATOM
, 32, PropModeAppend
,
2864 (unsigned char*) NULL
, 0);
2866 /* Make all the standard events reach the Emacs frame. */
2867 attributes
.event_mask
= STANDARD_EVENT_SET
;
2868 attribute_mask
= CWEventMask
;
2869 XChangeWindowAttributes (XtDisplay (shell_widget
), XtWindow (shell_widget
),
2870 attribute_mask
, &attributes
);
2872 XtMapWidget (frame_widget
);
2874 /* x_set_name normally ignores requests to set the name if the
2875 requested name is the same as the current name. This is the one
2876 place where that assumption isn't correct; f->name is set, but
2877 the X server hasn't been told. */
2880 int explicit = f
->explicit_name
;
2882 f
->explicit_name
= 0;
2885 x_set_name (f
, name
, explicit);
2888 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2889 f
->output_data
.x
->text_cursor
);
2893 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
2894 initialize_frame_menubar (f
);
2895 lw_set_main_areas (pane_widget
, f
->output_data
.x
->menubar_widget
, frame_widget
);
2897 if (FRAME_X_WINDOW (f
) == 0)
2898 error ("Unable to create window");
2901 #else /* not USE_X_TOOLKIT */
2903 /* Create and set up the X window for frame F. */
2909 XClassHint class_hints
;
2910 XSetWindowAttributes attributes
;
2911 unsigned long attribute_mask
;
2913 attributes
.background_pixel
= f
->output_data
.x
->background_pixel
;
2914 attributes
.border_pixel
= f
->output_data
.x
->border_pixel
;
2915 attributes
.bit_gravity
= StaticGravity
;
2916 attributes
.backing_store
= NotUseful
;
2917 attributes
.save_under
= True
;
2918 attributes
.event_mask
= STANDARD_EVENT_SET
;
2919 attribute_mask
= (CWBackPixel
| CWBorderPixel
| CWBitGravity
2921 | CWBackingStore
| CWSaveUnder
2927 = XCreateWindow (FRAME_X_DISPLAY (f
),
2928 f
->output_data
.x
->parent_desc
,
2929 f
->output_data
.x
->left_pos
,
2930 f
->output_data
.x
->top_pos
,
2931 PIXEL_WIDTH (f
), PIXEL_HEIGHT (f
),
2932 f
->output_data
.x
->border_width
,
2933 CopyFromParent
, /* depth */
2934 InputOutput
, /* class */
2935 FRAME_X_DISPLAY_INFO (f
)->visual
,
2936 attribute_mask
, &attributes
);
2938 #ifndef X_I18N_INHIBITED
2943 xim
= XOpenIM (FRAME_X_DISPLAY(f
), NULL
, NULL
, NULL
);
2947 xic
= XCreateIC (xim
,
2948 XNInputStyle
, XIMPreeditNothing
| XIMStatusNothing
,
2949 XNClientWindow
, FRAME_X_WINDOW(f
),
2950 XNFocusWindow
, FRAME_X_WINDOW(f
),
2960 FRAME_XIM (f
) = xim
;
2961 FRAME_XIC (f
) = xic
;
2963 #else /* X_I18N_INHIBITED */
2966 #endif /* X_I18N_INHIBITED */
2967 #endif /* HAVE_X_I18N */
2969 validate_x_resource_name ();
2971 class_hints
.res_name
= (char *) XSTRING (Vx_resource_name
)->data
;
2972 class_hints
.res_class
= (char *) XSTRING (Vx_resource_class
)->data
;
2973 XSetClassHint (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &class_hints
);
2975 /* The menubar is part of the ordinary display;
2976 it does not count in addition to the height of the window. */
2977 f
->output_data
.x
->menubar_height
= 0;
2979 /* This indicates that we use the "Passive Input" input model.
2980 Unless we do this, we don't get the Focus{In,Out} events that we
2981 need to draw the cursor correctly. Accursed bureaucrats.
2982 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2984 f
->output_data
.x
->wm_hints
.input
= True
;
2985 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2986 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2987 &f
->output_data
.x
->wm_hints
);
2988 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
2990 /* Request "save yourself" and "delete window" commands from wm. */
2993 protocols
[0] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2994 protocols
[1] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2995 XSetWMProtocols (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), protocols
, 2);
2998 /* x_set_name normally ignores requests to set the name if the
2999 requested name is the same as the current name. This is the one
3000 place where that assumption isn't correct; f->name is set, but
3001 the X server hasn't been told. */
3004 int explicit = f
->explicit_name
;
3006 f
->explicit_name
= 0;
3009 x_set_name (f
, name
, explicit);
3012 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3013 f
->output_data
.x
->text_cursor
);
3017 if (FRAME_X_WINDOW (f
) == 0)
3018 error ("Unable to create window");
3021 #endif /* not USE_X_TOOLKIT */
3023 /* Handle the icon stuff for this window. Perhaps later we might
3024 want an x_set_icon_position which can be called interactively as
3032 Lisp_Object icon_x
, icon_y
;
3033 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3035 /* Set the position of the icon. Note that twm groups all
3036 icons in an icon window. */
3037 icon_x
= x_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, number
);
3038 icon_y
= x_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, number
);
3039 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
3041 CHECK_NUMBER (icon_x
, 0);
3042 CHECK_NUMBER (icon_y
, 0);
3044 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
3045 error ("Both left and top icon corners of icon must be specified");
3049 if (! EQ (icon_x
, Qunbound
))
3050 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
3052 /* Start up iconic or window? */
3053 x_wm_set_window_state
3054 (f
, (EQ (x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0, symbol
), Qicon
)
3058 x_text_icon (f
, (char *) XSTRING ((!NILP (f
->icon_name
)
3065 /* Make the GC's needed for this window, setting the
3066 background, border and mouse colors; also create the
3067 mouse cursor and the gray border tile. */
3069 static char cursor_bits
[] =
3071 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3072 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3073 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3074 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3081 XGCValues gc_values
;
3087 /* Create the GC's of this frame.
3088 Note that many default values are used. */
3091 gc_values
.font
= f
->output_data
.x
->font
->fid
;
3092 gc_values
.foreground
= f
->output_data
.x
->foreground_pixel
;
3093 gc_values
.background
= f
->output_data
.x
->background_pixel
;
3094 gc_values
.line_width
= 0; /* Means 1 using fast algorithm. */
3095 f
->output_data
.x
->normal_gc
= XCreateGC (FRAME_X_DISPLAY (f
),
3097 GCLineWidth
| GCFont
3098 | GCForeground
| GCBackground
,
3101 /* Reverse video style. */
3102 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
3103 gc_values
.background
= f
->output_data
.x
->foreground_pixel
;
3104 f
->output_data
.x
->reverse_gc
= XCreateGC (FRAME_X_DISPLAY (f
),
3106 GCFont
| GCForeground
| GCBackground
3110 /* Cursor has cursor-color background, background-color foreground. */
3111 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
3112 gc_values
.background
= f
->output_data
.x
->cursor_pixel
;
3113 gc_values
.fill_style
= FillOpaqueStippled
;
3115 = XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
3116 FRAME_X_DISPLAY_INFO (f
)->root_window
,
3117 cursor_bits
, 16, 16);
3118 f
->output_data
.x
->cursor_gc
3119 = XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3120 (GCFont
| GCForeground
| GCBackground
3121 | GCFillStyle
| GCStipple
| GCLineWidth
),
3124 /* Create the gray border tile used when the pointer is not in
3125 the frame. Since this depends on the frame's pixel values,
3126 this must be done on a per-frame basis. */
3127 f
->output_data
.x
->border_tile
3128 = (XCreatePixmapFromBitmapData
3129 (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
3130 gray_bits
, gray_width
, gray_height
,
3131 f
->output_data
.x
->foreground_pixel
,
3132 f
->output_data
.x
->background_pixel
,
3133 DefaultDepth (FRAME_X_DISPLAY (f
),
3134 XScreenNumberOfScreen (FRAME_X_SCREEN (f
)))));
3139 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
3141 "Make a new X window, which is called a \"frame\" in Emacs terms.\n\
3142 Returns an Emacs frame object.\n\
3143 ALIST is an alist of frame parameters.\n\
3144 If the parameters specify that the frame should not have a minibuffer,\n\
3145 and do not specify a specific minibuffer window to use,\n\
3146 then `default-minibuffer-frame' must be a frame whose minibuffer can\n\
3147 be shared by the new frame.\n\
3149 This function is an internal primitive--use `make-frame' instead.")
3154 Lisp_Object frame
, tem
;
3156 int minibuffer_only
= 0;
3157 long window_prompting
= 0;
3159 int count
= specpdl_ptr
- specpdl
;
3160 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
3161 Lisp_Object display
;
3162 struct x_display_info
*dpyinfo
;
3168 /* Use this general default value to start with
3169 until we know if this frame has a specified name. */
3170 Vx_resource_name
= Vinvocation_name
;
3172 display
= x_get_arg (dpyinfo
, parms
, Qdisplay
, 0, 0, string
);
3173 if (EQ (display
, Qunbound
))
3175 dpyinfo
= check_x_display_info (display
);
3177 kb
= dpyinfo
->kboard
;
3179 kb
= &the_only_kboard
;
3182 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", string
);
3184 && ! EQ (name
, Qunbound
)
3186 error ("Invalid frame name--not a string or nil");
3189 Vx_resource_name
= name
;
3191 /* See if parent window is specified. */
3192 parent
= x_get_arg (dpyinfo
, parms
, Qparent_id
, NULL
, NULL
, number
);
3193 if (EQ (parent
, Qunbound
))
3195 if (! NILP (parent
))
3196 CHECK_NUMBER (parent
, 0);
3198 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
3199 /* No need to protect DISPLAY because that's not used after passing
3200 it to make_frame_without_minibuffer. */
3202 GCPRO4 (parms
, parent
, name
, frame
);
3203 tem
= x_get_arg (dpyinfo
, parms
, Qminibuffer
, "minibuffer", "Minibuffer", symbol
);
3204 if (EQ (tem
, Qnone
) || NILP (tem
))
3205 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
3206 else if (EQ (tem
, Qonly
))
3208 f
= make_minibuffer_frame ();
3209 minibuffer_only
= 1;
3211 else if (WINDOWP (tem
))
3212 f
= make_frame_without_minibuffer (tem
, kb
, display
);
3216 XSETFRAME (frame
, f
);
3218 /* Note that X Windows does support scroll bars. */
3219 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
3221 f
->output_method
= output_x_window
;
3222 f
->output_data
.x
= (struct x_output
*) xmalloc (sizeof (struct x_output
));
3223 bzero (f
->output_data
.x
, sizeof (struct x_output
));
3224 f
->output_data
.x
->icon_bitmap
= -1;
3227 = x_get_arg (dpyinfo
, parms
, Qicon_name
, "iconName", "Title", string
);
3228 if (! STRINGP (f
->icon_name
))
3229 f
->icon_name
= Qnil
;
3231 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
3233 FRAME_KBOARD (f
) = kb
;
3236 /* Specify the parent under which to make this X window. */
3240 f
->output_data
.x
->parent_desc
= (Window
) XINT (parent
);
3241 f
->output_data
.x
->explicit_parent
= 1;
3245 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3246 f
->output_data
.x
->explicit_parent
= 0;
3249 /* Note that the frame has no physical cursor right now. */
3250 f
->phys_cursor_x
= -1;
3252 /* Set the name; the functions to which we pass f expect the name to
3254 if (EQ (name
, Qunbound
) || NILP (name
))
3256 f
->name
= build_string (dpyinfo
->x_id_name
);
3257 f
->explicit_name
= 0;
3262 f
->explicit_name
= 1;
3263 /* use the frame's title when getting resources for this frame. */
3264 specbind (Qx_resource_name
, name
);
3267 /* Create fontsets from `global_fontset_alist' before handling fonts. */
3268 for (tem
= Vglobal_fontset_alist
; CONSP (tem
); tem
= XCONS (tem
)->cdr
)
3269 fs_register_fontset (f
, XCONS (tem
)->car
);
3271 /* Extract the window parameters from the supplied values
3272 that are needed to determine window geometry. */
3276 if (! STRINGP (font
))
3277 font
= x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", string
);
3279 /* First, try whatever font the caller has specified. */
3282 tem
= Fquery_fontset (font
);
3284 font
= x_new_fontset (f
, XSTRING (tem
)->data
);
3286 font
= x_new_font (f
, XSTRING (font
)->data
);
3288 /* Try out a font which we hope has bold and italic variations. */
3289 if (!STRINGP (font
))
3290 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3291 if (! STRINGP (font
))
3292 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3293 if (! STRINGP (font
))
3294 /* This was formerly the first thing tried, but it finds too many fonts
3295 and takes too long. */
3296 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
3297 /* If those didn't work, look for something which will at least work. */
3298 if (! STRINGP (font
))
3299 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
3301 if (! STRINGP (font
))
3302 font
= build_string ("fixed");
3304 x_default_parameter (f
, parms
, Qfont
, font
,
3305 "font", "Font", string
);
3309 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
3310 whereby it fails to get any font. */
3311 xlwmenu_default_font
= f
->output_data
.x
->font
;
3314 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
3315 "borderwidth", "BorderWidth", number
);
3316 /* This defaults to 2 in order to match xterm. We recognize either
3317 internalBorderWidth or internalBorder (which is what xterm calls
3319 if (NILP (Fassq (Qinternal_border_width
, parms
)))
3323 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
3324 "internalBorder", "internalBorder", number
);
3325 if (! EQ (value
, Qunbound
))
3326 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
3329 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
3330 "internalBorderWidth", "internalBorderWidth", number
);
3331 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qleft
,
3332 "verticalScrollBars", "ScrollBars", boolean
);
3334 /* Also do the stuff which must be set before the window exists. */
3335 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
3336 "foreground", "Foreground", string
);
3337 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
3338 "background", "Background", string
);
3339 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
3340 "pointerColor", "Foreground", string
);
3341 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
3342 "cursorColor", "Foreground", string
);
3343 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
3344 "borderColor", "BorderColor", string
);
3346 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
3347 "menuBar", "MenuBar", number
);
3348 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
3349 "scrollBarWidth", "ScrollBarWidth", number
);
3350 x_default_parameter (f
, parms
, Qbuffer_predicate
, Qnil
,
3351 "bufferPredicate", "BufferPredicate", symbol
);
3352 x_default_parameter (f
, parms
, Qtitle
, Qnil
,
3353 "title", "Title", string
);
3355 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3356 window_prompting
= x_figure_window_size (f
, parms
);
3358 if (window_prompting
& XNegative
)
3360 if (window_prompting
& YNegative
)
3361 f
->output_data
.x
->win_gravity
= SouthEastGravity
;
3363 f
->output_data
.x
->win_gravity
= NorthEastGravity
;
3367 if (window_prompting
& YNegative
)
3368 f
->output_data
.x
->win_gravity
= SouthWestGravity
;
3370 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
3373 f
->output_data
.x
->size_hint_flags
= window_prompting
;
3375 #ifdef USE_X_TOOLKIT
3376 x_window (f
, window_prompting
, minibuffer_only
);
3382 init_frame_faces (f
);
3384 /* We need to do this after creating the X window, so that the
3385 icon-creation functions can say whose icon they're describing. */
3386 x_default_parameter (f
, parms
, Qicon_type
, Qnil
,
3387 "bitmapIcon", "BitmapIcon", symbol
);
3389 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
3390 "autoRaise", "AutoRaiseLower", boolean
);
3391 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
3392 "autoLower", "AutoRaiseLower", boolean
);
3393 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
3394 "cursorType", "CursorType", symbol
);
3396 /* Dimensions, especially f->height, must be done via change_frame_size.
3397 Change will not be effected unless different from the current
3402 SET_FRAME_WIDTH (f
, 0);
3403 change_frame_size (f
, height
, width
, 1, 0);
3405 /* Tell the server what size and position, etc, we want,
3406 and how badly we want them. */
3408 x_wm_set_size_hint (f
, window_prompting
, 0);
3411 tem
= x_get_arg (dpyinfo
, parms
, Qunsplittable
, 0, 0, boolean
);
3412 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
3416 /* It is now ok to make the frame official
3417 even if we get an error below.
3418 And the frame needs to be on Vframe_list
3419 or making it visible won't work. */
3420 Vframe_list
= Fcons (frame
, Vframe_list
);
3422 /* Now that the frame is official, it counts as a reference to
3424 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
3426 /* Make the window appear on the frame and enable display,
3427 unless the caller says not to. However, with explicit parent,
3428 Emacs cannot control visibility, so don't try. */
3429 if (! f
->output_data
.x
->explicit_parent
)
3431 Lisp_Object visibility
;
3433 visibility
= x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0, symbol
);
3434 if (EQ (visibility
, Qunbound
))
3437 if (EQ (visibility
, Qicon
))
3438 x_iconify_frame (f
);
3439 else if (! NILP (visibility
))
3440 x_make_frame_visible (f
);
3442 /* Must have been Qnil. */
3446 return unbind_to (count
, frame
);
3449 /* FRAME is used only to get a handle on the X display. We don't pass the
3450 display info directly because we're called from frame.c, which doesn't
3451 know about that structure. */
3454 x_get_focus_frame (frame
)
3455 struct frame
*frame
;
3457 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (frame
);
3459 if (! dpyinfo
->x_focus_frame
)
3462 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
3467 #include "x-list-font.c"
3469 DEFUN ("x-list-fonts", Fx_list_fonts
, Sx_list_fonts
, 1, 4, 0,
3470 "Return a list of the names of available fonts matching PATTERN.\n\
3471 If optional arguments FACE and FRAME are specified, return only fonts\n\
3472 the same size as FACE on FRAME.\n\
3474 PATTERN is a string, perhaps with wildcard characters;\n\
3475 the * character matches any substring, and\n\
3476 the ? character matches any single character.\n\
3477 PATTERN is case-insensitive.\n\
3478 FACE is a face name--a symbol.\n\
3480 The return value is a list of strings, suitable as arguments to\n\
3483 Fonts Emacs can't use (i.e. proportional fonts) may or may not be excluded\n\
3484 even if they match PATTERN and FACE.\n\
3486 The optional fourth argument MAXIMUM sets a limit on how many\n\
3487 fonts to match. The first MAXIMUM fonts are reported.")
3488 (pattern
, face
, frame
, maximum
)
3489 Lisp_Object pattern
, face
, frame
, maximum
;
3493 #ifndef BROKEN_XLISTFONTSWITHINFO
3496 XFontStruct
*size_ref
;
3504 CHECK_STRING (pattern
, 0);
3506 CHECK_SYMBOL (face
, 1);
3512 CHECK_NATNUM (maximum
, 0);
3513 maxnames
= XINT (maximum
);
3516 f
= check_x_frame (frame
);
3518 /* Determine the width standard for comparison with the fonts we find. */
3526 /* Don't die if we get called with a terminal frame. */
3527 if (! FRAME_X_P (f
))
3528 error ("Non-X frame used in `x-list-fonts'");
3530 face_id
= face_name_id_number (f
, face
);
3532 if (face_id
< 0 || face_id
>= FRAME_N_PARAM_FACES (f
)
3533 || FRAME_PARAM_FACES (f
) [face_id
] == 0)
3534 size_ref
= f
->output_data
.x
->font
;
3537 size_ref
= FRAME_PARAM_FACES (f
) [face_id
]->font
;
3538 if (size_ref
== (XFontStruct
*) (~0))
3539 size_ref
= f
->output_data
.x
->font
;
3543 /* See if we cached the result for this particular query. */
3544 key
= Fcons (pattern
, maximum
);
3546 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
);
3548 /* We have info in the cache for this PATTERN. */
3551 Lisp_Object tem
, newlist
;
3553 /* We have info about this pattern. */
3554 list
= XCONS (list
)->cdr
;
3561 /* Filter the cached info and return just the fonts that match FACE. */
3563 for (tem
= list
; CONSP (tem
); tem
= XCONS (tem
)->cdr
)
3565 XFontStruct
*thisinfo
;
3567 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
3569 thisinfo
= XLoadQueryFont (FRAME_X_DISPLAY (f
),
3570 XSTRING (XCONS (tem
)->car
)->data
);
3572 x_check_errors (FRAME_X_DISPLAY (f
), "XLoadQueryFont failure: %s");
3573 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
3575 if (thisinfo
&& same_size_fonts (thisinfo
, size_ref
))
3576 newlist
= Fcons (XCONS (tem
)->car
, newlist
);
3579 XFreeFont (FRAME_X_DISPLAY (f
), thisinfo
);
3589 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
3591 /* Solaris 2.3 has a bug in XListFontsWithInfo. */
3592 #ifndef BROKEN_XLISTFONTSWITHINFO
3594 names
= XListFontsWithInfo (FRAME_X_DISPLAY (f
),
3595 XSTRING (pattern
)->data
,
3597 &num_fonts
, /* count_return */
3598 &info
); /* info_return */
3601 names
= XListFonts (FRAME_X_DISPLAY (f
),
3602 XSTRING (pattern
)->data
,
3604 &num_fonts
); /* count_return */
3606 x_check_errors (FRAME_X_DISPLAY (f
), "XListFonts failure: %s");
3607 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
3616 Lisp_Object full_list
;
3618 /* Make a list of all the fonts we got back.
3619 Store that in the font cache for the display. */
3621 for (i
= 0; i
< num_fonts
; i
++)
3622 full_list
= Fcons (build_string (names
[i
]), full_list
);
3623 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
3624 = Fcons (Fcons (key
, full_list
),
3625 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
);
3627 /* Make a list of the fonts that have the right width. */
3629 for (i
= 0; i
< num_fonts
; i
++)
3637 #ifdef BROKEN_XLISTFONTSWITHINFO
3638 XFontStruct
*thisinfo
;
3642 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
3643 thisinfo
= XLoadQueryFont (FRAME_X_DISPLAY (f
), names
[i
]);
3644 x_check_errors (FRAME_X_DISPLAY (f
),
3645 "XLoadQueryFont failure: %s");
3646 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
3650 keeper
= thisinfo
&& same_size_fonts (thisinfo
, size_ref
);
3652 if (thisinfo
&& ! keeper
)
3653 XFreeFont (FRAME_X_DISPLAY (f
), thisinfo
);
3655 XFreeFontInfo (NULL
, thisinfo
, 1);
3658 keeper
= same_size_fonts (&info
[i
], size_ref
);
3662 list
= Fcons (build_string (names
[i
]), list
);
3664 list
= Fnreverse (list
);
3667 #ifndef BROKEN_XLISTFONTSWITHINFO
3669 XFreeFontInfo (names
, info
, num_fonts
);
3672 XFreeFontNames (names
);
3681 DEFUN ("x-color-defined-p", Fx_color_defined_p
, Sx_color_defined_p
, 1, 2, 0,
3682 "Return non-nil if color COLOR is supported on frame FRAME.\n\
3683 If FRAME is omitted or nil, use the selected frame.")
3685 Lisp_Object color
, frame
;
3688 FRAME_PTR f
= check_x_frame (frame
);
3690 CHECK_STRING (color
, 1);
3692 if (defined_color (f
, XSTRING (color
)->data
, &foo
, 0))
3698 DEFUN ("x-color-values", Fx_color_values
, Sx_color_values
, 1, 2, 0,
3699 "Return a description of the color named COLOR on frame FRAME.\n\
3700 The value is a list of integer RGB values--(RED GREEN BLUE).\n\
3701 These values appear to range from 0 to 65280 or 65535, depending\n\
3702 on the system; white is (65280 65280 65280) or (65535 65535 65535).\n\
3703 If FRAME is omitted or nil, use the selected frame.")
3705 Lisp_Object color
, frame
;
3708 FRAME_PTR f
= check_x_frame (frame
);
3710 CHECK_STRING (color
, 1);
3712 if (defined_color (f
, XSTRING (color
)->data
, &foo
, 0))
3716 rgb
[0] = make_number (foo
.red
);
3717 rgb
[1] = make_number (foo
.green
);
3718 rgb
[2] = make_number (foo
.blue
);
3719 return Flist (3, rgb
);
3725 DEFUN ("x-display-color-p", Fx_display_color_p
, Sx_display_color_p
, 0, 1, 0,
3726 "Return t if the X display supports color.\n\
3727 The optional argument DISPLAY specifies which display to ask about.\n\
3728 DISPLAY should be either a frame or a display name (a string).\n\
3729 If omitted or nil, that stands for the selected frame's display.")
3731 Lisp_Object display
;
3733 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3735 if (dpyinfo
->n_planes
<= 2)
3738 switch (dpyinfo
->visual
->class)
3751 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
3753 "Return t if the X display supports shades of gray.\n\
3754 Note that color displays do support shades of gray.\n\
3755 The optional argument DISPLAY specifies which display to ask about.\n\
3756 DISPLAY should be either a frame or a display name (a string).\n\
3757 If omitted or nil, that stands for the selected frame's display.")
3759 Lisp_Object display
;
3761 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3763 if (dpyinfo
->n_planes
<= 1)
3766 switch (dpyinfo
->visual
->class)
3781 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
3783 "Returns the width in pixels of the X display DISPLAY.\n\
3784 The optional argument DISPLAY specifies which display to ask about.\n\
3785 DISPLAY should be either a frame or a display name (a string).\n\
3786 If omitted or nil, that stands for the selected frame's display.")
3788 Lisp_Object display
;
3790 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3792 return make_number (dpyinfo
->width
);
3795 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
3796 Sx_display_pixel_height
, 0, 1, 0,
3797 "Returns the height in pixels of the X display DISPLAY.\n\
3798 The optional argument DISPLAY specifies which display to ask about.\n\
3799 DISPLAY should be either a frame or a display name (a string).\n\
3800 If omitted or nil, that stands for the selected frame's display.")
3802 Lisp_Object display
;
3804 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3806 return make_number (dpyinfo
->height
);
3809 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
3811 "Returns the number of bitplanes of the X display DISPLAY.\n\
3812 The optional argument DISPLAY specifies which display to ask about.\n\
3813 DISPLAY should be either a frame or a display name (a string).\n\
3814 If omitted or nil, that stands for the selected frame's display.")
3816 Lisp_Object display
;
3818 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3820 return make_number (dpyinfo
->n_planes
);
3823 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
3825 "Returns the number of color cells of the X display DISPLAY.\n\
3826 The optional argument DISPLAY specifies which display to ask about.\n\
3827 DISPLAY should be either a frame or a display name (a string).\n\
3828 If omitted or nil, that stands for the selected frame's display.")
3830 Lisp_Object display
;
3832 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3834 return make_number (DisplayCells (dpyinfo
->display
,
3835 XScreenNumberOfScreen (dpyinfo
->screen
)));
3838 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
3839 Sx_server_max_request_size
,
3841 "Returns the maximum request size of the X server of display DISPLAY.\n\
3842 The optional argument DISPLAY specifies which display to ask about.\n\
3843 DISPLAY should be either a frame or a display name (a string).\n\
3844 If omitted or nil, that stands for the selected frame's display.")
3846 Lisp_Object display
;
3848 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3850 return make_number (MAXREQUEST (dpyinfo
->display
));
3853 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
3854 "Returns the vendor ID string of the X server of display DISPLAY.\n\
3855 The optional argument DISPLAY specifies which display to ask about.\n\
3856 DISPLAY should be either a frame or a display name (a string).\n\
3857 If omitted or nil, that stands for the selected frame's display.")
3859 Lisp_Object display
;
3861 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3862 char *vendor
= ServerVendor (dpyinfo
->display
);
3864 if (! vendor
) vendor
= "";
3865 return build_string (vendor
);
3868 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
3869 "Returns the version numbers of the X server of display DISPLAY.\n\
3870 The value is a list of three integers: the major and minor\n\
3871 version numbers of the X Protocol in use, and the vendor-specific release\n\
3872 number. See also the function `x-server-vendor'.\n\n\
3873 The optional argument DISPLAY specifies which display to ask about.\n\
3874 DISPLAY should be either a frame or a display name (a string).\n\
3875 If omitted or nil, that stands for the selected frame's display.")
3877 Lisp_Object display
;
3879 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3880 Display
*dpy
= dpyinfo
->display
;
3882 return Fcons (make_number (ProtocolVersion (dpy
)),
3883 Fcons (make_number (ProtocolRevision (dpy
)),
3884 Fcons (make_number (VendorRelease (dpy
)), Qnil
)));
3887 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
3888 "Returns the number of screens on the X server of display DISPLAY.\n\
3889 The optional argument DISPLAY specifies which display to ask about.\n\
3890 DISPLAY should be either a frame or a display name (a string).\n\
3891 If omitted or nil, that stands for the selected frame's display.")
3893 Lisp_Object display
;
3895 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3897 return make_number (ScreenCount (dpyinfo
->display
));
3900 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
3901 "Returns the height in millimeters of the X display DISPLAY.\n\
3902 The optional argument DISPLAY specifies which display to ask about.\n\
3903 DISPLAY should be either a frame or a display name (a string).\n\
3904 If omitted or nil, that stands for the selected frame's display.")
3906 Lisp_Object display
;
3908 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3910 return make_number (HeightMMOfScreen (dpyinfo
->screen
));
3913 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
3914 "Returns the width in millimeters of the X display DISPLAY.\n\
3915 The optional argument DISPLAY specifies which display to ask about.\n\
3916 DISPLAY should be either a frame or a display name (a string).\n\
3917 If omitted or nil, that stands for the selected frame's display.")
3919 Lisp_Object display
;
3921 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3923 return make_number (WidthMMOfScreen (dpyinfo
->screen
));
3926 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
3927 Sx_display_backing_store
, 0, 1, 0,
3928 "Returns an indication of whether X display DISPLAY does backing store.\n\
3929 The value may be `always', `when-mapped', or `not-useful'.\n\
3930 The optional argument DISPLAY specifies which display to ask about.\n\
3931 DISPLAY should be either a frame or a display name (a string).\n\
3932 If omitted or nil, that stands for the selected frame's display.")
3934 Lisp_Object display
;
3936 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3938 switch (DoesBackingStore (dpyinfo
->screen
))
3941 return intern ("always");
3944 return intern ("when-mapped");
3947 return intern ("not-useful");
3950 error ("Strange value for BackingStore parameter of screen");
3954 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
3955 Sx_display_visual_class
, 0, 1, 0,
3956 "Returns the visual class of the X display DISPLAY.\n\
3957 The value is one of the symbols `static-gray', `gray-scale',\n\
3958 `static-color', `pseudo-color', `true-color', or `direct-color'.\n\n\
3959 The optional argument DISPLAY specifies which display to ask about.\n\
3960 DISPLAY should be either a frame or a display name (a string).\n\
3961 If omitted or nil, that stands for the selected frame's display.")
3963 Lisp_Object display
;
3965 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3967 switch (dpyinfo
->visual
->class)
3969 case StaticGray
: return (intern ("static-gray"));
3970 case GrayScale
: return (intern ("gray-scale"));
3971 case StaticColor
: return (intern ("static-color"));
3972 case PseudoColor
: return (intern ("pseudo-color"));
3973 case TrueColor
: return (intern ("true-color"));
3974 case DirectColor
: return (intern ("direct-color"));
3976 error ("Display has an unknown visual class");
3980 DEFUN ("x-display-save-under", Fx_display_save_under
,
3981 Sx_display_save_under
, 0, 1, 0,
3982 "Returns t if the X display DISPLAY supports the save-under feature.\n\
3983 The optional argument DISPLAY specifies which display to ask about.\n\
3984 DISPLAY should be either a frame or a display name (a string).\n\
3985 If omitted or nil, that stands for the selected frame's display.")
3987 Lisp_Object display
;
3989 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3991 if (DoesSaveUnders (dpyinfo
->screen
) == True
)
3999 register struct frame
*f
;
4001 return PIXEL_WIDTH (f
);
4006 register struct frame
*f
;
4008 return PIXEL_HEIGHT (f
);
4013 register struct frame
*f
;
4015 return FONT_WIDTH (f
->output_data
.x
->font
);
4020 register struct frame
*f
;
4022 return f
->output_data
.x
->line_height
;
4026 x_screen_planes (frame
)
4029 return FRAME_X_DISPLAY_INFO (XFRAME (frame
))->n_planes
;
4032 #if 0 /* These no longer seem like the right way to do things. */
4034 /* Draw a rectangle on the frame with left top corner including
4035 the character specified by LEFT_CHAR and TOP_CHAR. The rectangle is
4036 CHARS by LINES wide and long and is the color of the cursor. */
4039 x_rectangle (f
, gc
, left_char
, top_char
, chars
, lines
)
4040 register struct frame
*f
;
4042 register int top_char
, left_char
, chars
, lines
;
4046 int left
= (left_char
* FONT_WIDTH (f
->output_data
.x
->font
)
4047 + f
->output_data
.x
->internal_border_width
);
4048 int top
= (top_char
* f
->output_data
.x
->line_height
4049 + f
->output_data
.x
->internal_border_width
);
4052 width
= FONT_WIDTH (f
->output_data
.x
->font
) / 2;
4054 width
= FONT_WIDTH (f
->output_data
.x
->font
) * chars
;
4056 height
= f
->output_data
.x
->line_height
/ 2;
4058 height
= f
->output_data
.x
->line_height
* lines
;
4060 XDrawRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4061 gc
, left
, top
, width
, height
);
4064 DEFUN ("x-draw-rectangle", Fx_draw_rectangle
, Sx_draw_rectangle
, 5, 5, 0,
4065 "Draw a rectangle on FRAME between coordinates specified by\n\
4066 numbers X0, Y0, X1, Y1 in the cursor pixel.")
4067 (frame
, X0
, Y0
, X1
, Y1
)
4068 register Lisp_Object frame
, X0
, X1
, Y0
, Y1
;
4070 register int x0
, y0
, x1
, y1
, top
, left
, n_chars
, n_lines
;
4072 CHECK_LIVE_FRAME (frame
, 0);
4073 CHECK_NUMBER (X0
, 0);
4074 CHECK_NUMBER (Y0
, 1);
4075 CHECK_NUMBER (X1
, 2);
4076 CHECK_NUMBER (Y1
, 3);
4086 n_lines
= y1
- y0
+ 1;
4091 n_lines
= y0
- y1
+ 1;
4097 n_chars
= x1
- x0
+ 1;
4102 n_chars
= x0
- x1
+ 1;
4106 x_rectangle (XFRAME (frame
), XFRAME (frame
)->output_data
.x
->cursor_gc
,
4107 left
, top
, n_chars
, n_lines
);
4113 DEFUN ("x-erase-rectangle", Fx_erase_rectangle
, Sx_erase_rectangle
, 5, 5, 0,
4114 "Draw a rectangle drawn on FRAME between coordinates\n\
4115 X0, Y0, X1, Y1 in the regular background-pixel.")
4116 (frame
, X0
, Y0
, X1
, Y1
)
4117 register Lisp_Object frame
, X0
, Y0
, X1
, Y1
;
4119 register int x0
, y0
, x1
, y1
, top
, left
, n_chars
, n_lines
;
4121 CHECK_LIVE_FRAME (frame
, 0);
4122 CHECK_NUMBER (X0
, 0);
4123 CHECK_NUMBER (Y0
, 1);
4124 CHECK_NUMBER (X1
, 2);
4125 CHECK_NUMBER (Y1
, 3);
4135 n_lines
= y1
- y0
+ 1;
4140 n_lines
= y0
- y1
+ 1;
4146 n_chars
= x1
- x0
+ 1;
4151 n_chars
= x0
- x1
+ 1;
4155 x_rectangle (XFRAME (frame
), XFRAME (frame
)->output_data
.x
->reverse_gc
,
4156 left
, top
, n_chars
, n_lines
);
4162 /* Draw lines around the text region beginning at the character position
4163 TOP_X, TOP_Y and ending at BOTTOM_X and BOTTOM_Y. GC specifies the
4164 pixel and line characteristics. */
4166 #define line_len(line) (FRAME_CURRENT_GLYPHS (f)->used[(line)])
4169 outline_region (f
, gc
, top_x
, top_y
, bottom_x
, bottom_y
)
4170 register struct frame
*f
;
4172 int top_x
, top_y
, bottom_x
, bottom_y
;
4174 register int ibw
= f
->output_data
.x
->internal_border_width
;
4175 register int font_w
= FONT_WIDTH (f
->output_data
.x
->font
);
4176 register int font_h
= f
->output_data
.x
->line_height
;
4178 int x
= line_len (y
);
4179 XPoint
*pixel_points
4180 = (XPoint
*) alloca (((bottom_y
- top_y
+ 2) * 4) * sizeof (XPoint
));
4181 register XPoint
*this_point
= pixel_points
;
4183 /* Do the horizontal top line/lines */
4186 this_point
->x
= ibw
;
4187 this_point
->y
= ibw
+ (font_h
* top_y
);
4190 this_point
->x
= ibw
+ (font_w
/ 2); /* Half-size for newline chars. */
4192 this_point
->x
= ibw
+ (font_w
* x
);
4193 this_point
->y
= (this_point
- 1)->y
;
4197 this_point
->x
= ibw
;
4198 this_point
->y
= ibw
+ (font_h
* (top_y
+ 1));
4200 this_point
->x
= ibw
+ (font_w
* top_x
);
4201 this_point
->y
= (this_point
- 1)->y
;
4203 this_point
->x
= (this_point
- 1)->x
;
4204 this_point
->y
= ibw
+ (font_h
* top_y
);
4206 this_point
->x
= ibw
+ (font_w
* x
);
4207 this_point
->y
= (this_point
- 1)->y
;
4210 /* Now do the right side. */
4211 while (y
< bottom_y
)
4212 { /* Right vertical edge */
4214 this_point
->x
= (this_point
- 1)->x
;
4215 this_point
->y
= ibw
+ (font_h
* (y
+ 1));
4218 y
++; /* Horizontal connection to next line */
4221 this_point
->x
= ibw
+ (font_w
/ 2);
4223 this_point
->x
= ibw
+ (font_w
* x
);
4225 this_point
->y
= (this_point
- 1)->y
;
4228 /* Now do the bottom and connect to the top left point. */
4229 this_point
->x
= ibw
+ (font_w
* (bottom_x
+ 1));
4232 this_point
->x
= (this_point
- 1)->x
;
4233 this_point
->y
= ibw
+ (font_h
* (bottom_y
+ 1));
4235 this_point
->x
= ibw
;
4236 this_point
->y
= (this_point
- 1)->y
;
4238 this_point
->x
= pixel_points
->x
;
4239 this_point
->y
= pixel_points
->y
;
4241 XDrawLines (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4243 (this_point
- pixel_points
+ 1), CoordModeOrigin
);
4246 DEFUN ("x-contour-region", Fx_contour_region
, Sx_contour_region
, 1, 1, 0,
4247 "Highlight the region between point and the character under the mouse\n\
4250 register Lisp_Object event
;
4252 register int x0
, y0
, x1
, y1
;
4253 register struct frame
*f
= selected_frame
;
4254 register int p1
, p2
;
4256 CHECK_CONS (event
, 0);
4259 x0
= XINT (Fcar (Fcar (event
)));
4260 y0
= XINT (Fcar (Fcdr (Fcar (event
))));
4262 /* If the mouse is past the end of the line, don't that area. */
4263 /* ReWrite this... */
4268 if (y1
> y0
) /* point below mouse */
4269 outline_region (f
, f
->output_data
.x
->cursor_gc
,
4271 else if (y1
< y0
) /* point above mouse */
4272 outline_region (f
, f
->output_data
.x
->cursor_gc
,
4274 else /* same line: draw horizontal rectangle */
4277 x_rectangle (f
, f
->output_data
.x
->cursor_gc
,
4278 x0
, y0
, (x1
- x0
+ 1), 1);
4280 x_rectangle (f
, f
->output_data
.x
->cursor_gc
,
4281 x1
, y1
, (x0
- x1
+ 1), 1);
4284 XFlush (FRAME_X_DISPLAY (f
));
4290 DEFUN ("x-uncontour-region", Fx_uncontour_region
, Sx_uncontour_region
, 1, 1, 0,
4291 "Erase any highlighting of the region between point and the character\n\
4292 at X, Y on the selected frame.")
4294 register Lisp_Object event
;
4296 register int x0
, y0
, x1
, y1
;
4297 register struct frame
*f
= selected_frame
;
4300 x0
= XINT (Fcar (Fcar (event
)));
4301 y0
= XINT (Fcar (Fcdr (Fcar (event
))));
4305 if (y1
> y0
) /* point below mouse */
4306 outline_region (f
, f
->output_data
.x
->reverse_gc
,
4308 else if (y1
< y0
) /* point above mouse */
4309 outline_region (f
, f
->output_data
.x
->reverse_gc
,
4311 else /* same line: draw horizontal rectangle */
4314 x_rectangle (f
, f
->output_data
.x
->reverse_gc
,
4315 x0
, y0
, (x1
- x0
+ 1), 1);
4317 x_rectangle (f
, f
->output_data
.x
->reverse_gc
,
4318 x1
, y1
, (x0
- x1
+ 1), 1);
4326 int contour_begin_x
, contour_begin_y
;
4327 int contour_end_x
, contour_end_y
;
4328 int contour_npoints
;
4330 /* Clip the top part of the contour lines down (and including) line Y_POS.
4331 If X_POS is in the middle (rather than at the end) of the line, drop
4332 down a line at that character. */
4335 clip_contour_top (y_pos
, x_pos
)
4337 register XPoint
*begin
= contour_lines
[y_pos
].top_left
;
4338 register XPoint
*end
;
4339 register int npoints
;
4340 register struct display_line
*line
= selected_frame
->phys_lines
[y_pos
+ 1];
4342 if (x_pos
>= line
->len
- 1) /* Draw one, straight horizontal line. */
4344 end
= contour_lines
[y_pos
].top_right
;
4345 npoints
= (end
- begin
+ 1);
4346 XDrawLines (x_current_display
, contour_window
,
4347 contour_erase_gc
, begin_erase
, npoints
, CoordModeOrigin
);
4349 bcopy (end
, begin
+ 1, contour_last_point
- end
+ 1);
4350 contour_last_point
-= (npoints
- 2);
4351 XDrawLines (x_current_display
, contour_window
,
4352 contour_erase_gc
, begin
, 2, CoordModeOrigin
);
4353 XFlush (x_current_display
);
4355 /* Now, update contour_lines structure. */
4360 register XPoint
*p
= begin
+ 1;
4361 end
= contour_lines
[y_pos
].bottom_right
;
4362 npoints
= (end
- begin
+ 1);
4363 XDrawLines (x_current_display
, contour_window
,
4364 contour_erase_gc
, begin_erase
, npoints
, CoordModeOrigin
);
4367 p
->x
= ibw
+ (font_w
* (x_pos
+ 1));
4369 p
->y
= begin
->y
+ font_h
;
4371 bcopy (end
, begin
+ 3, contour_last_point
- end
+ 1);
4372 contour_last_point
-= (npoints
- 5);
4373 XDrawLines (x_current_display
, contour_window
,
4374 contour_erase_gc
, begin
, 4, CoordModeOrigin
);
4375 XFlush (x_current_display
);
4377 /* Now, update contour_lines structure. */
4381 /* Erase the top horizontal lines of the contour, and then extend
4382 the contour upwards. */
4385 extend_contour_top (line
)
4390 clip_contour_bottom (x_pos
, y_pos
)
4396 extend_contour_bottom (x_pos
, y_pos
)
4400 DEFUN ("x-select-region", Fx_select_region
, Sx_select_region
, 1, 1, "e",
4405 register struct frame
*f
= selected_frame
;
4406 register int point_x
= f
->cursor_x
;
4407 register int point_y
= f
->cursor_y
;
4408 register int mouse_below_point
;
4409 register Lisp_Object obj
;
4410 register int x_contour_x
, x_contour_y
;
4412 x_contour_x
= x_mouse_x
;
4413 x_contour_y
= x_mouse_y
;
4414 if (x_contour_y
> point_y
|| (x_contour_y
== point_y
4415 && x_contour_x
> point_x
))
4417 mouse_below_point
= 1;
4418 outline_region (f
, f
->output_data
.x
->cursor_gc
, point_x
, point_y
,
4419 x_contour_x
, x_contour_y
);
4423 mouse_below_point
= 0;
4424 outline_region (f
, f
->output_data
.x
->cursor_gc
, x_contour_x
, x_contour_y
,
4430 obj
= read_char (-1, 0, 0, Qnil
, 0);
4434 if (mouse_below_point
)
4436 if (x_mouse_y
<= point_y
) /* Flipped. */
4438 mouse_below_point
= 0;
4440 outline_region (f
, f
->output_data
.x
->reverse_gc
, point_x
, point_y
,
4441 x_contour_x
, x_contour_y
);
4442 outline_region (f
, f
->output_data
.x
->cursor_gc
, x_mouse_x
, x_mouse_y
,
4445 else if (x_mouse_y
< x_contour_y
) /* Bottom clipped. */
4447 clip_contour_bottom (x_mouse_y
);
4449 else if (x_mouse_y
> x_contour_y
) /* Bottom extended. */
4451 extend_bottom_contour (x_mouse_y
);
4454 x_contour_x
= x_mouse_x
;
4455 x_contour_y
= x_mouse_y
;
4457 else /* mouse above or same line as point */
4459 if (x_mouse_y
>= point_y
) /* Flipped. */
4461 mouse_below_point
= 1;
4463 outline_region (f
, f
->output_data
.x
->reverse_gc
,
4464 x_contour_x
, x_contour_y
, point_x
, point_y
);
4465 outline_region (f
, f
->output_data
.x
->cursor_gc
, point_x
, point_y
,
4466 x_mouse_x
, x_mouse_y
);
4468 else if (x_mouse_y
> x_contour_y
) /* Top clipped. */
4470 clip_contour_top (x_mouse_y
);
4472 else if (x_mouse_y
< x_contour_y
) /* Top extended. */
4474 extend_contour_top (x_mouse_y
);
4479 unread_command_event
= obj
;
4480 if (mouse_below_point
)
4482 contour_begin_x
= point_x
;
4483 contour_begin_y
= point_y
;
4484 contour_end_x
= x_contour_x
;
4485 contour_end_y
= x_contour_y
;
4489 contour_begin_x
= x_contour_x
;
4490 contour_begin_y
= x_contour_y
;
4491 contour_end_x
= point_x
;
4492 contour_end_y
= point_y
;
4497 DEFUN ("x-horizontal-line", Fx_horizontal_line
, Sx_horizontal_line
, 1, 1, "e",
4502 register Lisp_Object obj
;
4503 struct frame
*f
= selected_frame
;
4504 register struct window
*w
= XWINDOW (selected_window
);
4505 register GC line_gc
= f
->output_data
.x
->cursor_gc
;
4506 register GC erase_gc
= f
->output_data
.x
->reverse_gc
;
4508 char dash_list
[] = {6, 4, 6, 4};
4510 XGCValues gc_values
;
4512 register int previous_y
;
4513 register int line
= (x_mouse_y
+ 1) * f
->output_data
.x
->line_height
4514 + f
->output_data
.x
->internal_border_width
;
4515 register int left
= f
->output_data
.x
->internal_border_width
4516 + (WINDOW_LEFT_MARGIN (w
)
4517 * FONT_WIDTH (f
->output_data
.x
->font
));
4518 register int right
= left
+ (w
->width
4519 * FONT_WIDTH (f
->output_data
.x
->font
))
4520 - f
->output_data
.x
->internal_border_width
;
4524 gc_values
.foreground
= f
->output_data
.x
->cursor_pixel
;
4525 gc_values
.background
= f
->output_data
.x
->background_pixel
;
4526 gc_values
.line_width
= 1;
4527 gc_values
.line_style
= LineOnOffDash
;
4528 gc_values
.cap_style
= CapRound
;
4529 gc_values
.join_style
= JoinRound
;
4531 line_gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4532 GCLineStyle
| GCJoinStyle
| GCCapStyle
4533 | GCLineWidth
| GCForeground
| GCBackground
,
4535 XSetDashes (FRAME_X_DISPLAY (f
), line_gc
, 0, dash_list
, dashes
);
4536 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
4537 gc_values
.background
= f
->output_data
.x
->foreground_pixel
;
4538 erase_gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4539 GCLineStyle
| GCJoinStyle
| GCCapStyle
4540 | GCLineWidth
| GCForeground
| GCBackground
,
4542 XSetDashes (FRAME_X_DISPLAY (f
), erase_gc
, 0, dash_list
, dashes
);
4549 if (x_mouse_y
>= XINT (w
->top
)
4550 && x_mouse_y
< XINT (w
->top
) + XINT (w
->height
) - 1)
4552 previous_y
= x_mouse_y
;
4553 line
= (x_mouse_y
+ 1) * f
->output_data
.x
->line_height
4554 + f
->output_data
.x
->internal_border_width
;
4555 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4556 line_gc
, left
, line
, right
, line
);
4558 XFlush (FRAME_X_DISPLAY (f
));
4563 obj
= read_char (-1, 0, 0, Qnil
, 0);
4565 || (! EQ (Fcar (Fcdr (Fcdr (obj
))),
4566 Qvertical_scroll_bar
))
4570 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4571 erase_gc
, left
, line
, right
, line
);
4572 unread_command_event
= obj
;
4574 XFreeGC (FRAME_X_DISPLAY (f
), line_gc
);
4575 XFreeGC (FRAME_X_DISPLAY (f
), erase_gc
);
4581 while (x_mouse_y
== previous_y
);
4584 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4585 erase_gc
, left
, line
, right
, line
);
4592 /* These keep track of the rectangle following the pointer. */
4593 int mouse_track_top
, mouse_track_left
, mouse_track_width
;
4595 /* Offset in buffer of character under the pointer, or 0. */
4596 int mouse_buffer_offset
;
4598 DEFUN ("x-track-pointer", Fx_track_pointer
, Sx_track_pointer
, 0, 0, 0,
4599 "Track the pointer.")
4602 static Cursor current_pointer_shape
;
4603 FRAME_PTR f
= x_mouse_frame
;
4606 if (EQ (Vmouse_frame_part
, Qtext_part
)
4607 && (current_pointer_shape
!= f
->output_data
.x
->nontext_cursor
))
4612 current_pointer_shape
= f
->output_data
.x
->nontext_cursor
;
4613 XDefineCursor (FRAME_X_DISPLAY (f
),
4615 current_pointer_shape
);
4617 buf
= XBUFFER (XWINDOW (Vmouse_window
)->buffer
);
4618 c
= *(BUF_CHAR_ADDRESS (buf
, mouse_buffer_offset
));
4620 else if (EQ (Vmouse_frame_part
, Qmodeline_part
)
4621 && (current_pointer_shape
!= f
->output_data
.x
->modeline_cursor
))
4623 current_pointer_shape
= f
->output_data
.x
->modeline_cursor
;
4624 XDefineCursor (FRAME_X_DISPLAY (f
),
4626 current_pointer_shape
);
4629 XFlush (FRAME_X_DISPLAY (f
));
4635 DEFUN ("x-track-pointer", Fx_track_pointer
, Sx_track_pointer
, 1, 1, "e",
4636 "Draw rectangle around character under mouse pointer, if there is one.")
4640 struct window
*w
= XWINDOW (Vmouse_window
);
4641 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4642 struct buffer
*b
= XBUFFER (w
->buffer
);
4645 if (! EQ (Vmouse_window
, selected_window
))
4648 if (EQ (event
, Qnil
))
4652 x_read_mouse_position (selected_frame
, &x
, &y
);
4656 mouse_track_width
= 0;
4657 mouse_track_left
= mouse_track_top
= -1;
4661 if ((x_mouse_x
!= mouse_track_left
4662 && (x_mouse_x
< mouse_track_left
4663 || x_mouse_x
> (mouse_track_left
+ mouse_track_width
)))
4664 || x_mouse_y
!= mouse_track_top
)
4666 int hp
= 0; /* Horizontal position */
4667 int len
= FRAME_CURRENT_GLYPHS (f
)->used
[x_mouse_y
];
4668 int p
= FRAME_CURRENT_GLYPHS (f
)->bufp
[x_mouse_y
];
4669 int tab_width
= XINT (b
->tab_width
);
4670 int ctl_arrow_p
= !NILP (b
->ctl_arrow
);
4672 int mode_line_vpos
= XFASTINT (w
->height
) + XFASTINT (w
->top
) - 1;
4673 int in_mode_line
= 0;
4675 if (! FRAME_CURRENT_GLYPHS (f
)->enable
[x_mouse_y
])
4678 /* Erase previous rectangle. */
4679 if (mouse_track_width
)
4681 x_rectangle (f
, f
->output_data
.x
->reverse_gc
,
4682 mouse_track_left
, mouse_track_top
,
4683 mouse_track_width
, 1);
4685 if ((mouse_track_left
== f
->phys_cursor_x
4686 || mouse_track_left
== f
->phys_cursor_x
- 1)
4687 && mouse_track_top
== f
->phys_cursor_y
)
4689 x_display_cursor (f
, 1);
4693 mouse_track_left
= x_mouse_x
;
4694 mouse_track_top
= x_mouse_y
;
4695 mouse_track_width
= 0;
4697 if (mouse_track_left
> len
) /* Past the end of line. */
4700 if (mouse_track_top
== mode_line_vpos
)
4706 if (tab_width
<= 0 || tab_width
> 20) tab_width
= 8;
4710 if (len
== f
->width
&& hp
== len
- 1 && c
!= '\n')
4716 mouse_track_width
= tab_width
- (hp
% tab_width
);
4718 hp
+= mouse_track_width
;
4721 mouse_track_left
= hp
- mouse_track_width
;
4727 mouse_track_width
= -1;
4731 if (ctl_arrow_p
&& (c
< 040 || c
== 0177))
4736 mouse_track_width
= 2;
4741 mouse_track_left
= hp
- mouse_track_width
;
4747 mouse_track_width
= 1;
4754 while (hp
<= x_mouse_x
);
4757 if (mouse_track_width
) /* Over text; use text pointer shape. */
4759 XDefineCursor (FRAME_X_DISPLAY (f
),
4761 f
->output_data
.x
->text_cursor
);
4762 x_rectangle (f
, f
->output_data
.x
->cursor_gc
,
4763 mouse_track_left
, mouse_track_top
,
4764 mouse_track_width
, 1);
4766 else if (in_mode_line
)
4767 XDefineCursor (FRAME_X_DISPLAY (f
),
4769 f
->output_data
.x
->modeline_cursor
);
4771 XDefineCursor (FRAME_X_DISPLAY (f
),
4773 f
->output_data
.x
->nontext_cursor
);
4776 XFlush (FRAME_X_DISPLAY (f
));
4779 obj
= read_char (-1, 0, 0, Qnil
, 0);
4782 while (CONSP (obj
) /* Mouse event */
4783 && EQ (Fcar (Fcdr (Fcdr (obj
))), Qnil
) /* Not scroll bar */
4784 && EQ (Vmouse_depressed
, Qnil
) /* Only motion events */
4785 && EQ (Vmouse_window
, selected_window
) /* In this window */
4788 unread_command_event
= obj
;
4790 if (mouse_track_width
)
4792 x_rectangle (f
, f
->output_data
.x
->reverse_gc
,
4793 mouse_track_left
, mouse_track_top
,
4794 mouse_track_width
, 1);
4795 mouse_track_width
= 0;
4796 if ((mouse_track_left
== f
->phys_cursor_x
4797 || mouse_track_left
- 1 == f
->phys_cursor_x
)
4798 && mouse_track_top
== f
->phys_cursor_y
)
4800 x_display_cursor (f
, 1);
4803 XDefineCursor (FRAME_X_DISPLAY (f
),
4805 f
->output_data
.x
->nontext_cursor
);
4806 XFlush (FRAME_X_DISPLAY (f
));
4816 /* Draw a pixmap specified by IMAGE_DATA of dimensions WIDTH and HEIGHT
4817 on the frame F at position X, Y. */
4819 x_draw_pixmap (f
, x
, y
, image_data
, width
, height
)
4821 int x
, y
, width
, height
;
4826 image
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
4827 FRAME_X_WINDOW (f
), image_data
,
4829 XCopyPlane (FRAME_X_DISPLAY (f
), image
, FRAME_X_WINDOW (f
),
4830 f
->output_data
.x
->normal_gc
, 0, 0, width
, height
, x
, y
);
4834 #if 0 /* I'm told these functions are superfluous
4835 given the ability to bind function keys. */
4838 DEFUN ("x-rebind-key", Fx_rebind_key
, Sx_rebind_key
, 3, 3, 0,
4839 "Rebind X keysym KEYSYM, with MODIFIERS, to generate NEWSTRING.\n\
4840 KEYSYM is a string which conforms to the X keysym definitions found\n\
4841 in X11/keysymdef.h, sans the initial XK_. MODIFIERS is nil or a\n\
4842 list of strings specifying modifier keys such as Control_L, which must\n\
4843 also be depressed for NEWSTRING to appear.")
4844 (x_keysym
, modifiers
, newstring
)
4845 register Lisp_Object x_keysym
;
4846 register Lisp_Object modifiers
;
4847 register Lisp_Object newstring
;
4850 register KeySym keysym
;
4851 KeySym modifier_list
[16];
4854 CHECK_STRING (x_keysym
, 1);
4855 CHECK_STRING (newstring
, 3);
4857 keysym
= XStringToKeysym ((char *) XSTRING (x_keysym
)->data
);
4858 if (keysym
== NoSymbol
)
4859 error ("Keysym does not exist");
4861 if (NILP (modifiers
))
4862 XRebindKeysym (x_current_display
, keysym
, modifier_list
, 0,
4863 XSTRING (newstring
)->data
, XSTRING (newstring
)->size
);
4866 register Lisp_Object rest
, mod
;
4869 for (rest
= modifiers
; !NILP (rest
); rest
= Fcdr (rest
))
4872 error ("Can't have more than 16 modifiers");
4875 CHECK_STRING (mod
, 3);
4876 modifier_list
[i
] = XStringToKeysym ((char *) XSTRING (mod
)->data
);
4878 if (modifier_list
[i
] == NoSymbol
4879 || !(IsModifierKey (modifier_list
[i
])
4880 || ((unsigned)(modifier_list
[i
]) == XK_Mode_switch
)
4881 || ((unsigned)(modifier_list
[i
]) == XK_Num_Lock
)))
4883 if (modifier_list
[i
] == NoSymbol
4884 || !IsModifierKey (modifier_list
[i
]))
4886 error ("Element is not a modifier keysym");
4890 XRebindKeysym (x_current_display
, keysym
, modifier_list
, i
,
4891 XSTRING (newstring
)->data
, XSTRING (newstring
)->size
);
4897 DEFUN ("x-rebind-keys", Fx_rebind_keys
, Sx_rebind_keys
, 2, 2, 0,
4898 "Rebind KEYCODE to list of strings STRINGS.\n\
4899 STRINGS should be a list of 16 elements, one for each shift combination.\n\
4900 nil as element means don't change.\n\
4901 See the documentation of `x-rebind-key' for more information.")
4903 register Lisp_Object keycode
;
4904 register Lisp_Object strings
;
4906 register Lisp_Object item
;
4907 register unsigned char *rawstring
;
4908 KeySym rawkey
, modifier
[1];
4910 register unsigned i
;
4913 CHECK_NUMBER (keycode
, 1);
4914 CHECK_CONS (strings
, 2);
4915 rawkey
= (KeySym
) ((unsigned) (XINT (keycode
))) & 255;
4916 for (i
= 0; i
<= 15; strings
= Fcdr (strings
), i
++)
4918 item
= Fcar (strings
);
4921 CHECK_STRING (item
, 2);
4922 strsize
= XSTRING (item
)->size
;
4923 rawstring
= (unsigned char *) xmalloc (strsize
);
4924 bcopy (XSTRING (item
)->data
, rawstring
, strsize
);
4925 modifier
[1] = 1 << i
;
4926 XRebindKeysym (x_current_display
, rawkey
, modifier
, 1,
4927 rawstring
, strsize
);
4932 #endif /* HAVE_X11 */
4935 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4937 XScreenNumberOfScreen (scr
)
4938 register Screen
*scr
;
4940 register Display
*dpy
;
4941 register Screen
*dpyscr
;
4945 dpyscr
= dpy
->screens
;
4947 for (i
= 0; i
< dpy
->nscreens
; i
++, dpyscr
++)
4953 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4956 select_visual (dpy
, screen
, depth
)
4959 unsigned int *depth
;
4962 XVisualInfo
*vinfo
, vinfo_template
;
4965 v
= DefaultVisualOfScreen (screen
);
4968 vinfo_template
.visualid
= XVisualIDFromVisual (v
);
4970 vinfo_template
.visualid
= v
->visualid
;
4973 vinfo_template
.screen
= XScreenNumberOfScreen (screen
);
4975 vinfo
= XGetVisualInfo (dpy
,
4976 VisualIDMask
| VisualScreenMask
, &vinfo_template
,
4979 fatal ("Can't get proper X visual info");
4981 if ((1 << vinfo
->depth
) == vinfo
->colormap_size
)
4982 *depth
= vinfo
->depth
;
4986 int n
= vinfo
->colormap_size
- 1;
4995 XFree ((char *) vinfo
);
4999 /* Return the X display structure for the display named NAME.
5000 Open a new connection if necessary. */
5002 struct x_display_info
*
5003 x_display_info_for_name (name
)
5007 struct x_display_info
*dpyinfo
;
5009 CHECK_STRING (name
, 0);
5011 if (! EQ (Vwindow_system
, intern ("x")))
5012 error ("Not using X Windows");
5014 for (dpyinfo
= x_display_list
, names
= x_display_name_list
;
5016 dpyinfo
= dpyinfo
->next
, names
= XCONS (names
)->cdr
)
5019 tem
= Fstring_equal (XCONS (XCONS (names
)->car
)->car
, name
);
5024 /* Use this general default value to start with. */
5025 Vx_resource_name
= Vinvocation_name
;
5027 validate_x_resource_name ();
5029 dpyinfo
= x_term_init (name
, (unsigned char *)0,
5030 (char *) XSTRING (Vx_resource_name
)->data
);
5033 error ("Cannot connect to X server %s", XSTRING (name
)->data
);
5036 XSETFASTINT (Vwindow_system_version
, 11);
5041 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
5042 1, 3, 0, "Open a connection to an X server.\n\
5043 DISPLAY is the name of the display to connect to.\n\
5044 Optional second arg XRM-STRING is a string of resources in xrdb format.\n\
5045 If the optional third arg MUST-SUCCEED is non-nil,\n\
5046 terminate Emacs if we can't open the connection.")
5047 (display
, xrm_string
, must_succeed
)
5048 Lisp_Object display
, xrm_string
, must_succeed
;
5050 unsigned int n_planes
;
5051 unsigned char *xrm_option
;
5052 struct x_display_info
*dpyinfo
;
5054 CHECK_STRING (display
, 0);
5055 if (! NILP (xrm_string
))
5056 CHECK_STRING (xrm_string
, 1);
5058 if (! EQ (Vwindow_system
, intern ("x")))
5059 error ("Not using X Windows");
5061 if (! NILP (xrm_string
))
5062 xrm_option
= (unsigned char *) XSTRING (xrm_string
)->data
;
5064 xrm_option
= (unsigned char *) 0;
5066 validate_x_resource_name ();
5068 /* This is what opens the connection and sets x_current_display.
5069 This also initializes many symbols, such as those used for input. */
5070 dpyinfo
= x_term_init (display
, xrm_option
,
5071 (char *) XSTRING (Vx_resource_name
)->data
);
5075 if (!NILP (must_succeed
))
5076 fatal ("Cannot connect to X server %s.\n\
5077 Check the DISPLAY environment variable or use `-d'.\n\
5078 Also use the `xhost' program to verify that it is set to permit\n\
5079 connections from your machine.\n",
5080 XSTRING (display
)->data
);
5082 error ("Cannot connect to X server %s", XSTRING (display
)->data
);
5087 XSETFASTINT (Vwindow_system_version
, 11);
5091 DEFUN ("x-close-connection", Fx_close_connection
,
5092 Sx_close_connection
, 1, 1, 0,
5093 "Close the connection to DISPLAY's X server.\n\
5094 For DISPLAY, specify either a frame or a display name (a string).\n\
5095 If DISPLAY is nil, that stands for the selected frame's display.")
5097 Lisp_Object display
;
5099 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
5100 struct x_display_info
*tail
;
5103 if (dpyinfo
->reference_count
> 0)
5104 error ("Display still has frames on it");
5107 /* Free the fonts in the font table. */
5108 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
5110 if (dpyinfo
->font_table
[i
].name
)
5111 free (dpyinfo
->font_table
[i
].name
);
5112 /* Don't free the full_name string;
5113 it is always shared with something else. */
5114 XFreeFont (dpyinfo
->display
, dpyinfo
->font_table
[i
].font
);
5116 x_destroy_all_bitmaps (dpyinfo
);
5117 XSetCloseDownMode (dpyinfo
->display
, DestroyAll
);
5119 #ifdef USE_X_TOOLKIT
5120 XtCloseDisplay (dpyinfo
->display
);
5122 XCloseDisplay (dpyinfo
->display
);
5125 x_delete_display (dpyinfo
);
5131 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
5132 "Return the list of display names that Emacs has connections to.")
5135 Lisp_Object tail
, result
;
5138 for (tail
= x_display_name_list
; ! NILP (tail
); tail
= XCONS (tail
)->cdr
)
5139 result
= Fcons (XCONS (XCONS (tail
)->car
)->car
, result
);
5144 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
5145 "If ON is non-nil, report X errors as soon as the erring request is made.\n\
5146 If ON is nil, allow buffering of requests.\n\
5147 Turning on synchronization prohibits the Xlib routines from buffering\n\
5148 requests and seriously degrades performance, but makes debugging much\n\
5150 The optional second argument DISPLAY specifies which display to act on.\n\
5151 DISPLAY should be either a frame or a display name (a string).\n\
5152 If DISPLAY is omitted or nil, that stands for the selected frame's display.")
5154 Lisp_Object display
, on
;
5156 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
5158 XSynchronize (dpyinfo
->display
, !EQ (on
, Qnil
));
5163 /* Wait for responses to all X commands issued so far for frame F. */
5170 XSync (FRAME_X_DISPLAY (f
), False
);
5176 /* This is zero if not using X windows. */
5179 /* The section below is built by the lisp expression at the top of the file,
5180 just above where these variables are declared. */
5181 /*&&& init symbols here &&&*/
5182 Qauto_raise
= intern ("auto-raise");
5183 staticpro (&Qauto_raise
);
5184 Qauto_lower
= intern ("auto-lower");
5185 staticpro (&Qauto_lower
);
5186 Qbackground_color
= intern ("background-color");
5187 staticpro (&Qbackground_color
);
5188 Qbar
= intern ("bar");
5190 Qborder_color
= intern ("border-color");
5191 staticpro (&Qborder_color
);
5192 Qborder_width
= intern ("border-width");
5193 staticpro (&Qborder_width
);
5194 Qbox
= intern ("box");
5196 Qcursor_color
= intern ("cursor-color");
5197 staticpro (&Qcursor_color
);
5198 Qcursor_type
= intern ("cursor-type");
5199 staticpro (&Qcursor_type
);
5200 Qforeground_color
= intern ("foreground-color");
5201 staticpro (&Qforeground_color
);
5202 Qgeometry
= intern ("geometry");
5203 staticpro (&Qgeometry
);
5204 Qicon_left
= intern ("icon-left");
5205 staticpro (&Qicon_left
);
5206 Qicon_top
= intern ("icon-top");
5207 staticpro (&Qicon_top
);
5208 Qicon_type
= intern ("icon-type");
5209 staticpro (&Qicon_type
);
5210 Qicon_name
= intern ("icon-name");
5211 staticpro (&Qicon_name
);
5212 Qinternal_border_width
= intern ("internal-border-width");
5213 staticpro (&Qinternal_border_width
);
5214 Qleft
= intern ("left");
5216 Qright
= intern ("right");
5217 staticpro (&Qright
);
5218 Qmouse_color
= intern ("mouse-color");
5219 staticpro (&Qmouse_color
);
5220 Qnone
= intern ("none");
5222 Qparent_id
= intern ("parent-id");
5223 staticpro (&Qparent_id
);
5224 Qscroll_bar_width
= intern ("scroll-bar-width");
5225 staticpro (&Qscroll_bar_width
);
5226 Qsuppress_icon
= intern ("suppress-icon");
5227 staticpro (&Qsuppress_icon
);
5228 Qtop
= intern ("top");
5230 Qundefined_color
= intern ("undefined-color");
5231 staticpro (&Qundefined_color
);
5232 Qvertical_scroll_bars
= intern ("vertical-scroll-bars");
5233 staticpro (&Qvertical_scroll_bars
);
5234 Qvisibility
= intern ("visibility");
5235 staticpro (&Qvisibility
);
5236 Qwindow_id
= intern ("window-id");
5237 staticpro (&Qwindow_id
);
5238 Qx_frame_parameter
= intern ("x-frame-parameter");
5239 staticpro (&Qx_frame_parameter
);
5240 Qx_resource_name
= intern ("x-resource-name");
5241 staticpro (&Qx_resource_name
);
5242 Quser_position
= intern ("user-position");
5243 staticpro (&Quser_position
);
5244 Quser_size
= intern ("user-size");
5245 staticpro (&Quser_size
);
5246 Qdisplay
= intern ("display");
5247 staticpro (&Qdisplay
);
5248 /* This is the end of symbol initialization. */
5250 Fput (Qundefined_color
, Qerror_conditions
,
5251 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
5252 Fput (Qundefined_color
, Qerror_message
,
5253 build_string ("Undefined color"));
5255 init_x_parm_symbols ();
5257 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path
,
5258 "List of directories to search for bitmap files for X.");
5259 Vx_bitmap_file_path
= decode_env_path ((char *) 0, PATH_BITMAPS
);
5261 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
5262 "The shape of the pointer when over text.\n\
5263 Changing the value does not affect existing frames\n\
5264 unless you set the mouse color.");
5265 Vx_pointer_shape
= Qnil
;
5267 DEFVAR_LISP ("x-resource-name", &Vx_resource_name
,
5268 "The name Emacs uses to look up X resources.\n\
5269 `x-get-resource' uses this as the first component of the instance name\n\
5270 when requesting resource values.\n\
5271 Emacs initially sets `x-resource-name' to the name under which Emacs\n\
5272 was invoked, or to the value specified with the `-name' or `-rn'\n\
5273 switches, if present.\n\
5275 It may be useful to bind this variable locally around a call\n\
5276 to `x-get-resource'. See also the variable `x-resource-class'.");
5277 Vx_resource_name
= Qnil
;
5279 DEFVAR_LISP ("x-resource-class", &Vx_resource_class
,
5280 "The class Emacs uses to look up X resources.\n\
5281 `x-get-resource' uses this as the first component of the instance class\n\
5282 when requesting resource values.\n\
5283 Emacs initially sets `x-resource-class' to \"Emacs\".\n\
5285 Setting this variable permanently is not a reasonable thing to do,\n\
5286 but binding this variable locally around a call to `x-get-resource'\n\
5287 is a reasonabvle practice. See also the variable `x-resource-name'.");
5288 Vx_resource_class
= build_string (EMACS_CLASS
);
5290 #if 0 /* This doesn't really do anything. */
5291 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape
,
5292 "The shape of the pointer when not over text.\n\
5293 This variable takes effect when you create a new frame\n\
5294 or when you set the mouse color.");
5296 Vx_nontext_pointer_shape
= Qnil
;
5298 #if 0 /* This doesn't really do anything. */
5299 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape
,
5300 "The shape of the pointer when over the mode line.\n\
5301 This variable takes effect when you create a new frame\n\
5302 or when you set the mouse color.");
5304 Vx_mode_pointer_shape
= Qnil
;
5306 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
5307 &Vx_sensitive_text_pointer_shape
,
5308 "The shape of the pointer when over mouse-sensitive text.\n\
5309 This variable takes effect when you create a new frame\n\
5310 or when you set the mouse color.");
5311 Vx_sensitive_text_pointer_shape
= Qnil
;
5313 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
5314 "A string indicating the foreground color of the cursor box.");
5315 Vx_cursor_fore_pixel
= Qnil
;
5317 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
5318 "Non-nil if no X window manager is in use.\n\
5319 Emacs doesn't try to figure this out; this is always nil\n\
5320 unless you set it to something else.");
5321 /* We don't have any way to find this out, so set it to nil
5322 and maybe the user would like to set it to t. */
5323 Vx_no_window_manager
= Qnil
;
5325 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
5326 &Vx_pixel_size_width_font_regexp
,
5327 "Regexp matching a font name whose width is the same as `PIXEL_SIZE'.\n\
5329 Since Emacs gets width of a font matching with this regexp from\n\
5330 PIXEL_SIZE field of the name, font finding mechanism gets faster for\n\
5331 such a font. This is especially effective for such large fonts as\n\
5332 Chinese, Japanese, and Korean.");
5333 Vx_pixel_size_width_font_regexp
= Qnil
;
5335 #ifdef USE_X_TOOLKIT
5336 Fprovide (intern ("x-toolkit"));
5339 Fprovide (intern ("motif"));
5342 defsubr (&Sx_get_resource
);
5344 defsubr (&Sx_draw_rectangle
);
5345 defsubr (&Sx_erase_rectangle
);
5346 defsubr (&Sx_contour_region
);
5347 defsubr (&Sx_uncontour_region
);
5349 defsubr (&Sx_list_fonts
);
5350 defsubr (&Sx_display_color_p
);
5351 defsubr (&Sx_display_grayscale_p
);
5352 defsubr (&Sx_color_defined_p
);
5353 defsubr (&Sx_color_values
);
5354 defsubr (&Sx_server_max_request_size
);
5355 defsubr (&Sx_server_vendor
);
5356 defsubr (&Sx_server_version
);
5357 defsubr (&Sx_display_pixel_width
);
5358 defsubr (&Sx_display_pixel_height
);
5359 defsubr (&Sx_display_mm_width
);
5360 defsubr (&Sx_display_mm_height
);
5361 defsubr (&Sx_display_screens
);
5362 defsubr (&Sx_display_planes
);
5363 defsubr (&Sx_display_color_cells
);
5364 defsubr (&Sx_display_visual_class
);
5365 defsubr (&Sx_display_backing_store
);
5366 defsubr (&Sx_display_save_under
);
5368 defsubr (&Sx_rebind_key
);
5369 defsubr (&Sx_rebind_keys
);
5370 defsubr (&Sx_track_pointer
);
5371 defsubr (&Sx_grab_pointer
);
5372 defsubr (&Sx_ungrab_pointer
);
5374 defsubr (&Sx_parse_geometry
);
5375 defsubr (&Sx_create_frame
);
5377 defsubr (&Sx_horizontal_line
);
5379 defsubr (&Sx_open_connection
);
5380 defsubr (&Sx_close_connection
);
5381 defsubr (&Sx_display_list
);
5382 defsubr (&Sx_synchronize
);
5384 /* Setting callback functions for fontset handler. */
5385 get_font_info_func
= x_get_font_info
;
5386 list_fonts_func
= x_list_fonts
;
5387 load_font_func
= x_load_font
;
5388 query_font_func
= x_query_font
;
5389 set_frame_fontset_func
= x_set_font
;
5390 check_window_system_func
= check_x
;
5393 #endif /* HAVE_X_WINDOWS */