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 /* Likewise, but exclude the menu bar widget. */
332 x_non_menubar_window_to_frame (dpyinfo
, wdesc
)
333 struct x_display_info
*dpyinfo
;
336 Lisp_Object tail
, frame
;
340 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
342 frame
= XCONS (tail
)->car
;
343 if (!GC_FRAMEP (frame
))
346 if (f
->display
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
349 /* This frame matches if the window is any of its widgets. */
350 if (wdesc
== XtWindow (x
->widget
)
351 || wdesc
== XtWindow (x
->column_widget
)
352 || wdesc
== XtWindow (x
->edit_widget
))
358 /* Return the frame whose principal (outermost) window is WDESC.
359 If WDESC is some other (smaller) window, we return 0. */
362 x_top_window_to_frame (dpyinfo
, wdesc
)
363 struct x_display_info
*dpyinfo
;
366 Lisp_Object tail
, frame
;
370 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
372 frame
= XCONS (tail
)->car
;
373 if (!GC_FRAMEP (frame
))
376 if (f
->display
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
379 /* This frame matches if the window is its topmost widget. */
380 if (wdesc
== XtWindow (x
->widget
))
382 #if 0 /* I don't know why it did this,
383 but it seems logically wrong,
384 and it causes trouble for MapNotify events. */
385 /* Match if the window is this frame's menubar. */
386 if (x
->menubar_widget
387 && wdesc
== XtWindow (x
->menubar_widget
))
393 #endif /* USE_X_TOOLKIT */
397 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
398 id, which is just an int that this section returns. Bitmaps are
399 reference counted so they can be shared among frames.
401 Bitmap indices are guaranteed to be > 0, so a negative number can
402 be used to indicate no bitmap.
404 If you use x_create_bitmap_from_data, then you must keep track of
405 the bitmaps yourself. That is, creating a bitmap from the same
406 data more than once will not be caught. */
409 /* Functions to access the contents of a bitmap, given an id. */
412 x_bitmap_height (f
, id
)
416 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].height
;
420 x_bitmap_width (f
, id
)
424 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].width
;
428 x_bitmap_pixmap (f
, id
)
432 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].pixmap
;
436 /* Allocate a new bitmap record. Returns index of new record. */
439 x_allocate_bitmap_record (f
)
442 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
445 if (dpyinfo
->bitmaps
== NULL
)
447 dpyinfo
->bitmaps_size
= 10;
449 = (struct x_bitmap_record
*) xmalloc (dpyinfo
->bitmaps_size
* sizeof (struct x_bitmap_record
));
450 dpyinfo
->bitmaps_last
= 1;
454 if (dpyinfo
->bitmaps_last
< dpyinfo
->bitmaps_size
)
455 return ++dpyinfo
->bitmaps_last
;
457 for (i
= 0; i
< dpyinfo
->bitmaps_size
; ++i
)
458 if (dpyinfo
->bitmaps
[i
].refcount
== 0)
461 dpyinfo
->bitmaps_size
*= 2;
463 = (struct x_bitmap_record
*) xrealloc (dpyinfo
->bitmaps
,
464 dpyinfo
->bitmaps_size
* sizeof (struct x_bitmap_record
));
465 return ++dpyinfo
->bitmaps_last
;
468 /* Add one reference to the reference count of the bitmap with id ID. */
471 x_reference_bitmap (f
, id
)
475 ++FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].refcount
;
478 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
481 x_create_bitmap_from_data (f
, bits
, width
, height
)
484 unsigned int width
, height
;
486 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
490 bitmap
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
491 bits
, width
, height
);
496 id
= x_allocate_bitmap_record (f
);
497 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
498 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
499 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
500 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
501 dpyinfo
->bitmaps
[id
- 1].height
= height
;
502 dpyinfo
->bitmaps
[id
- 1].width
= width
;
507 /* Create bitmap from file FILE for frame F. */
510 x_create_bitmap_from_file (f
, file
)
514 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
515 unsigned int width
, height
;
517 int xhot
, yhot
, result
, id
;
522 /* Look for an existing bitmap with the same name. */
523 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
525 if (dpyinfo
->bitmaps
[id
].refcount
526 && dpyinfo
->bitmaps
[id
].file
527 && !strcmp (dpyinfo
->bitmaps
[id
].file
, (char *) XSTRING (file
)->data
))
529 ++dpyinfo
->bitmaps
[id
].refcount
;
534 /* Search bitmap-file-path for the file, if appropriate. */
535 fd
= openp (Vx_bitmap_file_path
, file
, "", &found
, 0);
540 filename
= (char *) XSTRING (found
)->data
;
542 result
= XReadBitmapFile (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
543 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
544 if (result
!= BitmapSuccess
)
547 id
= x_allocate_bitmap_record (f
);
548 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
549 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
550 dpyinfo
->bitmaps
[id
- 1].file
= (char *) xmalloc (XSTRING (file
)->size
+ 1);
551 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
552 dpyinfo
->bitmaps
[id
- 1].height
= height
;
553 dpyinfo
->bitmaps
[id
- 1].width
= width
;
554 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, XSTRING (file
)->data
);
559 /* Remove reference to bitmap with id number ID. */
562 x_destroy_bitmap (f
, id
)
566 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
570 --dpyinfo
->bitmaps
[id
- 1].refcount
;
571 if (dpyinfo
->bitmaps
[id
- 1].refcount
== 0)
573 XFreePixmap (FRAME_X_DISPLAY (f
), dpyinfo
->bitmaps
[id
- 1].pixmap
);
574 if (dpyinfo
->bitmaps
[id
- 1].file
)
576 free (dpyinfo
->bitmaps
[id
- 1].file
);
577 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
583 /* Free all the bitmaps for the display specified by DPYINFO. */
586 x_destroy_all_bitmaps (dpyinfo
)
587 struct x_display_info
*dpyinfo
;
590 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++)
591 if (dpyinfo
->bitmaps
[i
].refcount
> 0)
593 XFreePixmap (dpyinfo
->display
, dpyinfo
->bitmaps
[i
].pixmap
);
594 if (dpyinfo
->bitmaps
[i
].file
)
595 free (dpyinfo
->bitmaps
[i
].file
);
597 dpyinfo
->bitmaps_last
= 0;
600 /* Connect the frame-parameter names for X frames
601 to the ways of passing the parameter values to the window system.
603 The name of a parameter, as a Lisp symbol,
604 has an `x-frame-parameter' property which is an integer in Lisp
605 but can be interpreted as an `enum x_frame_parm' in C. */
609 X_PARM_FOREGROUND_COLOR
,
610 X_PARM_BACKGROUND_COLOR
,
617 X_PARM_INTERNAL_BORDER_WIDTH
,
621 X_PARM_VERT_SCROLL_BAR
,
623 X_PARM_MENU_BAR_LINES
627 struct x_frame_parm_table
630 void (*setter
)( /* struct frame *frame, Lisp_Object val, oldval */ );
633 void x_set_foreground_color ();
634 void x_set_background_color ();
635 void x_set_mouse_color ();
636 void x_set_cursor_color ();
637 void x_set_border_color ();
638 void x_set_cursor_type ();
639 void x_set_icon_type ();
641 void x_set_border_width ();
642 void x_set_internal_border_width ();
643 void x_explicitly_set_name ();
644 void x_set_autoraise ();
645 void x_set_autolower ();
646 void x_set_vertical_scroll_bars ();
647 void x_set_visibility ();
648 void x_set_menu_bar_lines ();
649 void x_set_scroll_bar_width ();
650 void x_set_unsplittable ();
652 static struct x_frame_parm_table x_frame_parms
[] =
654 "foreground-color", x_set_foreground_color
,
655 "background-color", x_set_background_color
,
656 "mouse-color", x_set_mouse_color
,
657 "cursor-color", x_set_cursor_color
,
658 "border-color", x_set_border_color
,
659 "cursor-type", x_set_cursor_type
,
660 "icon-type", x_set_icon_type
,
662 "border-width", x_set_border_width
,
663 "internal-border-width", x_set_internal_border_width
,
664 "name", x_explicitly_set_name
,
665 "auto-raise", x_set_autoraise
,
666 "auto-lower", x_set_autolower
,
667 "vertical-scroll-bars", x_set_vertical_scroll_bars
,
668 "visibility", x_set_visibility
,
669 "menu-bar-lines", x_set_menu_bar_lines
,
670 "scroll-bar-width", x_set_scroll_bar_width
,
671 "unsplittable", x_set_unsplittable
,
674 /* Attach the `x-frame-parameter' properties to
675 the Lisp symbol names of parameters relevant to X. */
677 init_x_parm_symbols ()
681 for (i
= 0; i
< sizeof (x_frame_parms
) / sizeof (x_frame_parms
[0]); i
++)
682 Fput (intern (x_frame_parms
[i
].name
), Qx_frame_parameter
,
686 /* Change the parameters of FRAME as specified by ALIST.
687 If a parameter is not specially recognized, do nothing;
688 otherwise call the `x_set_...' function for that parameter. */
691 x_set_frame_parameters (f
, alist
)
697 /* If both of these parameters are present, it's more efficient to
698 set them both at once. So we wait until we've looked at the
699 entire list before we set them. */
700 Lisp_Object width
, height
;
703 Lisp_Object left
, top
;
705 /* Same with these. */
706 Lisp_Object icon_left
, icon_top
;
708 /* Record in these vectors all the parms specified. */
712 int left_no_change
= 0, top_no_change
= 0;
713 int icon_left_no_change
= 0, icon_top_no_change
= 0;
716 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
719 parms
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
720 values
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
722 /* Extract parm names and values into those vectors. */
725 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
727 Lisp_Object elt
, prop
, val
;
730 parms
[i
] = Fcar (elt
);
731 values
[i
] = Fcdr (elt
);
735 width
= height
= top
= left
= Qunbound
;
736 icon_left
= icon_top
= Qunbound
;
738 /* Now process them in reverse of specified order. */
739 for (i
--; i
>= 0; i
--)
741 Lisp_Object prop
, val
;
746 if (EQ (prop
, Qwidth
))
748 else if (EQ (prop
, Qheight
))
750 else if (EQ (prop
, Qtop
))
752 else if (EQ (prop
, Qleft
))
754 else if (EQ (prop
, Qicon_top
))
756 else if (EQ (prop
, Qicon_left
))
760 register Lisp_Object param_index
, old_value
;
762 param_index
= Fget (prop
, Qx_frame_parameter
);
763 old_value
= get_frame_param (f
, prop
);
764 store_frame_param (f
, prop
, val
);
765 if (NATNUMP (param_index
)
766 && (XFASTINT (param_index
)
767 < sizeof (x_frame_parms
)/sizeof (x_frame_parms
[0])))
768 (*x_frame_parms
[XINT (param_index
)].setter
)(f
, val
, old_value
);
772 /* Don't die if just one of these was set. */
773 if (EQ (left
, Qunbound
))
776 if (f
->display
.x
->left_pos
< 0)
777 left
= Fcons (Qplus
, Fcons (make_number (f
->display
.x
->left_pos
), Qnil
));
779 XSETINT (left
, f
->display
.x
->left_pos
);
781 if (EQ (top
, Qunbound
))
784 if (f
->display
.x
->top_pos
< 0)
785 top
= Fcons (Qplus
, Fcons (make_number (f
->display
.x
->top_pos
), Qnil
));
787 XSETINT (top
, f
->display
.x
->top_pos
);
790 /* If one of the icon positions was not set, preserve or default it. */
791 if (EQ (icon_left
, Qunbound
) || ! INTEGERP (icon_left
))
793 icon_left_no_change
= 1;
794 icon_left
= Fcdr (Fassq (Qicon_left
, f
->param_alist
));
795 if (NILP (icon_left
))
796 XSETINT (icon_left
, 0);
798 if (EQ (icon_top
, Qunbound
) || ! INTEGERP (icon_top
))
800 icon_top_no_change
= 1;
801 icon_top
= Fcdr (Fassq (Qicon_top
, f
->param_alist
));
803 XSETINT (icon_top
, 0);
806 /* Don't die if just one of these was set. */
807 if (EQ (width
, Qunbound
))
808 XSETINT (width
, FRAME_WIDTH (f
));
809 if (EQ (height
, Qunbound
))
810 XSETINT (height
, FRAME_HEIGHT (f
));
812 /* Don't set these parameters unless they've been explicitly
813 specified. The window might be mapped or resized while we're in
814 this function, and we don't want to override that unless the lisp
815 code has asked for it.
817 Don't set these parameters unless they actually differ from the
818 window's current parameters; the window may not actually exist
823 check_frame_size (f
, &height
, &width
);
825 XSETFRAME (frame
, f
);
827 if ((NUMBERP (width
) && XINT (width
) != FRAME_WIDTH (f
))
828 || (NUMBERP (height
) && XINT (height
) != FRAME_HEIGHT (f
)))
829 Fset_frame_size (frame
, width
, height
);
831 if ((!NILP (left
) || !NILP (top
))
832 && ! (left_no_change
&& top_no_change
)
833 && ! (NUMBERP (left
) && XINT (left
) == f
->display
.x
->left_pos
834 && NUMBERP (top
) && XINT (top
) == f
->display
.x
->top_pos
))
839 /* Record the signs. */
840 f
->display
.x
->size_hint_flags
&= ~ (XNegative
| YNegative
);
841 if (EQ (left
, Qminus
))
842 f
->display
.x
->size_hint_flags
|= XNegative
;
843 else if (INTEGERP (left
))
845 leftpos
= XINT (left
);
847 f
->display
.x
->size_hint_flags
|= XNegative
;
849 else if (CONSP (left
) && EQ (XCONS (left
)->car
, Qminus
)
850 && CONSP (XCONS (left
)->cdr
)
851 && INTEGERP (XCONS (XCONS (left
)->cdr
)->car
))
853 leftpos
= - XINT (XCONS (XCONS (left
)->cdr
)->car
);
854 f
->display
.x
->size_hint_flags
|= XNegative
;
856 else if (CONSP (left
) && EQ (XCONS (left
)->car
, Qplus
)
857 && CONSP (XCONS (left
)->cdr
)
858 && INTEGERP (XCONS (XCONS (left
)->cdr
)->car
))
860 leftpos
= XINT (XCONS (XCONS (left
)->cdr
)->car
);
863 if (EQ (top
, Qminus
))
864 f
->display
.x
->size_hint_flags
|= YNegative
;
865 else if (INTEGERP (top
))
869 f
->display
.x
->size_hint_flags
|= YNegative
;
871 else if (CONSP (top
) && EQ (XCONS (top
)->car
, Qminus
)
872 && CONSP (XCONS (top
)->cdr
)
873 && INTEGERP (XCONS (XCONS (top
)->cdr
)->car
))
875 toppos
= - XINT (XCONS (XCONS (top
)->cdr
)->car
);
876 f
->display
.x
->size_hint_flags
|= YNegative
;
878 else if (CONSP (top
) && EQ (XCONS (top
)->car
, Qplus
)
879 && CONSP (XCONS (top
)->cdr
)
880 && INTEGERP (XCONS (XCONS (top
)->cdr
)->car
))
882 toppos
= XINT (XCONS (XCONS (top
)->cdr
)->car
);
886 /* Store the numeric value of the position. */
887 f
->display
.x
->top_pos
= toppos
;
888 f
->display
.x
->left_pos
= leftpos
;
890 f
->display
.x
->win_gravity
= NorthWestGravity
;
892 /* Actually set that position, and convert to absolute. */
893 x_set_offset (f
, leftpos
, toppos
, -1);
896 if ((!NILP (icon_left
) || !NILP (icon_top
))
897 && ! (icon_left_no_change
&& icon_top_no_change
))
898 x_wm_set_icon_position (f
, XINT (icon_left
), XINT (icon_top
));
902 /* Store the screen positions of frame F into XPTR and YPTR.
903 These are the positions of the containing window manager window,
904 not Emacs's own window. */
907 x_real_positions (f
, xptr
, yptr
)
914 /* This is pretty gross, but seems to be the easiest way out of
915 the problem that arises when restarting window-managers. */
918 Window outer
= XtWindow (f
->display
.x
->widget
);
920 Window outer
= f
->display
.x
->window_desc
;
922 Window tmp_root_window
;
923 Window
*tmp_children
;
926 x_catch_errors (FRAME_X_DISPLAY (f
));
929 XQueryTree (FRAME_X_DISPLAY (f
), outer
, &tmp_root_window
,
930 &f
->display
.x
->parent_desc
,
931 &tmp_children
, &tmp_nchildren
);
932 xfree (tmp_children
);
936 /* Find the position of the outside upper-left corner of
937 the inner window, with respect to the outer window. */
938 if (f
->display
.x
->parent_desc
!= FRAME_X_DISPLAY_INFO (f
)->root_window
)
940 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
942 /* From-window, to-window. */
944 XtWindow (f
->display
.x
->widget
),
946 f
->display
.x
->window_desc
,
948 f
->display
.x
->parent_desc
,
950 /* From-position, to-position. */
951 0, 0, &win_x
, &win_y
,
956 #if 0 /* The values seem to be right without this and wrong with. */
957 win_x
+= f
->display
.x
->border_width
;
958 win_y
+= f
->display
.x
->border_width
;
962 /* It is possible for the window returned by the XQueryNotify
963 to become invalid by the time we call XTranslateCoordinates.
964 That can happen when you restart some window managers.
965 If so, we get an error in XTranslateCoordinates.
966 Detect that and try the whole thing over. */
967 if (! x_had_errors_p (FRAME_X_DISPLAY (f
)))
971 x_uncatch_errors (FRAME_X_DISPLAY (f
));
973 *xptr
= f
->display
.x
->left_pos
- win_x
;
974 *yptr
= f
->display
.x
->top_pos
- win_y
;
977 /* Insert a description of internally-recorded parameters of frame X
978 into the parameter alist *ALISTPTR that is to be given to the user.
979 Only parameters that are specific to the X window system
980 and whose values are not correctly recorded in the frame's
981 param_alist need to be considered here. */
983 x_report_frame_params (f
, alistptr
)
985 Lisp_Object
*alistptr
;
990 /* Represent negative positions (off the top or left screen edge)
991 in a way that Fmodify_frame_parameters will understand correctly. */
992 XSETINT (tem
, f
->display
.x
->left_pos
);
993 if (f
->display
.x
->left_pos
>= 0)
994 store_in_alist (alistptr
, Qleft
, tem
);
996 store_in_alist (alistptr
, Qleft
, Fcons (Qplus
, Fcons (tem
, Qnil
)));
998 XSETINT (tem
, f
->display
.x
->top_pos
);
999 if (f
->display
.x
->top_pos
>= 0)
1000 store_in_alist (alistptr
, Qtop
, tem
);
1002 store_in_alist (alistptr
, Qtop
, Fcons (Qplus
, Fcons (tem
, Qnil
)));
1004 store_in_alist (alistptr
, Qborder_width
,
1005 make_number (f
->display
.x
->border_width
));
1006 store_in_alist (alistptr
, Qinternal_border_width
,
1007 make_number (f
->display
.x
->internal_border_width
));
1008 sprintf (buf
, "%ld", (long) FRAME_X_WINDOW (f
));
1009 store_in_alist (alistptr
, Qwindow_id
,
1010 build_string (buf
));
1011 FRAME_SAMPLE_VISIBILITY (f
);
1012 store_in_alist (alistptr
, Qvisibility
,
1013 (FRAME_VISIBLE_P (f
) ? Qt
1014 : FRAME_ICONIFIED_P (f
) ? Qicon
: Qnil
));
1015 store_in_alist (alistptr
, Qdisplay
,
1016 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->car
);
1020 /* Decide if color named COLOR is valid for the display associated with
1021 the selected frame; if so, return the rgb values in COLOR_DEF.
1022 If ALLOC is nonzero, allocate a new colormap cell. */
1025 defined_color (f
, color
, color_def
, alloc
)
1031 register int status
;
1032 Colormap screen_colormap
;
1033 Display
*display
= FRAME_X_DISPLAY (f
);
1036 screen_colormap
= DefaultColormap (display
, XDefaultScreen (display
));
1038 status
= XParseColor (display
, screen_colormap
, color
, color_def
);
1039 if (status
&& alloc
)
1041 status
= XAllocColor (display
, screen_colormap
, color_def
);
1044 /* If we got to this point, the colormap is full, so we're
1045 going to try and get the next closest color.
1046 The algorithm used is a least-squares matching, which is
1047 what X uses for closest color matching with StaticColor visuals. */
1052 long nearest_delta
, trial_delta
;
1055 no_cells
= XDisplayCells (display
, XDefaultScreen (display
));
1056 cells
= (XColor
*) alloca (sizeof (XColor
) * no_cells
);
1058 for (x
= 0; x
< no_cells
; x
++)
1061 XQueryColors (display
, screen_colormap
, cells
, no_cells
);
1063 /* I'm assuming CSE so I'm not going to condense this. */
1064 nearest_delta
= ((((color_def
->red
>> 8) - (cells
[0].red
>> 8))
1065 * ((color_def
->red
>> 8) - (cells
[0].red
>> 8)))
1067 (((color_def
->green
>> 8) - (cells
[0].green
>> 8))
1068 * ((color_def
->green
>> 8) - (cells
[0].green
>> 8)))
1070 (((color_def
->blue
>> 8) - (cells
[0].blue
>> 8))
1071 * ((color_def
->blue
>> 8) - (cells
[0].blue
>> 8))));
1072 for (x
= 1; x
< no_cells
; x
++)
1074 trial_delta
= ((((color_def
->red
>> 8) - (cells
[x
].red
>> 8))
1075 * ((color_def
->red
>> 8) - (cells
[x
].red
>> 8)))
1077 (((color_def
->green
>> 8) - (cells
[x
].green
>> 8))
1078 * ((color_def
->green
>> 8) - (cells
[x
].green
>> 8)))
1080 (((color_def
->blue
>> 8) - (cells
[x
].blue
>> 8))
1081 * ((color_def
->blue
>> 8) - (cells
[x
].blue
>> 8))));
1082 if (trial_delta
< nearest_delta
)
1085 nearest_delta
= trial_delta
;
1088 color_def
->red
= cells
[nearest
].red
;
1089 color_def
->green
= cells
[nearest
].green
;
1090 color_def
->blue
= cells
[nearest
].blue
;
1091 status
= XAllocColor (display
, screen_colormap
, color_def
);
1102 /* Given a string ARG naming a color, compute a pixel value from it
1103 suitable for screen F.
1104 If F is not a color screen, return DEF (default) regardless of what
1108 x_decode_color (f
, arg
, def
)
1115 CHECK_STRING (arg
, 0);
1117 if (strcmp (XSTRING (arg
)->data
, "black") == 0)
1118 return BLACK_PIX_DEFAULT (f
);
1119 else if (strcmp (XSTRING (arg
)->data
, "white") == 0)
1120 return WHITE_PIX_DEFAULT (f
);
1122 if (FRAME_X_DISPLAY_INFO (f
)->n_planes
== 1)
1125 /* defined_color is responsible for coping with failures
1126 by looking for a near-miss. */
1127 if (defined_color (f
, XSTRING (arg
)->data
, &cdef
, 1))
1130 /* defined_color failed; return an ultimate default. */
1134 /* Functions called only from `x_set_frame_param'
1135 to set individual parameters.
1137 If FRAME_X_WINDOW (f) is 0,
1138 the frame is being created and its X-window does not exist yet.
1139 In that case, just record the parameter's new value
1140 in the standard place; do not attempt to change the window. */
1143 x_set_foreground_color (f
, arg
, oldval
)
1145 Lisp_Object arg
, oldval
;
1147 f
->display
.x
->foreground_pixel
1148 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1149 if (FRAME_X_WINDOW (f
) != 0)
1152 XSetForeground (FRAME_X_DISPLAY (f
), f
->display
.x
->normal_gc
,
1153 f
->display
.x
->foreground_pixel
);
1154 XSetBackground (FRAME_X_DISPLAY (f
), f
->display
.x
->reverse_gc
,
1155 f
->display
.x
->foreground_pixel
);
1157 recompute_basic_faces (f
);
1158 if (FRAME_VISIBLE_P (f
))
1164 x_set_background_color (f
, arg
, oldval
)
1166 Lisp_Object arg
, oldval
;
1171 f
->display
.x
->background_pixel
1172 = x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
1174 if (FRAME_X_WINDOW (f
) != 0)
1177 /* The main frame area. */
1178 XSetBackground (FRAME_X_DISPLAY (f
), f
->display
.x
->normal_gc
,
1179 f
->display
.x
->background_pixel
);
1180 XSetForeground (FRAME_X_DISPLAY (f
), f
->display
.x
->reverse_gc
,
1181 f
->display
.x
->background_pixel
);
1182 XSetForeground (FRAME_X_DISPLAY (f
), f
->display
.x
->cursor_gc
,
1183 f
->display
.x
->background_pixel
);
1184 XSetWindowBackground (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1185 f
->display
.x
->background_pixel
);
1188 for (bar
= FRAME_SCROLL_BARS (f
); !NILP (bar
);
1189 bar
= XSCROLL_BAR (bar
)->next
)
1190 XSetWindowBackground (FRAME_X_DISPLAY (f
),
1191 SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
)),
1192 f
->display
.x
->background_pixel
);
1196 recompute_basic_faces (f
);
1198 if (FRAME_VISIBLE_P (f
))
1204 x_set_mouse_color (f
, arg
, oldval
)
1206 Lisp_Object arg
, oldval
;
1208 Cursor cursor
, nontext_cursor
, mode_cursor
, cross_cursor
;
1211 if (!EQ (Qnil
, arg
))
1212 f
->display
.x
->mouse_pixel
1213 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1214 mask_color
= f
->display
.x
->background_pixel
;
1215 /* No invisible pointers. */
1216 if (mask_color
== f
->display
.x
->mouse_pixel
1217 && mask_color
== f
->display
.x
->background_pixel
)
1218 f
->display
.x
->mouse_pixel
= f
->display
.x
->foreground_pixel
;
1222 /* It's not okay to crash if the user selects a screwy cursor. */
1223 x_catch_errors (FRAME_X_DISPLAY (f
));
1225 if (!EQ (Qnil
, Vx_pointer_shape
))
1227 CHECK_NUMBER (Vx_pointer_shape
, 0);
1228 cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XINT (Vx_pointer_shape
));
1231 cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_xterm
);
1232 x_check_errors (FRAME_X_DISPLAY (f
), "bad text pointer cursor: %s");
1234 if (!EQ (Qnil
, Vx_nontext_pointer_shape
))
1236 CHECK_NUMBER (Vx_nontext_pointer_shape
, 0);
1237 nontext_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
),
1238 XINT (Vx_nontext_pointer_shape
));
1241 nontext_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_left_ptr
);
1242 x_check_errors (FRAME_X_DISPLAY (f
), "bad nontext pointer cursor: %s");
1244 if (!EQ (Qnil
, Vx_mode_pointer_shape
))
1246 CHECK_NUMBER (Vx_mode_pointer_shape
, 0);
1247 mode_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
),
1248 XINT (Vx_mode_pointer_shape
));
1251 mode_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_xterm
);
1252 x_check_errors (FRAME_X_DISPLAY (f
), "bad modeline pointer cursor: %s");
1254 if (!EQ (Qnil
, Vx_sensitive_text_pointer_shape
))
1256 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
, 0);
1258 = XCreateFontCursor (FRAME_X_DISPLAY (f
),
1259 XINT (Vx_sensitive_text_pointer_shape
));
1262 cross_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_crosshair
);
1264 /* Check and report errors with the above calls. */
1265 x_check_errors (FRAME_X_DISPLAY (f
), "can't set cursor shape: %s");
1266 x_uncatch_errors (FRAME_X_DISPLAY (f
));
1269 XColor fore_color
, back_color
;
1271 fore_color
.pixel
= f
->display
.x
->mouse_pixel
;
1272 back_color
.pixel
= mask_color
;
1273 XQueryColor (FRAME_X_DISPLAY (f
),
1274 DefaultColormap (FRAME_X_DISPLAY (f
),
1275 DefaultScreen (FRAME_X_DISPLAY (f
))),
1277 XQueryColor (FRAME_X_DISPLAY (f
),
1278 DefaultColormap (FRAME_X_DISPLAY (f
),
1279 DefaultScreen (FRAME_X_DISPLAY (f
))),
1281 XRecolorCursor (FRAME_X_DISPLAY (f
), cursor
,
1282 &fore_color
, &back_color
);
1283 XRecolorCursor (FRAME_X_DISPLAY (f
), nontext_cursor
,
1284 &fore_color
, &back_color
);
1285 XRecolorCursor (FRAME_X_DISPLAY (f
), mode_cursor
,
1286 &fore_color
, &back_color
);
1287 XRecolorCursor (FRAME_X_DISPLAY (f
), cross_cursor
,
1288 &fore_color
, &back_color
);
1291 if (FRAME_X_WINDOW (f
) != 0)
1293 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
1296 if (cursor
!= f
->display
.x
->text_cursor
&& f
->display
.x
->text_cursor
!= 0)
1297 XFreeCursor (FRAME_X_DISPLAY (f
), f
->display
.x
->text_cursor
);
1298 f
->display
.x
->text_cursor
= cursor
;
1300 if (nontext_cursor
!= f
->display
.x
->nontext_cursor
1301 && f
->display
.x
->nontext_cursor
!= 0)
1302 XFreeCursor (FRAME_X_DISPLAY (f
), f
->display
.x
->nontext_cursor
);
1303 f
->display
.x
->nontext_cursor
= nontext_cursor
;
1305 if (mode_cursor
!= f
->display
.x
->modeline_cursor
1306 && f
->display
.x
->modeline_cursor
!= 0)
1307 XFreeCursor (FRAME_X_DISPLAY (f
), f
->display
.x
->modeline_cursor
);
1308 f
->display
.x
->modeline_cursor
= mode_cursor
;
1309 if (cross_cursor
!= f
->display
.x
->cross_cursor
1310 && f
->display
.x
->cross_cursor
!= 0)
1311 XFreeCursor (FRAME_X_DISPLAY (f
), f
->display
.x
->cross_cursor
);
1312 f
->display
.x
->cross_cursor
= cross_cursor
;
1314 XFlush (FRAME_X_DISPLAY (f
));
1319 x_set_cursor_color (f
, arg
, oldval
)
1321 Lisp_Object arg
, oldval
;
1323 unsigned long fore_pixel
;
1325 if (!EQ (Vx_cursor_fore_pixel
, Qnil
))
1326 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
1327 WHITE_PIX_DEFAULT (f
));
1329 fore_pixel
= f
->display
.x
->background_pixel
;
1330 f
->display
.x
->cursor_pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1332 /* Make sure that the cursor color differs from the background color. */
1333 if (f
->display
.x
->cursor_pixel
== f
->display
.x
->background_pixel
)
1335 f
->display
.x
->cursor_pixel
= f
->display
.x
->mouse_pixel
;
1336 if (f
->display
.x
->cursor_pixel
== fore_pixel
)
1337 fore_pixel
= f
->display
.x
->background_pixel
;
1339 f
->display
.x
->cursor_foreground_pixel
= fore_pixel
;
1341 if (FRAME_X_WINDOW (f
) != 0)
1344 XSetBackground (FRAME_X_DISPLAY (f
), f
->display
.x
->cursor_gc
,
1345 f
->display
.x
->cursor_pixel
);
1346 XSetForeground (FRAME_X_DISPLAY (f
), f
->display
.x
->cursor_gc
,
1350 if (FRAME_VISIBLE_P (f
))
1352 x_display_cursor (f
, 0);
1353 x_display_cursor (f
, 1);
1358 /* Set the border-color of frame F to value described by ARG.
1359 ARG can be a string naming a color.
1360 The border-color is used for the border that is drawn by the X server.
1361 Note that this does not fully take effect if done before
1362 F has an x-window; it must be redone when the window is created.
1364 Note: this is done in two routines because of the way X10 works.
1366 Note: under X11, this is normally the province of the window manager,
1367 and so emacs' border colors may be overridden. */
1370 x_set_border_color (f
, arg
, oldval
)
1372 Lisp_Object arg
, oldval
;
1377 CHECK_STRING (arg
, 0);
1378 str
= XSTRING (arg
)->data
;
1380 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1382 x_set_border_pixel (f
, pix
);
1385 /* Set the border-color of frame F to pixel value PIX.
1386 Note that this does not fully take effect if done before
1387 F has an x-window. */
1389 x_set_border_pixel (f
, pix
)
1393 f
->display
.x
->border_pixel
= pix
;
1395 if (FRAME_X_WINDOW (f
) != 0 && f
->display
.x
->border_width
> 0)
1401 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1402 (unsigned long)pix
);
1405 if (FRAME_VISIBLE_P (f
))
1411 x_set_cursor_type (f
, arg
, oldval
)
1413 Lisp_Object arg
, oldval
;
1417 FRAME_DESIRED_CURSOR (f
) = bar_cursor
;
1418 f
->display
.x
->cursor_width
= 2;
1420 else if (CONSP (arg
) && EQ (XCONS (arg
)->car
, Qbar
)
1421 && INTEGERP (XCONS (arg
)->cdr
))
1423 FRAME_DESIRED_CURSOR (f
) = bar_cursor
;
1424 f
->display
.x
->cursor_width
= XINT (XCONS (arg
)->cdr
);
1427 /* Treat anything unknown as "box cursor".
1428 It was bad to signal an error; people have trouble fixing
1429 .Xdefaults with Emacs, when it has something bad in it. */
1430 FRAME_DESIRED_CURSOR (f
) = filled_box_cursor
;
1432 /* Make sure the cursor gets redrawn. This is overkill, but how
1433 often do people change cursor types? */
1434 update_mode_lines
++;
1438 x_set_icon_type (f
, arg
, oldval
)
1440 Lisp_Object arg
, oldval
;
1447 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1450 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1455 result
= x_text_icon (f
, 0);
1457 result
= x_bitmap_icon (f
, arg
);
1462 error ("No icon window available");
1465 /* If the window was unmapped (and its icon was mapped),
1466 the new icon is not mapped, so map the window in its stead. */
1467 if (FRAME_VISIBLE_P (f
))
1469 #ifdef USE_X_TOOLKIT
1470 XtPopup (f
->display
.x
->widget
, XtGrabNone
);
1472 XMapWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
1475 XFlush (FRAME_X_DISPLAY (f
));
1479 /* Return non-nil if frame F wants a bitmap icon. */
1487 tem
= assq_no_quit (Qicon_type
, f
->param_alist
);
1489 return XCONS (tem
)->cdr
;
1494 extern Lisp_Object
x_new_font ();
1497 x_set_font (f
, arg
, oldval
)
1499 Lisp_Object arg
, oldval
;
1503 CHECK_STRING (arg
, 1);
1506 result
= x_new_font (f
, XSTRING (arg
)->data
);
1509 if (EQ (result
, Qnil
))
1510 error ("Font \"%s\" is not defined", XSTRING (arg
)->data
);
1511 else if (EQ (result
, Qt
))
1512 error ("the characters of the given font have varying widths");
1513 else if (STRINGP (result
))
1515 recompute_basic_faces (f
);
1516 store_frame_param (f
, Qfont
, result
);
1523 x_set_border_width (f
, arg
, oldval
)
1525 Lisp_Object arg
, oldval
;
1527 CHECK_NUMBER (arg
, 0);
1529 if (XINT (arg
) == f
->display
.x
->border_width
)
1532 if (FRAME_X_WINDOW (f
) != 0)
1533 error ("Cannot change the border width of a window");
1535 f
->display
.x
->border_width
= XINT (arg
);
1539 x_set_internal_border_width (f
, arg
, oldval
)
1541 Lisp_Object arg
, oldval
;
1544 int old
= f
->display
.x
->internal_border_width
;
1546 CHECK_NUMBER (arg
, 0);
1547 f
->display
.x
->internal_border_width
= XINT (arg
);
1548 if (f
->display
.x
->internal_border_width
< 0)
1549 f
->display
.x
->internal_border_width
= 0;
1551 if (f
->display
.x
->internal_border_width
== old
)
1554 if (FRAME_X_WINDOW (f
) != 0)
1557 x_set_window_size (f
, 0, f
->width
, f
->height
);
1559 x_set_resize_hint (f
);
1561 XFlush (FRAME_X_DISPLAY (f
));
1563 SET_FRAME_GARBAGED (f
);
1568 x_set_visibility (f
, value
, oldval
)
1570 Lisp_Object value
, oldval
;
1573 XSETFRAME (frame
, f
);
1576 Fmake_frame_invisible (frame
, Qt
);
1577 else if (EQ (value
, Qicon
))
1578 Ficonify_frame (frame
);
1580 Fmake_frame_visible (frame
);
1584 x_set_menu_bar_lines_1 (window
, n
)
1588 struct window
*w
= XWINDOW (window
);
1590 XSETFASTINT (w
->top
, XFASTINT (w
->top
) + n
);
1591 XSETFASTINT (w
->height
, XFASTINT (w
->height
) - n
);
1593 /* Handle just the top child in a vertical split. */
1594 if (!NILP (w
->vchild
))
1595 x_set_menu_bar_lines_1 (w
->vchild
, n
);
1597 /* Adjust all children in a horizontal split. */
1598 for (window
= w
->hchild
; !NILP (window
); window
= w
->next
)
1600 w
= XWINDOW (window
);
1601 x_set_menu_bar_lines_1 (window
, n
);
1606 x_set_menu_bar_lines (f
, value
, oldval
)
1608 Lisp_Object value
, oldval
;
1611 int olines
= FRAME_MENU_BAR_LINES (f
);
1613 /* Right now, menu bars don't work properly in minibuf-only frames;
1614 most of the commands try to apply themselves to the minibuffer
1615 frame itslef, and get an error because you can't switch buffers
1616 in or split the minibuffer window. */
1617 if (FRAME_MINIBUF_ONLY_P (f
))
1620 if (INTEGERP (value
))
1621 nlines
= XINT (value
);
1625 #ifdef USE_X_TOOLKIT
1626 FRAME_MENU_BAR_LINES (f
) = 0;
1628 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
1631 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
1632 free_frame_menubar (f
);
1633 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
1634 f
->display
.x
->menubar_widget
= 0;
1636 #else /* not USE_X_TOOLKIT */
1637 FRAME_MENU_BAR_LINES (f
) = nlines
;
1638 x_set_menu_bar_lines_1 (f
->root_window
, nlines
- olines
);
1639 #endif /* not USE_X_TOOLKIT */
1642 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1645 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1646 name; if NAME is a string, set F's name to NAME and set
1647 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1649 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1650 suggesting a new name, which lisp code should override; if
1651 F->explicit_name is set, ignore the new name; otherwise, set it. */
1654 x_set_name (f
, name
, explicit)
1659 /* Make sure that requests from lisp code override requests from
1660 Emacs redisplay code. */
1663 /* If we're switching from explicit to implicit, we had better
1664 update the mode lines and thereby update the title. */
1665 if (f
->explicit_name
&& NILP (name
))
1666 update_mode_lines
= 1;
1668 f
->explicit_name
= ! NILP (name
);
1670 else if (f
->explicit_name
)
1673 /* If NAME is nil, set the name to the x_id_name. */
1676 /* Check for no change needed in this very common case
1677 before we do any consing. */
1678 if (!strcmp (FRAME_X_DISPLAY_INFO (f
)->x_id_name
,
1679 XSTRING (f
->name
)->data
))
1681 name
= build_string (FRAME_X_DISPLAY_INFO (f
)->x_id_name
);
1684 CHECK_STRING (name
, 0);
1686 /* Don't change the name if it's already NAME. */
1687 if (! NILP (Fstring_equal (name
, f
->name
)))
1690 if (FRAME_X_WINDOW (f
))
1696 text
.value
= XSTRING (name
)->data
;
1697 text
.encoding
= XA_STRING
;
1699 text
.nitems
= XSTRING (name
)->size
;
1700 #ifdef USE_X_TOOLKIT
1701 XSetWMName (FRAME_X_DISPLAY (f
),
1702 XtWindow (f
->display
.x
->widget
), &text
);
1703 XSetWMIconName (FRAME_X_DISPLAY (f
), XtWindow (f
->display
.x
->widget
),
1705 #else /* not USE_X_TOOLKIT */
1706 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &text
);
1707 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &text
);
1708 #endif /* not USE_X_TOOLKIT */
1710 #else /* not HAVE_X11R4 */
1711 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1712 XSTRING (name
)->data
);
1713 XStoreName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1714 XSTRING (name
)->data
);
1715 #endif /* not HAVE_X11R4 */
1722 /* This function should be called when the user's lisp code has
1723 specified a name for the frame; the name will override any set by the
1726 x_explicitly_set_name (f
, arg
, oldval
)
1728 Lisp_Object arg
, oldval
;
1730 x_set_name (f
, arg
, 1);
1733 /* This function should be called by Emacs redisplay code to set the
1734 name; names set this way will never override names set by the user's
1737 x_implicitly_set_name (f
, arg
, oldval
)
1739 Lisp_Object arg
, oldval
;
1741 x_set_name (f
, arg
, 0);
1745 x_set_autoraise (f
, arg
, oldval
)
1747 Lisp_Object arg
, oldval
;
1749 f
->auto_raise
= !EQ (Qnil
, arg
);
1753 x_set_autolower (f
, arg
, oldval
)
1755 Lisp_Object arg
, oldval
;
1757 f
->auto_lower
= !EQ (Qnil
, arg
);
1761 x_set_unsplittable (f
, arg
, oldval
)
1763 Lisp_Object arg
, oldval
;
1765 f
->no_split
= !NILP (arg
);
1769 x_set_vertical_scroll_bars (f
, arg
, oldval
)
1771 Lisp_Object arg
, oldval
;
1773 if (NILP (arg
) != ! FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
1775 FRAME_HAS_VERTICAL_SCROLL_BARS (f
) = ! NILP (arg
);
1777 /* We set this parameter before creating the X window for the
1778 frame, so we can get the geometry right from the start.
1779 However, if the window hasn't been created yet, we shouldn't
1780 call x_set_window_size. */
1781 if (FRAME_X_WINDOW (f
))
1782 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
1787 x_set_scroll_bar_width (f
, arg
, oldval
)
1789 Lisp_Object arg
, oldval
;
1793 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = 0;
1794 FRAME_SCROLL_BAR_COLS (f
) = 2;
1796 else if (INTEGERP (arg
) && XINT (arg
) > 0
1797 && XFASTINT (arg
) != FRAME_SCROLL_BAR_PIXEL_WIDTH (f
))
1799 int wid
= FONT_WIDTH (f
->display
.x
->font
);
1800 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = XFASTINT (arg
);
1801 FRAME_SCROLL_BAR_COLS (f
) = (XFASTINT (arg
) + wid
-1) / wid
;
1802 if (FRAME_X_WINDOW (f
))
1803 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
1807 /* Subroutines of creating an X frame. */
1809 /* Make sure that Vx_resource_name is set to a reasonable value.
1810 Fix it up, or set it to `emacs' if it is too hopeless. */
1813 validate_x_resource_name ()
1816 /* Number of valid characters in the resource name. */
1818 /* Number of invalid characters in the resource name. */
1823 if (STRINGP (Vx_resource_name
))
1825 unsigned char *p
= XSTRING (Vx_resource_name
)->data
;
1828 len
= XSTRING (Vx_resource_name
)->size
;
1830 /* Only letters, digits, - and _ are valid in resource names.
1831 Count the valid characters and count the invalid ones. */
1832 for (i
= 0; i
< len
; i
++)
1835 if (! ((c
>= 'a' && c
<= 'z')
1836 || (c
>= 'A' && c
<= 'Z')
1837 || (c
>= '0' && c
<= '9')
1838 || c
== '-' || c
== '_'))
1845 /* Not a string => completely invalid. */
1846 bad_count
= 5, good_count
= 0;
1848 /* If name is valid already, return. */
1852 /* If name is entirely invalid, or nearly so, use `emacs'. */
1854 || (good_count
== 1 && bad_count
> 0))
1856 Vx_resource_name
= build_string ("emacs");
1860 /* Name is partly valid. Copy it and replace the invalid characters
1861 with underscores. */
1863 Vx_resource_name
= new = Fcopy_sequence (Vx_resource_name
);
1865 for (i
= 0; i
< len
; i
++)
1867 int c
= XSTRING (new)->data
[i
];
1868 if (! ((c
>= 'a' && c
<= 'z')
1869 || (c
>= 'A' && c
<= 'Z')
1870 || (c
>= '0' && c
<= '9')
1871 || c
== '-' || c
== '_'))
1872 XSTRING (new)->data
[i
] = '_';
1877 extern char *x_get_string_resource ();
1879 DEFUN ("x-get-resource", Fx_get_resource
, Sx_get_resource
, 2, 4, 0,
1880 "Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.\n\
1881 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the\n\
1882 class, where INSTANCE is the name under which Emacs was invoked, or\n\
1883 the name specified by the `-name' or `-rn' command-line arguments.\n\
1885 The optional arguments COMPONENT and SUBCLASS add to the key and the\n\
1886 class, respectively. You must specify both of them or neither.\n\
1887 If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'\n\
1888 and the class is `Emacs.CLASS.SUBCLASS'.")
1889 (attribute
, class, component
, subclass
)
1890 Lisp_Object attribute
, class, component
, subclass
;
1892 register char *value
;
1898 CHECK_STRING (attribute
, 0);
1899 CHECK_STRING (class, 0);
1901 if (!NILP (component
))
1902 CHECK_STRING (component
, 1);
1903 if (!NILP (subclass
))
1904 CHECK_STRING (subclass
, 2);
1905 if (NILP (component
) != NILP (subclass
))
1906 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
1908 validate_x_resource_name ();
1910 /* Allocate space for the components, the dots which separate them,
1911 and the final '\0'. Make them big enough for the worst case. */
1912 name_key
= (char *) alloca (XSTRING (Vx_resource_name
)->size
1913 + (STRINGP (component
)
1914 ? XSTRING (component
)->size
: 0)
1915 + XSTRING (attribute
)->size
1918 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
1919 + XSTRING (class)->size
1920 + (STRINGP (subclass
)
1921 ? XSTRING (subclass
)->size
: 0)
1924 /* Start with emacs.FRAMENAME for the name (the specific one)
1925 and with `Emacs' for the class key (the general one). */
1926 strcpy (name_key
, XSTRING (Vx_resource_name
)->data
);
1927 strcpy (class_key
, EMACS_CLASS
);
1929 strcat (class_key
, ".");
1930 strcat (class_key
, XSTRING (class)->data
);
1932 if (!NILP (component
))
1934 strcat (class_key
, ".");
1935 strcat (class_key
, XSTRING (subclass
)->data
);
1937 strcat (name_key
, ".");
1938 strcat (name_key
, XSTRING (component
)->data
);
1941 strcat (name_key
, ".");
1942 strcat (name_key
, XSTRING (attribute
)->data
);
1944 value
= x_get_string_resource (check_x_display_info (Qnil
)->xrdb
,
1945 name_key
, class_key
);
1947 if (value
!= (char *) 0)
1948 return build_string (value
);
1953 /* Used when C code wants a resource value. */
1956 x_get_resource_string (attribute
, class)
1957 char *attribute
, *class;
1959 register char *value
;
1963 /* Allocate space for the components, the dots which separate them,
1964 and the final '\0'. */
1965 name_key
= (char *) alloca (XSTRING (Vinvocation_name
)->size
1966 + strlen (attribute
) + 2);
1967 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
1968 + strlen (class) + 2);
1970 sprintf (name_key
, "%s.%s",
1971 XSTRING (Vinvocation_name
)->data
,
1973 sprintf (class_key
, "%s.%s", EMACS_CLASS
, class);
1975 return x_get_string_resource (FRAME_X_DISPLAY_INFO (selected_frame
)->xrdb
,
1976 name_key
, class_key
);
1979 /* Types we might convert a resource string into. */
1982 number
, boolean
, string
, symbol
1985 /* Return the value of parameter PARAM.
1987 First search ALIST, then Vdefault_frame_alist, then the X defaults
1988 database, using ATTRIBUTE as the attribute name and CLASS as its class.
1990 Convert the resource to the type specified by desired_type.
1992 If no default is specified, return Qunbound. If you call
1993 x_get_arg, make sure you deal with Qunbound in a reasonable way,
1994 and don't let it get stored in any Lisp-visible variables! */
1997 x_get_arg (alist
, param
, attribute
, class, type
)
1998 Lisp_Object alist
, param
;
2001 enum resource_types type
;
2003 register Lisp_Object tem
;
2005 tem
= Fassq (param
, alist
);
2007 tem
= Fassq (param
, Vdefault_frame_alist
);
2013 tem
= Fx_get_resource (build_string (attribute
),
2014 build_string (class),
2023 return make_number (atoi (XSTRING (tem
)->data
));
2026 tem
= Fdowncase (tem
);
2027 if (!strcmp (XSTRING (tem
)->data
, "on")
2028 || !strcmp (XSTRING (tem
)->data
, "true"))
2037 /* As a special case, we map the values `true' and `on'
2038 to Qt, and `false' and `off' to Qnil. */
2041 lower
= Fdowncase (tem
);
2042 if (!strcmp (XSTRING (lower
)->data
, "on")
2043 || !strcmp (XSTRING (lower
)->data
, "true"))
2045 else if (!strcmp (XSTRING (lower
)->data
, "off")
2046 || !strcmp (XSTRING (lower
)->data
, "false"))
2049 return Fintern (tem
, Qnil
);
2062 /* Record in frame F the specified or default value according to ALIST
2063 of the parameter named PARAM (a Lisp symbol).
2064 If no value is specified for PARAM, look for an X default for XPROP
2065 on the frame named NAME.
2066 If that is not found either, use the value DEFLT. */
2069 x_default_parameter (f
, alist
, prop
, deflt
, xprop
, xclass
, type
)
2076 enum resource_types type
;
2080 tem
= x_get_arg (alist
, prop
, xprop
, xclass
, type
);
2081 if (EQ (tem
, Qunbound
))
2083 x_set_frame_parameters (f
, Fcons (Fcons (prop
, tem
), Qnil
));
2087 DEFUN ("x-parse-geometry", Fx_parse_geometry
, Sx_parse_geometry
, 1, 1, 0,
2088 "Parse an X-style geometry string STRING.\n\
2089 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).\n\
2090 The properties returned may include `top', `left', `height', and `width'.\n\
2091 The value of `left' or `top' may be an integer,\n\
2092 or a list (+ N) meaning N pixels relative to top/left corner,\n\
2093 or a list (- N) meaning -N pixels relative to bottom/right corner.")
2098 unsigned int width
, height
;
2101 CHECK_STRING (string
, 0);
2103 geometry
= XParseGeometry ((char *) XSTRING (string
)->data
,
2104 &x
, &y
, &width
, &height
);
2107 if (!!(geometry
& XValue
) != !!(geometry
& YValue
))
2108 error ("Must specify both x and y position, or neither");
2112 if (geometry
& XValue
)
2114 Lisp_Object element
;
2116 if (x
>= 0 && (geometry
& XNegative
))
2117 element
= Fcons (Qleft
, Fcons (Qminus
, Fcons (make_number (-x
), Qnil
)));
2118 else if (x
< 0 && ! (geometry
& XNegative
))
2119 element
= Fcons (Qleft
, Fcons (Qplus
, Fcons (make_number (x
), Qnil
)));
2121 element
= Fcons (Qleft
, make_number (x
));
2122 result
= Fcons (element
, result
);
2125 if (geometry
& YValue
)
2127 Lisp_Object element
;
2129 if (y
>= 0 && (geometry
& YNegative
))
2130 element
= Fcons (Qtop
, Fcons (Qminus
, Fcons (make_number (-y
), Qnil
)));
2131 else if (y
< 0 && ! (geometry
& YNegative
))
2132 element
= Fcons (Qtop
, Fcons (Qplus
, Fcons (make_number (y
), Qnil
)));
2134 element
= Fcons (Qtop
, make_number (y
));
2135 result
= Fcons (element
, result
);
2138 if (geometry
& WidthValue
)
2139 result
= Fcons (Fcons (Qwidth
, make_number (width
)), result
);
2140 if (geometry
& HeightValue
)
2141 result
= Fcons (Fcons (Qheight
, make_number (height
)), result
);
2146 /* Calculate the desired size and position of this window,
2147 and return the flags saying which aspects were specified.
2149 This function does not make the coordinates positive. */
2151 #define DEFAULT_ROWS 40
2152 #define DEFAULT_COLS 80
2155 x_figure_window_size (f
, parms
)
2159 register Lisp_Object tem0
, tem1
, tem2
;
2160 int height
, width
, left
, top
;
2161 register int geometry
;
2162 long window_prompting
= 0;
2164 /* Default values if we fall through.
2165 Actually, if that happens we should get
2166 window manager prompting. */
2167 f
->width
= DEFAULT_COLS
;
2168 f
->height
= DEFAULT_ROWS
;
2169 /* Window managers expect that if program-specified
2170 positions are not (0,0), they're intentional, not defaults. */
2171 f
->display
.x
->top_pos
= 0;
2172 f
->display
.x
->left_pos
= 0;
2174 tem0
= x_get_arg (parms
, Qheight
, 0, 0, number
);
2175 tem1
= x_get_arg (parms
, Qwidth
, 0, 0, number
);
2176 tem2
= x_get_arg (parms
, Quser_size
, 0, 0, number
);
2177 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
2179 if (!EQ (tem0
, Qunbound
))
2181 CHECK_NUMBER (tem0
, 0);
2182 f
->height
= XINT (tem0
);
2184 if (!EQ (tem1
, Qunbound
))
2186 CHECK_NUMBER (tem1
, 0);
2187 f
->width
= XINT (tem1
);
2189 if (!NILP (tem2
) && !EQ (tem2
, Qunbound
))
2190 window_prompting
|= USSize
;
2192 window_prompting
|= PSize
;
2195 f
->display
.x
->vertical_scroll_bar_extra
2196 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
2198 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0
2199 ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f
)
2200 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->display
.x
->font
)));
2201 f
->display
.x
->pixel_width
= CHAR_TO_PIXEL_WIDTH (f
, f
->width
);
2202 f
->display
.x
->pixel_height
= CHAR_TO_PIXEL_HEIGHT (f
, f
->height
);
2204 tem0
= x_get_arg (parms
, Qtop
, 0, 0, number
);
2205 tem1
= x_get_arg (parms
, Qleft
, 0, 0, number
);
2206 tem2
= x_get_arg (parms
, Quser_position
, 0, 0, number
);
2207 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
2209 if (EQ (tem0
, Qminus
))
2211 f
->display
.x
->top_pos
= 0;
2212 window_prompting
|= YNegative
;
2214 else if (CONSP (tem0
) && EQ (XCONS (tem0
)->car
, Qminus
)
2215 && CONSP (XCONS (tem0
)->cdr
)
2216 && INTEGERP (XCONS (XCONS (tem0
)->cdr
)->car
))
2218 f
->display
.x
->top_pos
= - XINT (XCONS (XCONS (tem0
)->cdr
)->car
);
2219 window_prompting
|= YNegative
;
2221 else if (CONSP (tem0
) && EQ (XCONS (tem0
)->car
, Qplus
)
2222 && CONSP (XCONS (tem0
)->cdr
)
2223 && INTEGERP (XCONS (XCONS (tem0
)->cdr
)->car
))
2225 f
->display
.x
->top_pos
= XINT (XCONS (XCONS (tem0
)->cdr
)->car
);
2227 else if (EQ (tem0
, Qunbound
))
2228 f
->display
.x
->top_pos
= 0;
2231 CHECK_NUMBER (tem0
, 0);
2232 f
->display
.x
->top_pos
= XINT (tem0
);
2233 if (f
->display
.x
->top_pos
< 0)
2234 window_prompting
|= YNegative
;
2237 if (EQ (tem1
, Qminus
))
2239 f
->display
.x
->left_pos
= 0;
2240 window_prompting
|= XNegative
;
2242 else if (CONSP (tem1
) && EQ (XCONS (tem1
)->car
, Qminus
)
2243 && CONSP (XCONS (tem1
)->cdr
)
2244 && INTEGERP (XCONS (XCONS (tem1
)->cdr
)->car
))
2246 f
->display
.x
->left_pos
= - XINT (XCONS (XCONS (tem1
)->cdr
)->car
);
2247 window_prompting
|= XNegative
;
2249 else if (CONSP (tem1
) && EQ (XCONS (tem1
)->car
, Qplus
)
2250 && CONSP (XCONS (tem1
)->cdr
)
2251 && INTEGERP (XCONS (XCONS (tem1
)->cdr
)->car
))
2253 f
->display
.x
->left_pos
= XINT (XCONS (XCONS (tem1
)->cdr
)->car
);
2255 else if (EQ (tem1
, Qunbound
))
2256 f
->display
.x
->left_pos
= 0;
2259 CHECK_NUMBER (tem1
, 0);
2260 f
->display
.x
->left_pos
= XINT (tem1
);
2261 if (f
->display
.x
->left_pos
< 0)
2262 window_prompting
|= XNegative
;
2265 if (!NILP (tem2
) && ! EQ (tem2
, Qunbound
))
2266 window_prompting
|= USPosition
;
2268 window_prompting
|= PPosition
;
2271 return window_prompting
;
2274 #if !defined (HAVE_X11R4) && !defined (HAVE_XSETWMPROTOCOLS)
2277 XSetWMProtocols (dpy
, w
, protocols
, count
)
2284 prop
= XInternAtom (dpy
, "WM_PROTOCOLS", False
);
2285 if (prop
== None
) return False
;
2286 XChangeProperty (dpy
, w
, prop
, XA_ATOM
, 32, PropModeReplace
,
2287 (unsigned char *) protocols
, count
);
2290 #endif /* not HAVE_X11R4 && not HAVE_XSETWMPROTOCOLS */
2292 #ifdef USE_X_TOOLKIT
2294 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
2295 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
2296 already be present because of the toolkit (Motif adds some of them,
2297 for example, but Xt doesn't). */
2300 hack_wm_protocols (f
, widget
)
2304 Display
*dpy
= XtDisplay (widget
);
2305 Window w
= XtWindow (widget
);
2306 int need_delete
= 1;
2312 Atom type
, *atoms
= 0;
2314 unsigned long nitems
= 0;
2315 unsigned long bytes_after
;
2317 if ((XGetWindowProperty (dpy
, w
,
2318 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2319 (long)0, (long)100, False
, XA_ATOM
,
2320 &type
, &format
, &nitems
, &bytes_after
,
2321 (unsigned char **) &atoms
)
2323 && format
== 32 && type
== XA_ATOM
)
2327 if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
)
2329 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
)
2331 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
)
2334 if (atoms
) XFree ((char *) atoms
);
2340 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2342 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
;
2344 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2346 XChangeProperty (dpy
, w
, FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2347 XA_ATOM
, 32, PropModeAppend
,
2348 (unsigned char *) props
, count
);
2354 #ifdef USE_X_TOOLKIT
2356 /* Create and set up the X widget for frame F. */
2359 x_window (f
, window_prompting
, minibuffer_only
)
2361 long window_prompting
;
2362 int minibuffer_only
;
2364 XClassHint class_hints
;
2365 XSetWindowAttributes attributes
;
2366 unsigned long attribute_mask
;
2368 Widget shell_widget
;
2370 Widget frame_widget
;
2376 /* Use the resource name as the top-level widget name
2377 for looking up resources. Make a non-Lisp copy
2378 for the window manager, so GC relocation won't bother it.
2380 Elsewhere we specify the window name for the window manager. */
2383 char *str
= (char *) XSTRING (Vx_resource_name
)->data
;
2384 f
->namebuf
= (char *) xmalloc (strlen (str
) + 1);
2385 strcpy (f
->namebuf
, str
);
2389 XtSetArg (al
[ac
], XtNallowShellResize
, 1); ac
++;
2390 XtSetArg (al
[ac
], XtNinput
, 1); ac
++;
2391 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2392 XtSetArg (al
[ac
], XtNborderWidth
, f
->display
.x
->border_width
); ac
++;
2393 shell_widget
= XtAppCreateShell (f
->namebuf
, EMACS_CLASS
,
2394 applicationShellWidgetClass
,
2395 FRAME_X_DISPLAY (f
), al
, ac
);
2397 f
->display
.x
->widget
= shell_widget
;
2398 /* maybe_set_screen_title_format (shell_widget); */
2400 pane_widget
= lw_create_widget ("main", "pane", widget_id_tick
++,
2401 (widget_value
*) NULL
,
2402 shell_widget
, False
,
2405 (lw_callback
) NULL
);
2407 f
->display
.x
->column_widget
= pane_widget
;
2409 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2410 the emacs screen when changing menubar. This reduces flickering. */
2413 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2414 XtSetArg (al
[ac
], XtNshowGrip
, 0); ac
++;
2415 XtSetArg (al
[ac
], XtNallowResize
, 1); ac
++;
2416 XtSetArg (al
[ac
], XtNresizeToPreferred
, 1); ac
++;
2417 XtSetArg (al
[ac
], XtNemacsFrame
, f
); ac
++;
2418 frame_widget
= XtCreateWidget (f
->namebuf
,
2420 pane_widget
, al
, ac
);
2422 f
->display
.x
->edit_widget
= frame_widget
;
2424 XtManageChild (frame_widget
);
2426 /* Do some needed geometry management. */
2429 char *tem
, shell_position
[32];
2433 = (f
->display
.x
->menubar_widget
2434 ? (f
->display
.x
->menubar_widget
->core
.height
2435 + f
->display
.x
->menubar_widget
->core
.border_width
)
2438 if (FRAME_EXTERNAL_MENU_BAR (f
))
2441 XtVaGetValues (pane_widget
, XtNinternalBorderWidth
, &ibw
, NULL
);
2442 menubar_size
+= ibw
;
2445 f
->display
.x
->menubar_height
= menubar_size
;
2447 /* Convert our geometry parameters into a geometry string
2449 Note that we do not specify here whether the position
2450 is a user-specified or program-specified one.
2451 We pass that information later, in x_wm_set_size_hints. */
2453 int left
= f
->display
.x
->left_pos
;
2454 int xneg
= window_prompting
& XNegative
;
2455 int top
= f
->display
.x
->top_pos
;
2456 int yneg
= window_prompting
& YNegative
;
2462 if (window_prompting
& USPosition
)
2463 sprintf (shell_position
, "=%dx%d%c%d%c%d", PIXEL_WIDTH (f
),
2464 PIXEL_HEIGHT (f
) + menubar_size
,
2465 (xneg
? '-' : '+'), left
,
2466 (yneg
? '-' : '+'), top
);
2468 sprintf (shell_position
, "=%dx%d", PIXEL_WIDTH (f
),
2469 PIXEL_HEIGHT (f
) + menubar_size
);
2472 len
= strlen (shell_position
) + 1;
2473 tem
= (char *) xmalloc (len
);
2474 strncpy (tem
, shell_position
, len
);
2475 XtSetArg (al
[ac
], XtNgeometry
, tem
); ac
++;
2476 XtSetValues (shell_widget
, al
, ac
);
2479 XtManageChild (pane_widget
);
2480 XtRealizeWidget (shell_widget
);
2482 FRAME_X_WINDOW (f
) = XtWindow (frame_widget
);
2484 validate_x_resource_name ();
2486 class_hints
.res_name
= (char *) XSTRING (Vx_resource_name
)->data
;
2487 class_hints
.res_class
= EMACS_CLASS
;
2488 XSetClassHint (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
), &class_hints
);
2490 f
->display
.x
->wm_hints
.input
= True
;
2491 f
->display
.x
->wm_hints
.flags
|= InputHint
;
2492 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2493 &f
->display
.x
->wm_hints
);
2495 hack_wm_protocols (f
, shell_widget
);
2498 XtAddEventHandler (shell_widget
, 0, True
, _XEditResCheckMessages
, 0);
2501 /* Do a stupid property change to force the server to generate a
2502 propertyNotify event so that the event_stream server timestamp will
2503 be initialized to something relevant to the time we created the window.
2505 XChangeProperty (XtDisplay (frame_widget
), XtWindow (frame_widget
),
2506 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2507 XA_ATOM
, 32, PropModeAppend
,
2508 (unsigned char*) NULL
, 0);
2510 /* Make all the standard events reach the Emacs frame. */
2511 attributes
.event_mask
= STANDARD_EVENT_SET
;
2512 attribute_mask
= CWEventMask
;
2513 XChangeWindowAttributes (XtDisplay (shell_widget
), XtWindow (shell_widget
),
2514 attribute_mask
, &attributes
);
2516 XtMapWidget (frame_widget
);
2518 /* x_set_name normally ignores requests to set the name if the
2519 requested name is the same as the current name. This is the one
2520 place where that assumption isn't correct; f->name is set, but
2521 the X server hasn't been told. */
2524 int explicit = f
->explicit_name
;
2526 f
->explicit_name
= 0;
2529 x_set_name (f
, name
, explicit);
2532 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2533 f
->display
.x
->text_cursor
);
2537 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
2538 initialize_frame_menubar (f
);
2539 lw_set_main_areas (pane_widget
, f
->display
.x
->menubar_widget
, frame_widget
);
2541 if (FRAME_X_WINDOW (f
) == 0)
2542 error ("Unable to create window");
2545 #else /* not USE_X_TOOLKIT */
2547 /* Create and set up the X window for frame F. */
2553 XClassHint class_hints
;
2554 XSetWindowAttributes attributes
;
2555 unsigned long attribute_mask
;
2557 attributes
.background_pixel
= f
->display
.x
->background_pixel
;
2558 attributes
.border_pixel
= f
->display
.x
->border_pixel
;
2559 attributes
.bit_gravity
= StaticGravity
;
2560 attributes
.backing_store
= NotUseful
;
2561 attributes
.save_under
= True
;
2562 attributes
.event_mask
= STANDARD_EVENT_SET
;
2563 attribute_mask
= (CWBackPixel
| CWBorderPixel
| CWBitGravity
2565 | CWBackingStore
| CWSaveUnder
2571 = XCreateWindow (FRAME_X_DISPLAY (f
),
2572 f
->display
.x
->parent_desc
,
2573 f
->display
.x
->left_pos
,
2574 f
->display
.x
->top_pos
,
2575 PIXEL_WIDTH (f
), PIXEL_HEIGHT (f
),
2576 f
->display
.x
->border_width
,
2577 CopyFromParent
, /* depth */
2578 InputOutput
, /* class */
2579 FRAME_X_DISPLAY_INFO (f
)->visual
,
2580 attribute_mask
, &attributes
);
2582 validate_x_resource_name ();
2584 class_hints
.res_name
= (char *) XSTRING (Vx_resource_name
)->data
;
2585 class_hints
.res_class
= EMACS_CLASS
;
2586 XSetClassHint (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &class_hints
);
2588 /* The menubar is part of the ordinary display;
2589 it does not count in addition to the height of the window. */
2590 f
->display
.x
->menubar_height
= 0;
2592 /* This indicates that we use the "Passive Input" input model.
2593 Unless we do this, we don't get the Focus{In,Out} events that we
2594 need to draw the cursor correctly. Accursed bureaucrats.
2595 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2597 f
->display
.x
->wm_hints
.input
= True
;
2598 f
->display
.x
->wm_hints
.flags
|= InputHint
;
2599 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2600 &f
->display
.x
->wm_hints
);
2602 /* Request "save yourself" and "delete window" commands from wm. */
2605 protocols
[0] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2606 protocols
[1] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2607 XSetWMProtocols (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), protocols
, 2);
2610 /* x_set_name normally ignores requests to set the name if the
2611 requested name is the same as the current name. This is the one
2612 place where that assumption isn't correct; f->name is set, but
2613 the X server hasn't been told. */
2616 int explicit = f
->explicit_name
;
2618 f
->explicit_name
= 0;
2621 x_set_name (f
, name
, explicit);
2624 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2625 f
->display
.x
->text_cursor
);
2629 if (FRAME_X_WINDOW (f
) == 0)
2630 error ("Unable to create window");
2633 #endif /* not USE_X_TOOLKIT */
2635 /* Handle the icon stuff for this window. Perhaps later we might
2636 want an x_set_icon_position which can be called interactively as
2644 Lisp_Object icon_x
, icon_y
;
2646 /* Set the position of the icon. Note that twm groups all
2647 icons in an icon window. */
2648 icon_x
= x_get_arg (parms
, Qicon_left
, 0, 0, number
);
2649 icon_y
= x_get_arg (parms
, Qicon_top
, 0, 0, number
);
2650 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2652 CHECK_NUMBER (icon_x
, 0);
2653 CHECK_NUMBER (icon_y
, 0);
2655 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2656 error ("Both left and top icon corners of icon must be specified");
2660 if (! EQ (icon_x
, Qunbound
))
2661 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
2663 /* Start up iconic or window? */
2664 x_wm_set_window_state
2665 (f
, (EQ (x_get_arg (parms
, Qvisibility
, 0, 0, symbol
), Qicon
)
2672 /* Make the GC's needed for this window, setting the
2673 background, border and mouse colors; also create the
2674 mouse cursor and the gray border tile. */
2676 static char cursor_bits
[] =
2678 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2679 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2680 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2681 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2688 XGCValues gc_values
;
2694 /* Create the GC's of this frame.
2695 Note that many default values are used. */
2698 gc_values
.font
= f
->display
.x
->font
->fid
;
2699 gc_values
.foreground
= f
->display
.x
->foreground_pixel
;
2700 gc_values
.background
= f
->display
.x
->background_pixel
;
2701 gc_values
.line_width
= 0; /* Means 1 using fast algorithm. */
2702 f
->display
.x
->normal_gc
= XCreateGC (FRAME_X_DISPLAY (f
),
2704 GCLineWidth
| GCFont
2705 | GCForeground
| GCBackground
,
2708 /* Reverse video style. */
2709 gc_values
.foreground
= f
->display
.x
->background_pixel
;
2710 gc_values
.background
= f
->display
.x
->foreground_pixel
;
2711 f
->display
.x
->reverse_gc
= XCreateGC (FRAME_X_DISPLAY (f
),
2713 GCFont
| GCForeground
| GCBackground
2717 /* Cursor has cursor-color background, background-color foreground. */
2718 gc_values
.foreground
= f
->display
.x
->background_pixel
;
2719 gc_values
.background
= f
->display
.x
->cursor_pixel
;
2720 gc_values
.fill_style
= FillOpaqueStippled
;
2722 = XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
2723 FRAME_X_DISPLAY_INFO (f
)->root_window
,
2724 cursor_bits
, 16, 16);
2725 f
->display
.x
->cursor_gc
2726 = XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2727 (GCFont
| GCForeground
| GCBackground
2728 | GCFillStyle
| GCStipple
| GCLineWidth
),
2731 /* Create the gray border tile used when the pointer is not in
2732 the frame. Since this depends on the frame's pixel values,
2733 this must be done on a per-frame basis. */
2734 f
->display
.x
->border_tile
2735 = (XCreatePixmapFromBitmapData
2736 (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
2737 gray_bits
, gray_width
, gray_height
,
2738 f
->display
.x
->foreground_pixel
,
2739 f
->display
.x
->background_pixel
,
2740 DefaultDepth (FRAME_X_DISPLAY (f
),
2741 XScreenNumberOfScreen (FRAME_X_SCREEN (f
)))));
2746 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
2748 "Make a new X window, which is called a \"frame\" in Emacs terms.\n\
2749 Returns an Emacs frame object.\n\
2750 ALIST is an alist of frame parameters.\n\
2751 If the parameters specify that the frame should not have a minibuffer,\n\
2752 and do not specify a specific minibuffer window to use,\n\
2753 then `default-minibuffer-frame' must be a frame whose minibuffer can\n\
2754 be shared by the new frame.\n\
2756 This function is an internal primitive--use `make-frame' instead.")
2761 Lisp_Object frame
, tem
;
2763 int minibuffer_only
= 0;
2764 long window_prompting
= 0;
2766 int count
= specpdl_ptr
- specpdl
;
2767 struct gcpro gcpro1
;
2768 Lisp_Object display
;
2769 struct x_display_info
*dpyinfo
;
2775 /* Use this general default value to start with
2776 until we know if this frame has a specified name. */
2777 Vx_resource_name
= Vinvocation_name
;
2779 display
= x_get_arg (parms
, Qdisplay
, 0, 0, 0);
2780 if (EQ (display
, Qunbound
))
2782 dpyinfo
= check_x_display_info (display
);
2784 kb
= dpyinfo
->kboard
;
2786 kb
= &the_only_kboard
;
2789 name
= x_get_arg (parms
, Qname
, "title", "Title", string
);
2791 && ! EQ (name
, Qunbound
)
2793 error ("Invalid frame name--not a string or nil");
2796 Vx_resource_name
= name
;
2798 /* See if parent window is specified. */
2799 parent
= x_get_arg (parms
, Qparent_id
, NULL
, NULL
, number
);
2800 if (EQ (parent
, Qunbound
))
2802 if (! NILP (parent
))
2803 CHECK_NUMBER (parent
, 0);
2805 tem
= x_get_arg (parms
, Qminibuffer
, 0, 0, symbol
);
2806 if (EQ (tem
, Qnone
) || NILP (tem
))
2807 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
2808 else if (EQ (tem
, Qonly
))
2810 f
= make_minibuffer_frame ();
2811 minibuffer_only
= 1;
2813 else if (WINDOWP (tem
))
2814 f
= make_frame_without_minibuffer (tem
, kb
, display
);
2818 /* Note that X Windows does support scroll bars. */
2819 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
2821 XSETFRAME (frame
, f
);
2824 f
->output_method
= output_x_window
;
2825 f
->display
.x
= (struct x_display
*) xmalloc (sizeof (struct x_display
));
2826 bzero (f
->display
.x
, sizeof (struct x_display
));
2827 f
->display
.x
->icon_bitmap
= -1;
2829 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
2831 FRAME_KBOARD (f
) = kb
;
2834 /* Specify the parent under which to make this X window. */
2838 f
->display
.x
->parent_desc
= parent
;
2839 f
->display
.x
->explicit_parent
= 1;
2843 f
->display
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
2844 f
->display
.x
->explicit_parent
= 0;
2847 /* Note that the frame has no physical cursor right now. */
2848 f
->phys_cursor_x
= -1;
2850 /* Set the name; the functions to which we pass f expect the name to
2852 if (EQ (name
, Qunbound
) || NILP (name
))
2854 f
->name
= build_string (dpyinfo
->x_id_name
);
2855 f
->explicit_name
= 0;
2860 f
->explicit_name
= 1;
2861 /* use the frame's title when getting resources for this frame. */
2862 specbind (Qx_resource_name
, name
);
2865 /* Extract the window parameters from the supplied values
2866 that are needed to determine window geometry. */
2870 font
= x_get_arg (parms
, Qfont
, "font", "Font", string
);
2872 /* First, try whatever font the caller has specified. */
2874 font
= x_new_font (f
, XSTRING (font
)->data
);
2875 /* Try out a font which we hope has bold and italic variations. */
2876 if (!STRINGP (font
))
2877 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
2878 if (! STRINGP (font
))
2879 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
2880 if (! STRINGP (font
))
2881 /* This was formerly the first thing tried, but it finds too many fonts
2882 and takes too long. */
2883 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
2884 /* If those didn't work, look for something which will at least work. */
2885 if (! STRINGP (font
))
2886 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
2888 if (! STRINGP (font
))
2889 font
= build_string ("fixed");
2891 x_default_parameter (f
, parms
, Qfont
, font
,
2892 "font", "Font", string
);
2895 #ifdef USE_X_TOOLKIT
2896 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
2897 whereby it fails to get any font. */
2898 xlwmenu_default_font
= f
->display
.x
->font
;
2901 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
2902 "borderwidth", "BorderWidth", number
);
2903 /* This defaults to 2 in order to match xterm. We recognize either
2904 internalBorderWidth or internalBorder (which is what xterm calls
2906 if (NILP (Fassq (Qinternal_border_width
, parms
)))
2910 value
= x_get_arg (parms
, Qinternal_border_width
,
2911 "internalBorder", "BorderWidth", number
);
2912 if (! EQ (value
, Qunbound
))
2913 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
2916 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (2),
2917 "internalBorderWidth", "BorderWidth", number
);
2918 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qt
,
2919 "verticalScrollBars", "ScrollBars", boolean
);
2921 /* Also do the stuff which must be set before the window exists. */
2922 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
2923 "foreground", "Foreground", string
);
2924 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
2925 "background", "Background", string
);
2926 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
2927 "pointerColor", "Foreground", string
);
2928 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
2929 "cursorColor", "Foreground", string
);
2930 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
2931 "borderColor", "BorderColor", string
);
2933 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
2934 "menuBar", "MenuBar", number
);
2935 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
2936 "scrollBarWidth", "ScrollBarWidth", number
);
2938 f
->display
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
2939 window_prompting
= x_figure_window_size (f
, parms
);
2941 if (window_prompting
& XNegative
)
2943 if (window_prompting
& YNegative
)
2944 f
->display
.x
->win_gravity
= SouthEastGravity
;
2946 f
->display
.x
->win_gravity
= NorthEastGravity
;
2950 if (window_prompting
& YNegative
)
2951 f
->display
.x
->win_gravity
= SouthWestGravity
;
2953 f
->display
.x
->win_gravity
= NorthWestGravity
;
2956 f
->display
.x
->size_hint_flags
= window_prompting
;
2958 #ifdef USE_X_TOOLKIT
2959 x_window (f
, window_prompting
, minibuffer_only
);
2965 init_frame_faces (f
);
2967 /* We need to do this after creating the X window, so that the
2968 icon-creation functions can say whose icon they're describing. */
2969 x_default_parameter (f
, parms
, Qicon_type
, Qnil
,
2970 "bitmapIcon", "BitmapIcon", symbol
);
2972 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
2973 "autoRaise", "AutoRaiseLower", boolean
);
2974 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
2975 "autoLower", "AutoRaiseLower", boolean
);
2976 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
2977 "cursorType", "CursorType", symbol
);
2979 /* Dimensions, especially f->height, must be done via change_frame_size.
2980 Change will not be effected unless different from the current
2984 f
->height
= f
->width
= 0;
2985 change_frame_size (f
, height
, width
, 1, 0);
2987 /* Tell the server what size and position, etc, we want,
2988 and how badly we want them. */
2990 x_wm_set_size_hint (f
, window_prompting
, 0);
2993 tem
= x_get_arg (parms
, Qunsplittable
, 0, 0, boolean
);
2994 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
2998 /* It is now ok to make the frame official
2999 even if we get an error below.
3000 And the frame needs to be on Vframe_list
3001 or making it visible won't work. */
3002 Vframe_list
= Fcons (frame
, Vframe_list
);
3004 /* Now that the frame is official, it counts as a reference to
3006 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
3008 /* Make the window appear on the frame and enable display,
3009 unless the caller says not to. However, with explicit parent,
3010 Emacs cannot control visibility, so don't try. */
3011 if (! f
->display
.x
->explicit_parent
)
3013 Lisp_Object visibility
;
3015 visibility
= x_get_arg (parms
, Qvisibility
, 0, 0, symbol
);
3016 if (EQ (visibility
, Qunbound
))
3019 if (EQ (visibility
, Qicon
))
3020 x_iconify_frame (f
);
3021 else if (! NILP (visibility
))
3022 x_make_frame_visible (f
);
3024 /* Must have been Qnil. */
3028 return unbind_to (count
, frame
);
3031 /* FRAME is used only to get a handle on the X display. We don't pass the
3032 display info directly because we're called from frame.c, which doesn't
3033 know about that structure. */
3035 x_get_focus_frame (frame
)
3036 struct frame
*frame
;
3038 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (frame
);
3040 if (! dpyinfo
->x_focus_frame
)
3043 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
3047 DEFUN ("focus-frame", Ffocus_frame
, Sfocus_frame
, 1, 1, 0,
3048 "Set the focus on FRAME.")
3052 CHECK_LIVE_FRAME (frame
, 0);
3054 if (FRAME_X_P (XFRAME (frame
)))
3057 x_focus_on_frame (XFRAME (frame
));
3065 DEFUN ("unfocus-frame", Funfocus_frame
, Sunfocus_frame
, 0, 0, 0,
3066 "If a frame has been focused, release it.")
3069 if (FRAME_X_P (selected_frame
))
3071 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (selected_frame
);
3073 if (dpyinfo
->x_focus_frame
)
3076 x_unfocus_frame (dpyinfo
->x_focus_frame
);
3084 DEFUN ("x-list-fonts", Fx_list_fonts
, Sx_list_fonts
, 1, 3, 0,
3085 "Return a list of the names of available fonts matching PATTERN.\n\
3086 If optional arguments FACE and FRAME are specified, return only fonts\n\
3087 the same size as FACE on FRAME.\n\
3089 PATTERN is a string, perhaps with wildcard characters;\n\
3090 the * character matches any substring, and\n\
3091 the ? character matches any single character.\n\
3092 PATTERN is case-insensitive.\n\
3093 FACE is a face name--a symbol.\n\
3095 The return value is a list of strings, suitable as arguments to\n\
3098 Fonts Emacs can't use (i.e. proportional fonts) may or may not be excluded\n\
3099 even if they match PATTERN and FACE.")
3100 (pattern
, face
, frame
)
3101 Lisp_Object pattern
, face
, frame
;
3105 #ifndef BROKEN_XLISTFONTSWITHINFO
3108 XFontStruct
*size_ref
;
3113 CHECK_STRING (pattern
, 0);
3115 CHECK_SYMBOL (face
, 1);
3117 f
= check_x_frame (frame
);
3119 /* Determine the width standard for comparison with the fonts we find. */
3127 /* Don't die if we get called with a terminal frame. */
3128 if (! FRAME_X_P (f
))
3129 error ("non-X frame used in `x-list-fonts'");
3131 face_id
= face_name_id_number (f
, face
);
3133 if (face_id
< 0 || face_id
>= FRAME_N_PARAM_FACES (f
)
3134 || FRAME_PARAM_FACES (f
) [face_id
] == 0)
3135 size_ref
= f
->display
.x
->font
;
3138 size_ref
= FRAME_PARAM_FACES (f
) [face_id
]->font
;
3139 if (size_ref
== (XFontStruct
*) (~0))
3140 size_ref
= f
->display
.x
->font
;
3144 /* See if we cached the result for this particular query. */
3145 list
= Fassoc (pattern
,
3146 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
);
3148 /* We have info in the cache for this PATTERN. */
3151 Lisp_Object tem
, newlist
;
3153 /* We have info about this pattern. */
3154 list
= XCONS (list
)->cdr
;
3161 /* Filter the cached info and return just the fonts that match FACE. */
3163 for (tem
= list
; CONSP (tem
); tem
= XCONS (tem
)->cdr
)
3165 XFontStruct
*thisinfo
;
3167 thisinfo
= XLoadQueryFont (FRAME_X_DISPLAY (f
),
3168 XSTRING (XCONS (tem
)->car
)->data
);
3170 if (thisinfo
&& same_size_fonts (thisinfo
, size_ref
))
3171 newlist
= Fcons (XCONS (tem
)->car
, newlist
);
3173 XFreeFont (FRAME_X_DISPLAY (f
), thisinfo
);
3183 /* Solaris 2.3 has a bug in XListFontsWithInfo. */
3184 #ifndef BROKEN_XLISTFONTSWITHINFO
3186 names
= XListFontsWithInfo (FRAME_X_DISPLAY (f
),
3187 XSTRING (pattern
)->data
,
3188 2000, /* maxnames */
3189 &num_fonts
, /* count_return */
3190 &info
); /* info_return */
3193 names
= XListFonts (FRAME_X_DISPLAY (f
),
3194 XSTRING (pattern
)->data
,
3195 2000, /* maxnames */
3196 &num_fonts
); /* count_return */
3205 Lisp_Object full_list
;
3207 /* Make a list of all the fonts we got back.
3208 Store that in the font cache for the display. */
3210 for (i
= 0; i
< num_fonts
; i
++)
3211 full_list
= Fcons (build_string (names
[i
]), full_list
);
3212 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
3213 = Fcons (Fcons (pattern
, full_list
),
3214 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
);
3216 /* Make a list of the fonts that have the right width. */
3218 for (i
= 0; i
< num_fonts
; i
++)
3226 #ifdef BROKEN_XLISTFONTSWITHINFO
3227 XFontStruct
*thisinfo
;
3230 thisinfo
= XLoadQueryFont (FRAME_X_DISPLAY (f
), names
[i
]);
3233 keeper
= thisinfo
&& same_size_fonts (thisinfo
, size_ref
);
3235 keeper
= same_size_fonts (&info
[i
], size_ref
);
3239 list
= Fcons (build_string (names
[i
]), list
);
3241 list
= Fnreverse (list
);
3244 #ifndef BROKEN_XLISTFONTSWITHINFO
3246 XFreeFontInfo (names
, info
, num_fonts
);
3249 XFreeFontNames (names
);
3257 DEFUN ("x-color-defined-p", Fx_color_defined_p
, Sx_color_defined_p
, 1, 2, 0,
3258 "Return non-nil if color COLOR is supported on frame FRAME.\n\
3259 If FRAME is omitted or nil, use the selected frame.")
3261 Lisp_Object color
, frame
;
3264 FRAME_PTR f
= check_x_frame (frame
);
3266 CHECK_STRING (color
, 1);
3268 if (defined_color (f
, XSTRING (color
)->data
, &foo
, 0))
3274 DEFUN ("x-color-values", Fx_color_values
, Sx_color_values
, 1, 2, 0,
3275 "Return a description of the color named COLOR on frame FRAME.\n\
3276 The value is a list of integer RGB values--(RED GREEN BLUE).\n\
3277 These values appear to range from 0 to 65280 or 65535, depending\n\
3278 on the system; white is (65280 65280 65280) or (65535 65535 65535).\n\
3279 If FRAME is omitted or nil, use the selected frame.")
3281 Lisp_Object color
, frame
;
3284 FRAME_PTR f
= check_x_frame (frame
);
3286 CHECK_STRING (color
, 1);
3288 if (defined_color (f
, XSTRING (color
)->data
, &foo
, 0))
3292 rgb
[0] = make_number (foo
.red
);
3293 rgb
[1] = make_number (foo
.green
);
3294 rgb
[2] = make_number (foo
.blue
);
3295 return Flist (3, rgb
);
3301 DEFUN ("x-display-color-p", Fx_display_color_p
, Sx_display_color_p
, 0, 1, 0,
3302 "Return t if the X display supports color.\n\
3303 The optional argument DISPLAY specifies which display to ask about.\n\
3304 DISPLAY should be either a frame or a display name (a string).\n\
3305 If omitted or nil, that stands for the selected frame's display.")
3307 Lisp_Object display
;
3309 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3311 if (dpyinfo
->n_planes
<= 2)
3314 switch (dpyinfo
->visual
->class)
3327 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
3329 "Return t if the X display supports shades of gray.\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 if (dpyinfo
->n_planes
<= 2)
3341 return (dpyinfo
->n_planes
> 1
3342 && (dpyinfo
->visual
->class == StaticGray
3343 || dpyinfo
->visual
->class == GrayScale
));
3346 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
3348 "Returns the width in pixels of the X display DISPLAY.\n\
3349 The optional argument DISPLAY specifies which display to ask about.\n\
3350 DISPLAY should be either a frame or a display name (a string).\n\
3351 If omitted or nil, that stands for the selected frame's display.")
3353 Lisp_Object display
;
3355 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3357 return make_number (dpyinfo
->width
);
3360 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
3361 Sx_display_pixel_height
, 0, 1, 0,
3362 "Returns the height in pixels of the X display DISPLAY.\n\
3363 The optional argument DISPLAY specifies which display to ask about.\n\
3364 DISPLAY should be either a frame or a display name (a string).\n\
3365 If omitted or nil, that stands for the selected frame's display.")
3367 Lisp_Object display
;
3369 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3371 return make_number (dpyinfo
->height
);
3374 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
3376 "Returns the number of bitplanes of the X 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 (dpyinfo
->n_planes
);
3388 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
3390 "Returns the number of color cells of the X display DISPLAY.\n\
3391 The optional argument DISPLAY specifies which display to ask about.\n\
3392 DISPLAY should be either a frame or a display name (a string).\n\
3393 If omitted or nil, that stands for the selected frame's display.")
3395 Lisp_Object display
;
3397 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3399 return make_number (DisplayCells (dpyinfo
->display
,
3400 XScreenNumberOfScreen (dpyinfo
->screen
)));
3403 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
3404 Sx_server_max_request_size
,
3406 "Returns the maximum request size of the X server of display DISPLAY.\n\
3407 The optional argument DISPLAY specifies which display to ask about.\n\
3408 DISPLAY should be either a frame or a display name (a string).\n\
3409 If omitted or nil, that stands for the selected frame's display.")
3411 Lisp_Object display
;
3413 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3415 return make_number (MAXREQUEST (dpyinfo
->display
));
3418 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
3419 "Returns the vendor ID string of the X server of display DISPLAY.\n\
3420 The optional argument DISPLAY specifies which display to ask about.\n\
3421 DISPLAY should be either a frame or a display name (a string).\n\
3422 If omitted or nil, that stands for the selected frame's display.")
3424 Lisp_Object display
;
3426 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3427 char *vendor
= ServerVendor (dpyinfo
->display
);
3429 if (! vendor
) vendor
= "";
3430 return build_string (vendor
);
3433 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
3434 "Returns the version numbers of the X server of display DISPLAY.\n\
3435 The value is a list of three integers: the major and minor\n\
3436 version numbers of the X Protocol in use, and the vendor-specific release\n\
3437 number. See also the function `x-server-vendor'.\n\n\
3438 The optional argument DISPLAY specifies which display to ask about.\n\
3439 DISPLAY should be either a frame or a display name (a string).\n\
3440 If omitted or nil, that stands for the selected frame's display.")
3442 Lisp_Object display
;
3444 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3445 Display
*dpy
= dpyinfo
->display
;
3447 return Fcons (make_number (ProtocolVersion (dpy
)),
3448 Fcons (make_number (ProtocolRevision (dpy
)),
3449 Fcons (make_number (VendorRelease (dpy
)), Qnil
)));
3452 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
3453 "Returns the number of screens on the X server of display DISPLAY.\n\
3454 The optional argument DISPLAY specifies which display to ask about.\n\
3455 DISPLAY should be either a frame or a display name (a string).\n\
3456 If omitted or nil, that stands for the selected frame's display.")
3458 Lisp_Object display
;
3460 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3462 return make_number (ScreenCount (dpyinfo
->display
));
3465 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
3466 "Returns the height in millimeters of the X display DISPLAY.\n\
3467 The optional argument DISPLAY specifies which display to ask about.\n\
3468 DISPLAY should be either a frame or a display name (a string).\n\
3469 If omitted or nil, that stands for the selected frame's display.")
3471 Lisp_Object display
;
3473 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3475 return make_number (HeightMMOfScreen (dpyinfo
->screen
));
3478 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
3479 "Returns the width in millimeters of the X display DISPLAY.\n\
3480 The optional argument DISPLAY specifies which display to ask about.\n\
3481 DISPLAY should be either a frame or a display name (a string).\n\
3482 If omitted or nil, that stands for the selected frame's display.")
3484 Lisp_Object display
;
3486 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3488 return make_number (WidthMMOfScreen (dpyinfo
->screen
));
3491 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
3492 Sx_display_backing_store
, 0, 1, 0,
3493 "Returns an indication of whether X display DISPLAY does backing store.\n\
3494 The value may be `always', `when-mapped', or `not-useful'.\n\
3495 The optional argument DISPLAY specifies which display to ask about.\n\
3496 DISPLAY should be either a frame or a display name (a string).\n\
3497 If omitted or nil, that stands for the selected frame's display.")
3499 Lisp_Object display
;
3501 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3503 switch (DoesBackingStore (dpyinfo
->screen
))
3506 return intern ("always");
3509 return intern ("when-mapped");
3512 return intern ("not-useful");
3515 error ("Strange value for BackingStore parameter of screen");
3519 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
3520 Sx_display_visual_class
, 0, 1, 0,
3521 "Returns the visual class of the X display DISPLAY.\n\
3522 The value is one of the symbols `static-gray', `gray-scale',\n\
3523 `static-color', `pseudo-color', `true-color', or `direct-color'.\n\n\
3524 The optional argument DISPLAY specifies which display to ask about.\n\
3525 DISPLAY should be either a frame or a display name (a string).\n\
3526 If omitted or nil, that stands for the selected frame's display.")
3528 Lisp_Object display
;
3530 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3532 switch (dpyinfo
->visual
->class)
3534 case StaticGray
: return (intern ("static-gray"));
3535 case GrayScale
: return (intern ("gray-scale"));
3536 case StaticColor
: return (intern ("static-color"));
3537 case PseudoColor
: return (intern ("pseudo-color"));
3538 case TrueColor
: return (intern ("true-color"));
3539 case DirectColor
: return (intern ("direct-color"));
3541 error ("Display has an unknown visual class");
3545 DEFUN ("x-display-save-under", Fx_display_save_under
,
3546 Sx_display_save_under
, 0, 1, 0,
3547 "Returns t if the X display DISPLAY supports the save-under feature.\n\
3548 The optional argument DISPLAY specifies which display to ask about.\n\
3549 DISPLAY should be either a frame or a display name (a string).\n\
3550 If omitted or nil, that stands for the selected frame's display.")
3552 Lisp_Object display
;
3554 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3556 if (DoesSaveUnders (dpyinfo
->screen
) == True
)
3564 register struct frame
*f
;
3566 return PIXEL_WIDTH (f
);
3571 register struct frame
*f
;
3573 return PIXEL_HEIGHT (f
);
3578 register struct frame
*f
;
3580 return FONT_WIDTH (f
->display
.x
->font
);
3585 register struct frame
*f
;
3587 return f
->display
.x
->line_height
;
3591 x_screen_planes (frame
)
3594 return FRAME_X_DISPLAY_INFO (XFRAME (frame
))->n_planes
;
3597 #if 0 /* These no longer seem like the right way to do things. */
3599 /* Draw a rectangle on the frame with left top corner including
3600 the character specified by LEFT_CHAR and TOP_CHAR. The rectangle is
3601 CHARS by LINES wide and long and is the color of the cursor. */
3604 x_rectangle (f
, gc
, left_char
, top_char
, chars
, lines
)
3605 register struct frame
*f
;
3607 register int top_char
, left_char
, chars
, lines
;
3611 int left
= (left_char
* FONT_WIDTH (f
->display
.x
->font
)
3612 + f
->display
.x
->internal_border_width
);
3613 int top
= (top_char
* f
->display
.x
->line_height
3614 + f
->display
.x
->internal_border_width
);
3617 width
= FONT_WIDTH (f
->display
.x
->font
) / 2;
3619 width
= FONT_WIDTH (f
->display
.x
->font
) * chars
;
3621 height
= f
->display
.x
->line_height
/ 2;
3623 height
= f
->display
.x
->line_height
* lines
;
3625 XDrawRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3626 gc
, left
, top
, width
, height
);
3629 DEFUN ("x-draw-rectangle", Fx_draw_rectangle
, Sx_draw_rectangle
, 5, 5, 0,
3630 "Draw a rectangle on FRAME between coordinates specified by\n\
3631 numbers X0, Y0, X1, Y1 in the cursor pixel.")
3632 (frame
, X0
, Y0
, X1
, Y1
)
3633 register Lisp_Object frame
, X0
, X1
, Y0
, Y1
;
3635 register int x0
, y0
, x1
, y1
, top
, left
, n_chars
, n_lines
;
3637 CHECK_LIVE_FRAME (frame
, 0);
3638 CHECK_NUMBER (X0
, 0);
3639 CHECK_NUMBER (Y0
, 1);
3640 CHECK_NUMBER (X1
, 2);
3641 CHECK_NUMBER (Y1
, 3);
3651 n_lines
= y1
- y0
+ 1;
3656 n_lines
= y0
- y1
+ 1;
3662 n_chars
= x1
- x0
+ 1;
3667 n_chars
= x0
- x1
+ 1;
3671 x_rectangle (XFRAME (frame
), XFRAME (frame
)->display
.x
->cursor_gc
,
3672 left
, top
, n_chars
, n_lines
);
3678 DEFUN ("x-erase-rectangle", Fx_erase_rectangle
, Sx_erase_rectangle
, 5, 5, 0,
3679 "Draw a rectangle drawn on FRAME between coordinates\n\
3680 X0, Y0, X1, Y1 in the regular background-pixel.")
3681 (frame
, X0
, Y0
, X1
, Y1
)
3682 register Lisp_Object frame
, X0
, Y0
, X1
, Y1
;
3684 register int x0
, y0
, x1
, y1
, top
, left
, n_chars
, n_lines
;
3686 CHECK_LIVE_FRAME (frame
, 0);
3687 CHECK_NUMBER (X0
, 0);
3688 CHECK_NUMBER (Y0
, 1);
3689 CHECK_NUMBER (X1
, 2);
3690 CHECK_NUMBER (Y1
, 3);
3700 n_lines
= y1
- y0
+ 1;
3705 n_lines
= y0
- y1
+ 1;
3711 n_chars
= x1
- x0
+ 1;
3716 n_chars
= x0
- x1
+ 1;
3720 x_rectangle (XFRAME (frame
), XFRAME (frame
)->display
.x
->reverse_gc
,
3721 left
, top
, n_chars
, n_lines
);
3727 /* Draw lines around the text region beginning at the character position
3728 TOP_X, TOP_Y and ending at BOTTOM_X and BOTTOM_Y. GC specifies the
3729 pixel and line characteristics. */
3731 #define line_len(line) (FRAME_CURRENT_GLYPHS (f)->used[(line)])
3734 outline_region (f
, gc
, top_x
, top_y
, bottom_x
, bottom_y
)
3735 register struct frame
*f
;
3737 int top_x
, top_y
, bottom_x
, bottom_y
;
3739 register int ibw
= f
->display
.x
->internal_border_width
;
3740 register int font_w
= FONT_WIDTH (f
->display
.x
->font
);
3741 register int font_h
= f
->display
.x
->line_height
;
3743 int x
= line_len (y
);
3744 XPoint
*pixel_points
3745 = (XPoint
*) alloca (((bottom_y
- top_y
+ 2) * 4) * sizeof (XPoint
));
3746 register XPoint
*this_point
= pixel_points
;
3748 /* Do the horizontal top line/lines */
3751 this_point
->x
= ibw
;
3752 this_point
->y
= ibw
+ (font_h
* top_y
);
3755 this_point
->x
= ibw
+ (font_w
/ 2); /* Half-size for newline chars. */
3757 this_point
->x
= ibw
+ (font_w
* x
);
3758 this_point
->y
= (this_point
- 1)->y
;
3762 this_point
->x
= ibw
;
3763 this_point
->y
= ibw
+ (font_h
* (top_y
+ 1));
3765 this_point
->x
= ibw
+ (font_w
* top_x
);
3766 this_point
->y
= (this_point
- 1)->y
;
3768 this_point
->x
= (this_point
- 1)->x
;
3769 this_point
->y
= ibw
+ (font_h
* top_y
);
3771 this_point
->x
= ibw
+ (font_w
* x
);
3772 this_point
->y
= (this_point
- 1)->y
;
3775 /* Now do the right side. */
3776 while (y
< bottom_y
)
3777 { /* Right vertical edge */
3779 this_point
->x
= (this_point
- 1)->x
;
3780 this_point
->y
= ibw
+ (font_h
* (y
+ 1));
3783 y
++; /* Horizontal connection to next line */
3786 this_point
->x
= ibw
+ (font_w
/ 2);
3788 this_point
->x
= ibw
+ (font_w
* x
);
3790 this_point
->y
= (this_point
- 1)->y
;
3793 /* Now do the bottom and connect to the top left point. */
3794 this_point
->x
= ibw
+ (font_w
* (bottom_x
+ 1));
3797 this_point
->x
= (this_point
- 1)->x
;
3798 this_point
->y
= ibw
+ (font_h
* (bottom_y
+ 1));
3800 this_point
->x
= ibw
;
3801 this_point
->y
= (this_point
- 1)->y
;
3803 this_point
->x
= pixel_points
->x
;
3804 this_point
->y
= pixel_points
->y
;
3806 XDrawLines (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3808 (this_point
- pixel_points
+ 1), CoordModeOrigin
);
3811 DEFUN ("x-contour-region", Fx_contour_region
, Sx_contour_region
, 1, 1, 0,
3812 "Highlight the region between point and the character under the mouse\n\
3815 register Lisp_Object event
;
3817 register int x0
, y0
, x1
, y1
;
3818 register struct frame
*f
= selected_frame
;
3819 register int p1
, p2
;
3821 CHECK_CONS (event
, 0);
3824 x0
= XINT (Fcar (Fcar (event
)));
3825 y0
= XINT (Fcar (Fcdr (Fcar (event
))));
3827 /* If the mouse is past the end of the line, don't that area. */
3828 /* ReWrite this... */
3833 if (y1
> y0
) /* point below mouse */
3834 outline_region (f
, f
->display
.x
->cursor_gc
,
3836 else if (y1
< y0
) /* point above mouse */
3837 outline_region (f
, f
->display
.x
->cursor_gc
,
3839 else /* same line: draw horizontal rectangle */
3842 x_rectangle (f
, f
->display
.x
->cursor_gc
,
3843 x0
, y0
, (x1
- x0
+ 1), 1);
3845 x_rectangle (f
, f
->display
.x
->cursor_gc
,
3846 x1
, y1
, (x0
- x1
+ 1), 1);
3849 XFlush (FRAME_X_DISPLAY (f
));
3855 DEFUN ("x-uncontour-region", Fx_uncontour_region
, Sx_uncontour_region
, 1, 1, 0,
3856 "Erase any highlighting of the region between point and the character\n\
3857 at X, Y on the selected frame.")
3859 register Lisp_Object event
;
3861 register int x0
, y0
, x1
, y1
;
3862 register struct frame
*f
= selected_frame
;
3865 x0
= XINT (Fcar (Fcar (event
)));
3866 y0
= XINT (Fcar (Fcdr (Fcar (event
))));
3870 if (y1
> y0
) /* point below mouse */
3871 outline_region (f
, f
->display
.x
->reverse_gc
,
3873 else if (y1
< y0
) /* point above mouse */
3874 outline_region (f
, f
->display
.x
->reverse_gc
,
3876 else /* same line: draw horizontal rectangle */
3879 x_rectangle (f
, f
->display
.x
->reverse_gc
,
3880 x0
, y0
, (x1
- x0
+ 1), 1);
3882 x_rectangle (f
, f
->display
.x
->reverse_gc
,
3883 x1
, y1
, (x0
- x1
+ 1), 1);
3891 int contour_begin_x
, contour_begin_y
;
3892 int contour_end_x
, contour_end_y
;
3893 int contour_npoints
;
3895 /* Clip the top part of the contour lines down (and including) line Y_POS.
3896 If X_POS is in the middle (rather than at the end) of the line, drop
3897 down a line at that character. */
3900 clip_contour_top (y_pos
, x_pos
)
3902 register XPoint
*begin
= contour_lines
[y_pos
].top_left
;
3903 register XPoint
*end
;
3904 register int npoints
;
3905 register struct display_line
*line
= selected_frame
->phys_lines
[y_pos
+ 1];
3907 if (x_pos
>= line
->len
- 1) /* Draw one, straight horizontal line. */
3909 end
= contour_lines
[y_pos
].top_right
;
3910 npoints
= (end
- begin
+ 1);
3911 XDrawLines (x_current_display
, contour_window
,
3912 contour_erase_gc
, begin_erase
, npoints
, CoordModeOrigin
);
3914 bcopy (end
, begin
+ 1, contour_last_point
- end
+ 1);
3915 contour_last_point
-= (npoints
- 2);
3916 XDrawLines (x_current_display
, contour_window
,
3917 contour_erase_gc
, begin
, 2, CoordModeOrigin
);
3918 XFlush (x_current_display
);
3920 /* Now, update contour_lines structure. */
3925 register XPoint
*p
= begin
+ 1;
3926 end
= contour_lines
[y_pos
].bottom_right
;
3927 npoints
= (end
- begin
+ 1);
3928 XDrawLines (x_current_display
, contour_window
,
3929 contour_erase_gc
, begin_erase
, npoints
, CoordModeOrigin
);
3932 p
->x
= ibw
+ (font_w
* (x_pos
+ 1));
3934 p
->y
= begin
->y
+ font_h
;
3936 bcopy (end
, begin
+ 3, contour_last_point
- end
+ 1);
3937 contour_last_point
-= (npoints
- 5);
3938 XDrawLines (x_current_display
, contour_window
,
3939 contour_erase_gc
, begin
, 4, CoordModeOrigin
);
3940 XFlush (x_current_display
);
3942 /* Now, update contour_lines structure. */
3946 /* Erase the top horizontal lines of the contour, and then extend
3947 the contour upwards. */
3950 extend_contour_top (line
)
3955 clip_contour_bottom (x_pos
, y_pos
)
3961 extend_contour_bottom (x_pos
, y_pos
)
3965 DEFUN ("x-select-region", Fx_select_region
, Sx_select_region
, 1, 1, "e",
3970 register struct frame
*f
= selected_frame
;
3971 register int point_x
= f
->cursor_x
;
3972 register int point_y
= f
->cursor_y
;
3973 register int mouse_below_point
;
3974 register Lisp_Object obj
;
3975 register int x_contour_x
, x_contour_y
;
3977 x_contour_x
= x_mouse_x
;
3978 x_contour_y
= x_mouse_y
;
3979 if (x_contour_y
> point_y
|| (x_contour_y
== point_y
3980 && x_contour_x
> point_x
))
3982 mouse_below_point
= 1;
3983 outline_region (f
, f
->display
.x
->cursor_gc
, point_x
, point_y
,
3984 x_contour_x
, x_contour_y
);
3988 mouse_below_point
= 0;
3989 outline_region (f
, f
->display
.x
->cursor_gc
, x_contour_x
, x_contour_y
,
3995 obj
= read_char (-1, 0, 0, Qnil
, 0);
3999 if (mouse_below_point
)
4001 if (x_mouse_y
<= point_y
) /* Flipped. */
4003 mouse_below_point
= 0;
4005 outline_region (f
, f
->display
.x
->reverse_gc
, point_x
, point_y
,
4006 x_contour_x
, x_contour_y
);
4007 outline_region (f
, f
->display
.x
->cursor_gc
, x_mouse_x
, x_mouse_y
,
4010 else if (x_mouse_y
< x_contour_y
) /* Bottom clipped. */
4012 clip_contour_bottom (x_mouse_y
);
4014 else if (x_mouse_y
> x_contour_y
) /* Bottom extended. */
4016 extend_bottom_contour (x_mouse_y
);
4019 x_contour_x
= x_mouse_x
;
4020 x_contour_y
= x_mouse_y
;
4022 else /* mouse above or same line as point */
4024 if (x_mouse_y
>= point_y
) /* Flipped. */
4026 mouse_below_point
= 1;
4028 outline_region (f
, f
->display
.x
->reverse_gc
,
4029 x_contour_x
, x_contour_y
, point_x
, point_y
);
4030 outline_region (f
, f
->display
.x
->cursor_gc
, point_x
, point_y
,
4031 x_mouse_x
, x_mouse_y
);
4033 else if (x_mouse_y
> x_contour_y
) /* Top clipped. */
4035 clip_contour_top (x_mouse_y
);
4037 else if (x_mouse_y
< x_contour_y
) /* Top extended. */
4039 extend_contour_top (x_mouse_y
);
4044 unread_command_event
= obj
;
4045 if (mouse_below_point
)
4047 contour_begin_x
= point_x
;
4048 contour_begin_y
= point_y
;
4049 contour_end_x
= x_contour_x
;
4050 contour_end_y
= x_contour_y
;
4054 contour_begin_x
= x_contour_x
;
4055 contour_begin_y
= x_contour_y
;
4056 contour_end_x
= point_x
;
4057 contour_end_y
= point_y
;
4062 DEFUN ("x-horizontal-line", Fx_horizontal_line
, Sx_horizontal_line
, 1, 1, "e",
4067 register Lisp_Object obj
;
4068 struct frame
*f
= selected_frame
;
4069 register struct window
*w
= XWINDOW (selected_window
);
4070 register GC line_gc
= f
->display
.x
->cursor_gc
;
4071 register GC erase_gc
= f
->display
.x
->reverse_gc
;
4073 char dash_list
[] = {6, 4, 6, 4};
4075 XGCValues gc_values
;
4077 register int previous_y
;
4078 register int line
= (x_mouse_y
+ 1) * f
->display
.x
->line_height
4079 + f
->display
.x
->internal_border_width
;
4080 register int left
= f
->display
.x
->internal_border_width
4082 * FONT_WIDTH (f
->display
.x
->font
));
4083 register int right
= left
+ (w
->width
4084 * FONT_WIDTH (f
->display
.x
->font
))
4085 - f
->display
.x
->internal_border_width
;
4089 gc_values
.foreground
= f
->display
.x
->cursor_pixel
;
4090 gc_values
.background
= f
->display
.x
->background_pixel
;
4091 gc_values
.line_width
= 1;
4092 gc_values
.line_style
= LineOnOffDash
;
4093 gc_values
.cap_style
= CapRound
;
4094 gc_values
.join_style
= JoinRound
;
4096 line_gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4097 GCLineStyle
| GCJoinStyle
| GCCapStyle
4098 | GCLineWidth
| GCForeground
| GCBackground
,
4100 XSetDashes (FRAME_X_DISPLAY (f
), line_gc
, 0, dash_list
, dashes
);
4101 gc_values
.foreground
= f
->display
.x
->background_pixel
;
4102 gc_values
.background
= f
->display
.x
->foreground_pixel
;
4103 erase_gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4104 GCLineStyle
| GCJoinStyle
| GCCapStyle
4105 | GCLineWidth
| GCForeground
| GCBackground
,
4107 XSetDashes (FRAME_X_DISPLAY (f
), erase_gc
, 0, dash_list
, dashes
);
4113 if (x_mouse_y
>= XINT (w
->top
)
4114 && x_mouse_y
< XINT (w
->top
) + XINT (w
->height
) - 1)
4116 previous_y
= x_mouse_y
;
4117 line
= (x_mouse_y
+ 1) * f
->display
.x
->line_height
4118 + f
->display
.x
->internal_border_width
;
4119 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4120 line_gc
, left
, line
, right
, line
);
4122 XFlush (FRAME_X_DISPLAY (f
));
4127 obj
= read_char (-1, 0, 0, Qnil
, 0);
4129 || (! EQ (Fcar (Fcdr (Fcdr (obj
))),
4130 Qvertical_scroll_bar
))
4134 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4135 erase_gc
, left
, line
, right
, line
);
4137 unread_command_event
= obj
;
4139 XFreeGC (FRAME_X_DISPLAY (f
), line_gc
);
4140 XFreeGC (FRAME_X_DISPLAY (f
), erase_gc
);
4145 while (x_mouse_y
== previous_y
);
4148 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4149 erase_gc
, left
, line
, right
, line
);
4156 /* These keep track of the rectangle following the pointer. */
4157 int mouse_track_top
, mouse_track_left
, mouse_track_width
;
4159 /* Offset in buffer of character under the pointer, or 0. */
4160 int mouse_buffer_offset
;
4162 DEFUN ("x-track-pointer", Fx_track_pointer
, Sx_track_pointer
, 0, 0, 0,
4163 "Track the pointer.")
4166 static Cursor current_pointer_shape
;
4167 FRAME_PTR f
= x_mouse_frame
;
4170 if (EQ (Vmouse_frame_part
, Qtext_part
)
4171 && (current_pointer_shape
!= f
->display
.x
->nontext_cursor
))
4176 current_pointer_shape
= f
->display
.x
->nontext_cursor
;
4177 XDefineCursor (FRAME_X_DISPLAY (f
),
4179 current_pointer_shape
);
4181 buf
= XBUFFER (XWINDOW (Vmouse_window
)->buffer
);
4182 c
= *(BUF_CHAR_ADDRESS (buf
, mouse_buffer_offset
));
4184 else if (EQ (Vmouse_frame_part
, Qmodeline_part
)
4185 && (current_pointer_shape
!= f
->display
.x
->modeline_cursor
))
4187 current_pointer_shape
= f
->display
.x
->modeline_cursor
;
4188 XDefineCursor (FRAME_X_DISPLAY (f
),
4190 current_pointer_shape
);
4193 XFlush (FRAME_X_DISPLAY (f
));
4199 DEFUN ("x-track-pointer", Fx_track_pointer
, Sx_track_pointer
, 1, 1, "e",
4200 "Draw rectangle around character under mouse pointer, if there is one.")
4204 struct window
*w
= XWINDOW (Vmouse_window
);
4205 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4206 struct buffer
*b
= XBUFFER (w
->buffer
);
4209 if (! EQ (Vmouse_window
, selected_window
))
4212 if (EQ (event
, Qnil
))
4216 x_read_mouse_position (selected_frame
, &x
, &y
);
4220 mouse_track_width
= 0;
4221 mouse_track_left
= mouse_track_top
= -1;
4225 if ((x_mouse_x
!= mouse_track_left
4226 && (x_mouse_x
< mouse_track_left
4227 || x_mouse_x
> (mouse_track_left
+ mouse_track_width
)))
4228 || x_mouse_y
!= mouse_track_top
)
4230 int hp
= 0; /* Horizontal position */
4231 int len
= FRAME_CURRENT_GLYPHS (f
)->used
[x_mouse_y
];
4232 int p
= FRAME_CURRENT_GLYPHS (f
)->bufp
[x_mouse_y
];
4233 int tab_width
= XINT (b
->tab_width
);
4234 int ctl_arrow_p
= !NILP (b
->ctl_arrow
);
4236 int mode_line_vpos
= XFASTINT (w
->height
) + XFASTINT (w
->top
) - 1;
4237 int in_mode_line
= 0;
4239 if (! FRAME_CURRENT_GLYPHS (f
)->enable
[x_mouse_y
])
4242 /* Erase previous rectangle. */
4243 if (mouse_track_width
)
4245 x_rectangle (f
, f
->display
.x
->reverse_gc
,
4246 mouse_track_left
, mouse_track_top
,
4247 mouse_track_width
, 1);
4249 if ((mouse_track_left
== f
->phys_cursor_x
4250 || mouse_track_left
== f
->phys_cursor_x
- 1)
4251 && mouse_track_top
== f
->phys_cursor_y
)
4253 x_display_cursor (f
, 1);
4257 mouse_track_left
= x_mouse_x
;
4258 mouse_track_top
= x_mouse_y
;
4259 mouse_track_width
= 0;
4261 if (mouse_track_left
> len
) /* Past the end of line. */
4264 if (mouse_track_top
== mode_line_vpos
)
4270 if (tab_width
<= 0 || tab_width
> 20) tab_width
= 8;
4274 if (len
== f
->width
&& hp
== len
- 1 && c
!= '\n')
4280 mouse_track_width
= tab_width
- (hp
% tab_width
);
4282 hp
+= mouse_track_width
;
4285 mouse_track_left
= hp
- mouse_track_width
;
4291 mouse_track_width
= -1;
4295 if (ctl_arrow_p
&& (c
< 040 || c
== 0177))
4300 mouse_track_width
= 2;
4305 mouse_track_left
= hp
- mouse_track_width
;
4311 mouse_track_width
= 1;
4318 while (hp
<= x_mouse_x
);
4321 if (mouse_track_width
) /* Over text; use text pointer shape. */
4323 XDefineCursor (FRAME_X_DISPLAY (f
),
4325 f
->display
.x
->text_cursor
);
4326 x_rectangle (f
, f
->display
.x
->cursor_gc
,
4327 mouse_track_left
, mouse_track_top
,
4328 mouse_track_width
, 1);
4330 else if (in_mode_line
)
4331 XDefineCursor (FRAME_X_DISPLAY (f
),
4333 f
->display
.x
->modeline_cursor
);
4335 XDefineCursor (FRAME_X_DISPLAY (f
),
4337 f
->display
.x
->nontext_cursor
);
4340 XFlush (FRAME_X_DISPLAY (f
));
4343 obj
= read_char (-1, 0, 0, Qnil
, 0);
4346 while (CONSP (obj
) /* Mouse event */
4347 && EQ (Fcar (Fcdr (Fcdr (obj
))), Qnil
) /* Not scroll bar */
4348 && EQ (Vmouse_depressed
, Qnil
) /* Only motion events */
4349 && EQ (Vmouse_window
, selected_window
) /* In this window */
4352 unread_command_event
= obj
;
4354 if (mouse_track_width
)
4356 x_rectangle (f
, f
->display
.x
->reverse_gc
,
4357 mouse_track_left
, mouse_track_top
,
4358 mouse_track_width
, 1);
4359 mouse_track_width
= 0;
4360 if ((mouse_track_left
== f
->phys_cursor_x
4361 || mouse_track_left
- 1 == f
->phys_cursor_x
)
4362 && mouse_track_top
== f
->phys_cursor_y
)
4364 x_display_cursor (f
, 1);
4367 XDefineCursor (FRAME_X_DISPLAY (f
),
4369 f
->display
.x
->nontext_cursor
);
4370 XFlush (FRAME_X_DISPLAY (f
));
4380 /* Draw a pixmap specified by IMAGE_DATA of dimensions WIDTH and HEIGHT
4381 on the frame F at position X, Y. */
4383 x_draw_pixmap (f
, x
, y
, image_data
, width
, height
)
4385 int x
, y
, width
, height
;
4390 image
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
4391 FRAME_X_WINDOW (f
), image_data
,
4393 XCopyPlane (FRAME_X_DISPLAY (f
), image
, FRAME_X_WINDOW (f
),
4394 f
->display
.x
->normal_gc
, 0, 0, width
, height
, x
, y
);
4398 #if 0 /* I'm told these functions are superfluous
4399 given the ability to bind function keys. */
4402 DEFUN ("x-rebind-key", Fx_rebind_key
, Sx_rebind_key
, 3, 3, 0,
4403 "Rebind X keysym KEYSYM, with MODIFIERS, to generate NEWSTRING.\n\
4404 KEYSYM is a string which conforms to the X keysym definitions found\n\
4405 in X11/keysymdef.h, sans the initial XK_. MODIFIERS is nil or a\n\
4406 list of strings specifying modifier keys such as Control_L, which must\n\
4407 also be depressed for NEWSTRING to appear.")
4408 (x_keysym
, modifiers
, newstring
)
4409 register Lisp_Object x_keysym
;
4410 register Lisp_Object modifiers
;
4411 register Lisp_Object newstring
;
4414 register KeySym keysym
;
4415 KeySym modifier_list
[16];
4418 CHECK_STRING (x_keysym
, 1);
4419 CHECK_STRING (newstring
, 3);
4421 keysym
= XStringToKeysym ((char *) XSTRING (x_keysym
)->data
);
4422 if (keysym
== NoSymbol
)
4423 error ("Keysym does not exist");
4425 if (NILP (modifiers
))
4426 XRebindKeysym (x_current_display
, keysym
, modifier_list
, 0,
4427 XSTRING (newstring
)->data
, XSTRING (newstring
)->size
);
4430 register Lisp_Object rest
, mod
;
4433 for (rest
= modifiers
; !NILP (rest
); rest
= Fcdr (rest
))
4436 error ("Can't have more than 16 modifiers");
4439 CHECK_STRING (mod
, 3);
4440 modifier_list
[i
] = XStringToKeysym ((char *) XSTRING (mod
)->data
);
4442 if (modifier_list
[i
] == NoSymbol
4443 || !(IsModifierKey (modifier_list
[i
])
4444 || ((unsigned)(modifier_list
[i
]) == XK_Mode_switch
)
4445 || ((unsigned)(modifier_list
[i
]) == XK_Num_Lock
)))
4447 if (modifier_list
[i
] == NoSymbol
4448 || !IsModifierKey (modifier_list
[i
]))
4450 error ("Element is not a modifier keysym");
4454 XRebindKeysym (x_current_display
, keysym
, modifier_list
, i
,
4455 XSTRING (newstring
)->data
, XSTRING (newstring
)->size
);
4461 DEFUN ("x-rebind-keys", Fx_rebind_keys
, Sx_rebind_keys
, 2, 2, 0,
4462 "Rebind KEYCODE to list of strings STRINGS.\n\
4463 STRINGS should be a list of 16 elements, one for each shift combination.\n\
4464 nil as element means don't change.\n\
4465 See the documentation of `x-rebind-key' for more information.")
4467 register Lisp_Object keycode
;
4468 register Lisp_Object strings
;
4470 register Lisp_Object item
;
4471 register unsigned char *rawstring
;
4472 KeySym rawkey
, modifier
[1];
4474 register unsigned i
;
4477 CHECK_NUMBER (keycode
, 1);
4478 CHECK_CONS (strings
, 2);
4479 rawkey
= (KeySym
) ((unsigned) (XINT (keycode
))) & 255;
4480 for (i
= 0; i
<= 15; strings
= Fcdr (strings
), i
++)
4482 item
= Fcar (strings
);
4485 CHECK_STRING (item
, 2);
4486 strsize
= XSTRING (item
)->size
;
4487 rawstring
= (unsigned char *) xmalloc (strsize
);
4488 bcopy (XSTRING (item
)->data
, rawstring
, strsize
);
4489 modifier
[1] = 1 << i
;
4490 XRebindKeysym (x_current_display
, rawkey
, modifier
, 1,
4491 rawstring
, strsize
);
4496 #endif /* HAVE_X11 */
4499 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4501 XScreenNumberOfScreen (scr
)
4502 register Screen
*scr
;
4504 register Display
*dpy
;
4505 register Screen
*dpyscr
;
4509 dpyscr
= dpy
->screens
;
4511 for (i
= 0; i
< dpy
->nscreens
; i
++, dpyscr
++)
4517 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4520 select_visual (dpy
, screen
, depth
)
4523 unsigned int *depth
;
4526 XVisualInfo
*vinfo
, vinfo_template
;
4529 v
= DefaultVisualOfScreen (screen
);
4532 vinfo_template
.visualid
= XVisualIDFromVisual (v
);
4534 vinfo_template
.visualid
= v
->visualid
;
4537 vinfo_template
.screen
= XScreenNumberOfScreen (screen
);
4539 vinfo
= XGetVisualInfo (dpy
,
4540 VisualIDMask
| VisualScreenMask
, &vinfo_template
,
4543 fatal ("Can't get proper X visual info");
4545 if ((1 << vinfo
->depth
) == vinfo
->colormap_size
)
4546 *depth
= vinfo
->depth
;
4550 int n
= vinfo
->colormap_size
- 1;
4559 XFree ((char *) vinfo
);
4563 /* Return the X display structure for the display named NAME.
4564 Open a new connection if necessary. */
4566 struct x_display_info
*
4567 x_display_info_for_name (name
)
4571 struct x_display_info
*dpyinfo
;
4573 CHECK_STRING (name
, 0);
4575 for (dpyinfo
= x_display_list
, names
= x_display_name_list
;
4577 dpyinfo
= dpyinfo
->next
, names
= XCONS (names
)->cdr
)
4580 tem
= Fstring_equal (XCONS (XCONS (names
)->car
)->car
, name
);
4585 /* Use this general default value to start with. */
4586 Vx_resource_name
= Vinvocation_name
;
4588 validate_x_resource_name ();
4590 dpyinfo
= x_term_init (name
, (unsigned char *)0,
4591 (char *) XSTRING (Vx_resource_name
)->data
);
4594 error ("X server %s not responding", XSTRING (name
)->data
);
4597 XSETFASTINT (Vwindow_system_version
, 11);
4602 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
4603 1, 3, 0, "Open a connection to an X server.\n\
4604 DISPLAY is the name of the display to connect to.\n\
4605 Optional second arg XRM-STRING is a string of resources in xrdb format.\n\
4606 If the optional third arg MUST-SUCCEED is non-nil,\n\
4607 terminate Emacs if we can't open the connection.")
4608 (display
, xrm_string
, must_succeed
)
4609 Lisp_Object display
, xrm_string
, must_succeed
;
4611 unsigned int n_planes
;
4612 unsigned char *xrm_option
;
4613 struct x_display_info
*dpyinfo
;
4615 CHECK_STRING (display
, 0);
4616 if (! NILP (xrm_string
))
4617 CHECK_STRING (xrm_string
, 1);
4619 if (! NILP (xrm_string
))
4620 xrm_option
= (unsigned char *) XSTRING (xrm_string
)->data
;
4622 xrm_option
= (unsigned char *) 0;
4624 /* Use this general default value to start with. */
4625 Vx_resource_name
= Vinvocation_name
;
4627 validate_x_resource_name ();
4629 /* This is what opens the connection and sets x_current_display.
4630 This also initializes many symbols, such as those used for input. */
4631 dpyinfo
= x_term_init (display
, xrm_option
,
4632 (char *) XSTRING (Vx_resource_name
)->data
);
4636 if (!NILP (must_succeed
))
4637 fatal ("X server %s not responding.\n\
4638 Check the DISPLAY environment variable or use \"-d\"\n",
4639 XSTRING (display
)->data
);
4641 error ("X server %s not responding", XSTRING (display
)->data
);
4646 XSETFASTINT (Vwindow_system_version
, 11);
4650 DEFUN ("x-close-connection", Fx_close_connection
,
4651 Sx_close_connection
, 1, 1, 0,
4652 "Close the connection to DISPLAY's X server.\n\
4653 For DISPLAY, specify either a frame or a display name (a string).\n\
4654 If DISPLAY is nil, that stands for the selected frame's display.")
4656 Lisp_Object display
;
4658 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4659 struct x_display_info
*tail
;
4662 if (dpyinfo
->reference_count
> 0)
4663 error ("Display still has frames on it");
4666 /* Free the fonts in the font table. */
4667 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
4669 if (dpyinfo
->font_table
[i
].name
)
4670 free (dpyinfo
->font_table
[i
].name
);
4671 /* Don't free the full_name string;
4672 it is always shared with something else. */
4673 XFreeFont (dpyinfo
->display
, dpyinfo
->font_table
[i
].font
);
4675 x_destroy_all_bitmaps (dpyinfo
);
4676 XSetCloseDownMode (dpyinfo
->display
, DestroyAll
);
4678 #ifdef USE_X_TOOLKIT
4679 XtCloseDisplay (dpyinfo
->display
);
4681 XCloseDisplay (dpyinfo
->display
);
4684 x_delete_display (dpyinfo
);
4690 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
4691 "Return the list of display names that Emacs has connections to.")
4694 Lisp_Object tail
, result
;
4697 for (tail
= x_display_name_list
; ! NILP (tail
); tail
= XCONS (tail
)->cdr
)
4698 result
= Fcons (XCONS (XCONS (tail
)->car
)->car
, result
);
4703 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
4704 "If ON is non-nil, report X errors as soon as the erring request is made.\n\
4705 If ON is nil, allow buffering of requests.\n\
4706 Turning on synchronization prohibits the Xlib routines from buffering\n\
4707 requests and seriously degrades performance, but makes debugging much\n\
4709 The optional second argument DISPLAY specifies which display to act on.\n\
4710 DISPLAY should be either a frame or a display name (a string).\n\
4711 If DISPLAY is omitted or nil, that stands for the selected frame's display.")
4713 Lisp_Object display
, on
;
4715 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4717 XSynchronize (dpyinfo
->display
, !EQ (on
, Qnil
));
4722 /* Wait for responses to all X commands issued so far for frame F. */
4729 XSync (FRAME_X_DISPLAY (f
), False
);
4735 /* This is zero if not using X windows. */
4738 /* The section below is built by the lisp expression at the top of the file,
4739 just above where these variables are declared. */
4740 /*&&& init symbols here &&&*/
4741 Qauto_raise
= intern ("auto-raise");
4742 staticpro (&Qauto_raise
);
4743 Qauto_lower
= intern ("auto-lower");
4744 staticpro (&Qauto_lower
);
4745 Qbackground_color
= intern ("background-color");
4746 staticpro (&Qbackground_color
);
4747 Qbar
= intern ("bar");
4749 Qborder_color
= intern ("border-color");
4750 staticpro (&Qborder_color
);
4751 Qborder_width
= intern ("border-width");
4752 staticpro (&Qborder_width
);
4753 Qbox
= intern ("box");
4755 Qcursor_color
= intern ("cursor-color");
4756 staticpro (&Qcursor_color
);
4757 Qcursor_type
= intern ("cursor-type");
4758 staticpro (&Qcursor_type
);
4759 Qfont
= intern ("font");
4761 Qforeground_color
= intern ("foreground-color");
4762 staticpro (&Qforeground_color
);
4763 Qgeometry
= intern ("geometry");
4764 staticpro (&Qgeometry
);
4765 Qicon_left
= intern ("icon-left");
4766 staticpro (&Qicon_left
);
4767 Qicon_top
= intern ("icon-top");
4768 staticpro (&Qicon_top
);
4769 Qicon_type
= intern ("icon-type");
4770 staticpro (&Qicon_type
);
4771 Qinternal_border_width
= intern ("internal-border-width");
4772 staticpro (&Qinternal_border_width
);
4773 Qleft
= intern ("left");
4775 Qmouse_color
= intern ("mouse-color");
4776 staticpro (&Qmouse_color
);
4777 Qnone
= intern ("none");
4779 Qparent_id
= intern ("parent-id");
4780 staticpro (&Qparent_id
);
4781 Qscroll_bar_width
= intern ("scroll-bar-width");
4782 staticpro (&Qscroll_bar_width
);
4783 Qsuppress_icon
= intern ("suppress-icon");
4784 staticpro (&Qsuppress_icon
);
4785 Qtop
= intern ("top");
4787 Qundefined_color
= intern ("undefined-color");
4788 staticpro (&Qundefined_color
);
4789 Qvertical_scroll_bars
= intern ("vertical-scroll-bars");
4790 staticpro (&Qvertical_scroll_bars
);
4791 Qvisibility
= intern ("visibility");
4792 staticpro (&Qvisibility
);
4793 Qwindow_id
= intern ("window-id");
4794 staticpro (&Qwindow_id
);
4795 Qx_frame_parameter
= intern ("x-frame-parameter");
4796 staticpro (&Qx_frame_parameter
);
4797 Qx_resource_name
= intern ("x-resource-name");
4798 staticpro (&Qx_resource_name
);
4799 Quser_position
= intern ("user-position");
4800 staticpro (&Quser_position
);
4801 Quser_size
= intern ("user-size");
4802 staticpro (&Quser_size
);
4803 Qdisplay
= intern ("display");
4804 staticpro (&Qdisplay
);
4805 /* This is the end of symbol initialization. */
4807 Fput (Qundefined_color
, Qerror_conditions
,
4808 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
4809 Fput (Qundefined_color
, Qerror_message
,
4810 build_string ("Undefined color"));
4812 init_x_parm_symbols ();
4814 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path
,
4815 "List of directories to search for bitmap files for X.");
4816 Vx_bitmap_file_path
= decode_env_path ((char *) 0, PATH_BITMAPS
);
4818 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
4819 "The shape of the pointer when over text.\n\
4820 Changing the value does not affect existing frames\n\
4821 unless you set the mouse color.");
4822 Vx_pointer_shape
= Qnil
;
4824 DEFVAR_LISP ("x-resource-name", &Vx_resource_name
,
4825 "The name Emacs uses to look up X resources; for internal use only.\n\
4826 `x-get-resource' uses this as the first component of the instance name\n\
4827 when requesting resource values.\n\
4828 Emacs initially sets `x-resource-name' to the name under which Emacs\n\
4829 was invoked, or to the value specified with the `-name' or `-rn'\n\
4830 switches, if present.");
4831 Vx_resource_name
= Qnil
;
4833 #if 0 /* This doesn't really do anything. */
4834 DEFVAR_INT ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape
,
4835 "The shape of the pointer when not over text.\n\
4836 This variable takes effect when you create a new frame\n\
4837 or when you set the mouse color.");
4839 Vx_nontext_pointer_shape
= Qnil
;
4841 #if 0 /* This doesn't really do anything. */
4842 DEFVAR_INT ("x-mode-pointer-shape", &Vx_mode_pointer_shape
,
4843 "The shape of the pointer when over the mode line.\n\
4844 This variable takes effect when you create a new frame\n\
4845 or when you set the mouse color.");
4847 Vx_mode_pointer_shape
= Qnil
;
4849 DEFVAR_INT ("x-sensitive-text-pointer-shape",
4850 &Vx_sensitive_text_pointer_shape
,
4851 "The shape of the pointer when over mouse-sensitive text.\n\
4852 This variable takes effect when you create a new frame\n\
4853 or when you set the mouse color.");
4854 Vx_sensitive_text_pointer_shape
= Qnil
;
4856 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
4857 "A string indicating the foreground color of the cursor box.");
4858 Vx_cursor_fore_pixel
= Qnil
;
4860 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
4861 "Non-nil if no X window manager is in use.");
4863 #ifdef USE_X_TOOLKIT
4864 Fprovide (intern ("x-toolkit"));
4867 defsubr (&Sx_get_resource
);
4869 defsubr (&Sx_draw_rectangle
);
4870 defsubr (&Sx_erase_rectangle
);
4871 defsubr (&Sx_contour_region
);
4872 defsubr (&Sx_uncontour_region
);
4874 defsubr (&Sx_list_fonts
);
4875 defsubr (&Sx_display_color_p
);
4876 defsubr (&Sx_display_grayscale_p
);
4877 defsubr (&Sx_color_defined_p
);
4878 defsubr (&Sx_color_values
);
4879 defsubr (&Sx_server_max_request_size
);
4880 defsubr (&Sx_server_vendor
);
4881 defsubr (&Sx_server_version
);
4882 defsubr (&Sx_display_pixel_width
);
4883 defsubr (&Sx_display_pixel_height
);
4884 defsubr (&Sx_display_mm_width
);
4885 defsubr (&Sx_display_mm_height
);
4886 defsubr (&Sx_display_screens
);
4887 defsubr (&Sx_display_planes
);
4888 defsubr (&Sx_display_color_cells
);
4889 defsubr (&Sx_display_visual_class
);
4890 defsubr (&Sx_display_backing_store
);
4891 defsubr (&Sx_display_save_under
);
4893 defsubr (&Sx_rebind_key
);
4894 defsubr (&Sx_rebind_keys
);
4895 defsubr (&Sx_track_pointer
);
4896 defsubr (&Sx_grab_pointer
);
4897 defsubr (&Sx_ungrab_pointer
);
4899 defsubr (&Sx_parse_geometry
);
4900 defsubr (&Sx_create_frame
);
4901 defsubr (&Sfocus_frame
);
4902 defsubr (&Sunfocus_frame
);
4904 defsubr (&Sx_horizontal_line
);
4906 defsubr (&Sx_open_connection
);
4907 defsubr (&Sx_close_connection
);
4908 defsubr (&Sx_display_list
);
4909 defsubr (&Sx_synchronize
);
4912 #endif /* HAVE_X_WINDOWS */