1 /* Functions for the X window system.
2 Copyright (C) 1989, 1992, 1993, 1994, 1995 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 /* This is part of a kludge--see lwlib/xlwmenu.c. */
82 XFontStruct
*xlwmenu_default_font
;
84 extern void free_frame_menubar ();
85 #endif /* USE_X_TOOLKIT */
87 #define min(a,b) ((a) < (b) ? (a) : (b))
88 #define max(a,b) ((a) > (b) ? (a) : (b))
91 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
93 #define MAXREQUEST(dpy) ((dpy)->max_request_size)
96 /* The name we're using in resource queries. */
97 Lisp_Object Vx_resource_name
;
99 /* The background and shape of the mouse pointer, and shape when not
100 over text or in the modeline. */
101 Lisp_Object Vx_pointer_shape
, Vx_nontext_pointer_shape
, Vx_mode_pointer_shape
;
102 /* The shape when over mouse-sensitive text. */
103 Lisp_Object Vx_sensitive_text_pointer_shape
;
105 /* Color of chars displayed in cursor box. */
106 Lisp_Object Vx_cursor_fore_pixel
;
108 /* Nonzero if using X. */
111 /* Non nil if no window manager is in use. */
112 Lisp_Object Vx_no_window_manager
;
114 /* Search path for bitmap files. */
115 Lisp_Object Vx_bitmap_file_path
;
117 /* Evaluate this expression to rebuild the section of syms_of_xfns
118 that initializes and staticpros the symbols declared below. Note
119 that Emacs 18 has a bug that keeps C-x C-e from being able to
120 evaluate this expression.
123 ;; Accumulate a list of the symbols we want to initialize from the
124 ;; declarations at the top of the file.
125 (goto-char (point-min))
126 (search-forward "/\*&&& symbols declared here &&&*\/\n")
128 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
130 (cons (buffer-substring (match-beginning 1) (match-end 1))
133 (setq symbol-list (nreverse symbol-list))
134 ;; Delete the section of syms_of_... where we initialize the symbols.
135 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
136 (let ((start (point)))
137 (while (looking-at "^ Q")
139 (kill-region start (point)))
140 ;; Write a new symbol initialization section.
142 (insert (format " %s = intern (\"" (car symbol-list)))
143 (let ((start (point)))
144 (insert (substring (car symbol-list) 1))
145 (subst-char-in-region start (point) ?_ ?-))
146 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
147 (setq symbol-list (cdr symbol-list)))))
151 /*&&& symbols declared here &&&*/
152 Lisp_Object Qauto_raise
;
153 Lisp_Object Qauto_lower
;
154 Lisp_Object Qbackground_color
;
156 Lisp_Object Qborder_color
;
157 Lisp_Object Qborder_width
;
159 Lisp_Object Qcursor_color
;
160 Lisp_Object Qcursor_type
;
162 Lisp_Object Qforeground_color
;
163 Lisp_Object Qgeometry
;
164 Lisp_Object Qicon_left
;
165 Lisp_Object Qicon_top
;
166 Lisp_Object Qicon_type
;
167 Lisp_Object Qinternal_border_width
;
169 Lisp_Object Qmouse_color
;
171 Lisp_Object Qparent_id
;
172 Lisp_Object Qscroll_bar_width
;
173 Lisp_Object Qsuppress_icon
;
175 Lisp_Object Qundefined_color
;
176 Lisp_Object Qvertical_scroll_bars
;
177 Lisp_Object Qvisibility
;
178 Lisp_Object Qwindow_id
;
179 Lisp_Object Qx_frame_parameter
;
180 Lisp_Object Qx_resource_name
;
181 Lisp_Object Quser_position
;
182 Lisp_Object Quser_size
;
183 Lisp_Object Qdisplay
;
185 /* The below are defined in frame.c. */
186 extern Lisp_Object Qheight
, Qminibuffer
, Qname
, Qonly
, Qwidth
;
187 extern Lisp_Object Qunsplittable
, Qmenu_bar_lines
;
189 extern Lisp_Object Vwindow_system_version
;
192 /* Error if we are not connected to X. */
197 error ("X windows are not in use or not initialized");
200 /* Nonzero if using X for display. */
208 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
209 and checking validity for X. */
212 check_x_frame (frame
)
221 CHECK_LIVE_FRAME (frame
, 0);
225 error ("non-X frame used");
229 /* Let the user specify an X display with a frame.
230 nil stands for the selected frame--or, if that is not an X frame,
231 the first X display on the list. */
233 static struct x_display_info
*
234 check_x_display_info (frame
)
239 if (FRAME_X_P (selected_frame
))
240 return FRAME_X_DISPLAY_INFO (selected_frame
);
241 else if (x_display_list
!= 0)
242 return x_display_list
;
244 error ("X windows are not in use or not initialized");
246 else if (STRINGP (frame
))
247 return x_display_info_for_name (frame
);
252 CHECK_LIVE_FRAME (frame
, 0);
255 error ("non-X frame used");
256 return FRAME_X_DISPLAY_INFO (f
);
260 /* Return the Emacs frame-object corresponding to an X window.
261 It could be the frame's main window or an icon window. */
263 /* This function can be called during GC, so use GC_xxx type test macros. */
266 x_window_to_frame (dpyinfo
, wdesc
)
267 struct x_display_info
*dpyinfo
;
270 Lisp_Object tail
, frame
;
273 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
275 frame
= XCONS (tail
)->car
;
276 if (!GC_FRAMEP (frame
))
279 if (f
->display
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
282 if ((f
->display
.x
->edit_widget
283 && XtWindow (f
->display
.x
->edit_widget
) == wdesc
)
284 || f
->display
.x
->icon_desc
== wdesc
)
286 #else /* not USE_X_TOOLKIT */
287 if (FRAME_X_WINDOW (f
) == wdesc
288 || f
->display
.x
->icon_desc
== wdesc
)
290 #endif /* not USE_X_TOOLKIT */
296 /* Like x_window_to_frame but also compares the window with the widget's
300 x_any_window_to_frame (dpyinfo
, wdesc
)
301 struct x_display_info
*dpyinfo
;
304 Lisp_Object tail
, frame
;
308 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
310 frame
= XCONS (tail
)->car
;
311 if (!GC_FRAMEP (frame
))
314 if (f
->display
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
317 /* This frame matches if the window is any of its widgets. */
318 if (wdesc
== XtWindow (x
->widget
)
319 || wdesc
== XtWindow (x
->column_widget
)
320 || wdesc
== XtWindow (x
->edit_widget
))
322 /* Match if the window is this frame's menubar. */
323 if (lw_window_is_in_menubar (wdesc
, x
->menubar_widget
))
329 /* Return the frame whose principal (outermost) window is WDESC.
330 If WDESC is some other (smaller) window, we return 0. */
333 x_top_window_to_frame (dpyinfo
, wdesc
)
334 struct x_display_info
*dpyinfo
;
337 Lisp_Object tail
, frame
;
341 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
343 frame
= XCONS (tail
)->car
;
344 if (!GC_FRAMEP (frame
))
347 if (f
->display
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
350 /* This frame matches if the window is its topmost widget. */
351 if (wdesc
== XtWindow (x
->widget
))
353 /* Match if the window is this frame's menubar. */
354 if (x
->menubar_widget
355 && wdesc
== XtWindow (x
->menubar_widget
))
360 #endif /* USE_X_TOOLKIT */
364 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
365 id, which is just an int that this section returns. Bitmaps are
366 reference counted so they can be shared among frames.
368 Bitmap indices are guaranteed to be > 0, so a negative number can
369 be used to indicate no bitmap.
371 If you use x_create_bitmap_from_data, then you must keep track of
372 the bitmaps yourself. That is, creating a bitmap from the same
373 data more than once will not be caught. */
376 /* Functions to access the contents of a bitmap, given an id. */
379 x_bitmap_height (f
, id
)
383 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].height
;
387 x_bitmap_width (f
, id
)
391 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].width
;
395 x_bitmap_pixmap (f
, id
)
399 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].pixmap
;
403 /* Allocate a new bitmap record. Returns index of new record. */
406 x_allocate_bitmap_record (f
)
409 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
412 if (dpyinfo
->bitmaps
== NULL
)
414 dpyinfo
->bitmaps_size
= 10;
416 = (struct x_bitmap_record
*) xmalloc (dpyinfo
->bitmaps_size
* sizeof (struct x_bitmap_record
));
417 dpyinfo
->bitmaps_last
= 1;
421 if (dpyinfo
->bitmaps_last
< dpyinfo
->bitmaps_size
)
422 return ++dpyinfo
->bitmaps_last
;
424 for (i
= 0; i
< dpyinfo
->bitmaps_size
; ++i
)
425 if (dpyinfo
->bitmaps
[i
].refcount
== 0)
428 dpyinfo
->bitmaps_size
*= 2;
430 = (struct x_bitmap_record
*) xrealloc (dpyinfo
->bitmaps
,
431 dpyinfo
->bitmaps_size
* sizeof (struct x_bitmap_record
));
432 return ++dpyinfo
->bitmaps_last
;
435 /* Add one reference to the reference count of the bitmap with id ID. */
438 x_reference_bitmap (f
, id
)
442 ++FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].refcount
;
445 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
448 x_create_bitmap_from_data (f
, bits
, width
, height
)
451 unsigned int width
, height
;
453 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
457 bitmap
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
458 bits
, width
, height
);
463 id
= x_allocate_bitmap_record (f
);
464 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
465 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
466 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
467 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
468 dpyinfo
->bitmaps
[id
- 1].height
= height
;
469 dpyinfo
->bitmaps
[id
- 1].width
= width
;
474 /* Create bitmap from file FILE for frame F. */
477 x_create_bitmap_from_file (f
, file
)
481 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
482 unsigned int width
, height
;
484 int xhot
, yhot
, result
, id
;
489 /* Look for an existing bitmap with the same name. */
490 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
492 if (dpyinfo
->bitmaps
[id
].refcount
493 && dpyinfo
->bitmaps
[id
].file
494 && !strcmp (dpyinfo
->bitmaps
[id
].file
, (char *) XSTRING (file
)->data
))
496 ++dpyinfo
->bitmaps
[id
].refcount
;
501 /* Search bitmap-file-path for the file, if appropriate. */
502 fd
= openp (Vx_bitmap_file_path
, file
, "", &found
, 0);
507 filename
= (char *) XSTRING (found
)->data
;
509 result
= XReadBitmapFile (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
510 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
511 if (result
!= BitmapSuccess
)
514 id
= x_allocate_bitmap_record (f
);
515 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
516 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
517 dpyinfo
->bitmaps
[id
- 1].file
= (char *) xmalloc (XSTRING (file
)->size
+ 1);
518 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
519 dpyinfo
->bitmaps
[id
- 1].height
= height
;
520 dpyinfo
->bitmaps
[id
- 1].width
= width
;
521 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, XSTRING (file
)->data
);
526 /* Remove reference to bitmap with id number ID. */
529 x_destroy_bitmap (f
, id
)
533 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
537 --dpyinfo
->bitmaps
[id
- 1].refcount
;
538 if (dpyinfo
->bitmaps
[id
- 1].refcount
== 0)
540 XFreePixmap (FRAME_X_DISPLAY (f
), dpyinfo
->bitmaps
[id
- 1].pixmap
);
541 if (dpyinfo
->bitmaps
[id
- 1].file
)
543 free (dpyinfo
->bitmaps
[id
- 1].file
);
544 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
550 /* Free all the bitmaps for the display specified by DPYINFO. */
553 x_destroy_all_bitmaps (dpyinfo
)
554 struct x_display_info
*dpyinfo
;
557 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++)
558 if (dpyinfo
->bitmaps
[i
].refcount
> 0)
560 XFreePixmap (dpyinfo
->display
, dpyinfo
->bitmaps
[i
].pixmap
);
561 if (dpyinfo
->bitmaps
[i
].file
)
562 free (dpyinfo
->bitmaps
[i
].file
);
564 dpyinfo
->bitmaps_last
= 0;
567 /* Connect the frame-parameter names for X frames
568 to the ways of passing the parameter values to the window system.
570 The name of a parameter, as a Lisp symbol,
571 has an `x-frame-parameter' property which is an integer in Lisp
572 but can be interpreted as an `enum x_frame_parm' in C. */
576 X_PARM_FOREGROUND_COLOR
,
577 X_PARM_BACKGROUND_COLOR
,
584 X_PARM_INTERNAL_BORDER_WIDTH
,
588 X_PARM_VERT_SCROLL_BAR
,
590 X_PARM_MENU_BAR_LINES
594 struct x_frame_parm_table
597 void (*setter
)( /* struct frame *frame, Lisp_Object val, oldval */ );
600 void x_set_foreground_color ();
601 void x_set_background_color ();
602 void x_set_mouse_color ();
603 void x_set_cursor_color ();
604 void x_set_border_color ();
605 void x_set_cursor_type ();
606 void x_set_icon_type ();
608 void x_set_border_width ();
609 void x_set_internal_border_width ();
610 void x_explicitly_set_name ();
611 void x_set_autoraise ();
612 void x_set_autolower ();
613 void x_set_vertical_scroll_bars ();
614 void x_set_visibility ();
615 void x_set_menu_bar_lines ();
616 void x_set_scroll_bar_width ();
617 void x_set_unsplittable ();
619 static struct x_frame_parm_table x_frame_parms
[] =
621 "foreground-color", x_set_foreground_color
,
622 "background-color", x_set_background_color
,
623 "mouse-color", x_set_mouse_color
,
624 "cursor-color", x_set_cursor_color
,
625 "border-color", x_set_border_color
,
626 "cursor-type", x_set_cursor_type
,
627 "icon-type", x_set_icon_type
,
629 "border-width", x_set_border_width
,
630 "internal-border-width", x_set_internal_border_width
,
631 "name", x_explicitly_set_name
,
632 "auto-raise", x_set_autoraise
,
633 "auto-lower", x_set_autolower
,
634 "vertical-scroll-bars", x_set_vertical_scroll_bars
,
635 "visibility", x_set_visibility
,
636 "menu-bar-lines", x_set_menu_bar_lines
,
637 "scroll-bar-width", x_set_scroll_bar_width
,
638 "unsplittable", x_set_unsplittable
,
641 /* Attach the `x-frame-parameter' properties to
642 the Lisp symbol names of parameters relevant to X. */
644 init_x_parm_symbols ()
648 for (i
= 0; i
< sizeof (x_frame_parms
) / sizeof (x_frame_parms
[0]); i
++)
649 Fput (intern (x_frame_parms
[i
].name
), Qx_frame_parameter
,
653 /* Change the parameters of FRAME as specified by ALIST.
654 If a parameter is not specially recognized, do nothing;
655 otherwise call the `x_set_...' function for that parameter. */
658 x_set_frame_parameters (f
, alist
)
664 /* If both of these parameters are present, it's more efficient to
665 set them both at once. So we wait until we've looked at the
666 entire list before we set them. */
667 Lisp_Object width
, height
;
670 Lisp_Object left
, top
;
672 /* Same with these. */
673 Lisp_Object icon_left
, icon_top
;
675 /* Record in these vectors all the parms specified. */
679 int left_no_change
= 0, top_no_change
= 0;
680 int icon_left_no_change
= 0, icon_top_no_change
= 0;
683 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
686 parms
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
687 values
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
689 /* Extract parm names and values into those vectors. */
692 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
694 Lisp_Object elt
, prop
, val
;
697 parms
[i
] = Fcar (elt
);
698 values
[i
] = Fcdr (elt
);
702 width
= height
= top
= left
= Qunbound
;
703 icon_left
= icon_top
= 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
))
721 else if (EQ (prop
, Qicon_top
))
723 else if (EQ (prop
, Qicon_left
))
727 register Lisp_Object param_index
, old_value
;
729 param_index
= Fget (prop
, Qx_frame_parameter
);
730 old_value
= get_frame_param (f
, prop
);
731 store_frame_param (f
, prop
, val
);
732 if (NATNUMP (param_index
)
733 && (XFASTINT (param_index
)
734 < sizeof (x_frame_parms
)/sizeof (x_frame_parms
[0])))
735 (*x_frame_parms
[XINT (param_index
)].setter
)(f
, val
, old_value
);
739 /* Don't die if just one of these was set. */
740 if (EQ (left
, Qunbound
))
743 if (f
->display
.x
->left_pos
< 0)
744 left
= Fcons (Qplus
, Fcons (make_number (f
->display
.x
->left_pos
), Qnil
));
746 XSETINT (left
, f
->display
.x
->left_pos
);
748 if (EQ (top
, Qunbound
))
751 if (f
->display
.x
->top_pos
< 0)
752 top
= Fcons (Qplus
, Fcons (make_number (f
->display
.x
->top_pos
), Qnil
));
754 XSETINT (top
, f
->display
.x
->top_pos
);
757 /* If one of the icon positions was not set, preserve or default it. */
758 if (EQ (icon_left
, Qunbound
) || ! INTEGERP (icon_left
))
760 icon_left_no_change
= 1;
761 icon_left
= Fcdr (Fassq (Qicon_left
, f
->param_alist
));
762 if (NILP (icon_left
))
763 XSETINT (icon_left
, 0);
765 if (EQ (icon_top
, Qunbound
) || ! INTEGERP (icon_top
))
767 icon_top_no_change
= 1;
768 icon_top
= Fcdr (Fassq (Qicon_top
, f
->param_alist
));
770 XSETINT (icon_top
, 0);
773 /* Don't die if just one of these was set. */
774 if (EQ (width
, Qunbound
))
775 XSETINT (width
, FRAME_WIDTH (f
));
776 if (EQ (height
, Qunbound
))
777 XSETINT (height
, FRAME_HEIGHT (f
));
779 /* Don't set these parameters these unless they've been explicitly
780 specified. The window might be mapped or resized while we're in
781 this function, and we don't want to override that unless the lisp
782 code has asked for it.
784 Don't set these parameters unless they actually differ from the
785 window's current parameters; the window may not actually exist
790 check_frame_size (f
, &height
, &width
);
792 XSETFRAME (frame
, f
);
794 if ((NUMBERP (width
) && XINT (width
) != FRAME_WIDTH (f
))
795 || (NUMBERP (height
) && XINT (height
) != FRAME_HEIGHT (f
)))
796 Fset_frame_size (frame
, width
, height
);
798 if ((!NILP (left
) || !NILP (top
))
799 && ! (left_no_change
&& top_no_change
)
800 && ! (NUMBERP (left
) && XINT (left
) == f
->display
.x
->left_pos
801 && NUMBERP (top
) && XINT (top
) == f
->display
.x
->top_pos
))
806 /* Record the signs. */
807 f
->display
.x
->size_hint_flags
&= ~ (XNegative
| YNegative
);
808 if (EQ (left
, Qminus
))
809 f
->display
.x
->size_hint_flags
|= XNegative
;
810 else if (INTEGERP (left
))
812 leftpos
= XINT (left
);
814 f
->display
.x
->size_hint_flags
|= XNegative
;
816 else if (CONSP (left
) && EQ (XCONS (left
)->car
, Qminus
)
817 && CONSP (XCONS (left
)->cdr
)
818 && INTEGERP (XCONS (XCONS (left
)->cdr
)->car
))
820 leftpos
= - XINT (XCONS (XCONS (left
)->cdr
)->car
);
821 f
->display
.x
->size_hint_flags
|= XNegative
;
823 else if (CONSP (left
) && EQ (XCONS (left
)->car
, Qplus
)
824 && CONSP (XCONS (left
)->cdr
)
825 && INTEGERP (XCONS (XCONS (left
)->cdr
)->car
))
827 leftpos
= XINT (XCONS (XCONS (left
)->cdr
)->car
);
830 if (EQ (top
, Qminus
))
831 f
->display
.x
->size_hint_flags
|= YNegative
;
832 else if (INTEGERP (top
))
836 f
->display
.x
->size_hint_flags
|= YNegative
;
838 else if (CONSP (top
) && EQ (XCONS (top
)->car
, Qminus
)
839 && CONSP (XCONS (top
)->cdr
)
840 && INTEGERP (XCONS (XCONS (top
)->cdr
)->car
))
842 toppos
= - XINT (XCONS (XCONS (top
)->cdr
)->car
);
843 f
->display
.x
->size_hint_flags
|= YNegative
;
845 else if (CONSP (top
) && EQ (XCONS (top
)->car
, Qplus
)
846 && CONSP (XCONS (top
)->cdr
)
847 && INTEGERP (XCONS (XCONS (top
)->cdr
)->car
))
849 toppos
= XINT (XCONS (XCONS (top
)->cdr
)->car
);
853 /* Store the numeric value of the position. */
854 f
->display
.x
->top_pos
= toppos
;
855 f
->display
.x
->left_pos
= leftpos
;
857 f
->display
.x
->win_gravity
= NorthWestGravity
;
859 /* Actually set that position, and convert to absolute. */
860 x_set_offset (f
, leftpos
, toppos
, 0);
863 if ((!NILP (icon_left
) || !NILP (icon_top
))
864 && ! (icon_left_no_change
&& icon_top_no_change
))
865 x_wm_set_icon_position (f
, XINT (icon_left
), XINT (icon_top
));
869 /* Store the screen positions of frame F into XPTR and YPTR.
870 These are the positions of the containing window manager window,
871 not Emacs's own window. */
874 x_real_positions (f
, xptr
, yptr
)
881 /* This is pretty gross, but seems to be the easiest way out of
882 the problem that arises when restarting window-managers. */
885 Window outer
= XtWindow (f
->display
.x
->widget
);
887 Window outer
= f
->display
.x
->window_desc
;
889 Window tmp_root_window
;
890 Window
*tmp_children
;
893 x_catch_errors (FRAME_X_DISPLAY (f
));
896 XQueryTree (FRAME_X_DISPLAY (f
), outer
, &tmp_root_window
,
897 &f
->display
.x
->parent_desc
,
898 &tmp_children
, &tmp_nchildren
);
899 xfree (tmp_children
);
903 /* Find the position of the outside upper-left corner of
904 the inner window, with respect to the outer window. */
905 if (f
->display
.x
->parent_desc
!= FRAME_X_DISPLAY_INFO (f
)->root_window
)
907 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
909 /* From-window, to-window. */
911 XtWindow (f
->display
.x
->widget
),
913 f
->display
.x
->window_desc
,
915 f
->display
.x
->parent_desc
,
917 /* From-position, to-position. */
918 0, 0, &win_x
, &win_y
,
923 win_x
+= f
->display
.x
->border_width
;
924 win_y
+= f
->display
.x
->border_width
;
927 /* It is possible for the window returned by the XQueryNotify
928 to become invalid by the time we call XTranslateCoordinates.
929 That can happen when you restart some window managers.
930 If so, we get an error in XTranslateCoordinates.
931 Detect that and try the whole thing over. */
932 if (! x_had_errors_p (FRAME_X_DISPLAY (f
)))
936 x_uncatch_errors (FRAME_X_DISPLAY (f
));
938 *xptr
= f
->display
.x
->left_pos
- win_x
;
939 *yptr
= f
->display
.x
->top_pos
- win_y
;
942 /* Insert a description of internally-recorded parameters of frame X
943 into the parameter alist *ALISTPTR that is to be given to the user.
944 Only parameters that are specific to the X window system
945 and whose values are not correctly recorded in the frame's
946 param_alist need to be considered here. */
948 x_report_frame_params (f
, alistptr
)
950 Lisp_Object
*alistptr
;
954 store_in_alist (alistptr
, Qleft
, make_number (f
->display
.x
->left_pos
));
955 store_in_alist (alistptr
, Qtop
, make_number (f
->display
.x
->top_pos
));
956 store_in_alist (alistptr
, Qborder_width
,
957 make_number (f
->display
.x
->border_width
));
958 store_in_alist (alistptr
, Qinternal_border_width
,
959 make_number (f
->display
.x
->internal_border_width
));
960 sprintf (buf
, "%ld", (long) FRAME_X_WINDOW (f
));
961 store_in_alist (alistptr
, Qwindow_id
,
963 FRAME_SAMPLE_VISIBILITY (f
);
964 store_in_alist (alistptr
, Qvisibility
,
965 (FRAME_VISIBLE_P (f
) ? Qt
966 : FRAME_ICONIFIED_P (f
) ? Qicon
: Qnil
));
967 store_in_alist (alistptr
, Qdisplay
,
968 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->car
);
972 /* Decide if color named COLOR is valid for the display associated with
973 the selected frame; if so, return the rgb values in COLOR_DEF.
974 If ALLOC is nonzero, allocate a new colormap cell. */
977 defined_color (f
, color
, color_def
, alloc
)
984 Colormap screen_colormap
;
985 Display
*display
= FRAME_X_DISPLAY (f
);
988 screen_colormap
= DefaultColormap (display
, XDefaultScreen (display
));
990 status
= XParseColor (display
, screen_colormap
, color
, color_def
);
993 status
= XAllocColor (display
, screen_colormap
, color_def
);
996 /* If we got to this point, the colormap is full, so we're
997 going to try and get the next closest color.
998 The algorithm used is a least-squares matching, which is
999 what X uses for closest color matching with StaticColor visuals. */
1004 long nearest_delta
, trial_delta
;
1007 no_cells
= XDisplayCells (display
, XDefaultScreen (display
));
1008 cells
= (XColor
*) alloca (sizeof (XColor
) * no_cells
);
1010 for (x
= 0; x
< no_cells
; x
++)
1013 XQueryColors (display
, screen_colormap
, cells
, no_cells
);
1015 /* I'm assuming CSE so I'm not going to condense this. */
1016 nearest_delta
= ((((color_def
->red
>> 8) - (cells
[0].red
>> 8))
1017 * ((color_def
->red
>> 8) - (cells
[0].red
>> 8)))
1019 (((color_def
->green
>> 8) - (cells
[0].green
>> 8))
1020 * ((color_def
->green
>> 8) - (cells
[0].green
>> 8)))
1022 (((color_def
->blue
>> 8) - (cells
[0].blue
>> 8))
1023 * ((color_def
->blue
>> 8) - (cells
[0].blue
>> 8))));
1024 for (x
= 1; x
< no_cells
; x
++)
1026 trial_delta
= ((((color_def
->red
>> 8) - (cells
[x
].red
>> 8))
1027 * ((color_def
->red
>> 8) - (cells
[x
].red
>> 8)))
1029 (((color_def
->green
>> 8) - (cells
[x
].green
>> 8))
1030 * ((color_def
->green
>> 8) - (cells
[x
].green
>> 8)))
1032 (((color_def
->blue
>> 8) - (cells
[x
].blue
>> 8))
1033 * ((color_def
->blue
>> 8) - (cells
[x
].blue
>> 8))));
1034 if (trial_delta
< nearest_delta
)
1037 nearest_delta
= trial_delta
;
1040 color_def
->red
= cells
[nearest
].red
;
1041 color_def
->green
= cells
[nearest
].green
;
1042 color_def
->blue
= cells
[nearest
].blue
;
1043 status
= XAllocColor (display
, screen_colormap
, color_def
);
1054 /* Given a string ARG naming a color, compute a pixel value from it
1055 suitable for screen F.
1056 If F is not a color screen, return DEF (default) regardless of what
1060 x_decode_color (f
, arg
, def
)
1067 CHECK_STRING (arg
, 0);
1069 if (strcmp (XSTRING (arg
)->data
, "black") == 0)
1070 return BLACK_PIX_DEFAULT (f
);
1071 else if (strcmp (XSTRING (arg
)->data
, "white") == 0)
1072 return WHITE_PIX_DEFAULT (f
);
1074 if (FRAME_X_DISPLAY_INFO (f
)->n_planes
== 1)
1077 /* defined_color is responsible for coping with failures
1078 by looking for a near-miss. */
1079 if (defined_color (f
, XSTRING (arg
)->data
, &cdef
, 1))
1082 /* defined_color failed; return an ultimate default. */
1086 /* Functions called only from `x_set_frame_param'
1087 to set individual parameters.
1089 If FRAME_X_WINDOW (f) is 0,
1090 the frame is being created and its X-window does not exist yet.
1091 In that case, just record the parameter's new value
1092 in the standard place; do not attempt to change the window. */
1095 x_set_foreground_color (f
, arg
, oldval
)
1097 Lisp_Object arg
, oldval
;
1099 f
->display
.x
->foreground_pixel
1100 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1101 if (FRAME_X_WINDOW (f
) != 0)
1104 XSetForeground (FRAME_X_DISPLAY (f
), f
->display
.x
->normal_gc
,
1105 f
->display
.x
->foreground_pixel
);
1106 XSetBackground (FRAME_X_DISPLAY (f
), f
->display
.x
->reverse_gc
,
1107 f
->display
.x
->foreground_pixel
);
1109 recompute_basic_faces (f
);
1110 if (FRAME_VISIBLE_P (f
))
1116 x_set_background_color (f
, arg
, oldval
)
1118 Lisp_Object arg
, oldval
;
1123 f
->display
.x
->background_pixel
1124 = x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
1126 if (FRAME_X_WINDOW (f
) != 0)
1129 /* The main frame area. */
1130 XSetBackground (FRAME_X_DISPLAY (f
), f
->display
.x
->normal_gc
,
1131 f
->display
.x
->background_pixel
);
1132 XSetForeground (FRAME_X_DISPLAY (f
), f
->display
.x
->reverse_gc
,
1133 f
->display
.x
->background_pixel
);
1134 XSetForeground (FRAME_X_DISPLAY (f
), f
->display
.x
->cursor_gc
,
1135 f
->display
.x
->background_pixel
);
1136 XSetWindowBackground (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1137 f
->display
.x
->background_pixel
);
1140 for (bar
= FRAME_SCROLL_BARS (f
); !NILP (bar
);
1141 bar
= XSCROLL_BAR (bar
)->next
)
1142 XSetWindowBackground (FRAME_X_DISPLAY (f
),
1143 SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
)),
1144 f
->display
.x
->background_pixel
);
1148 recompute_basic_faces (f
);
1150 if (FRAME_VISIBLE_P (f
))
1156 x_set_mouse_color (f
, arg
, oldval
)
1158 Lisp_Object arg
, oldval
;
1160 Cursor cursor
, nontext_cursor
, mode_cursor
, cross_cursor
;
1163 if (!EQ (Qnil
, arg
))
1164 f
->display
.x
->mouse_pixel
1165 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1166 mask_color
= f
->display
.x
->background_pixel
;
1167 /* No invisible pointers. */
1168 if (mask_color
== f
->display
.x
->mouse_pixel
1169 && mask_color
== f
->display
.x
->background_pixel
)
1170 f
->display
.x
->mouse_pixel
= f
->display
.x
->foreground_pixel
;
1174 /* It's not okay to crash if the user selects a screwy cursor. */
1175 x_catch_errors (FRAME_X_DISPLAY (f
));
1177 if (!EQ (Qnil
, Vx_pointer_shape
))
1179 CHECK_NUMBER (Vx_pointer_shape
, 0);
1180 cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XINT (Vx_pointer_shape
));
1183 cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_xterm
);
1184 x_check_errors (FRAME_X_DISPLAY (f
), "bad text pointer cursor: %s");
1186 if (!EQ (Qnil
, Vx_nontext_pointer_shape
))
1188 CHECK_NUMBER (Vx_nontext_pointer_shape
, 0);
1189 nontext_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
),
1190 XINT (Vx_nontext_pointer_shape
));
1193 nontext_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_left_ptr
);
1194 x_check_errors (FRAME_X_DISPLAY (f
), "bad nontext pointer cursor: %s");
1196 if (!EQ (Qnil
, Vx_mode_pointer_shape
))
1198 CHECK_NUMBER (Vx_mode_pointer_shape
, 0);
1199 mode_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
),
1200 XINT (Vx_mode_pointer_shape
));
1203 mode_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_xterm
);
1204 x_check_errors (FRAME_X_DISPLAY (f
), "bad modeline pointer cursor: %s");
1206 if (!EQ (Qnil
, Vx_sensitive_text_pointer_shape
))
1208 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
, 0);
1210 = XCreateFontCursor (FRAME_X_DISPLAY (f
),
1211 XINT (Vx_sensitive_text_pointer_shape
));
1214 cross_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_crosshair
);
1216 /* Check and report errors with the above calls. */
1217 x_check_errors (FRAME_X_DISPLAY (f
), "can't set cursor shape: %s");
1218 x_uncatch_errors (FRAME_X_DISPLAY (f
));
1221 XColor fore_color
, back_color
;
1223 fore_color
.pixel
= f
->display
.x
->mouse_pixel
;
1224 back_color
.pixel
= mask_color
;
1225 XQueryColor (FRAME_X_DISPLAY (f
),
1226 DefaultColormap (FRAME_X_DISPLAY (f
),
1227 DefaultScreen (FRAME_X_DISPLAY (f
))),
1229 XQueryColor (FRAME_X_DISPLAY (f
),
1230 DefaultColormap (FRAME_X_DISPLAY (f
),
1231 DefaultScreen (FRAME_X_DISPLAY (f
))),
1233 XRecolorCursor (FRAME_X_DISPLAY (f
), cursor
,
1234 &fore_color
, &back_color
);
1235 XRecolorCursor (FRAME_X_DISPLAY (f
), nontext_cursor
,
1236 &fore_color
, &back_color
);
1237 XRecolorCursor (FRAME_X_DISPLAY (f
), mode_cursor
,
1238 &fore_color
, &back_color
);
1239 XRecolorCursor (FRAME_X_DISPLAY (f
), cross_cursor
,
1240 &fore_color
, &back_color
);
1243 if (FRAME_X_WINDOW (f
) != 0)
1245 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
1248 if (cursor
!= f
->display
.x
->text_cursor
&& f
->display
.x
->text_cursor
!= 0)
1249 XFreeCursor (FRAME_X_DISPLAY (f
), f
->display
.x
->text_cursor
);
1250 f
->display
.x
->text_cursor
= cursor
;
1252 if (nontext_cursor
!= f
->display
.x
->nontext_cursor
1253 && f
->display
.x
->nontext_cursor
!= 0)
1254 XFreeCursor (FRAME_X_DISPLAY (f
), f
->display
.x
->nontext_cursor
);
1255 f
->display
.x
->nontext_cursor
= nontext_cursor
;
1257 if (mode_cursor
!= f
->display
.x
->modeline_cursor
1258 && f
->display
.x
->modeline_cursor
!= 0)
1259 XFreeCursor (FRAME_X_DISPLAY (f
), f
->display
.x
->modeline_cursor
);
1260 f
->display
.x
->modeline_cursor
= mode_cursor
;
1261 if (cross_cursor
!= f
->display
.x
->cross_cursor
1262 && f
->display
.x
->cross_cursor
!= 0)
1263 XFreeCursor (FRAME_X_DISPLAY (f
), f
->display
.x
->cross_cursor
);
1264 f
->display
.x
->cross_cursor
= cross_cursor
;
1266 XFlush (FRAME_X_DISPLAY (f
));
1271 x_set_cursor_color (f
, arg
, oldval
)
1273 Lisp_Object arg
, oldval
;
1275 unsigned long fore_pixel
;
1277 if (!EQ (Vx_cursor_fore_pixel
, Qnil
))
1278 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
1279 WHITE_PIX_DEFAULT (f
));
1281 fore_pixel
= f
->display
.x
->background_pixel
;
1282 f
->display
.x
->cursor_pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1284 /* Make sure that the cursor color differs from the background color. */
1285 if (f
->display
.x
->cursor_pixel
== f
->display
.x
->background_pixel
)
1287 f
->display
.x
->cursor_pixel
= f
->display
.x
->mouse_pixel
;
1288 if (f
->display
.x
->cursor_pixel
== fore_pixel
)
1289 fore_pixel
= f
->display
.x
->background_pixel
;
1291 f
->display
.x
->cursor_foreground_pixel
= fore_pixel
;
1293 if (FRAME_X_WINDOW (f
) != 0)
1296 XSetBackground (FRAME_X_DISPLAY (f
), f
->display
.x
->cursor_gc
,
1297 f
->display
.x
->cursor_pixel
);
1298 XSetForeground (FRAME_X_DISPLAY (f
), f
->display
.x
->cursor_gc
,
1302 if (FRAME_VISIBLE_P (f
))
1304 x_display_cursor (f
, 0);
1305 x_display_cursor (f
, 1);
1310 /* Set the border-color of frame F to value described by ARG.
1311 ARG can be a string naming a color.
1312 The border-color is used for the border that is drawn by the X server.
1313 Note that this does not fully take effect if done before
1314 F has an x-window; it must be redone when the window is created.
1316 Note: this is done in two routines because of the way X10 works.
1318 Note: under X11, this is normally the province of the window manager,
1319 and so emacs' border colors may be overridden. */
1322 x_set_border_color (f
, arg
, oldval
)
1324 Lisp_Object arg
, oldval
;
1329 CHECK_STRING (arg
, 0);
1330 str
= XSTRING (arg
)->data
;
1332 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1334 x_set_border_pixel (f
, pix
);
1337 /* Set the border-color of frame F to pixel value PIX.
1338 Note that this does not fully take effect if done before
1339 F has an x-window. */
1341 x_set_border_pixel (f
, pix
)
1345 f
->display
.x
->border_pixel
= pix
;
1347 if (FRAME_X_WINDOW (f
) != 0 && f
->display
.x
->border_width
> 0)
1353 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1357 if (FRAME_VISIBLE_P (f
))
1363 x_set_cursor_type (f
, arg
, oldval
)
1365 Lisp_Object arg
, oldval
;
1369 FRAME_DESIRED_CURSOR (f
) = bar_cursor
;
1370 f
->display
.x
->cursor_width
= 2;
1372 else if (CONSP (arg
) && EQ (XCONS (arg
)->car
, Qbar
)
1373 && INTEGERP (XCONS (arg
)->cdr
))
1375 FRAME_DESIRED_CURSOR (f
) = bar_cursor
;
1376 f
->display
.x
->cursor_width
= XINT (XCONS (arg
)->cdr
);
1379 /* Treat anything unknown as "box cursor".
1380 It was bad to signal an error; people have trouble fixing
1381 .Xdefaults with Emacs, when it has something bad in it. */
1382 FRAME_DESIRED_CURSOR (f
) = filled_box_cursor
;
1384 /* Make sure the cursor gets redrawn. This is overkill, but how
1385 often do people change cursor types? */
1386 update_mode_lines
++;
1390 x_set_icon_type (f
, arg
, oldval
)
1392 Lisp_Object arg
, oldval
;
1399 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1402 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1407 result
= x_text_icon (f
, 0);
1409 result
= x_bitmap_icon (f
, arg
);
1414 error ("No icon window available");
1417 /* If the window was unmapped (and its icon was mapped),
1418 the new icon is not mapped, so map the window in its stead. */
1419 if (FRAME_VISIBLE_P (f
))
1421 #ifdef USE_X_TOOLKIT
1422 XtPopup (f
->display
.x
->widget
, XtGrabNone
);
1424 XMapWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
1427 XFlush (FRAME_X_DISPLAY (f
));
1431 /* Return non-nil if frame F wants a bitmap icon. */
1439 tem
= assq_no_quit (Qicon_type
, f
->param_alist
);
1441 return XCONS (tem
)->cdr
;
1446 extern Lisp_Object
x_new_font ();
1449 x_set_font (f
, arg
, oldval
)
1451 Lisp_Object arg
, oldval
;
1455 CHECK_STRING (arg
, 1);
1458 result
= x_new_font (f
, XSTRING (arg
)->data
);
1461 if (EQ (result
, Qnil
))
1462 error ("Font \"%s\" is not defined", XSTRING (arg
)->data
);
1463 else if (EQ (result
, Qt
))
1464 error ("the characters of the given font have varying widths");
1465 else if (STRINGP (result
))
1467 recompute_basic_faces (f
);
1468 store_frame_param (f
, Qfont
, result
);
1475 x_set_border_width (f
, arg
, oldval
)
1477 Lisp_Object arg
, oldval
;
1479 CHECK_NUMBER (arg
, 0);
1481 if (XINT (arg
) == f
->display
.x
->border_width
)
1484 if (FRAME_X_WINDOW (f
) != 0)
1485 error ("Cannot change the border width of a window");
1487 f
->display
.x
->border_width
= XINT (arg
);
1491 x_set_internal_border_width (f
, arg
, oldval
)
1493 Lisp_Object arg
, oldval
;
1496 int old
= f
->display
.x
->internal_border_width
;
1498 CHECK_NUMBER (arg
, 0);
1499 f
->display
.x
->internal_border_width
= XINT (arg
);
1500 if (f
->display
.x
->internal_border_width
< 0)
1501 f
->display
.x
->internal_border_width
= 0;
1503 if (f
->display
.x
->internal_border_width
== old
)
1506 if (FRAME_X_WINDOW (f
) != 0)
1509 x_set_window_size (f
, 0, f
->width
, f
->height
);
1511 x_set_resize_hint (f
);
1513 XFlush (FRAME_X_DISPLAY (f
));
1515 SET_FRAME_GARBAGED (f
);
1520 x_set_visibility (f
, value
, oldval
)
1522 Lisp_Object value
, oldval
;
1525 XSETFRAME (frame
, f
);
1528 Fmake_frame_invisible (frame
, Qt
);
1529 else if (EQ (value
, Qicon
))
1530 Ficonify_frame (frame
);
1532 Fmake_frame_visible (frame
);
1536 x_set_menu_bar_lines_1 (window
, n
)
1540 struct window
*w
= XWINDOW (window
);
1542 XSETFASTINT (w
->top
, XFASTINT (w
->top
) + n
);
1543 XSETFASTINT (w
->height
, XFASTINT (w
->height
) - n
);
1545 /* Handle just the top child in a vertical split. */
1546 if (!NILP (w
->vchild
))
1547 x_set_menu_bar_lines_1 (w
->vchild
, n
);
1549 /* Adjust all children in a horizontal split. */
1550 for (window
= w
->hchild
; !NILP (window
); window
= w
->next
)
1552 w
= XWINDOW (window
);
1553 x_set_menu_bar_lines_1 (window
, n
);
1558 x_set_menu_bar_lines (f
, value
, oldval
)
1560 Lisp_Object value
, oldval
;
1563 int olines
= FRAME_MENU_BAR_LINES (f
);
1565 /* Right now, menu bars don't work properly in minibuf-only frames;
1566 most of the commands try to apply themselves to the minibuffer
1567 frame itslef, and get an error because you can't switch buffers
1568 in or split the minibuffer window. */
1569 if (FRAME_MINIBUF_ONLY_P (f
))
1572 if (INTEGERP (value
))
1573 nlines
= XINT (value
);
1577 #ifdef USE_X_TOOLKIT
1578 FRAME_MENU_BAR_LINES (f
) = 0;
1580 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
1583 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
1584 free_frame_menubar (f
);
1585 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
1586 f
->display
.x
->menubar_widget
= 0;
1588 #else /* not USE_X_TOOLKIT */
1589 FRAME_MENU_BAR_LINES (f
) = nlines
;
1590 x_set_menu_bar_lines_1 (f
->root_window
, nlines
- olines
);
1591 #endif /* not USE_X_TOOLKIT */
1594 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1597 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1598 name; if NAME is a string, set F's name to NAME and set
1599 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1601 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1602 suggesting a new name, which lisp code should override; if
1603 F->explicit_name is set, ignore the new name; otherwise, set it. */
1606 x_set_name (f
, name
, explicit)
1611 /* Make sure that requests from lisp code override requests from
1612 Emacs redisplay code. */
1615 /* If we're switching from explicit to implicit, we had better
1616 update the mode lines and thereby update the title. */
1617 if (f
->explicit_name
&& NILP (name
))
1618 update_mode_lines
= 1;
1620 f
->explicit_name
= ! NILP (name
);
1622 else if (f
->explicit_name
)
1625 /* If NAME is nil, set the name to the x_id_name. */
1628 /* Check for no change needed in this very common case
1629 before we do any consing. */
1630 if (!strcmp (FRAME_X_DISPLAY_INFO (f
)->x_id_name
,
1631 XSTRING (f
->name
)->data
))
1633 name
= build_string (FRAME_X_DISPLAY_INFO (f
)->x_id_name
);
1636 CHECK_STRING (name
, 0);
1638 /* Don't change the name if it's already NAME. */
1639 if (! NILP (Fstring_equal (name
, f
->name
)))
1642 if (FRAME_X_WINDOW (f
))
1648 text
.value
= XSTRING (name
)->data
;
1649 text
.encoding
= XA_STRING
;
1651 text
.nitems
= XSTRING (name
)->size
;
1652 #ifdef USE_X_TOOLKIT
1653 XSetWMName (FRAME_X_DISPLAY (f
),
1654 XtWindow (f
->display
.x
->widget
), &text
);
1655 XSetWMIconName (FRAME_X_DISPLAY (f
), XtWindow (f
->display
.x
->widget
),
1657 #else /* not USE_X_TOOLKIT */
1658 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &text
);
1659 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &text
);
1660 #endif /* not USE_X_TOOLKIT */
1662 #else /* not HAVE_X11R4 */
1663 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1664 XSTRING (name
)->data
);
1665 XStoreName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1666 XSTRING (name
)->data
);
1667 #endif /* not HAVE_X11R4 */
1674 /* This function should be called when the user's lisp code has
1675 specified a name for the frame; the name will override any set by the
1678 x_explicitly_set_name (f
, arg
, oldval
)
1680 Lisp_Object arg
, oldval
;
1682 x_set_name (f
, arg
, 1);
1685 /* This function should be called by Emacs redisplay code to set the
1686 name; names set this way will never override names set by the user's
1689 x_implicitly_set_name (f
, arg
, oldval
)
1691 Lisp_Object arg
, oldval
;
1693 x_set_name (f
, arg
, 0);
1697 x_set_autoraise (f
, arg
, oldval
)
1699 Lisp_Object arg
, oldval
;
1701 f
->auto_raise
= !EQ (Qnil
, arg
);
1705 x_set_autolower (f
, arg
, oldval
)
1707 Lisp_Object arg
, oldval
;
1709 f
->auto_lower
= !EQ (Qnil
, arg
);
1713 x_set_unsplittable (f
, arg
, oldval
)
1715 Lisp_Object arg
, oldval
;
1717 f
->no_split
= !NILP (arg
);
1721 x_set_vertical_scroll_bars (f
, arg
, oldval
)
1723 Lisp_Object arg
, oldval
;
1725 if (NILP (arg
) != ! FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
1727 FRAME_HAS_VERTICAL_SCROLL_BARS (f
) = ! NILP (arg
);
1729 /* We set this parameter before creating the X window for the
1730 frame, so we can get the geometry right from the start.
1731 However, if the window hasn't been created yet, we shouldn't
1732 call x_set_window_size. */
1733 if (FRAME_X_WINDOW (f
))
1734 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
1739 x_set_scroll_bar_width (f
, arg
, oldval
)
1741 Lisp_Object arg
, oldval
;
1745 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = 0;
1746 FRAME_SCROLL_BAR_COLS (f
) = 2;
1748 else if (INTEGERP (arg
) && XINT (arg
) > 0
1749 && XFASTINT (arg
) != FRAME_SCROLL_BAR_PIXEL_WIDTH (f
))
1751 int wid
= FONT_WIDTH (f
->display
.x
->font
);
1752 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = XFASTINT (arg
);
1753 FRAME_SCROLL_BAR_COLS (f
) = (XFASTINT (arg
) + wid
-1) / wid
;
1754 if (FRAME_X_WINDOW (f
))
1755 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
1759 /* Subroutines of creating an X frame. */
1761 /* Make sure that Vx_resource_name is set to a reasonable value. */
1763 validate_x_resource_name ()
1766 /* Number of valid characters in the resource name. */
1768 /* Number of invalid characters in the resource name. */
1773 if (STRINGP (Vx_resource_name
))
1775 unsigned char *p
= XSTRING (Vx_resource_name
)->data
;
1778 len
= XSTRING (Vx_resource_name
)->size
;
1780 /* Only letters, digits, - and _ are valid in resource names.
1781 Count the valid characters and count the invalid ones. */
1782 for (i
= 0; i
< len
; i
++)
1785 if (! ((c
>= 'a' && c
<= 'z')
1786 || (c
>= 'A' && c
<= 'Z')
1787 || (c
>= '0' && c
<= '9')
1788 || c
== '-' || c
== '_'))
1795 /* Not a string => completely invalid. */
1796 bad_count
= 5, good_count
= 0;
1798 /* If name is valid already, return. */
1802 /* If name is entirely invalid, or nearly so, use `emacs'. */
1804 || (good_count
== 1 && bad_count
> 0))
1806 Vx_resource_name
= make_string ("emacs", 5);
1810 /* Name is partly valid. Copy it and replace the invalid characters
1811 with underscores. */
1813 Vx_resource_name
= new = Fcopy_sequence (Vx_resource_name
);
1815 for (i
= 0; i
< len
; i
++)
1817 int c
= XSTRING (new)->data
[i
];
1818 if (! ((c
>= 'a' && c
<= 'z')
1819 || (c
>= 'A' && c
<= 'Z')
1820 || (c
>= '0' && c
<= '9')
1821 || c
== '-' || c
== '_'))
1822 XSTRING (new)->data
[i
] = '_';
1827 extern char *x_get_string_resource ();
1829 DEFUN ("x-get-resource", Fx_get_resource
, Sx_get_resource
, 2, 4, 0,
1830 "Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.\n\
1831 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the\n\
1832 class, where INSTANCE is the name under which Emacs was invoked, or\n\
1833 the name specified by the `-name' or `-rn' command-line arguments.\n\
1835 The optional arguments COMPONENT and SUBCLASS add to the key and the\n\
1836 class, respectively. You must specify both of them or neither.\n\
1837 If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'\n\
1838 and the class is `Emacs.CLASS.SUBCLASS'.")
1839 (attribute
, class, component
, subclass
)
1840 Lisp_Object attribute
, class, component
, subclass
;
1842 register char *value
;
1845 Lisp_Object resname
;
1849 CHECK_STRING (attribute
, 0);
1850 CHECK_STRING (class, 0);
1852 if (!NILP (component
))
1853 CHECK_STRING (component
, 1);
1854 if (!NILP (subclass
))
1855 CHECK_STRING (subclass
, 2);
1856 if (NILP (component
) != NILP (subclass
))
1857 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
1859 validate_x_resource_name ();
1860 resname
= Vx_resource_name
;
1862 if (NILP (component
))
1864 /* Allocate space for the components, the dots which separate them,
1865 and the final '\0'. */
1866 name_key
= (char *) alloca (XSTRING (resname
)->size
1867 + XSTRING (attribute
)->size
1869 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
1870 + XSTRING (class)->size
1873 sprintf (name_key
, "%s.%s",
1874 XSTRING (resname
)->data
,
1875 XSTRING (attribute
)->data
);
1876 sprintf (class_key
, "%s.%s",
1878 XSTRING (class)->data
);
1882 name_key
= (char *) alloca (XSTRING (resname
)->size
1883 + XSTRING (component
)->size
1884 + XSTRING (attribute
)->size
1887 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
1888 + XSTRING (class)->size
1889 + XSTRING (subclass
)->size
1892 sprintf (name_key
, "%s.%s.%s",
1893 XSTRING (resname
)->data
,
1894 XSTRING (component
)->data
,
1895 XSTRING (attribute
)->data
);
1896 sprintf (class_key
, "%s.%s.%s",
1898 XSTRING (class)->data
,
1899 XSTRING (subclass
)->data
);
1902 value
= x_get_string_resource (check_x_display_info (Qnil
)->xrdb
,
1903 name_key
, class_key
);
1905 if (value
!= (char *) 0)
1906 return build_string (value
);
1911 /* Used when C code wants a resource value. */
1914 x_get_resource_string (attribute
, class)
1915 char *attribute
, *class;
1917 register char *value
;
1921 /* Allocate space for the components, the dots which separate them,
1922 and the final '\0'. */
1923 name_key
= (char *) alloca (XSTRING (Vinvocation_name
)->size
1924 + strlen (attribute
) + 2);
1925 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
1926 + strlen (class) + 2);
1928 sprintf (name_key
, "%s.%s",
1929 XSTRING (Vinvocation_name
)->data
,
1931 sprintf (class_key
, "%s.%s", EMACS_CLASS
, class);
1933 return x_get_string_resource (FRAME_X_DISPLAY_INFO (selected_frame
)->xrdb
,
1934 name_key
, class_key
);
1937 /* Types we might convert a resource string into. */
1940 number
, boolean
, string
, symbol
1943 /* Return the value of parameter PARAM.
1945 First search ALIST, then Vdefault_frame_alist, then the X defaults
1946 database, using ATTRIBUTE as the attribute name and CLASS as its class.
1948 Convert the resource to the type specified by desired_type.
1950 If no default is specified, return Qunbound. If you call
1951 x_get_arg, make sure you deal with Qunbound in a reasonable way,
1952 and don't let it get stored in any Lisp-visible variables! */
1955 x_get_arg (alist
, param
, attribute
, class, type
)
1956 Lisp_Object alist
, param
;
1959 enum resource_types type
;
1961 register Lisp_Object tem
;
1963 tem
= Fassq (param
, alist
);
1965 tem
= Fassq (param
, Vdefault_frame_alist
);
1971 tem
= Fx_get_resource (build_string (attribute
),
1972 build_string (class),
1981 return make_number (atoi (XSTRING (tem
)->data
));
1984 tem
= Fdowncase (tem
);
1985 if (!strcmp (XSTRING (tem
)->data
, "on")
1986 || !strcmp (XSTRING (tem
)->data
, "true"))
1995 /* As a special case, we map the values `true' and `on'
1996 to Qt, and `false' and `off' to Qnil. */
1999 lower
= Fdowncase (tem
);
2000 if (!strcmp (XSTRING (lower
)->data
, "on")
2001 || !strcmp (XSTRING (lower
)->data
, "true"))
2003 else if (!strcmp (XSTRING (lower
)->data
, "off")
2004 || !strcmp (XSTRING (lower
)->data
, "false"))
2007 return Fintern (tem
, Qnil
);
2020 /* Record in frame F the specified or default value according to ALIST
2021 of the parameter named PARAM (a Lisp symbol).
2022 If no value is specified for PARAM, look for an X default for XPROP
2023 on the frame named NAME.
2024 If that is not found either, use the value DEFLT. */
2027 x_default_parameter (f
, alist
, prop
, deflt
, xprop
, xclass
, type
)
2034 enum resource_types type
;
2038 tem
= x_get_arg (alist
, prop
, xprop
, xclass
, type
);
2039 if (EQ (tem
, Qunbound
))
2041 x_set_frame_parameters (f
, Fcons (Fcons (prop
, tem
), Qnil
));
2045 DEFUN ("x-parse-geometry", Fx_parse_geometry
, Sx_parse_geometry
, 1, 1, 0,
2046 "Parse an X-style geometry string STRING.\n\
2047 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).\n\
2048 The properties returned may include `top', `left', `height', and `width'.\n\
2049 The value of `left' or `top' may be an integer,\n\
2050 or a list (+ N) meaning N pixels relative to top/left corner,\n\
2051 or a list (- N) meaning -N pixels relative to bottom/right corner.")
2056 unsigned int width
, height
;
2059 CHECK_STRING (string
, 0);
2061 geometry
= XParseGeometry ((char *) XSTRING (string
)->data
,
2062 &x
, &y
, &width
, &height
);
2065 if (!!(geometry
& XValue
) != !!(geometry
& YValue
))
2066 error ("Must specify both x and y position, or neither");
2070 if (geometry
& XValue
)
2072 Lisp_Object element
;
2074 if (x
>= 0 && (geometry
& XNegative
))
2075 element
= Fcons (Qleft
, Fcons (Qminus
, Fcons (make_number (-x
), Qnil
)));
2076 else if (x
< 0 && ! (geometry
& XNegative
))
2077 element
= Fcons (Qleft
, Fcons (Qplus
, Fcons (make_number (x
), Qnil
)));
2079 element
= Fcons (Qleft
, make_number (x
));
2080 result
= Fcons (element
, result
);
2083 if (geometry
& YValue
)
2085 Lisp_Object element
;
2087 if (y
>= 0 && (geometry
& YNegative
))
2088 element
= Fcons (Qtop
, Fcons (Qminus
, Fcons (make_number (-y
), Qnil
)));
2089 else if (y
< 0 && ! (geometry
& YNegative
))
2090 element
= Fcons (Qtop
, Fcons (Qplus
, Fcons (make_number (y
), Qnil
)));
2092 element
= Fcons (Qtop
, make_number (y
));
2093 result
= Fcons (element
, result
);
2096 if (geometry
& WidthValue
)
2097 result
= Fcons (Fcons (Qwidth
, make_number (width
)), result
);
2098 if (geometry
& HeightValue
)
2099 result
= Fcons (Fcons (Qheight
, make_number (height
)), result
);
2104 /* Calculate the desired size and position of this window,
2105 and return the flags saying which aspects were specified.
2107 This function does not make the coordinates positive. */
2109 #define DEFAULT_ROWS 40
2110 #define DEFAULT_COLS 80
2113 x_figure_window_size (f
, parms
)
2117 register Lisp_Object tem0
, tem1
, tem2
;
2118 int height
, width
, left
, top
;
2119 register int geometry
;
2120 long window_prompting
= 0;
2122 /* Default values if we fall through.
2123 Actually, if that happens we should get
2124 window manager prompting. */
2125 f
->width
= DEFAULT_COLS
;
2126 f
->height
= DEFAULT_ROWS
;
2127 /* Window managers expect that if program-specified
2128 positions are not (0,0), they're intentional, not defaults. */
2129 f
->display
.x
->top_pos
= 0;
2130 f
->display
.x
->left_pos
= 0;
2132 tem0
= x_get_arg (parms
, Qheight
, 0, 0, number
);
2133 tem1
= x_get_arg (parms
, Qwidth
, 0, 0, number
);
2134 tem2
= x_get_arg (parms
, Quser_size
, 0, 0, number
);
2135 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
2137 if (!EQ (tem0
, Qunbound
))
2139 CHECK_NUMBER (tem0
, 0);
2140 f
->height
= XINT (tem0
);
2142 if (!EQ (tem1
, Qunbound
))
2144 CHECK_NUMBER (tem1
, 0);
2145 f
->width
= XINT (tem1
);
2147 if (!NILP (tem2
) && !EQ (tem2
, Qunbound
))
2148 window_prompting
|= USSize
;
2150 window_prompting
|= PSize
;
2153 f
->display
.x
->vertical_scroll_bar_extra
2154 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
2156 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0
2157 ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f
)
2158 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->display
.x
->font
)));
2159 f
->display
.x
->pixel_width
= CHAR_TO_PIXEL_WIDTH (f
, f
->width
);
2160 f
->display
.x
->pixel_height
= CHAR_TO_PIXEL_HEIGHT (f
, f
->height
);
2162 tem0
= x_get_arg (parms
, Qtop
, 0, 0, number
);
2163 tem1
= x_get_arg (parms
, Qleft
, 0, 0, number
);
2164 tem2
= x_get_arg (parms
, Quser_position
, 0, 0, number
);
2165 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
2167 if (EQ (tem0
, Qminus
))
2169 f
->display
.x
->top_pos
= 0;
2170 window_prompting
|= YNegative
;
2172 else if (CONSP (tem0
) && EQ (XCONS (tem0
)->car
, Qminus
)
2173 && CONSP (XCONS (tem0
)->cdr
)
2174 && INTEGERP (XCONS (XCONS (tem0
)->cdr
)->car
))
2176 f
->display
.x
->top_pos
= - XINT (XCONS (XCONS (tem0
)->cdr
)->car
);
2177 window_prompting
|= YNegative
;
2179 else if (CONSP (tem0
) && EQ (XCONS (tem0
)->car
, Qplus
)
2180 && CONSP (XCONS (tem0
)->cdr
)
2181 && INTEGERP (XCONS (XCONS (tem0
)->cdr
)->car
))
2183 f
->display
.x
->top_pos
= XINT (XCONS (XCONS (tem0
)->cdr
)->car
);
2185 else if (EQ (tem0
, Qunbound
))
2186 f
->display
.x
->top_pos
= 0;
2189 CHECK_NUMBER (tem0
, 0);
2190 f
->display
.x
->top_pos
= XINT (tem0
);
2191 if (f
->display
.x
->top_pos
< 0)
2192 window_prompting
|= YNegative
;
2195 if (EQ (tem1
, Qminus
))
2197 f
->display
.x
->left_pos
= 0;
2198 window_prompting
|= XNegative
;
2200 else if (CONSP (tem1
) && EQ (XCONS (tem1
)->car
, Qminus
)
2201 && CONSP (XCONS (tem1
)->cdr
)
2202 && INTEGERP (XCONS (XCONS (tem1
)->cdr
)->car
))
2204 f
->display
.x
->left_pos
= - XINT (XCONS (XCONS (tem1
)->cdr
)->car
);
2205 window_prompting
|= XNegative
;
2207 else if (CONSP (tem1
) && EQ (XCONS (tem1
)->car
, Qplus
)
2208 && CONSP (XCONS (tem1
)->cdr
)
2209 && INTEGERP (XCONS (XCONS (tem1
)->cdr
)->car
))
2211 f
->display
.x
->left_pos
= XINT (XCONS (XCONS (tem1
)->cdr
)->car
);
2213 else if (EQ (tem1
, Qunbound
))
2214 f
->display
.x
->left_pos
= 0;
2217 CHECK_NUMBER (tem1
, 0);
2218 f
->display
.x
->left_pos
= XINT (tem1
);
2219 if (f
->display
.x
->left_pos
< 0)
2220 window_prompting
|= XNegative
;
2223 if (!NILP (tem2
) && ! EQ (tem2
, Qunbound
))
2224 window_prompting
|= USPosition
;
2226 window_prompting
|= PPosition
;
2229 return window_prompting
;
2232 #if !defined (HAVE_X11R4) && !defined (HAVE_XSETWMPROTOCOLS)
2235 XSetWMProtocols (dpy
, w
, protocols
, count
)
2242 prop
= XInternAtom (dpy
, "WM_PROTOCOLS", False
);
2243 if (prop
== None
) return False
;
2244 XChangeProperty (dpy
, w
, prop
, XA_ATOM
, 32, PropModeReplace
,
2245 (unsigned char *) protocols
, count
);
2248 #endif /* not HAVE_X11R4 && not HAVE_XSETWMPROTOCOLS */
2250 #ifdef USE_X_TOOLKIT
2252 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
2253 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
2254 already be present because of the toolkit (Motif adds some of them,
2255 for example, but Xt doesn't). */
2258 hack_wm_protocols (f
, widget
)
2262 Display
*dpy
= XtDisplay (widget
);
2263 Window w
= XtWindow (widget
);
2264 int need_delete
= 1;
2270 Atom type
, *atoms
= 0;
2272 unsigned long nitems
= 0;
2273 unsigned long bytes_after
;
2275 if (Success
== XGetWindowProperty (dpy
, w
,
2276 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2277 0, 100, False
, XA_ATOM
,
2278 &type
, &format
, &nitems
, &bytes_after
,
2279 (unsigned char **) &atoms
)
2280 && format
== 32 && type
== XA_ATOM
)
2284 if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
)
2286 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
)
2288 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
)
2291 if (atoms
) XFree ((char *) atoms
);
2297 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2299 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
;
2301 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2303 XChangeProperty (dpy
, w
, FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2304 XA_ATOM
, 32, PropModeAppend
,
2305 (unsigned char *) props
, count
);
2311 #ifdef USE_X_TOOLKIT
2313 /* Create and set up the X widget for frame F. */
2316 x_window (f
, window_prompting
, minibuffer_only
)
2318 long window_prompting
;
2319 int minibuffer_only
;
2321 XClassHint class_hints
;
2322 XSetWindowAttributes attributes
;
2323 unsigned long attribute_mask
;
2325 Widget shell_widget
;
2327 Widget frame_widget
;
2335 = (STRINGP (f
->name
) ? (char *)XSTRING (f
->name
)->data
: "emacs");
2336 f
->namebuf
= (char *) xrealloc (f
->namebuf
, strlen (str
) + 1);
2337 strcpy (f
->namebuf
, str
);
2341 XtSetArg (al
[ac
], XtNallowShellResize
, 1); ac
++;
2342 XtSetArg (al
[ac
], XtNinput
, 1); ac
++;
2343 shell_widget
= XtAppCreateShell (f
->namebuf
, EMACS_CLASS
,
2344 topLevelShellWidgetClass
,
2345 FRAME_X_DISPLAY (f
), al
, ac
);
2347 f
->display
.x
->widget
= shell_widget
;
2348 /* maybe_set_screen_title_format (shell_widget); */
2350 pane_widget
= lw_create_widget ("main", "pane", widget_id_tick
++,
2351 (widget_value
*) NULL
,
2352 shell_widget
, False
,
2355 (lw_callback
) NULL
);
2357 f
->display
.x
->column_widget
= pane_widget
;
2359 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
2360 initialize_frame_menubar (f
);
2362 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2363 the emacs screen when changing menubar. This reduces flickering. */
2366 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2367 XtSetArg (al
[ac
], XtNshowGrip
, 0); ac
++;
2368 XtSetArg (al
[ac
], XtNallowResize
, 1); ac
++;
2369 XtSetArg (al
[ac
], XtNresizeToPreferred
, 1); ac
++;
2370 XtSetArg (al
[ac
], XtNemacsFrame
, f
); ac
++;
2371 frame_widget
= XtCreateWidget (f
->namebuf
,
2373 pane_widget
, al
, ac
);
2374 lw_set_main_areas (pane_widget
, f
->display
.x
->menubar_widget
, frame_widget
);
2376 f
->display
.x
->edit_widget
= frame_widget
;
2378 if (f
->display
.x
->menubar_widget
)
2379 XtManageChild (f
->display
.x
->menubar_widget
);
2380 XtManageChild (frame_widget
);
2382 /* Do some needed geometry management. */
2385 char *tem
, shell_position
[32];
2389 = (f
->display
.x
->menubar_widget
2390 ? (f
->display
.x
->menubar_widget
->core
.height
2391 + f
->display
.x
->menubar_widget
->core
.border_width
)
2394 if (FRAME_EXTERNAL_MENU_BAR (f
))
2397 XtVaGetValues (pane_widget
, XtNinternalBorderWidth
, &ibw
, NULL
);
2398 menubar_size
+= ibw
;
2401 if (window_prompting
& USPosition
)
2403 int left
= f
->display
.x
->left_pos
;
2404 int xneg
= window_prompting
& XNegative
;
2405 int top
= f
->display
.x
->top_pos
;
2406 int yneg
= window_prompting
& YNegative
;
2411 sprintf (shell_position
, "=%dx%d%c%d%c%d", PIXEL_WIDTH (f
),
2412 PIXEL_HEIGHT (f
) + menubar_size
,
2413 (xneg
? '-' : '+'), left
,
2414 (yneg
? '-' : '+'), top
);
2417 sprintf (shell_position
, "=%dx%d", PIXEL_WIDTH (f
),
2418 PIXEL_HEIGHT (f
) + menubar_size
);
2419 len
= strlen (shell_position
) + 1;
2420 tem
= (char *) xmalloc (len
);
2421 strncpy (tem
, shell_position
, len
);
2422 XtSetArg (al
[ac
], XtNgeometry
, tem
); ac
++;
2423 XtSetValues (shell_widget
, al
, ac
);
2426 x_calc_absolute_position (f
);
2428 XtManageChild (pane_widget
);
2429 XtRealizeWidget (shell_widget
);
2431 FRAME_X_WINDOW (f
) = XtWindow (frame_widget
);
2433 validate_x_resource_name ();
2434 class_hints
.res_name
= (char *) XSTRING (Vx_resource_name
)->data
;
2435 class_hints
.res_class
= EMACS_CLASS
;
2436 XSetClassHint (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
), &class_hints
);
2438 f
->display
.x
->wm_hints
.input
= True
;
2439 f
->display
.x
->wm_hints
.flags
|= InputHint
;
2440 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2441 &f
->display
.x
->wm_hints
);
2443 hack_wm_protocols (f
, shell_widget
);
2446 XtAddEventHandler (shell_widget
, 0, True
, _XEditResCheckMessages
, 0);
2449 /* Do a stupid property change to force the server to generate a
2450 propertyNotify event so that the event_stream server timestamp will
2451 be initialized to something relevant to the time we created the window.
2453 XChangeProperty (XtDisplay (frame_widget
), XtWindow (frame_widget
),
2454 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2455 XA_ATOM
, 32, PropModeAppend
,
2456 (unsigned char*) NULL
, 0);
2458 /* Make all the standard events reach the Emacs frame. */
2459 attributes
.event_mask
= STANDARD_EVENT_SET
;
2460 attribute_mask
= CWEventMask
;
2461 XChangeWindowAttributes (XtDisplay (shell_widget
), XtWindow (shell_widget
),
2462 attribute_mask
, &attributes
);
2464 XtMapWidget (frame_widget
);
2466 /* x_set_name normally ignores requests to set the name if the
2467 requested name is the same as the current name. This is the one
2468 place where that assumption isn't correct; f->name is set, but
2469 the X server hasn't been told. */
2472 int explicit = f
->explicit_name
;
2474 f
->explicit_name
= 0;
2477 x_set_name (f
, name
, explicit);
2480 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2481 f
->display
.x
->text_cursor
);
2485 if (FRAME_X_WINDOW (f
) == 0)
2486 error ("Unable to create window");
2489 #else /* not USE_X_TOOLKIT */
2491 /* Create and set up the X window for frame F. */
2497 XClassHint class_hints
;
2498 XSetWindowAttributes attributes
;
2499 unsigned long attribute_mask
;
2501 attributes
.background_pixel
= f
->display
.x
->background_pixel
;
2502 attributes
.border_pixel
= f
->display
.x
->border_pixel
;
2503 attributes
.bit_gravity
= StaticGravity
;
2504 attributes
.backing_store
= NotUseful
;
2505 attributes
.save_under
= True
;
2506 attributes
.event_mask
= STANDARD_EVENT_SET
;
2507 attribute_mask
= (CWBackPixel
| CWBorderPixel
| CWBitGravity
2509 | CWBackingStore
| CWSaveUnder
2515 = XCreateWindow (FRAME_X_DISPLAY (f
),
2516 f
->display
.x
->parent_desc
,
2517 f
->display
.x
->left_pos
,
2518 f
->display
.x
->top_pos
,
2519 PIXEL_WIDTH (f
), PIXEL_HEIGHT (f
),
2520 f
->display
.x
->border_width
,
2521 CopyFromParent
, /* depth */
2522 InputOutput
, /* class */
2523 FRAME_X_DISPLAY_INFO (f
)->visual
,
2524 attribute_mask
, &attributes
);
2526 validate_x_resource_name ();
2527 class_hints
.res_name
= (char *) XSTRING (Vx_resource_name
)->data
;
2528 class_hints
.res_class
= EMACS_CLASS
;
2529 XSetClassHint (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &class_hints
);
2531 /* This indicates that we use the "Passive Input" input model.
2532 Unless we do this, we don't get the Focus{In,Out} events that we
2533 need to draw the cursor correctly. Accursed bureaucrats.
2534 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2536 f
->display
.x
->wm_hints
.input
= True
;
2537 f
->display
.x
->wm_hints
.flags
|= InputHint
;
2538 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2539 &f
->display
.x
->wm_hints
);
2541 /* Request "save yourself" and "delete window" commands from wm. */
2544 protocols
[0] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2545 protocols
[1] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2546 XSetWMProtocols (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), protocols
, 2);
2549 /* x_set_name normally ignores requests to set the name if the
2550 requested name is the same as the current name. This is the one
2551 place where that assumption isn't correct; f->name is set, but
2552 the X server hasn't been told. */
2555 int explicit = f
->explicit_name
;
2557 f
->explicit_name
= 0;
2560 x_set_name (f
, name
, explicit);
2563 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2564 f
->display
.x
->text_cursor
);
2568 if (FRAME_X_WINDOW (f
) == 0)
2569 error ("Unable to create window");
2572 #endif /* not USE_X_TOOLKIT */
2574 /* Handle the icon stuff for this window. Perhaps later we might
2575 want an x_set_icon_position which can be called interactively as
2583 Lisp_Object icon_x
, icon_y
;
2585 /* Set the position of the icon. Note that twm groups all
2586 icons in an icon window. */
2587 icon_x
= x_get_arg (parms
, Qicon_left
, 0, 0, number
);
2588 icon_y
= x_get_arg (parms
, Qicon_top
, 0, 0, number
);
2589 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2591 CHECK_NUMBER (icon_x
, 0);
2592 CHECK_NUMBER (icon_y
, 0);
2594 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2595 error ("Both left and top icon corners of icon must be specified");
2599 if (! EQ (icon_x
, Qunbound
))
2600 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
2602 /* Start up iconic or window? */
2603 x_wm_set_window_state
2604 (f
, (EQ (x_get_arg (parms
, Qvisibility
, 0, 0, symbol
), Qicon
)
2611 /* Make the GC's needed for this window, setting the
2612 background, border and mouse colors; also create the
2613 mouse cursor and the gray border tile. */
2615 static char cursor_bits
[] =
2617 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2618 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2619 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2620 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2627 XGCValues gc_values
;
2633 /* Create the GC's of this frame.
2634 Note that many default values are used. */
2637 gc_values
.font
= f
->display
.x
->font
->fid
;
2638 gc_values
.foreground
= f
->display
.x
->foreground_pixel
;
2639 gc_values
.background
= f
->display
.x
->background_pixel
;
2640 gc_values
.line_width
= 0; /* Means 1 using fast algorithm. */
2641 f
->display
.x
->normal_gc
= XCreateGC (FRAME_X_DISPLAY (f
),
2643 GCLineWidth
| GCFont
2644 | GCForeground
| GCBackground
,
2647 /* Reverse video style. */
2648 gc_values
.foreground
= f
->display
.x
->background_pixel
;
2649 gc_values
.background
= f
->display
.x
->foreground_pixel
;
2650 f
->display
.x
->reverse_gc
= XCreateGC (FRAME_X_DISPLAY (f
),
2652 GCFont
| GCForeground
| GCBackground
2656 /* Cursor has cursor-color background, background-color foreground. */
2657 gc_values
.foreground
= f
->display
.x
->background_pixel
;
2658 gc_values
.background
= f
->display
.x
->cursor_pixel
;
2659 gc_values
.fill_style
= FillOpaqueStippled
;
2661 = XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
2662 FRAME_X_DISPLAY_INFO (f
)->root_window
,
2663 cursor_bits
, 16, 16);
2664 f
->display
.x
->cursor_gc
2665 = XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2666 (GCFont
| GCForeground
| GCBackground
2667 | GCFillStyle
| GCStipple
| GCLineWidth
),
2670 /* Create the gray border tile used when the pointer is not in
2671 the frame. Since this depends on the frame's pixel values,
2672 this must be done on a per-frame basis. */
2673 f
->display
.x
->border_tile
2674 = (XCreatePixmapFromBitmapData
2675 (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
2676 gray_bits
, gray_width
, gray_height
,
2677 f
->display
.x
->foreground_pixel
,
2678 f
->display
.x
->background_pixel
,
2679 DefaultDepth (FRAME_X_DISPLAY (f
),
2680 XScreenNumberOfScreen (FRAME_X_SCREEN (f
)))));
2685 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
2687 "Make a new X window, which is called a \"frame\" in Emacs terms.\n\
2688 Returns an Emacs frame object.\n\
2689 ALIST is an alist of frame parameters.\n\
2690 If the parameters specify that the frame should not have a minibuffer,\n\
2691 and do not specify a specific minibuffer window to use,\n\
2692 then `default-minibuffer-frame' must be a frame whose minibuffer can\n\
2693 be shared by the new frame.\n\
2695 This function is an internal primitive--use `make-frame' instead.")
2700 Lisp_Object frame
, tem
;
2702 int minibuffer_only
= 0;
2703 long window_prompting
= 0;
2705 int count
= specpdl_ptr
- specpdl
;
2706 struct gcpro gcpro1
;
2707 Lisp_Object display
;
2708 struct x_display_info
*dpyinfo
;
2713 display
= x_get_arg (parms
, Qdisplay
, 0, 0, 0);
2714 if (EQ (display
, Qunbound
))
2716 dpyinfo
= check_x_display_info (display
);
2718 name
= x_get_arg (parms
, Qname
, "title", "Title", string
);
2720 && ! EQ (name
, Qunbound
)
2722 error ("Invalid frame name--not a string or nil");
2724 /* See if parent window is specified. */
2725 parent
= x_get_arg (parms
, Qparent_id
, NULL
, NULL
, number
);
2726 if (EQ (parent
, Qunbound
))
2728 if (! NILP (parent
))
2729 CHECK_NUMBER (parent
, 0);
2731 tem
= x_get_arg (parms
, Qminibuffer
, 0, 0, symbol
);
2732 if (EQ (tem
, Qnone
) || NILP (tem
))
2733 f
= make_frame_without_minibuffer (Qnil
);
2734 else if (EQ (tem
, Qonly
))
2736 f
= make_minibuffer_frame ();
2737 minibuffer_only
= 1;
2739 else if (WINDOWP (tem
))
2740 f
= make_frame_without_minibuffer (tem
);
2744 /* Note that X Windows does support scroll bars. */
2745 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
2747 XSETFRAME (frame
, f
);
2750 f
->output_method
= output_x_window
;
2751 f
->display
.x
= (struct x_display
*) xmalloc (sizeof (struct x_display
));
2752 bzero (f
->display
.x
, sizeof (struct x_display
));
2753 f
->display
.x
->icon_bitmap
= -1;
2755 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
2757 FRAME_KBOARD (f
) = dpyinfo
->kboard
;
2760 /* Specify the parent under which to make this X window. */
2764 f
->display
.x
->parent_desc
= parent
;
2765 f
->display
.x
->explicit_parent
= 1;
2769 f
->display
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
2770 f
->display
.x
->explicit_parent
= 0;
2773 /* Note that the frame has no physical cursor right now. */
2774 f
->phys_cursor_x
= -1;
2776 /* Set the name; the functions to which we pass f expect the name to
2778 if (EQ (name
, Qunbound
) || NILP (name
))
2780 f
->name
= build_string (dpyinfo
->x_id_name
);
2781 f
->explicit_name
= 0;
2786 f
->explicit_name
= 1;
2787 /* use the frame's title when getting resources for this frame. */
2788 specbind (Qx_resource_name
, name
);
2791 /* Extract the window parameters from the supplied values
2792 that are needed to determine window geometry. */
2796 font
= x_get_arg (parms
, Qfont
, "font", "Font", string
);
2798 /* First, try whatever font the caller has specified. */
2800 font
= x_new_font (f
, XSTRING (font
)->data
);
2801 /* Try out a font which we hope has bold and italic variations. */
2802 if (!STRINGP (font
))
2803 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
2804 if (! STRINGP (font
))
2805 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
2806 if (! STRINGP (font
))
2807 /* This was formerly the first thing tried, but it finds too many fonts
2808 and takes too long. */
2809 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
2810 /* If those didn't work, look for something which will at least work. */
2811 if (! STRINGP (font
))
2812 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
2814 if (! STRINGP (font
))
2815 font
= build_string ("fixed");
2817 x_default_parameter (f
, parms
, Qfont
, font
,
2818 "font", "Font", string
);
2821 #ifdef USE_X_TOOLKIT
2822 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
2823 whereby it fails to get any font. */
2824 xlwmenu_default_font
= f
->display
.x
->font
;
2827 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
2828 "borderwidth", "BorderWidth", number
);
2829 /* This defaults to 2 in order to match xterm. We recognize either
2830 internalBorderWidth or internalBorder (which is what xterm calls
2832 if (NILP (Fassq (Qinternal_border_width
, parms
)))
2836 value
= x_get_arg (parms
, Qinternal_border_width
,
2837 "internalBorder", "BorderWidth", number
);
2838 if (! EQ (value
, Qunbound
))
2839 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
2842 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (2),
2843 "internalBorderWidth", "BorderWidth", number
);
2844 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qt
,
2845 "verticalScrollBars", "ScrollBars", boolean
);
2847 /* Also do the stuff which must be set before the window exists. */
2848 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
2849 "foreground", "Foreground", string
);
2850 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
2851 "background", "Background", string
);
2852 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
2853 "pointerColor", "Foreground", string
);
2854 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
2855 "cursorColor", "Foreground", string
);
2856 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
2857 "borderColor", "BorderColor", string
);
2859 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
2860 "menuBar", "MenuBar", number
);
2861 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
2862 "scrollBarWidth", "ScrollBarWidth", number
);
2864 f
->display
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
2865 window_prompting
= x_figure_window_size (f
, parms
);
2867 if (window_prompting
& XNegative
)
2869 if (window_prompting
& YNegative
)
2870 f
->display
.x
->win_gravity
= SouthEastGravity
;
2872 f
->display
.x
->win_gravity
= NorthEastGravity
;
2876 if (window_prompting
& YNegative
)
2877 f
->display
.x
->win_gravity
= SouthWestGravity
;
2879 f
->display
.x
->win_gravity
= NorthWestGravity
;
2882 f
->display
.x
->size_hint_flags
= window_prompting
;
2884 #ifdef USE_X_TOOLKIT
2885 x_window (f
, window_prompting
, minibuffer_only
);
2891 init_frame_faces (f
);
2893 /* We need to do this after creating the X window, so that the
2894 icon-creation functions can say whose icon they're describing. */
2895 x_default_parameter (f
, parms
, Qicon_type
, Qnil
,
2896 "bitmapIcon", "BitmapIcon", symbol
);
2898 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
2899 "autoRaise", "AutoRaiseLower", boolean
);
2900 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
2901 "autoLower", "AutoRaiseLower", boolean
);
2902 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
2903 "cursorType", "CursorType", symbol
);
2905 /* Dimensions, especially f->height, must be done via change_frame_size.
2906 Change will not be effected unless different from the current
2910 f
->height
= f
->width
= 0;
2911 change_frame_size (f
, height
, width
, 1, 0);
2913 /* With the toolkit, the geometry management is done in x_window. */
2914 #ifndef USE_X_TOOLKIT
2916 x_wm_set_size_hint (f
, window_prompting
, 0);
2918 #endif /* USE_X_TOOLKIT */
2920 tem
= x_get_arg (parms
, Qunsplittable
, 0, 0, boolean
);
2921 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
2925 /* It is now ok to make the frame official
2926 even if we get an error below.
2927 And the frame needs to be on Vframe_list
2928 or making it visible won't work. */
2929 Vframe_list
= Fcons (frame
, Vframe_list
);
2931 /* Now that the frame is official, it counts as a reference to
2933 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
2935 /* Make the window appear on the frame and enable display,
2936 unless the caller says not to. However, with explicit parent,
2937 Emacs cannot control visibility, so don't try. */
2938 if (! f
->display
.x
->explicit_parent
)
2940 Lisp_Object visibility
;
2942 visibility
= x_get_arg (parms
, Qvisibility
, 0, 0, symbol
);
2943 if (EQ (visibility
, Qunbound
))
2946 if (EQ (visibility
, Qicon
))
2947 x_iconify_frame (f
);
2948 else if (! NILP (visibility
))
2949 x_make_frame_visible (f
);
2951 /* Must have been Qnil. */
2955 return unbind_to (count
, frame
);
2958 /* FRAME is used only to get a handle on the X display. We don't pass the
2959 display info directly because we're called from frame.c, which doesn't
2960 know about that structure. */
2962 x_get_focus_frame (frame
)
2963 struct frame
*frame
;
2965 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (frame
);
2967 if (! dpyinfo
->x_focus_frame
)
2970 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
2974 DEFUN ("focus-frame", Ffocus_frame
, Sfocus_frame
, 1, 1, 0,
2975 "Set the focus on FRAME.")
2979 CHECK_LIVE_FRAME (frame
, 0);
2981 if (FRAME_X_P (XFRAME (frame
)))
2984 x_focus_on_frame (XFRAME (frame
));
2992 DEFUN ("unfocus-frame", Funfocus_frame
, Sunfocus_frame
, 0, 0, 0,
2993 "If a frame has been focused, release it.")
2996 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (selected_frame
);
2997 if (dpyinfo
->x_focus_frame
)
3000 x_unfocus_frame (dpyinfo
->x_focus_frame
);
3007 DEFUN ("x-list-fonts", Fx_list_fonts
, Sx_list_fonts
, 1, 3, 0,
3008 "Return a list of the names of available fonts matching PATTERN.\n\
3009 If optional arguments FACE and FRAME are specified, return only fonts\n\
3010 the same size as FACE on FRAME.\n\
3012 PATTERN is a string, perhaps with wildcard characters;\n\
3013 the * character matches any substring, and\n\
3014 the ? character matches any single character.\n\
3015 PATTERN is case-insensitive.\n\
3016 FACE is a face name--a symbol.\n\
3018 The return value is a list of strings, suitable as arguments to\n\
3021 Fonts Emacs can't use (i.e. proportional fonts) may or may not be excluded\n\
3022 even if they match PATTERN and FACE.")
3023 (pattern
, face
, frame
)
3024 Lisp_Object pattern
, face
, frame
;
3028 #ifndef BROKEN_XLISTFONTSWITHINFO
3031 XFontStruct
*size_ref
;
3036 CHECK_STRING (pattern
, 0);
3038 CHECK_SYMBOL (face
, 1);
3040 f
= check_x_frame (frame
);
3042 /* Determine the width standard for comparison with the fonts we find. */
3050 /* Don't die if we get called with a terminal frame. */
3051 if (! FRAME_X_P (f
))
3052 error ("non-X frame used in `x-list-fonts'");
3054 face_id
= face_name_id_number (f
, face
);
3056 if (face_id
< 0 || face_id
>= FRAME_N_PARAM_FACES (f
)
3057 || FRAME_PARAM_FACES (f
) [face_id
] == 0)
3058 size_ref
= f
->display
.x
->font
;
3061 size_ref
= FRAME_PARAM_FACES (f
) [face_id
]->font
;
3062 if (size_ref
== (XFontStruct
*) (~0))
3063 size_ref
= f
->display
.x
->font
;
3067 /* See if we cached the result for this particular query. */
3068 list
= Fassoc (pattern
,
3069 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
);
3071 /* We have info in the cache for this PATTERN. */
3074 Lisp_Object tem
, newlist
;
3076 /* We have info about this pattern. */
3077 list
= XCONS (list
)->cdr
;
3084 /* Filter the cached info and return just the fonts that match FACE. */
3086 for (tem
= list
; CONSP (tem
); tem
= XCONS (tem
)->cdr
)
3088 XFontStruct
*thisinfo
;
3090 thisinfo
= XLoadQueryFont (FRAME_X_DISPLAY (f
),
3091 XSTRING (XCONS (tem
)->car
)->data
);
3093 if (thisinfo
&& same_size_fonts (thisinfo
, size_ref
))
3094 newlist
= Fcons (XCONS (tem
)->car
, newlist
);
3096 XFreeFont (FRAME_X_DISPLAY (f
), thisinfo
);
3106 /* Solaris 2.3 has a bug in XListFontsWithInfo. */
3107 #ifndef BROKEN_XLISTFONTSWITHINFO
3109 names
= XListFontsWithInfo (FRAME_X_DISPLAY (f
),
3110 XSTRING (pattern
)->data
,
3111 2000, /* maxnames */
3112 &num_fonts
, /* count_return */
3113 &info
); /* info_return */
3116 names
= XListFonts (FRAME_X_DISPLAY (f
),
3117 XSTRING (pattern
)->data
,
3118 2000, /* maxnames */
3119 &num_fonts
); /* count_return */
3128 Lisp_Object full_list
;
3130 /* Make a list of all the fonts we got back.
3131 Store that in the font cache for the display. */
3133 for (i
= 0; i
< num_fonts
; i
++)
3134 full_list
= Fcons (build_string (names
[i
]), full_list
);
3135 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
3136 = Fcons (Fcons (pattern
, full_list
),
3137 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
);
3139 /* Make a list of the fonts that have the right width. */
3141 for (i
= 0; i
< num_fonts
; i
++)
3149 #ifdef BROKEN_XLISTFONTSWITHINFO
3150 XFontStruct
*thisinfo
;
3153 thisinfo
= XLoadQueryFont (FRAME_X_DISPLAY (f
), names
[i
]);
3156 keeper
= thisinfo
&& same_size_fonts (thisinfo
, size_ref
);
3158 keeper
= same_size_fonts (&info
[i
], size_ref
);
3162 list
= Fcons (build_string (names
[i
]), list
);
3164 list
= Fnreverse (list
);
3167 #ifndef BROKEN_XLISTFONTSWITHINFO
3169 XFreeFontInfo (names
, info
, num_fonts
);
3172 XFreeFontNames (names
);
3180 DEFUN ("x-color-defined-p", Fx_color_defined_p
, Sx_color_defined_p
, 1, 2, 0,
3181 "Return non-nil if color COLOR is supported on frame FRAME.\n\
3182 If FRAME is omitted or nil, use the selected frame.")
3184 Lisp_Object color
, frame
;
3187 FRAME_PTR f
= check_x_frame (frame
);
3189 CHECK_STRING (color
, 1);
3191 if (defined_color (f
, XSTRING (color
)->data
, &foo
, 0))
3197 DEFUN ("x-color-values", Fx_color_values
, Sx_color_values
, 1, 2, 0,
3198 "Return a description of the color named COLOR on frame FRAME.\n\
3199 The value is a list of integer RGB values--(RED GREEN BLUE).\n\
3200 These values appear to range from 0 to 65280 or 65535, depending\n\
3201 on the system; white is (65280 65280 65280) or (65535 65535 65535).\n\
3202 If FRAME is omitted or nil, use the selected frame.")
3204 Lisp_Object color
, frame
;
3207 FRAME_PTR f
= check_x_frame (frame
);
3209 CHECK_STRING (color
, 1);
3211 if (defined_color (f
, XSTRING (color
)->data
, &foo
, 0))
3215 rgb
[0] = make_number (foo
.red
);
3216 rgb
[1] = make_number (foo
.green
);
3217 rgb
[2] = make_number (foo
.blue
);
3218 return Flist (3, rgb
);
3224 DEFUN ("x-display-color-p", Fx_display_color_p
, Sx_display_color_p
, 0, 1, 0,
3225 "Return t if the X display supports color.\n\
3226 The optional argument DISPLAY specifies which display to ask about.\n\
3227 DISPLAY should be either a frame or a display name (a string).\n\
3228 If omitted or nil, that stands for the selected frame's display.")
3230 Lisp_Object display
;
3232 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3234 if (dpyinfo
->n_planes
<= 2)
3237 switch (dpyinfo
->visual
->class)
3250 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
3252 "Return t if the X display supports shades of gray.\n\
3253 The optional argument DISPLAY specifies which display to ask about.\n\
3254 DISPLAY should be either a frame or a display name (a string).\n\
3255 If omitted or nil, that stands for the selected frame's display.")
3257 Lisp_Object display
;
3259 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3261 if (dpyinfo
->n_planes
<= 2)
3264 return (dpyinfo
->n_planes
> 1
3265 && (dpyinfo
->visual
->class == StaticGray
3266 || dpyinfo
->visual
->class == GrayScale
));
3269 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
3271 "Returns the width in pixels of the X display DISPLAY.\n\
3272 The optional argument DISPLAY specifies which display to ask about.\n\
3273 DISPLAY should be either a frame or a display name (a string).\n\
3274 If omitted or nil, that stands for the selected frame's display.")
3276 Lisp_Object display
;
3278 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3280 return make_number (dpyinfo
->width
);
3283 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
3284 Sx_display_pixel_height
, 0, 1, 0,
3285 "Returns the height in pixels of the X display DISPLAY.\n\
3286 The optional argument DISPLAY specifies which display to ask about.\n\
3287 DISPLAY should be either a frame or a display name (a string).\n\
3288 If omitted or nil, that stands for the selected frame's display.")
3290 Lisp_Object display
;
3292 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3294 return make_number (dpyinfo
->height
);
3297 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
3299 "Returns the number of bitplanes of the X display DISPLAY.\n\
3300 The optional argument DISPLAY specifies which display to ask about.\n\
3301 DISPLAY should be either a frame or a display name (a string).\n\
3302 If omitted or nil, that stands for the selected frame's display.")
3304 Lisp_Object display
;
3306 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3308 return make_number (dpyinfo
->n_planes
);
3311 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
3313 "Returns the number of color cells of the X display DISPLAY.\n\
3314 The optional argument DISPLAY specifies which display to ask about.\n\
3315 DISPLAY should be either a frame or a display name (a string).\n\
3316 If omitted or nil, that stands for the selected frame's display.")
3318 Lisp_Object display
;
3320 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3322 return make_number (DisplayCells (dpyinfo
->display
,
3323 XScreenNumberOfScreen (dpyinfo
->screen
)));
3326 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
3327 Sx_server_max_request_size
,
3329 "Returns the maximum request size of the X server of display DISPLAY.\n\
3330 The optional argument DISPLAY specifies which display to ask about.\n\
3331 DISPLAY should be either a frame or a display name (a string).\n\
3332 If omitted or nil, that stands for the selected frame's display.")
3334 Lisp_Object display
;
3336 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3338 return make_number (MAXREQUEST (dpyinfo
->display
));
3341 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
3342 "Returns the vendor ID string of the X server of display DISPLAY.\n\
3343 The optional argument DISPLAY specifies which display to ask about.\n\
3344 DISPLAY should be either a frame or a display name (a string).\n\
3345 If omitted or nil, that stands for the selected frame's display.")
3347 Lisp_Object display
;
3349 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3350 char *vendor
= ServerVendor (dpyinfo
->display
);
3352 if (! vendor
) vendor
= "";
3353 return build_string (vendor
);
3356 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
3357 "Returns the version numbers of the X server of display DISPLAY.\n\
3358 The value is a list of three integers: the major and minor\n\
3359 version numbers of the X Protocol in use, and the vendor-specific release\n\
3360 number. See also the function `x-server-vendor'.\n\n\
3361 The optional argument DISPLAY specifies which display to ask about.\n\
3362 DISPLAY should be either a frame or a display name (a string).\n\
3363 If omitted or nil, that stands for the selected frame's display.")
3365 Lisp_Object display
;
3367 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3368 Display
*dpy
= dpyinfo
->display
;
3370 return Fcons (make_number (ProtocolVersion (dpy
)),
3371 Fcons (make_number (ProtocolRevision (dpy
)),
3372 Fcons (make_number (VendorRelease (dpy
)), Qnil
)));
3375 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
3376 "Returns the number of screens on the X server of display DISPLAY.\n\
3377 The optional argument DISPLAY specifies which display to ask about.\n\
3378 DISPLAY should be either a frame or a display name (a string).\n\
3379 If omitted or nil, that stands for the selected frame's display.")
3381 Lisp_Object display
;
3383 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3385 return make_number (ScreenCount (dpyinfo
->display
));
3388 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
3389 "Returns the height in millimeters of the X display DISPLAY.\n\
3390 The optional argument DISPLAY specifies which display to ask about.\n\
3391 DISPLAY should be either a frame or a display name (a string).\n\
3392 If omitted or nil, that stands for the selected frame's display.")
3394 Lisp_Object display
;
3396 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3398 return make_number (HeightMMOfScreen (dpyinfo
->screen
));
3401 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
3402 "Returns the width in millimeters of the X display DISPLAY.\n\
3403 The optional argument DISPLAY specifies which display to ask about.\n\
3404 DISPLAY should be either a frame or a display name (a string).\n\
3405 If omitted or nil, that stands for the selected frame's display.")
3407 Lisp_Object display
;
3409 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3411 return make_number (WidthMMOfScreen (dpyinfo
->screen
));
3414 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
3415 Sx_display_backing_store
, 0, 1, 0,
3416 "Returns an indication of whether X display DISPLAY does backing store.\n\
3417 The value may be `always', `when-mapped', or `not-useful'.\n\
3418 The optional argument DISPLAY specifies which display to ask about.\n\
3419 DISPLAY should be either a frame or a display name (a string).\n\
3420 If omitted or nil, that stands for the selected frame's display.")
3422 Lisp_Object display
;
3424 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3426 switch (DoesBackingStore (dpyinfo
->screen
))
3429 return intern ("always");
3432 return intern ("when-mapped");
3435 return intern ("not-useful");
3438 error ("Strange value for BackingStore parameter of screen");
3442 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
3443 Sx_display_visual_class
, 0, 1, 0,
3444 "Returns the visual class of the X display DISPLAY.\n\
3445 The value is one of the symbols `static-gray', `gray-scale',\n\
3446 `static-color', `pseudo-color', `true-color', or `direct-color'.\n\n\
3447 The optional argument DISPLAY specifies which display to ask about.\n\
3448 DISPLAY should be either a frame or a display name (a string).\n\
3449 If omitted or nil, that stands for the selected frame's display.")
3451 Lisp_Object display
;
3453 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3455 switch (dpyinfo
->visual
->class)
3457 case StaticGray
: return (intern ("static-gray"));
3458 case GrayScale
: return (intern ("gray-scale"));
3459 case StaticColor
: return (intern ("static-color"));
3460 case PseudoColor
: return (intern ("pseudo-color"));
3461 case TrueColor
: return (intern ("true-color"));
3462 case DirectColor
: return (intern ("direct-color"));
3464 error ("Display has an unknown visual class");
3468 DEFUN ("x-display-save-under", Fx_display_save_under
,
3469 Sx_display_save_under
, 0, 1, 0,
3470 "Returns t if the X display DISPLAY supports the save-under feature.\n\
3471 The optional argument DISPLAY specifies which display to ask about.\n\
3472 DISPLAY should be either a frame or a display name (a string).\n\
3473 If omitted or nil, that stands for the selected frame's display.")
3475 Lisp_Object display
;
3477 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3479 if (DoesSaveUnders (dpyinfo
->screen
) == True
)
3487 register struct frame
*f
;
3489 return PIXEL_WIDTH (f
);
3494 register struct frame
*f
;
3496 return PIXEL_HEIGHT (f
);
3501 register struct frame
*f
;
3503 return FONT_WIDTH (f
->display
.x
->font
);
3508 register struct frame
*f
;
3510 return f
->display
.x
->line_height
;
3514 x_screen_planes (frame
)
3517 return FRAME_X_DISPLAY_INFO (XFRAME (frame
))->n_planes
;
3520 #if 0 /* These no longer seem like the right way to do things. */
3522 /* Draw a rectangle on the frame with left top corner including
3523 the character specified by LEFT_CHAR and TOP_CHAR. The rectangle is
3524 CHARS by LINES wide and long and is the color of the cursor. */
3527 x_rectangle (f
, gc
, left_char
, top_char
, chars
, lines
)
3528 register struct frame
*f
;
3530 register int top_char
, left_char
, chars
, lines
;
3534 int left
= (left_char
* FONT_WIDTH (f
->display
.x
->font
)
3535 + f
->display
.x
->internal_border_width
);
3536 int top
= (top_char
* f
->display
.x
->line_height
3537 + f
->display
.x
->internal_border_width
);
3540 width
= FONT_WIDTH (f
->display
.x
->font
) / 2;
3542 width
= FONT_WIDTH (f
->display
.x
->font
) * chars
;
3544 height
= f
->display
.x
->line_height
/ 2;
3546 height
= f
->display
.x
->line_height
* lines
;
3548 XDrawRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3549 gc
, left
, top
, width
, height
);
3552 DEFUN ("x-draw-rectangle", Fx_draw_rectangle
, Sx_draw_rectangle
, 5, 5, 0,
3553 "Draw a rectangle on FRAME between coordinates specified by\n\
3554 numbers X0, Y0, X1, Y1 in the cursor pixel.")
3555 (frame
, X0
, Y0
, X1
, Y1
)
3556 register Lisp_Object frame
, X0
, X1
, Y0
, Y1
;
3558 register int x0
, y0
, x1
, y1
, top
, left
, n_chars
, n_lines
;
3560 CHECK_LIVE_FRAME (frame
, 0);
3561 CHECK_NUMBER (X0
, 0);
3562 CHECK_NUMBER (Y0
, 1);
3563 CHECK_NUMBER (X1
, 2);
3564 CHECK_NUMBER (Y1
, 3);
3574 n_lines
= y1
- y0
+ 1;
3579 n_lines
= y0
- y1
+ 1;
3585 n_chars
= x1
- x0
+ 1;
3590 n_chars
= x0
- x1
+ 1;
3594 x_rectangle (XFRAME (frame
), XFRAME (frame
)->display
.x
->cursor_gc
,
3595 left
, top
, n_chars
, n_lines
);
3601 DEFUN ("x-erase-rectangle", Fx_erase_rectangle
, Sx_erase_rectangle
, 5, 5, 0,
3602 "Draw a rectangle drawn on FRAME between coordinates\n\
3603 X0, Y0, X1, Y1 in the regular background-pixel.")
3604 (frame
, X0
, Y0
, X1
, Y1
)
3605 register Lisp_Object frame
, X0
, Y0
, X1
, Y1
;
3607 register int x0
, y0
, x1
, y1
, top
, left
, n_chars
, n_lines
;
3609 CHECK_LIVE_FRAME (frame
, 0);
3610 CHECK_NUMBER (X0
, 0);
3611 CHECK_NUMBER (Y0
, 1);
3612 CHECK_NUMBER (X1
, 2);
3613 CHECK_NUMBER (Y1
, 3);
3623 n_lines
= y1
- y0
+ 1;
3628 n_lines
= y0
- y1
+ 1;
3634 n_chars
= x1
- x0
+ 1;
3639 n_chars
= x0
- x1
+ 1;
3643 x_rectangle (XFRAME (frame
), XFRAME (frame
)->display
.x
->reverse_gc
,
3644 left
, top
, n_chars
, n_lines
);
3650 /* Draw lines around the text region beginning at the character position
3651 TOP_X, TOP_Y and ending at BOTTOM_X and BOTTOM_Y. GC specifies the
3652 pixel and line characteristics. */
3654 #define line_len(line) (FRAME_CURRENT_GLYPHS (f)->used[(line)])
3657 outline_region (f
, gc
, top_x
, top_y
, bottom_x
, bottom_y
)
3658 register struct frame
*f
;
3660 int top_x
, top_y
, bottom_x
, bottom_y
;
3662 register int ibw
= f
->display
.x
->internal_border_width
;
3663 register int font_w
= FONT_WIDTH (f
->display
.x
->font
);
3664 register int font_h
= f
->display
.x
->line_height
;
3666 int x
= line_len (y
);
3667 XPoint
*pixel_points
3668 = (XPoint
*) alloca (((bottom_y
- top_y
+ 2) * 4) * sizeof (XPoint
));
3669 register XPoint
*this_point
= pixel_points
;
3671 /* Do the horizontal top line/lines */
3674 this_point
->x
= ibw
;
3675 this_point
->y
= ibw
+ (font_h
* top_y
);
3678 this_point
->x
= ibw
+ (font_w
/ 2); /* Half-size for newline chars. */
3680 this_point
->x
= ibw
+ (font_w
* x
);
3681 this_point
->y
= (this_point
- 1)->y
;
3685 this_point
->x
= ibw
;
3686 this_point
->y
= ibw
+ (font_h
* (top_y
+ 1));
3688 this_point
->x
= ibw
+ (font_w
* top_x
);
3689 this_point
->y
= (this_point
- 1)->y
;
3691 this_point
->x
= (this_point
- 1)->x
;
3692 this_point
->y
= ibw
+ (font_h
* top_y
);
3694 this_point
->x
= ibw
+ (font_w
* x
);
3695 this_point
->y
= (this_point
- 1)->y
;
3698 /* Now do the right side. */
3699 while (y
< bottom_y
)
3700 { /* Right vertical edge */
3702 this_point
->x
= (this_point
- 1)->x
;
3703 this_point
->y
= ibw
+ (font_h
* (y
+ 1));
3706 y
++; /* Horizontal connection to next line */
3709 this_point
->x
= ibw
+ (font_w
/ 2);
3711 this_point
->x
= ibw
+ (font_w
* x
);
3713 this_point
->y
= (this_point
- 1)->y
;
3716 /* Now do the bottom and connect to the top left point. */
3717 this_point
->x
= ibw
+ (font_w
* (bottom_x
+ 1));
3720 this_point
->x
= (this_point
- 1)->x
;
3721 this_point
->y
= ibw
+ (font_h
* (bottom_y
+ 1));
3723 this_point
->x
= ibw
;
3724 this_point
->y
= (this_point
- 1)->y
;
3726 this_point
->x
= pixel_points
->x
;
3727 this_point
->y
= pixel_points
->y
;
3729 XDrawLines (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3731 (this_point
- pixel_points
+ 1), CoordModeOrigin
);
3734 DEFUN ("x-contour-region", Fx_contour_region
, Sx_contour_region
, 1, 1, 0,
3735 "Highlight the region between point and the character under the mouse\n\
3738 register Lisp_Object event
;
3740 register int x0
, y0
, x1
, y1
;
3741 register struct frame
*f
= selected_frame
;
3742 register int p1
, p2
;
3744 CHECK_CONS (event
, 0);
3747 x0
= XINT (Fcar (Fcar (event
)));
3748 y0
= XINT (Fcar (Fcdr (Fcar (event
))));
3750 /* If the mouse is past the end of the line, don't that area. */
3751 /* ReWrite this... */
3756 if (y1
> y0
) /* point below mouse */
3757 outline_region (f
, f
->display
.x
->cursor_gc
,
3759 else if (y1
< y0
) /* point above mouse */
3760 outline_region (f
, f
->display
.x
->cursor_gc
,
3762 else /* same line: draw horizontal rectangle */
3765 x_rectangle (f
, f
->display
.x
->cursor_gc
,
3766 x0
, y0
, (x1
- x0
+ 1), 1);
3768 x_rectangle (f
, f
->display
.x
->cursor_gc
,
3769 x1
, y1
, (x0
- x1
+ 1), 1);
3772 XFlush (FRAME_X_DISPLAY (f
));
3778 DEFUN ("x-uncontour-region", Fx_uncontour_region
, Sx_uncontour_region
, 1, 1, 0,
3779 "Erase any highlighting of the region between point and the character\n\
3780 at X, Y on the selected frame.")
3782 register Lisp_Object event
;
3784 register int x0
, y0
, x1
, y1
;
3785 register struct frame
*f
= selected_frame
;
3788 x0
= XINT (Fcar (Fcar (event
)));
3789 y0
= XINT (Fcar (Fcdr (Fcar (event
))));
3793 if (y1
> y0
) /* point below mouse */
3794 outline_region (f
, f
->display
.x
->reverse_gc
,
3796 else if (y1
< y0
) /* point above mouse */
3797 outline_region (f
, f
->display
.x
->reverse_gc
,
3799 else /* same line: draw horizontal rectangle */
3802 x_rectangle (f
, f
->display
.x
->reverse_gc
,
3803 x0
, y0
, (x1
- x0
+ 1), 1);
3805 x_rectangle (f
, f
->display
.x
->reverse_gc
,
3806 x1
, y1
, (x0
- x1
+ 1), 1);
3814 int contour_begin_x
, contour_begin_y
;
3815 int contour_end_x
, contour_end_y
;
3816 int contour_npoints
;
3818 /* Clip the top part of the contour lines down (and including) line Y_POS.
3819 If X_POS is in the middle (rather than at the end) of the line, drop
3820 down a line at that character. */
3823 clip_contour_top (y_pos
, x_pos
)
3825 register XPoint
*begin
= contour_lines
[y_pos
].top_left
;
3826 register XPoint
*end
;
3827 register int npoints
;
3828 register struct display_line
*line
= selected_frame
->phys_lines
[y_pos
+ 1];
3830 if (x_pos
>= line
->len
- 1) /* Draw one, straight horizontal line. */
3832 end
= contour_lines
[y_pos
].top_right
;
3833 npoints
= (end
- begin
+ 1);
3834 XDrawLines (x_current_display
, contour_window
,
3835 contour_erase_gc
, begin_erase
, npoints
, CoordModeOrigin
);
3837 bcopy (end
, begin
+ 1, contour_last_point
- end
+ 1);
3838 contour_last_point
-= (npoints
- 2);
3839 XDrawLines (x_current_display
, contour_window
,
3840 contour_erase_gc
, begin
, 2, CoordModeOrigin
);
3841 XFlush (x_current_display
);
3843 /* Now, update contour_lines structure. */
3848 register XPoint
*p
= begin
+ 1;
3849 end
= contour_lines
[y_pos
].bottom_right
;
3850 npoints
= (end
- begin
+ 1);
3851 XDrawLines (x_current_display
, contour_window
,
3852 contour_erase_gc
, begin_erase
, npoints
, CoordModeOrigin
);
3855 p
->x
= ibw
+ (font_w
* (x_pos
+ 1));
3857 p
->y
= begin
->y
+ font_h
;
3859 bcopy (end
, begin
+ 3, contour_last_point
- end
+ 1);
3860 contour_last_point
-= (npoints
- 5);
3861 XDrawLines (x_current_display
, contour_window
,
3862 contour_erase_gc
, begin
, 4, CoordModeOrigin
);
3863 XFlush (x_current_display
);
3865 /* Now, update contour_lines structure. */
3869 /* Erase the top horizontal lines of the contour, and then extend
3870 the contour upwards. */
3873 extend_contour_top (line
)
3878 clip_contour_bottom (x_pos
, y_pos
)
3884 extend_contour_bottom (x_pos
, y_pos
)
3888 DEFUN ("x-select-region", Fx_select_region
, Sx_select_region
, 1, 1, "e",
3893 register struct frame
*f
= selected_frame
;
3894 register int point_x
= f
->cursor_x
;
3895 register int point_y
= f
->cursor_y
;
3896 register int mouse_below_point
;
3897 register Lisp_Object obj
;
3898 register int x_contour_x
, x_contour_y
;
3900 x_contour_x
= x_mouse_x
;
3901 x_contour_y
= x_mouse_y
;
3902 if (x_contour_y
> point_y
|| (x_contour_y
== point_y
3903 && x_contour_x
> point_x
))
3905 mouse_below_point
= 1;
3906 outline_region (f
, f
->display
.x
->cursor_gc
, point_x
, point_y
,
3907 x_contour_x
, x_contour_y
);
3911 mouse_below_point
= 0;
3912 outline_region (f
, f
->display
.x
->cursor_gc
, x_contour_x
, x_contour_y
,
3918 obj
= read_char (-1, 0, 0, Qnil
, 0);
3922 if (mouse_below_point
)
3924 if (x_mouse_y
<= point_y
) /* Flipped. */
3926 mouse_below_point
= 0;
3928 outline_region (f
, f
->display
.x
->reverse_gc
, point_x
, point_y
,
3929 x_contour_x
, x_contour_y
);
3930 outline_region (f
, f
->display
.x
->cursor_gc
, x_mouse_x
, x_mouse_y
,
3933 else if (x_mouse_y
< x_contour_y
) /* Bottom clipped. */
3935 clip_contour_bottom (x_mouse_y
);
3937 else if (x_mouse_y
> x_contour_y
) /* Bottom extended. */
3939 extend_bottom_contour (x_mouse_y
);
3942 x_contour_x
= x_mouse_x
;
3943 x_contour_y
= x_mouse_y
;
3945 else /* mouse above or same line as point */
3947 if (x_mouse_y
>= point_y
) /* Flipped. */
3949 mouse_below_point
= 1;
3951 outline_region (f
, f
->display
.x
->reverse_gc
,
3952 x_contour_x
, x_contour_y
, point_x
, point_y
);
3953 outline_region (f
, f
->display
.x
->cursor_gc
, point_x
, point_y
,
3954 x_mouse_x
, x_mouse_y
);
3956 else if (x_mouse_y
> x_contour_y
) /* Top clipped. */
3958 clip_contour_top (x_mouse_y
);
3960 else if (x_mouse_y
< x_contour_y
) /* Top extended. */
3962 extend_contour_top (x_mouse_y
);
3967 unread_command_event
= obj
;
3968 if (mouse_below_point
)
3970 contour_begin_x
= point_x
;
3971 contour_begin_y
= point_y
;
3972 contour_end_x
= x_contour_x
;
3973 contour_end_y
= x_contour_y
;
3977 contour_begin_x
= x_contour_x
;
3978 contour_begin_y
= x_contour_y
;
3979 contour_end_x
= point_x
;
3980 contour_end_y
= point_y
;
3985 DEFUN ("x-horizontal-line", Fx_horizontal_line
, Sx_horizontal_line
, 1, 1, "e",
3990 register Lisp_Object obj
;
3991 struct frame
*f
= selected_frame
;
3992 register struct window
*w
= XWINDOW (selected_window
);
3993 register GC line_gc
= f
->display
.x
->cursor_gc
;
3994 register GC erase_gc
= f
->display
.x
->reverse_gc
;
3996 char dash_list
[] = {6, 4, 6, 4};
3998 XGCValues gc_values
;
4000 register int previous_y
;
4001 register int line
= (x_mouse_y
+ 1) * f
->display
.x
->line_height
4002 + f
->display
.x
->internal_border_width
;
4003 register int left
= f
->display
.x
->internal_border_width
4005 * FONT_WIDTH (f
->display
.x
->font
));
4006 register int right
= left
+ (w
->width
4007 * FONT_WIDTH (f
->display
.x
->font
))
4008 - f
->display
.x
->internal_border_width
;
4012 gc_values
.foreground
= f
->display
.x
->cursor_pixel
;
4013 gc_values
.background
= f
->display
.x
->background_pixel
;
4014 gc_values
.line_width
= 1;
4015 gc_values
.line_style
= LineOnOffDash
;
4016 gc_values
.cap_style
= CapRound
;
4017 gc_values
.join_style
= JoinRound
;
4019 line_gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4020 GCLineStyle
| GCJoinStyle
| GCCapStyle
4021 | GCLineWidth
| GCForeground
| GCBackground
,
4023 XSetDashes (FRAME_X_DISPLAY (f
), line_gc
, 0, dash_list
, dashes
);
4024 gc_values
.foreground
= f
->display
.x
->background_pixel
;
4025 gc_values
.background
= f
->display
.x
->foreground_pixel
;
4026 erase_gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4027 GCLineStyle
| GCJoinStyle
| GCCapStyle
4028 | GCLineWidth
| GCForeground
| GCBackground
,
4030 XSetDashes (FRAME_X_DISPLAY (f
), erase_gc
, 0, dash_list
, dashes
);
4036 if (x_mouse_y
>= XINT (w
->top
)
4037 && x_mouse_y
< XINT (w
->top
) + XINT (w
->height
) - 1)
4039 previous_y
= x_mouse_y
;
4040 line
= (x_mouse_y
+ 1) * f
->display
.x
->line_height
4041 + f
->display
.x
->internal_border_width
;
4042 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4043 line_gc
, left
, line
, right
, line
);
4045 XFlush (FRAME_X_DISPLAY (f
));
4050 obj
= read_char (-1, 0, 0, Qnil
, 0);
4052 || (! EQ (Fcar (Fcdr (Fcdr (obj
))),
4053 Qvertical_scroll_bar
))
4057 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4058 erase_gc
, left
, line
, right
, line
);
4060 unread_command_event
= obj
;
4062 XFreeGC (FRAME_X_DISPLAY (f
), line_gc
);
4063 XFreeGC (FRAME_X_DISPLAY (f
), erase_gc
);
4068 while (x_mouse_y
== previous_y
);
4071 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4072 erase_gc
, left
, line
, right
, line
);
4079 /* These keep track of the rectangle following the pointer. */
4080 int mouse_track_top
, mouse_track_left
, mouse_track_width
;
4082 /* Offset in buffer of character under the pointer, or 0. */
4083 int mouse_buffer_offset
;
4085 DEFUN ("x-track-pointer", Fx_track_pointer
, Sx_track_pointer
, 0, 0, 0,
4086 "Track the pointer.")
4089 static Cursor current_pointer_shape
;
4090 FRAME_PTR f
= x_mouse_frame
;
4093 if (EQ (Vmouse_frame_part
, Qtext_part
)
4094 && (current_pointer_shape
!= f
->display
.x
->nontext_cursor
))
4099 current_pointer_shape
= f
->display
.x
->nontext_cursor
;
4100 XDefineCursor (FRAME_X_DISPLAY (f
),
4102 current_pointer_shape
);
4104 buf
= XBUFFER (XWINDOW (Vmouse_window
)->buffer
);
4105 c
= *(BUF_CHAR_ADDRESS (buf
, mouse_buffer_offset
));
4107 else if (EQ (Vmouse_frame_part
, Qmodeline_part
)
4108 && (current_pointer_shape
!= f
->display
.x
->modeline_cursor
))
4110 current_pointer_shape
= f
->display
.x
->modeline_cursor
;
4111 XDefineCursor (FRAME_X_DISPLAY (f
),
4113 current_pointer_shape
);
4116 XFlush (FRAME_X_DISPLAY (f
));
4122 DEFUN ("x-track-pointer", Fx_track_pointer
, Sx_track_pointer
, 1, 1, "e",
4123 "Draw rectangle around character under mouse pointer, if there is one.")
4127 struct window
*w
= XWINDOW (Vmouse_window
);
4128 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4129 struct buffer
*b
= XBUFFER (w
->buffer
);
4132 if (! EQ (Vmouse_window
, selected_window
))
4135 if (EQ (event
, Qnil
))
4139 x_read_mouse_position (selected_frame
, &x
, &y
);
4143 mouse_track_width
= 0;
4144 mouse_track_left
= mouse_track_top
= -1;
4148 if ((x_mouse_x
!= mouse_track_left
4149 && (x_mouse_x
< mouse_track_left
4150 || x_mouse_x
> (mouse_track_left
+ mouse_track_width
)))
4151 || x_mouse_y
!= mouse_track_top
)
4153 int hp
= 0; /* Horizontal position */
4154 int len
= FRAME_CURRENT_GLYPHS (f
)->used
[x_mouse_y
];
4155 int p
= FRAME_CURRENT_GLYPHS (f
)->bufp
[x_mouse_y
];
4156 int tab_width
= XINT (b
->tab_width
);
4157 int ctl_arrow_p
= !NILP (b
->ctl_arrow
);
4159 int mode_line_vpos
= XFASTINT (w
->height
) + XFASTINT (w
->top
) - 1;
4160 int in_mode_line
= 0;
4162 if (! FRAME_CURRENT_GLYPHS (f
)->enable
[x_mouse_y
])
4165 /* Erase previous rectangle. */
4166 if (mouse_track_width
)
4168 x_rectangle (f
, f
->display
.x
->reverse_gc
,
4169 mouse_track_left
, mouse_track_top
,
4170 mouse_track_width
, 1);
4172 if ((mouse_track_left
== f
->phys_cursor_x
4173 || mouse_track_left
== f
->phys_cursor_x
- 1)
4174 && mouse_track_top
== f
->phys_cursor_y
)
4176 x_display_cursor (f
, 1);
4180 mouse_track_left
= x_mouse_x
;
4181 mouse_track_top
= x_mouse_y
;
4182 mouse_track_width
= 0;
4184 if (mouse_track_left
> len
) /* Past the end of line. */
4187 if (mouse_track_top
== mode_line_vpos
)
4193 if (tab_width
<= 0 || tab_width
> 20) tab_width
= 8;
4197 if (len
== f
->width
&& hp
== len
- 1 && c
!= '\n')
4203 mouse_track_width
= tab_width
- (hp
% tab_width
);
4205 hp
+= mouse_track_width
;
4208 mouse_track_left
= hp
- mouse_track_width
;
4214 mouse_track_width
= -1;
4218 if (ctl_arrow_p
&& (c
< 040 || c
== 0177))
4223 mouse_track_width
= 2;
4228 mouse_track_left
= hp
- mouse_track_width
;
4234 mouse_track_width
= 1;
4241 while (hp
<= x_mouse_x
);
4244 if (mouse_track_width
) /* Over text; use text pointer shape. */
4246 XDefineCursor (FRAME_X_DISPLAY (f
),
4248 f
->display
.x
->text_cursor
);
4249 x_rectangle (f
, f
->display
.x
->cursor_gc
,
4250 mouse_track_left
, mouse_track_top
,
4251 mouse_track_width
, 1);
4253 else if (in_mode_line
)
4254 XDefineCursor (FRAME_X_DISPLAY (f
),
4256 f
->display
.x
->modeline_cursor
);
4258 XDefineCursor (FRAME_X_DISPLAY (f
),
4260 f
->display
.x
->nontext_cursor
);
4263 XFlush (FRAME_X_DISPLAY (f
));
4266 obj
= read_char (-1, 0, 0, Qnil
, 0);
4269 while (CONSP (obj
) /* Mouse event */
4270 && EQ (Fcar (Fcdr (Fcdr (obj
))), Qnil
) /* Not scroll bar */
4271 && EQ (Vmouse_depressed
, Qnil
) /* Only motion events */
4272 && EQ (Vmouse_window
, selected_window
) /* In this window */
4275 unread_command_event
= obj
;
4277 if (mouse_track_width
)
4279 x_rectangle (f
, f
->display
.x
->reverse_gc
,
4280 mouse_track_left
, mouse_track_top
,
4281 mouse_track_width
, 1);
4282 mouse_track_width
= 0;
4283 if ((mouse_track_left
== f
->phys_cursor_x
4284 || mouse_track_left
- 1 == f
->phys_cursor_x
)
4285 && mouse_track_top
== f
->phys_cursor_y
)
4287 x_display_cursor (f
, 1);
4290 XDefineCursor (FRAME_X_DISPLAY (f
),
4292 f
->display
.x
->nontext_cursor
);
4293 XFlush (FRAME_X_DISPLAY (f
));
4303 /* Draw a pixmap specified by IMAGE_DATA of dimensions WIDTH and HEIGHT
4304 on the frame F at position X, Y. */
4306 x_draw_pixmap (f
, x
, y
, image_data
, width
, height
)
4308 int x
, y
, width
, height
;
4313 image
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
4314 FRAME_X_WINDOW (f
), image_data
,
4316 XCopyPlane (FRAME_X_DISPLAY (f
), image
, FRAME_X_WINDOW (f
),
4317 f
->display
.x
->normal_gc
, 0, 0, width
, height
, x
, y
);
4321 #if 0 /* I'm told these functions are superfluous
4322 given the ability to bind function keys. */
4325 DEFUN ("x-rebind-key", Fx_rebind_key
, Sx_rebind_key
, 3, 3, 0,
4326 "Rebind X keysym KEYSYM, with MODIFIERS, to generate NEWSTRING.\n\
4327 KEYSYM is a string which conforms to the X keysym definitions found\n\
4328 in X11/keysymdef.h, sans the initial XK_. MODIFIERS is nil or a\n\
4329 list of strings specifying modifier keys such as Control_L, which must\n\
4330 also be depressed for NEWSTRING to appear.")
4331 (x_keysym
, modifiers
, newstring
)
4332 register Lisp_Object x_keysym
;
4333 register Lisp_Object modifiers
;
4334 register Lisp_Object newstring
;
4337 register KeySym keysym
;
4338 KeySym modifier_list
[16];
4341 CHECK_STRING (x_keysym
, 1);
4342 CHECK_STRING (newstring
, 3);
4344 keysym
= XStringToKeysym ((char *) XSTRING (x_keysym
)->data
);
4345 if (keysym
== NoSymbol
)
4346 error ("Keysym does not exist");
4348 if (NILP (modifiers
))
4349 XRebindKeysym (x_current_display
, keysym
, modifier_list
, 0,
4350 XSTRING (newstring
)->data
, XSTRING (newstring
)->size
);
4353 register Lisp_Object rest
, mod
;
4356 for (rest
= modifiers
; !NILP (rest
); rest
= Fcdr (rest
))
4359 error ("Can't have more than 16 modifiers");
4362 CHECK_STRING (mod
, 3);
4363 modifier_list
[i
] = XStringToKeysym ((char *) XSTRING (mod
)->data
);
4365 if (modifier_list
[i
] == NoSymbol
4366 || !(IsModifierKey (modifier_list
[i
])
4367 || ((unsigned)(modifier_list
[i
]) == XK_Mode_switch
)
4368 || ((unsigned)(modifier_list
[i
]) == XK_Num_Lock
)))
4370 if (modifier_list
[i
] == NoSymbol
4371 || !IsModifierKey (modifier_list
[i
]))
4373 error ("Element is not a modifier keysym");
4377 XRebindKeysym (x_current_display
, keysym
, modifier_list
, i
,
4378 XSTRING (newstring
)->data
, XSTRING (newstring
)->size
);
4384 DEFUN ("x-rebind-keys", Fx_rebind_keys
, Sx_rebind_keys
, 2, 2, 0,
4385 "Rebind KEYCODE to list of strings STRINGS.\n\
4386 STRINGS should be a list of 16 elements, one for each shift combination.\n\
4387 nil as element means don't change.\n\
4388 See the documentation of `x-rebind-key' for more information.")
4390 register Lisp_Object keycode
;
4391 register Lisp_Object strings
;
4393 register Lisp_Object item
;
4394 register unsigned char *rawstring
;
4395 KeySym rawkey
, modifier
[1];
4397 register unsigned i
;
4400 CHECK_NUMBER (keycode
, 1);
4401 CHECK_CONS (strings
, 2);
4402 rawkey
= (KeySym
) ((unsigned) (XINT (keycode
))) & 255;
4403 for (i
= 0; i
<= 15; strings
= Fcdr (strings
), i
++)
4405 item
= Fcar (strings
);
4408 CHECK_STRING (item
, 2);
4409 strsize
= XSTRING (item
)->size
;
4410 rawstring
= (unsigned char *) xmalloc (strsize
);
4411 bcopy (XSTRING (item
)->data
, rawstring
, strsize
);
4412 modifier
[1] = 1 << i
;
4413 XRebindKeysym (x_current_display
, rawkey
, modifier
, 1,
4414 rawstring
, strsize
);
4419 #endif /* HAVE_X11 */
4422 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4424 XScreenNumberOfScreen (scr
)
4425 register Screen
*scr
;
4427 register Display
*dpy
;
4428 register Screen
*dpyscr
;
4432 dpyscr
= dpy
->screens
;
4434 for (i
= 0; i
< dpy
->nscreens
; i
++, dpyscr
++)
4440 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4443 select_visual (dpy
, screen
, depth
)
4446 unsigned int *depth
;
4449 XVisualInfo
*vinfo
, vinfo_template
;
4452 v
= DefaultVisualOfScreen (screen
);
4455 vinfo_template
.visualid
= XVisualIDFromVisual (v
);
4457 vinfo_template
.visualid
= v
->visualid
;
4460 vinfo_template
.screen
= XScreenNumberOfScreen (screen
);
4462 vinfo
= XGetVisualInfo (dpy
,
4463 VisualIDMask
| VisualScreenMask
, &vinfo_template
,
4466 fatal ("Can't get proper X visual info");
4468 if ((1 << vinfo
->depth
) == vinfo
->colormap_size
)
4469 *depth
= vinfo
->depth
;
4473 int n
= vinfo
->colormap_size
- 1;
4482 XFree ((char *) vinfo
);
4486 /* Return the X display structure for the display named NAME.
4487 Open a new connection if necessary. */
4489 struct x_display_info
*
4490 x_display_info_for_name (name
)
4494 struct x_display_info
*dpyinfo
;
4496 CHECK_STRING (name
, 0);
4498 for (dpyinfo
= x_display_list
, names
= x_display_name_list
;
4500 dpyinfo
= dpyinfo
->next
, names
= XCONS (names
)->cdr
)
4503 tem
= Fstring_equal (XCONS (XCONS (names
)->car
)->car
, name
);
4508 validate_x_resource_name ();
4510 dpyinfo
= x_term_init (name
, (unsigned char *)0,
4511 XSTRING (Vx_resource_name
)->data
);
4514 error ("X server %s not responding", XSTRING (name
)->data
);
4517 XSETFASTINT (Vwindow_system_version
, 11);
4522 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
4523 1, 3, 0, "Open a connection to an X server.\n\
4524 DISPLAY is the name of the display to connect to.\n\
4525 Optional second arg XRM-STRING is a string of resources in xrdb format.\n\
4526 If the optional third arg MUST-SUCCEED is non-nil,\n\
4527 terminate Emacs if we can't open the connection.")
4528 (display
, xrm_string
, must_succeed
)
4529 Lisp_Object display
, xrm_string
, must_succeed
;
4531 unsigned int n_planes
;
4532 unsigned char *xrm_option
;
4533 struct x_display_info
*dpyinfo
;
4535 CHECK_STRING (display
, 0);
4536 if (! NILP (xrm_string
))
4537 CHECK_STRING (xrm_string
, 1);
4539 if (! NILP (xrm_string
))
4540 xrm_option
= (unsigned char *) XSTRING (xrm_string
)->data
;
4542 xrm_option
= (unsigned char *) 0;
4544 validate_x_resource_name ();
4546 /* This is what opens the connection and sets x_current_display.
4547 This also initializes many symbols, such as those used for input. */
4548 dpyinfo
= x_term_init (display
, xrm_option
,
4549 XSTRING (Vx_resource_name
)->data
);
4553 if (!NILP (must_succeed
))
4554 fatal ("X server %s not responding.\n\
4555 Check the DISPLAY environment variable or use \"-d\"\n",
4556 XSTRING (display
)->data
);
4558 error ("X server %s not responding", XSTRING (display
)->data
);
4563 XSETFASTINT (Vwindow_system_version
, 11);
4567 DEFUN ("x-close-connection", Fx_close_connection
,
4568 Sx_close_connection
, 1, 1, 0,
4569 "Close the connection to DISPLAY's X server.\n\
4570 For DISPLAY, specify either a frame or a display name (a string).\n\
4571 If DISPLAY is nil, that stands for the selected frame's display.")
4573 Lisp_Object display
;
4575 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4576 struct x_display_info
*tail
;
4579 if (dpyinfo
->reference_count
> 0)
4580 error ("Display still has frames on it");
4583 /* Free the fonts in the font table. */
4584 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
4586 if (dpyinfo
->font_table
[i
].name
)
4587 free (dpyinfo
->font_table
[i
].name
);
4588 /* Don't free the full_name string;
4589 it is always shared with something else. */
4590 XFreeFont (dpyinfo
->display
, dpyinfo
->font_table
[i
].font
);
4592 x_destroy_all_bitmaps (dpyinfo
);
4593 XSetCloseDownMode (dpyinfo
->display
, DestroyAll
);
4595 #ifdef USE_X_TOOLKIT
4596 XtCloseDisplay (dpyinfo
->display
);
4598 XCloseDisplay (dpyinfo
->display
);
4601 x_delete_display (dpyinfo
);
4607 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
4608 "Return the list of display names that Emacs has connections to.")
4611 Lisp_Object tail
, result
;
4614 for (tail
= x_display_name_list
; ! NILP (tail
); tail
= XCONS (tail
)->cdr
)
4615 result
= Fcons (XCONS (XCONS (tail
)->car
)->car
, result
);
4620 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
4621 "If ON is non-nil, report X errors as soon as the erring request is made.\n\
4622 If ON is nil, allow buffering of requests.\n\
4623 Turning on synchronization prohibits the Xlib routines from buffering\n\
4624 requests and seriously degrades performance, but makes debugging much\n\
4626 The optional second argument DISPLAY specifies which display to act on.\n\
4627 DISPLAY should be either a frame or a display name (a string).\n\
4628 If DISPLAY is omitted or nil, that stands for the selected frame's display.")
4630 Lisp_Object display
, on
;
4632 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4634 XSynchronize (dpyinfo
->display
, !EQ (on
, Qnil
));
4639 /* Wait for responses to all X commands issued so far for frame F. */
4646 XSync (FRAME_X_DISPLAY (f
), False
);
4652 /* This is zero if not using X windows. */
4655 /* The section below is built by the lisp expression at the top of the file,
4656 just above where these variables are declared. */
4657 /*&&& init symbols here &&&*/
4658 Qauto_raise
= intern ("auto-raise");
4659 staticpro (&Qauto_raise
);
4660 Qauto_lower
= intern ("auto-lower");
4661 staticpro (&Qauto_lower
);
4662 Qbackground_color
= intern ("background-color");
4663 staticpro (&Qbackground_color
);
4664 Qbar
= intern ("bar");
4666 Qborder_color
= intern ("border-color");
4667 staticpro (&Qborder_color
);
4668 Qborder_width
= intern ("border-width");
4669 staticpro (&Qborder_width
);
4670 Qbox
= intern ("box");
4672 Qcursor_color
= intern ("cursor-color");
4673 staticpro (&Qcursor_color
);
4674 Qcursor_type
= intern ("cursor-type");
4675 staticpro (&Qcursor_type
);
4676 Qfont
= intern ("font");
4678 Qforeground_color
= intern ("foreground-color");
4679 staticpro (&Qforeground_color
);
4680 Qgeometry
= intern ("geometry");
4681 staticpro (&Qgeometry
);
4682 Qicon_left
= intern ("icon-left");
4683 staticpro (&Qicon_left
);
4684 Qicon_top
= intern ("icon-top");
4685 staticpro (&Qicon_top
);
4686 Qicon_type
= intern ("icon-type");
4687 staticpro (&Qicon_type
);
4688 Qinternal_border_width
= intern ("internal-border-width");
4689 staticpro (&Qinternal_border_width
);
4690 Qleft
= intern ("left");
4692 Qmouse_color
= intern ("mouse-color");
4693 staticpro (&Qmouse_color
);
4694 Qnone
= intern ("none");
4696 Qparent_id
= intern ("parent-id");
4697 staticpro (&Qparent_id
);
4698 Qscroll_bar_width
= intern ("scroll-bar-width");
4699 staticpro (&Qscroll_bar_width
);
4700 Qsuppress_icon
= intern ("suppress-icon");
4701 staticpro (&Qsuppress_icon
);
4702 Qtop
= intern ("top");
4704 Qundefined_color
= intern ("undefined-color");
4705 staticpro (&Qundefined_color
);
4706 Qvertical_scroll_bars
= intern ("vertical-scroll-bars");
4707 staticpro (&Qvertical_scroll_bars
);
4708 Qvisibility
= intern ("visibility");
4709 staticpro (&Qvisibility
);
4710 Qwindow_id
= intern ("window-id");
4711 staticpro (&Qwindow_id
);
4712 Qx_frame_parameter
= intern ("x-frame-parameter");
4713 staticpro (&Qx_frame_parameter
);
4714 Qx_resource_name
= intern ("x-resource-name");
4715 staticpro (&Qx_resource_name
);
4716 Quser_position
= intern ("user-position");
4717 staticpro (&Quser_position
);
4718 Quser_size
= intern ("user-size");
4719 staticpro (&Quser_size
);
4720 Qdisplay
= intern ("display");
4721 staticpro (&Qdisplay
);
4722 /* This is the end of symbol initialization. */
4724 Fput (Qundefined_color
, Qerror_conditions
,
4725 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
4726 Fput (Qundefined_color
, Qerror_message
,
4727 build_string ("Undefined color"));
4729 init_x_parm_symbols ();
4731 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path
,
4732 "List of directories to search for bitmap files for X.");
4733 Vx_bitmap_file_path
= Fcons (build_string (PATH_BITMAPS
), Qnil
);
4735 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
4736 "The shape of the pointer when over text.\n\
4737 Changing the value does not affect existing frames\n\
4738 unless you set the mouse color.");
4739 Vx_pointer_shape
= Qnil
;
4741 DEFVAR_LISP ("x-resource-name", &Vx_resource_name
,
4742 "The name Emacs uses to look up X resources; for internal use only.\n\
4743 `x-get-resource' uses this as the first component of the instance name\n\
4744 when requesting resource values.\n\
4745 Emacs initially sets `x-resource-name' to the name under which Emacs\n\
4746 was invoked, or to the value specified with the `-name' or `-rn'\n\
4747 switches, if present.");
4748 Vx_resource_name
= Qnil
;
4750 #if 0 /* This doesn't really do anything. */
4751 DEFVAR_INT ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape
,
4752 "The shape of the pointer when not over text.\n\
4753 This variable takes effect when you create a new frame\n\
4754 or when you set the mouse color.");
4756 Vx_nontext_pointer_shape
= Qnil
;
4758 #if 0 /* This doesn't really do anything. */
4759 DEFVAR_INT ("x-mode-pointer-shape", &Vx_mode_pointer_shape
,
4760 "The shape of the pointer when over the mode line.\n\
4761 This variable takes effect when you create a new frame\n\
4762 or when you set the mouse color.");
4764 Vx_mode_pointer_shape
= Qnil
;
4766 DEFVAR_INT ("x-sensitive-text-pointer-shape",
4767 &Vx_sensitive_text_pointer_shape
,
4768 "The shape of the pointer when over mouse-sensitive text.\n\
4769 This variable takes effect when you create a new frame\n\
4770 or when you set the mouse color.");
4771 Vx_sensitive_text_pointer_shape
= Qnil
;
4773 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
4774 "A string indicating the foreground color of the cursor box.");
4775 Vx_cursor_fore_pixel
= Qnil
;
4777 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
4778 "Non-nil if no X window manager is in use.");
4780 #ifdef USE_X_TOOLKIT
4781 Fprovide (intern ("x-toolkit"));
4784 defsubr (&Sx_get_resource
);
4786 defsubr (&Sx_draw_rectangle
);
4787 defsubr (&Sx_erase_rectangle
);
4788 defsubr (&Sx_contour_region
);
4789 defsubr (&Sx_uncontour_region
);
4791 defsubr (&Sx_list_fonts
);
4792 defsubr (&Sx_display_color_p
);
4793 defsubr (&Sx_display_grayscale_p
);
4794 defsubr (&Sx_color_defined_p
);
4795 defsubr (&Sx_color_values
);
4796 defsubr (&Sx_server_max_request_size
);
4797 defsubr (&Sx_server_vendor
);
4798 defsubr (&Sx_server_version
);
4799 defsubr (&Sx_display_pixel_width
);
4800 defsubr (&Sx_display_pixel_height
);
4801 defsubr (&Sx_display_mm_width
);
4802 defsubr (&Sx_display_mm_height
);
4803 defsubr (&Sx_display_screens
);
4804 defsubr (&Sx_display_planes
);
4805 defsubr (&Sx_display_color_cells
);
4806 defsubr (&Sx_display_visual_class
);
4807 defsubr (&Sx_display_backing_store
);
4808 defsubr (&Sx_display_save_under
);
4810 defsubr (&Sx_rebind_key
);
4811 defsubr (&Sx_rebind_keys
);
4812 defsubr (&Sx_track_pointer
);
4813 defsubr (&Sx_grab_pointer
);
4814 defsubr (&Sx_ungrab_pointer
);
4816 defsubr (&Sx_parse_geometry
);
4817 defsubr (&Sx_create_frame
);
4818 defsubr (&Sfocus_frame
);
4819 defsubr (&Sunfocus_frame
);
4821 defsubr (&Sx_horizontal_line
);
4823 defsubr (&Sx_open_connection
);
4824 defsubr (&Sx_close_connection
);
4825 defsubr (&Sx_display_list
);
4826 defsubr (&Sx_synchronize
);
4829 #endif /* HAVE_X_WINDOWS */