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 /* Match if the window is this frame's menubar. */
383 if (x
->menubar_widget
384 && wdesc
== XtWindow (x
->menubar_widget
))
389 #endif /* USE_X_TOOLKIT */
393 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
394 id, which is just an int that this section returns. Bitmaps are
395 reference counted so they can be shared among frames.
397 Bitmap indices are guaranteed to be > 0, so a negative number can
398 be used to indicate no bitmap.
400 If you use x_create_bitmap_from_data, then you must keep track of
401 the bitmaps yourself. That is, creating a bitmap from the same
402 data more than once will not be caught. */
405 /* Functions to access the contents of a bitmap, given an id. */
408 x_bitmap_height (f
, id
)
412 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].height
;
416 x_bitmap_width (f
, id
)
420 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].width
;
424 x_bitmap_pixmap (f
, id
)
428 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].pixmap
;
432 /* Allocate a new bitmap record. Returns index of new record. */
435 x_allocate_bitmap_record (f
)
438 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
441 if (dpyinfo
->bitmaps
== NULL
)
443 dpyinfo
->bitmaps_size
= 10;
445 = (struct x_bitmap_record
*) xmalloc (dpyinfo
->bitmaps_size
* sizeof (struct x_bitmap_record
));
446 dpyinfo
->bitmaps_last
= 1;
450 if (dpyinfo
->bitmaps_last
< dpyinfo
->bitmaps_size
)
451 return ++dpyinfo
->bitmaps_last
;
453 for (i
= 0; i
< dpyinfo
->bitmaps_size
; ++i
)
454 if (dpyinfo
->bitmaps
[i
].refcount
== 0)
457 dpyinfo
->bitmaps_size
*= 2;
459 = (struct x_bitmap_record
*) xrealloc (dpyinfo
->bitmaps
,
460 dpyinfo
->bitmaps_size
* sizeof (struct x_bitmap_record
));
461 return ++dpyinfo
->bitmaps_last
;
464 /* Add one reference to the reference count of the bitmap with id ID. */
467 x_reference_bitmap (f
, id
)
471 ++FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].refcount
;
474 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
477 x_create_bitmap_from_data (f
, bits
, width
, height
)
480 unsigned int width
, height
;
482 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
486 bitmap
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
487 bits
, width
, height
);
492 id
= x_allocate_bitmap_record (f
);
493 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
494 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
495 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
496 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
497 dpyinfo
->bitmaps
[id
- 1].height
= height
;
498 dpyinfo
->bitmaps
[id
- 1].width
= width
;
503 /* Create bitmap from file FILE for frame F. */
506 x_create_bitmap_from_file (f
, file
)
510 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
511 unsigned int width
, height
;
513 int xhot
, yhot
, result
, id
;
518 /* Look for an existing bitmap with the same name. */
519 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
521 if (dpyinfo
->bitmaps
[id
].refcount
522 && dpyinfo
->bitmaps
[id
].file
523 && !strcmp (dpyinfo
->bitmaps
[id
].file
, (char *) XSTRING (file
)->data
))
525 ++dpyinfo
->bitmaps
[id
].refcount
;
530 /* Search bitmap-file-path for the file, if appropriate. */
531 fd
= openp (Vx_bitmap_file_path
, file
, "", &found
, 0);
536 filename
= (char *) XSTRING (found
)->data
;
538 result
= XReadBitmapFile (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
539 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
540 if (result
!= BitmapSuccess
)
543 id
= x_allocate_bitmap_record (f
);
544 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
545 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
546 dpyinfo
->bitmaps
[id
- 1].file
= (char *) xmalloc (XSTRING (file
)->size
+ 1);
547 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
548 dpyinfo
->bitmaps
[id
- 1].height
= height
;
549 dpyinfo
->bitmaps
[id
- 1].width
= width
;
550 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, XSTRING (file
)->data
);
555 /* Remove reference to bitmap with id number ID. */
558 x_destroy_bitmap (f
, id
)
562 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
566 --dpyinfo
->bitmaps
[id
- 1].refcount
;
567 if (dpyinfo
->bitmaps
[id
- 1].refcount
== 0)
569 XFreePixmap (FRAME_X_DISPLAY (f
), dpyinfo
->bitmaps
[id
- 1].pixmap
);
570 if (dpyinfo
->bitmaps
[id
- 1].file
)
572 free (dpyinfo
->bitmaps
[id
- 1].file
);
573 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
579 /* Free all the bitmaps for the display specified by DPYINFO. */
582 x_destroy_all_bitmaps (dpyinfo
)
583 struct x_display_info
*dpyinfo
;
586 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++)
587 if (dpyinfo
->bitmaps
[i
].refcount
> 0)
589 XFreePixmap (dpyinfo
->display
, dpyinfo
->bitmaps
[i
].pixmap
);
590 if (dpyinfo
->bitmaps
[i
].file
)
591 free (dpyinfo
->bitmaps
[i
].file
);
593 dpyinfo
->bitmaps_last
= 0;
596 /* Connect the frame-parameter names for X frames
597 to the ways of passing the parameter values to the window system.
599 The name of a parameter, as a Lisp symbol,
600 has an `x-frame-parameter' property which is an integer in Lisp
601 but can be interpreted as an `enum x_frame_parm' in C. */
605 X_PARM_FOREGROUND_COLOR
,
606 X_PARM_BACKGROUND_COLOR
,
613 X_PARM_INTERNAL_BORDER_WIDTH
,
617 X_PARM_VERT_SCROLL_BAR
,
619 X_PARM_MENU_BAR_LINES
623 struct x_frame_parm_table
626 void (*setter
)( /* struct frame *frame, Lisp_Object val, oldval */ );
629 void x_set_foreground_color ();
630 void x_set_background_color ();
631 void x_set_mouse_color ();
632 void x_set_cursor_color ();
633 void x_set_border_color ();
634 void x_set_cursor_type ();
635 void x_set_icon_type ();
637 void x_set_border_width ();
638 void x_set_internal_border_width ();
639 void x_explicitly_set_name ();
640 void x_set_autoraise ();
641 void x_set_autolower ();
642 void x_set_vertical_scroll_bars ();
643 void x_set_visibility ();
644 void x_set_menu_bar_lines ();
645 void x_set_scroll_bar_width ();
646 void x_set_unsplittable ();
648 static struct x_frame_parm_table x_frame_parms
[] =
650 "foreground-color", x_set_foreground_color
,
651 "background-color", x_set_background_color
,
652 "mouse-color", x_set_mouse_color
,
653 "cursor-color", x_set_cursor_color
,
654 "border-color", x_set_border_color
,
655 "cursor-type", x_set_cursor_type
,
656 "icon-type", x_set_icon_type
,
658 "border-width", x_set_border_width
,
659 "internal-border-width", x_set_internal_border_width
,
660 "name", x_explicitly_set_name
,
661 "auto-raise", x_set_autoraise
,
662 "auto-lower", x_set_autolower
,
663 "vertical-scroll-bars", x_set_vertical_scroll_bars
,
664 "visibility", x_set_visibility
,
665 "menu-bar-lines", x_set_menu_bar_lines
,
666 "scroll-bar-width", x_set_scroll_bar_width
,
667 "unsplittable", x_set_unsplittable
,
670 /* Attach the `x-frame-parameter' properties to
671 the Lisp symbol names of parameters relevant to X. */
673 init_x_parm_symbols ()
677 for (i
= 0; i
< sizeof (x_frame_parms
) / sizeof (x_frame_parms
[0]); i
++)
678 Fput (intern (x_frame_parms
[i
].name
), Qx_frame_parameter
,
682 /* Change the parameters of FRAME as specified by ALIST.
683 If a parameter is not specially recognized, do nothing;
684 otherwise call the `x_set_...' function for that parameter. */
687 x_set_frame_parameters (f
, alist
)
693 /* If both of these parameters are present, it's more efficient to
694 set them both at once. So we wait until we've looked at the
695 entire list before we set them. */
696 Lisp_Object width
, height
;
699 Lisp_Object left
, top
;
701 /* Same with these. */
702 Lisp_Object icon_left
, icon_top
;
704 /* Record in these vectors all the parms specified. */
708 int left_no_change
= 0, top_no_change
= 0;
709 int icon_left_no_change
= 0, icon_top_no_change
= 0;
712 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
715 parms
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
716 values
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
718 /* Extract parm names and values into those vectors. */
721 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
723 Lisp_Object elt
, prop
, val
;
726 parms
[i
] = Fcar (elt
);
727 values
[i
] = Fcdr (elt
);
731 width
= height
= top
= left
= Qunbound
;
732 icon_left
= icon_top
= Qunbound
;
734 /* Now process them in reverse of specified order. */
735 for (i
--; i
>= 0; i
--)
737 Lisp_Object prop
, val
;
742 if (EQ (prop
, Qwidth
))
744 else if (EQ (prop
, Qheight
))
746 else if (EQ (prop
, Qtop
))
748 else if (EQ (prop
, Qleft
))
750 else if (EQ (prop
, Qicon_top
))
752 else if (EQ (prop
, Qicon_left
))
756 register Lisp_Object param_index
, old_value
;
758 param_index
= Fget (prop
, Qx_frame_parameter
);
759 old_value
= get_frame_param (f
, prop
);
760 store_frame_param (f
, prop
, val
);
761 if (NATNUMP (param_index
)
762 && (XFASTINT (param_index
)
763 < sizeof (x_frame_parms
)/sizeof (x_frame_parms
[0])))
764 (*x_frame_parms
[XINT (param_index
)].setter
)(f
, val
, old_value
);
768 /* Don't die if just one of these was set. */
769 if (EQ (left
, Qunbound
))
772 if (f
->display
.x
->left_pos
< 0)
773 left
= Fcons (Qplus
, Fcons (make_number (f
->display
.x
->left_pos
), Qnil
));
775 XSETINT (left
, f
->display
.x
->left_pos
);
777 if (EQ (top
, Qunbound
))
780 if (f
->display
.x
->top_pos
< 0)
781 top
= Fcons (Qplus
, Fcons (make_number (f
->display
.x
->top_pos
), Qnil
));
783 XSETINT (top
, f
->display
.x
->top_pos
);
786 /* If one of the icon positions was not set, preserve or default it. */
787 if (EQ (icon_left
, Qunbound
) || ! INTEGERP (icon_left
))
789 icon_left_no_change
= 1;
790 icon_left
= Fcdr (Fassq (Qicon_left
, f
->param_alist
));
791 if (NILP (icon_left
))
792 XSETINT (icon_left
, 0);
794 if (EQ (icon_top
, Qunbound
) || ! INTEGERP (icon_top
))
796 icon_top_no_change
= 1;
797 icon_top
= Fcdr (Fassq (Qicon_top
, f
->param_alist
));
799 XSETINT (icon_top
, 0);
802 /* Don't die if just one of these was set. */
803 if (EQ (width
, Qunbound
))
804 XSETINT (width
, FRAME_WIDTH (f
));
805 if (EQ (height
, Qunbound
))
806 XSETINT (height
, FRAME_HEIGHT (f
));
808 /* Don't set these parameters these unless they've been explicitly
809 specified. The window might be mapped or resized while we're in
810 this function, and we don't want to override that unless the lisp
811 code has asked for it.
813 Don't set these parameters unless they actually differ from the
814 window's current parameters; the window may not actually exist
819 check_frame_size (f
, &height
, &width
);
821 XSETFRAME (frame
, f
);
823 if ((NUMBERP (width
) && XINT (width
) != FRAME_WIDTH (f
))
824 || (NUMBERP (height
) && XINT (height
) != FRAME_HEIGHT (f
)))
825 Fset_frame_size (frame
, width
, height
);
827 if ((!NILP (left
) || !NILP (top
))
828 && ! (left_no_change
&& top_no_change
)
829 && ! (NUMBERP (left
) && XINT (left
) == f
->display
.x
->left_pos
830 && NUMBERP (top
) && XINT (top
) == f
->display
.x
->top_pos
))
835 /* Record the signs. */
836 f
->display
.x
->size_hint_flags
&= ~ (XNegative
| YNegative
);
837 if (EQ (left
, Qminus
))
838 f
->display
.x
->size_hint_flags
|= XNegative
;
839 else if (INTEGERP (left
))
841 leftpos
= XINT (left
);
843 f
->display
.x
->size_hint_flags
|= XNegative
;
845 else if (CONSP (left
) && EQ (XCONS (left
)->car
, Qminus
)
846 && CONSP (XCONS (left
)->cdr
)
847 && INTEGERP (XCONS (XCONS (left
)->cdr
)->car
))
849 leftpos
= - XINT (XCONS (XCONS (left
)->cdr
)->car
);
850 f
->display
.x
->size_hint_flags
|= XNegative
;
852 else if (CONSP (left
) && EQ (XCONS (left
)->car
, Qplus
)
853 && CONSP (XCONS (left
)->cdr
)
854 && INTEGERP (XCONS (XCONS (left
)->cdr
)->car
))
856 leftpos
= XINT (XCONS (XCONS (left
)->cdr
)->car
);
859 if (EQ (top
, Qminus
))
860 f
->display
.x
->size_hint_flags
|= YNegative
;
861 else if (INTEGERP (top
))
865 f
->display
.x
->size_hint_flags
|= YNegative
;
867 else if (CONSP (top
) && EQ (XCONS (top
)->car
, Qminus
)
868 && CONSP (XCONS (top
)->cdr
)
869 && INTEGERP (XCONS (XCONS (top
)->cdr
)->car
))
871 toppos
= - XINT (XCONS (XCONS (top
)->cdr
)->car
);
872 f
->display
.x
->size_hint_flags
|= YNegative
;
874 else if (CONSP (top
) && EQ (XCONS (top
)->car
, Qplus
)
875 && CONSP (XCONS (top
)->cdr
)
876 && INTEGERP (XCONS (XCONS (top
)->cdr
)->car
))
878 toppos
= XINT (XCONS (XCONS (top
)->cdr
)->car
);
882 /* Store the numeric value of the position. */
883 f
->display
.x
->top_pos
= toppos
;
884 f
->display
.x
->left_pos
= leftpos
;
886 f
->display
.x
->win_gravity
= NorthWestGravity
;
888 /* Actually set that position, and convert to absolute. */
889 x_set_offset (f
, leftpos
, toppos
, 0);
892 if ((!NILP (icon_left
) || !NILP (icon_top
))
893 && ! (icon_left_no_change
&& icon_top_no_change
))
894 x_wm_set_icon_position (f
, XINT (icon_left
), XINT (icon_top
));
898 /* Store the screen positions of frame F into XPTR and YPTR.
899 These are the positions of the containing window manager window,
900 not Emacs's own window. */
903 x_real_positions (f
, xptr
, yptr
)
910 /* This is pretty gross, but seems to be the easiest way out of
911 the problem that arises when restarting window-managers. */
914 Window outer
= XtWindow (f
->display
.x
->widget
);
916 Window outer
= f
->display
.x
->window_desc
;
918 Window tmp_root_window
;
919 Window
*tmp_children
;
922 x_catch_errors (FRAME_X_DISPLAY (f
));
925 XQueryTree (FRAME_X_DISPLAY (f
), outer
, &tmp_root_window
,
926 &f
->display
.x
->parent_desc
,
927 &tmp_children
, &tmp_nchildren
);
928 xfree (tmp_children
);
932 /* Find the position of the outside upper-left corner of
933 the inner window, with respect to the outer window. */
934 if (f
->display
.x
->parent_desc
!= FRAME_X_DISPLAY_INFO (f
)->root_window
)
936 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
938 /* From-window, to-window. */
940 XtWindow (f
->display
.x
->widget
),
942 f
->display
.x
->window_desc
,
944 f
->display
.x
->parent_desc
,
946 /* From-position, to-position. */
947 0, 0, &win_x
, &win_y
,
952 win_x
+= f
->display
.x
->border_width
;
953 win_y
+= f
->display
.x
->border_width
;
956 /* It is possible for the window returned by the XQueryNotify
957 to become invalid by the time we call XTranslateCoordinates.
958 That can happen when you restart some window managers.
959 If so, we get an error in XTranslateCoordinates.
960 Detect that and try the whole thing over. */
961 if (! x_had_errors_p (FRAME_X_DISPLAY (f
)))
965 x_uncatch_errors (FRAME_X_DISPLAY (f
));
967 *xptr
= f
->display
.x
->left_pos
- win_x
;
968 *yptr
= f
->display
.x
->top_pos
- win_y
;
971 /* Insert a description of internally-recorded parameters of frame X
972 into the parameter alist *ALISTPTR that is to be given to the user.
973 Only parameters that are specific to the X window system
974 and whose values are not correctly recorded in the frame's
975 param_alist need to be considered here. */
977 x_report_frame_params (f
, alistptr
)
979 Lisp_Object
*alistptr
;
983 store_in_alist (alistptr
, Qleft
, make_number (f
->display
.x
->left_pos
));
984 store_in_alist (alistptr
, Qtop
, make_number (f
->display
.x
->top_pos
));
985 store_in_alist (alistptr
, Qborder_width
,
986 make_number (f
->display
.x
->border_width
));
987 store_in_alist (alistptr
, Qinternal_border_width
,
988 make_number (f
->display
.x
->internal_border_width
));
989 sprintf (buf
, "%ld", (long) FRAME_X_WINDOW (f
));
990 store_in_alist (alistptr
, Qwindow_id
,
992 FRAME_SAMPLE_VISIBILITY (f
);
993 store_in_alist (alistptr
, Qvisibility
,
994 (FRAME_VISIBLE_P (f
) ? Qt
995 : FRAME_ICONIFIED_P (f
) ? Qicon
: Qnil
));
996 store_in_alist (alistptr
, Qdisplay
,
997 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->car
);
1001 /* Decide if color named COLOR is valid for the display associated with
1002 the selected frame; if so, return the rgb values in COLOR_DEF.
1003 If ALLOC is nonzero, allocate a new colormap cell. */
1006 defined_color (f
, color
, color_def
, alloc
)
1012 register int status
;
1013 Colormap screen_colormap
;
1014 Display
*display
= FRAME_X_DISPLAY (f
);
1017 screen_colormap
= DefaultColormap (display
, XDefaultScreen (display
));
1019 status
= XParseColor (display
, screen_colormap
, color
, color_def
);
1020 if (status
&& alloc
)
1022 status
= XAllocColor (display
, screen_colormap
, color_def
);
1025 /* If we got to this point, the colormap is full, so we're
1026 going to try and get the next closest color.
1027 The algorithm used is a least-squares matching, which is
1028 what X uses for closest color matching with StaticColor visuals. */
1033 long nearest_delta
, trial_delta
;
1036 no_cells
= XDisplayCells (display
, XDefaultScreen (display
));
1037 cells
= (XColor
*) alloca (sizeof (XColor
) * no_cells
);
1039 for (x
= 0; x
< no_cells
; x
++)
1042 XQueryColors (display
, screen_colormap
, cells
, no_cells
);
1044 /* I'm assuming CSE so I'm not going to condense this. */
1045 nearest_delta
= ((((color_def
->red
>> 8) - (cells
[0].red
>> 8))
1046 * ((color_def
->red
>> 8) - (cells
[0].red
>> 8)))
1048 (((color_def
->green
>> 8) - (cells
[0].green
>> 8))
1049 * ((color_def
->green
>> 8) - (cells
[0].green
>> 8)))
1051 (((color_def
->blue
>> 8) - (cells
[0].blue
>> 8))
1052 * ((color_def
->blue
>> 8) - (cells
[0].blue
>> 8))));
1053 for (x
= 1; x
< no_cells
; x
++)
1055 trial_delta
= ((((color_def
->red
>> 8) - (cells
[x
].red
>> 8))
1056 * ((color_def
->red
>> 8) - (cells
[x
].red
>> 8)))
1058 (((color_def
->green
>> 8) - (cells
[x
].green
>> 8))
1059 * ((color_def
->green
>> 8) - (cells
[x
].green
>> 8)))
1061 (((color_def
->blue
>> 8) - (cells
[x
].blue
>> 8))
1062 * ((color_def
->blue
>> 8) - (cells
[x
].blue
>> 8))));
1063 if (trial_delta
< nearest_delta
)
1066 nearest_delta
= trial_delta
;
1069 color_def
->red
= cells
[nearest
].red
;
1070 color_def
->green
= cells
[nearest
].green
;
1071 color_def
->blue
= cells
[nearest
].blue
;
1072 status
= XAllocColor (display
, screen_colormap
, color_def
);
1083 /* Given a string ARG naming a color, compute a pixel value from it
1084 suitable for screen F.
1085 If F is not a color screen, return DEF (default) regardless of what
1089 x_decode_color (f
, arg
, def
)
1096 CHECK_STRING (arg
, 0);
1098 if (strcmp (XSTRING (arg
)->data
, "black") == 0)
1099 return BLACK_PIX_DEFAULT (f
);
1100 else if (strcmp (XSTRING (arg
)->data
, "white") == 0)
1101 return WHITE_PIX_DEFAULT (f
);
1103 if (FRAME_X_DISPLAY_INFO (f
)->n_planes
== 1)
1106 /* defined_color is responsible for coping with failures
1107 by looking for a near-miss. */
1108 if (defined_color (f
, XSTRING (arg
)->data
, &cdef
, 1))
1111 /* defined_color failed; return an ultimate default. */
1115 /* Functions called only from `x_set_frame_param'
1116 to set individual parameters.
1118 If FRAME_X_WINDOW (f) is 0,
1119 the frame is being created and its X-window does not exist yet.
1120 In that case, just record the parameter's new value
1121 in the standard place; do not attempt to change the window. */
1124 x_set_foreground_color (f
, arg
, oldval
)
1126 Lisp_Object arg
, oldval
;
1128 f
->display
.x
->foreground_pixel
1129 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1130 if (FRAME_X_WINDOW (f
) != 0)
1133 XSetForeground (FRAME_X_DISPLAY (f
), f
->display
.x
->normal_gc
,
1134 f
->display
.x
->foreground_pixel
);
1135 XSetBackground (FRAME_X_DISPLAY (f
), f
->display
.x
->reverse_gc
,
1136 f
->display
.x
->foreground_pixel
);
1138 recompute_basic_faces (f
);
1139 if (FRAME_VISIBLE_P (f
))
1145 x_set_background_color (f
, arg
, oldval
)
1147 Lisp_Object arg
, oldval
;
1152 f
->display
.x
->background_pixel
1153 = x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
1155 if (FRAME_X_WINDOW (f
) != 0)
1158 /* The main frame area. */
1159 XSetBackground (FRAME_X_DISPLAY (f
), f
->display
.x
->normal_gc
,
1160 f
->display
.x
->background_pixel
);
1161 XSetForeground (FRAME_X_DISPLAY (f
), f
->display
.x
->reverse_gc
,
1162 f
->display
.x
->background_pixel
);
1163 XSetForeground (FRAME_X_DISPLAY (f
), f
->display
.x
->cursor_gc
,
1164 f
->display
.x
->background_pixel
);
1165 XSetWindowBackground (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1166 f
->display
.x
->background_pixel
);
1169 for (bar
= FRAME_SCROLL_BARS (f
); !NILP (bar
);
1170 bar
= XSCROLL_BAR (bar
)->next
)
1171 XSetWindowBackground (FRAME_X_DISPLAY (f
),
1172 SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
)),
1173 f
->display
.x
->background_pixel
);
1177 recompute_basic_faces (f
);
1179 if (FRAME_VISIBLE_P (f
))
1185 x_set_mouse_color (f
, arg
, oldval
)
1187 Lisp_Object arg
, oldval
;
1189 Cursor cursor
, nontext_cursor
, mode_cursor
, cross_cursor
;
1192 if (!EQ (Qnil
, arg
))
1193 f
->display
.x
->mouse_pixel
1194 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1195 mask_color
= f
->display
.x
->background_pixel
;
1196 /* No invisible pointers. */
1197 if (mask_color
== f
->display
.x
->mouse_pixel
1198 && mask_color
== f
->display
.x
->background_pixel
)
1199 f
->display
.x
->mouse_pixel
= f
->display
.x
->foreground_pixel
;
1203 /* It's not okay to crash if the user selects a screwy cursor. */
1204 x_catch_errors (FRAME_X_DISPLAY (f
));
1206 if (!EQ (Qnil
, Vx_pointer_shape
))
1208 CHECK_NUMBER (Vx_pointer_shape
, 0);
1209 cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XINT (Vx_pointer_shape
));
1212 cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_xterm
);
1213 x_check_errors (FRAME_X_DISPLAY (f
), "bad text pointer cursor: %s");
1215 if (!EQ (Qnil
, Vx_nontext_pointer_shape
))
1217 CHECK_NUMBER (Vx_nontext_pointer_shape
, 0);
1218 nontext_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
),
1219 XINT (Vx_nontext_pointer_shape
));
1222 nontext_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_left_ptr
);
1223 x_check_errors (FRAME_X_DISPLAY (f
), "bad nontext pointer cursor: %s");
1225 if (!EQ (Qnil
, Vx_mode_pointer_shape
))
1227 CHECK_NUMBER (Vx_mode_pointer_shape
, 0);
1228 mode_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
),
1229 XINT (Vx_mode_pointer_shape
));
1232 mode_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_xterm
);
1233 x_check_errors (FRAME_X_DISPLAY (f
), "bad modeline pointer cursor: %s");
1235 if (!EQ (Qnil
, Vx_sensitive_text_pointer_shape
))
1237 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
, 0);
1239 = XCreateFontCursor (FRAME_X_DISPLAY (f
),
1240 XINT (Vx_sensitive_text_pointer_shape
));
1243 cross_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_crosshair
);
1245 /* Check and report errors with the above calls. */
1246 x_check_errors (FRAME_X_DISPLAY (f
), "can't set cursor shape: %s");
1247 x_uncatch_errors (FRAME_X_DISPLAY (f
));
1250 XColor fore_color
, back_color
;
1252 fore_color
.pixel
= f
->display
.x
->mouse_pixel
;
1253 back_color
.pixel
= mask_color
;
1254 XQueryColor (FRAME_X_DISPLAY (f
),
1255 DefaultColormap (FRAME_X_DISPLAY (f
),
1256 DefaultScreen (FRAME_X_DISPLAY (f
))),
1258 XQueryColor (FRAME_X_DISPLAY (f
),
1259 DefaultColormap (FRAME_X_DISPLAY (f
),
1260 DefaultScreen (FRAME_X_DISPLAY (f
))),
1262 XRecolorCursor (FRAME_X_DISPLAY (f
), cursor
,
1263 &fore_color
, &back_color
);
1264 XRecolorCursor (FRAME_X_DISPLAY (f
), nontext_cursor
,
1265 &fore_color
, &back_color
);
1266 XRecolorCursor (FRAME_X_DISPLAY (f
), mode_cursor
,
1267 &fore_color
, &back_color
);
1268 XRecolorCursor (FRAME_X_DISPLAY (f
), cross_cursor
,
1269 &fore_color
, &back_color
);
1272 if (FRAME_X_WINDOW (f
) != 0)
1274 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
1277 if (cursor
!= f
->display
.x
->text_cursor
&& f
->display
.x
->text_cursor
!= 0)
1278 XFreeCursor (FRAME_X_DISPLAY (f
), f
->display
.x
->text_cursor
);
1279 f
->display
.x
->text_cursor
= cursor
;
1281 if (nontext_cursor
!= f
->display
.x
->nontext_cursor
1282 && f
->display
.x
->nontext_cursor
!= 0)
1283 XFreeCursor (FRAME_X_DISPLAY (f
), f
->display
.x
->nontext_cursor
);
1284 f
->display
.x
->nontext_cursor
= nontext_cursor
;
1286 if (mode_cursor
!= f
->display
.x
->modeline_cursor
1287 && f
->display
.x
->modeline_cursor
!= 0)
1288 XFreeCursor (FRAME_X_DISPLAY (f
), f
->display
.x
->modeline_cursor
);
1289 f
->display
.x
->modeline_cursor
= mode_cursor
;
1290 if (cross_cursor
!= f
->display
.x
->cross_cursor
1291 && f
->display
.x
->cross_cursor
!= 0)
1292 XFreeCursor (FRAME_X_DISPLAY (f
), f
->display
.x
->cross_cursor
);
1293 f
->display
.x
->cross_cursor
= cross_cursor
;
1295 XFlush (FRAME_X_DISPLAY (f
));
1300 x_set_cursor_color (f
, arg
, oldval
)
1302 Lisp_Object arg
, oldval
;
1304 unsigned long fore_pixel
;
1306 if (!EQ (Vx_cursor_fore_pixel
, Qnil
))
1307 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
1308 WHITE_PIX_DEFAULT (f
));
1310 fore_pixel
= f
->display
.x
->background_pixel
;
1311 f
->display
.x
->cursor_pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1313 /* Make sure that the cursor color differs from the background color. */
1314 if (f
->display
.x
->cursor_pixel
== f
->display
.x
->background_pixel
)
1316 f
->display
.x
->cursor_pixel
= f
->display
.x
->mouse_pixel
;
1317 if (f
->display
.x
->cursor_pixel
== fore_pixel
)
1318 fore_pixel
= f
->display
.x
->background_pixel
;
1320 f
->display
.x
->cursor_foreground_pixel
= fore_pixel
;
1322 if (FRAME_X_WINDOW (f
) != 0)
1325 XSetBackground (FRAME_X_DISPLAY (f
), f
->display
.x
->cursor_gc
,
1326 f
->display
.x
->cursor_pixel
);
1327 XSetForeground (FRAME_X_DISPLAY (f
), f
->display
.x
->cursor_gc
,
1331 if (FRAME_VISIBLE_P (f
))
1333 x_display_cursor (f
, 0);
1334 x_display_cursor (f
, 1);
1339 /* Set the border-color of frame F to value described by ARG.
1340 ARG can be a string naming a color.
1341 The border-color is used for the border that is drawn by the X server.
1342 Note that this does not fully take effect if done before
1343 F has an x-window; it must be redone when the window is created.
1345 Note: this is done in two routines because of the way X10 works.
1347 Note: under X11, this is normally the province of the window manager,
1348 and so emacs' border colors may be overridden. */
1351 x_set_border_color (f
, arg
, oldval
)
1353 Lisp_Object arg
, oldval
;
1358 CHECK_STRING (arg
, 0);
1359 str
= XSTRING (arg
)->data
;
1361 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1363 x_set_border_pixel (f
, pix
);
1366 /* Set the border-color of frame F to pixel value PIX.
1367 Note that this does not fully take effect if done before
1368 F has an x-window. */
1370 x_set_border_pixel (f
, pix
)
1374 f
->display
.x
->border_pixel
= pix
;
1376 if (FRAME_X_WINDOW (f
) != 0 && f
->display
.x
->border_width
> 0)
1382 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1386 if (FRAME_VISIBLE_P (f
))
1392 x_set_cursor_type (f
, arg
, oldval
)
1394 Lisp_Object arg
, oldval
;
1398 FRAME_DESIRED_CURSOR (f
) = bar_cursor
;
1399 f
->display
.x
->cursor_width
= 2;
1401 else if (CONSP (arg
) && EQ (XCONS (arg
)->car
, Qbar
)
1402 && INTEGERP (XCONS (arg
)->cdr
))
1404 FRAME_DESIRED_CURSOR (f
) = bar_cursor
;
1405 f
->display
.x
->cursor_width
= XINT (XCONS (arg
)->cdr
);
1408 /* Treat anything unknown as "box cursor".
1409 It was bad to signal an error; people have trouble fixing
1410 .Xdefaults with Emacs, when it has something bad in it. */
1411 FRAME_DESIRED_CURSOR (f
) = filled_box_cursor
;
1413 /* Make sure the cursor gets redrawn. This is overkill, but how
1414 often do people change cursor types? */
1415 update_mode_lines
++;
1419 x_set_icon_type (f
, arg
, oldval
)
1421 Lisp_Object arg
, oldval
;
1428 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1431 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1436 result
= x_text_icon (f
, 0);
1438 result
= x_bitmap_icon (f
, arg
);
1443 error ("No icon window available");
1446 /* If the window was unmapped (and its icon was mapped),
1447 the new icon is not mapped, so map the window in its stead. */
1448 if (FRAME_VISIBLE_P (f
))
1450 #ifdef USE_X_TOOLKIT
1451 XtPopup (f
->display
.x
->widget
, XtGrabNone
);
1453 XMapWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
1456 XFlush (FRAME_X_DISPLAY (f
));
1460 /* Return non-nil if frame F wants a bitmap icon. */
1468 tem
= assq_no_quit (Qicon_type
, f
->param_alist
);
1470 return XCONS (tem
)->cdr
;
1475 extern Lisp_Object
x_new_font ();
1478 x_set_font (f
, arg
, oldval
)
1480 Lisp_Object arg
, oldval
;
1484 CHECK_STRING (arg
, 1);
1487 result
= x_new_font (f
, XSTRING (arg
)->data
);
1490 if (EQ (result
, Qnil
))
1491 error ("Font \"%s\" is not defined", XSTRING (arg
)->data
);
1492 else if (EQ (result
, Qt
))
1493 error ("the characters of the given font have varying widths");
1494 else if (STRINGP (result
))
1496 recompute_basic_faces (f
);
1497 store_frame_param (f
, Qfont
, result
);
1504 x_set_border_width (f
, arg
, oldval
)
1506 Lisp_Object arg
, oldval
;
1508 CHECK_NUMBER (arg
, 0);
1510 if (XINT (arg
) == f
->display
.x
->border_width
)
1513 if (FRAME_X_WINDOW (f
) != 0)
1514 error ("Cannot change the border width of a window");
1516 f
->display
.x
->border_width
= XINT (arg
);
1520 x_set_internal_border_width (f
, arg
, oldval
)
1522 Lisp_Object arg
, oldval
;
1525 int old
= f
->display
.x
->internal_border_width
;
1527 CHECK_NUMBER (arg
, 0);
1528 f
->display
.x
->internal_border_width
= XINT (arg
);
1529 if (f
->display
.x
->internal_border_width
< 0)
1530 f
->display
.x
->internal_border_width
= 0;
1532 if (f
->display
.x
->internal_border_width
== old
)
1535 if (FRAME_X_WINDOW (f
) != 0)
1538 x_set_window_size (f
, 0, f
->width
, f
->height
);
1540 x_set_resize_hint (f
);
1542 XFlush (FRAME_X_DISPLAY (f
));
1544 SET_FRAME_GARBAGED (f
);
1549 x_set_visibility (f
, value
, oldval
)
1551 Lisp_Object value
, oldval
;
1554 XSETFRAME (frame
, f
);
1557 Fmake_frame_invisible (frame
, Qt
);
1558 else if (EQ (value
, Qicon
))
1559 Ficonify_frame (frame
);
1561 Fmake_frame_visible (frame
);
1565 x_set_menu_bar_lines_1 (window
, n
)
1569 struct window
*w
= XWINDOW (window
);
1571 XSETFASTINT (w
->top
, XFASTINT (w
->top
) + n
);
1572 XSETFASTINT (w
->height
, XFASTINT (w
->height
) - n
);
1574 /* Handle just the top child in a vertical split. */
1575 if (!NILP (w
->vchild
))
1576 x_set_menu_bar_lines_1 (w
->vchild
, n
);
1578 /* Adjust all children in a horizontal split. */
1579 for (window
= w
->hchild
; !NILP (window
); window
= w
->next
)
1581 w
= XWINDOW (window
);
1582 x_set_menu_bar_lines_1 (window
, n
);
1587 x_set_menu_bar_lines (f
, value
, oldval
)
1589 Lisp_Object value
, oldval
;
1592 int olines
= FRAME_MENU_BAR_LINES (f
);
1594 /* Right now, menu bars don't work properly in minibuf-only frames;
1595 most of the commands try to apply themselves to the minibuffer
1596 frame itslef, and get an error because you can't switch buffers
1597 in or split the minibuffer window. */
1598 if (FRAME_MINIBUF_ONLY_P (f
))
1601 if (INTEGERP (value
))
1602 nlines
= XINT (value
);
1606 #ifdef USE_X_TOOLKIT
1607 FRAME_MENU_BAR_LINES (f
) = 0;
1609 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
1612 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
1613 free_frame_menubar (f
);
1614 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
1615 f
->display
.x
->menubar_widget
= 0;
1617 #else /* not USE_X_TOOLKIT */
1618 FRAME_MENU_BAR_LINES (f
) = nlines
;
1619 x_set_menu_bar_lines_1 (f
->root_window
, nlines
- olines
);
1620 #endif /* not USE_X_TOOLKIT */
1623 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1626 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1627 name; if NAME is a string, set F's name to NAME and set
1628 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1630 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1631 suggesting a new name, which lisp code should override; if
1632 F->explicit_name is set, ignore the new name; otherwise, set it. */
1635 x_set_name (f
, name
, explicit)
1640 /* Make sure that requests from lisp code override requests from
1641 Emacs redisplay code. */
1644 /* If we're switching from explicit to implicit, we had better
1645 update the mode lines and thereby update the title. */
1646 if (f
->explicit_name
&& NILP (name
))
1647 update_mode_lines
= 1;
1649 f
->explicit_name
= ! NILP (name
);
1651 else if (f
->explicit_name
)
1654 /* If NAME is nil, set the name to the x_id_name. */
1657 /* Check for no change needed in this very common case
1658 before we do any consing. */
1659 if (!strcmp (FRAME_X_DISPLAY_INFO (f
)->x_id_name
,
1660 XSTRING (f
->name
)->data
))
1662 name
= build_string (FRAME_X_DISPLAY_INFO (f
)->x_id_name
);
1665 CHECK_STRING (name
, 0);
1667 /* Don't change the name if it's already NAME. */
1668 if (! NILP (Fstring_equal (name
, f
->name
)))
1671 if (FRAME_X_WINDOW (f
))
1677 text
.value
= XSTRING (name
)->data
;
1678 text
.encoding
= XA_STRING
;
1680 text
.nitems
= XSTRING (name
)->size
;
1681 #ifdef USE_X_TOOLKIT
1682 XSetWMName (FRAME_X_DISPLAY (f
),
1683 XtWindow (f
->display
.x
->widget
), &text
);
1684 XSetWMIconName (FRAME_X_DISPLAY (f
), XtWindow (f
->display
.x
->widget
),
1686 #else /* not USE_X_TOOLKIT */
1687 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &text
);
1688 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &text
);
1689 #endif /* not USE_X_TOOLKIT */
1691 #else /* not HAVE_X11R4 */
1692 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1693 XSTRING (name
)->data
);
1694 XStoreName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1695 XSTRING (name
)->data
);
1696 #endif /* not HAVE_X11R4 */
1703 /* This function should be called when the user's lisp code has
1704 specified a name for the frame; the name will override any set by the
1707 x_explicitly_set_name (f
, arg
, oldval
)
1709 Lisp_Object arg
, oldval
;
1711 x_set_name (f
, arg
, 1);
1714 /* This function should be called by Emacs redisplay code to set the
1715 name; names set this way will never override names set by the user's
1718 x_implicitly_set_name (f
, arg
, oldval
)
1720 Lisp_Object arg
, oldval
;
1722 x_set_name (f
, arg
, 0);
1726 x_set_autoraise (f
, arg
, oldval
)
1728 Lisp_Object arg
, oldval
;
1730 f
->auto_raise
= !EQ (Qnil
, arg
);
1734 x_set_autolower (f
, arg
, oldval
)
1736 Lisp_Object arg
, oldval
;
1738 f
->auto_lower
= !EQ (Qnil
, arg
);
1742 x_set_unsplittable (f
, arg
, oldval
)
1744 Lisp_Object arg
, oldval
;
1746 f
->no_split
= !NILP (arg
);
1750 x_set_vertical_scroll_bars (f
, arg
, oldval
)
1752 Lisp_Object arg
, oldval
;
1754 if (NILP (arg
) != ! FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
1756 FRAME_HAS_VERTICAL_SCROLL_BARS (f
) = ! NILP (arg
);
1758 /* We set this parameter before creating the X window for the
1759 frame, so we can get the geometry right from the start.
1760 However, if the window hasn't been created yet, we shouldn't
1761 call x_set_window_size. */
1762 if (FRAME_X_WINDOW (f
))
1763 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
1768 x_set_scroll_bar_width (f
, arg
, oldval
)
1770 Lisp_Object arg
, oldval
;
1774 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = 0;
1775 FRAME_SCROLL_BAR_COLS (f
) = 2;
1777 else if (INTEGERP (arg
) && XINT (arg
) > 0
1778 && XFASTINT (arg
) != FRAME_SCROLL_BAR_PIXEL_WIDTH (f
))
1780 int wid
= FONT_WIDTH (f
->display
.x
->font
);
1781 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = XFASTINT (arg
);
1782 FRAME_SCROLL_BAR_COLS (f
) = (XFASTINT (arg
) + wid
-1) / wid
;
1783 if (FRAME_X_WINDOW (f
))
1784 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
1788 /* Subroutines of creating an X frame. */
1790 /* Make sure that Vx_resource_name is set to a reasonable value. */
1792 validate_x_resource_name ()
1795 /* Number of valid characters in the resource name. */
1797 /* Number of invalid characters in the resource name. */
1802 if (STRINGP (Vx_resource_name
))
1804 unsigned char *p
= XSTRING (Vx_resource_name
)->data
;
1807 len
= XSTRING (Vx_resource_name
)->size
;
1809 /* Only letters, digits, - and _ are valid in resource names.
1810 Count the valid characters and count the invalid ones. */
1811 for (i
= 0; i
< len
; i
++)
1814 if (! ((c
>= 'a' && c
<= 'z')
1815 || (c
>= 'A' && c
<= 'Z')
1816 || (c
>= '0' && c
<= '9')
1817 || c
== '-' || c
== '_'))
1824 /* Not a string => completely invalid. */
1825 bad_count
= 5, good_count
= 0;
1827 /* If name is valid already, return. */
1831 /* If name is entirely invalid, or nearly so, use `emacs'. */
1833 || (good_count
== 1 && bad_count
> 0))
1835 Vx_resource_name
= make_string ("emacs", 5);
1839 /* Name is partly valid. Copy it and replace the invalid characters
1840 with underscores. */
1842 Vx_resource_name
= new = Fcopy_sequence (Vx_resource_name
);
1844 for (i
= 0; i
< len
; i
++)
1846 int c
= XSTRING (new)->data
[i
];
1847 if (! ((c
>= 'a' && c
<= 'z')
1848 || (c
>= 'A' && c
<= 'Z')
1849 || (c
>= '0' && c
<= '9')
1850 || c
== '-' || c
== '_'))
1851 XSTRING (new)->data
[i
] = '_';
1856 extern char *x_get_string_resource ();
1858 DEFUN ("x-get-resource", Fx_get_resource
, Sx_get_resource
, 2, 4, 0,
1859 "Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.\n\
1860 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the\n\
1861 class, where INSTANCE is the name under which Emacs was invoked, or\n\
1862 the name specified by the `-name' or `-rn' command-line arguments.\n\
1864 The optional arguments COMPONENT and SUBCLASS add to the key and the\n\
1865 class, respectively. You must specify both of them or neither.\n\
1866 If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'\n\
1867 and the class is `Emacs.CLASS.SUBCLASS'.")
1868 (attribute
, class, component
, subclass
)
1869 Lisp_Object attribute
, class, component
, subclass
;
1871 register char *value
;
1874 Lisp_Object resname
;
1878 CHECK_STRING (attribute
, 0);
1879 CHECK_STRING (class, 0);
1881 if (!NILP (component
))
1882 CHECK_STRING (component
, 1);
1883 if (!NILP (subclass
))
1884 CHECK_STRING (subclass
, 2);
1885 if (NILP (component
) != NILP (subclass
))
1886 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
1888 validate_x_resource_name ();
1889 resname
= Vx_resource_name
;
1891 if (NILP (component
))
1893 /* Allocate space for the components, the dots which separate them,
1894 and the final '\0'. */
1895 name_key
= (char *) alloca (XSTRING (resname
)->size
1896 + XSTRING (attribute
)->size
1898 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
1899 + XSTRING (class)->size
1902 sprintf (name_key
, "%s.%s",
1903 XSTRING (resname
)->data
,
1904 XSTRING (attribute
)->data
);
1905 sprintf (class_key
, "%s.%s",
1907 XSTRING (class)->data
);
1911 name_key
= (char *) alloca (XSTRING (resname
)->size
1912 + XSTRING (component
)->size
1913 + XSTRING (attribute
)->size
1916 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
1917 + XSTRING (class)->size
1918 + XSTRING (subclass
)->size
1921 sprintf (name_key
, "%s.%s.%s",
1922 XSTRING (resname
)->data
,
1923 XSTRING (component
)->data
,
1924 XSTRING (attribute
)->data
);
1925 sprintf (class_key
, "%s.%s.%s",
1927 XSTRING (class)->data
,
1928 XSTRING (subclass
)->data
);
1931 value
= x_get_string_resource (check_x_display_info (Qnil
)->xrdb
,
1932 name_key
, class_key
);
1934 if (value
!= (char *) 0)
1935 return build_string (value
);
1940 /* Used when C code wants a resource value. */
1943 x_get_resource_string (attribute
, class)
1944 char *attribute
, *class;
1946 register char *value
;
1950 /* Allocate space for the components, the dots which separate them,
1951 and the final '\0'. */
1952 name_key
= (char *) alloca (XSTRING (Vinvocation_name
)->size
1953 + strlen (attribute
) + 2);
1954 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
1955 + strlen (class) + 2);
1957 sprintf (name_key
, "%s.%s",
1958 XSTRING (Vinvocation_name
)->data
,
1960 sprintf (class_key
, "%s.%s", EMACS_CLASS
, class);
1962 return x_get_string_resource (FRAME_X_DISPLAY_INFO (selected_frame
)->xrdb
,
1963 name_key
, class_key
);
1966 /* Types we might convert a resource string into. */
1969 number
, boolean
, string
, symbol
1972 /* Return the value of parameter PARAM.
1974 First search ALIST, then Vdefault_frame_alist, then the X defaults
1975 database, using ATTRIBUTE as the attribute name and CLASS as its class.
1977 Convert the resource to the type specified by desired_type.
1979 If no default is specified, return Qunbound. If you call
1980 x_get_arg, make sure you deal with Qunbound in a reasonable way,
1981 and don't let it get stored in any Lisp-visible variables! */
1984 x_get_arg (alist
, param
, attribute
, class, type
)
1985 Lisp_Object alist
, param
;
1988 enum resource_types type
;
1990 register Lisp_Object tem
;
1992 tem
= Fassq (param
, alist
);
1994 tem
= Fassq (param
, Vdefault_frame_alist
);
2000 tem
= Fx_get_resource (build_string (attribute
),
2001 build_string (class),
2010 return make_number (atoi (XSTRING (tem
)->data
));
2013 tem
= Fdowncase (tem
);
2014 if (!strcmp (XSTRING (tem
)->data
, "on")
2015 || !strcmp (XSTRING (tem
)->data
, "true"))
2024 /* As a special case, we map the values `true' and `on'
2025 to Qt, and `false' and `off' to Qnil. */
2028 lower
= Fdowncase (tem
);
2029 if (!strcmp (XSTRING (lower
)->data
, "on")
2030 || !strcmp (XSTRING (lower
)->data
, "true"))
2032 else if (!strcmp (XSTRING (lower
)->data
, "off")
2033 || !strcmp (XSTRING (lower
)->data
, "false"))
2036 return Fintern (tem
, Qnil
);
2049 /* Record in frame F the specified or default value according to ALIST
2050 of the parameter named PARAM (a Lisp symbol).
2051 If no value is specified for PARAM, look for an X default for XPROP
2052 on the frame named NAME.
2053 If that is not found either, use the value DEFLT. */
2056 x_default_parameter (f
, alist
, prop
, deflt
, xprop
, xclass
, type
)
2063 enum resource_types type
;
2067 tem
= x_get_arg (alist
, prop
, xprop
, xclass
, type
);
2068 if (EQ (tem
, Qunbound
))
2070 x_set_frame_parameters (f
, Fcons (Fcons (prop
, tem
), Qnil
));
2074 DEFUN ("x-parse-geometry", Fx_parse_geometry
, Sx_parse_geometry
, 1, 1, 0,
2075 "Parse an X-style geometry string STRING.\n\
2076 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).\n\
2077 The properties returned may include `top', `left', `height', and `width'.\n\
2078 The value of `left' or `top' may be an integer,\n\
2079 or a list (+ N) meaning N pixels relative to top/left corner,\n\
2080 or a list (- N) meaning -N pixels relative to bottom/right corner.")
2085 unsigned int width
, height
;
2088 CHECK_STRING (string
, 0);
2090 geometry
= XParseGeometry ((char *) XSTRING (string
)->data
,
2091 &x
, &y
, &width
, &height
);
2094 if (!!(geometry
& XValue
) != !!(geometry
& YValue
))
2095 error ("Must specify both x and y position, or neither");
2099 if (geometry
& XValue
)
2101 Lisp_Object element
;
2103 if (x
>= 0 && (geometry
& XNegative
))
2104 element
= Fcons (Qleft
, Fcons (Qminus
, Fcons (make_number (-x
), Qnil
)));
2105 else if (x
< 0 && ! (geometry
& XNegative
))
2106 element
= Fcons (Qleft
, Fcons (Qplus
, Fcons (make_number (x
), Qnil
)));
2108 element
= Fcons (Qleft
, make_number (x
));
2109 result
= Fcons (element
, result
);
2112 if (geometry
& YValue
)
2114 Lisp_Object element
;
2116 if (y
>= 0 && (geometry
& YNegative
))
2117 element
= Fcons (Qtop
, Fcons (Qminus
, Fcons (make_number (-y
), Qnil
)));
2118 else if (y
< 0 && ! (geometry
& YNegative
))
2119 element
= Fcons (Qtop
, Fcons (Qplus
, Fcons (make_number (y
), Qnil
)));
2121 element
= Fcons (Qtop
, make_number (y
));
2122 result
= Fcons (element
, result
);
2125 if (geometry
& WidthValue
)
2126 result
= Fcons (Fcons (Qwidth
, make_number (width
)), result
);
2127 if (geometry
& HeightValue
)
2128 result
= Fcons (Fcons (Qheight
, make_number (height
)), result
);
2133 /* Calculate the desired size and position of this window,
2134 and return the flags saying which aspects were specified.
2136 This function does not make the coordinates positive. */
2138 #define DEFAULT_ROWS 40
2139 #define DEFAULT_COLS 80
2142 x_figure_window_size (f
, parms
)
2146 register Lisp_Object tem0
, tem1
, tem2
;
2147 int height
, width
, left
, top
;
2148 register int geometry
;
2149 long window_prompting
= 0;
2151 /* Default values if we fall through.
2152 Actually, if that happens we should get
2153 window manager prompting. */
2154 f
->width
= DEFAULT_COLS
;
2155 f
->height
= DEFAULT_ROWS
;
2156 /* Window managers expect that if program-specified
2157 positions are not (0,0), they're intentional, not defaults. */
2158 f
->display
.x
->top_pos
= 0;
2159 f
->display
.x
->left_pos
= 0;
2161 tem0
= x_get_arg (parms
, Qheight
, 0, 0, number
);
2162 tem1
= x_get_arg (parms
, Qwidth
, 0, 0, number
);
2163 tem2
= x_get_arg (parms
, Quser_size
, 0, 0, number
);
2164 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
2166 if (!EQ (tem0
, Qunbound
))
2168 CHECK_NUMBER (tem0
, 0);
2169 f
->height
= XINT (tem0
);
2171 if (!EQ (tem1
, Qunbound
))
2173 CHECK_NUMBER (tem1
, 0);
2174 f
->width
= XINT (tem1
);
2176 if (!NILP (tem2
) && !EQ (tem2
, Qunbound
))
2177 window_prompting
|= USSize
;
2179 window_prompting
|= PSize
;
2182 f
->display
.x
->vertical_scroll_bar_extra
2183 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
2185 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0
2186 ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f
)
2187 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->display
.x
->font
)));
2188 f
->display
.x
->pixel_width
= CHAR_TO_PIXEL_WIDTH (f
, f
->width
);
2189 f
->display
.x
->pixel_height
= CHAR_TO_PIXEL_HEIGHT (f
, f
->height
);
2191 tem0
= x_get_arg (parms
, Qtop
, 0, 0, number
);
2192 tem1
= x_get_arg (parms
, Qleft
, 0, 0, number
);
2193 tem2
= x_get_arg (parms
, Quser_position
, 0, 0, number
);
2194 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
2196 if (EQ (tem0
, Qminus
))
2198 f
->display
.x
->top_pos
= 0;
2199 window_prompting
|= YNegative
;
2201 else if (CONSP (tem0
) && EQ (XCONS (tem0
)->car
, Qminus
)
2202 && CONSP (XCONS (tem0
)->cdr
)
2203 && INTEGERP (XCONS (XCONS (tem0
)->cdr
)->car
))
2205 f
->display
.x
->top_pos
= - XINT (XCONS (XCONS (tem0
)->cdr
)->car
);
2206 window_prompting
|= YNegative
;
2208 else if (CONSP (tem0
) && EQ (XCONS (tem0
)->car
, Qplus
)
2209 && CONSP (XCONS (tem0
)->cdr
)
2210 && INTEGERP (XCONS (XCONS (tem0
)->cdr
)->car
))
2212 f
->display
.x
->top_pos
= XINT (XCONS (XCONS (tem0
)->cdr
)->car
);
2214 else if (EQ (tem0
, Qunbound
))
2215 f
->display
.x
->top_pos
= 0;
2218 CHECK_NUMBER (tem0
, 0);
2219 f
->display
.x
->top_pos
= XINT (tem0
);
2220 if (f
->display
.x
->top_pos
< 0)
2221 window_prompting
|= YNegative
;
2224 if (EQ (tem1
, Qminus
))
2226 f
->display
.x
->left_pos
= 0;
2227 window_prompting
|= XNegative
;
2229 else if (CONSP (tem1
) && EQ (XCONS (tem1
)->car
, Qminus
)
2230 && CONSP (XCONS (tem1
)->cdr
)
2231 && INTEGERP (XCONS (XCONS (tem1
)->cdr
)->car
))
2233 f
->display
.x
->left_pos
= - XINT (XCONS (XCONS (tem1
)->cdr
)->car
);
2234 window_prompting
|= XNegative
;
2236 else if (CONSP (tem1
) && EQ (XCONS (tem1
)->car
, Qplus
)
2237 && CONSP (XCONS (tem1
)->cdr
)
2238 && INTEGERP (XCONS (XCONS (tem1
)->cdr
)->car
))
2240 f
->display
.x
->left_pos
= XINT (XCONS (XCONS (tem1
)->cdr
)->car
);
2242 else if (EQ (tem1
, Qunbound
))
2243 f
->display
.x
->left_pos
= 0;
2246 CHECK_NUMBER (tem1
, 0);
2247 f
->display
.x
->left_pos
= XINT (tem1
);
2248 if (f
->display
.x
->left_pos
< 0)
2249 window_prompting
|= XNegative
;
2252 if (!NILP (tem2
) && ! EQ (tem2
, Qunbound
))
2253 window_prompting
|= USPosition
;
2255 window_prompting
|= PPosition
;
2258 return window_prompting
;
2261 #if !defined (HAVE_X11R4) && !defined (HAVE_XSETWMPROTOCOLS)
2264 XSetWMProtocols (dpy
, w
, protocols
, count
)
2271 prop
= XInternAtom (dpy
, "WM_PROTOCOLS", False
);
2272 if (prop
== None
) return False
;
2273 XChangeProperty (dpy
, w
, prop
, XA_ATOM
, 32, PropModeReplace
,
2274 (unsigned char *) protocols
, count
);
2277 #endif /* not HAVE_X11R4 && not HAVE_XSETWMPROTOCOLS */
2279 #ifdef USE_X_TOOLKIT
2281 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
2282 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
2283 already be present because of the toolkit (Motif adds some of them,
2284 for example, but Xt doesn't). */
2287 hack_wm_protocols (f
, widget
)
2291 Display
*dpy
= XtDisplay (widget
);
2292 Window w
= XtWindow (widget
);
2293 int need_delete
= 1;
2299 Atom type
, *atoms
= 0;
2301 unsigned long nitems
= 0;
2302 unsigned long bytes_after
;
2304 if (Success
== XGetWindowProperty (dpy
, w
,
2305 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2306 0, 100, False
, XA_ATOM
,
2307 &type
, &format
, &nitems
, &bytes_after
,
2308 (unsigned char **) &atoms
)
2309 && format
== 32 && type
== XA_ATOM
)
2313 if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
)
2315 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
)
2317 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
)
2320 if (atoms
) XFree ((char *) atoms
);
2326 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2328 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
;
2330 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2332 XChangeProperty (dpy
, w
, FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2333 XA_ATOM
, 32, PropModeAppend
,
2334 (unsigned char *) props
, count
);
2340 #ifdef USE_X_TOOLKIT
2342 /* Create and set up the X widget for frame F. */
2345 x_window (f
, window_prompting
, minibuffer_only
)
2347 long window_prompting
;
2348 int minibuffer_only
;
2350 XClassHint class_hints
;
2351 XSetWindowAttributes attributes
;
2352 unsigned long attribute_mask
;
2354 Widget shell_widget
;
2356 Widget frame_widget
;
2364 = (STRINGP (f
->name
) ? (char *)XSTRING (f
->name
)->data
: "emacs");
2365 f
->namebuf
= (char *) xrealloc (f
->namebuf
, strlen (str
) + 1);
2366 strcpy (f
->namebuf
, str
);
2370 XtSetArg (al
[ac
], XtNallowShellResize
, 1); ac
++;
2371 XtSetArg (al
[ac
], XtNinput
, 1); ac
++;
2372 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2373 shell_widget
= XtAppCreateShell (f
->namebuf
, EMACS_CLASS
,
2374 topLevelShellWidgetClass
,
2375 FRAME_X_DISPLAY (f
), al
, ac
);
2377 f
->display
.x
->widget
= shell_widget
;
2378 /* maybe_set_screen_title_format (shell_widget); */
2380 pane_widget
= lw_create_widget ("main", "pane", widget_id_tick
++,
2381 (widget_value
*) NULL
,
2382 shell_widget
, False
,
2385 (lw_callback
) NULL
);
2387 f
->display
.x
->column_widget
= pane_widget
;
2389 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
2390 initialize_frame_menubar (f
);
2392 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2393 the emacs screen when changing menubar. This reduces flickering. */
2396 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2397 XtSetArg (al
[ac
], XtNshowGrip
, 0); ac
++;
2398 XtSetArg (al
[ac
], XtNallowResize
, 1); ac
++;
2399 XtSetArg (al
[ac
], XtNresizeToPreferred
, 1); ac
++;
2400 XtSetArg (al
[ac
], XtNemacsFrame
, f
); ac
++;
2401 frame_widget
= XtCreateWidget (f
->namebuf
,
2403 pane_widget
, al
, ac
);
2404 lw_set_main_areas (pane_widget
, f
->display
.x
->menubar_widget
, frame_widget
);
2406 f
->display
.x
->edit_widget
= frame_widget
;
2408 if (f
->display
.x
->menubar_widget
)
2409 XtManageChild (f
->display
.x
->menubar_widget
);
2410 XtManageChild (frame_widget
);
2412 /* Do some needed geometry management. */
2415 char *tem
, shell_position
[32];
2419 = (f
->display
.x
->menubar_widget
2420 ? (f
->display
.x
->menubar_widget
->core
.height
2421 + f
->display
.x
->menubar_widget
->core
.border_width
)
2424 if (FRAME_EXTERNAL_MENU_BAR (f
))
2427 XtVaGetValues (pane_widget
, XtNinternalBorderWidth
, &ibw
, NULL
);
2428 menubar_size
+= ibw
;
2431 /* Convert our geometry parameters into a geometry string
2433 Note that we do not specify here whether the position
2434 is a user-specified or program-specified one.
2435 We pass that information later, in x_wm_set_size_hints. */
2437 int left
= f
->display
.x
->left_pos
;
2438 int xneg
= window_prompting
& XNegative
;
2439 int top
= f
->display
.x
->top_pos
;
2440 int yneg
= window_prompting
& YNegative
;
2445 sprintf (shell_position
, "=%dx%d%c%d%c%d", PIXEL_WIDTH (f
),
2446 PIXEL_HEIGHT (f
) + menubar_size
,
2447 (xneg
? '-' : '+'), left
,
2448 (yneg
? '-' : '+'), top
);
2451 len
= strlen (shell_position
) + 1;
2452 tem
= (char *) xmalloc (len
);
2453 strncpy (tem
, shell_position
, len
);
2454 XtSetArg (al
[ac
], XtNgeometry
, tem
); ac
++;
2455 XtSetValues (shell_widget
, al
, ac
);
2458 x_calc_absolute_position (f
);
2460 XtManageChild (pane_widget
);
2461 XtRealizeWidget (shell_widget
);
2463 FRAME_X_WINDOW (f
) = XtWindow (frame_widget
);
2465 validate_x_resource_name ();
2466 class_hints
.res_name
= (char *) XSTRING (Vx_resource_name
)->data
;
2467 class_hints
.res_class
= EMACS_CLASS
;
2468 XSetClassHint (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
), &class_hints
);
2470 f
->display
.x
->wm_hints
.input
= True
;
2471 f
->display
.x
->wm_hints
.flags
|= InputHint
;
2472 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2473 &f
->display
.x
->wm_hints
);
2475 hack_wm_protocols (f
, shell_widget
);
2478 XtAddEventHandler (shell_widget
, 0, True
, _XEditResCheckMessages
, 0);
2481 /* Do a stupid property change to force the server to generate a
2482 propertyNotify event so that the event_stream server timestamp will
2483 be initialized to something relevant to the time we created the window.
2485 XChangeProperty (XtDisplay (frame_widget
), XtWindow (frame_widget
),
2486 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2487 XA_ATOM
, 32, PropModeAppend
,
2488 (unsigned char*) NULL
, 0);
2490 /* Make all the standard events reach the Emacs frame. */
2491 attributes
.event_mask
= STANDARD_EVENT_SET
;
2492 attribute_mask
= CWEventMask
;
2493 XChangeWindowAttributes (XtDisplay (shell_widget
), XtWindow (shell_widget
),
2494 attribute_mask
, &attributes
);
2496 XtMapWidget (frame_widget
);
2498 /* x_set_name normally ignores requests to set the name if the
2499 requested name is the same as the current name. This is the one
2500 place where that assumption isn't correct; f->name is set, but
2501 the X server hasn't been told. */
2504 int explicit = f
->explicit_name
;
2506 f
->explicit_name
= 0;
2509 x_set_name (f
, name
, explicit);
2512 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2513 f
->display
.x
->text_cursor
);
2517 if (FRAME_X_WINDOW (f
) == 0)
2518 error ("Unable to create window");
2521 #else /* not USE_X_TOOLKIT */
2523 /* Create and set up the X window for frame F. */
2529 XClassHint class_hints
;
2530 XSetWindowAttributes attributes
;
2531 unsigned long attribute_mask
;
2533 attributes
.background_pixel
= f
->display
.x
->background_pixel
;
2534 attributes
.border_pixel
= f
->display
.x
->border_pixel
;
2535 attributes
.bit_gravity
= StaticGravity
;
2536 attributes
.backing_store
= NotUseful
;
2537 attributes
.save_under
= True
;
2538 attributes
.event_mask
= STANDARD_EVENT_SET
;
2539 attribute_mask
= (CWBackPixel
| CWBorderPixel
| CWBitGravity
2541 | CWBackingStore
| CWSaveUnder
2547 = XCreateWindow (FRAME_X_DISPLAY (f
),
2548 f
->display
.x
->parent_desc
,
2549 f
->display
.x
->left_pos
,
2550 f
->display
.x
->top_pos
,
2551 PIXEL_WIDTH (f
), PIXEL_HEIGHT (f
),
2552 f
->display
.x
->border_width
,
2553 CopyFromParent
, /* depth */
2554 InputOutput
, /* class */
2555 FRAME_X_DISPLAY_INFO (f
)->visual
,
2556 attribute_mask
, &attributes
);
2558 validate_x_resource_name ();
2559 class_hints
.res_name
= (char *) XSTRING (Vx_resource_name
)->data
;
2560 class_hints
.res_class
= EMACS_CLASS
;
2561 XSetClassHint (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &class_hints
);
2563 /* This indicates that we use the "Passive Input" input model.
2564 Unless we do this, we don't get the Focus{In,Out} events that we
2565 need to draw the cursor correctly. Accursed bureaucrats.
2566 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2568 f
->display
.x
->wm_hints
.input
= True
;
2569 f
->display
.x
->wm_hints
.flags
|= InputHint
;
2570 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2571 &f
->display
.x
->wm_hints
);
2573 /* Request "save yourself" and "delete window" commands from wm. */
2576 protocols
[0] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2577 protocols
[1] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2578 XSetWMProtocols (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), protocols
, 2);
2581 /* x_set_name normally ignores requests to set the name if the
2582 requested name is the same as the current name. This is the one
2583 place where that assumption isn't correct; f->name is set, but
2584 the X server hasn't been told. */
2587 int explicit = f
->explicit_name
;
2589 f
->explicit_name
= 0;
2592 x_set_name (f
, name
, explicit);
2595 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2596 f
->display
.x
->text_cursor
);
2600 if (FRAME_X_WINDOW (f
) == 0)
2601 error ("Unable to create window");
2604 #endif /* not USE_X_TOOLKIT */
2606 /* Handle the icon stuff for this window. Perhaps later we might
2607 want an x_set_icon_position which can be called interactively as
2615 Lisp_Object icon_x
, icon_y
;
2617 /* Set the position of the icon. Note that twm groups all
2618 icons in an icon window. */
2619 icon_x
= x_get_arg (parms
, Qicon_left
, 0, 0, number
);
2620 icon_y
= x_get_arg (parms
, Qicon_top
, 0, 0, number
);
2621 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2623 CHECK_NUMBER (icon_x
, 0);
2624 CHECK_NUMBER (icon_y
, 0);
2626 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2627 error ("Both left and top icon corners of icon must be specified");
2631 if (! EQ (icon_x
, Qunbound
))
2632 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
2634 /* Start up iconic or window? */
2635 x_wm_set_window_state
2636 (f
, (EQ (x_get_arg (parms
, Qvisibility
, 0, 0, symbol
), Qicon
)
2643 /* Make the GC's needed for this window, setting the
2644 background, border and mouse colors; also create the
2645 mouse cursor and the gray border tile. */
2647 static char cursor_bits
[] =
2649 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2650 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2651 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2652 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2659 XGCValues gc_values
;
2665 /* Create the GC's of this frame.
2666 Note that many default values are used. */
2669 gc_values
.font
= f
->display
.x
->font
->fid
;
2670 gc_values
.foreground
= f
->display
.x
->foreground_pixel
;
2671 gc_values
.background
= f
->display
.x
->background_pixel
;
2672 gc_values
.line_width
= 0; /* Means 1 using fast algorithm. */
2673 f
->display
.x
->normal_gc
= XCreateGC (FRAME_X_DISPLAY (f
),
2675 GCLineWidth
| GCFont
2676 | GCForeground
| GCBackground
,
2679 /* Reverse video style. */
2680 gc_values
.foreground
= f
->display
.x
->background_pixel
;
2681 gc_values
.background
= f
->display
.x
->foreground_pixel
;
2682 f
->display
.x
->reverse_gc
= XCreateGC (FRAME_X_DISPLAY (f
),
2684 GCFont
| GCForeground
| GCBackground
2688 /* Cursor has cursor-color background, background-color foreground. */
2689 gc_values
.foreground
= f
->display
.x
->background_pixel
;
2690 gc_values
.background
= f
->display
.x
->cursor_pixel
;
2691 gc_values
.fill_style
= FillOpaqueStippled
;
2693 = XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
2694 FRAME_X_DISPLAY_INFO (f
)->root_window
,
2695 cursor_bits
, 16, 16);
2696 f
->display
.x
->cursor_gc
2697 = XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2698 (GCFont
| GCForeground
| GCBackground
2699 | GCFillStyle
| GCStipple
| GCLineWidth
),
2702 /* Create the gray border tile used when the pointer is not in
2703 the frame. Since this depends on the frame's pixel values,
2704 this must be done on a per-frame basis. */
2705 f
->display
.x
->border_tile
2706 = (XCreatePixmapFromBitmapData
2707 (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
2708 gray_bits
, gray_width
, gray_height
,
2709 f
->display
.x
->foreground_pixel
,
2710 f
->display
.x
->background_pixel
,
2711 DefaultDepth (FRAME_X_DISPLAY (f
),
2712 XScreenNumberOfScreen (FRAME_X_SCREEN (f
)))));
2717 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
2719 "Make a new X window, which is called a \"frame\" in Emacs terms.\n\
2720 Returns an Emacs frame object.\n\
2721 ALIST is an alist of frame parameters.\n\
2722 If the parameters specify that the frame should not have a minibuffer,\n\
2723 and do not specify a specific minibuffer window to use,\n\
2724 then `default-minibuffer-frame' must be a frame whose minibuffer can\n\
2725 be shared by the new frame.\n\
2727 This function is an internal primitive--use `make-frame' instead.")
2732 Lisp_Object frame
, tem
;
2734 int minibuffer_only
= 0;
2735 long window_prompting
= 0;
2737 int count
= specpdl_ptr
- specpdl
;
2738 struct gcpro gcpro1
;
2739 Lisp_Object display
;
2740 struct x_display_info
*dpyinfo
;
2745 display
= x_get_arg (parms
, Qdisplay
, 0, 0, 0);
2746 if (EQ (display
, Qunbound
))
2748 dpyinfo
= check_x_display_info (display
);
2750 name
= x_get_arg (parms
, Qname
, "title", "Title", string
);
2752 && ! EQ (name
, Qunbound
)
2754 error ("Invalid frame name--not a string or nil");
2756 /* See if parent window is specified. */
2757 parent
= x_get_arg (parms
, Qparent_id
, NULL
, NULL
, number
);
2758 if (EQ (parent
, Qunbound
))
2760 if (! NILP (parent
))
2761 CHECK_NUMBER (parent
, 0);
2763 tem
= x_get_arg (parms
, Qminibuffer
, 0, 0, symbol
);
2764 if (EQ (tem
, Qnone
) || NILP (tem
))
2765 f
= make_frame_without_minibuffer (Qnil
);
2766 else if (EQ (tem
, Qonly
))
2768 f
= make_minibuffer_frame ();
2769 minibuffer_only
= 1;
2771 else if (WINDOWP (tem
))
2772 f
= make_frame_without_minibuffer (tem
);
2776 /* Note that X Windows does support scroll bars. */
2777 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
2779 XSETFRAME (frame
, f
);
2782 f
->output_method
= output_x_window
;
2783 f
->display
.x
= (struct x_display
*) xmalloc (sizeof (struct x_display
));
2784 bzero (f
->display
.x
, sizeof (struct x_display
));
2785 f
->display
.x
->icon_bitmap
= -1;
2787 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
2789 FRAME_KBOARD (f
) = dpyinfo
->kboard
;
2792 /* Specify the parent under which to make this X window. */
2796 f
->display
.x
->parent_desc
= parent
;
2797 f
->display
.x
->explicit_parent
= 1;
2801 f
->display
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
2802 f
->display
.x
->explicit_parent
= 0;
2805 /* Note that the frame has no physical cursor right now. */
2806 f
->phys_cursor_x
= -1;
2808 /* Set the name; the functions to which we pass f expect the name to
2810 if (EQ (name
, Qunbound
) || NILP (name
))
2812 f
->name
= build_string (dpyinfo
->x_id_name
);
2813 f
->explicit_name
= 0;
2818 f
->explicit_name
= 1;
2819 /* use the frame's title when getting resources for this frame. */
2820 specbind (Qx_resource_name
, name
);
2823 /* Extract the window parameters from the supplied values
2824 that are needed to determine window geometry. */
2828 font
= x_get_arg (parms
, Qfont
, "font", "Font", string
);
2830 /* First, try whatever font the caller has specified. */
2832 font
= x_new_font (f
, XSTRING (font
)->data
);
2833 /* Try out a font which we hope has bold and italic variations. */
2834 if (!STRINGP (font
))
2835 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
2836 if (! STRINGP (font
))
2837 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
2838 if (! STRINGP (font
))
2839 /* This was formerly the first thing tried, but it finds too many fonts
2840 and takes too long. */
2841 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
2842 /* If those didn't work, look for something which will at least work. */
2843 if (! STRINGP (font
))
2844 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
2846 if (! STRINGP (font
))
2847 font
= build_string ("fixed");
2849 x_default_parameter (f
, parms
, Qfont
, font
,
2850 "font", "Font", string
);
2853 #ifdef USE_X_TOOLKIT
2854 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
2855 whereby it fails to get any font. */
2856 xlwmenu_default_font
= f
->display
.x
->font
;
2859 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
2860 "borderwidth", "BorderWidth", number
);
2861 /* This defaults to 2 in order to match xterm. We recognize either
2862 internalBorderWidth or internalBorder (which is what xterm calls
2864 if (NILP (Fassq (Qinternal_border_width
, parms
)))
2868 value
= x_get_arg (parms
, Qinternal_border_width
,
2869 "internalBorder", "BorderWidth", number
);
2870 if (! EQ (value
, Qunbound
))
2871 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
2874 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (2),
2875 "internalBorderWidth", "BorderWidth", number
);
2876 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qt
,
2877 "verticalScrollBars", "ScrollBars", boolean
);
2879 /* Also do the stuff which must be set before the window exists. */
2880 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
2881 "foreground", "Foreground", string
);
2882 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
2883 "background", "Background", string
);
2884 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
2885 "pointerColor", "Foreground", string
);
2886 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
2887 "cursorColor", "Foreground", string
);
2888 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
2889 "borderColor", "BorderColor", string
);
2891 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
2892 "menuBar", "MenuBar", number
);
2893 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
2894 "scrollBarWidth", "ScrollBarWidth", number
);
2896 f
->display
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
2897 window_prompting
= x_figure_window_size (f
, parms
);
2899 if (window_prompting
& XNegative
)
2901 if (window_prompting
& YNegative
)
2902 f
->display
.x
->win_gravity
= SouthEastGravity
;
2904 f
->display
.x
->win_gravity
= NorthEastGravity
;
2908 if (window_prompting
& YNegative
)
2909 f
->display
.x
->win_gravity
= SouthWestGravity
;
2911 f
->display
.x
->win_gravity
= NorthWestGravity
;
2914 f
->display
.x
->size_hint_flags
= window_prompting
;
2916 #ifdef USE_X_TOOLKIT
2917 x_window (f
, window_prompting
, minibuffer_only
);
2923 init_frame_faces (f
);
2925 /* We need to do this after creating the X window, so that the
2926 icon-creation functions can say whose icon they're describing. */
2927 x_default_parameter (f
, parms
, Qicon_type
, Qnil
,
2928 "bitmapIcon", "BitmapIcon", symbol
);
2930 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
2931 "autoRaise", "AutoRaiseLower", boolean
);
2932 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
2933 "autoLower", "AutoRaiseLower", boolean
);
2934 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
2935 "cursorType", "CursorType", symbol
);
2937 /* Dimensions, especially f->height, must be done via change_frame_size.
2938 Change will not be effected unless different from the current
2942 f
->height
= f
->width
= 0;
2943 change_frame_size (f
, height
, width
, 1, 0);
2945 /* Tell the server what size and position, etc, we want,
2946 and how badly we want them. */
2948 x_wm_set_size_hint (f
, window_prompting
, 0);
2951 tem
= x_get_arg (parms
, Qunsplittable
, 0, 0, boolean
);
2952 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
2956 /* It is now ok to make the frame official
2957 even if we get an error below.
2958 And the frame needs to be on Vframe_list
2959 or making it visible won't work. */
2960 Vframe_list
= Fcons (frame
, Vframe_list
);
2962 /* Now that the frame is official, it counts as a reference to
2964 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
2966 /* Make the window appear on the frame and enable display,
2967 unless the caller says not to. However, with explicit parent,
2968 Emacs cannot control visibility, so don't try. */
2969 if (! f
->display
.x
->explicit_parent
)
2971 Lisp_Object visibility
;
2973 visibility
= x_get_arg (parms
, Qvisibility
, 0, 0, symbol
);
2974 if (EQ (visibility
, Qunbound
))
2977 if (EQ (visibility
, Qicon
))
2978 x_iconify_frame (f
);
2979 else if (! NILP (visibility
))
2980 x_make_frame_visible (f
);
2982 /* Must have been Qnil. */
2986 return unbind_to (count
, frame
);
2989 /* FRAME is used only to get a handle on the X display. We don't pass the
2990 display info directly because we're called from frame.c, which doesn't
2991 know about that structure. */
2993 x_get_focus_frame (frame
)
2994 struct frame
*frame
;
2996 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (frame
);
2998 if (! dpyinfo
->x_focus_frame
)
3001 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
3005 DEFUN ("focus-frame", Ffocus_frame
, Sfocus_frame
, 1, 1, 0,
3006 "Set the focus on FRAME.")
3010 CHECK_LIVE_FRAME (frame
, 0);
3012 if (FRAME_X_P (XFRAME (frame
)))
3015 x_focus_on_frame (XFRAME (frame
));
3023 DEFUN ("unfocus-frame", Funfocus_frame
, Sunfocus_frame
, 0, 0, 0,
3024 "If a frame has been focused, release it.")
3027 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (selected_frame
);
3028 if (dpyinfo
->x_focus_frame
)
3031 x_unfocus_frame (dpyinfo
->x_focus_frame
);
3038 DEFUN ("x-list-fonts", Fx_list_fonts
, Sx_list_fonts
, 1, 3, 0,
3039 "Return a list of the names of available fonts matching PATTERN.\n\
3040 If optional arguments FACE and FRAME are specified, return only fonts\n\
3041 the same size as FACE on FRAME.\n\
3043 PATTERN is a string, perhaps with wildcard characters;\n\
3044 the * character matches any substring, and\n\
3045 the ? character matches any single character.\n\
3046 PATTERN is case-insensitive.\n\
3047 FACE is a face name--a symbol.\n\
3049 The return value is a list of strings, suitable as arguments to\n\
3052 Fonts Emacs can't use (i.e. proportional fonts) may or may not be excluded\n\
3053 even if they match PATTERN and FACE.")
3054 (pattern
, face
, frame
)
3055 Lisp_Object pattern
, face
, frame
;
3059 #ifndef BROKEN_XLISTFONTSWITHINFO
3062 XFontStruct
*size_ref
;
3067 CHECK_STRING (pattern
, 0);
3069 CHECK_SYMBOL (face
, 1);
3071 f
= check_x_frame (frame
);
3073 /* Determine the width standard for comparison with the fonts we find. */
3081 /* Don't die if we get called with a terminal frame. */
3082 if (! FRAME_X_P (f
))
3083 error ("non-X frame used in `x-list-fonts'");
3085 face_id
= face_name_id_number (f
, face
);
3087 if (face_id
< 0 || face_id
>= FRAME_N_PARAM_FACES (f
)
3088 || FRAME_PARAM_FACES (f
) [face_id
] == 0)
3089 size_ref
= f
->display
.x
->font
;
3092 size_ref
= FRAME_PARAM_FACES (f
) [face_id
]->font
;
3093 if (size_ref
== (XFontStruct
*) (~0))
3094 size_ref
= f
->display
.x
->font
;
3098 /* See if we cached the result for this particular query. */
3099 list
= Fassoc (pattern
,
3100 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
);
3102 /* We have info in the cache for this PATTERN. */
3105 Lisp_Object tem
, newlist
;
3107 /* We have info about this pattern. */
3108 list
= XCONS (list
)->cdr
;
3115 /* Filter the cached info and return just the fonts that match FACE. */
3117 for (tem
= list
; CONSP (tem
); tem
= XCONS (tem
)->cdr
)
3119 XFontStruct
*thisinfo
;
3121 thisinfo
= XLoadQueryFont (FRAME_X_DISPLAY (f
),
3122 XSTRING (XCONS (tem
)->car
)->data
);
3124 if (thisinfo
&& same_size_fonts (thisinfo
, size_ref
))
3125 newlist
= Fcons (XCONS (tem
)->car
, newlist
);
3127 XFreeFont (FRAME_X_DISPLAY (f
), thisinfo
);
3137 /* Solaris 2.3 has a bug in XListFontsWithInfo. */
3138 #ifndef BROKEN_XLISTFONTSWITHINFO
3140 names
= XListFontsWithInfo (FRAME_X_DISPLAY (f
),
3141 XSTRING (pattern
)->data
,
3142 2000, /* maxnames */
3143 &num_fonts
, /* count_return */
3144 &info
); /* info_return */
3147 names
= XListFonts (FRAME_X_DISPLAY (f
),
3148 XSTRING (pattern
)->data
,
3149 2000, /* maxnames */
3150 &num_fonts
); /* count_return */
3159 Lisp_Object full_list
;
3161 /* Make a list of all the fonts we got back.
3162 Store that in the font cache for the display. */
3164 for (i
= 0; i
< num_fonts
; i
++)
3165 full_list
= Fcons (build_string (names
[i
]), full_list
);
3166 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
3167 = Fcons (Fcons (pattern
, full_list
),
3168 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
);
3170 /* Make a list of the fonts that have the right width. */
3172 for (i
= 0; i
< num_fonts
; i
++)
3180 #ifdef BROKEN_XLISTFONTSWITHINFO
3181 XFontStruct
*thisinfo
;
3184 thisinfo
= XLoadQueryFont (FRAME_X_DISPLAY (f
), names
[i
]);
3187 keeper
= thisinfo
&& same_size_fonts (thisinfo
, size_ref
);
3189 keeper
= same_size_fonts (&info
[i
], size_ref
);
3193 list
= Fcons (build_string (names
[i
]), list
);
3195 list
= Fnreverse (list
);
3198 #ifndef BROKEN_XLISTFONTSWITHINFO
3200 XFreeFontInfo (names
, info
, num_fonts
);
3203 XFreeFontNames (names
);
3211 DEFUN ("x-color-defined-p", Fx_color_defined_p
, Sx_color_defined_p
, 1, 2, 0,
3212 "Return non-nil if color COLOR is supported on frame FRAME.\n\
3213 If FRAME is omitted or nil, use the selected frame.")
3215 Lisp_Object color
, frame
;
3218 FRAME_PTR f
= check_x_frame (frame
);
3220 CHECK_STRING (color
, 1);
3222 if (defined_color (f
, XSTRING (color
)->data
, &foo
, 0))
3228 DEFUN ("x-color-values", Fx_color_values
, Sx_color_values
, 1, 2, 0,
3229 "Return a description of the color named COLOR on frame FRAME.\n\
3230 The value is a list of integer RGB values--(RED GREEN BLUE).\n\
3231 These values appear to range from 0 to 65280 or 65535, depending\n\
3232 on the system; white is (65280 65280 65280) or (65535 65535 65535).\n\
3233 If FRAME is omitted or nil, use the selected frame.")
3235 Lisp_Object color
, frame
;
3238 FRAME_PTR f
= check_x_frame (frame
);
3240 CHECK_STRING (color
, 1);
3242 if (defined_color (f
, XSTRING (color
)->data
, &foo
, 0))
3246 rgb
[0] = make_number (foo
.red
);
3247 rgb
[1] = make_number (foo
.green
);
3248 rgb
[2] = make_number (foo
.blue
);
3249 return Flist (3, rgb
);
3255 DEFUN ("x-display-color-p", Fx_display_color_p
, Sx_display_color_p
, 0, 1, 0,
3256 "Return t if the X display supports color.\n\
3257 The optional argument DISPLAY specifies which display to ask about.\n\
3258 DISPLAY should be either a frame or a display name (a string).\n\
3259 If omitted or nil, that stands for the selected frame's display.")
3261 Lisp_Object display
;
3263 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3265 if (dpyinfo
->n_planes
<= 2)
3268 switch (dpyinfo
->visual
->class)
3281 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
3283 "Return t if the X display supports shades of gray.\n\
3284 The optional argument DISPLAY specifies which display to ask about.\n\
3285 DISPLAY should be either a frame or a display name (a string).\n\
3286 If omitted or nil, that stands for the selected frame's display.")
3288 Lisp_Object display
;
3290 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3292 if (dpyinfo
->n_planes
<= 2)
3295 return (dpyinfo
->n_planes
> 1
3296 && (dpyinfo
->visual
->class == StaticGray
3297 || dpyinfo
->visual
->class == GrayScale
));
3300 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
3302 "Returns the width in pixels of the X display DISPLAY.\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 return make_number (dpyinfo
->width
);
3314 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
3315 Sx_display_pixel_height
, 0, 1, 0,
3316 "Returns the height in pixels of the X display DISPLAY.\n\
3317 The optional argument DISPLAY specifies which display to ask about.\n\
3318 DISPLAY should be either a frame or a display name (a string).\n\
3319 If omitted or nil, that stands for the selected frame's display.")
3321 Lisp_Object display
;
3323 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3325 return make_number (dpyinfo
->height
);
3328 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
3330 "Returns the number of bitplanes of the X display DISPLAY.\n\
3331 The optional argument DISPLAY specifies which display to ask about.\n\
3332 DISPLAY should be either a frame or a display name (a string).\n\
3333 If omitted or nil, that stands for the selected frame's display.")
3335 Lisp_Object display
;
3337 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3339 return make_number (dpyinfo
->n_planes
);
3342 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
3344 "Returns the number of color cells of the X display DISPLAY.\n\
3345 The optional argument DISPLAY specifies which display to ask about.\n\
3346 DISPLAY should be either a frame or a display name (a string).\n\
3347 If omitted or nil, that stands for the selected frame's display.")
3349 Lisp_Object display
;
3351 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3353 return make_number (DisplayCells (dpyinfo
->display
,
3354 XScreenNumberOfScreen (dpyinfo
->screen
)));
3357 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
3358 Sx_server_max_request_size
,
3360 "Returns the maximum request size of the X server of display DISPLAY.\n\
3361 The optional argument DISPLAY specifies which display to ask about.\n\
3362 DISPLAY should be either a frame or a display name (a string).\n\
3363 If omitted or nil, that stands for the selected frame's display.")
3365 Lisp_Object display
;
3367 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3369 return make_number (MAXREQUEST (dpyinfo
->display
));
3372 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
3373 "Returns the vendor ID string of the X server of display DISPLAY.\n\
3374 The optional argument DISPLAY specifies which display to ask about.\n\
3375 DISPLAY should be either a frame or a display name (a string).\n\
3376 If omitted or nil, that stands for the selected frame's display.")
3378 Lisp_Object display
;
3380 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3381 char *vendor
= ServerVendor (dpyinfo
->display
);
3383 if (! vendor
) vendor
= "";
3384 return build_string (vendor
);
3387 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
3388 "Returns the version numbers of the X server of display DISPLAY.\n\
3389 The value is a list of three integers: the major and minor\n\
3390 version numbers of the X Protocol in use, and the vendor-specific release\n\
3391 number. See also the function `x-server-vendor'.\n\n\
3392 The optional argument DISPLAY specifies which display to ask about.\n\
3393 DISPLAY should be either a frame or a display name (a string).\n\
3394 If omitted or nil, that stands for the selected frame's display.")
3396 Lisp_Object display
;
3398 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3399 Display
*dpy
= dpyinfo
->display
;
3401 return Fcons (make_number (ProtocolVersion (dpy
)),
3402 Fcons (make_number (ProtocolRevision (dpy
)),
3403 Fcons (make_number (VendorRelease (dpy
)), Qnil
)));
3406 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
3407 "Returns the number of screens on the X server of display DISPLAY.\n\
3408 The optional argument DISPLAY specifies which display to ask about.\n\
3409 DISPLAY should be either a frame or a display name (a string).\n\
3410 If omitted or nil, that stands for the selected frame's display.")
3412 Lisp_Object display
;
3414 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3416 return make_number (ScreenCount (dpyinfo
->display
));
3419 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
3420 "Returns the height in millimeters of the X display DISPLAY.\n\
3421 The optional argument DISPLAY specifies which display to ask about.\n\
3422 DISPLAY should be either a frame or a display name (a string).\n\
3423 If omitted or nil, that stands for the selected frame's display.")
3425 Lisp_Object display
;
3427 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3429 return make_number (HeightMMOfScreen (dpyinfo
->screen
));
3432 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
3433 "Returns the width in millimeters of the X display DISPLAY.\n\
3434 The optional argument DISPLAY specifies which display to ask about.\n\
3435 DISPLAY should be either a frame or a display name (a string).\n\
3436 If omitted or nil, that stands for the selected frame's display.")
3438 Lisp_Object display
;
3440 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3442 return make_number (WidthMMOfScreen (dpyinfo
->screen
));
3445 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
3446 Sx_display_backing_store
, 0, 1, 0,
3447 "Returns an indication of whether X display DISPLAY does backing store.\n\
3448 The value may be `always', `when-mapped', or `not-useful'.\n\
3449 The optional argument DISPLAY specifies which display to ask about.\n\
3450 DISPLAY should be either a frame or a display name (a string).\n\
3451 If omitted or nil, that stands for the selected frame's display.")
3453 Lisp_Object display
;
3455 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3457 switch (DoesBackingStore (dpyinfo
->screen
))
3460 return intern ("always");
3463 return intern ("when-mapped");
3466 return intern ("not-useful");
3469 error ("Strange value for BackingStore parameter of screen");
3473 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
3474 Sx_display_visual_class
, 0, 1, 0,
3475 "Returns the visual class of the X display DISPLAY.\n\
3476 The value is one of the symbols `static-gray', `gray-scale',\n\
3477 `static-color', `pseudo-color', `true-color', or `direct-color'.\n\n\
3478 The optional argument DISPLAY specifies which display to ask about.\n\
3479 DISPLAY should be either a frame or a display name (a string).\n\
3480 If omitted or nil, that stands for the selected frame's display.")
3482 Lisp_Object display
;
3484 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3486 switch (dpyinfo
->visual
->class)
3488 case StaticGray
: return (intern ("static-gray"));
3489 case GrayScale
: return (intern ("gray-scale"));
3490 case StaticColor
: return (intern ("static-color"));
3491 case PseudoColor
: return (intern ("pseudo-color"));
3492 case TrueColor
: return (intern ("true-color"));
3493 case DirectColor
: return (intern ("direct-color"));
3495 error ("Display has an unknown visual class");
3499 DEFUN ("x-display-save-under", Fx_display_save_under
,
3500 Sx_display_save_under
, 0, 1, 0,
3501 "Returns t if the X display DISPLAY supports the save-under feature.\n\
3502 The optional argument DISPLAY specifies which display to ask about.\n\
3503 DISPLAY should be either a frame or a display name (a string).\n\
3504 If omitted or nil, that stands for the selected frame's display.")
3506 Lisp_Object display
;
3508 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3510 if (DoesSaveUnders (dpyinfo
->screen
) == True
)
3518 register struct frame
*f
;
3520 return PIXEL_WIDTH (f
);
3525 register struct frame
*f
;
3527 return PIXEL_HEIGHT (f
);
3532 register struct frame
*f
;
3534 return FONT_WIDTH (f
->display
.x
->font
);
3539 register struct frame
*f
;
3541 return f
->display
.x
->line_height
;
3545 x_screen_planes (frame
)
3548 return FRAME_X_DISPLAY_INFO (XFRAME (frame
))->n_planes
;
3551 #if 0 /* These no longer seem like the right way to do things. */
3553 /* Draw a rectangle on the frame with left top corner including
3554 the character specified by LEFT_CHAR and TOP_CHAR. The rectangle is
3555 CHARS by LINES wide and long and is the color of the cursor. */
3558 x_rectangle (f
, gc
, left_char
, top_char
, chars
, lines
)
3559 register struct frame
*f
;
3561 register int top_char
, left_char
, chars
, lines
;
3565 int left
= (left_char
* FONT_WIDTH (f
->display
.x
->font
)
3566 + f
->display
.x
->internal_border_width
);
3567 int top
= (top_char
* f
->display
.x
->line_height
3568 + f
->display
.x
->internal_border_width
);
3571 width
= FONT_WIDTH (f
->display
.x
->font
) / 2;
3573 width
= FONT_WIDTH (f
->display
.x
->font
) * chars
;
3575 height
= f
->display
.x
->line_height
/ 2;
3577 height
= f
->display
.x
->line_height
* lines
;
3579 XDrawRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3580 gc
, left
, top
, width
, height
);
3583 DEFUN ("x-draw-rectangle", Fx_draw_rectangle
, Sx_draw_rectangle
, 5, 5, 0,
3584 "Draw a rectangle on FRAME between coordinates specified by\n\
3585 numbers X0, Y0, X1, Y1 in the cursor pixel.")
3586 (frame
, X0
, Y0
, X1
, Y1
)
3587 register Lisp_Object frame
, X0
, X1
, Y0
, Y1
;
3589 register int x0
, y0
, x1
, y1
, top
, left
, n_chars
, n_lines
;
3591 CHECK_LIVE_FRAME (frame
, 0);
3592 CHECK_NUMBER (X0
, 0);
3593 CHECK_NUMBER (Y0
, 1);
3594 CHECK_NUMBER (X1
, 2);
3595 CHECK_NUMBER (Y1
, 3);
3605 n_lines
= y1
- y0
+ 1;
3610 n_lines
= y0
- y1
+ 1;
3616 n_chars
= x1
- x0
+ 1;
3621 n_chars
= x0
- x1
+ 1;
3625 x_rectangle (XFRAME (frame
), XFRAME (frame
)->display
.x
->cursor_gc
,
3626 left
, top
, n_chars
, n_lines
);
3632 DEFUN ("x-erase-rectangle", Fx_erase_rectangle
, Sx_erase_rectangle
, 5, 5, 0,
3633 "Draw a rectangle drawn on FRAME between coordinates\n\
3634 X0, Y0, X1, Y1 in the regular background-pixel.")
3635 (frame
, X0
, Y0
, X1
, Y1
)
3636 register Lisp_Object frame
, X0
, Y0
, X1
, Y1
;
3638 register int x0
, y0
, x1
, y1
, top
, left
, n_chars
, n_lines
;
3640 CHECK_LIVE_FRAME (frame
, 0);
3641 CHECK_NUMBER (X0
, 0);
3642 CHECK_NUMBER (Y0
, 1);
3643 CHECK_NUMBER (X1
, 2);
3644 CHECK_NUMBER (Y1
, 3);
3654 n_lines
= y1
- y0
+ 1;
3659 n_lines
= y0
- y1
+ 1;
3665 n_chars
= x1
- x0
+ 1;
3670 n_chars
= x0
- x1
+ 1;
3674 x_rectangle (XFRAME (frame
), XFRAME (frame
)->display
.x
->reverse_gc
,
3675 left
, top
, n_chars
, n_lines
);
3681 /* Draw lines around the text region beginning at the character position
3682 TOP_X, TOP_Y and ending at BOTTOM_X and BOTTOM_Y. GC specifies the
3683 pixel and line characteristics. */
3685 #define line_len(line) (FRAME_CURRENT_GLYPHS (f)->used[(line)])
3688 outline_region (f
, gc
, top_x
, top_y
, bottom_x
, bottom_y
)
3689 register struct frame
*f
;
3691 int top_x
, top_y
, bottom_x
, bottom_y
;
3693 register int ibw
= f
->display
.x
->internal_border_width
;
3694 register int font_w
= FONT_WIDTH (f
->display
.x
->font
);
3695 register int font_h
= f
->display
.x
->line_height
;
3697 int x
= line_len (y
);
3698 XPoint
*pixel_points
3699 = (XPoint
*) alloca (((bottom_y
- top_y
+ 2) * 4) * sizeof (XPoint
));
3700 register XPoint
*this_point
= pixel_points
;
3702 /* Do the horizontal top line/lines */
3705 this_point
->x
= ibw
;
3706 this_point
->y
= ibw
+ (font_h
* top_y
);
3709 this_point
->x
= ibw
+ (font_w
/ 2); /* Half-size for newline chars. */
3711 this_point
->x
= ibw
+ (font_w
* x
);
3712 this_point
->y
= (this_point
- 1)->y
;
3716 this_point
->x
= ibw
;
3717 this_point
->y
= ibw
+ (font_h
* (top_y
+ 1));
3719 this_point
->x
= ibw
+ (font_w
* top_x
);
3720 this_point
->y
= (this_point
- 1)->y
;
3722 this_point
->x
= (this_point
- 1)->x
;
3723 this_point
->y
= ibw
+ (font_h
* top_y
);
3725 this_point
->x
= ibw
+ (font_w
* x
);
3726 this_point
->y
= (this_point
- 1)->y
;
3729 /* Now do the right side. */
3730 while (y
< bottom_y
)
3731 { /* Right vertical edge */
3733 this_point
->x
= (this_point
- 1)->x
;
3734 this_point
->y
= ibw
+ (font_h
* (y
+ 1));
3737 y
++; /* Horizontal connection to next line */
3740 this_point
->x
= ibw
+ (font_w
/ 2);
3742 this_point
->x
= ibw
+ (font_w
* x
);
3744 this_point
->y
= (this_point
- 1)->y
;
3747 /* Now do the bottom and connect to the top left point. */
3748 this_point
->x
= ibw
+ (font_w
* (bottom_x
+ 1));
3751 this_point
->x
= (this_point
- 1)->x
;
3752 this_point
->y
= ibw
+ (font_h
* (bottom_y
+ 1));
3754 this_point
->x
= ibw
;
3755 this_point
->y
= (this_point
- 1)->y
;
3757 this_point
->x
= pixel_points
->x
;
3758 this_point
->y
= pixel_points
->y
;
3760 XDrawLines (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3762 (this_point
- pixel_points
+ 1), CoordModeOrigin
);
3765 DEFUN ("x-contour-region", Fx_contour_region
, Sx_contour_region
, 1, 1, 0,
3766 "Highlight the region between point and the character under the mouse\n\
3769 register Lisp_Object event
;
3771 register int x0
, y0
, x1
, y1
;
3772 register struct frame
*f
= selected_frame
;
3773 register int p1
, p2
;
3775 CHECK_CONS (event
, 0);
3778 x0
= XINT (Fcar (Fcar (event
)));
3779 y0
= XINT (Fcar (Fcdr (Fcar (event
))));
3781 /* If the mouse is past the end of the line, don't that area. */
3782 /* ReWrite this... */
3787 if (y1
> y0
) /* point below mouse */
3788 outline_region (f
, f
->display
.x
->cursor_gc
,
3790 else if (y1
< y0
) /* point above mouse */
3791 outline_region (f
, f
->display
.x
->cursor_gc
,
3793 else /* same line: draw horizontal rectangle */
3796 x_rectangle (f
, f
->display
.x
->cursor_gc
,
3797 x0
, y0
, (x1
- x0
+ 1), 1);
3799 x_rectangle (f
, f
->display
.x
->cursor_gc
,
3800 x1
, y1
, (x0
- x1
+ 1), 1);
3803 XFlush (FRAME_X_DISPLAY (f
));
3809 DEFUN ("x-uncontour-region", Fx_uncontour_region
, Sx_uncontour_region
, 1, 1, 0,
3810 "Erase any highlighting of the region between point and the character\n\
3811 at X, Y on the selected frame.")
3813 register Lisp_Object event
;
3815 register int x0
, y0
, x1
, y1
;
3816 register struct frame
*f
= selected_frame
;
3819 x0
= XINT (Fcar (Fcar (event
)));
3820 y0
= XINT (Fcar (Fcdr (Fcar (event
))));
3824 if (y1
> y0
) /* point below mouse */
3825 outline_region (f
, f
->display
.x
->reverse_gc
,
3827 else if (y1
< y0
) /* point above mouse */
3828 outline_region (f
, f
->display
.x
->reverse_gc
,
3830 else /* same line: draw horizontal rectangle */
3833 x_rectangle (f
, f
->display
.x
->reverse_gc
,
3834 x0
, y0
, (x1
- x0
+ 1), 1);
3836 x_rectangle (f
, f
->display
.x
->reverse_gc
,
3837 x1
, y1
, (x0
- x1
+ 1), 1);
3845 int contour_begin_x
, contour_begin_y
;
3846 int contour_end_x
, contour_end_y
;
3847 int contour_npoints
;
3849 /* Clip the top part of the contour lines down (and including) line Y_POS.
3850 If X_POS is in the middle (rather than at the end) of the line, drop
3851 down a line at that character. */
3854 clip_contour_top (y_pos
, x_pos
)
3856 register XPoint
*begin
= contour_lines
[y_pos
].top_left
;
3857 register XPoint
*end
;
3858 register int npoints
;
3859 register struct display_line
*line
= selected_frame
->phys_lines
[y_pos
+ 1];
3861 if (x_pos
>= line
->len
- 1) /* Draw one, straight horizontal line. */
3863 end
= contour_lines
[y_pos
].top_right
;
3864 npoints
= (end
- begin
+ 1);
3865 XDrawLines (x_current_display
, contour_window
,
3866 contour_erase_gc
, begin_erase
, npoints
, CoordModeOrigin
);
3868 bcopy (end
, begin
+ 1, contour_last_point
- end
+ 1);
3869 contour_last_point
-= (npoints
- 2);
3870 XDrawLines (x_current_display
, contour_window
,
3871 contour_erase_gc
, begin
, 2, CoordModeOrigin
);
3872 XFlush (x_current_display
);
3874 /* Now, update contour_lines structure. */
3879 register XPoint
*p
= begin
+ 1;
3880 end
= contour_lines
[y_pos
].bottom_right
;
3881 npoints
= (end
- begin
+ 1);
3882 XDrawLines (x_current_display
, contour_window
,
3883 contour_erase_gc
, begin_erase
, npoints
, CoordModeOrigin
);
3886 p
->x
= ibw
+ (font_w
* (x_pos
+ 1));
3888 p
->y
= begin
->y
+ font_h
;
3890 bcopy (end
, begin
+ 3, contour_last_point
- end
+ 1);
3891 contour_last_point
-= (npoints
- 5);
3892 XDrawLines (x_current_display
, contour_window
,
3893 contour_erase_gc
, begin
, 4, CoordModeOrigin
);
3894 XFlush (x_current_display
);
3896 /* Now, update contour_lines structure. */
3900 /* Erase the top horizontal lines of the contour, and then extend
3901 the contour upwards. */
3904 extend_contour_top (line
)
3909 clip_contour_bottom (x_pos
, y_pos
)
3915 extend_contour_bottom (x_pos
, y_pos
)
3919 DEFUN ("x-select-region", Fx_select_region
, Sx_select_region
, 1, 1, "e",
3924 register struct frame
*f
= selected_frame
;
3925 register int point_x
= f
->cursor_x
;
3926 register int point_y
= f
->cursor_y
;
3927 register int mouse_below_point
;
3928 register Lisp_Object obj
;
3929 register int x_contour_x
, x_contour_y
;
3931 x_contour_x
= x_mouse_x
;
3932 x_contour_y
= x_mouse_y
;
3933 if (x_contour_y
> point_y
|| (x_contour_y
== point_y
3934 && x_contour_x
> point_x
))
3936 mouse_below_point
= 1;
3937 outline_region (f
, f
->display
.x
->cursor_gc
, point_x
, point_y
,
3938 x_contour_x
, x_contour_y
);
3942 mouse_below_point
= 0;
3943 outline_region (f
, f
->display
.x
->cursor_gc
, x_contour_x
, x_contour_y
,
3949 obj
= read_char (-1, 0, 0, Qnil
, 0);
3953 if (mouse_below_point
)
3955 if (x_mouse_y
<= point_y
) /* Flipped. */
3957 mouse_below_point
= 0;
3959 outline_region (f
, f
->display
.x
->reverse_gc
, point_x
, point_y
,
3960 x_contour_x
, x_contour_y
);
3961 outline_region (f
, f
->display
.x
->cursor_gc
, x_mouse_x
, x_mouse_y
,
3964 else if (x_mouse_y
< x_contour_y
) /* Bottom clipped. */
3966 clip_contour_bottom (x_mouse_y
);
3968 else if (x_mouse_y
> x_contour_y
) /* Bottom extended. */
3970 extend_bottom_contour (x_mouse_y
);
3973 x_contour_x
= x_mouse_x
;
3974 x_contour_y
= x_mouse_y
;
3976 else /* mouse above or same line as point */
3978 if (x_mouse_y
>= point_y
) /* Flipped. */
3980 mouse_below_point
= 1;
3982 outline_region (f
, f
->display
.x
->reverse_gc
,
3983 x_contour_x
, x_contour_y
, point_x
, point_y
);
3984 outline_region (f
, f
->display
.x
->cursor_gc
, point_x
, point_y
,
3985 x_mouse_x
, x_mouse_y
);
3987 else if (x_mouse_y
> x_contour_y
) /* Top clipped. */
3989 clip_contour_top (x_mouse_y
);
3991 else if (x_mouse_y
< x_contour_y
) /* Top extended. */
3993 extend_contour_top (x_mouse_y
);
3998 unread_command_event
= obj
;
3999 if (mouse_below_point
)
4001 contour_begin_x
= point_x
;
4002 contour_begin_y
= point_y
;
4003 contour_end_x
= x_contour_x
;
4004 contour_end_y
= x_contour_y
;
4008 contour_begin_x
= x_contour_x
;
4009 contour_begin_y
= x_contour_y
;
4010 contour_end_x
= point_x
;
4011 contour_end_y
= point_y
;
4016 DEFUN ("x-horizontal-line", Fx_horizontal_line
, Sx_horizontal_line
, 1, 1, "e",
4021 register Lisp_Object obj
;
4022 struct frame
*f
= selected_frame
;
4023 register struct window
*w
= XWINDOW (selected_window
);
4024 register GC line_gc
= f
->display
.x
->cursor_gc
;
4025 register GC erase_gc
= f
->display
.x
->reverse_gc
;
4027 char dash_list
[] = {6, 4, 6, 4};
4029 XGCValues gc_values
;
4031 register int previous_y
;
4032 register int line
= (x_mouse_y
+ 1) * f
->display
.x
->line_height
4033 + f
->display
.x
->internal_border_width
;
4034 register int left
= f
->display
.x
->internal_border_width
4036 * FONT_WIDTH (f
->display
.x
->font
));
4037 register int right
= left
+ (w
->width
4038 * FONT_WIDTH (f
->display
.x
->font
))
4039 - f
->display
.x
->internal_border_width
;
4043 gc_values
.foreground
= f
->display
.x
->cursor_pixel
;
4044 gc_values
.background
= f
->display
.x
->background_pixel
;
4045 gc_values
.line_width
= 1;
4046 gc_values
.line_style
= LineOnOffDash
;
4047 gc_values
.cap_style
= CapRound
;
4048 gc_values
.join_style
= JoinRound
;
4050 line_gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4051 GCLineStyle
| GCJoinStyle
| GCCapStyle
4052 | GCLineWidth
| GCForeground
| GCBackground
,
4054 XSetDashes (FRAME_X_DISPLAY (f
), line_gc
, 0, dash_list
, dashes
);
4055 gc_values
.foreground
= f
->display
.x
->background_pixel
;
4056 gc_values
.background
= f
->display
.x
->foreground_pixel
;
4057 erase_gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4058 GCLineStyle
| GCJoinStyle
| GCCapStyle
4059 | GCLineWidth
| GCForeground
| GCBackground
,
4061 XSetDashes (FRAME_X_DISPLAY (f
), erase_gc
, 0, dash_list
, dashes
);
4067 if (x_mouse_y
>= XINT (w
->top
)
4068 && x_mouse_y
< XINT (w
->top
) + XINT (w
->height
) - 1)
4070 previous_y
= x_mouse_y
;
4071 line
= (x_mouse_y
+ 1) * f
->display
.x
->line_height
4072 + f
->display
.x
->internal_border_width
;
4073 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4074 line_gc
, left
, line
, right
, line
);
4076 XFlush (FRAME_X_DISPLAY (f
));
4081 obj
= read_char (-1, 0, 0, Qnil
, 0);
4083 || (! EQ (Fcar (Fcdr (Fcdr (obj
))),
4084 Qvertical_scroll_bar
))
4088 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4089 erase_gc
, left
, line
, right
, line
);
4091 unread_command_event
= obj
;
4093 XFreeGC (FRAME_X_DISPLAY (f
), line_gc
);
4094 XFreeGC (FRAME_X_DISPLAY (f
), erase_gc
);
4099 while (x_mouse_y
== previous_y
);
4102 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4103 erase_gc
, left
, line
, right
, line
);
4110 /* These keep track of the rectangle following the pointer. */
4111 int mouse_track_top
, mouse_track_left
, mouse_track_width
;
4113 /* Offset in buffer of character under the pointer, or 0. */
4114 int mouse_buffer_offset
;
4116 DEFUN ("x-track-pointer", Fx_track_pointer
, Sx_track_pointer
, 0, 0, 0,
4117 "Track the pointer.")
4120 static Cursor current_pointer_shape
;
4121 FRAME_PTR f
= x_mouse_frame
;
4124 if (EQ (Vmouse_frame_part
, Qtext_part
)
4125 && (current_pointer_shape
!= f
->display
.x
->nontext_cursor
))
4130 current_pointer_shape
= f
->display
.x
->nontext_cursor
;
4131 XDefineCursor (FRAME_X_DISPLAY (f
),
4133 current_pointer_shape
);
4135 buf
= XBUFFER (XWINDOW (Vmouse_window
)->buffer
);
4136 c
= *(BUF_CHAR_ADDRESS (buf
, mouse_buffer_offset
));
4138 else if (EQ (Vmouse_frame_part
, Qmodeline_part
)
4139 && (current_pointer_shape
!= f
->display
.x
->modeline_cursor
))
4141 current_pointer_shape
= f
->display
.x
->modeline_cursor
;
4142 XDefineCursor (FRAME_X_DISPLAY (f
),
4144 current_pointer_shape
);
4147 XFlush (FRAME_X_DISPLAY (f
));
4153 DEFUN ("x-track-pointer", Fx_track_pointer
, Sx_track_pointer
, 1, 1, "e",
4154 "Draw rectangle around character under mouse pointer, if there is one.")
4158 struct window
*w
= XWINDOW (Vmouse_window
);
4159 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4160 struct buffer
*b
= XBUFFER (w
->buffer
);
4163 if (! EQ (Vmouse_window
, selected_window
))
4166 if (EQ (event
, Qnil
))
4170 x_read_mouse_position (selected_frame
, &x
, &y
);
4174 mouse_track_width
= 0;
4175 mouse_track_left
= mouse_track_top
= -1;
4179 if ((x_mouse_x
!= mouse_track_left
4180 && (x_mouse_x
< mouse_track_left
4181 || x_mouse_x
> (mouse_track_left
+ mouse_track_width
)))
4182 || x_mouse_y
!= mouse_track_top
)
4184 int hp
= 0; /* Horizontal position */
4185 int len
= FRAME_CURRENT_GLYPHS (f
)->used
[x_mouse_y
];
4186 int p
= FRAME_CURRENT_GLYPHS (f
)->bufp
[x_mouse_y
];
4187 int tab_width
= XINT (b
->tab_width
);
4188 int ctl_arrow_p
= !NILP (b
->ctl_arrow
);
4190 int mode_line_vpos
= XFASTINT (w
->height
) + XFASTINT (w
->top
) - 1;
4191 int in_mode_line
= 0;
4193 if (! FRAME_CURRENT_GLYPHS (f
)->enable
[x_mouse_y
])
4196 /* Erase previous rectangle. */
4197 if (mouse_track_width
)
4199 x_rectangle (f
, f
->display
.x
->reverse_gc
,
4200 mouse_track_left
, mouse_track_top
,
4201 mouse_track_width
, 1);
4203 if ((mouse_track_left
== f
->phys_cursor_x
4204 || mouse_track_left
== f
->phys_cursor_x
- 1)
4205 && mouse_track_top
== f
->phys_cursor_y
)
4207 x_display_cursor (f
, 1);
4211 mouse_track_left
= x_mouse_x
;
4212 mouse_track_top
= x_mouse_y
;
4213 mouse_track_width
= 0;
4215 if (mouse_track_left
> len
) /* Past the end of line. */
4218 if (mouse_track_top
== mode_line_vpos
)
4224 if (tab_width
<= 0 || tab_width
> 20) tab_width
= 8;
4228 if (len
== f
->width
&& hp
== len
- 1 && c
!= '\n')
4234 mouse_track_width
= tab_width
- (hp
% tab_width
);
4236 hp
+= mouse_track_width
;
4239 mouse_track_left
= hp
- mouse_track_width
;
4245 mouse_track_width
= -1;
4249 if (ctl_arrow_p
&& (c
< 040 || c
== 0177))
4254 mouse_track_width
= 2;
4259 mouse_track_left
= hp
- mouse_track_width
;
4265 mouse_track_width
= 1;
4272 while (hp
<= x_mouse_x
);
4275 if (mouse_track_width
) /* Over text; use text pointer shape. */
4277 XDefineCursor (FRAME_X_DISPLAY (f
),
4279 f
->display
.x
->text_cursor
);
4280 x_rectangle (f
, f
->display
.x
->cursor_gc
,
4281 mouse_track_left
, mouse_track_top
,
4282 mouse_track_width
, 1);
4284 else if (in_mode_line
)
4285 XDefineCursor (FRAME_X_DISPLAY (f
),
4287 f
->display
.x
->modeline_cursor
);
4289 XDefineCursor (FRAME_X_DISPLAY (f
),
4291 f
->display
.x
->nontext_cursor
);
4294 XFlush (FRAME_X_DISPLAY (f
));
4297 obj
= read_char (-1, 0, 0, Qnil
, 0);
4300 while (CONSP (obj
) /* Mouse event */
4301 && EQ (Fcar (Fcdr (Fcdr (obj
))), Qnil
) /* Not scroll bar */
4302 && EQ (Vmouse_depressed
, Qnil
) /* Only motion events */
4303 && EQ (Vmouse_window
, selected_window
) /* In this window */
4306 unread_command_event
= obj
;
4308 if (mouse_track_width
)
4310 x_rectangle (f
, f
->display
.x
->reverse_gc
,
4311 mouse_track_left
, mouse_track_top
,
4312 mouse_track_width
, 1);
4313 mouse_track_width
= 0;
4314 if ((mouse_track_left
== f
->phys_cursor_x
4315 || mouse_track_left
- 1 == f
->phys_cursor_x
)
4316 && mouse_track_top
== f
->phys_cursor_y
)
4318 x_display_cursor (f
, 1);
4321 XDefineCursor (FRAME_X_DISPLAY (f
),
4323 f
->display
.x
->nontext_cursor
);
4324 XFlush (FRAME_X_DISPLAY (f
));
4334 /* Draw a pixmap specified by IMAGE_DATA of dimensions WIDTH and HEIGHT
4335 on the frame F at position X, Y. */
4337 x_draw_pixmap (f
, x
, y
, image_data
, width
, height
)
4339 int x
, y
, width
, height
;
4344 image
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
4345 FRAME_X_WINDOW (f
), image_data
,
4347 XCopyPlane (FRAME_X_DISPLAY (f
), image
, FRAME_X_WINDOW (f
),
4348 f
->display
.x
->normal_gc
, 0, 0, width
, height
, x
, y
);
4352 #if 0 /* I'm told these functions are superfluous
4353 given the ability to bind function keys. */
4356 DEFUN ("x-rebind-key", Fx_rebind_key
, Sx_rebind_key
, 3, 3, 0,
4357 "Rebind X keysym KEYSYM, with MODIFIERS, to generate NEWSTRING.\n\
4358 KEYSYM is a string which conforms to the X keysym definitions found\n\
4359 in X11/keysymdef.h, sans the initial XK_. MODIFIERS is nil or a\n\
4360 list of strings specifying modifier keys such as Control_L, which must\n\
4361 also be depressed for NEWSTRING to appear.")
4362 (x_keysym
, modifiers
, newstring
)
4363 register Lisp_Object x_keysym
;
4364 register Lisp_Object modifiers
;
4365 register Lisp_Object newstring
;
4368 register KeySym keysym
;
4369 KeySym modifier_list
[16];
4372 CHECK_STRING (x_keysym
, 1);
4373 CHECK_STRING (newstring
, 3);
4375 keysym
= XStringToKeysym ((char *) XSTRING (x_keysym
)->data
);
4376 if (keysym
== NoSymbol
)
4377 error ("Keysym does not exist");
4379 if (NILP (modifiers
))
4380 XRebindKeysym (x_current_display
, keysym
, modifier_list
, 0,
4381 XSTRING (newstring
)->data
, XSTRING (newstring
)->size
);
4384 register Lisp_Object rest
, mod
;
4387 for (rest
= modifiers
; !NILP (rest
); rest
= Fcdr (rest
))
4390 error ("Can't have more than 16 modifiers");
4393 CHECK_STRING (mod
, 3);
4394 modifier_list
[i
] = XStringToKeysym ((char *) XSTRING (mod
)->data
);
4396 if (modifier_list
[i
] == NoSymbol
4397 || !(IsModifierKey (modifier_list
[i
])
4398 || ((unsigned)(modifier_list
[i
]) == XK_Mode_switch
)
4399 || ((unsigned)(modifier_list
[i
]) == XK_Num_Lock
)))
4401 if (modifier_list
[i
] == NoSymbol
4402 || !IsModifierKey (modifier_list
[i
]))
4404 error ("Element is not a modifier keysym");
4408 XRebindKeysym (x_current_display
, keysym
, modifier_list
, i
,
4409 XSTRING (newstring
)->data
, XSTRING (newstring
)->size
);
4415 DEFUN ("x-rebind-keys", Fx_rebind_keys
, Sx_rebind_keys
, 2, 2, 0,
4416 "Rebind KEYCODE to list of strings STRINGS.\n\
4417 STRINGS should be a list of 16 elements, one for each shift combination.\n\
4418 nil as element means don't change.\n\
4419 See the documentation of `x-rebind-key' for more information.")
4421 register Lisp_Object keycode
;
4422 register Lisp_Object strings
;
4424 register Lisp_Object item
;
4425 register unsigned char *rawstring
;
4426 KeySym rawkey
, modifier
[1];
4428 register unsigned i
;
4431 CHECK_NUMBER (keycode
, 1);
4432 CHECK_CONS (strings
, 2);
4433 rawkey
= (KeySym
) ((unsigned) (XINT (keycode
))) & 255;
4434 for (i
= 0; i
<= 15; strings
= Fcdr (strings
), i
++)
4436 item
= Fcar (strings
);
4439 CHECK_STRING (item
, 2);
4440 strsize
= XSTRING (item
)->size
;
4441 rawstring
= (unsigned char *) xmalloc (strsize
);
4442 bcopy (XSTRING (item
)->data
, rawstring
, strsize
);
4443 modifier
[1] = 1 << i
;
4444 XRebindKeysym (x_current_display
, rawkey
, modifier
, 1,
4445 rawstring
, strsize
);
4450 #endif /* HAVE_X11 */
4453 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4455 XScreenNumberOfScreen (scr
)
4456 register Screen
*scr
;
4458 register Display
*dpy
;
4459 register Screen
*dpyscr
;
4463 dpyscr
= dpy
->screens
;
4465 for (i
= 0; i
< dpy
->nscreens
; i
++, dpyscr
++)
4471 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4474 select_visual (dpy
, screen
, depth
)
4477 unsigned int *depth
;
4480 XVisualInfo
*vinfo
, vinfo_template
;
4483 v
= DefaultVisualOfScreen (screen
);
4486 vinfo_template
.visualid
= XVisualIDFromVisual (v
);
4488 vinfo_template
.visualid
= v
->visualid
;
4491 vinfo_template
.screen
= XScreenNumberOfScreen (screen
);
4493 vinfo
= XGetVisualInfo (dpy
,
4494 VisualIDMask
| VisualScreenMask
, &vinfo_template
,
4497 fatal ("Can't get proper X visual info");
4499 if ((1 << vinfo
->depth
) == vinfo
->colormap_size
)
4500 *depth
= vinfo
->depth
;
4504 int n
= vinfo
->colormap_size
- 1;
4513 XFree ((char *) vinfo
);
4517 /* Return the X display structure for the display named NAME.
4518 Open a new connection if necessary. */
4520 struct x_display_info
*
4521 x_display_info_for_name (name
)
4525 struct x_display_info
*dpyinfo
;
4527 CHECK_STRING (name
, 0);
4529 for (dpyinfo
= x_display_list
, names
= x_display_name_list
;
4531 dpyinfo
= dpyinfo
->next
, names
= XCONS (names
)->cdr
)
4534 tem
= Fstring_equal (XCONS (XCONS (names
)->car
)->car
, name
);
4539 validate_x_resource_name ();
4541 dpyinfo
= x_term_init (name
, (unsigned char *)0,
4542 XSTRING (Vx_resource_name
)->data
);
4545 error ("X server %s not responding", XSTRING (name
)->data
);
4548 XSETFASTINT (Vwindow_system_version
, 11);
4553 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
4554 1, 3, 0, "Open a connection to an X server.\n\
4555 DISPLAY is the name of the display to connect to.\n\
4556 Optional second arg XRM-STRING is a string of resources in xrdb format.\n\
4557 If the optional third arg MUST-SUCCEED is non-nil,\n\
4558 terminate Emacs if we can't open the connection.")
4559 (display
, xrm_string
, must_succeed
)
4560 Lisp_Object display
, xrm_string
, must_succeed
;
4562 unsigned int n_planes
;
4563 unsigned char *xrm_option
;
4564 struct x_display_info
*dpyinfo
;
4566 CHECK_STRING (display
, 0);
4567 if (! NILP (xrm_string
))
4568 CHECK_STRING (xrm_string
, 1);
4570 if (! NILP (xrm_string
))
4571 xrm_option
= (unsigned char *) XSTRING (xrm_string
)->data
;
4573 xrm_option
= (unsigned char *) 0;
4575 validate_x_resource_name ();
4577 /* This is what opens the connection and sets x_current_display.
4578 This also initializes many symbols, such as those used for input. */
4579 dpyinfo
= x_term_init (display
, xrm_option
,
4580 XSTRING (Vx_resource_name
)->data
);
4584 if (!NILP (must_succeed
))
4585 fatal ("X server %s not responding.\n\
4586 Check the DISPLAY environment variable or use \"-d\"\n",
4587 XSTRING (display
)->data
);
4589 error ("X server %s not responding", XSTRING (display
)->data
);
4594 XSETFASTINT (Vwindow_system_version
, 11);
4598 DEFUN ("x-close-connection", Fx_close_connection
,
4599 Sx_close_connection
, 1, 1, 0,
4600 "Close the connection to DISPLAY's X server.\n\
4601 For DISPLAY, specify either a frame or a display name (a string).\n\
4602 If DISPLAY is nil, that stands for the selected frame's display.")
4604 Lisp_Object display
;
4606 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4607 struct x_display_info
*tail
;
4610 if (dpyinfo
->reference_count
> 0)
4611 error ("Display still has frames on it");
4614 /* Free the fonts in the font table. */
4615 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
4617 if (dpyinfo
->font_table
[i
].name
)
4618 free (dpyinfo
->font_table
[i
].name
);
4619 /* Don't free the full_name string;
4620 it is always shared with something else. */
4621 XFreeFont (dpyinfo
->display
, dpyinfo
->font_table
[i
].font
);
4623 x_destroy_all_bitmaps (dpyinfo
);
4624 XSetCloseDownMode (dpyinfo
->display
, DestroyAll
);
4626 #ifdef USE_X_TOOLKIT
4627 XtCloseDisplay (dpyinfo
->display
);
4629 XCloseDisplay (dpyinfo
->display
);
4632 x_delete_display (dpyinfo
);
4638 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
4639 "Return the list of display names that Emacs has connections to.")
4642 Lisp_Object tail
, result
;
4645 for (tail
= x_display_name_list
; ! NILP (tail
); tail
= XCONS (tail
)->cdr
)
4646 result
= Fcons (XCONS (XCONS (tail
)->car
)->car
, result
);
4651 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
4652 "If ON is non-nil, report X errors as soon as the erring request is made.\n\
4653 If ON is nil, allow buffering of requests.\n\
4654 Turning on synchronization prohibits the Xlib routines from buffering\n\
4655 requests and seriously degrades performance, but makes debugging much\n\
4657 The optional second argument DISPLAY specifies which display to act on.\n\
4658 DISPLAY should be either a frame or a display name (a string).\n\
4659 If DISPLAY is omitted or nil, that stands for the selected frame's display.")
4661 Lisp_Object display
, on
;
4663 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4665 XSynchronize (dpyinfo
->display
, !EQ (on
, Qnil
));
4670 /* Wait for responses to all X commands issued so far for frame F. */
4677 XSync (FRAME_X_DISPLAY (f
), False
);
4683 /* This is zero if not using X windows. */
4686 /* The section below is built by the lisp expression at the top of the file,
4687 just above where these variables are declared. */
4688 /*&&& init symbols here &&&*/
4689 Qauto_raise
= intern ("auto-raise");
4690 staticpro (&Qauto_raise
);
4691 Qauto_lower
= intern ("auto-lower");
4692 staticpro (&Qauto_lower
);
4693 Qbackground_color
= intern ("background-color");
4694 staticpro (&Qbackground_color
);
4695 Qbar
= intern ("bar");
4697 Qborder_color
= intern ("border-color");
4698 staticpro (&Qborder_color
);
4699 Qborder_width
= intern ("border-width");
4700 staticpro (&Qborder_width
);
4701 Qbox
= intern ("box");
4703 Qcursor_color
= intern ("cursor-color");
4704 staticpro (&Qcursor_color
);
4705 Qcursor_type
= intern ("cursor-type");
4706 staticpro (&Qcursor_type
);
4707 Qfont
= intern ("font");
4709 Qforeground_color
= intern ("foreground-color");
4710 staticpro (&Qforeground_color
);
4711 Qgeometry
= intern ("geometry");
4712 staticpro (&Qgeometry
);
4713 Qicon_left
= intern ("icon-left");
4714 staticpro (&Qicon_left
);
4715 Qicon_top
= intern ("icon-top");
4716 staticpro (&Qicon_top
);
4717 Qicon_type
= intern ("icon-type");
4718 staticpro (&Qicon_type
);
4719 Qinternal_border_width
= intern ("internal-border-width");
4720 staticpro (&Qinternal_border_width
);
4721 Qleft
= intern ("left");
4723 Qmouse_color
= intern ("mouse-color");
4724 staticpro (&Qmouse_color
);
4725 Qnone
= intern ("none");
4727 Qparent_id
= intern ("parent-id");
4728 staticpro (&Qparent_id
);
4729 Qscroll_bar_width
= intern ("scroll-bar-width");
4730 staticpro (&Qscroll_bar_width
);
4731 Qsuppress_icon
= intern ("suppress-icon");
4732 staticpro (&Qsuppress_icon
);
4733 Qtop
= intern ("top");
4735 Qundefined_color
= intern ("undefined-color");
4736 staticpro (&Qundefined_color
);
4737 Qvertical_scroll_bars
= intern ("vertical-scroll-bars");
4738 staticpro (&Qvertical_scroll_bars
);
4739 Qvisibility
= intern ("visibility");
4740 staticpro (&Qvisibility
);
4741 Qwindow_id
= intern ("window-id");
4742 staticpro (&Qwindow_id
);
4743 Qx_frame_parameter
= intern ("x-frame-parameter");
4744 staticpro (&Qx_frame_parameter
);
4745 Qx_resource_name
= intern ("x-resource-name");
4746 staticpro (&Qx_resource_name
);
4747 Quser_position
= intern ("user-position");
4748 staticpro (&Quser_position
);
4749 Quser_size
= intern ("user-size");
4750 staticpro (&Quser_size
);
4751 Qdisplay
= intern ("display");
4752 staticpro (&Qdisplay
);
4753 /* This is the end of symbol initialization. */
4755 Fput (Qundefined_color
, Qerror_conditions
,
4756 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
4757 Fput (Qundefined_color
, Qerror_message
,
4758 build_string ("Undefined color"));
4760 init_x_parm_symbols ();
4762 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path
,
4763 "List of directories to search for bitmap files for X.");
4764 Vx_bitmap_file_path
= Fcons (build_string (PATH_BITMAPS
), Qnil
);
4766 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
4767 "The shape of the pointer when over text.\n\
4768 Changing the value does not affect existing frames\n\
4769 unless you set the mouse color.");
4770 Vx_pointer_shape
= Qnil
;
4772 DEFVAR_LISP ("x-resource-name", &Vx_resource_name
,
4773 "The name Emacs uses to look up X resources; for internal use only.\n\
4774 `x-get-resource' uses this as the first component of the instance name\n\
4775 when requesting resource values.\n\
4776 Emacs initially sets `x-resource-name' to the name under which Emacs\n\
4777 was invoked, or to the value specified with the `-name' or `-rn'\n\
4778 switches, if present.");
4779 Vx_resource_name
= Qnil
;
4781 #if 0 /* This doesn't really do anything. */
4782 DEFVAR_INT ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape
,
4783 "The shape of the pointer when not over text.\n\
4784 This variable takes effect when you create a new frame\n\
4785 or when you set the mouse color.");
4787 Vx_nontext_pointer_shape
= Qnil
;
4789 #if 0 /* This doesn't really do anything. */
4790 DEFVAR_INT ("x-mode-pointer-shape", &Vx_mode_pointer_shape
,
4791 "The shape of the pointer when over the mode line.\n\
4792 This variable takes effect when you create a new frame\n\
4793 or when you set the mouse color.");
4795 Vx_mode_pointer_shape
= Qnil
;
4797 DEFVAR_INT ("x-sensitive-text-pointer-shape",
4798 &Vx_sensitive_text_pointer_shape
,
4799 "The shape of the pointer when over mouse-sensitive text.\n\
4800 This variable takes effect when you create a new frame\n\
4801 or when you set the mouse color.");
4802 Vx_sensitive_text_pointer_shape
= Qnil
;
4804 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
4805 "A string indicating the foreground color of the cursor box.");
4806 Vx_cursor_fore_pixel
= Qnil
;
4808 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
4809 "Non-nil if no X window manager is in use.");
4811 #ifdef USE_X_TOOLKIT
4812 Fprovide (intern ("x-toolkit"));
4815 defsubr (&Sx_get_resource
);
4817 defsubr (&Sx_draw_rectangle
);
4818 defsubr (&Sx_erase_rectangle
);
4819 defsubr (&Sx_contour_region
);
4820 defsubr (&Sx_uncontour_region
);
4822 defsubr (&Sx_list_fonts
);
4823 defsubr (&Sx_display_color_p
);
4824 defsubr (&Sx_display_grayscale_p
);
4825 defsubr (&Sx_color_defined_p
);
4826 defsubr (&Sx_color_values
);
4827 defsubr (&Sx_server_max_request_size
);
4828 defsubr (&Sx_server_vendor
);
4829 defsubr (&Sx_server_version
);
4830 defsubr (&Sx_display_pixel_width
);
4831 defsubr (&Sx_display_pixel_height
);
4832 defsubr (&Sx_display_mm_width
);
4833 defsubr (&Sx_display_mm_height
);
4834 defsubr (&Sx_display_screens
);
4835 defsubr (&Sx_display_planes
);
4836 defsubr (&Sx_display_color_cells
);
4837 defsubr (&Sx_display_visual_class
);
4838 defsubr (&Sx_display_backing_store
);
4839 defsubr (&Sx_display_save_under
);
4841 defsubr (&Sx_rebind_key
);
4842 defsubr (&Sx_rebind_keys
);
4843 defsubr (&Sx_track_pointer
);
4844 defsubr (&Sx_grab_pointer
);
4845 defsubr (&Sx_ungrab_pointer
);
4847 defsubr (&Sx_parse_geometry
);
4848 defsubr (&Sx_create_frame
);
4849 defsubr (&Sfocus_frame
);
4850 defsubr (&Sunfocus_frame
);
4852 defsubr (&Sx_horizontal_line
);
4854 defsubr (&Sx_open_connection
);
4855 defsubr (&Sx_close_connection
);
4856 defsubr (&Sx_display_list
);
4857 defsubr (&Sx_synchronize
);
4860 #endif /* HAVE_X_WINDOWS */