1 /* Functions for the X window system.
2 Copyright (C) 1989, 1992, 1993, 1994 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
20 /* Completely rewritten by Richard Stallman. */
22 /* Rewritten for X11 by Joseph Arceneaux */
27 /* This makes the fields of a Display accessible, in Xlib header files. */
28 #define XLIB_ILLEGAL_ACCESS
35 #include "dispextern.h"
37 #include "blockinput.h"
44 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */
45 #include "bitmaps/gray.xbm"
47 #include <X11/bitmaps/gray>
50 #include "[.bitmaps]gray.xbm"
54 #include <X11/Shell.h>
56 #include <X11/Xaw/Paned.h>
57 #include <X11/Xaw/Label.h>
60 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
69 #include "../lwlib/lwlib.h"
71 /* Do the EDITRES protocol if running X11R5 */
72 #if (XtSpecificationRelease >= 5)
74 extern void _XEditResCheckMessages ();
75 #endif /* R5 + Athena */
77 /* Unique id counter for widgets created by the Lucid Widget
79 extern LWLIB_ID widget_id_tick
;
81 /* The one and only application context associated with the connection
82 to the one and only X display that Emacs uses. */
83 XtAppContext Xt_app_con
;
85 /* The one and only application shell. Emacs screens are popup shells of this
89 extern void free_frame_menubar ();
90 #endif /* USE_X_TOOLKIT */
92 #define min(a,b) ((a) < (b) ? (a) : (b))
93 #define max(a,b) ((a) > (b) ? (a) : (b))
96 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
98 #define MAXREQUEST(dpy) ((dpy)->max_request_size)
101 /* The name we're using in resource queries. */
102 Lisp_Object Vx_resource_name
;
104 /* The background and shape of the mouse pointer, and shape when not
105 over text or in the modeline. */
106 Lisp_Object Vx_pointer_shape
, Vx_nontext_pointer_shape
, Vx_mode_pointer_shape
;
107 /* The shape when over mouse-sensitive text. */
108 Lisp_Object Vx_sensitive_text_pointer_shape
;
110 /* Color of chars displayed in cursor box. */
111 Lisp_Object Vx_cursor_fore_pixel
;
113 /* Nonzero if using X. */
116 /* Non nil if no window manager is in use. */
117 Lisp_Object Vx_no_window_manager
;
119 /* Search path for bitmap files. */
120 Lisp_Object Vx_bitmap_file_path
;
122 /* Evaluate this expression to rebuild the section of syms_of_xfns
123 that initializes and staticpros the symbols declared below. Note
124 that Emacs 18 has a bug that keeps C-x C-e from being able to
125 evaluate this expression.
128 ;; Accumulate a list of the symbols we want to initialize from the
129 ;; declarations at the top of the file.
130 (goto-char (point-min))
131 (search-forward "/\*&&& symbols declared here &&&*\/\n")
133 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
135 (cons (buffer-substring (match-beginning 1) (match-end 1))
138 (setq symbol-list (nreverse symbol-list))
139 ;; Delete the section of syms_of_... where we initialize the symbols.
140 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
141 (let ((start (point)))
142 (while (looking-at "^ Q")
144 (kill-region start (point)))
145 ;; Write a new symbol initialization section.
147 (insert (format " %s = intern (\"" (car symbol-list)))
148 (let ((start (point)))
149 (insert (substring (car symbol-list) 1))
150 (subst-char-in-region start (point) ?_ ?-))
151 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
152 (setq symbol-list (cdr symbol-list)))))
156 /*&&& symbols declared here &&&*/
157 Lisp_Object Qauto_raise
;
158 Lisp_Object Qauto_lower
;
159 Lisp_Object Qbackground_color
;
161 Lisp_Object Qborder_color
;
162 Lisp_Object Qborder_width
;
164 Lisp_Object Qcursor_color
;
165 Lisp_Object Qcursor_type
;
167 Lisp_Object Qforeground_color
;
168 Lisp_Object Qgeometry
;
169 Lisp_Object Qicon_left
;
170 Lisp_Object Qicon_top
;
171 Lisp_Object Qicon_type
;
172 Lisp_Object Qinternal_border_width
;
174 Lisp_Object Qmouse_color
;
176 Lisp_Object Qparent_id
;
177 Lisp_Object Qscroll_bar_width
;
178 Lisp_Object Qsuppress_icon
;
180 Lisp_Object Qundefined_color
;
181 Lisp_Object Qvertical_scroll_bars
;
182 Lisp_Object Qvisibility
;
183 Lisp_Object Qwindow_id
;
184 Lisp_Object Qx_frame_parameter
;
185 Lisp_Object Qx_resource_name
;
186 Lisp_Object Quser_position
;
187 Lisp_Object Quser_size
;
188 Lisp_Object Qdisplay
;
190 /* The below are defined in frame.c. */
191 extern Lisp_Object Qheight
, Qminibuffer
, Qname
, Qonly
, Qwidth
;
192 extern Lisp_Object Qunsplittable
, Qmenu_bar_lines
;
194 extern Lisp_Object Vwindow_system_version
;
197 /* Error if we are not connected to X. */
202 error ("X windows are not in use or not initialized");
205 /* Nonzero if using X for display. */
213 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
214 and checking validity for X. */
217 check_x_frame (frame
)
226 CHECK_LIVE_FRAME (frame
, 0);
230 error ("non-X frame used");
234 /* Let the user specify an X display with a frame.
235 nil stands for the selected frame--or, if that is not an X frame,
236 the first X display on the list. */
238 static struct x_display_info
*
239 check_x_display_info (frame
)
244 if (FRAME_X_P (selected_frame
))
245 return FRAME_X_DISPLAY_INFO (selected_frame
);
246 else if (x_display_list
!= 0)
247 return x_display_list
;
249 error ("X windows are not in use or not initialized");
251 else if (STRINGP (frame
))
252 return x_display_info_for_name (frame
);
257 CHECK_LIVE_FRAME (frame
, 0);
260 error ("non-X frame used");
261 return FRAME_X_DISPLAY_INFO (f
);
265 /* Return the Emacs frame-object corresponding to an X window.
266 It could be the frame's main window or an icon window. */
268 /* This function can be called during GC, so use XGCTYPE. */
271 x_window_to_frame (wdesc
)
274 Lisp_Object tail
, frame
;
277 for (tail
= Vframe_list
; XGCTYPE (tail
) == Lisp_Cons
;
278 tail
= XCONS (tail
)->cdr
)
280 frame
= XCONS (tail
)->car
;
281 if (XGCTYPE (frame
) != Lisp_Frame
)
285 if (f
->display
.nothing
== 1)
287 if ((f
->display
.x
->edit_widget
288 && XtWindow (f
->display
.x
->edit_widget
) == wdesc
)
289 || f
->display
.x
->icon_desc
== wdesc
)
291 #else /* not USE_X_TOOLKIT */
292 if (FRAME_X_WINDOW (f
) == wdesc
293 || f
->display
.x
->icon_desc
== wdesc
)
295 #endif /* not USE_X_TOOLKIT */
301 /* Like x_window_to_frame but also compares the window with the widget's
305 x_any_window_to_frame (wdesc
)
308 Lisp_Object tail
, frame
;
312 for (tail
= Vframe_list
; XGCTYPE (tail
) == Lisp_Cons
;
313 tail
= XCONS (tail
)->cdr
)
315 frame
= XCONS (tail
)->car
;
316 if (XGCTYPE (frame
) != Lisp_Frame
)
319 if (f
->display
.nothing
== 1)
322 /* This frame matches if the window is any of its widgets. */
323 if (wdesc
== XtWindow (x
->widget
)
324 || wdesc
== XtWindow (x
->column_widget
)
325 || wdesc
== XtWindow (x
->edit_widget
))
327 /* Match if the window is this frame's menubar. */
328 if (lw_window_is_in_menubar (wdesc
, x
->menubar_widget
))
334 /* Return the frame whose principal (outermost) window is WDESC.
335 If WDESC is some other (smaller) window, we return 0. */
338 x_top_window_to_frame (wdesc
)
341 Lisp_Object tail
, frame
;
345 for (tail
= Vframe_list
; XGCTYPE (tail
) == Lisp_Cons
;
346 tail
= XCONS (tail
)->cdr
)
348 frame
= XCONS (tail
)->car
;
349 if (XGCTYPE (frame
) != Lisp_Frame
)
352 if (f
->display
.nothing
== 1)
355 /* This frame matches if the window is its topmost widget. */
356 if (wdesc
== XtWindow (x
->widget
))
358 /* Match if the window is this frame's menubar. */
359 if (x
->menubar_widget
360 && wdesc
== XtWindow (x
->menubar_widget
))
365 #endif /* USE_X_TOOLKIT */
369 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
370 id, which is just an int that this section returns. Bitmaps are
371 reference counted so they can be shared among frames.
373 Bitmap indices are guaranteed to be > 0, so a negative number can
374 be used to indicate no bitmap.
376 If you use x_create_bitmap_from_data, then you must keep track of
377 the bitmaps yourself. That is, creating a bitmap from the same
378 data more than once will not be caught. */
381 /* Functions to access the contents of a bitmap, given an id. */
384 x_bitmap_height (f
, id
)
388 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].height
;
392 x_bitmap_width (f
, id
)
396 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].width
;
400 x_bitmap_pixmap (f
, id
)
404 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].pixmap
;
408 /* Allocate a new bitmap record. Returns index of new record. */
411 x_allocate_bitmap_record (f
)
414 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
417 if (dpyinfo
->bitmaps
== NULL
)
419 dpyinfo
->bitmaps_size
= 10;
421 = (struct x_bitmap_record
*) xmalloc (dpyinfo
->bitmaps_size
* sizeof (struct x_bitmap_record
));
422 dpyinfo
->bitmaps_last
= 1;
426 if (dpyinfo
->bitmaps_last
< dpyinfo
->bitmaps_size
)
427 return ++dpyinfo
->bitmaps_last
;
429 for (i
= 0; i
< dpyinfo
->bitmaps_size
; ++i
)
430 if (dpyinfo
->bitmaps
[i
].refcount
== 0)
433 dpyinfo
->bitmaps_size
*= 2;
435 = (struct x_bitmap_record
*) xrealloc (dpyinfo
->bitmaps
,
436 dpyinfo
->bitmaps_size
* sizeof (struct x_bitmap_record
));
437 return ++dpyinfo
->bitmaps_last
;
440 /* Add one reference to the reference count of the bitmap with id ID. */
443 x_reference_bitmap (f
, id
)
447 ++FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].refcount
;
450 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
453 x_create_bitmap_from_data (f
, bits
, width
, height
)
456 unsigned int width
, height
;
458 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
462 bitmap
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
463 bits
, width
, height
);
468 id
= x_allocate_bitmap_record (f
);
469 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
470 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
471 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
472 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
473 dpyinfo
->bitmaps
[id
- 1].height
= height
;
474 dpyinfo
->bitmaps
[id
- 1].width
= width
;
479 /* Create bitmap from file FILE for frame F. */
482 x_create_bitmap_from_file (f
, file
)
486 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
487 unsigned int width
, height
;
489 int xhot
, yhot
, result
, id
;
494 /* Look for an existing bitmap with the same name. */
495 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
497 if (dpyinfo
->bitmaps
[id
].refcount
498 && dpyinfo
->bitmaps
[id
].file
499 && !strcmp (dpyinfo
->bitmaps
[id
].file
, (char *) XSTRING (file
)->data
))
501 ++dpyinfo
->bitmaps
[id
].refcount
;
506 /* Search bitmap-file-path for the file, if appropriate. */
507 fd
= openp (Vx_bitmap_file_path
, file
, "", &found
, 0);
512 filename
= (char *) XSTRING (found
)->data
;
514 result
= XReadBitmapFile (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
515 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
516 if (result
!= BitmapSuccess
)
519 id
= x_allocate_bitmap_record (f
);
520 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
521 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
522 dpyinfo
->bitmaps
[id
- 1].file
= (char *) xmalloc (XSTRING (file
)->size
+ 1);
523 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
524 dpyinfo
->bitmaps
[id
- 1].height
= height
;
525 dpyinfo
->bitmaps
[id
- 1].width
= width
;
526 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, XSTRING (file
)->data
);
531 /* Remove reference to bitmap with id number ID. */
534 x_destroy_bitmap (f
, id
)
538 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
542 --dpyinfo
->bitmaps
[id
- 1].refcount
;
543 if (dpyinfo
->bitmaps
[id
- 1].refcount
== 0)
545 XFreePixmap (FRAME_X_DISPLAY (f
), dpyinfo
->bitmaps
[id
- 1].pixmap
);
546 if (dpyinfo
->bitmaps
[id
- 1].file
)
548 free (dpyinfo
->bitmaps
[id
- 1].file
);
549 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
555 /* Free all the bitmaps for the display specified by DPYINFO. */
558 x_destroy_all_bitmaps (dpyinfo
)
559 struct x_display_info
*dpyinfo
;
562 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++)
563 if (dpyinfo
->bitmaps
[i
].refcount
> 0)
565 XFreePixmap (dpyinfo
->display
, dpyinfo
->bitmaps
[i
].pixmap
);
566 if (dpyinfo
->bitmaps
[i
].file
)
567 free (dpyinfo
->bitmaps
[i
].file
);
569 dpyinfo
->bitmaps_last
= 0;
572 /* Connect the frame-parameter names for X frames
573 to the ways of passing the parameter values to the window system.
575 The name of a parameter, as a Lisp symbol,
576 has an `x-frame-parameter' property which is an integer in Lisp
577 but can be interpreted as an `enum x_frame_parm' in C. */
581 X_PARM_FOREGROUND_COLOR
,
582 X_PARM_BACKGROUND_COLOR
,
589 X_PARM_INTERNAL_BORDER_WIDTH
,
593 X_PARM_VERT_SCROLL_BAR
,
595 X_PARM_MENU_BAR_LINES
599 struct x_frame_parm_table
602 void (*setter
)( /* struct frame *frame, Lisp_Object val, oldval */ );
605 void x_set_foreground_color ();
606 void x_set_background_color ();
607 void x_set_mouse_color ();
608 void x_set_cursor_color ();
609 void x_set_border_color ();
610 void x_set_cursor_type ();
611 void x_set_icon_type ();
613 void x_set_border_width ();
614 void x_set_internal_border_width ();
615 void x_explicitly_set_name ();
616 void x_set_autoraise ();
617 void x_set_autolower ();
618 void x_set_vertical_scroll_bars ();
619 void x_set_visibility ();
620 void x_set_menu_bar_lines ();
621 void x_set_scroll_bar_width ();
622 void x_set_unsplittable ();
624 static struct x_frame_parm_table x_frame_parms
[] =
626 "foreground-color", x_set_foreground_color
,
627 "background-color", x_set_background_color
,
628 "mouse-color", x_set_mouse_color
,
629 "cursor-color", x_set_cursor_color
,
630 "border-color", x_set_border_color
,
631 "cursor-type", x_set_cursor_type
,
632 "icon-type", x_set_icon_type
,
634 "border-width", x_set_border_width
,
635 "internal-border-width", x_set_internal_border_width
,
636 "name", x_explicitly_set_name
,
637 "auto-raise", x_set_autoraise
,
638 "auto-lower", x_set_autolower
,
639 "vertical-scroll-bars", x_set_vertical_scroll_bars
,
640 "visibility", x_set_visibility
,
641 "menu-bar-lines", x_set_menu_bar_lines
,
642 "scroll-bar-width", x_set_scroll_bar_width
,
643 "unsplittable", x_set_unsplittable
,
646 /* Attach the `x-frame-parameter' properties to
647 the Lisp symbol names of parameters relevant to X. */
649 init_x_parm_symbols ()
653 for (i
= 0; i
< sizeof (x_frame_parms
) / sizeof (x_frame_parms
[0]); i
++)
654 Fput (intern (x_frame_parms
[i
].name
), Qx_frame_parameter
,
658 /* Change the parameters of FRAME as specified by ALIST.
659 If a parameter is not specially recognized, do nothing;
660 otherwise call the `x_set_...' function for that parameter. */
663 x_set_frame_parameters (f
, alist
)
669 /* If both of these parameters are present, it's more efficient to
670 set them both at once. So we wait until we've looked at the
671 entire list before we set them. */
672 Lisp_Object width
, height
;
675 Lisp_Object left
, top
;
677 /* Record in these vectors all the parms specified. */
681 int left_no_change
= 0, top_no_change
= 0;
684 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
687 parms
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
688 values
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
690 /* Extract parm names and values into those vectors. */
693 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
695 Lisp_Object elt
, prop
, val
;
698 parms
[i
] = Fcar (elt
);
699 values
[i
] = Fcdr (elt
);
703 width
= height
= top
= left
= Qunbound
;
705 /* Now process them in reverse of specified order. */
706 for (i
--; i
>= 0; i
--)
708 Lisp_Object prop
, val
;
713 if (EQ (prop
, Qwidth
))
715 else if (EQ (prop
, Qheight
))
717 else if (EQ (prop
, Qtop
))
719 else if (EQ (prop
, Qleft
))
723 register Lisp_Object param_index
, old_value
;
725 param_index
= Fget (prop
, Qx_frame_parameter
);
726 old_value
= get_frame_param (f
, prop
);
727 store_frame_param (f
, prop
, val
);
728 if (INTEGERP (param_index
)
729 && XINT (param_index
) >= 0
730 && (XINT (param_index
)
731 < sizeof (x_frame_parms
)/sizeof (x_frame_parms
[0])))
732 (*x_frame_parms
[XINT (param_index
)].setter
)(f
, val
, old_value
);
736 /* Don't die if just one of these was set. */
737 if (EQ (left
, Qunbound
))
740 if (f
->display
.x
->left_pos
< 0)
741 left
= Fcons (Qplus
, Fcons (make_number (f
->display
.x
->left_pos
), Qnil
));
743 XSETINT (left
, f
->display
.x
->left_pos
);
745 if (EQ (top
, Qunbound
))
748 if (f
->display
.x
->top_pos
< 0)
749 top
= Fcons (Qplus
, Fcons (make_number (f
->display
.x
->top_pos
), Qnil
));
751 XSETINT (top
, f
->display
.x
->top_pos
);
754 /* Don't die if just one of these was set. */
755 if (EQ (width
, Qunbound
))
756 XSETINT (width
, FRAME_WIDTH (f
));
757 if (EQ (height
, Qunbound
))
758 XSETINT (height
, FRAME_HEIGHT (f
));
760 /* Don't set these parameters these unless they've been explicitly
761 specified. The window might be mapped or resized while we're in
762 this function, and we don't want to override that unless the lisp
763 code has asked for it.
765 Don't set these parameters unless they actually differ from the
766 window's current parameters; the window may not actually exist
771 check_frame_size (f
, &height
, &width
);
773 XSETFRAME (frame
, f
);
775 if ((NUMBERP (width
) && XINT (width
) != FRAME_WIDTH (f
))
776 || (NUMBERP (height
) && XINT (height
) != FRAME_HEIGHT (f
)))
777 Fset_frame_size (frame
, width
, height
);
779 if ((!NILP (left
) || !NILP (top
))
780 && ! (left_no_change
&& top_no_change
)
781 && ! (NUMBERP (left
) && XINT (left
) == f
->display
.x
->left_pos
782 && NUMBERP (top
) && XINT (top
) == f
->display
.x
->top_pos
))
787 /* Record the signs. */
788 f
->display
.x
->size_hint_flags
&= ~ (XNegative
| YNegative
);
789 if (EQ (left
, Qminus
))
790 f
->display
.x
->size_hint_flags
|= XNegative
;
791 else if (INTEGERP (left
))
793 leftpos
= XINT (left
);
795 f
->display
.x
->size_hint_flags
|= XNegative
;
797 else if (CONSP (left
) && EQ (XCONS (left
)->car
, Qminus
)
798 && CONSP (XCONS (left
)->cdr
)
799 && INTEGERP (XCONS (XCONS (left
)->cdr
)->car
))
801 leftpos
= - XINT (XCONS (XCONS (left
)->cdr
)->car
);
802 f
->display
.x
->size_hint_flags
|= XNegative
;
804 else if (CONSP (left
) && EQ (XCONS (left
)->car
, Qplus
)
805 && CONSP (XCONS (left
)->cdr
)
806 && INTEGERP (XCONS (XCONS (left
)->cdr
)->car
))
808 leftpos
= XINT (XCONS (XCONS (left
)->cdr
)->car
);
811 if (EQ (top
, Qminus
))
812 f
->display
.x
->size_hint_flags
|= YNegative
;
813 else if (INTEGERP (top
))
817 f
->display
.x
->size_hint_flags
|= YNegative
;
819 else if (CONSP (top
) && EQ (XCONS (top
)->car
, Qminus
)
820 && CONSP (XCONS (top
)->cdr
)
821 && INTEGERP (XCONS (XCONS (top
)->cdr
)->car
))
823 toppos
= - XINT (XCONS (XCONS (top
)->cdr
)->car
);
824 f
->display
.x
->size_hint_flags
|= YNegative
;
826 else if (CONSP (top
) && EQ (XCONS (top
)->car
, Qplus
)
827 && CONSP (XCONS (top
)->cdr
)
828 && INTEGERP (XCONS (XCONS (top
)->cdr
)->car
))
830 toppos
= XINT (XCONS (XCONS (top
)->cdr
)->car
);
834 /* Store the numeric value of the position. */
835 f
->display
.x
->top_pos
= toppos
;
836 f
->display
.x
->left_pos
= leftpos
;
838 f
->display
.x
->win_gravity
= NorthWestGravity
;
840 /* Actually set that position, and convert to absolute. */
841 x_set_offset (f
, leftpos
, toppos
, 0);
846 /* Store the screen positions of frame F into XPTR and YPTR.
847 These are the positions of the containing window manager window,
848 not Emacs's own window. */
851 x_real_positions (f
, xptr
, yptr
)
858 /* This is pretty gross, but seems to be the easiest way out of
859 the problem that arises when restarting window-managers. */
862 Window outer
= XtWindow (f
->display
.x
->widget
);
864 Window outer
= f
->display
.x
->window_desc
;
866 Window tmp_root_window
;
867 Window
*tmp_children
;
873 XQueryTree (FRAME_X_DISPLAY (f
), outer
, &tmp_root_window
,
874 &f
->display
.x
->parent_desc
,
875 &tmp_children
, &tmp_nchildren
);
876 xfree (tmp_children
);
880 /* Find the position of the outside upper-left corner of
881 the inner window, with respect to the outer window. */
882 if (f
->display
.x
->parent_desc
!= FRAME_X_DISPLAY_INFO (f
)->root_window
)
884 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
886 /* From-window, to-window. */
888 XtWindow (f
->display
.x
->widget
),
890 f
->display
.x
->window_desc
,
892 f
->display
.x
->parent_desc
,
894 /* From-position, to-position. */
895 0, 0, &win_x
, &win_y
,
900 win_x
+= f
->display
.x
->border_width
;
901 win_y
+= f
->display
.x
->border_width
;
904 /* It is possible for the window returned by the XQueryNotify
905 to become invalid by the time we call XTranslateCoordinates.
906 That can happen when you restart some window managers.
907 If so, we get an error in XTranslateCoordinates.
908 Detect that and try the whole thing over. */
909 if (! x_had_errors_p (f
))
913 x_uncatch_errors (f
);
915 *xptr
= f
->display
.x
->left_pos
- win_x
;
916 *yptr
= f
->display
.x
->top_pos
- win_y
;
919 /* Insert a description of internally-recorded parameters of frame X
920 into the parameter alist *ALISTPTR that is to be given to the user.
921 Only parameters that are specific to the X window system
922 and whose values are not correctly recorded in the frame's
923 param_alist need to be considered here. */
925 x_report_frame_params (f
, alistptr
)
927 Lisp_Object
*alistptr
;
931 store_in_alist (alistptr
, Qleft
, make_number (f
->display
.x
->left_pos
));
932 store_in_alist (alistptr
, Qtop
, make_number (f
->display
.x
->top_pos
));
933 store_in_alist (alistptr
, Qborder_width
,
934 make_number (f
->display
.x
->border_width
));
935 store_in_alist (alistptr
, Qinternal_border_width
,
936 make_number (f
->display
.x
->internal_border_width
));
937 sprintf (buf
, "%ld", (long) FRAME_X_WINDOW (f
));
938 store_in_alist (alistptr
, Qwindow_id
,
940 FRAME_SAMPLE_VISIBILITY (f
);
941 store_in_alist (alistptr
, Qvisibility
,
942 (FRAME_VISIBLE_P (f
) ? Qt
943 : FRAME_ICONIFIED_P (f
) ? Qicon
: Qnil
));
946 /* Decide if color named COLOR is valid for the display associated with
947 the selected frame; if so, return the rgb values in COLOR_DEF.
948 If ALLOC is nonzero, allocate a new colormap cell. */
951 defined_color (f
, color
, color_def
, alloc
)
958 Colormap screen_colormap
;
962 = DefaultColormap (FRAME_X_DISPLAY (f
),
963 XDefaultScreen (FRAME_X_DISPLAY (f
)));
965 foo
= XParseColor (FRAME_X_DISPLAY (f
), screen_colormap
, color
, color_def
);
967 foo
= XAllocColor (FRAME_X_DISPLAY (f
), screen_colormap
, color_def
);
976 /* Given a string ARG naming a color, compute a pixel value from it
977 suitable for screen F.
978 If F is not a color screen, return DEF (default) regardless of what
982 x_decode_color (f
, arg
, def
)
989 CHECK_STRING (arg
, 0);
991 if (strcmp (XSTRING (arg
)->data
, "black") == 0)
992 return BLACK_PIX_DEFAULT (f
);
993 else if (strcmp (XSTRING (arg
)->data
, "white") == 0)
994 return WHITE_PIX_DEFAULT (f
);
996 if (FRAME_X_DISPLAY_INFO (f
)->n_planes
== 1)
999 if (defined_color (f
, XSTRING (arg
)->data
, &cdef
, 1))
1002 Fsignal (Qundefined_color
, Fcons (arg
, Qnil
));
1005 /* Functions called only from `x_set_frame_param'
1006 to set individual parameters.
1008 If FRAME_X_WINDOW (f) is 0,
1009 the frame is being created and its X-window does not exist yet.
1010 In that case, just record the parameter's new value
1011 in the standard place; do not attempt to change the window. */
1014 x_set_foreground_color (f
, arg
, oldval
)
1016 Lisp_Object arg
, oldval
;
1018 f
->display
.x
->foreground_pixel
1019 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1020 if (FRAME_X_WINDOW (f
) != 0)
1023 XSetForeground (FRAME_X_DISPLAY (f
), f
->display
.x
->normal_gc
,
1024 f
->display
.x
->foreground_pixel
);
1025 XSetBackground (FRAME_X_DISPLAY (f
), f
->display
.x
->reverse_gc
,
1026 f
->display
.x
->foreground_pixel
);
1028 recompute_basic_faces (f
);
1029 if (FRAME_VISIBLE_P (f
))
1035 x_set_background_color (f
, arg
, oldval
)
1037 Lisp_Object arg
, oldval
;
1042 f
->display
.x
->background_pixel
1043 = x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
1045 if (FRAME_X_WINDOW (f
) != 0)
1048 /* The main frame area. */
1049 XSetBackground (FRAME_X_DISPLAY (f
), f
->display
.x
->normal_gc
,
1050 f
->display
.x
->background_pixel
);
1051 XSetForeground (FRAME_X_DISPLAY (f
), f
->display
.x
->reverse_gc
,
1052 f
->display
.x
->background_pixel
);
1053 XSetForeground (FRAME_X_DISPLAY (f
), f
->display
.x
->cursor_gc
,
1054 f
->display
.x
->background_pixel
);
1055 XSetWindowBackground (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1056 f
->display
.x
->background_pixel
);
1059 for (bar
= FRAME_SCROLL_BARS (f
); !NILP (bar
);
1060 bar
= XSCROLL_BAR (bar
)->next
)
1061 XSetWindowBackground (FRAME_X_DISPLAY (f
),
1062 SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
)),
1063 f
->display
.x
->background_pixel
);
1067 recompute_basic_faces (f
);
1069 if (FRAME_VISIBLE_P (f
))
1075 x_set_mouse_color (f
, arg
, oldval
)
1077 Lisp_Object arg
, oldval
;
1079 Cursor cursor
, nontext_cursor
, mode_cursor
, cross_cursor
;
1082 if (!EQ (Qnil
, arg
))
1083 f
->display
.x
->mouse_pixel
1084 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1085 mask_color
= f
->display
.x
->background_pixel
;
1086 /* No invisible pointers. */
1087 if (mask_color
== f
->display
.x
->mouse_pixel
1088 && mask_color
== f
->display
.x
->background_pixel
)
1089 f
->display
.x
->mouse_pixel
= f
->display
.x
->foreground_pixel
;
1093 /* It's not okay to crash if the user selects a screwy cursor. */
1096 if (!EQ (Qnil
, Vx_pointer_shape
))
1098 CHECK_NUMBER (Vx_pointer_shape
, 0);
1099 cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XINT (Vx_pointer_shape
));
1102 cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_xterm
);
1103 x_check_errors (f
, "bad text pointer cursor: %s");
1105 if (!EQ (Qnil
, Vx_nontext_pointer_shape
))
1107 CHECK_NUMBER (Vx_nontext_pointer_shape
, 0);
1108 nontext_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
),
1109 XINT (Vx_nontext_pointer_shape
));
1112 nontext_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_left_ptr
);
1113 x_check_errors (f
, "bad nontext pointer cursor: %s");
1115 if (!EQ (Qnil
, Vx_mode_pointer_shape
))
1117 CHECK_NUMBER (Vx_mode_pointer_shape
, 0);
1118 mode_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
),
1119 XINT (Vx_mode_pointer_shape
));
1122 mode_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_xterm
);
1123 x_check_errors (f
, "bad modeline pointer cursor: %s");
1125 if (!EQ (Qnil
, Vx_sensitive_text_pointer_shape
))
1127 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
, 0);
1129 = XCreateFontCursor (FRAME_X_DISPLAY (f
),
1130 XINT (Vx_sensitive_text_pointer_shape
));
1133 cross_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_crosshair
);
1135 /* Check and report errors with the above calls. */
1136 x_check_errors (f
, "can't set cursor shape: %s");
1137 x_uncatch_errors (f
);
1140 XColor fore_color
, back_color
;
1142 fore_color
.pixel
= f
->display
.x
->mouse_pixel
;
1143 back_color
.pixel
= mask_color
;
1144 XQueryColor (FRAME_X_DISPLAY (f
),
1145 DefaultColormap (FRAME_X_DISPLAY (f
),
1146 DefaultScreen (FRAME_X_DISPLAY (f
))),
1148 XQueryColor (FRAME_X_DISPLAY (f
),
1149 DefaultColormap (FRAME_X_DISPLAY (f
),
1150 DefaultScreen (FRAME_X_DISPLAY (f
))),
1152 XRecolorCursor (FRAME_X_DISPLAY (f
), cursor
,
1153 &fore_color
, &back_color
);
1154 XRecolorCursor (FRAME_X_DISPLAY (f
), nontext_cursor
,
1155 &fore_color
, &back_color
);
1156 XRecolorCursor (FRAME_X_DISPLAY (f
), mode_cursor
,
1157 &fore_color
, &back_color
);
1158 XRecolorCursor (FRAME_X_DISPLAY (f
), cross_cursor
,
1159 &fore_color
, &back_color
);
1162 if (FRAME_X_WINDOW (f
) != 0)
1164 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
1167 if (cursor
!= f
->display
.x
->text_cursor
&& f
->display
.x
->text_cursor
!= 0)
1168 XFreeCursor (FRAME_X_DISPLAY (f
), f
->display
.x
->text_cursor
);
1169 f
->display
.x
->text_cursor
= cursor
;
1171 if (nontext_cursor
!= f
->display
.x
->nontext_cursor
1172 && f
->display
.x
->nontext_cursor
!= 0)
1173 XFreeCursor (FRAME_X_DISPLAY (f
), f
->display
.x
->nontext_cursor
);
1174 f
->display
.x
->nontext_cursor
= nontext_cursor
;
1176 if (mode_cursor
!= f
->display
.x
->modeline_cursor
1177 && f
->display
.x
->modeline_cursor
!= 0)
1178 XFreeCursor (FRAME_X_DISPLAY (f
), f
->display
.x
->modeline_cursor
);
1179 f
->display
.x
->modeline_cursor
= mode_cursor
;
1180 if (cross_cursor
!= f
->display
.x
->cross_cursor
1181 && f
->display
.x
->cross_cursor
!= 0)
1182 XFreeCursor (FRAME_X_DISPLAY (f
), f
->display
.x
->cross_cursor
);
1183 f
->display
.x
->cross_cursor
= cross_cursor
;
1185 XFlush (FRAME_X_DISPLAY (f
));
1190 x_set_cursor_color (f
, arg
, oldval
)
1192 Lisp_Object arg
, oldval
;
1194 unsigned long fore_pixel
;
1196 if (!EQ (Vx_cursor_fore_pixel
, Qnil
))
1197 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
1198 WHITE_PIX_DEFAULT (f
));
1200 fore_pixel
= f
->display
.x
->background_pixel
;
1201 f
->display
.x
->cursor_pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1203 /* Make sure that the cursor color differs from the background color. */
1204 if (f
->display
.x
->cursor_pixel
== f
->display
.x
->background_pixel
)
1206 f
->display
.x
->cursor_pixel
= f
->display
.x
->mouse_pixel
;
1207 if (f
->display
.x
->cursor_pixel
== fore_pixel
)
1208 fore_pixel
= f
->display
.x
->background_pixel
;
1210 f
->display
.x
->cursor_foreground_pixel
= fore_pixel
;
1212 if (FRAME_X_WINDOW (f
) != 0)
1215 XSetBackground (FRAME_X_DISPLAY (f
), f
->display
.x
->cursor_gc
,
1216 f
->display
.x
->cursor_pixel
);
1217 XSetForeground (FRAME_X_DISPLAY (f
), f
->display
.x
->cursor_gc
,
1221 if (FRAME_VISIBLE_P (f
))
1223 x_display_cursor (f
, 0);
1224 x_display_cursor (f
, 1);
1229 /* Set the border-color of frame F to value described by ARG.
1230 ARG can be a string naming a color.
1231 The border-color is used for the border that is drawn by the X server.
1232 Note that this does not fully take effect if done before
1233 F has an x-window; it must be redone when the window is created.
1235 Note: this is done in two routines because of the way X10 works.
1237 Note: under X11, this is normally the province of the window manager,
1238 and so emacs' border colors may be overridden. */
1241 x_set_border_color (f
, arg
, oldval
)
1243 Lisp_Object arg
, oldval
;
1248 CHECK_STRING (arg
, 0);
1249 str
= XSTRING (arg
)->data
;
1251 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1253 x_set_border_pixel (f
, pix
);
1256 /* Set the border-color of frame F to pixel value PIX.
1257 Note that this does not fully take effect if done before
1258 F has an x-window. */
1260 x_set_border_pixel (f
, pix
)
1264 f
->display
.x
->border_pixel
= pix
;
1266 if (FRAME_X_WINDOW (f
) != 0 && f
->display
.x
->border_width
> 0)
1272 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1276 if (FRAME_VISIBLE_P (f
))
1282 x_set_cursor_type (f
, arg
, oldval
)
1284 Lisp_Object arg
, oldval
;
1287 FRAME_DESIRED_CURSOR (f
) = bar_cursor
;
1292 FRAME_DESIRED_CURSOR (f
) = filled_box_cursor
;
1293 /* Error messages commented out because people have trouble fixing
1294 .Xdefaults with Emacs, when it has something bad in it. */
1298 ("the `cursor-type' frame parameter should be either `bar' or `box'");
1301 /* Make sure the cursor gets redrawn. This is overkill, but how
1302 often do people change cursor types? */
1303 update_mode_lines
++;
1307 x_set_icon_type (f
, arg
, oldval
)
1309 Lisp_Object arg
, oldval
;
1316 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1319 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1324 result
= x_text_icon (f
, 0);
1326 result
= x_bitmap_icon (f
, arg
);
1331 error ("No icon window available");
1334 /* If the window was unmapped (and its icon was mapped),
1335 the new icon is not mapped, so map the window in its stead. */
1336 if (FRAME_VISIBLE_P (f
))
1338 #ifdef USE_X_TOOLKIT
1339 XtPopup (f
->display
.x
->widget
, XtGrabNone
);
1341 XMapWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
1344 XFlush (FRAME_X_DISPLAY (f
));
1348 /* Return non-nil if frame F wants a bitmap icon. */
1356 tem
= assq_no_quit (Qicon_type
, f
->param_alist
);
1358 return XCONS (tem
)->cdr
;
1363 extern Lisp_Object
x_new_font ();
1366 x_set_font (f
, arg
, oldval
)
1368 Lisp_Object arg
, oldval
;
1372 CHECK_STRING (arg
, 1);
1375 result
= x_new_font (f
, XSTRING (arg
)->data
);
1378 if (EQ (result
, Qnil
))
1379 error ("Font \"%s\" is not defined", XSTRING (arg
)->data
);
1380 else if (EQ (result
, Qt
))
1381 error ("the characters of the given font have varying widths");
1382 else if (STRINGP (result
))
1384 recompute_basic_faces (f
);
1385 store_frame_param (f
, Qfont
, result
);
1392 x_set_border_width (f
, arg
, oldval
)
1394 Lisp_Object arg
, oldval
;
1396 CHECK_NUMBER (arg
, 0);
1398 if (XINT (arg
) == f
->display
.x
->border_width
)
1401 if (FRAME_X_WINDOW (f
) != 0)
1402 error ("Cannot change the border width of a window");
1404 f
->display
.x
->border_width
= XINT (arg
);
1408 x_set_internal_border_width (f
, arg
, oldval
)
1410 Lisp_Object arg
, oldval
;
1413 int old
= f
->display
.x
->internal_border_width
;
1415 CHECK_NUMBER (arg
, 0);
1416 f
->display
.x
->internal_border_width
= XINT (arg
);
1417 if (f
->display
.x
->internal_border_width
< 0)
1418 f
->display
.x
->internal_border_width
= 0;
1420 if (f
->display
.x
->internal_border_width
== old
)
1423 if (FRAME_X_WINDOW (f
) != 0)
1426 x_set_window_size (f
, 0, f
->width
, f
->height
);
1428 x_set_resize_hint (f
);
1430 XFlush (FRAME_X_DISPLAY (f
));
1432 SET_FRAME_GARBAGED (f
);
1437 x_set_visibility (f
, value
, oldval
)
1439 Lisp_Object value
, oldval
;
1442 XSETFRAME (frame
, f
);
1445 Fmake_frame_invisible (frame
, Qt
);
1446 else if (EQ (value
, Qicon
))
1447 Ficonify_frame (frame
);
1449 Fmake_frame_visible (frame
);
1453 x_set_menu_bar_lines_1 (window
, n
)
1457 struct window
*w
= XWINDOW (window
);
1459 XSETFASTINT (w
->top
, XFASTINT (w
->top
) + n
);
1460 XSETFASTINT (w
->height
, XFASTINT (w
->height
) - n
);
1462 /* Handle just the top child in a vertical split. */
1463 if (!NILP (w
->vchild
))
1464 x_set_menu_bar_lines_1 (w
->vchild
, n
);
1466 /* Adjust all children in a horizontal split. */
1467 for (window
= w
->hchild
; !NILP (window
); window
= w
->next
)
1469 w
= XWINDOW (window
);
1470 x_set_menu_bar_lines_1 (window
, n
);
1475 x_set_menu_bar_lines (f
, value
, oldval
)
1477 Lisp_Object value
, oldval
;
1480 int olines
= FRAME_MENU_BAR_LINES (f
);
1482 /* Right now, menu bars don't work properly in minibuf-only frames;
1483 most of the commands try to apply themselves to the minibuffer
1484 frame itslef, and get an error because you can't switch buffers
1485 in or split the minibuffer window. */
1486 if (FRAME_MINIBUF_ONLY_P (f
))
1489 if (INTEGERP (value
))
1490 nlines
= XINT (value
);
1494 #ifdef USE_X_TOOLKIT
1495 FRAME_MENU_BAR_LINES (f
) = 0;
1497 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
1500 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
1501 free_frame_menubar (f
);
1502 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
1503 f
->display
.x
->menubar_widget
= 0;
1505 #else /* not USE_X_TOOLKIT */
1506 FRAME_MENU_BAR_LINES (f
) = nlines
;
1507 x_set_menu_bar_lines_1 (f
->root_window
, nlines
- olines
);
1508 #endif /* not USE_X_TOOLKIT */
1511 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1514 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1515 name; if NAME is a string, set F's name to NAME and set
1516 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1518 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1519 suggesting a new name, which lisp code should override; if
1520 F->explicit_name is set, ignore the new name; otherwise, set it. */
1523 x_set_name (f
, name
, explicit)
1528 /* Make sure that requests from lisp code override requests from
1529 Emacs redisplay code. */
1532 /* If we're switching from explicit to implicit, we had better
1533 update the mode lines and thereby update the title. */
1534 if (f
->explicit_name
&& NILP (name
))
1535 update_mode_lines
= 1;
1537 f
->explicit_name
= ! NILP (name
);
1539 else if (f
->explicit_name
)
1542 /* If NAME is nil, set the name to the x_id_name. */
1545 /* Check for no change needed in this very common case
1546 before we do any consing. */
1547 if (!strcmp (FRAME_X_DISPLAY_INFO (f
)->x_id_name
,
1548 XSTRING (f
->name
)->data
))
1550 name
= build_string (FRAME_X_DISPLAY_INFO (f
)->x_id_name
);
1553 CHECK_STRING (name
, 0);
1555 /* Don't change the name if it's already NAME. */
1556 if (! NILP (Fstring_equal (name
, f
->name
)))
1559 if (FRAME_X_WINDOW (f
))
1565 text
.value
= XSTRING (name
)->data
;
1566 text
.encoding
= XA_STRING
;
1568 text
.nitems
= XSTRING (name
)->size
;
1569 #ifdef USE_X_TOOLKIT
1570 XSetWMName (FRAME_X_DISPLAY (f
),
1571 XtWindow (f
->display
.x
->widget
), &text
);
1572 XSetWMIconName (FRAME_X_DISPLAY (f
), XtWindow (f
->display
.x
->widget
),
1574 #else /* not USE_X_TOOLKIT */
1575 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &text
);
1576 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &text
);
1577 #endif /* not USE_X_TOOLKIT */
1579 #else /* not HAVE_X11R4 */
1580 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1581 XSTRING (name
)->data
);
1582 XStoreName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1583 XSTRING (name
)->data
);
1584 #endif /* not HAVE_X11R4 */
1591 /* This function should be called when the user's lisp code has
1592 specified a name for the frame; the name will override any set by the
1595 x_explicitly_set_name (f
, arg
, oldval
)
1597 Lisp_Object arg
, oldval
;
1599 x_set_name (f
, arg
, 1);
1602 /* This function should be called by Emacs redisplay code to set the
1603 name; names set this way will never override names set by the user's
1606 x_implicitly_set_name (f
, arg
, oldval
)
1608 Lisp_Object arg
, oldval
;
1610 x_set_name (f
, arg
, 0);
1614 x_set_autoraise (f
, arg
, oldval
)
1616 Lisp_Object arg
, oldval
;
1618 f
->auto_raise
= !EQ (Qnil
, arg
);
1622 x_set_autolower (f
, arg
, oldval
)
1624 Lisp_Object arg
, oldval
;
1626 f
->auto_lower
= !EQ (Qnil
, arg
);
1630 x_set_unsplittable (f
, arg
, oldval
)
1632 Lisp_Object arg
, oldval
;
1634 f
->no_split
= !NILP (arg
);
1638 x_set_vertical_scroll_bars (f
, arg
, oldval
)
1640 Lisp_Object arg
, oldval
;
1642 if (NILP (arg
) != ! FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
1644 FRAME_HAS_VERTICAL_SCROLL_BARS (f
) = ! NILP (arg
);
1646 /* We set this parameter before creating the X window for the
1647 frame, so we can get the geometry right from the start.
1648 However, if the window hasn't been created yet, we shouldn't
1649 call x_set_window_size. */
1650 if (FRAME_X_WINDOW (f
))
1651 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
1656 x_set_scroll_bar_width (f
, arg
, oldval
)
1658 Lisp_Object arg
, oldval
;
1662 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = 0;
1663 FRAME_SCROLL_BAR_COLS (f
) = 2;
1665 else if (INTEGERP (arg
) && XINT (arg
) > 0
1666 && XFASTINT (arg
) != FRAME_SCROLL_BAR_PIXEL_WIDTH (f
))
1668 int wid
= FONT_WIDTH (f
->display
.x
->font
);
1669 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = XFASTINT (arg
);
1670 FRAME_SCROLL_BAR_COLS (f
) = (XFASTINT (arg
) + wid
-1) / wid
;
1671 if (FRAME_X_WINDOW (f
))
1672 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
1676 /* Subroutines of creating an X frame. */
1678 /* Make sure that Vx_resource_name is set to a reasonable value. */
1680 validate_x_resource_name ()
1682 if (STRINGP (Vx_resource_name
))
1684 int len
= XSTRING (Vx_resource_name
)->size
;
1685 unsigned char *p
= XSTRING (Vx_resource_name
)->data
;
1688 /* Allow only letters, digits, - and _,
1689 because those are all that X allows. */
1690 for (i
= 0; i
< len
; i
++)
1693 if (! ((c
>= 'a' && c
<= 'z')
1694 || (c
>= 'A' && c
<= 'Z')
1695 || (c
>= '0' && c
<= '9')
1696 || c
== '-' || c
== '_'))
1702 Vx_resource_name
= make_string ("emacs", 5);
1706 extern char *x_get_string_resource ();
1708 DEFUN ("x-get-resource", Fx_get_resource
, Sx_get_resource
, 2, 4, 0,
1709 "Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.\n\
1710 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the\n\
1711 class, where INSTANCE is the name under which Emacs was invoked, or\n\
1712 the name specified by the `-name' or `-rn' command-line arguments.\n\
1714 The optional arguments COMPONENT and SUBCLASS add to the key and the\n\
1715 class, respectively. You must specify both of them or neither.\n\
1716 If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'\n\
1717 and the class is `Emacs.CLASS.SUBCLASS'.")
1718 (attribute
, class, component
, subclass
)
1719 Lisp_Object attribute
, class, component
, subclass
;
1721 register char *value
;
1724 Lisp_Object resname
;
1728 CHECK_STRING (attribute
, 0);
1729 CHECK_STRING (class, 0);
1731 if (!NILP (component
))
1732 CHECK_STRING (component
, 1);
1733 if (!NILP (subclass
))
1734 CHECK_STRING (subclass
, 2);
1735 if (NILP (component
) != NILP (subclass
))
1736 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
1738 validate_x_resource_name ();
1739 resname
= Vx_resource_name
;
1741 if (NILP (component
))
1743 /* Allocate space for the components, the dots which separate them,
1744 and the final '\0'. */
1745 name_key
= (char *) alloca (XSTRING (resname
)->size
1746 + XSTRING (attribute
)->size
1748 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
1749 + XSTRING (class)->size
1752 sprintf (name_key
, "%s.%s",
1753 XSTRING (resname
)->data
,
1754 XSTRING (attribute
)->data
);
1755 sprintf (class_key
, "%s.%s",
1757 XSTRING (class)->data
);
1761 name_key
= (char *) alloca (XSTRING (resname
)->size
1762 + XSTRING (component
)->size
1763 + XSTRING (attribute
)->size
1766 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
1767 + XSTRING (class)->size
1768 + XSTRING (subclass
)->size
1771 sprintf (name_key
, "%s.%s.%s",
1772 XSTRING (resname
)->data
,
1773 XSTRING (component
)->data
,
1774 XSTRING (attribute
)->data
);
1775 sprintf (class_key
, "%s.%s.%s",
1777 XSTRING (class)->data
,
1778 XSTRING (subclass
)->data
);
1781 value
= x_get_string_resource (check_x_display_info (Qnil
)->xrdb
,
1782 name_key
, class_key
);
1784 if (value
!= (char *) 0)
1785 return build_string (value
);
1790 /* Used when C code wants a resource value. */
1793 x_get_resource_string (attribute
, class)
1794 char *attribute
, *class;
1796 register char *value
;
1800 /* Allocate space for the components, the dots which separate them,
1801 and the final '\0'. */
1802 name_key
= (char *) alloca (XSTRING (Vinvocation_name
)->size
1803 + strlen (attribute
) + 2);
1804 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
1805 + strlen (class) + 2);
1807 sprintf (name_key
, "%s.%s",
1808 XSTRING (Vinvocation_name
)->data
,
1810 sprintf (class_key
, "%s.%s", EMACS_CLASS
, class);
1812 return x_get_string_resource (FRAME_X_DISPLAY_INFO (selected_frame
)->xrdb
,
1813 name_key
, class_key
);
1816 /* Types we might convert a resource string into. */
1819 number
, boolean
, string
, symbol
1822 /* Return the value of parameter PARAM.
1824 First search ALIST, then Vdefault_frame_alist, then the X defaults
1825 database, using ATTRIBUTE as the attribute name and CLASS as its class.
1827 Convert the resource to the type specified by desired_type.
1829 If no default is specified, return Qunbound. If you call
1830 x_get_arg, make sure you deal with Qunbound in a reasonable way,
1831 and don't let it get stored in any lisp-visible variables! */
1834 x_get_arg (alist
, param
, attribute
, class, type
)
1835 Lisp_Object alist
, param
;
1838 enum resource_types type
;
1840 register Lisp_Object tem
;
1842 tem
= Fassq (param
, alist
);
1844 tem
= Fassq (param
, Vdefault_frame_alist
);
1850 tem
= Fx_get_resource (build_string (attribute
),
1851 build_string (class),
1860 return make_number (atoi (XSTRING (tem
)->data
));
1863 tem
= Fdowncase (tem
);
1864 if (!strcmp (XSTRING (tem
)->data
, "on")
1865 || !strcmp (XSTRING (tem
)->data
, "true"))
1874 /* As a special case, we map the values `true' and `on'
1875 to Qt, and `false' and `off' to Qnil. */
1878 lower
= Fdowncase (tem
);
1879 if (!strcmp (XSTRING (lower
)->data
, "on")
1880 || !strcmp (XSTRING (lower
)->data
, "true"))
1882 else if (!strcmp (XSTRING (lower
)->data
, "off")
1883 || !strcmp (XSTRING (lower
)->data
, "false"))
1886 return Fintern (tem
, Qnil
);
1899 /* Record in frame F the specified or default value according to ALIST
1900 of the parameter named PARAM (a Lisp symbol).
1901 If no value is specified for PARAM, look for an X default for XPROP
1902 on the frame named NAME.
1903 If that is not found either, use the value DEFLT. */
1906 x_default_parameter (f
, alist
, prop
, deflt
, xprop
, xclass
, type
)
1913 enum resource_types type
;
1917 tem
= x_get_arg (alist
, prop
, xprop
, xclass
, type
);
1918 if (EQ (tem
, Qunbound
))
1920 x_set_frame_parameters (f
, Fcons (Fcons (prop
, tem
), Qnil
));
1924 DEFUN ("x-parse-geometry", Fx_parse_geometry
, Sx_parse_geometry
, 1, 1, 0,
1925 "Parse an X-style geometry string STRING.\n\
1926 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).\n\
1927 The properties returned may include `top', `left', `height', and `width'.\n\
1928 The value of `left' or `top' may be an integer,\n\
1929 or a list (+ N) meaning N pixels relative to top/left corner,\n\
1930 or a list (- N) meaning -N pixels relative to bottom/right corner.")
1935 unsigned int width
, height
;
1938 CHECK_STRING (string
, 0);
1940 geometry
= XParseGeometry ((char *) XSTRING (string
)->data
,
1941 &x
, &y
, &width
, &height
);
1944 if (!!(geometry
& XValue
) != !!(geometry
& YValue
))
1945 error ("Must specify both x and y position, or neither");
1949 if (geometry
& XValue
)
1951 Lisp_Object element
;
1953 if (x
>= 0 && (geometry
& XNegative
))
1954 element
= Fcons (Qleft
, Fcons (Qminus
, Fcons (make_number (-x
), Qnil
)));
1955 else if (x
< 0 && ! (geometry
& XNegative
))
1956 element
= Fcons (Qleft
, Fcons (Qplus
, Fcons (make_number (x
), Qnil
)));
1958 element
= Fcons (Qleft
, make_number (x
));
1959 result
= Fcons (element
, result
);
1962 if (geometry
& YValue
)
1964 Lisp_Object element
;
1966 if (y
>= 0 && (geometry
& YNegative
))
1967 element
= Fcons (Qtop
, Fcons (Qminus
, Fcons (make_number (-y
), Qnil
)));
1968 else if (y
< 0 && ! (geometry
& YNegative
))
1969 element
= Fcons (Qtop
, Fcons (Qplus
, Fcons (make_number (y
), Qnil
)));
1971 element
= Fcons (Qtop
, make_number (y
));
1972 result
= Fcons (element
, result
);
1975 if (geometry
& WidthValue
)
1976 result
= Fcons (Fcons (Qwidth
, make_number (width
)), result
);
1977 if (geometry
& HeightValue
)
1978 result
= Fcons (Fcons (Qheight
, make_number (height
)), result
);
1983 /* Calculate the desired size and position of this window,
1984 and return the flags saying which aspects were specified.
1986 This function does not make the coordinates positive. */
1988 #define DEFAULT_ROWS 40
1989 #define DEFAULT_COLS 80
1992 x_figure_window_size (f
, parms
)
1996 register Lisp_Object tem0
, tem1
, tem2
;
1997 int height
, width
, left
, top
;
1998 register int geometry
;
1999 long window_prompting
= 0;
2001 /* Default values if we fall through.
2002 Actually, if that happens we should get
2003 window manager prompting. */
2004 f
->width
= DEFAULT_COLS
;
2005 f
->height
= DEFAULT_ROWS
;
2006 /* Window managers expect that if program-specified
2007 positions are not (0,0), they're intentional, not defaults. */
2008 f
->display
.x
->top_pos
= 0;
2009 f
->display
.x
->left_pos
= 0;
2011 tem0
= x_get_arg (parms
, Qheight
, 0, 0, number
);
2012 tem1
= x_get_arg (parms
, Qwidth
, 0, 0, number
);
2013 tem2
= x_get_arg (parms
, Quser_size
, 0, 0, number
);
2014 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
2016 if (!EQ (tem0
, Qunbound
))
2018 CHECK_NUMBER (tem0
, 0);
2019 f
->height
= XINT (tem0
);
2021 if (!EQ (tem1
, Qunbound
))
2023 CHECK_NUMBER (tem1
, 0);
2024 f
->width
= XINT (tem1
);
2026 if (!NILP (tem2
) && !EQ (tem2
, Qunbound
))
2027 window_prompting
|= USSize
;
2029 window_prompting
|= PSize
;
2032 f
->display
.x
->vertical_scroll_bar_extra
2033 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
2035 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0
2036 ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f
)
2037 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->display
.x
->font
)));
2038 f
->display
.x
->pixel_width
= CHAR_TO_PIXEL_WIDTH (f
, f
->width
);
2039 f
->display
.x
->pixel_height
= CHAR_TO_PIXEL_HEIGHT (f
, f
->height
);
2041 tem0
= x_get_arg (parms
, Qtop
, 0, 0, number
);
2042 tem1
= x_get_arg (parms
, Qleft
, 0, 0, number
);
2043 tem2
= x_get_arg (parms
, Quser_position
, 0, 0, number
);
2044 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
2046 if (EQ (tem0
, Qminus
))
2048 f
->display
.x
->top_pos
= 0;
2049 window_prompting
|= YNegative
;
2051 else if (CONSP (tem0
) && EQ (XCONS (tem0
)->car
, Qminus
)
2052 && CONSP (XCONS (tem0
)->cdr
)
2053 && INTEGERP (XCONS (XCONS (tem0
)->cdr
)->car
))
2055 f
->display
.x
->top_pos
= - XINT (XCONS (XCONS (tem0
)->cdr
)->car
);
2056 window_prompting
|= YNegative
;
2058 else if (CONSP (tem0
) && EQ (XCONS (tem0
)->car
, Qplus
)
2059 && CONSP (XCONS (tem0
)->cdr
)
2060 && INTEGERP (XCONS (XCONS (tem0
)->cdr
)->car
))
2062 f
->display
.x
->top_pos
= XINT (XCONS (XCONS (tem0
)->cdr
)->car
);
2064 else if (EQ (tem0
, Qunbound
))
2065 f
->display
.x
->top_pos
= 0;
2068 CHECK_NUMBER (tem0
, 0);
2069 f
->display
.x
->top_pos
= XINT (tem0
);
2070 if (f
->display
.x
->top_pos
< 0)
2071 window_prompting
|= YNegative
;
2074 if (EQ (tem1
, Qminus
))
2076 f
->display
.x
->left_pos
= 0;
2077 window_prompting
|= XNegative
;
2079 else if (CONSP (tem1
) && EQ (XCONS (tem1
)->car
, Qminus
)
2080 && CONSP (XCONS (tem1
)->cdr
)
2081 && INTEGERP (XCONS (XCONS (tem1
)->cdr
)->car
))
2083 f
->display
.x
->left_pos
= - XINT (XCONS (XCONS (tem1
)->cdr
)->car
);
2084 window_prompting
|= XNegative
;
2086 else if (CONSP (tem1
) && EQ (XCONS (tem1
)->car
, Qplus
)
2087 && CONSP (XCONS (tem1
)->cdr
)
2088 && INTEGERP (XCONS (XCONS (tem1
)->cdr
)->car
))
2090 f
->display
.x
->left_pos
= XINT (XCONS (XCONS (tem1
)->cdr
)->car
);
2092 else if (EQ (tem1
, Qunbound
))
2093 f
->display
.x
->left_pos
= 0;
2096 CHECK_NUMBER (tem1
, 0);
2097 f
->display
.x
->left_pos
= XINT (tem1
);
2098 if (f
->display
.x
->left_pos
< 0)
2099 window_prompting
|= XNegative
;
2103 window_prompting
|= USPosition
;
2105 window_prompting
|= PPosition
;
2108 return window_prompting
;
2111 #if !defined (HAVE_X11R4) && !defined (HAVE_XSETWMPROTOCOLS)
2114 XSetWMProtocols (dpy
, w
, protocols
, count
)
2121 prop
= XInternAtom (dpy
, "WM_PROTOCOLS", False
);
2122 if (prop
== None
) return False
;
2123 XChangeProperty (dpy
, w
, prop
, XA_ATOM
, 32, PropModeReplace
,
2124 (unsigned char *) protocols
, count
);
2127 #endif /* not HAVE_X11R4 && not HAVE_XSETWMPROTOCOLS */
2129 #ifdef USE_X_TOOLKIT
2131 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
2132 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
2133 already be present because of the toolkit (Motif adds some of them,
2134 for example, but Xt doesn't). */
2137 hack_wm_protocols (f
, widget
)
2141 Display
*dpy
= XtDisplay (widget
);
2142 Window w
= XtWindow (widget
);
2143 int need_delete
= 1;
2149 Atom type
, *atoms
= 0;
2151 unsigned long nitems
= 0;
2152 unsigned long bytes_after
;
2154 if (Success
== XGetWindowProperty (dpy
, w
,
2155 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2156 0, 100, False
, XA_ATOM
,
2157 &type
, &format
, &nitems
, &bytes_after
,
2158 (unsigned char **) &atoms
)
2159 && format
== 32 && type
== XA_ATOM
)
2163 if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
)
2165 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
)
2167 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
)
2170 if (atoms
) XFree ((char *) atoms
);
2176 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2178 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
;
2180 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2182 XChangeProperty (dpy
, w
, FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2183 XA_ATOM
, 32, PropModeAppend
,
2184 (unsigned char *) props
, count
);
2190 #ifdef USE_X_TOOLKIT
2192 /* Create and set up the X widget for frame F. */
2195 x_window (f
, window_prompting
, minibuffer_only
)
2197 long window_prompting
;
2198 int minibuffer_only
;
2200 XClassHint class_hints
;
2201 XSetWindowAttributes attributes
;
2202 unsigned long attribute_mask
;
2204 Widget shell_widget
;
2206 Widget frame_widget
;
2213 if (STRINGP (f
->name
))
2214 name
= (char*) XSTRING (f
->name
)->data
;
2219 XtSetArg (al
[ac
], XtNallowShellResize
, 1); ac
++;
2220 XtSetArg (al
[ac
], XtNinput
, 1); ac
++;
2221 shell_widget
= XtCreatePopupShell ("shell",
2222 topLevelShellWidgetClass
,
2223 Xt_app_shell
, al
, ac
);
2225 f
->display
.x
->widget
= shell_widget
;
2226 /* maybe_set_screen_title_format (shell_widget); */
2228 pane_widget
= lw_create_widget ("main", "pane", widget_id_tick
++,
2229 (widget_value
*) NULL
,
2230 shell_widget
, False
,
2233 (lw_callback
) NULL
);
2235 f
->display
.x
->column_widget
= pane_widget
;
2237 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
2238 initialize_frame_menubar (f
);
2240 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2241 the emacs screen when changing menubar. This reduces flickering. */
2244 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2245 XtSetArg (al
[ac
], XtNshowGrip
, 0); ac
++;
2246 XtSetArg (al
[ac
], XtNallowResize
, 1); ac
++;
2247 XtSetArg (al
[ac
], XtNresizeToPreferred
, 1); ac
++;
2248 XtSetArg (al
[ac
], XtNemacsFrame
, f
); ac
++;
2249 frame_widget
= XtCreateWidget (name
,
2251 pane_widget
, al
, ac
);
2252 lw_set_main_areas (pane_widget
, f
->display
.x
->menubar_widget
, frame_widget
);
2254 f
->display
.x
->edit_widget
= frame_widget
;
2256 if (f
->display
.x
->menubar_widget
)
2257 XtManageChild (f
->display
.x
->menubar_widget
);
2258 XtManageChild (frame_widget
);
2260 /* Do some needed geometry management. */
2263 char *tem
, shell_position
[32];
2267 = (f
->display
.x
->menubar_widget
2268 ? (f
->display
.x
->menubar_widget
->core
.height
2269 + f
->display
.x
->menubar_widget
->core
.border_width
)
2272 if (FRAME_EXTERNAL_MENU_BAR (f
))
2275 XtVaGetValues (pane_widget
, XtNinternalBorderWidth
, &ibw
, NULL
);
2276 menubar_size
+= ibw
;
2279 if (window_prompting
& USPosition
)
2281 int left
= f
->display
.x
->left_pos
;
2282 int xneg
= window_prompting
& XNegative
;
2283 int top
= f
->display
.x
->top_pos
;
2284 int yneg
= window_prompting
& YNegative
;
2289 sprintf (shell_position
, "=%dx%d%c%d%c%d", PIXEL_WIDTH (f
),
2290 PIXEL_HEIGHT (f
) + menubar_size
,
2291 (xneg
? '-' : '+'), left
,
2292 (yneg
? '-' : '+'), top
);
2295 sprintf (shell_position
, "=%dx%d", PIXEL_WIDTH (f
),
2296 PIXEL_HEIGHT (f
) + menubar_size
);
2297 len
= strlen (shell_position
) + 1;
2298 tem
= (char *) xmalloc (len
);
2299 strncpy (tem
, shell_position
, len
);
2300 XtSetArg (al
[ac
], XtNgeometry
, tem
); ac
++;
2301 XtSetValues (shell_widget
, al
, ac
);
2304 x_calc_absolute_position (f
);
2306 XtManageChild (pane_widget
);
2307 XtRealizeWidget (shell_widget
);
2309 FRAME_X_WINDOW (f
) = XtWindow (frame_widget
);
2311 validate_x_resource_name ();
2312 class_hints
.res_name
= (char *) XSTRING (Vx_resource_name
)->data
;
2313 class_hints
.res_class
= EMACS_CLASS
;
2314 XSetClassHint (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
), &class_hints
);
2316 f
->display
.x
->wm_hints
.input
= True
;
2317 f
->display
.x
->wm_hints
.flags
|= InputHint
;
2318 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2319 &f
->display
.x
->wm_hints
);
2321 hack_wm_protocols (shell_widget
);
2324 XtAddEventHandler (shell_widget
, 0, True
, _XEditResCheckMessages
, 0);
2327 /* Do a stupid property change to force the server to generate a
2328 propertyNotify event so that the event_stream server timestamp will
2329 be initialized to something relevant to the time we created the window.
2331 XChangeProperty (XtDisplay (frame_widget
), XtWindow (frame_widget
),
2332 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2333 XA_ATOM
, 32, PropModeAppend
,
2334 (unsigned char*) NULL
, 0);
2336 /* Make all the standard events reach the Emacs frame. */
2337 attributes
.event_mask
= STANDARD_EVENT_SET
;
2338 attribute_mask
= CWEventMask
;
2339 XChangeWindowAttributes (XtDisplay (shell_widget
), XtWindow (shell_widget
),
2340 attribute_mask
, &attributes
);
2342 XtMapWidget (frame_widget
);
2344 /* x_set_name normally ignores requests to set the name if the
2345 requested name is the same as the current name. This is the one
2346 place where that assumption isn't correct; f->name is set, but
2347 the X server hasn't been told. */
2350 int explicit = f
->explicit_name
;
2352 f
->explicit_name
= 0;
2355 x_set_name (f
, name
, explicit);
2358 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2359 f
->display
.x
->text_cursor
);
2363 if (FRAME_X_WINDOW (f
) == 0)
2364 error ("Unable to create window");
2367 #else /* not USE_X_TOOLKIT */
2369 /* Create and set up the X window for frame F. */
2375 XClassHint class_hints
;
2376 XSetWindowAttributes attributes
;
2377 unsigned long attribute_mask
;
2379 attributes
.background_pixel
= f
->display
.x
->background_pixel
;
2380 attributes
.border_pixel
= f
->display
.x
->border_pixel
;
2381 attributes
.bit_gravity
= StaticGravity
;
2382 attributes
.backing_store
= NotUseful
;
2383 attributes
.save_under
= True
;
2384 attributes
.event_mask
= STANDARD_EVENT_SET
;
2385 attribute_mask
= (CWBackPixel
| CWBorderPixel
| CWBitGravity
2387 | CWBackingStore
| CWSaveUnder
2393 = XCreateWindow (FRAME_X_DISPLAY (f
),
2394 FRAME_X_DISPLAY_INFO (f
)->root_window
,
2395 f
->display
.x
->left_pos
,
2396 f
->display
.x
->top_pos
,
2397 PIXEL_WIDTH (f
), PIXEL_HEIGHT (f
),
2398 f
->display
.x
->border_width
,
2399 CopyFromParent
, /* depth */
2400 InputOutput
, /* class */
2401 FRAME_X_DISPLAY_INFO (f
)->visual
,
2402 attribute_mask
, &attributes
);
2404 validate_x_resource_name ();
2405 class_hints
.res_name
= (char *) XSTRING (Vx_resource_name
)->data
;
2406 class_hints
.res_class
= EMACS_CLASS
;
2407 XSetClassHint (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &class_hints
);
2409 /* This indicates that we use the "Passive Input" input model.
2410 Unless we do this, we don't get the Focus{In,Out} events that we
2411 need to draw the cursor correctly. Accursed bureaucrats.
2412 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2414 f
->display
.x
->wm_hints
.input
= True
;
2415 f
->display
.x
->wm_hints
.flags
|= InputHint
;
2416 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2417 &f
->display
.x
->wm_hints
);
2419 /* Request "save yourself" and "delete window" commands from wm. */
2422 protocols
[0] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2423 protocols
[1] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2424 XSetWMProtocols (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), protocols
, 2);
2427 /* x_set_name normally ignores requests to set the name if the
2428 requested name is the same as the current name. This is the one
2429 place where that assumption isn't correct; f->name is set, but
2430 the X server hasn't been told. */
2433 int explicit = f
->explicit_name
;
2435 f
->explicit_name
= 0;
2438 x_set_name (f
, name
, explicit);
2441 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2442 f
->display
.x
->text_cursor
);
2446 if (FRAME_X_WINDOW (f
) == 0)
2447 error ("Unable to create window");
2450 #endif /* not USE_X_TOOLKIT */
2452 /* Handle the icon stuff for this window. Perhaps later we might
2453 want an x_set_icon_position which can be called interactively as
2461 Lisp_Object icon_x
, icon_y
;
2463 /* Set the position of the icon. Note that twm groups all
2464 icons in an icon window. */
2465 icon_x
= x_get_arg (parms
, Qicon_left
, 0, 0, number
);
2466 icon_y
= x_get_arg (parms
, Qicon_top
, 0, 0, number
);
2467 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2469 CHECK_NUMBER (icon_x
, 0);
2470 CHECK_NUMBER (icon_y
, 0);
2472 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2473 error ("Both left and top icon corners of icon must be specified");
2477 if (! EQ (icon_x
, Qunbound
))
2478 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
2480 /* Start up iconic or window? */
2481 x_wm_set_window_state
2482 (f
, (EQ (x_get_arg (parms
, Qvisibility
, 0, 0, symbol
), Qicon
)
2489 /* Make the GC's needed for this window, setting the
2490 background, border and mouse colors; also create the
2491 mouse cursor and the gray border tile. */
2493 static char cursor_bits
[] =
2495 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2496 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2497 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2498 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2505 XGCValues gc_values
;
2511 /* Create the GC's of this frame.
2512 Note that many default values are used. */
2515 gc_values
.font
= f
->display
.x
->font
->fid
;
2516 gc_values
.foreground
= f
->display
.x
->foreground_pixel
;
2517 gc_values
.background
= f
->display
.x
->background_pixel
;
2518 gc_values
.line_width
= 0; /* Means 1 using fast algorithm. */
2519 f
->display
.x
->normal_gc
= XCreateGC (FRAME_X_DISPLAY (f
),
2521 GCLineWidth
| GCFont
2522 | GCForeground
| GCBackground
,
2525 /* Reverse video style. */
2526 gc_values
.foreground
= f
->display
.x
->background_pixel
;
2527 gc_values
.background
= f
->display
.x
->foreground_pixel
;
2528 f
->display
.x
->reverse_gc
= XCreateGC (FRAME_X_DISPLAY (f
),
2530 GCFont
| GCForeground
| GCBackground
2534 /* Cursor has cursor-color background, background-color foreground. */
2535 gc_values
.foreground
= f
->display
.x
->background_pixel
;
2536 gc_values
.background
= f
->display
.x
->cursor_pixel
;
2537 gc_values
.fill_style
= FillOpaqueStippled
;
2539 = XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
2540 FRAME_X_DISPLAY_INFO (f
)->root_window
,
2541 cursor_bits
, 16, 16);
2542 f
->display
.x
->cursor_gc
2543 = XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2544 (GCFont
| GCForeground
| GCBackground
2545 | GCFillStyle
| GCStipple
| GCLineWidth
),
2548 /* Create the gray border tile used when the pointer is not in
2549 the frame. Since this depends on the frame's pixel values,
2550 this must be done on a per-frame basis. */
2551 f
->display
.x
->border_tile
2552 = (XCreatePixmapFromBitmapData
2553 (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
2554 gray_bits
, gray_width
, gray_height
,
2555 f
->display
.x
->foreground_pixel
,
2556 f
->display
.x
->background_pixel
,
2557 DefaultDepth (FRAME_X_DISPLAY (f
),
2558 XScreenNumberOfScreen (FRAME_X_SCREEN (f
)))));
2563 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
2565 "Make a new X window, which is called a \"frame\" in Emacs terms.\n\
2566 Returns an Emacs frame object.\n\
2567 ALIST is an alist of frame parameters.\n\
2568 If the parameters specify that the frame should not have a minibuffer,\n\
2569 and do not specify a specific minibuffer window to use,\n\
2570 then `default-minibuffer-frame' must be a frame whose minibuffer can\n\
2571 be shared by the new frame.\n\
2573 This function is an internal primitive--use `make-frame' instead.")
2578 Lisp_Object frame
, tem
;
2580 int minibuffer_only
= 0;
2581 long window_prompting
= 0;
2583 int count
= specpdl_ptr
- specpdl
;
2584 struct gcpro gcpro1
;
2585 Lisp_Object display
;
2586 struct x_display_info
*dpyinfo
;
2590 display
= x_get_arg (parms
, Qdisplay
, 0, 0, 0);
2591 if (EQ (display
, Qunbound
))
2593 dpyinfo
= check_x_display_info (display
);
2595 name
= x_get_arg (parms
, Qname
, "title", "Title", string
);
2597 && ! EQ (name
, Qunbound
)
2599 error ("Invalid frame name--not a string or nil");
2601 tem
= x_get_arg (parms
, Qminibuffer
, 0, 0, symbol
);
2602 if (EQ (tem
, Qnone
) || NILP (tem
))
2603 f
= make_frame_without_minibuffer (Qnil
);
2604 else if (EQ (tem
, Qonly
))
2606 f
= make_minibuffer_frame ();
2607 minibuffer_only
= 1;
2609 else if (WINDOWP (tem
))
2610 f
= make_frame_without_minibuffer (tem
);
2614 /* Note that X Windows does support scroll bars. */
2615 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
2617 XSETFRAME (frame
, f
);
2620 f
->output_method
= output_x_window
;
2621 f
->display
.x
= (struct x_display
*) xmalloc (sizeof (struct x_display
));
2622 bzero (f
->display
.x
, sizeof (struct x_display
));
2623 f
->display
.x
->icon_bitmap
= -1;
2625 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
2627 /* Note that the frame has no physical cursor right now. */
2628 f
->phys_cursor_x
= -1;
2630 /* Set the name; the functions to which we pass f expect the name to
2632 if (EQ (name
, Qunbound
) || NILP (name
))
2634 f
->name
= build_string (dpyinfo
->x_id_name
);
2635 f
->explicit_name
= 0;
2640 f
->explicit_name
= 1;
2641 /* use the frame's title when getting resources for this frame. */
2642 specbind (Qx_resource_name
, name
);
2645 /* Extract the window parameters from the supplied values
2646 that are needed to determine window geometry. */
2650 font
= x_get_arg (parms
, Qfont
, "font", "Font", string
);
2652 /* First, try whatever font the caller has specified. */
2654 font
= x_new_font (f
, XSTRING (font
)->data
);
2655 /* Try out a font which we hope has bold and italic variations. */
2656 if (!STRINGP (font
))
2657 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
2658 if (! STRINGP (font
))
2659 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
2660 if (! STRINGP (font
))
2661 /* This was formerly the first thing tried, but it finds too many fonts
2662 and takes too long. */
2663 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
2664 /* If those didn't work, look for something which will at least work. */
2665 if (! STRINGP (font
))
2666 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
2668 if (! STRINGP (font
))
2669 font
= build_string ("fixed");
2671 x_default_parameter (f
, parms
, Qfont
, font
,
2672 "font", "Font", string
);
2675 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
2676 "borderwidth", "BorderWidth", number
);
2677 /* This defaults to 2 in order to match xterm. We recognize either
2678 internalBorderWidth or internalBorder (which is what xterm calls
2680 if (NILP (Fassq (Qinternal_border_width
, parms
)))
2684 value
= x_get_arg (parms
, Qinternal_border_width
,
2685 "internalBorder", "BorderWidth", number
);
2686 if (! EQ (value
, Qunbound
))
2687 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
2690 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (2),
2691 "internalBorderWidth", "BorderWidth", number
);
2692 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qt
,
2693 "verticalScrollBars", "ScrollBars", boolean
);
2695 /* Also do the stuff which must be set before the window exists. */
2696 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
2697 "foreground", "Foreground", string
);
2698 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
2699 "background", "Background", string
);
2700 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
2701 "pointerColor", "Foreground", string
);
2702 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
2703 "cursorColor", "Foreground", string
);
2704 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
2705 "borderColor", "BorderColor", string
);
2707 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
2708 "menuBar", "MenuBar", number
);
2709 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
2710 "scrollBarWidth", "ScrollBarWidth", number
);
2712 f
->display
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
2713 window_prompting
= x_figure_window_size (f
, parms
);
2715 if (window_prompting
& XNegative
)
2717 if (window_prompting
& YNegative
)
2718 f
->display
.x
->win_gravity
= SouthEastGravity
;
2720 f
->display
.x
->win_gravity
= NorthEastGravity
;
2724 if (window_prompting
& YNegative
)
2725 f
->display
.x
->win_gravity
= SouthWestGravity
;
2727 f
->display
.x
->win_gravity
= NorthWestGravity
;
2730 f
->display
.x
->size_hint_flags
= window_prompting
;
2732 #ifdef USE_X_TOOLKIT
2733 x_window (f
, window_prompting
, minibuffer_only
);
2739 init_frame_faces (f
);
2741 /* We need to do this after creating the X window, so that the
2742 icon-creation functions can say whose icon they're describing. */
2743 x_default_parameter (f
, parms
, Qicon_type
, Qnil
,
2744 "bitmapIcon", "BitmapIcon", symbol
);
2746 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
2747 "autoRaise", "AutoRaiseLower", boolean
);
2748 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
2749 "autoLower", "AutoRaiseLower", boolean
);
2750 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
2751 "cursorType", "CursorType", symbol
);
2753 /* Dimensions, especially f->height, must be done via change_frame_size.
2754 Change will not be effected unless different from the current
2758 f
->height
= f
->width
= 0;
2759 change_frame_size (f
, height
, width
, 1, 0);
2761 /* With the toolkit, the geometry management is done in x_window. */
2762 #ifndef USE_X_TOOLKIT
2764 x_wm_set_size_hint (f
, window_prompting
, 0);
2766 #endif /* USE_X_TOOLKIT */
2768 tem
= x_get_arg (parms
, Qunsplittable
, 0, 0, boolean
);
2769 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
2773 /* It is now ok to make the frame official
2774 even if we get an error below.
2775 And the frame needs to be on Vframe_list
2776 or making it visible won't work. */
2777 Vframe_list
= Fcons (frame
, Vframe_list
);
2779 /* Now that the frame is official, it counts as a reference to
2781 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
2783 /* Make the window appear on the frame and enable display,
2784 unless the caller says not to. */
2786 Lisp_Object visibility
;
2788 visibility
= x_get_arg (parms
, Qvisibility
, 0, 0, symbol
);
2789 if (EQ (visibility
, Qunbound
))
2792 if (EQ (visibility
, Qicon
))
2793 x_iconify_frame (f
);
2794 else if (! NILP (visibility
))
2795 x_make_frame_visible (f
);
2797 /* Must have been Qnil. */
2801 return unbind_to (count
, frame
);
2805 x_get_focus_frame ()
2808 if (! x_focus_frame
)
2811 XSETFRAME (xfocus
, x_focus_frame
);
2815 DEFUN ("focus-frame", Ffocus_frame
, Sfocus_frame
, 1, 1, 0,
2816 "Set the focus on FRAME.")
2820 CHECK_LIVE_FRAME (frame
, 0);
2822 if (FRAME_X_P (XFRAME (frame
)))
2825 x_focus_on_frame (XFRAME (frame
));
2833 DEFUN ("unfocus-frame", Funfocus_frame
, Sunfocus_frame
, 0, 0, 0,
2834 "If a frame has been focused, release it.")
2840 x_unfocus_frame (x_focus_frame
);
2847 DEFUN ("x-list-fonts", Fx_list_fonts
, Sx_list_fonts
, 1, 3, 0,
2848 "Return a list of the names of available fonts matching PATTERN.\n\
2849 If optional arguments FACE and FRAME are specified, return only fonts\n\
2850 the same size as FACE on FRAME.\n\
2852 PATTERN is a string, perhaps with wildcard characters;\n\
2853 the * character matches any substring, and\n\
2854 the ? character matches any single character.\n\
2855 PATTERN is case-insensitive.\n\
2856 FACE is a face name--a symbol.\n\
2858 The return value is a list of strings, suitable as arguments to\n\
2861 Fonts Emacs can't use (i.e. proportional fonts) may or may not be excluded\n\
2862 even if they match PATTERN and FACE.")
2863 (pattern
, face
, frame
)
2864 Lisp_Object pattern
, face
, frame
;
2869 XFontStruct
*size_ref
;
2874 CHECK_STRING (pattern
, 0);
2876 CHECK_SYMBOL (face
, 1);
2878 f
= check_x_frame (frame
);
2880 /* Determine the width standard for comparison with the fonts we find. */
2888 /* Don't die if we get called with a terminal frame. */
2889 if (! FRAME_X_P (f
))
2890 error ("non-X frame used in `x-list-fonts'");
2892 face_id
= face_name_id_number (f
, face
);
2894 if (face_id
< 0 || face_id
>= FRAME_N_PARAM_FACES (f
)
2895 || FRAME_PARAM_FACES (f
) [face_id
] == 0)
2896 size_ref
= f
->display
.x
->font
;
2899 size_ref
= FRAME_PARAM_FACES (f
) [face_id
]->font
;
2900 if (size_ref
== (XFontStruct
*) (~0))
2901 size_ref
= f
->display
.x
->font
;
2905 /* See if we cached the result for this particular query. */
2906 list
= Fassoc (pattern
,
2907 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
);
2909 /* We have info in the cache for this PATTERN. */
2912 Lisp_Object tem
, newlist
;
2914 /* We have info about this pattern. */
2915 list
= XCONS (list
)->cdr
;
2922 /* Filter the cached info and return just the fonts that match FACE. */
2924 for (tem
= list
; CONSP (tem
); tem
= XCONS (tem
)->cdr
)
2926 XFontStruct
*thisinfo
;
2928 thisinfo
= XLoadQueryFont (FRAME_X_DISPLAY (f
),
2929 XSTRING (XCONS (tem
)->car
)->data
);
2931 if (thisinfo
&& same_size_fonts (thisinfo
, size_ref
))
2932 newlist
= Fcons (XCONS (tem
)->car
, newlist
);
2934 XFreeFont (FRAME_X_DISPLAY (f
), thisinfo
);
2944 /* Solaris 2.3 has a bug in XListFontsWithInfo. */
2945 #ifdef BROKEN_XLISTFONTSWITHINFO
2946 names
= XListFonts (FRAME_X_DISPLAY (f
),
2947 XSTRING (pattern
)->data
,
2948 2000, /* maxnames */
2949 &num_fonts
); /* count_return */
2951 names
= XListFontsWithInfo (FRAME_X_DISPLAY (f
),
2952 XSTRING (pattern
)->data
,
2953 2000, /* maxnames */
2954 &num_fonts
, /* count_return */
2955 &info
); /* info_return */
2964 Lisp_Object full_list
;
2966 /* Make a list of all the fonts we got back.
2967 Store that in the font cache for the display. */
2969 for (i
= 0; i
< num_fonts
; i
++)
2970 full_list
= Fcons (build_string (names
[i
]), full_list
);
2971 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
2972 = Fcons (Fcons (pattern
, full_list
),
2973 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
);
2975 /* Make a list of the fonts that have the right width. */
2977 for (i
= 0; i
< num_fonts
; i
++)
2979 XFontStruct
*thisinfo
;
2981 #ifdef BROKEN_XLISTFONTSWITHINFO
2983 thisinfo
= XLoadQueryFont (FRAME_X_DISPLAY (f
), names
[i
]);
2986 thisinfo
= &info
[i
];
2988 if (thisinfo
&& (! size_ref
2989 || same_size_fonts (thisinfo
, size_ref
)))
2990 list
= Fcons (build_string (names
[i
]), list
);
2992 list
= Fnreverse (list
);
2995 #ifdef BROKEN_XLISTFONTSWITHINFO
2996 XFreeFontNames (names
);
2998 XFreeFontInfo (names
, info
, num_fonts
);
3007 DEFUN ("x-color-defined-p", Fx_color_defined_p
, Sx_color_defined_p
, 1, 2, 0,
3008 "Return non-nil color COLOR is supported on frame FRAME.\n\
3009 If FRAME is omitted or nil, use the selected frame.")
3011 Lisp_Object color
, frame
;
3014 FRAME_PTR f
= check_x_frame (frame
);
3016 CHECK_STRING (color
, 1);
3018 if (defined_color (f
, XSTRING (color
)->data
, &foo
, 0))
3024 DEFUN ("x-color-values", Fx_color_values
, Sx_color_values
, 1, 2, 0,
3025 "Return a description of the color named COLOR on frame FRAME.\n\
3026 The value is a list of integer RGB values--(RED GREEN BLUE).\n\
3027 These values appear to range from 0 to 65280; white is (65280 65280 65280).\n\
3028 If FRAME is omitted or nil, use the selected frame.")
3030 Lisp_Object color
, frame
;
3033 FRAME_PTR f
= check_x_frame (frame
);
3035 CHECK_STRING (color
, 1);
3037 if (defined_color (f
, XSTRING (color
)->data
, &foo
, 0))
3041 rgb
[0] = make_number (foo
.red
);
3042 rgb
[1] = make_number (foo
.green
);
3043 rgb
[2] = make_number (foo
.blue
);
3044 return Flist (3, rgb
);
3050 DEFUN ("x-display-color-p", Fx_display_color_p
, Sx_display_color_p
, 0, 1, 0,
3051 "Return t if the X display supports color.\n\
3052 The optional argument DISPLAY specifies which display to ask about.\n\
3053 DISPLAY should be either a frame or a display name (a string).\n\
3054 If omitted or nil, that stands for the selected frame's display.")
3056 Lisp_Object display
;
3058 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3060 if (dpyinfo
->n_planes
<= 2)
3063 switch (dpyinfo
->visual
->class)
3076 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
3078 "Return t if the X display supports shades of gray.\n\
3079 The optional argument DISPLAY specifies which display to ask about.\n\
3080 DISPLAY should be either a frame or a display name (a string).\n\
3081 If omitted or nil, that stands for the selected frame's display.")
3083 Lisp_Object display
;
3085 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3087 if (dpyinfo
->n_planes
<= 2)
3090 return (dpyinfo
->n_planes
> 1
3091 && (dpyinfo
->visual
->class == StaticGray
3092 || dpyinfo
->visual
->class == GrayScale
));
3095 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
3097 "Returns the width in pixels of the X display DISPLAY.\n\
3098 The optional argument DISPLAY specifies which display to ask about.\n\
3099 DISPLAY should be either a frame or a display name (a string).\n\
3100 If omitted or nil, that stands for the selected frame's display.")
3102 Lisp_Object display
;
3104 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3106 return make_number (dpyinfo
->width
);
3109 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
3110 Sx_display_pixel_height
, 0, 1, 0,
3111 "Returns the height in pixels of the X display DISPLAY.\n\
3112 The optional argument DISPLAY specifies which display to ask about.\n\
3113 DISPLAY should be either a frame or a display name (a string).\n\
3114 If omitted or nil, that stands for the selected frame's display.")
3116 Lisp_Object display
;
3118 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3120 return make_number (dpyinfo
->height
);
3123 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
3125 "Returns the number of bitplanes of the X display DISPLAY.\n\
3126 The optional argument DISPLAY specifies which display to ask about.\n\
3127 DISPLAY should be either a frame or a display name (a string).\n\
3128 If omitted or nil, that stands for the selected frame's display.")
3130 Lisp_Object display
;
3132 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3134 return make_number (dpyinfo
->n_planes
);
3137 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
3139 "Returns the number of color cells of the X display DISPLAY.\n\
3140 The optional argument DISPLAY specifies which display to ask about.\n\
3141 DISPLAY should be either a frame or a display name (a string).\n\
3142 If omitted or nil, that stands for the selected frame's display.")
3144 Lisp_Object display
;
3146 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3148 return make_number (DisplayCells (dpyinfo
->display
,
3149 XScreenNumberOfScreen (dpyinfo
->screen
)));
3152 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
3153 Sx_server_max_request_size
,
3155 "Returns the maximum request size of the X server of display DISPLAY.\n\
3156 The optional argument DISPLAY specifies which display to ask about.\n\
3157 DISPLAY should be either a frame or a display name (a string).\n\
3158 If omitted or nil, that stands for the selected frame's display.")
3160 Lisp_Object display
;
3162 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3164 return make_number (MAXREQUEST (dpyinfo
->display
));
3167 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
3168 "Returns the vendor ID string of the X server of display DISPLAY.\n\
3169 The optional argument DISPLAY specifies which display to ask about.\n\
3170 DISPLAY should be either a frame or a display name (a string).\n\
3171 If omitted or nil, that stands for the selected frame's display.")
3173 Lisp_Object display
;
3175 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3176 char *vendor
= ServerVendor (dpyinfo
->display
);
3178 if (! vendor
) vendor
= "";
3179 return build_string (vendor
);
3182 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
3183 "Returns the version numbers of the X server of display DISPLAY.\n\
3184 The value is a list of three integers: the major and minor\n\
3185 version numbers of the X Protocol in use, and the vendor-specific release\n\
3186 number. See also the function `x-server-vendor'.\n\n\
3187 The optional argument DISPLAY specifies which display to ask about.\n\
3188 DISPLAY should be either a frame or a display name (a string).\n\
3189 If omitted or nil, that stands for the selected frame's display.")
3191 Lisp_Object display
;
3193 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3194 Display
*dpy
= dpyinfo
->display
;
3196 return Fcons (make_number (ProtocolVersion (dpy
)),
3197 Fcons (make_number (ProtocolRevision (dpy
)),
3198 Fcons (make_number (VendorRelease (dpy
)), Qnil
)));
3201 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
3202 "Returns the number of screens on the X server of display DISPLAY.\n\
3203 The optional argument DISPLAY specifies which display to ask about.\n\
3204 DISPLAY should be either a frame or a display name (a string).\n\
3205 If omitted or nil, that stands for the selected frame's display.")
3207 Lisp_Object display
;
3209 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3211 return make_number (ScreenCount (dpyinfo
->display
));
3214 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
3215 "Returns the height in millimeters of the X display DISPLAY.\n\
3216 The optional argument DISPLAY specifies which display to ask about.\n\
3217 DISPLAY should be either a frame or a display name (a string).\n\
3218 If omitted or nil, that stands for the selected frame's display.")
3220 Lisp_Object display
;
3222 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3224 return make_number (HeightMMOfScreen (dpyinfo
->screen
));
3227 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
3228 "Returns the width in millimeters of the X display DISPLAY.\n\
3229 The optional argument DISPLAY specifies which display to ask about.\n\
3230 DISPLAY should be either a frame or a display name (a string).\n\
3231 If omitted or nil, that stands for the selected frame's display.")
3233 Lisp_Object display
;
3235 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3237 return make_number (WidthMMOfScreen (dpyinfo
->screen
));
3240 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
3241 Sx_display_backing_store
, 0, 1, 0,
3242 "Returns an indication of whether X display DISPLAY does backing store.\n\
3243 The value may be `always', `when-mapped', or `not-useful'.\n\
3244 The optional argument DISPLAY specifies which display to ask about.\n\
3245 DISPLAY should be either a frame or a display name (a string).\n\
3246 If omitted or nil, that stands for the selected frame's display.")
3248 Lisp_Object display
;
3250 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3252 switch (DoesBackingStore (dpyinfo
->screen
))
3255 return intern ("always");
3258 return intern ("when-mapped");
3261 return intern ("not-useful");
3264 error ("Strange value for BackingStore parameter of screen");
3268 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
3269 Sx_display_visual_class
, 0, 1, 0,
3270 "Returns the visual class of the X display DISPLAY.\n\
3271 The value is one of the symbols `static-gray', `gray-scale',\n\
3272 `static-color', `pseudo-color', `true-color', or `direct-color'.\n\n\
3273 The optional argument DISPLAY specifies which display to ask about.\n\
3274 DISPLAY should be either a frame or a display name (a string).\n\
3275 If omitted or nil, that stands for the selected frame's display.")
3277 Lisp_Object display
;
3279 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3281 switch (dpyinfo
->visual
->class)
3283 case StaticGray
: return (intern ("static-gray"));
3284 case GrayScale
: return (intern ("gray-scale"));
3285 case StaticColor
: return (intern ("static-color"));
3286 case PseudoColor
: return (intern ("pseudo-color"));
3287 case TrueColor
: return (intern ("true-color"));
3288 case DirectColor
: return (intern ("direct-color"));
3290 error ("Display has an unknown visual class");
3294 DEFUN ("x-display-save-under", Fx_display_save_under
,
3295 Sx_display_save_under
, 0, 1, 0,
3296 "Returns t if the X display DISPLAY supports the save-under feature.\n\
3297 The optional argument DISPLAY specifies which display to ask about.\n\
3298 DISPLAY should be either a frame or a display name (a string).\n\
3299 If omitted or nil, that stands for the selected frame's display.")
3301 Lisp_Object display
;
3303 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3305 if (DoesSaveUnders (dpyinfo
->screen
) == True
)
3313 register struct frame
*f
;
3315 return PIXEL_WIDTH (f
);
3320 register struct frame
*f
;
3322 return PIXEL_HEIGHT (f
);
3327 register struct frame
*f
;
3329 return FONT_WIDTH (f
->display
.x
->font
);
3334 register struct frame
*f
;
3336 return f
->display
.x
->line_height
;
3340 x_screen_planes (frame
)
3343 return FRAME_X_DISPLAY_INFO (XFRAME (frame
))->n_planes
;
3346 #if 0 /* These no longer seem like the right way to do things. */
3348 /* Draw a rectangle on the frame with left top corner including
3349 the character specified by LEFT_CHAR and TOP_CHAR. The rectangle is
3350 CHARS by LINES wide and long and is the color of the cursor. */
3353 x_rectangle (f
, gc
, left_char
, top_char
, chars
, lines
)
3354 register struct frame
*f
;
3356 register int top_char
, left_char
, chars
, lines
;
3360 int left
= (left_char
* FONT_WIDTH (f
->display
.x
->font
)
3361 + f
->display
.x
->internal_border_width
);
3362 int top
= (top_char
* f
->display
.x
->line_height
3363 + f
->display
.x
->internal_border_width
);
3366 width
= FONT_WIDTH (f
->display
.x
->font
) / 2;
3368 width
= FONT_WIDTH (f
->display
.x
->font
) * chars
;
3370 height
= f
->display
.x
->line_height
/ 2;
3372 height
= f
->display
.x
->line_height
* lines
;
3374 XDrawRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3375 gc
, left
, top
, width
, height
);
3378 DEFUN ("x-draw-rectangle", Fx_draw_rectangle
, Sx_draw_rectangle
, 5, 5, 0,
3379 "Draw a rectangle on FRAME between coordinates specified by\n\
3380 numbers X0, Y0, X1, Y1 in the cursor pixel.")
3381 (frame
, X0
, Y0
, X1
, Y1
)
3382 register Lisp_Object frame
, X0
, X1
, Y0
, Y1
;
3384 register int x0
, y0
, x1
, y1
, top
, left
, n_chars
, n_lines
;
3386 CHECK_LIVE_FRAME (frame
, 0);
3387 CHECK_NUMBER (X0
, 0);
3388 CHECK_NUMBER (Y0
, 1);
3389 CHECK_NUMBER (X1
, 2);
3390 CHECK_NUMBER (Y1
, 3);
3400 n_lines
= y1
- y0
+ 1;
3405 n_lines
= y0
- y1
+ 1;
3411 n_chars
= x1
- x0
+ 1;
3416 n_chars
= x0
- x1
+ 1;
3420 x_rectangle (XFRAME (frame
), XFRAME (frame
)->display
.x
->cursor_gc
,
3421 left
, top
, n_chars
, n_lines
);
3427 DEFUN ("x-erase-rectangle", Fx_erase_rectangle
, Sx_erase_rectangle
, 5, 5, 0,
3428 "Draw a rectangle drawn on FRAME between coordinates\n\
3429 X0, Y0, X1, Y1 in the regular background-pixel.")
3430 (frame
, X0
, Y0
, X1
, Y1
)
3431 register Lisp_Object frame
, X0
, Y0
, X1
, Y1
;
3433 register int x0
, y0
, x1
, y1
, top
, left
, n_chars
, n_lines
;
3435 CHECK_LIVE_FRAME (frame
, 0);
3436 CHECK_NUMBER (X0
, 0);
3437 CHECK_NUMBER (Y0
, 1);
3438 CHECK_NUMBER (X1
, 2);
3439 CHECK_NUMBER (Y1
, 3);
3449 n_lines
= y1
- y0
+ 1;
3454 n_lines
= y0
- y1
+ 1;
3460 n_chars
= x1
- x0
+ 1;
3465 n_chars
= x0
- x1
+ 1;
3469 x_rectangle (XFRAME (frame
), XFRAME (frame
)->display
.x
->reverse_gc
,
3470 left
, top
, n_chars
, n_lines
);
3476 /* Draw lines around the text region beginning at the character position
3477 TOP_X, TOP_Y and ending at BOTTOM_X and BOTTOM_Y. GC specifies the
3478 pixel and line characteristics. */
3480 #define line_len(line) (FRAME_CURRENT_GLYPHS (f)->used[(line)])
3483 outline_region (f
, gc
, top_x
, top_y
, bottom_x
, bottom_y
)
3484 register struct frame
*f
;
3486 int top_x
, top_y
, bottom_x
, bottom_y
;
3488 register int ibw
= f
->display
.x
->internal_border_width
;
3489 register int font_w
= FONT_WIDTH (f
->display
.x
->font
);
3490 register int font_h
= f
->display
.x
->line_height
;
3492 int x
= line_len (y
);
3493 XPoint
*pixel_points
3494 = (XPoint
*) alloca (((bottom_y
- top_y
+ 2) * 4) * sizeof (XPoint
));
3495 register XPoint
*this_point
= pixel_points
;
3497 /* Do the horizontal top line/lines */
3500 this_point
->x
= ibw
;
3501 this_point
->y
= ibw
+ (font_h
* top_y
);
3504 this_point
->x
= ibw
+ (font_w
/ 2); /* Half-size for newline chars. */
3506 this_point
->x
= ibw
+ (font_w
* x
);
3507 this_point
->y
= (this_point
- 1)->y
;
3511 this_point
->x
= ibw
;
3512 this_point
->y
= ibw
+ (font_h
* (top_y
+ 1));
3514 this_point
->x
= ibw
+ (font_w
* top_x
);
3515 this_point
->y
= (this_point
- 1)->y
;
3517 this_point
->x
= (this_point
- 1)->x
;
3518 this_point
->y
= ibw
+ (font_h
* top_y
);
3520 this_point
->x
= ibw
+ (font_w
* x
);
3521 this_point
->y
= (this_point
- 1)->y
;
3524 /* Now do the right side. */
3525 while (y
< bottom_y
)
3526 { /* Right vertical edge */
3528 this_point
->x
= (this_point
- 1)->x
;
3529 this_point
->y
= ibw
+ (font_h
* (y
+ 1));
3532 y
++; /* Horizontal connection to next line */
3535 this_point
->x
= ibw
+ (font_w
/ 2);
3537 this_point
->x
= ibw
+ (font_w
* x
);
3539 this_point
->y
= (this_point
- 1)->y
;
3542 /* Now do the bottom and connect to the top left point. */
3543 this_point
->x
= ibw
+ (font_w
* (bottom_x
+ 1));
3546 this_point
->x
= (this_point
- 1)->x
;
3547 this_point
->y
= ibw
+ (font_h
* (bottom_y
+ 1));
3549 this_point
->x
= ibw
;
3550 this_point
->y
= (this_point
- 1)->y
;
3552 this_point
->x
= pixel_points
->x
;
3553 this_point
->y
= pixel_points
->y
;
3555 XDrawLines (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3557 (this_point
- pixel_points
+ 1), CoordModeOrigin
);
3560 DEFUN ("x-contour-region", Fx_contour_region
, Sx_contour_region
, 1, 1, 0,
3561 "Highlight the region between point and the character under the mouse\n\
3564 register Lisp_Object event
;
3566 register int x0
, y0
, x1
, y1
;
3567 register struct frame
*f
= selected_frame
;
3568 register int p1
, p2
;
3570 CHECK_CONS (event
, 0);
3573 x0
= XINT (Fcar (Fcar (event
)));
3574 y0
= XINT (Fcar (Fcdr (Fcar (event
))));
3576 /* If the mouse is past the end of the line, don't that area. */
3577 /* ReWrite this... */
3582 if (y1
> y0
) /* point below mouse */
3583 outline_region (f
, f
->display
.x
->cursor_gc
,
3585 else if (y1
< y0
) /* point above mouse */
3586 outline_region (f
, f
->display
.x
->cursor_gc
,
3588 else /* same line: draw horizontal rectangle */
3591 x_rectangle (f
, f
->display
.x
->cursor_gc
,
3592 x0
, y0
, (x1
- x0
+ 1), 1);
3594 x_rectangle (f
, f
->display
.x
->cursor_gc
,
3595 x1
, y1
, (x0
- x1
+ 1), 1);
3598 XFlush (FRAME_X_DISPLAY (f
));
3604 DEFUN ("x-uncontour-region", Fx_uncontour_region
, Sx_uncontour_region
, 1, 1, 0,
3605 "Erase any highlighting of the region between point and the character\n\
3606 at X, Y on the selected frame.")
3608 register Lisp_Object event
;
3610 register int x0
, y0
, x1
, y1
;
3611 register struct frame
*f
= selected_frame
;
3614 x0
= XINT (Fcar (Fcar (event
)));
3615 y0
= XINT (Fcar (Fcdr (Fcar (event
))));
3619 if (y1
> y0
) /* point below mouse */
3620 outline_region (f
, f
->display
.x
->reverse_gc
,
3622 else if (y1
< y0
) /* point above mouse */
3623 outline_region (f
, f
->display
.x
->reverse_gc
,
3625 else /* same line: draw horizontal rectangle */
3628 x_rectangle (f
, f
->display
.x
->reverse_gc
,
3629 x0
, y0
, (x1
- x0
+ 1), 1);
3631 x_rectangle (f
, f
->display
.x
->reverse_gc
,
3632 x1
, y1
, (x0
- x1
+ 1), 1);
3640 int contour_begin_x
, contour_begin_y
;
3641 int contour_end_x
, contour_end_y
;
3642 int contour_npoints
;
3644 /* Clip the top part of the contour lines down (and including) line Y_POS.
3645 If X_POS is in the middle (rather than at the end) of the line, drop
3646 down a line at that character. */
3649 clip_contour_top (y_pos
, x_pos
)
3651 register XPoint
*begin
= contour_lines
[y_pos
].top_left
;
3652 register XPoint
*end
;
3653 register int npoints
;
3654 register struct display_line
*line
= selected_frame
->phys_lines
[y_pos
+ 1];
3656 if (x_pos
>= line
->len
- 1) /* Draw one, straight horizontal line. */
3658 end
= contour_lines
[y_pos
].top_right
;
3659 npoints
= (end
- begin
+ 1);
3660 XDrawLines (x_current_display
, contour_window
,
3661 contour_erase_gc
, begin_erase
, npoints
, CoordModeOrigin
);
3663 bcopy (end
, begin
+ 1, contour_last_point
- end
+ 1);
3664 contour_last_point
-= (npoints
- 2);
3665 XDrawLines (x_current_display
, contour_window
,
3666 contour_erase_gc
, begin
, 2, CoordModeOrigin
);
3667 XFlush (x_current_display
);
3669 /* Now, update contour_lines structure. */
3674 register XPoint
*p
= begin
+ 1;
3675 end
= contour_lines
[y_pos
].bottom_right
;
3676 npoints
= (end
- begin
+ 1);
3677 XDrawLines (x_current_display
, contour_window
,
3678 contour_erase_gc
, begin_erase
, npoints
, CoordModeOrigin
);
3681 p
->x
= ibw
+ (font_w
* (x_pos
+ 1));
3683 p
->y
= begin
->y
+ font_h
;
3685 bcopy (end
, begin
+ 3, contour_last_point
- end
+ 1);
3686 contour_last_point
-= (npoints
- 5);
3687 XDrawLines (x_current_display
, contour_window
,
3688 contour_erase_gc
, begin
, 4, CoordModeOrigin
);
3689 XFlush (x_current_display
);
3691 /* Now, update contour_lines structure. */
3695 /* Erase the top horizontal lines of the contour, and then extend
3696 the contour upwards. */
3699 extend_contour_top (line
)
3704 clip_contour_bottom (x_pos
, y_pos
)
3710 extend_contour_bottom (x_pos
, y_pos
)
3714 DEFUN ("x-select-region", Fx_select_region
, Sx_select_region
, 1, 1, "e",
3719 register struct frame
*f
= selected_frame
;
3720 register int point_x
= f
->cursor_x
;
3721 register int point_y
= f
->cursor_y
;
3722 register int mouse_below_point
;
3723 register Lisp_Object obj
;
3724 register int x_contour_x
, x_contour_y
;
3726 x_contour_x
= x_mouse_x
;
3727 x_contour_y
= x_mouse_y
;
3728 if (x_contour_y
> point_y
|| (x_contour_y
== point_y
3729 && x_contour_x
> point_x
))
3731 mouse_below_point
= 1;
3732 outline_region (f
, f
->display
.x
->cursor_gc
, point_x
, point_y
,
3733 x_contour_x
, x_contour_y
);
3737 mouse_below_point
= 0;
3738 outline_region (f
, f
->display
.x
->cursor_gc
, x_contour_x
, x_contour_y
,
3744 obj
= read_char (-1, 0, 0, Qnil
, 0);
3748 if (mouse_below_point
)
3750 if (x_mouse_y
<= point_y
) /* Flipped. */
3752 mouse_below_point
= 0;
3754 outline_region (f
, f
->display
.x
->reverse_gc
, point_x
, point_y
,
3755 x_contour_x
, x_contour_y
);
3756 outline_region (f
, f
->display
.x
->cursor_gc
, x_mouse_x
, x_mouse_y
,
3759 else if (x_mouse_y
< x_contour_y
) /* Bottom clipped. */
3761 clip_contour_bottom (x_mouse_y
);
3763 else if (x_mouse_y
> x_contour_y
) /* Bottom extended. */
3765 extend_bottom_contour (x_mouse_y
);
3768 x_contour_x
= x_mouse_x
;
3769 x_contour_y
= x_mouse_y
;
3771 else /* mouse above or same line as point */
3773 if (x_mouse_y
>= point_y
) /* Flipped. */
3775 mouse_below_point
= 1;
3777 outline_region (f
, f
->display
.x
->reverse_gc
,
3778 x_contour_x
, x_contour_y
, point_x
, point_y
);
3779 outline_region (f
, f
->display
.x
->cursor_gc
, point_x
, point_y
,
3780 x_mouse_x
, x_mouse_y
);
3782 else if (x_mouse_y
> x_contour_y
) /* Top clipped. */
3784 clip_contour_top (x_mouse_y
);
3786 else if (x_mouse_y
< x_contour_y
) /* Top extended. */
3788 extend_contour_top (x_mouse_y
);
3793 unread_command_event
= obj
;
3794 if (mouse_below_point
)
3796 contour_begin_x
= point_x
;
3797 contour_begin_y
= point_y
;
3798 contour_end_x
= x_contour_x
;
3799 contour_end_y
= x_contour_y
;
3803 contour_begin_x
= x_contour_x
;
3804 contour_begin_y
= x_contour_y
;
3805 contour_end_x
= point_x
;
3806 contour_end_y
= point_y
;
3811 DEFUN ("x-horizontal-line", Fx_horizontal_line
, Sx_horizontal_line
, 1, 1, "e",
3816 register Lisp_Object obj
;
3817 struct frame
*f
= selected_frame
;
3818 register struct window
*w
= XWINDOW (selected_window
);
3819 register GC line_gc
= f
->display
.x
->cursor_gc
;
3820 register GC erase_gc
= f
->display
.x
->reverse_gc
;
3822 char dash_list
[] = {6, 4, 6, 4};
3824 XGCValues gc_values
;
3826 register int previous_y
;
3827 register int line
= (x_mouse_y
+ 1) * f
->display
.x
->line_height
3828 + f
->display
.x
->internal_border_width
;
3829 register int left
= f
->display
.x
->internal_border_width
3831 * FONT_WIDTH (f
->display
.x
->font
));
3832 register int right
= left
+ (w
->width
3833 * FONT_WIDTH (f
->display
.x
->font
))
3834 - f
->display
.x
->internal_border_width
;
3838 gc_values
.foreground
= f
->display
.x
->cursor_pixel
;
3839 gc_values
.background
= f
->display
.x
->background_pixel
;
3840 gc_values
.line_width
= 1;
3841 gc_values
.line_style
= LineOnOffDash
;
3842 gc_values
.cap_style
= CapRound
;
3843 gc_values
.join_style
= JoinRound
;
3845 line_gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3846 GCLineStyle
| GCJoinStyle
| GCCapStyle
3847 | GCLineWidth
| GCForeground
| GCBackground
,
3849 XSetDashes (FRAME_X_DISPLAY (f
), line_gc
, 0, dash_list
, dashes
);
3850 gc_values
.foreground
= f
->display
.x
->background_pixel
;
3851 gc_values
.background
= f
->display
.x
->foreground_pixel
;
3852 erase_gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3853 GCLineStyle
| GCJoinStyle
| GCCapStyle
3854 | GCLineWidth
| GCForeground
| GCBackground
,
3856 XSetDashes (FRAME_X_DISPLAY (f
), erase_gc
, 0, dash_list
, dashes
);
3862 if (x_mouse_y
>= XINT (w
->top
)
3863 && x_mouse_y
< XINT (w
->top
) + XINT (w
->height
) - 1)
3865 previous_y
= x_mouse_y
;
3866 line
= (x_mouse_y
+ 1) * f
->display
.x
->line_height
3867 + f
->display
.x
->internal_border_width
;
3868 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3869 line_gc
, left
, line
, right
, line
);
3871 XFlush (FRAME_X_DISPLAY (f
));
3876 obj
= read_char (-1, 0, 0, Qnil
, 0);
3878 || (! EQ (Fcar (Fcdr (Fcdr (obj
))),
3879 Qvertical_scroll_bar
))
3883 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3884 erase_gc
, left
, line
, right
, line
);
3886 unread_command_event
= obj
;
3888 XFreeGC (FRAME_X_DISPLAY (f
), line_gc
);
3889 XFreeGC (FRAME_X_DISPLAY (f
), erase_gc
);
3894 while (x_mouse_y
== previous_y
);
3897 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3898 erase_gc
, left
, line
, right
, line
);
3905 /* These keep track of the rectangle following the pointer. */
3906 int mouse_track_top
, mouse_track_left
, mouse_track_width
;
3908 /* Offset in buffer of character under the pointer, or 0. */
3909 int mouse_buffer_offset
;
3911 DEFUN ("x-track-pointer", Fx_track_pointer
, Sx_track_pointer
, 0, 0, 0,
3912 "Track the pointer.")
3915 static Cursor current_pointer_shape
;
3916 FRAME_PTR f
= x_mouse_frame
;
3919 if (EQ (Vmouse_frame_part
, Qtext_part
)
3920 && (current_pointer_shape
!= f
->display
.x
->nontext_cursor
))
3925 current_pointer_shape
= f
->display
.x
->nontext_cursor
;
3926 XDefineCursor (FRAME_X_DISPLAY (f
),
3928 current_pointer_shape
);
3930 buf
= XBUFFER (XWINDOW (Vmouse_window
)->buffer
);
3931 c
= *(BUF_CHAR_ADDRESS (buf
, mouse_buffer_offset
));
3933 else if (EQ (Vmouse_frame_part
, Qmodeline_part
)
3934 && (current_pointer_shape
!= f
->display
.x
->modeline_cursor
))
3936 current_pointer_shape
= f
->display
.x
->modeline_cursor
;
3937 XDefineCursor (FRAME_X_DISPLAY (f
),
3939 current_pointer_shape
);
3942 XFlush (FRAME_X_DISPLAY (f
));
3948 DEFUN ("x-track-pointer", Fx_track_pointer
, Sx_track_pointer
, 1, 1, "e",
3949 "Draw rectangle around character under mouse pointer, if there is one.")
3953 struct window
*w
= XWINDOW (Vmouse_window
);
3954 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
3955 struct buffer
*b
= XBUFFER (w
->buffer
);
3958 if (! EQ (Vmouse_window
, selected_window
))
3961 if (EQ (event
, Qnil
))
3965 x_read_mouse_position (selected_frame
, &x
, &y
);
3969 mouse_track_width
= 0;
3970 mouse_track_left
= mouse_track_top
= -1;
3974 if ((x_mouse_x
!= mouse_track_left
3975 && (x_mouse_x
< mouse_track_left
3976 || x_mouse_x
> (mouse_track_left
+ mouse_track_width
)))
3977 || x_mouse_y
!= mouse_track_top
)
3979 int hp
= 0; /* Horizontal position */
3980 int len
= FRAME_CURRENT_GLYPHS (f
)->used
[x_mouse_y
];
3981 int p
= FRAME_CURRENT_GLYPHS (f
)->bufp
[x_mouse_y
];
3982 int tab_width
= XINT (b
->tab_width
);
3983 int ctl_arrow_p
= !NILP (b
->ctl_arrow
);
3985 int mode_line_vpos
= XFASTINT (w
->height
) + XFASTINT (w
->top
) - 1;
3986 int in_mode_line
= 0;
3988 if (! FRAME_CURRENT_GLYPHS (f
)->enable
[x_mouse_y
])
3991 /* Erase previous rectangle. */
3992 if (mouse_track_width
)
3994 x_rectangle (f
, f
->display
.x
->reverse_gc
,
3995 mouse_track_left
, mouse_track_top
,
3996 mouse_track_width
, 1);
3998 if ((mouse_track_left
== f
->phys_cursor_x
3999 || mouse_track_left
== f
->phys_cursor_x
- 1)
4000 && mouse_track_top
== f
->phys_cursor_y
)
4002 x_display_cursor (f
, 1);
4006 mouse_track_left
= x_mouse_x
;
4007 mouse_track_top
= x_mouse_y
;
4008 mouse_track_width
= 0;
4010 if (mouse_track_left
> len
) /* Past the end of line. */
4013 if (mouse_track_top
== mode_line_vpos
)
4019 if (tab_width
<= 0 || tab_width
> 20) tab_width
= 8;
4023 if (len
== f
->width
&& hp
== len
- 1 && c
!= '\n')
4029 mouse_track_width
= tab_width
- (hp
% tab_width
);
4031 hp
+= mouse_track_width
;
4034 mouse_track_left
= hp
- mouse_track_width
;
4040 mouse_track_width
= -1;
4044 if (ctl_arrow_p
&& (c
< 040 || c
== 0177))
4049 mouse_track_width
= 2;
4054 mouse_track_left
= hp
- mouse_track_width
;
4060 mouse_track_width
= 1;
4067 while (hp
<= x_mouse_x
);
4070 if (mouse_track_width
) /* Over text; use text pointer shape. */
4072 XDefineCursor (FRAME_X_DISPLAY (f
),
4074 f
->display
.x
->text_cursor
);
4075 x_rectangle (f
, f
->display
.x
->cursor_gc
,
4076 mouse_track_left
, mouse_track_top
,
4077 mouse_track_width
, 1);
4079 else if (in_mode_line
)
4080 XDefineCursor (FRAME_X_DISPLAY (f
),
4082 f
->display
.x
->modeline_cursor
);
4084 XDefineCursor (FRAME_X_DISPLAY (f
),
4086 f
->display
.x
->nontext_cursor
);
4089 XFlush (FRAME_X_DISPLAY (f
));
4092 obj
= read_char (-1, 0, 0, Qnil
, 0);
4095 while (CONSP (obj
) /* Mouse event */
4096 && EQ (Fcar (Fcdr (Fcdr (obj
))), Qnil
) /* Not scroll bar */
4097 && EQ (Vmouse_depressed
, Qnil
) /* Only motion events */
4098 && EQ (Vmouse_window
, selected_window
) /* In this window */
4101 unread_command_event
= obj
;
4103 if (mouse_track_width
)
4105 x_rectangle (f
, f
->display
.x
->reverse_gc
,
4106 mouse_track_left
, mouse_track_top
,
4107 mouse_track_width
, 1);
4108 mouse_track_width
= 0;
4109 if ((mouse_track_left
== f
->phys_cursor_x
4110 || mouse_track_left
- 1 == f
->phys_cursor_x
)
4111 && mouse_track_top
== f
->phys_cursor_y
)
4113 x_display_cursor (f
, 1);
4116 XDefineCursor (FRAME_X_DISPLAY (f
),
4118 f
->display
.x
->nontext_cursor
);
4119 XFlush (FRAME_X_DISPLAY (f
));
4129 /* Draw a pixmap specified by IMAGE_DATA of dimensions WIDTH and HEIGHT
4130 on the frame F at position X, Y. */
4132 x_draw_pixmap (f
, x
, y
, image_data
, width
, height
)
4134 int x
, y
, width
, height
;
4139 image
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
4140 FRAME_X_WINDOW (f
), image_data
,
4142 XCopyPlane (FRAME_X_DISPLAY (f
), image
, FRAME_X_WINDOW (f
),
4143 f
->display
.x
->normal_gc
, 0, 0, width
, height
, x
, y
);
4147 #if 0 /* I'm told these functions are superfluous
4148 given the ability to bind function keys. */
4151 DEFUN ("x-rebind-key", Fx_rebind_key
, Sx_rebind_key
, 3, 3, 0,
4152 "Rebind X keysym KEYSYM, with MODIFIERS, to generate NEWSTRING.\n\
4153 KEYSYM is a string which conforms to the X keysym definitions found\n\
4154 in X11/keysymdef.h, sans the initial XK_. MODIFIERS is nil or a\n\
4155 list of strings specifying modifier keys such as Control_L, which must\n\
4156 also be depressed for NEWSTRING to appear.")
4157 (x_keysym
, modifiers
, newstring
)
4158 register Lisp_Object x_keysym
;
4159 register Lisp_Object modifiers
;
4160 register Lisp_Object newstring
;
4163 register KeySym keysym
;
4164 KeySym modifier_list
[16];
4167 CHECK_STRING (x_keysym
, 1);
4168 CHECK_STRING (newstring
, 3);
4170 keysym
= XStringToKeysym ((char *) XSTRING (x_keysym
)->data
);
4171 if (keysym
== NoSymbol
)
4172 error ("Keysym does not exist");
4174 if (NILP (modifiers
))
4175 XRebindKeysym (x_current_display
, keysym
, modifier_list
, 0,
4176 XSTRING (newstring
)->data
, XSTRING (newstring
)->size
);
4179 register Lisp_Object rest
, mod
;
4182 for (rest
= modifiers
; !NILP (rest
); rest
= Fcdr (rest
))
4185 error ("Can't have more than 16 modifiers");
4188 CHECK_STRING (mod
, 3);
4189 modifier_list
[i
] = XStringToKeysym ((char *) XSTRING (mod
)->data
);
4191 if (modifier_list
[i
] == NoSymbol
4192 || !(IsModifierKey (modifier_list
[i
])
4193 || ((unsigned)(modifier_list
[i
]) == XK_Mode_switch
)
4194 || ((unsigned)(modifier_list
[i
]) == XK_Num_Lock
)))
4196 if (modifier_list
[i
] == NoSymbol
4197 || !IsModifierKey (modifier_list
[i
]))
4199 error ("Element is not a modifier keysym");
4203 XRebindKeysym (x_current_display
, keysym
, modifier_list
, i
,
4204 XSTRING (newstring
)->data
, XSTRING (newstring
)->size
);
4210 DEFUN ("x-rebind-keys", Fx_rebind_keys
, Sx_rebind_keys
, 2, 2, 0,
4211 "Rebind KEYCODE to list of strings STRINGS.\n\
4212 STRINGS should be a list of 16 elements, one for each shift combination.\n\
4213 nil as element means don't change.\n\
4214 See the documentation of `x-rebind-key' for more information.")
4216 register Lisp_Object keycode
;
4217 register Lisp_Object strings
;
4219 register Lisp_Object item
;
4220 register unsigned char *rawstring
;
4221 KeySym rawkey
, modifier
[1];
4223 register unsigned i
;
4226 CHECK_NUMBER (keycode
, 1);
4227 CHECK_CONS (strings
, 2);
4228 rawkey
= (KeySym
) ((unsigned) (XINT (keycode
))) & 255;
4229 for (i
= 0; i
<= 15; strings
= Fcdr (strings
), i
++)
4231 item
= Fcar (strings
);
4234 CHECK_STRING (item
, 2);
4235 strsize
= XSTRING (item
)->size
;
4236 rawstring
= (unsigned char *) xmalloc (strsize
);
4237 bcopy (XSTRING (item
)->data
, rawstring
, strsize
);
4238 modifier
[1] = 1 << i
;
4239 XRebindKeysym (x_current_display
, rawkey
, modifier
, 1,
4240 rawstring
, strsize
);
4245 #endif /* HAVE_X11 */
4248 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4250 XScreenNumberOfScreen (scr
)
4251 register Screen
*scr
;
4253 register Display
*dpy
;
4254 register Screen
*dpyscr
;
4258 dpyscr
= dpy
->screens
;
4260 for (i
= 0; i
< dpy
->nscreens
; i
++, dpyscr
++)
4266 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4269 select_visual (dpy
, screen
, depth
)
4272 unsigned int *depth
;
4275 XVisualInfo
*vinfo
, vinfo_template
;
4278 v
= DefaultVisualOfScreen (screen
);
4281 vinfo_template
.visualid
= XVisualIDFromVisual (v
);
4283 vinfo_template
.visualid
= v
->visualid
;
4286 vinfo_template
.screen
= XScreenNumberOfScreen (screen
);
4288 vinfo
= XGetVisualInfo (dpy
,
4289 VisualIDMask
| VisualScreenMask
, &vinfo_template
,
4292 fatal ("Can't get proper X visual info");
4294 if ((1 << vinfo
->depth
) == vinfo
->colormap_size
)
4295 *depth
= vinfo
->depth
;
4299 int n
= vinfo
->colormap_size
- 1;
4308 XFree ((char *) vinfo
);
4312 /* Return the X display structure for the display named NAME.
4313 Open a new connection if necessary. */
4315 struct x_display_info
*
4316 x_display_info_for_name (name
)
4320 struct x_display_info
*dpyinfo
;
4322 CHECK_STRING (name
, 0);
4324 for (dpyinfo
= x_display_list
, names
= x_display_name_list
;
4326 dpyinfo
= dpyinfo
->next
, names
= XCONS (names
)->cdr
)
4329 tem
= Fstring_equal (XCONS (XCONS (names
)->car
)->car
, name
);
4334 validate_x_resource_name ();
4336 dpyinfo
= x_term_init (name
, (unsigned char *)0,
4337 XSTRING (Vx_resource_name
)->data
);
4340 error ("X server %s not responding", XSTRING (name
)->data
);
4343 XSETFASTINT (Vwindow_system_version
, 11);
4348 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
4349 1, 3, 0, "Open a connection to an X server.\n\
4350 DISPLAY is the name of the display to connect to.\n\
4351 Optional second arg XRM-STRING is a string of resources in xrdb format.\n\
4352 If the optional third arg MUST-SUCCEED is non-nil,\n\
4353 terminate Emacs if we can't open the connection.")
4354 (display
, xrm_string
, must_succeed
)
4355 Lisp_Object display
, xrm_string
, must_succeed
;
4357 unsigned int n_planes
;
4358 unsigned char *xrm_option
;
4359 struct x_display_info
*dpyinfo
;
4361 CHECK_STRING (display
, 0);
4362 if (! NILP (xrm_string
))
4363 CHECK_STRING (xrm_string
, 1);
4365 if (! NILP (xrm_string
))
4366 xrm_option
= (unsigned char *) XSTRING (xrm_string
)->data
;
4368 xrm_option
= (unsigned char *) 0;
4370 validate_x_resource_name ();
4372 /* This is what opens the connection and sets x_current_display.
4373 This also initializes many symbols, such as those used for input. */
4374 dpyinfo
= x_term_init (display
, xrm_option
,
4375 XSTRING (Vx_resource_name
)->data
);
4379 if (!NILP (must_succeed
))
4380 fatal ("X server %s not responding.\n\
4381 Check the DISPLAY environment variable or use \"-d\"\n",
4382 XSTRING (display
)->data
);
4384 error ("X server %s not responding", XSTRING (display
)->data
);
4389 XSETFASTINT (Vwindow_system_version
, 11);
4393 DEFUN ("x-close-connection", Fx_close_connection
,
4394 Sx_close_connection
, 1, 1, 0,
4395 "Close the connection to DISPLAY's X server.\n\
4396 For DISPLAY, specify either a frame or a display name (a string).\n\
4397 If DISPLAY is nil, that stands for the selected frame's display.")
4399 Lisp_Object display
;
4401 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4402 struct x_display_info
*tail
;
4405 if (dpyinfo
->reference_count
> 0)
4406 error ("Display still has frames on it");
4409 /* Free the fonts in the font table. */
4410 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
4412 if (dpyinfo
->font_table
[i
].name
)
4413 free (dpyinfo
->font_table
[i
].name
);
4414 /* Don't free the full_name string;
4415 it is always shared with something else. */
4416 XFreeFont (dpyinfo
->display
, dpyinfo
->font_table
[i
].font
);
4418 x_destroy_all_bitmaps (dpyinfo
);
4419 XSetCloseDownMode (dpyinfo
->display
, DestroyAll
);
4420 XCloseDisplay (dpyinfo
->display
);
4422 x_delete_display (dpyinfo
);
4428 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
4429 "Return the list of display names that Emacs has connections to.")
4432 Lisp_Object tail
, result
;
4435 for (tail
= x_display_name_list
; ! NILP (tail
); tail
= XCONS (tail
)->cdr
)
4436 result
= Fcons (XCONS (XCONS (tail
)->car
)->car
, result
);
4441 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
4442 "If ON is non-nil, report X errors as soon as the erring request is made.\n\
4443 If ON is nil, allow buffering of requests.\n\
4444 Turning on synchronization prohibits the Xlib routines from buffering\n\
4445 requests and seriously degrades performance, but makes debugging much\n\
4447 The optional second argument DISPLAY specifies which display to act on.\n\
4448 DISPLAY should be either a frame or a display name (a string).\n\
4449 If DISPLAY is omitted or nil, that stands for the selected frame's display.")
4451 Lisp_Object display
, on
;
4453 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4455 XSynchronize (dpyinfo
->display
, !EQ (on
, Qnil
));
4460 /* Wait for responses to all X commands issued so far for frame F. */
4467 XSync (FRAME_X_DISPLAY (f
), False
);
4473 /* This is zero if not using X windows. */
4476 /* The section below is built by the lisp expression at the top of the file,
4477 just above where these variables are declared. */
4478 /*&&& init symbols here &&&*/
4479 Qauto_raise
= intern ("auto-raise");
4480 staticpro (&Qauto_raise
);
4481 Qauto_lower
= intern ("auto-lower");
4482 staticpro (&Qauto_lower
);
4483 Qbackground_color
= intern ("background-color");
4484 staticpro (&Qbackground_color
);
4485 Qbar
= intern ("bar");
4487 Qborder_color
= intern ("border-color");
4488 staticpro (&Qborder_color
);
4489 Qborder_width
= intern ("border-width");
4490 staticpro (&Qborder_width
);
4491 Qbox
= intern ("box");
4493 Qcursor_color
= intern ("cursor-color");
4494 staticpro (&Qcursor_color
);
4495 Qcursor_type
= intern ("cursor-type");
4496 staticpro (&Qcursor_type
);
4497 Qfont
= intern ("font");
4499 Qforeground_color
= intern ("foreground-color");
4500 staticpro (&Qforeground_color
);
4501 Qgeometry
= intern ("geometry");
4502 staticpro (&Qgeometry
);
4503 Qicon_left
= intern ("icon-left");
4504 staticpro (&Qicon_left
);
4505 Qicon_top
= intern ("icon-top");
4506 staticpro (&Qicon_top
);
4507 Qicon_type
= intern ("icon-type");
4508 staticpro (&Qicon_type
);
4509 Qinternal_border_width
= intern ("internal-border-width");
4510 staticpro (&Qinternal_border_width
);
4511 Qleft
= intern ("left");
4513 Qmouse_color
= intern ("mouse-color");
4514 staticpro (&Qmouse_color
);
4515 Qnone
= intern ("none");
4517 Qparent_id
= intern ("parent-id");
4518 staticpro (&Qparent_id
);
4519 Qscroll_bar_width
= intern ("scroll-bar-width");
4520 staticpro (&Qscroll_bar_width
);
4521 Qsuppress_icon
= intern ("suppress-icon");
4522 staticpro (&Qsuppress_icon
);
4523 Qtop
= intern ("top");
4525 Qundefined_color
= intern ("undefined-color");
4526 staticpro (&Qundefined_color
);
4527 Qvertical_scroll_bars
= intern ("vertical-scroll-bars");
4528 staticpro (&Qvertical_scroll_bars
);
4529 Qvisibility
= intern ("visibility");
4530 staticpro (&Qvisibility
);
4531 Qwindow_id
= intern ("window-id");
4532 staticpro (&Qwindow_id
);
4533 Qx_frame_parameter
= intern ("x-frame-parameter");
4534 staticpro (&Qx_frame_parameter
);
4535 Qx_resource_name
= intern ("x-resource-name");
4536 staticpro (&Qx_resource_name
);
4537 Quser_position
= intern ("user-position");
4538 staticpro (&Quser_position
);
4539 Quser_size
= intern ("user-size");
4540 staticpro (&Quser_size
);
4541 Qdisplay
= intern ("display");
4542 staticpro (&Qdisplay
);
4543 /* This is the end of symbol initialization. */
4545 Fput (Qundefined_color
, Qerror_conditions
,
4546 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
4547 Fput (Qundefined_color
, Qerror_message
,
4548 build_string ("Undefined color"));
4550 init_x_parm_symbols ();
4552 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path
,
4553 "List of directories to search for bitmap files for X.");
4554 Vx_bitmap_file_path
= Fcons (build_string (PATH_BITMAPS
), Qnil
);
4556 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
4557 "The shape of the pointer when over text.\n\
4558 Changing the value does not affect existing frames\n\
4559 unless you set the mouse color.");
4560 Vx_pointer_shape
= Qnil
;
4562 DEFVAR_LISP ("x-resource-name", &Vx_resource_name
,
4563 "The name Emacs uses to look up X resources; for internal use only.\n\
4564 `x-get-resource' uses this as the first component of the instance name\n\
4565 when requesting resource values.\n\
4566 Emacs initially sets `x-resource-name' to the name under which Emacs\n\
4567 was invoked, or to the value specified with the `-name' or `-rn'\n\
4568 switches, if present.");
4569 Vx_resource_name
= Qnil
;
4571 #if 0 /* This doesn't really do anything. */
4572 DEFVAR_INT ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape
,
4573 "The shape of the pointer when not over text.\n\
4574 This variable takes effect when you create a new frame\n\
4575 or when you set the mouse color.");
4577 Vx_nontext_pointer_shape
= Qnil
;
4579 #if 0 /* This doesn't really do anything. */
4580 DEFVAR_INT ("x-mode-pointer-shape", &Vx_mode_pointer_shape
,
4581 "The shape of the pointer when over the mode line.\n\
4582 This variable takes effect when you create a new frame\n\
4583 or when you set the mouse color.");
4585 Vx_mode_pointer_shape
= Qnil
;
4587 DEFVAR_INT ("x-sensitive-text-pointer-shape",
4588 &Vx_sensitive_text_pointer_shape
,
4589 "The shape of the pointer when over mouse-sensitive text.\n\
4590 This variable takes effect when you create a new frame\n\
4591 or when you set the mouse color.");
4592 Vx_sensitive_text_pointer_shape
= Qnil
;
4594 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
4595 "A string indicating the foreground color of the cursor box.");
4596 Vx_cursor_fore_pixel
= Qnil
;
4598 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
4599 "Non-nil if no X window manager is in use.");
4601 #ifdef USE_X_TOOLKIT
4602 Fprovide (intern ("x-toolkit"));
4605 defsubr (&Sx_get_resource
);
4607 defsubr (&Sx_draw_rectangle
);
4608 defsubr (&Sx_erase_rectangle
);
4609 defsubr (&Sx_contour_region
);
4610 defsubr (&Sx_uncontour_region
);
4612 defsubr (&Sx_list_fonts
);
4613 defsubr (&Sx_display_color_p
);
4614 defsubr (&Sx_display_grayscale_p
);
4615 defsubr (&Sx_color_defined_p
);
4616 defsubr (&Sx_color_values
);
4617 defsubr (&Sx_server_max_request_size
);
4618 defsubr (&Sx_server_vendor
);
4619 defsubr (&Sx_server_version
);
4620 defsubr (&Sx_display_pixel_width
);
4621 defsubr (&Sx_display_pixel_height
);
4622 defsubr (&Sx_display_mm_width
);
4623 defsubr (&Sx_display_mm_height
);
4624 defsubr (&Sx_display_screens
);
4625 defsubr (&Sx_display_planes
);
4626 defsubr (&Sx_display_color_cells
);
4627 defsubr (&Sx_display_visual_class
);
4628 defsubr (&Sx_display_backing_store
);
4629 defsubr (&Sx_display_save_under
);
4631 defsubr (&Sx_rebind_key
);
4632 defsubr (&Sx_rebind_keys
);
4633 defsubr (&Sx_track_pointer
);
4634 defsubr (&Sx_grab_pointer
);
4635 defsubr (&Sx_ungrab_pointer
);
4637 defsubr (&Sx_parse_geometry
);
4638 defsubr (&Sx_create_frame
);
4639 defsubr (&Sfocus_frame
);
4640 defsubr (&Sunfocus_frame
);
4642 defsubr (&Sx_horizontal_line
);
4644 defsubr (&Sx_open_connection
);
4645 defsubr (&Sx_close_connection
);
4646 defsubr (&Sx_display_list
);
4647 defsubr (&Sx_synchronize
);
4650 #endif /* HAVE_X_WINDOWS */