1 /* Functions for the X window system.
2 Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20 /* Completely rewritten by Richard Stallman. */
22 /* Rewritten for X11 by Joseph Arceneaux */
27 /* This makes the fields of a Display accessible, in Xlib header files. */
28 #define XLIB_ILLEGAL_ACCESS
35 #include "dispextern.h"
37 #include "blockinput.h"
44 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */
45 #include "bitmaps/gray.xbm"
47 #include <X11/bitmaps/gray>
50 #include "[.bitmaps]gray.xbm"
54 #include <X11/Shell.h>
56 #include <X11/Xaw/Paned.h>
57 #include <X11/Xaw/Label.h>
60 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
69 #include "../lwlib/lwlib.h"
71 /* Do the EDITRES protocol if running X11R5 */
72 #if (XtSpecificationRelease >= 5)
74 extern void _XEditResCheckMessages ();
75 #endif /* R5 + Athena */
77 /* Unique id counter for widgets created by the Lucid Widget
79 extern LWLIB_ID widget_id_tick
;
81 /* This is part of a kludge--see lwlib/xlwmenu.c. */
82 XFontStruct
*xlwmenu_default_font
;
84 extern void free_frame_menubar ();
85 #endif /* USE_X_TOOLKIT */
87 #define min(a,b) ((a) < (b) ? (a) : (b))
88 #define max(a,b) ((a) > (b) ? (a) : (b))
91 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
93 #define MAXREQUEST(dpy) ((dpy)->max_request_size)
96 /* The name we're using in resource queries. */
97 Lisp_Object Vx_resource_name
;
99 /* The background and shape of the mouse pointer, and shape when not
100 over text or in the modeline. */
101 Lisp_Object Vx_pointer_shape
, Vx_nontext_pointer_shape
, Vx_mode_pointer_shape
;
102 /* The shape when over mouse-sensitive text. */
103 Lisp_Object Vx_sensitive_text_pointer_shape
;
105 /* Color of chars displayed in cursor box. */
106 Lisp_Object Vx_cursor_fore_pixel
;
108 /* Nonzero if using X. */
111 /* Non nil if no window manager is in use. */
112 Lisp_Object Vx_no_window_manager
;
114 /* Search path for bitmap files. */
115 Lisp_Object Vx_bitmap_file_path
;
117 /* Evaluate this expression to rebuild the section of syms_of_xfns
118 that initializes and staticpros the symbols declared below. Note
119 that Emacs 18 has a bug that keeps C-x C-e from being able to
120 evaluate this expression.
123 ;; Accumulate a list of the symbols we want to initialize from the
124 ;; declarations at the top of the file.
125 (goto-char (point-min))
126 (search-forward "/\*&&& symbols declared here &&&*\/\n")
128 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
130 (cons (buffer-substring (match-beginning 1) (match-end 1))
133 (setq symbol-list (nreverse symbol-list))
134 ;; Delete the section of syms_of_... where we initialize the symbols.
135 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
136 (let ((start (point)))
137 (while (looking-at "^ Q")
139 (kill-region start (point)))
140 ;; Write a new symbol initialization section.
142 (insert (format " %s = intern (\"" (car symbol-list)))
143 (let ((start (point)))
144 (insert (substring (car symbol-list) 1))
145 (subst-char-in-region start (point) ?_ ?-))
146 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
147 (setq symbol-list (cdr symbol-list)))))
151 /*&&& symbols declared here &&&*/
152 Lisp_Object Qauto_raise
;
153 Lisp_Object Qauto_lower
;
154 Lisp_Object Qbackground_color
;
156 Lisp_Object Qborder_color
;
157 Lisp_Object Qborder_width
;
159 Lisp_Object Qcursor_color
;
160 Lisp_Object Qcursor_type
;
162 Lisp_Object Qforeground_color
;
163 Lisp_Object Qgeometry
;
164 Lisp_Object Qicon_left
;
165 Lisp_Object Qicon_top
;
166 Lisp_Object Qicon_type
;
167 Lisp_Object Qinternal_border_width
;
169 Lisp_Object Qmouse_color
;
171 Lisp_Object Qparent_id
;
172 Lisp_Object Qscroll_bar_width
;
173 Lisp_Object Qsuppress_icon
;
175 Lisp_Object Qundefined_color
;
176 Lisp_Object Qvertical_scroll_bars
;
177 Lisp_Object Qvisibility
;
178 Lisp_Object Qwindow_id
;
179 Lisp_Object Qx_frame_parameter
;
180 Lisp_Object Qx_resource_name
;
181 Lisp_Object Quser_position
;
182 Lisp_Object Quser_size
;
183 Lisp_Object Qdisplay
;
185 /* The below are defined in frame.c. */
186 extern Lisp_Object Qheight
, Qminibuffer
, Qname
, Qonly
, Qwidth
;
187 extern Lisp_Object Qunsplittable
, Qmenu_bar_lines
;
189 extern Lisp_Object Vwindow_system_version
;
192 /* Error if we are not connected to X. */
197 error ("X windows are not in use or not initialized");
200 /* Nonzero if using X for display. */
208 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
209 and checking validity for X. */
212 check_x_frame (frame
)
221 CHECK_LIVE_FRAME (frame
, 0);
225 error ("non-X frame used");
229 /* Let the user specify an X display with a frame.
230 nil stands for the selected frame--or, if that is not an X frame,
231 the first X display on the list. */
233 static struct x_display_info
*
234 check_x_display_info (frame
)
239 if (FRAME_X_P (selected_frame
))
240 return FRAME_X_DISPLAY_INFO (selected_frame
);
241 else if (x_display_list
!= 0)
242 return x_display_list
;
244 error ("X windows are not in use or not initialized");
246 else if (STRINGP (frame
))
247 return x_display_info_for_name (frame
);
252 CHECK_LIVE_FRAME (frame
, 0);
255 error ("non-X frame used");
256 return FRAME_X_DISPLAY_INFO (f
);
260 /* Return the Emacs frame-object corresponding to an X window.
261 It could be the frame's main window or an icon window. */
263 /* This function can be called during GC, so use GC_xxx type test macros. */
266 x_window_to_frame (dpyinfo
, wdesc
)
267 struct x_display_info
*dpyinfo
;
270 Lisp_Object tail
, frame
;
273 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
275 frame
= XCONS (tail
)->car
;
276 if (!GC_FRAMEP (frame
))
279 if (f
->display
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
282 if ((f
->display
.x
->edit_widget
283 && XtWindow (f
->display
.x
->edit_widget
) == wdesc
)
284 || f
->display
.x
->icon_desc
== wdesc
)
286 #else /* not USE_X_TOOLKIT */
287 if (FRAME_X_WINDOW (f
) == wdesc
288 || f
->display
.x
->icon_desc
== wdesc
)
290 #endif /* not USE_X_TOOLKIT */
296 /* Like x_window_to_frame but also compares the window with the widget's
300 x_any_window_to_frame (dpyinfo
, wdesc
)
301 struct x_display_info
*dpyinfo
;
304 Lisp_Object tail
, frame
;
308 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
310 frame
= XCONS (tail
)->car
;
311 if (!GC_FRAMEP (frame
))
314 if (f
->display
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
317 /* This frame matches if the window is any of its widgets. */
318 if (wdesc
== XtWindow (x
->widget
)
319 || wdesc
== XtWindow (x
->column_widget
)
320 || wdesc
== XtWindow (x
->edit_widget
))
322 /* Match if the window is this frame's menubar. */
323 if (lw_window_is_in_menubar (wdesc
, x
->menubar_widget
))
329 /* Likewise, but exclude the menu bar widget. */
332 x_non_menubar_window_to_frame (dpyinfo
, wdesc
)
333 struct x_display_info
*dpyinfo
;
336 Lisp_Object tail
, frame
;
340 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
342 frame
= XCONS (tail
)->car
;
343 if (!GC_FRAMEP (frame
))
346 if (f
->display
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
349 /* This frame matches if the window is any of its widgets. */
350 if (wdesc
== XtWindow (x
->widget
)
351 || wdesc
== XtWindow (x
->column_widget
)
352 || wdesc
== XtWindow (x
->edit_widget
))
358 /* Return the frame whose principal (outermost) window is WDESC.
359 If WDESC is some other (smaller) window, we return 0. */
362 x_top_window_to_frame (dpyinfo
, wdesc
)
363 struct x_display_info
*dpyinfo
;
366 Lisp_Object tail
, frame
;
370 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
372 frame
= XCONS (tail
)->car
;
373 if (!GC_FRAMEP (frame
))
376 if (f
->display
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
379 /* This frame matches if the window is its topmost widget. */
380 if (wdesc
== XtWindow (x
->widget
))
382 #if 0 /* I don't know why it did this,
383 but it seems logically wrong,
384 and it causes trouble for MapNotify events. */
385 /* Match if the window is this frame's menubar. */
386 if (x
->menubar_widget
387 && wdesc
== XtWindow (x
->menubar_widget
))
393 #endif /* USE_X_TOOLKIT */
397 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
398 id, which is just an int that this section returns. Bitmaps are
399 reference counted so they can be shared among frames.
401 Bitmap indices are guaranteed to be > 0, so a negative number can
402 be used to indicate no bitmap.
404 If you use x_create_bitmap_from_data, then you must keep track of
405 the bitmaps yourself. That is, creating a bitmap from the same
406 data more than once will not be caught. */
409 /* Functions to access the contents of a bitmap, given an id. */
412 x_bitmap_height (f
, id
)
416 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].height
;
420 x_bitmap_width (f
, id
)
424 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].width
;
428 x_bitmap_pixmap (f
, id
)
432 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].pixmap
;
436 /* Allocate a new bitmap record. Returns index of new record. */
439 x_allocate_bitmap_record (f
)
442 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
445 if (dpyinfo
->bitmaps
== NULL
)
447 dpyinfo
->bitmaps_size
= 10;
449 = (struct x_bitmap_record
*) xmalloc (dpyinfo
->bitmaps_size
* sizeof (struct x_bitmap_record
));
450 dpyinfo
->bitmaps_last
= 1;
454 if (dpyinfo
->bitmaps_last
< dpyinfo
->bitmaps_size
)
455 return ++dpyinfo
->bitmaps_last
;
457 for (i
= 0; i
< dpyinfo
->bitmaps_size
; ++i
)
458 if (dpyinfo
->bitmaps
[i
].refcount
== 0)
461 dpyinfo
->bitmaps_size
*= 2;
463 = (struct x_bitmap_record
*) xrealloc (dpyinfo
->bitmaps
,
464 dpyinfo
->bitmaps_size
* sizeof (struct x_bitmap_record
));
465 return ++dpyinfo
->bitmaps_last
;
468 /* Add one reference to the reference count of the bitmap with id ID. */
471 x_reference_bitmap (f
, id
)
475 ++FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].refcount
;
478 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
481 x_create_bitmap_from_data (f
, bits
, width
, height
)
484 unsigned int width
, height
;
486 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
490 bitmap
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
491 bits
, width
, height
);
496 id
= x_allocate_bitmap_record (f
);
497 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
498 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
499 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
500 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
501 dpyinfo
->bitmaps
[id
- 1].height
= height
;
502 dpyinfo
->bitmaps
[id
- 1].width
= width
;
507 /* Create bitmap from file FILE for frame F. */
510 x_create_bitmap_from_file (f
, file
)
514 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
515 unsigned int width
, height
;
517 int xhot
, yhot
, result
, id
;
522 /* Look for an existing bitmap with the same name. */
523 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
525 if (dpyinfo
->bitmaps
[id
].refcount
526 && dpyinfo
->bitmaps
[id
].file
527 && !strcmp (dpyinfo
->bitmaps
[id
].file
, (char *) XSTRING (file
)->data
))
529 ++dpyinfo
->bitmaps
[id
].refcount
;
534 /* Search bitmap-file-path for the file, if appropriate. */
535 fd
= openp (Vx_bitmap_file_path
, file
, "", &found
, 0);
540 filename
= (char *) XSTRING (found
)->data
;
542 result
= XReadBitmapFile (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
543 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
544 if (result
!= BitmapSuccess
)
547 id
= x_allocate_bitmap_record (f
);
548 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
549 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
550 dpyinfo
->bitmaps
[id
- 1].file
= (char *) xmalloc (XSTRING (file
)->size
+ 1);
551 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
552 dpyinfo
->bitmaps
[id
- 1].height
= height
;
553 dpyinfo
->bitmaps
[id
- 1].width
= width
;
554 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, XSTRING (file
)->data
);
559 /* Remove reference to bitmap with id number ID. */
562 x_destroy_bitmap (f
, id
)
566 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
570 --dpyinfo
->bitmaps
[id
- 1].refcount
;
571 if (dpyinfo
->bitmaps
[id
- 1].refcount
== 0)
574 XFreePixmap (FRAME_X_DISPLAY (f
), dpyinfo
->bitmaps
[id
- 1].pixmap
);
575 if (dpyinfo
->bitmaps
[id
- 1].file
)
577 free (dpyinfo
->bitmaps
[id
- 1].file
);
578 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
585 /* Free all the bitmaps for the display specified by DPYINFO. */
588 x_destroy_all_bitmaps (dpyinfo
)
589 struct x_display_info
*dpyinfo
;
592 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++)
593 if (dpyinfo
->bitmaps
[i
].refcount
> 0)
595 XFreePixmap (dpyinfo
->display
, dpyinfo
->bitmaps
[i
].pixmap
);
596 if (dpyinfo
->bitmaps
[i
].file
)
597 free (dpyinfo
->bitmaps
[i
].file
);
599 dpyinfo
->bitmaps_last
= 0;
602 /* Connect the frame-parameter names for X frames
603 to the ways of passing the parameter values to the window system.
605 The name of a parameter, as a Lisp symbol,
606 has an `x-frame-parameter' property which is an integer in Lisp
607 but can be interpreted as an `enum x_frame_parm' in C. */
611 X_PARM_FOREGROUND_COLOR
,
612 X_PARM_BACKGROUND_COLOR
,
619 X_PARM_INTERNAL_BORDER_WIDTH
,
623 X_PARM_VERT_SCROLL_BAR
,
625 X_PARM_MENU_BAR_LINES
629 struct x_frame_parm_table
632 void (*setter
)( /* struct frame *frame, Lisp_Object val, oldval */ );
635 void x_set_foreground_color ();
636 void x_set_background_color ();
637 void x_set_mouse_color ();
638 void x_set_cursor_color ();
639 void x_set_border_color ();
640 void x_set_cursor_type ();
641 void x_set_icon_type ();
643 void x_set_border_width ();
644 void x_set_internal_border_width ();
645 void x_explicitly_set_name ();
646 void x_set_autoraise ();
647 void x_set_autolower ();
648 void x_set_vertical_scroll_bars ();
649 void x_set_visibility ();
650 void x_set_menu_bar_lines ();
651 void x_set_scroll_bar_width ();
652 void x_set_unsplittable ();
654 static struct x_frame_parm_table x_frame_parms
[] =
656 "foreground-color", x_set_foreground_color
,
657 "background-color", x_set_background_color
,
658 "mouse-color", x_set_mouse_color
,
659 "cursor-color", x_set_cursor_color
,
660 "border-color", x_set_border_color
,
661 "cursor-type", x_set_cursor_type
,
662 "icon-type", x_set_icon_type
,
664 "border-width", x_set_border_width
,
665 "internal-border-width", x_set_internal_border_width
,
666 "name", x_explicitly_set_name
,
667 "auto-raise", x_set_autoraise
,
668 "auto-lower", x_set_autolower
,
669 "vertical-scroll-bars", x_set_vertical_scroll_bars
,
670 "visibility", x_set_visibility
,
671 "menu-bar-lines", x_set_menu_bar_lines
,
672 "scroll-bar-width", x_set_scroll_bar_width
,
673 "unsplittable", x_set_unsplittable
,
676 /* Attach the `x-frame-parameter' properties to
677 the Lisp symbol names of parameters relevant to X. */
679 init_x_parm_symbols ()
683 for (i
= 0; i
< sizeof (x_frame_parms
) / sizeof (x_frame_parms
[0]); i
++)
684 Fput (intern (x_frame_parms
[i
].name
), Qx_frame_parameter
,
688 /* Change the parameters of FRAME as specified by ALIST.
689 If a parameter is not specially recognized, do nothing;
690 otherwise call the `x_set_...' function for that parameter. */
693 x_set_frame_parameters (f
, alist
)
699 /* If both of these parameters are present, it's more efficient to
700 set them both at once. So we wait until we've looked at the
701 entire list before we set them. */
702 Lisp_Object width
, height
;
705 Lisp_Object left
, top
;
707 /* Same with these. */
708 Lisp_Object icon_left
, icon_top
;
710 /* Record in these vectors all the parms specified. */
714 int left_no_change
= 0, top_no_change
= 0;
715 int icon_left_no_change
= 0, icon_top_no_change
= 0;
718 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
721 parms
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
722 values
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
724 /* Extract parm names and values into those vectors. */
727 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
729 Lisp_Object elt
, prop
, val
;
732 parms
[i
] = Fcar (elt
);
733 values
[i
] = Fcdr (elt
);
737 width
= height
= top
= left
= Qunbound
;
738 icon_left
= icon_top
= Qunbound
;
740 /* Now process them in reverse of specified order. */
741 for (i
--; i
>= 0; i
--)
743 Lisp_Object prop
, val
;
748 if (EQ (prop
, Qwidth
))
750 else if (EQ (prop
, Qheight
))
752 else if (EQ (prop
, Qtop
))
754 else if (EQ (prop
, Qleft
))
756 else if (EQ (prop
, Qicon_top
))
758 else if (EQ (prop
, Qicon_left
))
762 register Lisp_Object param_index
, old_value
;
764 param_index
= Fget (prop
, Qx_frame_parameter
);
765 old_value
= get_frame_param (f
, prop
);
766 store_frame_param (f
, prop
, val
);
767 if (NATNUMP (param_index
)
768 && (XFASTINT (param_index
)
769 < sizeof (x_frame_parms
)/sizeof (x_frame_parms
[0])))
770 (*x_frame_parms
[XINT (param_index
)].setter
)(f
, val
, old_value
);
774 /* Don't die if just one of these was set. */
775 if (EQ (left
, Qunbound
))
778 if (f
->display
.x
->left_pos
< 0)
779 left
= Fcons (Qplus
, Fcons (make_number (f
->display
.x
->left_pos
), Qnil
));
781 XSETINT (left
, f
->display
.x
->left_pos
);
783 if (EQ (top
, Qunbound
))
786 if (f
->display
.x
->top_pos
< 0)
787 top
= Fcons (Qplus
, Fcons (make_number (f
->display
.x
->top_pos
), Qnil
));
789 XSETINT (top
, f
->display
.x
->top_pos
);
792 /* If one of the icon positions was not set, preserve or default it. */
793 if (EQ (icon_left
, Qunbound
) || ! INTEGERP (icon_left
))
795 icon_left_no_change
= 1;
796 icon_left
= Fcdr (Fassq (Qicon_left
, f
->param_alist
));
797 if (NILP (icon_left
))
798 XSETINT (icon_left
, 0);
800 if (EQ (icon_top
, Qunbound
) || ! INTEGERP (icon_top
))
802 icon_top_no_change
= 1;
803 icon_top
= Fcdr (Fassq (Qicon_top
, f
->param_alist
));
805 XSETINT (icon_top
, 0);
808 /* Don't die if just one of these was set. */
809 if (EQ (width
, Qunbound
))
810 XSETINT (width
, FRAME_WIDTH (f
));
811 if (EQ (height
, Qunbound
))
812 XSETINT (height
, FRAME_HEIGHT (f
));
814 /* Don't set these parameters unless they've been explicitly
815 specified. The window might be mapped or resized while we're in
816 this function, and we don't want to override that unless the lisp
817 code has asked for it.
819 Don't set these parameters unless they actually differ from the
820 window's current parameters; the window may not actually exist
825 check_frame_size (f
, &height
, &width
);
827 XSETFRAME (frame
, f
);
829 if ((NUMBERP (width
) && XINT (width
) != FRAME_WIDTH (f
))
830 || (NUMBERP (height
) && XINT (height
) != FRAME_HEIGHT (f
)))
831 Fset_frame_size (frame
, width
, height
);
833 if ((!NILP (left
) || !NILP (top
))
834 && ! (left_no_change
&& top_no_change
)
835 && ! (NUMBERP (left
) && XINT (left
) == f
->display
.x
->left_pos
836 && NUMBERP (top
) && XINT (top
) == f
->display
.x
->top_pos
))
841 /* Record the signs. */
842 f
->display
.x
->size_hint_flags
&= ~ (XNegative
| YNegative
);
843 if (EQ (left
, Qminus
))
844 f
->display
.x
->size_hint_flags
|= XNegative
;
845 else if (INTEGERP (left
))
847 leftpos
= XINT (left
);
849 f
->display
.x
->size_hint_flags
|= XNegative
;
851 else if (CONSP (left
) && EQ (XCONS (left
)->car
, Qminus
)
852 && CONSP (XCONS (left
)->cdr
)
853 && INTEGERP (XCONS (XCONS (left
)->cdr
)->car
))
855 leftpos
= - XINT (XCONS (XCONS (left
)->cdr
)->car
);
856 f
->display
.x
->size_hint_flags
|= XNegative
;
858 else if (CONSP (left
) && EQ (XCONS (left
)->car
, Qplus
)
859 && CONSP (XCONS (left
)->cdr
)
860 && INTEGERP (XCONS (XCONS (left
)->cdr
)->car
))
862 leftpos
= XINT (XCONS (XCONS (left
)->cdr
)->car
);
865 if (EQ (top
, Qminus
))
866 f
->display
.x
->size_hint_flags
|= YNegative
;
867 else if (INTEGERP (top
))
871 f
->display
.x
->size_hint_flags
|= YNegative
;
873 else if (CONSP (top
) && EQ (XCONS (top
)->car
, Qminus
)
874 && CONSP (XCONS (top
)->cdr
)
875 && INTEGERP (XCONS (XCONS (top
)->cdr
)->car
))
877 toppos
= - XINT (XCONS (XCONS (top
)->cdr
)->car
);
878 f
->display
.x
->size_hint_flags
|= YNegative
;
880 else if (CONSP (top
) && EQ (XCONS (top
)->car
, Qplus
)
881 && CONSP (XCONS (top
)->cdr
)
882 && INTEGERP (XCONS (XCONS (top
)->cdr
)->car
))
884 toppos
= XINT (XCONS (XCONS (top
)->cdr
)->car
);
888 /* Store the numeric value of the position. */
889 f
->display
.x
->top_pos
= toppos
;
890 f
->display
.x
->left_pos
= leftpos
;
892 f
->display
.x
->win_gravity
= NorthWestGravity
;
894 /* Actually set that position, and convert to absolute. */
895 x_set_offset (f
, leftpos
, toppos
, -1);
898 if ((!NILP (icon_left
) || !NILP (icon_top
))
899 && ! (icon_left_no_change
&& icon_top_no_change
))
900 x_wm_set_icon_position (f
, XINT (icon_left
), XINT (icon_top
));
904 /* Store the screen positions of frame F into XPTR and YPTR.
905 These are the positions of the containing window manager window,
906 not Emacs's own window. */
909 x_real_positions (f
, xptr
, yptr
)
916 /* This is pretty gross, but seems to be the easiest way out of
917 the problem that arises when restarting window-managers. */
920 Window outer
= XtWindow (f
->display
.x
->widget
);
922 Window outer
= f
->display
.x
->window_desc
;
924 Window tmp_root_window
;
925 Window
*tmp_children
;
928 x_catch_errors (FRAME_X_DISPLAY (f
));
931 XQueryTree (FRAME_X_DISPLAY (f
), outer
, &tmp_root_window
,
932 &f
->display
.x
->parent_desc
,
933 &tmp_children
, &tmp_nchildren
);
934 xfree (tmp_children
);
938 /* Find the position of the outside upper-left corner of
939 the inner window, with respect to the outer window. */
940 if (f
->display
.x
->parent_desc
!= FRAME_X_DISPLAY_INFO (f
)->root_window
)
942 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
944 /* From-window, to-window. */
946 XtWindow (f
->display
.x
->widget
),
948 f
->display
.x
->window_desc
,
950 f
->display
.x
->parent_desc
,
952 /* From-position, to-position. */
953 0, 0, &win_x
, &win_y
,
958 #if 0 /* The values seem to be right without this and wrong with. */
959 win_x
+= f
->display
.x
->border_width
;
960 win_y
+= f
->display
.x
->border_width
;
964 /* It is possible for the window returned by the XQueryNotify
965 to become invalid by the time we call XTranslateCoordinates.
966 That can happen when you restart some window managers.
967 If so, we get an error in XTranslateCoordinates.
968 Detect that and try the whole thing over. */
969 if (! x_had_errors_p (FRAME_X_DISPLAY (f
)))
973 x_uncatch_errors (FRAME_X_DISPLAY (f
));
975 *xptr
= f
->display
.x
->left_pos
- win_x
;
976 *yptr
= f
->display
.x
->top_pos
- win_y
;
979 /* Insert a description of internally-recorded parameters of frame X
980 into the parameter alist *ALISTPTR that is to be given to the user.
981 Only parameters that are specific to the X window system
982 and whose values are not correctly recorded in the frame's
983 param_alist need to be considered here. */
985 x_report_frame_params (f
, alistptr
)
987 Lisp_Object
*alistptr
;
992 /* Represent negative positions (off the top or left screen edge)
993 in a way that Fmodify_frame_parameters will understand correctly. */
994 XSETINT (tem
, f
->display
.x
->left_pos
);
995 if (f
->display
.x
->left_pos
>= 0)
996 store_in_alist (alistptr
, Qleft
, tem
);
998 store_in_alist (alistptr
, Qleft
, Fcons (Qplus
, Fcons (tem
, Qnil
)));
1000 XSETINT (tem
, f
->display
.x
->top_pos
);
1001 if (f
->display
.x
->top_pos
>= 0)
1002 store_in_alist (alistptr
, Qtop
, tem
);
1004 store_in_alist (alistptr
, Qtop
, Fcons (Qplus
, Fcons (tem
, Qnil
)));
1006 store_in_alist (alistptr
, Qborder_width
,
1007 make_number (f
->display
.x
->border_width
));
1008 store_in_alist (alistptr
, Qinternal_border_width
,
1009 make_number (f
->display
.x
->internal_border_width
));
1010 sprintf (buf
, "%ld", (long) FRAME_X_WINDOW (f
));
1011 store_in_alist (alistptr
, Qwindow_id
,
1012 build_string (buf
));
1013 FRAME_SAMPLE_VISIBILITY (f
);
1014 store_in_alist (alistptr
, Qvisibility
,
1015 (FRAME_VISIBLE_P (f
) ? Qt
1016 : FRAME_ICONIFIED_P (f
) ? Qicon
: Qnil
));
1017 store_in_alist (alistptr
, Qdisplay
,
1018 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->car
);
1022 /* Decide if color named COLOR is valid for the display associated with
1023 the selected frame; if so, return the rgb values in COLOR_DEF.
1024 If ALLOC is nonzero, allocate a new colormap cell. */
1027 defined_color (f
, color
, color_def
, alloc
)
1033 register int status
;
1034 Colormap screen_colormap
;
1035 Display
*display
= FRAME_X_DISPLAY (f
);
1038 screen_colormap
= DefaultColormap (display
, XDefaultScreen (display
));
1040 status
= XParseColor (display
, screen_colormap
, color
, color_def
);
1041 if (status
&& alloc
)
1043 status
= XAllocColor (display
, screen_colormap
, color_def
);
1046 /* If we got to this point, the colormap is full, so we're
1047 going to try and get the next closest color.
1048 The algorithm used is a least-squares matching, which is
1049 what X uses for closest color matching with StaticColor visuals. */
1054 long nearest_delta
, trial_delta
;
1057 no_cells
= XDisplayCells (display
, XDefaultScreen (display
));
1058 cells
= (XColor
*) alloca (sizeof (XColor
) * no_cells
);
1060 for (x
= 0; x
< no_cells
; x
++)
1063 XQueryColors (display
, screen_colormap
, cells
, no_cells
);
1065 /* I'm assuming CSE so I'm not going to condense this. */
1066 nearest_delta
= ((((color_def
->red
>> 8) - (cells
[0].red
>> 8))
1067 * ((color_def
->red
>> 8) - (cells
[0].red
>> 8)))
1069 (((color_def
->green
>> 8) - (cells
[0].green
>> 8))
1070 * ((color_def
->green
>> 8) - (cells
[0].green
>> 8)))
1072 (((color_def
->blue
>> 8) - (cells
[0].blue
>> 8))
1073 * ((color_def
->blue
>> 8) - (cells
[0].blue
>> 8))));
1074 for (x
= 1; x
< no_cells
; x
++)
1076 trial_delta
= ((((color_def
->red
>> 8) - (cells
[x
].red
>> 8))
1077 * ((color_def
->red
>> 8) - (cells
[x
].red
>> 8)))
1079 (((color_def
->green
>> 8) - (cells
[x
].green
>> 8))
1080 * ((color_def
->green
>> 8) - (cells
[x
].green
>> 8)))
1082 (((color_def
->blue
>> 8) - (cells
[x
].blue
>> 8))
1083 * ((color_def
->blue
>> 8) - (cells
[x
].blue
>> 8))));
1084 if (trial_delta
< nearest_delta
)
1087 nearest_delta
= trial_delta
;
1090 color_def
->red
= cells
[nearest
].red
;
1091 color_def
->green
= cells
[nearest
].green
;
1092 color_def
->blue
= cells
[nearest
].blue
;
1093 status
= XAllocColor (display
, screen_colormap
, color_def
);
1104 /* Given a string ARG naming a color, compute a pixel value from it
1105 suitable for screen F.
1106 If F is not a color screen, return DEF (default) regardless of what
1110 x_decode_color (f
, arg
, def
)
1117 CHECK_STRING (arg
, 0);
1119 if (strcmp (XSTRING (arg
)->data
, "black") == 0)
1120 return BLACK_PIX_DEFAULT (f
);
1121 else if (strcmp (XSTRING (arg
)->data
, "white") == 0)
1122 return WHITE_PIX_DEFAULT (f
);
1124 if (FRAME_X_DISPLAY_INFO (f
)->n_planes
== 1)
1127 /* defined_color is responsible for coping with failures
1128 by looking for a near-miss. */
1129 if (defined_color (f
, XSTRING (arg
)->data
, &cdef
, 1))
1132 /* defined_color failed; return an ultimate default. */
1136 /* Functions called only from `x_set_frame_param'
1137 to set individual parameters.
1139 If FRAME_X_WINDOW (f) is 0,
1140 the frame is being created and its X-window does not exist yet.
1141 In that case, just record the parameter's new value
1142 in the standard place; do not attempt to change the window. */
1145 x_set_foreground_color (f
, arg
, oldval
)
1147 Lisp_Object arg
, oldval
;
1149 f
->display
.x
->foreground_pixel
1150 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1151 if (FRAME_X_WINDOW (f
) != 0)
1154 XSetForeground (FRAME_X_DISPLAY (f
), f
->display
.x
->normal_gc
,
1155 f
->display
.x
->foreground_pixel
);
1156 XSetBackground (FRAME_X_DISPLAY (f
), f
->display
.x
->reverse_gc
,
1157 f
->display
.x
->foreground_pixel
);
1159 recompute_basic_faces (f
);
1160 if (FRAME_VISIBLE_P (f
))
1166 x_set_background_color (f
, arg
, oldval
)
1168 Lisp_Object arg
, oldval
;
1173 f
->display
.x
->background_pixel
1174 = x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
1176 if (FRAME_X_WINDOW (f
) != 0)
1179 /* The main frame area. */
1180 XSetBackground (FRAME_X_DISPLAY (f
), f
->display
.x
->normal_gc
,
1181 f
->display
.x
->background_pixel
);
1182 XSetForeground (FRAME_X_DISPLAY (f
), f
->display
.x
->reverse_gc
,
1183 f
->display
.x
->background_pixel
);
1184 XSetForeground (FRAME_X_DISPLAY (f
), f
->display
.x
->cursor_gc
,
1185 f
->display
.x
->background_pixel
);
1186 XSetWindowBackground (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1187 f
->display
.x
->background_pixel
);
1190 for (bar
= FRAME_SCROLL_BARS (f
); !NILP (bar
);
1191 bar
= XSCROLL_BAR (bar
)->next
)
1192 XSetWindowBackground (FRAME_X_DISPLAY (f
),
1193 SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
)),
1194 f
->display
.x
->background_pixel
);
1198 recompute_basic_faces (f
);
1200 if (FRAME_VISIBLE_P (f
))
1206 x_set_mouse_color (f
, arg
, oldval
)
1208 Lisp_Object arg
, oldval
;
1210 Cursor cursor
, nontext_cursor
, mode_cursor
, cross_cursor
;
1213 if (!EQ (Qnil
, arg
))
1214 f
->display
.x
->mouse_pixel
1215 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1216 mask_color
= f
->display
.x
->background_pixel
;
1217 /* No invisible pointers. */
1218 if (mask_color
== f
->display
.x
->mouse_pixel
1219 && mask_color
== f
->display
.x
->background_pixel
)
1220 f
->display
.x
->mouse_pixel
= f
->display
.x
->foreground_pixel
;
1224 /* It's not okay to crash if the user selects a screwy cursor. */
1225 x_catch_errors (FRAME_X_DISPLAY (f
));
1227 if (!EQ (Qnil
, Vx_pointer_shape
))
1229 CHECK_NUMBER (Vx_pointer_shape
, 0);
1230 cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XINT (Vx_pointer_shape
));
1233 cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_xterm
);
1234 x_check_errors (FRAME_X_DISPLAY (f
), "bad text pointer cursor: %s");
1236 if (!EQ (Qnil
, Vx_nontext_pointer_shape
))
1238 CHECK_NUMBER (Vx_nontext_pointer_shape
, 0);
1239 nontext_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
),
1240 XINT (Vx_nontext_pointer_shape
));
1243 nontext_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_left_ptr
);
1244 x_check_errors (FRAME_X_DISPLAY (f
), "bad nontext pointer cursor: %s");
1246 if (!EQ (Qnil
, Vx_mode_pointer_shape
))
1248 CHECK_NUMBER (Vx_mode_pointer_shape
, 0);
1249 mode_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
),
1250 XINT (Vx_mode_pointer_shape
));
1253 mode_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_xterm
);
1254 x_check_errors (FRAME_X_DISPLAY (f
), "bad modeline pointer cursor: %s");
1256 if (!EQ (Qnil
, Vx_sensitive_text_pointer_shape
))
1258 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
, 0);
1260 = XCreateFontCursor (FRAME_X_DISPLAY (f
),
1261 XINT (Vx_sensitive_text_pointer_shape
));
1264 cross_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_crosshair
);
1266 /* Check and report errors with the above calls. */
1267 x_check_errors (FRAME_X_DISPLAY (f
), "can't set cursor shape: %s");
1268 x_uncatch_errors (FRAME_X_DISPLAY (f
));
1271 XColor fore_color
, back_color
;
1273 fore_color
.pixel
= f
->display
.x
->mouse_pixel
;
1274 back_color
.pixel
= mask_color
;
1275 XQueryColor (FRAME_X_DISPLAY (f
),
1276 DefaultColormap (FRAME_X_DISPLAY (f
),
1277 DefaultScreen (FRAME_X_DISPLAY (f
))),
1279 XQueryColor (FRAME_X_DISPLAY (f
),
1280 DefaultColormap (FRAME_X_DISPLAY (f
),
1281 DefaultScreen (FRAME_X_DISPLAY (f
))),
1283 XRecolorCursor (FRAME_X_DISPLAY (f
), cursor
,
1284 &fore_color
, &back_color
);
1285 XRecolorCursor (FRAME_X_DISPLAY (f
), nontext_cursor
,
1286 &fore_color
, &back_color
);
1287 XRecolorCursor (FRAME_X_DISPLAY (f
), mode_cursor
,
1288 &fore_color
, &back_color
);
1289 XRecolorCursor (FRAME_X_DISPLAY (f
), cross_cursor
,
1290 &fore_color
, &back_color
);
1293 if (FRAME_X_WINDOW (f
) != 0)
1295 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
1298 if (cursor
!= f
->display
.x
->text_cursor
&& f
->display
.x
->text_cursor
!= 0)
1299 XFreeCursor (FRAME_X_DISPLAY (f
), f
->display
.x
->text_cursor
);
1300 f
->display
.x
->text_cursor
= cursor
;
1302 if (nontext_cursor
!= f
->display
.x
->nontext_cursor
1303 && f
->display
.x
->nontext_cursor
!= 0)
1304 XFreeCursor (FRAME_X_DISPLAY (f
), f
->display
.x
->nontext_cursor
);
1305 f
->display
.x
->nontext_cursor
= nontext_cursor
;
1307 if (mode_cursor
!= f
->display
.x
->modeline_cursor
1308 && f
->display
.x
->modeline_cursor
!= 0)
1309 XFreeCursor (FRAME_X_DISPLAY (f
), f
->display
.x
->modeline_cursor
);
1310 f
->display
.x
->modeline_cursor
= mode_cursor
;
1311 if (cross_cursor
!= f
->display
.x
->cross_cursor
1312 && f
->display
.x
->cross_cursor
!= 0)
1313 XFreeCursor (FRAME_X_DISPLAY (f
), f
->display
.x
->cross_cursor
);
1314 f
->display
.x
->cross_cursor
= cross_cursor
;
1316 XFlush (FRAME_X_DISPLAY (f
));
1321 x_set_cursor_color (f
, arg
, oldval
)
1323 Lisp_Object arg
, oldval
;
1325 unsigned long fore_pixel
;
1327 if (!EQ (Vx_cursor_fore_pixel
, Qnil
))
1328 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
1329 WHITE_PIX_DEFAULT (f
));
1331 fore_pixel
= f
->display
.x
->background_pixel
;
1332 f
->display
.x
->cursor_pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1334 /* Make sure that the cursor color differs from the background color. */
1335 if (f
->display
.x
->cursor_pixel
== f
->display
.x
->background_pixel
)
1337 f
->display
.x
->cursor_pixel
= f
->display
.x
->mouse_pixel
;
1338 if (f
->display
.x
->cursor_pixel
== fore_pixel
)
1339 fore_pixel
= f
->display
.x
->background_pixel
;
1341 f
->display
.x
->cursor_foreground_pixel
= fore_pixel
;
1343 if (FRAME_X_WINDOW (f
) != 0)
1346 XSetBackground (FRAME_X_DISPLAY (f
), f
->display
.x
->cursor_gc
,
1347 f
->display
.x
->cursor_pixel
);
1348 XSetForeground (FRAME_X_DISPLAY (f
), f
->display
.x
->cursor_gc
,
1352 if (FRAME_VISIBLE_P (f
))
1354 x_display_cursor (f
, 0);
1355 x_display_cursor (f
, 1);
1360 /* Set the border-color of frame F to value described by ARG.
1361 ARG can be a string naming a color.
1362 The border-color is used for the border that is drawn by the X server.
1363 Note that this does not fully take effect if done before
1364 F has an x-window; it must be redone when the window is created.
1366 Note: this is done in two routines because of the way X10 works.
1368 Note: under X11, this is normally the province of the window manager,
1369 and so emacs' border colors may be overridden. */
1372 x_set_border_color (f
, arg
, oldval
)
1374 Lisp_Object arg
, oldval
;
1379 CHECK_STRING (arg
, 0);
1380 str
= XSTRING (arg
)->data
;
1382 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1384 x_set_border_pixel (f
, pix
);
1387 /* Set the border-color of frame F to pixel value PIX.
1388 Note that this does not fully take effect if done before
1389 F has an x-window. */
1391 x_set_border_pixel (f
, pix
)
1395 f
->display
.x
->border_pixel
= pix
;
1397 if (FRAME_X_WINDOW (f
) != 0 && f
->display
.x
->border_width
> 0)
1403 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1404 (unsigned long)pix
);
1407 if (FRAME_VISIBLE_P (f
))
1413 x_set_cursor_type (f
, arg
, oldval
)
1415 Lisp_Object arg
, oldval
;
1419 FRAME_DESIRED_CURSOR (f
) = bar_cursor
;
1420 f
->display
.x
->cursor_width
= 2;
1422 else if (CONSP (arg
) && EQ (XCONS (arg
)->car
, Qbar
)
1423 && INTEGERP (XCONS (arg
)->cdr
))
1425 FRAME_DESIRED_CURSOR (f
) = bar_cursor
;
1426 f
->display
.x
->cursor_width
= XINT (XCONS (arg
)->cdr
);
1429 /* Treat anything unknown as "box cursor".
1430 It was bad to signal an error; people have trouble fixing
1431 .Xdefaults with Emacs, when it has something bad in it. */
1432 FRAME_DESIRED_CURSOR (f
) = filled_box_cursor
;
1434 /* Make sure the cursor gets redrawn. This is overkill, but how
1435 often do people change cursor types? */
1436 update_mode_lines
++;
1440 x_set_icon_type (f
, arg
, oldval
)
1442 Lisp_Object arg
, oldval
;
1449 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1452 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1457 result
= x_text_icon (f
, 0);
1459 result
= x_bitmap_icon (f
, arg
);
1464 error ("No icon window available");
1467 /* If the window was unmapped (and its icon was mapped),
1468 the new icon is not mapped, so map the window in its stead. */
1469 if (FRAME_VISIBLE_P (f
))
1471 #ifdef USE_X_TOOLKIT
1472 XtPopup (f
->display
.x
->widget
, XtGrabNone
);
1474 XMapWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
1477 XFlush (FRAME_X_DISPLAY (f
));
1481 /* Return non-nil if frame F wants a bitmap icon. */
1489 tem
= assq_no_quit (Qicon_type
, f
->param_alist
);
1491 return XCONS (tem
)->cdr
;
1496 extern Lisp_Object
x_new_font ();
1499 x_set_font (f
, arg
, oldval
)
1501 Lisp_Object arg
, oldval
;
1505 CHECK_STRING (arg
, 1);
1508 result
= x_new_font (f
, XSTRING (arg
)->data
);
1511 if (EQ (result
, Qnil
))
1512 error ("Font \"%s\" is not defined", XSTRING (arg
)->data
);
1513 else if (EQ (result
, Qt
))
1514 error ("the characters of the given font have varying widths");
1515 else if (STRINGP (result
))
1517 recompute_basic_faces (f
);
1518 store_frame_param (f
, Qfont
, result
);
1525 x_set_border_width (f
, arg
, oldval
)
1527 Lisp_Object arg
, oldval
;
1529 CHECK_NUMBER (arg
, 0);
1531 if (XINT (arg
) == f
->display
.x
->border_width
)
1534 if (FRAME_X_WINDOW (f
) != 0)
1535 error ("Cannot change the border width of a window");
1537 f
->display
.x
->border_width
= XINT (arg
);
1541 x_set_internal_border_width (f
, arg
, oldval
)
1543 Lisp_Object arg
, oldval
;
1546 int old
= f
->display
.x
->internal_border_width
;
1548 CHECK_NUMBER (arg
, 0);
1549 f
->display
.x
->internal_border_width
= XINT (arg
);
1550 if (f
->display
.x
->internal_border_width
< 0)
1551 f
->display
.x
->internal_border_width
= 0;
1553 if (f
->display
.x
->internal_border_width
== old
)
1556 if (FRAME_X_WINDOW (f
) != 0)
1559 x_set_window_size (f
, 0, f
->width
, f
->height
);
1561 x_set_resize_hint (f
);
1563 XFlush (FRAME_X_DISPLAY (f
));
1565 SET_FRAME_GARBAGED (f
);
1570 x_set_visibility (f
, value
, oldval
)
1572 Lisp_Object value
, oldval
;
1575 XSETFRAME (frame
, f
);
1578 Fmake_frame_invisible (frame
, Qt
);
1579 else if (EQ (value
, Qicon
))
1580 Ficonify_frame (frame
);
1582 Fmake_frame_visible (frame
);
1586 x_set_menu_bar_lines_1 (window
, n
)
1590 struct window
*w
= XWINDOW (window
);
1592 XSETFASTINT (w
->top
, XFASTINT (w
->top
) + n
);
1593 XSETFASTINT (w
->height
, XFASTINT (w
->height
) - n
);
1595 /* Handle just the top child in a vertical split. */
1596 if (!NILP (w
->vchild
))
1597 x_set_menu_bar_lines_1 (w
->vchild
, n
);
1599 /* Adjust all children in a horizontal split. */
1600 for (window
= w
->hchild
; !NILP (window
); window
= w
->next
)
1602 w
= XWINDOW (window
);
1603 x_set_menu_bar_lines_1 (window
, n
);
1608 x_set_menu_bar_lines (f
, value
, oldval
)
1610 Lisp_Object value
, oldval
;
1613 int olines
= FRAME_MENU_BAR_LINES (f
);
1615 /* Right now, menu bars don't work properly in minibuf-only frames;
1616 most of the commands try to apply themselves to the minibuffer
1617 frame itslef, and get an error because you can't switch buffers
1618 in or split the minibuffer window. */
1619 if (FRAME_MINIBUF_ONLY_P (f
))
1622 if (INTEGERP (value
))
1623 nlines
= XINT (value
);
1627 #ifdef USE_X_TOOLKIT
1628 FRAME_MENU_BAR_LINES (f
) = 0;
1630 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
1633 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
1634 free_frame_menubar (f
);
1635 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
1636 f
->display
.x
->menubar_widget
= 0;
1638 #else /* not USE_X_TOOLKIT */
1639 FRAME_MENU_BAR_LINES (f
) = nlines
;
1640 x_set_menu_bar_lines_1 (f
->root_window
, nlines
- olines
);
1641 #endif /* not USE_X_TOOLKIT */
1644 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1647 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1648 name; if NAME is a string, set F's name to NAME and set
1649 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1651 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1652 suggesting a new name, which lisp code should override; if
1653 F->explicit_name is set, ignore the new name; otherwise, set it. */
1656 x_set_name (f
, name
, explicit)
1661 /* Make sure that requests from lisp code override requests from
1662 Emacs redisplay code. */
1665 /* If we're switching from explicit to implicit, we had better
1666 update the mode lines and thereby update the title. */
1667 if (f
->explicit_name
&& NILP (name
))
1668 update_mode_lines
= 1;
1670 f
->explicit_name
= ! NILP (name
);
1672 else if (f
->explicit_name
)
1675 /* If NAME is nil, set the name to the x_id_name. */
1678 /* Check for no change needed in this very common case
1679 before we do any consing. */
1680 if (!strcmp (FRAME_X_DISPLAY_INFO (f
)->x_id_name
,
1681 XSTRING (f
->name
)->data
))
1683 name
= build_string (FRAME_X_DISPLAY_INFO (f
)->x_id_name
);
1686 CHECK_STRING (name
, 0);
1688 /* Don't change the name if it's already NAME. */
1689 if (! NILP (Fstring_equal (name
, f
->name
)))
1692 if (FRAME_X_WINDOW (f
))
1698 text
.value
= XSTRING (name
)->data
;
1699 text
.encoding
= XA_STRING
;
1701 text
.nitems
= XSTRING (name
)->size
;
1702 #ifdef USE_X_TOOLKIT
1703 XSetWMName (FRAME_X_DISPLAY (f
),
1704 XtWindow (f
->display
.x
->widget
), &text
);
1705 XSetWMIconName (FRAME_X_DISPLAY (f
), XtWindow (f
->display
.x
->widget
),
1707 #else /* not USE_X_TOOLKIT */
1708 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &text
);
1709 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &text
);
1710 #endif /* not USE_X_TOOLKIT */
1712 #else /* not HAVE_X11R4 */
1713 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1714 XSTRING (name
)->data
);
1715 XStoreName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1716 XSTRING (name
)->data
);
1717 #endif /* not HAVE_X11R4 */
1724 /* This function should be called when the user's lisp code has
1725 specified a name for the frame; the name will override any set by the
1728 x_explicitly_set_name (f
, arg
, oldval
)
1730 Lisp_Object arg
, oldval
;
1732 x_set_name (f
, arg
, 1);
1735 /* This function should be called by Emacs redisplay code to set the
1736 name; names set this way will never override names set by the user's
1739 x_implicitly_set_name (f
, arg
, oldval
)
1741 Lisp_Object arg
, oldval
;
1743 x_set_name (f
, arg
, 0);
1747 x_set_autoraise (f
, arg
, oldval
)
1749 Lisp_Object arg
, oldval
;
1751 f
->auto_raise
= !EQ (Qnil
, arg
);
1755 x_set_autolower (f
, arg
, oldval
)
1757 Lisp_Object arg
, oldval
;
1759 f
->auto_lower
= !EQ (Qnil
, arg
);
1763 x_set_unsplittable (f
, arg
, oldval
)
1765 Lisp_Object arg
, oldval
;
1767 f
->no_split
= !NILP (arg
);
1771 x_set_vertical_scroll_bars (f
, arg
, oldval
)
1773 Lisp_Object arg
, oldval
;
1775 if (NILP (arg
) != ! FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
1777 FRAME_HAS_VERTICAL_SCROLL_BARS (f
) = ! NILP (arg
);
1779 /* We set this parameter before creating the X window for the
1780 frame, so we can get the geometry right from the start.
1781 However, if the window hasn't been created yet, we shouldn't
1782 call x_set_window_size. */
1783 if (FRAME_X_WINDOW (f
))
1784 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
1789 x_set_scroll_bar_width (f
, arg
, oldval
)
1791 Lisp_Object arg
, oldval
;
1795 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = 0;
1796 FRAME_SCROLL_BAR_COLS (f
) = 2;
1798 else if (INTEGERP (arg
) && XINT (arg
) > 0
1799 && XFASTINT (arg
) != FRAME_SCROLL_BAR_PIXEL_WIDTH (f
))
1801 int wid
= FONT_WIDTH (f
->display
.x
->font
);
1802 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = XFASTINT (arg
);
1803 FRAME_SCROLL_BAR_COLS (f
) = (XFASTINT (arg
) + wid
-1) / wid
;
1804 if (FRAME_X_WINDOW (f
))
1805 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
1809 /* Subroutines of creating an X frame. */
1811 /* Make sure that Vx_resource_name is set to a reasonable value.
1812 Fix it up, or set it to `emacs' if it is too hopeless. */
1815 validate_x_resource_name ()
1818 /* Number of valid characters in the resource name. */
1820 /* Number of invalid characters in the resource name. */
1825 if (STRINGP (Vx_resource_name
))
1827 unsigned char *p
= XSTRING (Vx_resource_name
)->data
;
1830 len
= XSTRING (Vx_resource_name
)->size
;
1832 /* Only letters, digits, - and _ are valid in resource names.
1833 Count the valid characters and count the invalid ones. */
1834 for (i
= 0; i
< len
; i
++)
1837 if (! ((c
>= 'a' && c
<= 'z')
1838 || (c
>= 'A' && c
<= 'Z')
1839 || (c
>= '0' && c
<= '9')
1840 || c
== '-' || c
== '_'))
1847 /* Not a string => completely invalid. */
1848 bad_count
= 5, good_count
= 0;
1850 /* If name is valid already, return. */
1854 /* If name is entirely invalid, or nearly so, use `emacs'. */
1856 || (good_count
== 1 && bad_count
> 0))
1858 Vx_resource_name
= build_string ("emacs");
1862 /* Name is partly valid. Copy it and replace the invalid characters
1863 with underscores. */
1865 Vx_resource_name
= new = Fcopy_sequence (Vx_resource_name
);
1867 for (i
= 0; i
< len
; i
++)
1869 int c
= XSTRING (new)->data
[i
];
1870 if (! ((c
>= 'a' && c
<= 'z')
1871 || (c
>= 'A' && c
<= 'Z')
1872 || (c
>= '0' && c
<= '9')
1873 || c
== '-' || c
== '_'))
1874 XSTRING (new)->data
[i
] = '_';
1879 extern char *x_get_string_resource ();
1881 DEFUN ("x-get-resource", Fx_get_resource
, Sx_get_resource
, 2, 4, 0,
1882 "Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.\n\
1883 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the\n\
1884 class, where INSTANCE is the name under which Emacs was invoked, or\n\
1885 the name specified by the `-name' or `-rn' command-line arguments.\n\
1887 The optional arguments COMPONENT and SUBCLASS add to the key and the\n\
1888 class, respectively. You must specify both of them or neither.\n\
1889 If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'\n\
1890 and the class is `Emacs.CLASS.SUBCLASS'.")
1891 (attribute
, class, component
, subclass
)
1892 Lisp_Object attribute
, class, component
, subclass
;
1894 register char *value
;
1900 CHECK_STRING (attribute
, 0);
1901 CHECK_STRING (class, 0);
1903 if (!NILP (component
))
1904 CHECK_STRING (component
, 1);
1905 if (!NILP (subclass
))
1906 CHECK_STRING (subclass
, 2);
1907 if (NILP (component
) != NILP (subclass
))
1908 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
1910 validate_x_resource_name ();
1912 /* Allocate space for the components, the dots which separate them,
1913 and the final '\0'. Make them big enough for the worst case. */
1914 name_key
= (char *) alloca (XSTRING (Vx_resource_name
)->size
1915 + (STRINGP (component
)
1916 ? XSTRING (component
)->size
: 0)
1917 + XSTRING (attribute
)->size
1920 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
1921 + XSTRING (class)->size
1922 + (STRINGP (subclass
)
1923 ? XSTRING (subclass
)->size
: 0)
1926 /* Start with emacs.FRAMENAME for the name (the specific one)
1927 and with `Emacs' for the class key (the general one). */
1928 strcpy (name_key
, XSTRING (Vx_resource_name
)->data
);
1929 strcpy (class_key
, EMACS_CLASS
);
1931 strcat (class_key
, ".");
1932 strcat (class_key
, XSTRING (class)->data
);
1934 if (!NILP (component
))
1936 strcat (class_key
, ".");
1937 strcat (class_key
, XSTRING (subclass
)->data
);
1939 strcat (name_key
, ".");
1940 strcat (name_key
, XSTRING (component
)->data
);
1943 strcat (name_key
, ".");
1944 strcat (name_key
, XSTRING (attribute
)->data
);
1946 value
= x_get_string_resource (check_x_display_info (Qnil
)->xrdb
,
1947 name_key
, class_key
);
1949 if (value
!= (char *) 0)
1950 return build_string (value
);
1955 /* Used when C code wants a resource value. */
1958 x_get_resource_string (attribute
, class)
1959 char *attribute
, *class;
1961 register char *value
;
1965 /* Allocate space for the components, the dots which separate them,
1966 and the final '\0'. */
1967 name_key
= (char *) alloca (XSTRING (Vinvocation_name
)->size
1968 + strlen (attribute
) + 2);
1969 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
1970 + strlen (class) + 2);
1972 sprintf (name_key
, "%s.%s",
1973 XSTRING (Vinvocation_name
)->data
,
1975 sprintf (class_key
, "%s.%s", EMACS_CLASS
, class);
1977 return x_get_string_resource (FRAME_X_DISPLAY_INFO (selected_frame
)->xrdb
,
1978 name_key
, class_key
);
1981 /* Types we might convert a resource string into. */
1984 number
, boolean
, string
, symbol
1987 /* Return the value of parameter PARAM.
1989 First search ALIST, then Vdefault_frame_alist, then the X defaults
1990 database, using ATTRIBUTE as the attribute name and CLASS as its class.
1992 Convert the resource to the type specified by desired_type.
1994 If no default is specified, return Qunbound. If you call
1995 x_get_arg, make sure you deal with Qunbound in a reasonable way,
1996 and don't let it get stored in any Lisp-visible variables! */
1999 x_get_arg (alist
, param
, attribute
, class, type
)
2000 Lisp_Object alist
, param
;
2003 enum resource_types type
;
2005 register Lisp_Object tem
;
2007 tem
= Fassq (param
, alist
);
2009 tem
= Fassq (param
, Vdefault_frame_alist
);
2015 tem
= Fx_get_resource (build_string (attribute
),
2016 build_string (class),
2025 return make_number (atoi (XSTRING (tem
)->data
));
2028 tem
= Fdowncase (tem
);
2029 if (!strcmp (XSTRING (tem
)->data
, "on")
2030 || !strcmp (XSTRING (tem
)->data
, "true"))
2039 /* As a special case, we map the values `true' and `on'
2040 to Qt, and `false' and `off' to Qnil. */
2043 lower
= Fdowncase (tem
);
2044 if (!strcmp (XSTRING (lower
)->data
, "on")
2045 || !strcmp (XSTRING (lower
)->data
, "true"))
2047 else if (!strcmp (XSTRING (lower
)->data
, "off")
2048 || !strcmp (XSTRING (lower
)->data
, "false"))
2051 return Fintern (tem
, Qnil
);
2064 /* Record in frame F the specified or default value according to ALIST
2065 of the parameter named PARAM (a Lisp symbol).
2066 If no value is specified for PARAM, look for an X default for XPROP
2067 on the frame named NAME.
2068 If that is not found either, use the value DEFLT. */
2071 x_default_parameter (f
, alist
, prop
, deflt
, xprop
, xclass
, type
)
2078 enum resource_types type
;
2082 tem
= x_get_arg (alist
, prop
, xprop
, xclass
, type
);
2083 if (EQ (tem
, Qunbound
))
2085 x_set_frame_parameters (f
, Fcons (Fcons (prop
, tem
), Qnil
));
2089 DEFUN ("x-parse-geometry", Fx_parse_geometry
, Sx_parse_geometry
, 1, 1, 0,
2090 "Parse an X-style geometry string STRING.\n\
2091 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).\n\
2092 The properties returned may include `top', `left', `height', and `width'.\n\
2093 The value of `left' or `top' may be an integer,\n\
2094 or a list (+ N) meaning N pixels relative to top/left corner,\n\
2095 or a list (- N) meaning -N pixels relative to bottom/right corner.")
2100 unsigned int width
, height
;
2103 CHECK_STRING (string
, 0);
2105 geometry
= XParseGeometry ((char *) XSTRING (string
)->data
,
2106 &x
, &y
, &width
, &height
);
2109 if (!!(geometry
& XValue
) != !!(geometry
& YValue
))
2110 error ("Must specify both x and y position, or neither");
2114 if (geometry
& XValue
)
2116 Lisp_Object element
;
2118 if (x
>= 0 && (geometry
& XNegative
))
2119 element
= Fcons (Qleft
, Fcons (Qminus
, Fcons (make_number (-x
), Qnil
)));
2120 else if (x
< 0 && ! (geometry
& XNegative
))
2121 element
= Fcons (Qleft
, Fcons (Qplus
, Fcons (make_number (x
), Qnil
)));
2123 element
= Fcons (Qleft
, make_number (x
));
2124 result
= Fcons (element
, result
);
2127 if (geometry
& YValue
)
2129 Lisp_Object element
;
2131 if (y
>= 0 && (geometry
& YNegative
))
2132 element
= Fcons (Qtop
, Fcons (Qminus
, Fcons (make_number (-y
), Qnil
)));
2133 else if (y
< 0 && ! (geometry
& YNegative
))
2134 element
= Fcons (Qtop
, Fcons (Qplus
, Fcons (make_number (y
), Qnil
)));
2136 element
= Fcons (Qtop
, make_number (y
));
2137 result
= Fcons (element
, result
);
2140 if (geometry
& WidthValue
)
2141 result
= Fcons (Fcons (Qwidth
, make_number (width
)), result
);
2142 if (geometry
& HeightValue
)
2143 result
= Fcons (Fcons (Qheight
, make_number (height
)), result
);
2148 /* Calculate the desired size and position of this window,
2149 and return the flags saying which aspects were specified.
2151 This function does not make the coordinates positive. */
2153 #define DEFAULT_ROWS 40
2154 #define DEFAULT_COLS 80
2157 x_figure_window_size (f
, parms
)
2161 register Lisp_Object tem0
, tem1
, tem2
;
2162 int height
, width
, left
, top
;
2163 register int geometry
;
2164 long window_prompting
= 0;
2166 /* Default values if we fall through.
2167 Actually, if that happens we should get
2168 window manager prompting. */
2169 f
->width
= DEFAULT_COLS
;
2170 f
->height
= DEFAULT_ROWS
;
2171 /* Window managers expect that if program-specified
2172 positions are not (0,0), they're intentional, not defaults. */
2173 f
->display
.x
->top_pos
= 0;
2174 f
->display
.x
->left_pos
= 0;
2176 tem0
= x_get_arg (parms
, Qheight
, 0, 0, number
);
2177 tem1
= x_get_arg (parms
, Qwidth
, 0, 0, number
);
2178 tem2
= x_get_arg (parms
, Quser_size
, 0, 0, number
);
2179 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
2181 if (!EQ (tem0
, Qunbound
))
2183 CHECK_NUMBER (tem0
, 0);
2184 f
->height
= XINT (tem0
);
2186 if (!EQ (tem1
, Qunbound
))
2188 CHECK_NUMBER (tem1
, 0);
2189 f
->width
= XINT (tem1
);
2191 if (!NILP (tem2
) && !EQ (tem2
, Qunbound
))
2192 window_prompting
|= USSize
;
2194 window_prompting
|= PSize
;
2197 f
->display
.x
->vertical_scroll_bar_extra
2198 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
2200 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0
2201 ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f
)
2202 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->display
.x
->font
)));
2203 f
->display
.x
->pixel_width
= CHAR_TO_PIXEL_WIDTH (f
, f
->width
);
2204 f
->display
.x
->pixel_height
= CHAR_TO_PIXEL_HEIGHT (f
, f
->height
);
2206 tem0
= x_get_arg (parms
, Qtop
, 0, 0, number
);
2207 tem1
= x_get_arg (parms
, Qleft
, 0, 0, number
);
2208 tem2
= x_get_arg (parms
, Quser_position
, 0, 0, number
);
2209 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
2211 if (EQ (tem0
, Qminus
))
2213 f
->display
.x
->top_pos
= 0;
2214 window_prompting
|= YNegative
;
2216 else if (CONSP (tem0
) && EQ (XCONS (tem0
)->car
, Qminus
)
2217 && CONSP (XCONS (tem0
)->cdr
)
2218 && INTEGERP (XCONS (XCONS (tem0
)->cdr
)->car
))
2220 f
->display
.x
->top_pos
= - XINT (XCONS (XCONS (tem0
)->cdr
)->car
);
2221 window_prompting
|= YNegative
;
2223 else if (CONSP (tem0
) && EQ (XCONS (tem0
)->car
, Qplus
)
2224 && CONSP (XCONS (tem0
)->cdr
)
2225 && INTEGERP (XCONS (XCONS (tem0
)->cdr
)->car
))
2227 f
->display
.x
->top_pos
= XINT (XCONS (XCONS (tem0
)->cdr
)->car
);
2229 else if (EQ (tem0
, Qunbound
))
2230 f
->display
.x
->top_pos
= 0;
2233 CHECK_NUMBER (tem0
, 0);
2234 f
->display
.x
->top_pos
= XINT (tem0
);
2235 if (f
->display
.x
->top_pos
< 0)
2236 window_prompting
|= YNegative
;
2239 if (EQ (tem1
, Qminus
))
2241 f
->display
.x
->left_pos
= 0;
2242 window_prompting
|= XNegative
;
2244 else if (CONSP (tem1
) && EQ (XCONS (tem1
)->car
, Qminus
)
2245 && CONSP (XCONS (tem1
)->cdr
)
2246 && INTEGERP (XCONS (XCONS (tem1
)->cdr
)->car
))
2248 f
->display
.x
->left_pos
= - XINT (XCONS (XCONS (tem1
)->cdr
)->car
);
2249 window_prompting
|= XNegative
;
2251 else if (CONSP (tem1
) && EQ (XCONS (tem1
)->car
, Qplus
)
2252 && CONSP (XCONS (tem1
)->cdr
)
2253 && INTEGERP (XCONS (XCONS (tem1
)->cdr
)->car
))
2255 f
->display
.x
->left_pos
= XINT (XCONS (XCONS (tem1
)->cdr
)->car
);
2257 else if (EQ (tem1
, Qunbound
))
2258 f
->display
.x
->left_pos
= 0;
2261 CHECK_NUMBER (tem1
, 0);
2262 f
->display
.x
->left_pos
= XINT (tem1
);
2263 if (f
->display
.x
->left_pos
< 0)
2264 window_prompting
|= XNegative
;
2267 if (!NILP (tem2
) && ! EQ (tem2
, Qunbound
))
2268 window_prompting
|= USPosition
;
2270 window_prompting
|= PPosition
;
2273 return window_prompting
;
2276 #if !defined (HAVE_X11R4) && !defined (HAVE_XSETWMPROTOCOLS)
2279 XSetWMProtocols (dpy
, w
, protocols
, count
)
2286 prop
= XInternAtom (dpy
, "WM_PROTOCOLS", False
);
2287 if (prop
== None
) return False
;
2288 XChangeProperty (dpy
, w
, prop
, XA_ATOM
, 32, PropModeReplace
,
2289 (unsigned char *) protocols
, count
);
2292 #endif /* not HAVE_X11R4 && not HAVE_XSETWMPROTOCOLS */
2294 #ifdef USE_X_TOOLKIT
2296 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
2297 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
2298 already be present because of the toolkit (Motif adds some of them,
2299 for example, but Xt doesn't). */
2302 hack_wm_protocols (f
, widget
)
2306 Display
*dpy
= XtDisplay (widget
);
2307 Window w
= XtWindow (widget
);
2308 int need_delete
= 1;
2314 Atom type
, *atoms
= 0;
2316 unsigned long nitems
= 0;
2317 unsigned long bytes_after
;
2319 if ((XGetWindowProperty (dpy
, w
,
2320 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2321 (long)0, (long)100, False
, XA_ATOM
,
2322 &type
, &format
, &nitems
, &bytes_after
,
2323 (unsigned char **) &atoms
)
2325 && format
== 32 && type
== XA_ATOM
)
2329 if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
)
2331 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
)
2333 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
)
2336 if (atoms
) XFree ((char *) atoms
);
2342 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2344 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
;
2346 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2348 XChangeProperty (dpy
, w
, FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2349 XA_ATOM
, 32, PropModeAppend
,
2350 (unsigned char *) props
, count
);
2356 #ifdef USE_X_TOOLKIT
2358 /* Create and set up the X widget for frame F. */
2361 x_window (f
, window_prompting
, minibuffer_only
)
2363 long window_prompting
;
2364 int minibuffer_only
;
2366 XClassHint class_hints
;
2367 XSetWindowAttributes attributes
;
2368 unsigned long attribute_mask
;
2370 Widget shell_widget
;
2372 Widget frame_widget
;
2378 /* Use the resource name as the top-level widget name
2379 for looking up resources. Make a non-Lisp copy
2380 for the window manager, so GC relocation won't bother it.
2382 Elsewhere we specify the window name for the window manager. */
2385 char *str
= (char *) XSTRING (Vx_resource_name
)->data
;
2386 f
->namebuf
= (char *) xmalloc (strlen (str
) + 1);
2387 strcpy (f
->namebuf
, str
);
2391 XtSetArg (al
[ac
], XtNallowShellResize
, 1); ac
++;
2392 XtSetArg (al
[ac
], XtNinput
, 1); ac
++;
2393 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2394 XtSetArg (al
[ac
], XtNborderWidth
, f
->display
.x
->border_width
); ac
++;
2395 shell_widget
= XtAppCreateShell (f
->namebuf
, EMACS_CLASS
,
2396 applicationShellWidgetClass
,
2397 FRAME_X_DISPLAY (f
), al
, ac
);
2399 f
->display
.x
->widget
= shell_widget
;
2400 /* maybe_set_screen_title_format (shell_widget); */
2402 pane_widget
= lw_create_widget ("main", "pane", widget_id_tick
++,
2403 (widget_value
*) NULL
,
2404 shell_widget
, False
,
2407 (lw_callback
) NULL
);
2409 f
->display
.x
->column_widget
= pane_widget
;
2411 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2412 the emacs screen when changing menubar. This reduces flickering. */
2415 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2416 XtSetArg (al
[ac
], XtNshowGrip
, 0); ac
++;
2417 XtSetArg (al
[ac
], XtNallowResize
, 1); ac
++;
2418 XtSetArg (al
[ac
], XtNresizeToPreferred
, 1); ac
++;
2419 XtSetArg (al
[ac
], XtNemacsFrame
, f
); ac
++;
2420 frame_widget
= XtCreateWidget (f
->namebuf
,
2422 pane_widget
, al
, ac
);
2424 f
->display
.x
->edit_widget
= frame_widget
;
2426 XtManageChild (frame_widget
);
2428 /* Do some needed geometry management. */
2431 char *tem
, shell_position
[32];
2435 = (f
->display
.x
->menubar_widget
2436 ? (f
->display
.x
->menubar_widget
->core
.height
2437 + f
->display
.x
->menubar_widget
->core
.border_width
)
2440 if (FRAME_EXTERNAL_MENU_BAR (f
))
2443 XtVaGetValues (pane_widget
, XtNinternalBorderWidth
, &ibw
, NULL
);
2444 menubar_size
+= ibw
;
2447 f
->display
.x
->menubar_height
= menubar_size
;
2449 /* Convert our geometry parameters into a geometry string
2451 Note that we do not specify here whether the position
2452 is a user-specified or program-specified one.
2453 We pass that information later, in x_wm_set_size_hints. */
2455 int left
= f
->display
.x
->left_pos
;
2456 int xneg
= window_prompting
& XNegative
;
2457 int top
= f
->display
.x
->top_pos
;
2458 int yneg
= window_prompting
& YNegative
;
2464 if (window_prompting
& USPosition
)
2465 sprintf (shell_position
, "=%dx%d%c%d%c%d", PIXEL_WIDTH (f
),
2466 PIXEL_HEIGHT (f
) + menubar_size
,
2467 (xneg
? '-' : '+'), left
,
2468 (yneg
? '-' : '+'), top
);
2470 sprintf (shell_position
, "=%dx%d", PIXEL_WIDTH (f
),
2471 PIXEL_HEIGHT (f
) + menubar_size
);
2474 len
= strlen (shell_position
) + 1;
2475 tem
= (char *) xmalloc (len
);
2476 strncpy (tem
, shell_position
, len
);
2477 XtSetArg (al
[ac
], XtNgeometry
, tem
); ac
++;
2478 XtSetValues (shell_widget
, al
, ac
);
2481 XtManageChild (pane_widget
);
2482 XtRealizeWidget (shell_widget
);
2484 FRAME_X_WINDOW (f
) = XtWindow (frame_widget
);
2486 validate_x_resource_name ();
2488 class_hints
.res_name
= (char *) XSTRING (Vx_resource_name
)->data
;
2489 class_hints
.res_class
= EMACS_CLASS
;
2490 XSetClassHint (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
), &class_hints
);
2492 f
->display
.x
->wm_hints
.input
= True
;
2493 f
->display
.x
->wm_hints
.flags
|= InputHint
;
2494 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2495 &f
->display
.x
->wm_hints
);
2497 hack_wm_protocols (f
, shell_widget
);
2500 XtAddEventHandler (shell_widget
, 0, True
, _XEditResCheckMessages
, 0);
2503 /* Do a stupid property change to force the server to generate a
2504 propertyNotify event so that the event_stream server timestamp will
2505 be initialized to something relevant to the time we created the window.
2507 XChangeProperty (XtDisplay (frame_widget
), XtWindow (frame_widget
),
2508 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2509 XA_ATOM
, 32, PropModeAppend
,
2510 (unsigned char*) NULL
, 0);
2512 /* Make all the standard events reach the Emacs frame. */
2513 attributes
.event_mask
= STANDARD_EVENT_SET
;
2514 attribute_mask
= CWEventMask
;
2515 XChangeWindowAttributes (XtDisplay (shell_widget
), XtWindow (shell_widget
),
2516 attribute_mask
, &attributes
);
2518 XtMapWidget (frame_widget
);
2520 /* x_set_name normally ignores requests to set the name if the
2521 requested name is the same as the current name. This is the one
2522 place where that assumption isn't correct; f->name is set, but
2523 the X server hasn't been told. */
2526 int explicit = f
->explicit_name
;
2528 f
->explicit_name
= 0;
2531 x_set_name (f
, name
, explicit);
2534 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2535 f
->display
.x
->text_cursor
);
2539 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
2540 initialize_frame_menubar (f
);
2541 lw_set_main_areas (pane_widget
, f
->display
.x
->menubar_widget
, frame_widget
);
2543 if (FRAME_X_WINDOW (f
) == 0)
2544 error ("Unable to create window");
2547 #else /* not USE_X_TOOLKIT */
2549 /* Create and set up the X window for frame F. */
2555 XClassHint class_hints
;
2556 XSetWindowAttributes attributes
;
2557 unsigned long attribute_mask
;
2559 attributes
.background_pixel
= f
->display
.x
->background_pixel
;
2560 attributes
.border_pixel
= f
->display
.x
->border_pixel
;
2561 attributes
.bit_gravity
= StaticGravity
;
2562 attributes
.backing_store
= NotUseful
;
2563 attributes
.save_under
= True
;
2564 attributes
.event_mask
= STANDARD_EVENT_SET
;
2565 attribute_mask
= (CWBackPixel
| CWBorderPixel
| CWBitGravity
2567 | CWBackingStore
| CWSaveUnder
2573 = XCreateWindow (FRAME_X_DISPLAY (f
),
2574 f
->display
.x
->parent_desc
,
2575 f
->display
.x
->left_pos
,
2576 f
->display
.x
->top_pos
,
2577 PIXEL_WIDTH (f
), PIXEL_HEIGHT (f
),
2578 f
->display
.x
->border_width
,
2579 CopyFromParent
, /* depth */
2580 InputOutput
, /* class */
2581 FRAME_X_DISPLAY_INFO (f
)->visual
,
2582 attribute_mask
, &attributes
);
2584 validate_x_resource_name ();
2586 class_hints
.res_name
= (char *) XSTRING (Vx_resource_name
)->data
;
2587 class_hints
.res_class
= EMACS_CLASS
;
2588 XSetClassHint (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &class_hints
);
2590 /* The menubar is part of the ordinary display;
2591 it does not count in addition to the height of the window. */
2592 f
->display
.x
->menubar_height
= 0;
2594 /* This indicates that we use the "Passive Input" input model.
2595 Unless we do this, we don't get the Focus{In,Out} events that we
2596 need to draw the cursor correctly. Accursed bureaucrats.
2597 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2599 f
->display
.x
->wm_hints
.input
= True
;
2600 f
->display
.x
->wm_hints
.flags
|= InputHint
;
2601 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2602 &f
->display
.x
->wm_hints
);
2604 /* Request "save yourself" and "delete window" commands from wm. */
2607 protocols
[0] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2608 protocols
[1] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2609 XSetWMProtocols (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), protocols
, 2);
2612 /* x_set_name normally ignores requests to set the name if the
2613 requested name is the same as the current name. This is the one
2614 place where that assumption isn't correct; f->name is set, but
2615 the X server hasn't been told. */
2618 int explicit = f
->explicit_name
;
2620 f
->explicit_name
= 0;
2623 x_set_name (f
, name
, explicit);
2626 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2627 f
->display
.x
->text_cursor
);
2631 if (FRAME_X_WINDOW (f
) == 0)
2632 error ("Unable to create window");
2635 #endif /* not USE_X_TOOLKIT */
2637 /* Handle the icon stuff for this window. Perhaps later we might
2638 want an x_set_icon_position which can be called interactively as
2646 Lisp_Object icon_x
, icon_y
;
2648 /* Set the position of the icon. Note that twm groups all
2649 icons in an icon window. */
2650 icon_x
= x_get_arg (parms
, Qicon_left
, 0, 0, number
);
2651 icon_y
= x_get_arg (parms
, Qicon_top
, 0, 0, number
);
2652 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2654 CHECK_NUMBER (icon_x
, 0);
2655 CHECK_NUMBER (icon_y
, 0);
2657 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2658 error ("Both left and top icon corners of icon must be specified");
2662 if (! EQ (icon_x
, Qunbound
))
2663 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
2665 /* Start up iconic or window? */
2666 x_wm_set_window_state
2667 (f
, (EQ (x_get_arg (parms
, Qvisibility
, 0, 0, symbol
), Qicon
)
2674 /* Make the GC's needed for this window, setting the
2675 background, border and mouse colors; also create the
2676 mouse cursor and the gray border tile. */
2678 static char cursor_bits
[] =
2680 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2681 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2682 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2683 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2690 XGCValues gc_values
;
2696 /* Create the GC's of this frame.
2697 Note that many default values are used. */
2700 gc_values
.font
= f
->display
.x
->font
->fid
;
2701 gc_values
.foreground
= f
->display
.x
->foreground_pixel
;
2702 gc_values
.background
= f
->display
.x
->background_pixel
;
2703 gc_values
.line_width
= 0; /* Means 1 using fast algorithm. */
2704 f
->display
.x
->normal_gc
= XCreateGC (FRAME_X_DISPLAY (f
),
2706 GCLineWidth
| GCFont
2707 | GCForeground
| GCBackground
,
2710 /* Reverse video style. */
2711 gc_values
.foreground
= f
->display
.x
->background_pixel
;
2712 gc_values
.background
= f
->display
.x
->foreground_pixel
;
2713 f
->display
.x
->reverse_gc
= XCreateGC (FRAME_X_DISPLAY (f
),
2715 GCFont
| GCForeground
| GCBackground
2719 /* Cursor has cursor-color background, background-color foreground. */
2720 gc_values
.foreground
= f
->display
.x
->background_pixel
;
2721 gc_values
.background
= f
->display
.x
->cursor_pixel
;
2722 gc_values
.fill_style
= FillOpaqueStippled
;
2724 = XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
2725 FRAME_X_DISPLAY_INFO (f
)->root_window
,
2726 cursor_bits
, 16, 16);
2727 f
->display
.x
->cursor_gc
2728 = XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2729 (GCFont
| GCForeground
| GCBackground
2730 | GCFillStyle
| GCStipple
| GCLineWidth
),
2733 /* Create the gray border tile used when the pointer is not in
2734 the frame. Since this depends on the frame's pixel values,
2735 this must be done on a per-frame basis. */
2736 f
->display
.x
->border_tile
2737 = (XCreatePixmapFromBitmapData
2738 (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
2739 gray_bits
, gray_width
, gray_height
,
2740 f
->display
.x
->foreground_pixel
,
2741 f
->display
.x
->background_pixel
,
2742 DefaultDepth (FRAME_X_DISPLAY (f
),
2743 XScreenNumberOfScreen (FRAME_X_SCREEN (f
)))));
2748 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
2750 "Make a new X window, which is called a \"frame\" in Emacs terms.\n\
2751 Returns an Emacs frame object.\n\
2752 ALIST is an alist of frame parameters.\n\
2753 If the parameters specify that the frame should not have a minibuffer,\n\
2754 and do not specify a specific minibuffer window to use,\n\
2755 then `default-minibuffer-frame' must be a frame whose minibuffer can\n\
2756 be shared by the new frame.\n\
2758 This function is an internal primitive--use `make-frame' instead.")
2763 Lisp_Object frame
, tem
;
2765 int minibuffer_only
= 0;
2766 long window_prompting
= 0;
2768 int count
= specpdl_ptr
- specpdl
;
2769 struct gcpro gcpro1
;
2770 Lisp_Object display
;
2771 struct x_display_info
*dpyinfo
;
2777 /* Use this general default value to start with
2778 until we know if this frame has a specified name. */
2779 Vx_resource_name
= Vinvocation_name
;
2781 display
= x_get_arg (parms
, Qdisplay
, 0, 0, 0);
2782 if (EQ (display
, Qunbound
))
2784 dpyinfo
= check_x_display_info (display
);
2786 kb
= dpyinfo
->kboard
;
2788 kb
= &the_only_kboard
;
2791 name
= x_get_arg (parms
, Qname
, "title", "Title", string
);
2793 && ! EQ (name
, Qunbound
)
2795 error ("Invalid frame name--not a string or nil");
2798 Vx_resource_name
= name
;
2800 /* See if parent window is specified. */
2801 parent
= x_get_arg (parms
, Qparent_id
, NULL
, NULL
, number
);
2802 if (EQ (parent
, Qunbound
))
2804 if (! NILP (parent
))
2805 CHECK_NUMBER (parent
, 0);
2807 tem
= x_get_arg (parms
, Qminibuffer
, 0, 0, symbol
);
2808 if (EQ (tem
, Qnone
) || NILP (tem
))
2809 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
2810 else if (EQ (tem
, Qonly
))
2812 f
= make_minibuffer_frame ();
2813 minibuffer_only
= 1;
2815 else if (WINDOWP (tem
))
2816 f
= make_frame_without_minibuffer (tem
, kb
, display
);
2820 /* Note that X Windows does support scroll bars. */
2821 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
2823 XSETFRAME (frame
, f
);
2826 f
->output_method
= output_x_window
;
2827 f
->display
.x
= (struct x_display
*) xmalloc (sizeof (struct x_display
));
2828 bzero (f
->display
.x
, sizeof (struct x_display
));
2829 f
->display
.x
->icon_bitmap
= -1;
2831 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
2833 FRAME_KBOARD (f
) = kb
;
2836 /* Specify the parent under which to make this X window. */
2840 f
->display
.x
->parent_desc
= parent
;
2841 f
->display
.x
->explicit_parent
= 1;
2845 f
->display
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
2846 f
->display
.x
->explicit_parent
= 0;
2849 /* Note that the frame has no physical cursor right now. */
2850 f
->phys_cursor_x
= -1;
2852 /* Set the name; the functions to which we pass f expect the name to
2854 if (EQ (name
, Qunbound
) || NILP (name
))
2856 f
->name
= build_string (dpyinfo
->x_id_name
);
2857 f
->explicit_name
= 0;
2862 f
->explicit_name
= 1;
2863 /* use the frame's title when getting resources for this frame. */
2864 specbind (Qx_resource_name
, name
);
2867 /* Extract the window parameters from the supplied values
2868 that are needed to determine window geometry. */
2872 font
= x_get_arg (parms
, Qfont
, "font", "Font", string
);
2874 /* First, try whatever font the caller has specified. */
2876 font
= x_new_font (f
, XSTRING (font
)->data
);
2877 /* Try out a font which we hope has bold and italic variations. */
2878 if (!STRINGP (font
))
2879 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
2880 if (! STRINGP (font
))
2881 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
2882 if (! STRINGP (font
))
2883 /* This was formerly the first thing tried, but it finds too many fonts
2884 and takes too long. */
2885 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
2886 /* If those didn't work, look for something which will at least work. */
2887 if (! STRINGP (font
))
2888 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
2890 if (! STRINGP (font
))
2891 font
= build_string ("fixed");
2893 x_default_parameter (f
, parms
, Qfont
, font
,
2894 "font", "Font", string
);
2897 #ifdef USE_X_TOOLKIT
2898 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
2899 whereby it fails to get any font. */
2900 xlwmenu_default_font
= f
->display
.x
->font
;
2903 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
2904 "borderwidth", "BorderWidth", number
);
2905 /* This defaults to 2 in order to match xterm. We recognize either
2906 internalBorderWidth or internalBorder (which is what xterm calls
2908 if (NILP (Fassq (Qinternal_border_width
, parms
)))
2912 value
= x_get_arg (parms
, Qinternal_border_width
,
2913 "internalBorder", "BorderWidth", number
);
2914 if (! EQ (value
, Qunbound
))
2915 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
2918 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (2),
2919 "internalBorderWidth", "BorderWidth", number
);
2920 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qt
,
2921 "verticalScrollBars", "ScrollBars", boolean
);
2923 /* Also do the stuff which must be set before the window exists. */
2924 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
2925 "foreground", "Foreground", string
);
2926 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
2927 "background", "Background", string
);
2928 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
2929 "pointerColor", "Foreground", string
);
2930 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
2931 "cursorColor", "Foreground", string
);
2932 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
2933 "borderColor", "BorderColor", string
);
2935 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
2936 "menuBar", "MenuBar", number
);
2937 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
2938 "scrollBarWidth", "ScrollBarWidth", number
);
2940 f
->display
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
2941 window_prompting
= x_figure_window_size (f
, parms
);
2943 if (window_prompting
& XNegative
)
2945 if (window_prompting
& YNegative
)
2946 f
->display
.x
->win_gravity
= SouthEastGravity
;
2948 f
->display
.x
->win_gravity
= NorthEastGravity
;
2952 if (window_prompting
& YNegative
)
2953 f
->display
.x
->win_gravity
= SouthWestGravity
;
2955 f
->display
.x
->win_gravity
= NorthWestGravity
;
2958 f
->display
.x
->size_hint_flags
= window_prompting
;
2960 #ifdef USE_X_TOOLKIT
2961 x_window (f
, window_prompting
, minibuffer_only
);
2967 init_frame_faces (f
);
2969 /* We need to do this after creating the X window, so that the
2970 icon-creation functions can say whose icon they're describing. */
2971 x_default_parameter (f
, parms
, Qicon_type
, Qnil
,
2972 "bitmapIcon", "BitmapIcon", symbol
);
2974 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
2975 "autoRaise", "AutoRaiseLower", boolean
);
2976 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
2977 "autoLower", "AutoRaiseLower", boolean
);
2978 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
2979 "cursorType", "CursorType", symbol
);
2981 /* Dimensions, especially f->height, must be done via change_frame_size.
2982 Change will not be effected unless different from the current
2986 f
->height
= f
->width
= 0;
2987 change_frame_size (f
, height
, width
, 1, 0);
2989 /* Tell the server what size and position, etc, we want,
2990 and how badly we want them. */
2992 x_wm_set_size_hint (f
, window_prompting
, 0);
2995 tem
= x_get_arg (parms
, Qunsplittable
, 0, 0, boolean
);
2996 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
3000 /* It is now ok to make the frame official
3001 even if we get an error below.
3002 And the frame needs to be on Vframe_list
3003 or making it visible won't work. */
3004 Vframe_list
= Fcons (frame
, Vframe_list
);
3006 /* Now that the frame is official, it counts as a reference to
3008 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
3010 /* Make the window appear on the frame and enable display,
3011 unless the caller says not to. However, with explicit parent,
3012 Emacs cannot control visibility, so don't try. */
3013 if (! f
->display
.x
->explicit_parent
)
3015 Lisp_Object visibility
;
3017 visibility
= x_get_arg (parms
, Qvisibility
, 0, 0, symbol
);
3018 if (EQ (visibility
, Qunbound
))
3021 if (EQ (visibility
, Qicon
))
3022 x_iconify_frame (f
);
3023 else if (! NILP (visibility
))
3024 x_make_frame_visible (f
);
3026 /* Must have been Qnil. */
3030 return unbind_to (count
, frame
);
3033 /* FRAME is used only to get a handle on the X display. We don't pass the
3034 display info directly because we're called from frame.c, which doesn't
3035 know about that structure. */
3037 x_get_focus_frame (frame
)
3038 struct frame
*frame
;
3040 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (frame
);
3042 if (! dpyinfo
->x_focus_frame
)
3045 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
3049 DEFUN ("focus-frame", Ffocus_frame
, Sfocus_frame
, 1, 1, 0,
3050 "Set the focus on FRAME.")
3054 CHECK_LIVE_FRAME (frame
, 0);
3056 if (FRAME_X_P (XFRAME (frame
)))
3059 x_focus_on_frame (XFRAME (frame
));
3067 DEFUN ("unfocus-frame", Funfocus_frame
, Sunfocus_frame
, 0, 0, 0,
3068 "If a frame has been focused, release it.")
3071 if (FRAME_X_P (selected_frame
))
3073 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (selected_frame
);
3075 if (dpyinfo
->x_focus_frame
)
3078 x_unfocus_frame (dpyinfo
->x_focus_frame
);
3086 DEFUN ("x-list-fonts", Fx_list_fonts
, Sx_list_fonts
, 1, 3, 0,
3087 "Return a list of the names of available fonts matching PATTERN.\n\
3088 If optional arguments FACE and FRAME are specified, return only fonts\n\
3089 the same size as FACE on FRAME.\n\
3091 PATTERN is a string, perhaps with wildcard characters;\n\
3092 the * character matches any substring, and\n\
3093 the ? character matches any single character.\n\
3094 PATTERN is case-insensitive.\n\
3095 FACE is a face name--a symbol.\n\
3097 The return value is a list of strings, suitable as arguments to\n\
3100 Fonts Emacs can't use (i.e. proportional fonts) may or may not be excluded\n\
3101 even if they match PATTERN and FACE.")
3102 (pattern
, face
, frame
)
3103 Lisp_Object pattern
, face
, frame
;
3107 #ifndef BROKEN_XLISTFONTSWITHINFO
3110 XFontStruct
*size_ref
;
3115 CHECK_STRING (pattern
, 0);
3117 CHECK_SYMBOL (face
, 1);
3119 f
= check_x_frame (frame
);
3121 /* Determine the width standard for comparison with the fonts we find. */
3129 /* Don't die if we get called with a terminal frame. */
3130 if (! FRAME_X_P (f
))
3131 error ("non-X frame used in `x-list-fonts'");
3133 face_id
= face_name_id_number (f
, face
);
3135 if (face_id
< 0 || face_id
>= FRAME_N_PARAM_FACES (f
)
3136 || FRAME_PARAM_FACES (f
) [face_id
] == 0)
3137 size_ref
= f
->display
.x
->font
;
3140 size_ref
= FRAME_PARAM_FACES (f
) [face_id
]->font
;
3141 if (size_ref
== (XFontStruct
*) (~0))
3142 size_ref
= f
->display
.x
->font
;
3146 /* See if we cached the result for this particular query. */
3147 list
= Fassoc (pattern
,
3148 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
);
3150 /* We have info in the cache for this PATTERN. */
3153 Lisp_Object tem
, newlist
;
3155 /* We have info about this pattern. */
3156 list
= XCONS (list
)->cdr
;
3163 /* Filter the cached info and return just the fonts that match FACE. */
3165 for (tem
= list
; CONSP (tem
); tem
= XCONS (tem
)->cdr
)
3167 XFontStruct
*thisinfo
;
3169 thisinfo
= XLoadQueryFont (FRAME_X_DISPLAY (f
),
3170 XSTRING (XCONS (tem
)->car
)->data
);
3172 if (thisinfo
&& same_size_fonts (thisinfo
, size_ref
))
3173 newlist
= Fcons (XCONS (tem
)->car
, newlist
);
3175 XFreeFont (FRAME_X_DISPLAY (f
), thisinfo
);
3185 /* Solaris 2.3 has a bug in XListFontsWithInfo. */
3186 #ifndef BROKEN_XLISTFONTSWITHINFO
3188 names
= XListFontsWithInfo (FRAME_X_DISPLAY (f
),
3189 XSTRING (pattern
)->data
,
3190 2000, /* maxnames */
3191 &num_fonts
, /* count_return */
3192 &info
); /* info_return */
3195 names
= XListFonts (FRAME_X_DISPLAY (f
),
3196 XSTRING (pattern
)->data
,
3197 2000, /* maxnames */
3198 &num_fonts
); /* count_return */
3207 Lisp_Object full_list
;
3209 /* Make a list of all the fonts we got back.
3210 Store that in the font cache for the display. */
3212 for (i
= 0; i
< num_fonts
; i
++)
3213 full_list
= Fcons (build_string (names
[i
]), full_list
);
3214 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
3215 = Fcons (Fcons (pattern
, full_list
),
3216 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
);
3218 /* Make a list of the fonts that have the right width. */
3220 for (i
= 0; i
< num_fonts
; i
++)
3228 #ifdef BROKEN_XLISTFONTSWITHINFO
3229 XFontStruct
*thisinfo
;
3232 thisinfo
= XLoadQueryFont (FRAME_X_DISPLAY (f
), names
[i
]);
3235 keeper
= thisinfo
&& same_size_fonts (thisinfo
, size_ref
);
3237 keeper
= same_size_fonts (&info
[i
], size_ref
);
3241 list
= Fcons (build_string (names
[i
]), list
);
3243 list
= Fnreverse (list
);
3246 #ifndef BROKEN_XLISTFONTSWITHINFO
3248 XFreeFontInfo (names
, info
, num_fonts
);
3251 XFreeFontNames (names
);
3259 DEFUN ("x-color-defined-p", Fx_color_defined_p
, Sx_color_defined_p
, 1, 2, 0,
3260 "Return non-nil if color COLOR is supported on frame FRAME.\n\
3261 If FRAME is omitted or nil, use the selected frame.")
3263 Lisp_Object color
, frame
;
3266 FRAME_PTR f
= check_x_frame (frame
);
3268 CHECK_STRING (color
, 1);
3270 if (defined_color (f
, XSTRING (color
)->data
, &foo
, 0))
3276 DEFUN ("x-color-values", Fx_color_values
, Sx_color_values
, 1, 2, 0,
3277 "Return a description of the color named COLOR on frame FRAME.\n\
3278 The value is a list of integer RGB values--(RED GREEN BLUE).\n\
3279 These values appear to range from 0 to 65280 or 65535, depending\n\
3280 on the system; white is (65280 65280 65280) or (65535 65535 65535).\n\
3281 If FRAME is omitted or nil, use the selected frame.")
3283 Lisp_Object color
, frame
;
3286 FRAME_PTR f
= check_x_frame (frame
);
3288 CHECK_STRING (color
, 1);
3290 if (defined_color (f
, XSTRING (color
)->data
, &foo
, 0))
3294 rgb
[0] = make_number (foo
.red
);
3295 rgb
[1] = make_number (foo
.green
);
3296 rgb
[2] = make_number (foo
.blue
);
3297 return Flist (3, rgb
);
3303 DEFUN ("x-display-color-p", Fx_display_color_p
, Sx_display_color_p
, 0, 1, 0,
3304 "Return t if the X display supports color.\n\
3305 The optional argument DISPLAY specifies which display to ask about.\n\
3306 DISPLAY should be either a frame or a display name (a string).\n\
3307 If omitted or nil, that stands for the selected frame's display.")
3309 Lisp_Object display
;
3311 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3313 if (dpyinfo
->n_planes
<= 2)
3316 switch (dpyinfo
->visual
->class)
3329 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
3331 "Return t if the X display supports shades of gray.\n\
3332 The optional argument DISPLAY specifies which display to ask about.\n\
3333 DISPLAY should be either a frame or a display name (a string).\n\
3334 If omitted or nil, that stands for the selected frame's display.")
3336 Lisp_Object display
;
3338 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3340 if (dpyinfo
->n_planes
<= 2)
3343 return (dpyinfo
->n_planes
> 1
3344 && (dpyinfo
->visual
->class == StaticGray
3345 || dpyinfo
->visual
->class == GrayScale
));
3348 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
3350 "Returns the width in pixels of the X display DISPLAY.\n\
3351 The optional argument DISPLAY specifies which display to ask about.\n\
3352 DISPLAY should be either a frame or a display name (a string).\n\
3353 If omitted or nil, that stands for the selected frame's display.")
3355 Lisp_Object display
;
3357 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3359 return make_number (dpyinfo
->width
);
3362 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
3363 Sx_display_pixel_height
, 0, 1, 0,
3364 "Returns the height in pixels of the X display DISPLAY.\n\
3365 The optional argument DISPLAY specifies which display to ask about.\n\
3366 DISPLAY should be either a frame or a display name (a string).\n\
3367 If omitted or nil, that stands for the selected frame's display.")
3369 Lisp_Object display
;
3371 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3373 return make_number (dpyinfo
->height
);
3376 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
3378 "Returns the number of bitplanes of the X display DISPLAY.\n\
3379 The optional argument DISPLAY specifies which display to ask about.\n\
3380 DISPLAY should be either a frame or a display name (a string).\n\
3381 If omitted or nil, that stands for the selected frame's display.")
3383 Lisp_Object display
;
3385 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3387 return make_number (dpyinfo
->n_planes
);
3390 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
3392 "Returns the number of color cells of the X display DISPLAY.\n\
3393 The optional argument DISPLAY specifies which display to ask about.\n\
3394 DISPLAY should be either a frame or a display name (a string).\n\
3395 If omitted or nil, that stands for the selected frame's display.")
3397 Lisp_Object display
;
3399 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3401 return make_number (DisplayCells (dpyinfo
->display
,
3402 XScreenNumberOfScreen (dpyinfo
->screen
)));
3405 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
3406 Sx_server_max_request_size
,
3408 "Returns the maximum request size of the X server of display DISPLAY.\n\
3409 The optional argument DISPLAY specifies which display to ask about.\n\
3410 DISPLAY should be either a frame or a display name (a string).\n\
3411 If omitted or nil, that stands for the selected frame's display.")
3413 Lisp_Object display
;
3415 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3417 return make_number (MAXREQUEST (dpyinfo
->display
));
3420 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
3421 "Returns the vendor ID string of the X server of display DISPLAY.\n\
3422 The optional argument DISPLAY specifies which display to ask about.\n\
3423 DISPLAY should be either a frame or a display name (a string).\n\
3424 If omitted or nil, that stands for the selected frame's display.")
3426 Lisp_Object display
;
3428 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3429 char *vendor
= ServerVendor (dpyinfo
->display
);
3431 if (! vendor
) vendor
= "";
3432 return build_string (vendor
);
3435 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
3436 "Returns the version numbers of the X server of display DISPLAY.\n\
3437 The value is a list of three integers: the major and minor\n\
3438 version numbers of the X Protocol in use, and the vendor-specific release\n\
3439 number. See also the function `x-server-vendor'.\n\n\
3440 The optional argument DISPLAY specifies which display to ask about.\n\
3441 DISPLAY should be either a frame or a display name (a string).\n\
3442 If omitted or nil, that stands for the selected frame's display.")
3444 Lisp_Object display
;
3446 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3447 Display
*dpy
= dpyinfo
->display
;
3449 return Fcons (make_number (ProtocolVersion (dpy
)),
3450 Fcons (make_number (ProtocolRevision (dpy
)),
3451 Fcons (make_number (VendorRelease (dpy
)), Qnil
)));
3454 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
3455 "Returns the number of screens on the X server of display DISPLAY.\n\
3456 The optional argument DISPLAY specifies which display to ask about.\n\
3457 DISPLAY should be either a frame or a display name (a string).\n\
3458 If omitted or nil, that stands for the selected frame's display.")
3460 Lisp_Object display
;
3462 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3464 return make_number (ScreenCount (dpyinfo
->display
));
3467 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
3468 "Returns the height in millimeters of the X display DISPLAY.\n\
3469 The optional argument DISPLAY specifies which display to ask about.\n\
3470 DISPLAY should be either a frame or a display name (a string).\n\
3471 If omitted or nil, that stands for the selected frame's display.")
3473 Lisp_Object display
;
3475 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3477 return make_number (HeightMMOfScreen (dpyinfo
->screen
));
3480 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
3481 "Returns the width in millimeters of the X display DISPLAY.\n\
3482 The optional argument DISPLAY specifies which display to ask about.\n\
3483 DISPLAY should be either a frame or a display name (a string).\n\
3484 If omitted or nil, that stands for the selected frame's display.")
3486 Lisp_Object display
;
3488 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3490 return make_number (WidthMMOfScreen (dpyinfo
->screen
));
3493 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
3494 Sx_display_backing_store
, 0, 1, 0,
3495 "Returns an indication of whether X display DISPLAY does backing store.\n\
3496 The value may be `always', `when-mapped', or `not-useful'.\n\
3497 The optional argument DISPLAY specifies which display to ask about.\n\
3498 DISPLAY should be either a frame or a display name (a string).\n\
3499 If omitted or nil, that stands for the selected frame's display.")
3501 Lisp_Object display
;
3503 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3505 switch (DoesBackingStore (dpyinfo
->screen
))
3508 return intern ("always");
3511 return intern ("when-mapped");
3514 return intern ("not-useful");
3517 error ("Strange value for BackingStore parameter of screen");
3521 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
3522 Sx_display_visual_class
, 0, 1, 0,
3523 "Returns the visual class of the X display DISPLAY.\n\
3524 The value is one of the symbols `static-gray', `gray-scale',\n\
3525 `static-color', `pseudo-color', `true-color', or `direct-color'.\n\n\
3526 The optional argument DISPLAY specifies which display to ask about.\n\
3527 DISPLAY should be either a frame or a display name (a string).\n\
3528 If omitted or nil, that stands for the selected frame's display.")
3530 Lisp_Object display
;
3532 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3534 switch (dpyinfo
->visual
->class)
3536 case StaticGray
: return (intern ("static-gray"));
3537 case GrayScale
: return (intern ("gray-scale"));
3538 case StaticColor
: return (intern ("static-color"));
3539 case PseudoColor
: return (intern ("pseudo-color"));
3540 case TrueColor
: return (intern ("true-color"));
3541 case DirectColor
: return (intern ("direct-color"));
3543 error ("Display has an unknown visual class");
3547 DEFUN ("x-display-save-under", Fx_display_save_under
,
3548 Sx_display_save_under
, 0, 1, 0,
3549 "Returns t if the X display DISPLAY supports the save-under feature.\n\
3550 The optional argument DISPLAY specifies which display to ask about.\n\
3551 DISPLAY should be either a frame or a display name (a string).\n\
3552 If omitted or nil, that stands for the selected frame's display.")
3554 Lisp_Object display
;
3556 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3558 if (DoesSaveUnders (dpyinfo
->screen
) == True
)
3566 register struct frame
*f
;
3568 return PIXEL_WIDTH (f
);
3573 register struct frame
*f
;
3575 return PIXEL_HEIGHT (f
);
3580 register struct frame
*f
;
3582 return FONT_WIDTH (f
->display
.x
->font
);
3587 register struct frame
*f
;
3589 return f
->display
.x
->line_height
;
3593 x_screen_planes (frame
)
3596 return FRAME_X_DISPLAY_INFO (XFRAME (frame
))->n_planes
;
3599 #if 0 /* These no longer seem like the right way to do things. */
3601 /* Draw a rectangle on the frame with left top corner including
3602 the character specified by LEFT_CHAR and TOP_CHAR. The rectangle is
3603 CHARS by LINES wide and long and is the color of the cursor. */
3606 x_rectangle (f
, gc
, left_char
, top_char
, chars
, lines
)
3607 register struct frame
*f
;
3609 register int top_char
, left_char
, chars
, lines
;
3613 int left
= (left_char
* FONT_WIDTH (f
->display
.x
->font
)
3614 + f
->display
.x
->internal_border_width
);
3615 int top
= (top_char
* f
->display
.x
->line_height
3616 + f
->display
.x
->internal_border_width
);
3619 width
= FONT_WIDTH (f
->display
.x
->font
) / 2;
3621 width
= FONT_WIDTH (f
->display
.x
->font
) * chars
;
3623 height
= f
->display
.x
->line_height
/ 2;
3625 height
= f
->display
.x
->line_height
* lines
;
3627 XDrawRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3628 gc
, left
, top
, width
, height
);
3631 DEFUN ("x-draw-rectangle", Fx_draw_rectangle
, Sx_draw_rectangle
, 5, 5, 0,
3632 "Draw a rectangle on FRAME between coordinates specified by\n\
3633 numbers X0, Y0, X1, Y1 in the cursor pixel.")
3634 (frame
, X0
, Y0
, X1
, Y1
)
3635 register Lisp_Object frame
, X0
, X1
, Y0
, Y1
;
3637 register int x0
, y0
, x1
, y1
, top
, left
, n_chars
, n_lines
;
3639 CHECK_LIVE_FRAME (frame
, 0);
3640 CHECK_NUMBER (X0
, 0);
3641 CHECK_NUMBER (Y0
, 1);
3642 CHECK_NUMBER (X1
, 2);
3643 CHECK_NUMBER (Y1
, 3);
3653 n_lines
= y1
- y0
+ 1;
3658 n_lines
= y0
- y1
+ 1;
3664 n_chars
= x1
- x0
+ 1;
3669 n_chars
= x0
- x1
+ 1;
3673 x_rectangle (XFRAME (frame
), XFRAME (frame
)->display
.x
->cursor_gc
,
3674 left
, top
, n_chars
, n_lines
);
3680 DEFUN ("x-erase-rectangle", Fx_erase_rectangle
, Sx_erase_rectangle
, 5, 5, 0,
3681 "Draw a rectangle drawn on FRAME between coordinates\n\
3682 X0, Y0, X1, Y1 in the regular background-pixel.")
3683 (frame
, X0
, Y0
, X1
, Y1
)
3684 register Lisp_Object frame
, X0
, Y0
, X1
, Y1
;
3686 register int x0
, y0
, x1
, y1
, top
, left
, n_chars
, n_lines
;
3688 CHECK_LIVE_FRAME (frame
, 0);
3689 CHECK_NUMBER (X0
, 0);
3690 CHECK_NUMBER (Y0
, 1);
3691 CHECK_NUMBER (X1
, 2);
3692 CHECK_NUMBER (Y1
, 3);
3702 n_lines
= y1
- y0
+ 1;
3707 n_lines
= y0
- y1
+ 1;
3713 n_chars
= x1
- x0
+ 1;
3718 n_chars
= x0
- x1
+ 1;
3722 x_rectangle (XFRAME (frame
), XFRAME (frame
)->display
.x
->reverse_gc
,
3723 left
, top
, n_chars
, n_lines
);
3729 /* Draw lines around the text region beginning at the character position
3730 TOP_X, TOP_Y and ending at BOTTOM_X and BOTTOM_Y. GC specifies the
3731 pixel and line characteristics. */
3733 #define line_len(line) (FRAME_CURRENT_GLYPHS (f)->used[(line)])
3736 outline_region (f
, gc
, top_x
, top_y
, bottom_x
, bottom_y
)
3737 register struct frame
*f
;
3739 int top_x
, top_y
, bottom_x
, bottom_y
;
3741 register int ibw
= f
->display
.x
->internal_border_width
;
3742 register int font_w
= FONT_WIDTH (f
->display
.x
->font
);
3743 register int font_h
= f
->display
.x
->line_height
;
3745 int x
= line_len (y
);
3746 XPoint
*pixel_points
3747 = (XPoint
*) alloca (((bottom_y
- top_y
+ 2) * 4) * sizeof (XPoint
));
3748 register XPoint
*this_point
= pixel_points
;
3750 /* Do the horizontal top line/lines */
3753 this_point
->x
= ibw
;
3754 this_point
->y
= ibw
+ (font_h
* top_y
);
3757 this_point
->x
= ibw
+ (font_w
/ 2); /* Half-size for newline chars. */
3759 this_point
->x
= ibw
+ (font_w
* x
);
3760 this_point
->y
= (this_point
- 1)->y
;
3764 this_point
->x
= ibw
;
3765 this_point
->y
= ibw
+ (font_h
* (top_y
+ 1));
3767 this_point
->x
= ibw
+ (font_w
* top_x
);
3768 this_point
->y
= (this_point
- 1)->y
;
3770 this_point
->x
= (this_point
- 1)->x
;
3771 this_point
->y
= ibw
+ (font_h
* top_y
);
3773 this_point
->x
= ibw
+ (font_w
* x
);
3774 this_point
->y
= (this_point
- 1)->y
;
3777 /* Now do the right side. */
3778 while (y
< bottom_y
)
3779 { /* Right vertical edge */
3781 this_point
->x
= (this_point
- 1)->x
;
3782 this_point
->y
= ibw
+ (font_h
* (y
+ 1));
3785 y
++; /* Horizontal connection to next line */
3788 this_point
->x
= ibw
+ (font_w
/ 2);
3790 this_point
->x
= ibw
+ (font_w
* x
);
3792 this_point
->y
= (this_point
- 1)->y
;
3795 /* Now do the bottom and connect to the top left point. */
3796 this_point
->x
= ibw
+ (font_w
* (bottom_x
+ 1));
3799 this_point
->x
= (this_point
- 1)->x
;
3800 this_point
->y
= ibw
+ (font_h
* (bottom_y
+ 1));
3802 this_point
->x
= ibw
;
3803 this_point
->y
= (this_point
- 1)->y
;
3805 this_point
->x
= pixel_points
->x
;
3806 this_point
->y
= pixel_points
->y
;
3808 XDrawLines (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3810 (this_point
- pixel_points
+ 1), CoordModeOrigin
);
3813 DEFUN ("x-contour-region", Fx_contour_region
, Sx_contour_region
, 1, 1, 0,
3814 "Highlight the region between point and the character under the mouse\n\
3817 register Lisp_Object event
;
3819 register int x0
, y0
, x1
, y1
;
3820 register struct frame
*f
= selected_frame
;
3821 register int p1
, p2
;
3823 CHECK_CONS (event
, 0);
3826 x0
= XINT (Fcar (Fcar (event
)));
3827 y0
= XINT (Fcar (Fcdr (Fcar (event
))));
3829 /* If the mouse is past the end of the line, don't that area. */
3830 /* ReWrite this... */
3835 if (y1
> y0
) /* point below mouse */
3836 outline_region (f
, f
->display
.x
->cursor_gc
,
3838 else if (y1
< y0
) /* point above mouse */
3839 outline_region (f
, f
->display
.x
->cursor_gc
,
3841 else /* same line: draw horizontal rectangle */
3844 x_rectangle (f
, f
->display
.x
->cursor_gc
,
3845 x0
, y0
, (x1
- x0
+ 1), 1);
3847 x_rectangle (f
, f
->display
.x
->cursor_gc
,
3848 x1
, y1
, (x0
- x1
+ 1), 1);
3851 XFlush (FRAME_X_DISPLAY (f
));
3857 DEFUN ("x-uncontour-region", Fx_uncontour_region
, Sx_uncontour_region
, 1, 1, 0,
3858 "Erase any highlighting of the region between point and the character\n\
3859 at X, Y on the selected frame.")
3861 register Lisp_Object event
;
3863 register int x0
, y0
, x1
, y1
;
3864 register struct frame
*f
= selected_frame
;
3867 x0
= XINT (Fcar (Fcar (event
)));
3868 y0
= XINT (Fcar (Fcdr (Fcar (event
))));
3872 if (y1
> y0
) /* point below mouse */
3873 outline_region (f
, f
->display
.x
->reverse_gc
,
3875 else if (y1
< y0
) /* point above mouse */
3876 outline_region (f
, f
->display
.x
->reverse_gc
,
3878 else /* same line: draw horizontal rectangle */
3881 x_rectangle (f
, f
->display
.x
->reverse_gc
,
3882 x0
, y0
, (x1
- x0
+ 1), 1);
3884 x_rectangle (f
, f
->display
.x
->reverse_gc
,
3885 x1
, y1
, (x0
- x1
+ 1), 1);
3893 int contour_begin_x
, contour_begin_y
;
3894 int contour_end_x
, contour_end_y
;
3895 int contour_npoints
;
3897 /* Clip the top part of the contour lines down (and including) line Y_POS.
3898 If X_POS is in the middle (rather than at the end) of the line, drop
3899 down a line at that character. */
3902 clip_contour_top (y_pos
, x_pos
)
3904 register XPoint
*begin
= contour_lines
[y_pos
].top_left
;
3905 register XPoint
*end
;
3906 register int npoints
;
3907 register struct display_line
*line
= selected_frame
->phys_lines
[y_pos
+ 1];
3909 if (x_pos
>= line
->len
- 1) /* Draw one, straight horizontal line. */
3911 end
= contour_lines
[y_pos
].top_right
;
3912 npoints
= (end
- begin
+ 1);
3913 XDrawLines (x_current_display
, contour_window
,
3914 contour_erase_gc
, begin_erase
, npoints
, CoordModeOrigin
);
3916 bcopy (end
, begin
+ 1, contour_last_point
- end
+ 1);
3917 contour_last_point
-= (npoints
- 2);
3918 XDrawLines (x_current_display
, contour_window
,
3919 contour_erase_gc
, begin
, 2, CoordModeOrigin
);
3920 XFlush (x_current_display
);
3922 /* Now, update contour_lines structure. */
3927 register XPoint
*p
= begin
+ 1;
3928 end
= contour_lines
[y_pos
].bottom_right
;
3929 npoints
= (end
- begin
+ 1);
3930 XDrawLines (x_current_display
, contour_window
,
3931 contour_erase_gc
, begin_erase
, npoints
, CoordModeOrigin
);
3934 p
->x
= ibw
+ (font_w
* (x_pos
+ 1));
3936 p
->y
= begin
->y
+ font_h
;
3938 bcopy (end
, begin
+ 3, contour_last_point
- end
+ 1);
3939 contour_last_point
-= (npoints
- 5);
3940 XDrawLines (x_current_display
, contour_window
,
3941 contour_erase_gc
, begin
, 4, CoordModeOrigin
);
3942 XFlush (x_current_display
);
3944 /* Now, update contour_lines structure. */
3948 /* Erase the top horizontal lines of the contour, and then extend
3949 the contour upwards. */
3952 extend_contour_top (line
)
3957 clip_contour_bottom (x_pos
, y_pos
)
3963 extend_contour_bottom (x_pos
, y_pos
)
3967 DEFUN ("x-select-region", Fx_select_region
, Sx_select_region
, 1, 1, "e",
3972 register struct frame
*f
= selected_frame
;
3973 register int point_x
= f
->cursor_x
;
3974 register int point_y
= f
->cursor_y
;
3975 register int mouse_below_point
;
3976 register Lisp_Object obj
;
3977 register int x_contour_x
, x_contour_y
;
3979 x_contour_x
= x_mouse_x
;
3980 x_contour_y
= x_mouse_y
;
3981 if (x_contour_y
> point_y
|| (x_contour_y
== point_y
3982 && x_contour_x
> point_x
))
3984 mouse_below_point
= 1;
3985 outline_region (f
, f
->display
.x
->cursor_gc
, point_x
, point_y
,
3986 x_contour_x
, x_contour_y
);
3990 mouse_below_point
= 0;
3991 outline_region (f
, f
->display
.x
->cursor_gc
, x_contour_x
, x_contour_y
,
3997 obj
= read_char (-1, 0, 0, Qnil
, 0);
4001 if (mouse_below_point
)
4003 if (x_mouse_y
<= point_y
) /* Flipped. */
4005 mouse_below_point
= 0;
4007 outline_region (f
, f
->display
.x
->reverse_gc
, point_x
, point_y
,
4008 x_contour_x
, x_contour_y
);
4009 outline_region (f
, f
->display
.x
->cursor_gc
, x_mouse_x
, x_mouse_y
,
4012 else if (x_mouse_y
< x_contour_y
) /* Bottom clipped. */
4014 clip_contour_bottom (x_mouse_y
);
4016 else if (x_mouse_y
> x_contour_y
) /* Bottom extended. */
4018 extend_bottom_contour (x_mouse_y
);
4021 x_contour_x
= x_mouse_x
;
4022 x_contour_y
= x_mouse_y
;
4024 else /* mouse above or same line as point */
4026 if (x_mouse_y
>= point_y
) /* Flipped. */
4028 mouse_below_point
= 1;
4030 outline_region (f
, f
->display
.x
->reverse_gc
,
4031 x_contour_x
, x_contour_y
, point_x
, point_y
);
4032 outline_region (f
, f
->display
.x
->cursor_gc
, point_x
, point_y
,
4033 x_mouse_x
, x_mouse_y
);
4035 else if (x_mouse_y
> x_contour_y
) /* Top clipped. */
4037 clip_contour_top (x_mouse_y
);
4039 else if (x_mouse_y
< x_contour_y
) /* Top extended. */
4041 extend_contour_top (x_mouse_y
);
4046 unread_command_event
= obj
;
4047 if (mouse_below_point
)
4049 contour_begin_x
= point_x
;
4050 contour_begin_y
= point_y
;
4051 contour_end_x
= x_contour_x
;
4052 contour_end_y
= x_contour_y
;
4056 contour_begin_x
= x_contour_x
;
4057 contour_begin_y
= x_contour_y
;
4058 contour_end_x
= point_x
;
4059 contour_end_y
= point_y
;
4064 DEFUN ("x-horizontal-line", Fx_horizontal_line
, Sx_horizontal_line
, 1, 1, "e",
4069 register Lisp_Object obj
;
4070 struct frame
*f
= selected_frame
;
4071 register struct window
*w
= XWINDOW (selected_window
);
4072 register GC line_gc
= f
->display
.x
->cursor_gc
;
4073 register GC erase_gc
= f
->display
.x
->reverse_gc
;
4075 char dash_list
[] = {6, 4, 6, 4};
4077 XGCValues gc_values
;
4079 register int previous_y
;
4080 register int line
= (x_mouse_y
+ 1) * f
->display
.x
->line_height
4081 + f
->display
.x
->internal_border_width
;
4082 register int left
= f
->display
.x
->internal_border_width
4084 * FONT_WIDTH (f
->display
.x
->font
));
4085 register int right
= left
+ (w
->width
4086 * FONT_WIDTH (f
->display
.x
->font
))
4087 - f
->display
.x
->internal_border_width
;
4091 gc_values
.foreground
= f
->display
.x
->cursor_pixel
;
4092 gc_values
.background
= f
->display
.x
->background_pixel
;
4093 gc_values
.line_width
= 1;
4094 gc_values
.line_style
= LineOnOffDash
;
4095 gc_values
.cap_style
= CapRound
;
4096 gc_values
.join_style
= JoinRound
;
4098 line_gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4099 GCLineStyle
| GCJoinStyle
| GCCapStyle
4100 | GCLineWidth
| GCForeground
| GCBackground
,
4102 XSetDashes (FRAME_X_DISPLAY (f
), line_gc
, 0, dash_list
, dashes
);
4103 gc_values
.foreground
= f
->display
.x
->background_pixel
;
4104 gc_values
.background
= f
->display
.x
->foreground_pixel
;
4105 erase_gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4106 GCLineStyle
| GCJoinStyle
| GCCapStyle
4107 | GCLineWidth
| GCForeground
| GCBackground
,
4109 XSetDashes (FRAME_X_DISPLAY (f
), erase_gc
, 0, dash_list
, dashes
);
4116 if (x_mouse_y
>= XINT (w
->top
)
4117 && x_mouse_y
< XINT (w
->top
) + XINT (w
->height
) - 1)
4119 previous_y
= x_mouse_y
;
4120 line
= (x_mouse_y
+ 1) * f
->display
.x
->line_height
4121 + f
->display
.x
->internal_border_width
;
4122 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4123 line_gc
, left
, line
, right
, line
);
4125 XFlush (FRAME_X_DISPLAY (f
));
4130 obj
= read_char (-1, 0, 0, Qnil
, 0);
4132 || (! EQ (Fcar (Fcdr (Fcdr (obj
))),
4133 Qvertical_scroll_bar
))
4137 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4138 erase_gc
, left
, line
, right
, line
);
4139 unread_command_event
= obj
;
4141 XFreeGC (FRAME_X_DISPLAY (f
), line_gc
);
4142 XFreeGC (FRAME_X_DISPLAY (f
), erase_gc
);
4148 while (x_mouse_y
== previous_y
);
4151 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4152 erase_gc
, left
, line
, right
, line
);
4159 /* These keep track of the rectangle following the pointer. */
4160 int mouse_track_top
, mouse_track_left
, mouse_track_width
;
4162 /* Offset in buffer of character under the pointer, or 0. */
4163 int mouse_buffer_offset
;
4165 DEFUN ("x-track-pointer", Fx_track_pointer
, Sx_track_pointer
, 0, 0, 0,
4166 "Track the pointer.")
4169 static Cursor current_pointer_shape
;
4170 FRAME_PTR f
= x_mouse_frame
;
4173 if (EQ (Vmouse_frame_part
, Qtext_part
)
4174 && (current_pointer_shape
!= f
->display
.x
->nontext_cursor
))
4179 current_pointer_shape
= f
->display
.x
->nontext_cursor
;
4180 XDefineCursor (FRAME_X_DISPLAY (f
),
4182 current_pointer_shape
);
4184 buf
= XBUFFER (XWINDOW (Vmouse_window
)->buffer
);
4185 c
= *(BUF_CHAR_ADDRESS (buf
, mouse_buffer_offset
));
4187 else if (EQ (Vmouse_frame_part
, Qmodeline_part
)
4188 && (current_pointer_shape
!= f
->display
.x
->modeline_cursor
))
4190 current_pointer_shape
= f
->display
.x
->modeline_cursor
;
4191 XDefineCursor (FRAME_X_DISPLAY (f
),
4193 current_pointer_shape
);
4196 XFlush (FRAME_X_DISPLAY (f
));
4202 DEFUN ("x-track-pointer", Fx_track_pointer
, Sx_track_pointer
, 1, 1, "e",
4203 "Draw rectangle around character under mouse pointer, if there is one.")
4207 struct window
*w
= XWINDOW (Vmouse_window
);
4208 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4209 struct buffer
*b
= XBUFFER (w
->buffer
);
4212 if (! EQ (Vmouse_window
, selected_window
))
4215 if (EQ (event
, Qnil
))
4219 x_read_mouse_position (selected_frame
, &x
, &y
);
4223 mouse_track_width
= 0;
4224 mouse_track_left
= mouse_track_top
= -1;
4228 if ((x_mouse_x
!= mouse_track_left
4229 && (x_mouse_x
< mouse_track_left
4230 || x_mouse_x
> (mouse_track_left
+ mouse_track_width
)))
4231 || x_mouse_y
!= mouse_track_top
)
4233 int hp
= 0; /* Horizontal position */
4234 int len
= FRAME_CURRENT_GLYPHS (f
)->used
[x_mouse_y
];
4235 int p
= FRAME_CURRENT_GLYPHS (f
)->bufp
[x_mouse_y
];
4236 int tab_width
= XINT (b
->tab_width
);
4237 int ctl_arrow_p
= !NILP (b
->ctl_arrow
);
4239 int mode_line_vpos
= XFASTINT (w
->height
) + XFASTINT (w
->top
) - 1;
4240 int in_mode_line
= 0;
4242 if (! FRAME_CURRENT_GLYPHS (f
)->enable
[x_mouse_y
])
4245 /* Erase previous rectangle. */
4246 if (mouse_track_width
)
4248 x_rectangle (f
, f
->display
.x
->reverse_gc
,
4249 mouse_track_left
, mouse_track_top
,
4250 mouse_track_width
, 1);
4252 if ((mouse_track_left
== f
->phys_cursor_x
4253 || mouse_track_left
== f
->phys_cursor_x
- 1)
4254 && mouse_track_top
== f
->phys_cursor_y
)
4256 x_display_cursor (f
, 1);
4260 mouse_track_left
= x_mouse_x
;
4261 mouse_track_top
= x_mouse_y
;
4262 mouse_track_width
= 0;
4264 if (mouse_track_left
> len
) /* Past the end of line. */
4267 if (mouse_track_top
== mode_line_vpos
)
4273 if (tab_width
<= 0 || tab_width
> 20) tab_width
= 8;
4277 if (len
== f
->width
&& hp
== len
- 1 && c
!= '\n')
4283 mouse_track_width
= tab_width
- (hp
% tab_width
);
4285 hp
+= mouse_track_width
;
4288 mouse_track_left
= hp
- mouse_track_width
;
4294 mouse_track_width
= -1;
4298 if (ctl_arrow_p
&& (c
< 040 || c
== 0177))
4303 mouse_track_width
= 2;
4308 mouse_track_left
= hp
- mouse_track_width
;
4314 mouse_track_width
= 1;
4321 while (hp
<= x_mouse_x
);
4324 if (mouse_track_width
) /* Over text; use text pointer shape. */
4326 XDefineCursor (FRAME_X_DISPLAY (f
),
4328 f
->display
.x
->text_cursor
);
4329 x_rectangle (f
, f
->display
.x
->cursor_gc
,
4330 mouse_track_left
, mouse_track_top
,
4331 mouse_track_width
, 1);
4333 else if (in_mode_line
)
4334 XDefineCursor (FRAME_X_DISPLAY (f
),
4336 f
->display
.x
->modeline_cursor
);
4338 XDefineCursor (FRAME_X_DISPLAY (f
),
4340 f
->display
.x
->nontext_cursor
);
4343 XFlush (FRAME_X_DISPLAY (f
));
4346 obj
= read_char (-1, 0, 0, Qnil
, 0);
4349 while (CONSP (obj
) /* Mouse event */
4350 && EQ (Fcar (Fcdr (Fcdr (obj
))), Qnil
) /* Not scroll bar */
4351 && EQ (Vmouse_depressed
, Qnil
) /* Only motion events */
4352 && EQ (Vmouse_window
, selected_window
) /* In this window */
4355 unread_command_event
= obj
;
4357 if (mouse_track_width
)
4359 x_rectangle (f
, f
->display
.x
->reverse_gc
,
4360 mouse_track_left
, mouse_track_top
,
4361 mouse_track_width
, 1);
4362 mouse_track_width
= 0;
4363 if ((mouse_track_left
== f
->phys_cursor_x
4364 || mouse_track_left
- 1 == f
->phys_cursor_x
)
4365 && mouse_track_top
== f
->phys_cursor_y
)
4367 x_display_cursor (f
, 1);
4370 XDefineCursor (FRAME_X_DISPLAY (f
),
4372 f
->display
.x
->nontext_cursor
);
4373 XFlush (FRAME_X_DISPLAY (f
));
4383 /* Draw a pixmap specified by IMAGE_DATA of dimensions WIDTH and HEIGHT
4384 on the frame F at position X, Y. */
4386 x_draw_pixmap (f
, x
, y
, image_data
, width
, height
)
4388 int x
, y
, width
, height
;
4393 image
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
4394 FRAME_X_WINDOW (f
), image_data
,
4396 XCopyPlane (FRAME_X_DISPLAY (f
), image
, FRAME_X_WINDOW (f
),
4397 f
->display
.x
->normal_gc
, 0, 0, width
, height
, x
, y
);
4401 #if 0 /* I'm told these functions are superfluous
4402 given the ability to bind function keys. */
4405 DEFUN ("x-rebind-key", Fx_rebind_key
, Sx_rebind_key
, 3, 3, 0,
4406 "Rebind X keysym KEYSYM, with MODIFIERS, to generate NEWSTRING.\n\
4407 KEYSYM is a string which conforms to the X keysym definitions found\n\
4408 in X11/keysymdef.h, sans the initial XK_. MODIFIERS is nil or a\n\
4409 list of strings specifying modifier keys such as Control_L, which must\n\
4410 also be depressed for NEWSTRING to appear.")
4411 (x_keysym
, modifiers
, newstring
)
4412 register Lisp_Object x_keysym
;
4413 register Lisp_Object modifiers
;
4414 register Lisp_Object newstring
;
4417 register KeySym keysym
;
4418 KeySym modifier_list
[16];
4421 CHECK_STRING (x_keysym
, 1);
4422 CHECK_STRING (newstring
, 3);
4424 keysym
= XStringToKeysym ((char *) XSTRING (x_keysym
)->data
);
4425 if (keysym
== NoSymbol
)
4426 error ("Keysym does not exist");
4428 if (NILP (modifiers
))
4429 XRebindKeysym (x_current_display
, keysym
, modifier_list
, 0,
4430 XSTRING (newstring
)->data
, XSTRING (newstring
)->size
);
4433 register Lisp_Object rest
, mod
;
4436 for (rest
= modifiers
; !NILP (rest
); rest
= Fcdr (rest
))
4439 error ("Can't have more than 16 modifiers");
4442 CHECK_STRING (mod
, 3);
4443 modifier_list
[i
] = XStringToKeysym ((char *) XSTRING (mod
)->data
);
4445 if (modifier_list
[i
] == NoSymbol
4446 || !(IsModifierKey (modifier_list
[i
])
4447 || ((unsigned)(modifier_list
[i
]) == XK_Mode_switch
)
4448 || ((unsigned)(modifier_list
[i
]) == XK_Num_Lock
)))
4450 if (modifier_list
[i
] == NoSymbol
4451 || !IsModifierKey (modifier_list
[i
]))
4453 error ("Element is not a modifier keysym");
4457 XRebindKeysym (x_current_display
, keysym
, modifier_list
, i
,
4458 XSTRING (newstring
)->data
, XSTRING (newstring
)->size
);
4464 DEFUN ("x-rebind-keys", Fx_rebind_keys
, Sx_rebind_keys
, 2, 2, 0,
4465 "Rebind KEYCODE to list of strings STRINGS.\n\
4466 STRINGS should be a list of 16 elements, one for each shift combination.\n\
4467 nil as element means don't change.\n\
4468 See the documentation of `x-rebind-key' for more information.")
4470 register Lisp_Object keycode
;
4471 register Lisp_Object strings
;
4473 register Lisp_Object item
;
4474 register unsigned char *rawstring
;
4475 KeySym rawkey
, modifier
[1];
4477 register unsigned i
;
4480 CHECK_NUMBER (keycode
, 1);
4481 CHECK_CONS (strings
, 2);
4482 rawkey
= (KeySym
) ((unsigned) (XINT (keycode
))) & 255;
4483 for (i
= 0; i
<= 15; strings
= Fcdr (strings
), i
++)
4485 item
= Fcar (strings
);
4488 CHECK_STRING (item
, 2);
4489 strsize
= XSTRING (item
)->size
;
4490 rawstring
= (unsigned char *) xmalloc (strsize
);
4491 bcopy (XSTRING (item
)->data
, rawstring
, strsize
);
4492 modifier
[1] = 1 << i
;
4493 XRebindKeysym (x_current_display
, rawkey
, modifier
, 1,
4494 rawstring
, strsize
);
4499 #endif /* HAVE_X11 */
4502 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4504 XScreenNumberOfScreen (scr
)
4505 register Screen
*scr
;
4507 register Display
*dpy
;
4508 register Screen
*dpyscr
;
4512 dpyscr
= dpy
->screens
;
4514 for (i
= 0; i
< dpy
->nscreens
; i
++, dpyscr
++)
4520 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4523 select_visual (dpy
, screen
, depth
)
4526 unsigned int *depth
;
4529 XVisualInfo
*vinfo
, vinfo_template
;
4532 v
= DefaultVisualOfScreen (screen
);
4535 vinfo_template
.visualid
= XVisualIDFromVisual (v
);
4537 vinfo_template
.visualid
= v
->visualid
;
4540 vinfo_template
.screen
= XScreenNumberOfScreen (screen
);
4542 vinfo
= XGetVisualInfo (dpy
,
4543 VisualIDMask
| VisualScreenMask
, &vinfo_template
,
4546 fatal ("Can't get proper X visual info");
4548 if ((1 << vinfo
->depth
) == vinfo
->colormap_size
)
4549 *depth
= vinfo
->depth
;
4553 int n
= vinfo
->colormap_size
- 1;
4562 XFree ((char *) vinfo
);
4566 /* Return the X display structure for the display named NAME.
4567 Open a new connection if necessary. */
4569 struct x_display_info
*
4570 x_display_info_for_name (name
)
4574 struct x_display_info
*dpyinfo
;
4576 CHECK_STRING (name
, 0);
4578 for (dpyinfo
= x_display_list
, names
= x_display_name_list
;
4580 dpyinfo
= dpyinfo
->next
, names
= XCONS (names
)->cdr
)
4583 tem
= Fstring_equal (XCONS (XCONS (names
)->car
)->car
, name
);
4588 /* Use this general default value to start with. */
4589 Vx_resource_name
= Vinvocation_name
;
4591 validate_x_resource_name ();
4593 dpyinfo
= x_term_init (name
, (unsigned char *)0,
4594 (char *) XSTRING (Vx_resource_name
)->data
);
4597 error ("Cannot connect to X server %s", XSTRING (name
)->data
);
4600 XSETFASTINT (Vwindow_system_version
, 11);
4605 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
4606 1, 3, 0, "Open a connection to an X server.\n\
4607 DISPLAY is the name of the display to connect to.\n\
4608 Optional second arg XRM-STRING is a string of resources in xrdb format.\n\
4609 If the optional third arg MUST-SUCCEED is non-nil,\n\
4610 terminate Emacs if we can't open the connection.")
4611 (display
, xrm_string
, must_succeed
)
4612 Lisp_Object display
, xrm_string
, must_succeed
;
4614 unsigned int n_planes
;
4615 unsigned char *xrm_option
;
4616 struct x_display_info
*dpyinfo
;
4618 CHECK_STRING (display
, 0);
4619 if (! NILP (xrm_string
))
4620 CHECK_STRING (xrm_string
, 1);
4622 if (! NILP (xrm_string
))
4623 xrm_option
= (unsigned char *) XSTRING (xrm_string
)->data
;
4625 xrm_option
= (unsigned char *) 0;
4627 /* Use this general default value to start with. */
4628 Vx_resource_name
= Vinvocation_name
;
4630 validate_x_resource_name ();
4632 /* This is what opens the connection and sets x_current_display.
4633 This also initializes many symbols, such as those used for input. */
4634 dpyinfo
= x_term_init (display
, xrm_option
,
4635 (char *) XSTRING (Vx_resource_name
)->data
);
4639 if (!NILP (must_succeed
))
4640 fatal ("Cannot connect to X server %s.\n\
4641 Check the DISPLAY environment variable or use `-d'.\n\
4642 Also use the `xhost' program to verify that it is set to permit\n\
4643 connections from your machine.\n",
4644 XSTRING (display
)->data
);
4646 error ("Cannot connect to X server %s", XSTRING (display
)->data
);
4651 XSETFASTINT (Vwindow_system_version
, 11);
4655 DEFUN ("x-close-connection", Fx_close_connection
,
4656 Sx_close_connection
, 1, 1, 0,
4657 "Close the connection to DISPLAY's X server.\n\
4658 For DISPLAY, specify either a frame or a display name (a string).\n\
4659 If DISPLAY is nil, that stands for the selected frame's display.")
4661 Lisp_Object display
;
4663 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4664 struct x_display_info
*tail
;
4667 if (dpyinfo
->reference_count
> 0)
4668 error ("Display still has frames on it");
4671 /* Free the fonts in the font table. */
4672 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
4674 if (dpyinfo
->font_table
[i
].name
)
4675 free (dpyinfo
->font_table
[i
].name
);
4676 /* Don't free the full_name string;
4677 it is always shared with something else. */
4678 XFreeFont (dpyinfo
->display
, dpyinfo
->font_table
[i
].font
);
4680 x_destroy_all_bitmaps (dpyinfo
);
4681 XSetCloseDownMode (dpyinfo
->display
, DestroyAll
);
4683 #ifdef USE_X_TOOLKIT
4684 XtCloseDisplay (dpyinfo
->display
);
4686 XCloseDisplay (dpyinfo
->display
);
4689 x_delete_display (dpyinfo
);
4695 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
4696 "Return the list of display names that Emacs has connections to.")
4699 Lisp_Object tail
, result
;
4702 for (tail
= x_display_name_list
; ! NILP (tail
); tail
= XCONS (tail
)->cdr
)
4703 result
= Fcons (XCONS (XCONS (tail
)->car
)->car
, result
);
4708 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
4709 "If ON is non-nil, report X errors as soon as the erring request is made.\n\
4710 If ON is nil, allow buffering of requests.\n\
4711 Turning on synchronization prohibits the Xlib routines from buffering\n\
4712 requests and seriously degrades performance, but makes debugging much\n\
4714 The optional second argument DISPLAY specifies which display to act on.\n\
4715 DISPLAY should be either a frame or a display name (a string).\n\
4716 If DISPLAY is omitted or nil, that stands for the selected frame's display.")
4718 Lisp_Object display
, on
;
4720 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4722 XSynchronize (dpyinfo
->display
, !EQ (on
, Qnil
));
4727 /* Wait for responses to all X commands issued so far for frame F. */
4734 XSync (FRAME_X_DISPLAY (f
), False
);
4740 /* This is zero if not using X windows. */
4743 /* The section below is built by the lisp expression at the top of the file,
4744 just above where these variables are declared. */
4745 /*&&& init symbols here &&&*/
4746 Qauto_raise
= intern ("auto-raise");
4747 staticpro (&Qauto_raise
);
4748 Qauto_lower
= intern ("auto-lower");
4749 staticpro (&Qauto_lower
);
4750 Qbackground_color
= intern ("background-color");
4751 staticpro (&Qbackground_color
);
4752 Qbar
= intern ("bar");
4754 Qborder_color
= intern ("border-color");
4755 staticpro (&Qborder_color
);
4756 Qborder_width
= intern ("border-width");
4757 staticpro (&Qborder_width
);
4758 Qbox
= intern ("box");
4760 Qcursor_color
= intern ("cursor-color");
4761 staticpro (&Qcursor_color
);
4762 Qcursor_type
= intern ("cursor-type");
4763 staticpro (&Qcursor_type
);
4764 Qfont
= intern ("font");
4766 Qforeground_color
= intern ("foreground-color");
4767 staticpro (&Qforeground_color
);
4768 Qgeometry
= intern ("geometry");
4769 staticpro (&Qgeometry
);
4770 Qicon_left
= intern ("icon-left");
4771 staticpro (&Qicon_left
);
4772 Qicon_top
= intern ("icon-top");
4773 staticpro (&Qicon_top
);
4774 Qicon_type
= intern ("icon-type");
4775 staticpro (&Qicon_type
);
4776 Qinternal_border_width
= intern ("internal-border-width");
4777 staticpro (&Qinternal_border_width
);
4778 Qleft
= intern ("left");
4780 Qmouse_color
= intern ("mouse-color");
4781 staticpro (&Qmouse_color
);
4782 Qnone
= intern ("none");
4784 Qparent_id
= intern ("parent-id");
4785 staticpro (&Qparent_id
);
4786 Qscroll_bar_width
= intern ("scroll-bar-width");
4787 staticpro (&Qscroll_bar_width
);
4788 Qsuppress_icon
= intern ("suppress-icon");
4789 staticpro (&Qsuppress_icon
);
4790 Qtop
= intern ("top");
4792 Qundefined_color
= intern ("undefined-color");
4793 staticpro (&Qundefined_color
);
4794 Qvertical_scroll_bars
= intern ("vertical-scroll-bars");
4795 staticpro (&Qvertical_scroll_bars
);
4796 Qvisibility
= intern ("visibility");
4797 staticpro (&Qvisibility
);
4798 Qwindow_id
= intern ("window-id");
4799 staticpro (&Qwindow_id
);
4800 Qx_frame_parameter
= intern ("x-frame-parameter");
4801 staticpro (&Qx_frame_parameter
);
4802 Qx_resource_name
= intern ("x-resource-name");
4803 staticpro (&Qx_resource_name
);
4804 Quser_position
= intern ("user-position");
4805 staticpro (&Quser_position
);
4806 Quser_size
= intern ("user-size");
4807 staticpro (&Quser_size
);
4808 Qdisplay
= intern ("display");
4809 staticpro (&Qdisplay
);
4810 /* This is the end of symbol initialization. */
4812 Fput (Qundefined_color
, Qerror_conditions
,
4813 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
4814 Fput (Qundefined_color
, Qerror_message
,
4815 build_string ("Undefined color"));
4817 init_x_parm_symbols ();
4819 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path
,
4820 "List of directories to search for bitmap files for X.");
4821 Vx_bitmap_file_path
= decode_env_path ((char *) 0, PATH_BITMAPS
);
4823 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
4824 "The shape of the pointer when over text.\n\
4825 Changing the value does not affect existing frames\n\
4826 unless you set the mouse color.");
4827 Vx_pointer_shape
= Qnil
;
4829 DEFVAR_LISP ("x-resource-name", &Vx_resource_name
,
4830 "The name Emacs uses to look up X resources; for internal use only.\n\
4831 `x-get-resource' uses this as the first component of the instance name\n\
4832 when requesting resource values.\n\
4833 Emacs initially sets `x-resource-name' to the name under which Emacs\n\
4834 was invoked, or to the value specified with the `-name' or `-rn'\n\
4835 switches, if present.");
4836 Vx_resource_name
= Qnil
;
4838 #if 0 /* This doesn't really do anything. */
4839 DEFVAR_INT ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape
,
4840 "The shape of the pointer when not over text.\n\
4841 This variable takes effect when you create a new frame\n\
4842 or when you set the mouse color.");
4844 Vx_nontext_pointer_shape
= Qnil
;
4846 #if 0 /* This doesn't really do anything. */
4847 DEFVAR_INT ("x-mode-pointer-shape", &Vx_mode_pointer_shape
,
4848 "The shape of the pointer when over the mode line.\n\
4849 This variable takes effect when you create a new frame\n\
4850 or when you set the mouse color.");
4852 Vx_mode_pointer_shape
= Qnil
;
4854 DEFVAR_INT ("x-sensitive-text-pointer-shape",
4855 &Vx_sensitive_text_pointer_shape
,
4856 "The shape of the pointer when over mouse-sensitive text.\n\
4857 This variable takes effect when you create a new frame\n\
4858 or when you set the mouse color.");
4859 Vx_sensitive_text_pointer_shape
= Qnil
;
4861 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
4862 "A string indicating the foreground color of the cursor box.");
4863 Vx_cursor_fore_pixel
= Qnil
;
4865 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
4866 "Non-nil if no X window manager is in use.");
4868 #ifdef USE_X_TOOLKIT
4869 Fprovide (intern ("x-toolkit"));
4872 defsubr (&Sx_get_resource
);
4874 defsubr (&Sx_draw_rectangle
);
4875 defsubr (&Sx_erase_rectangle
);
4876 defsubr (&Sx_contour_region
);
4877 defsubr (&Sx_uncontour_region
);
4879 defsubr (&Sx_list_fonts
);
4880 defsubr (&Sx_display_color_p
);
4881 defsubr (&Sx_display_grayscale_p
);
4882 defsubr (&Sx_color_defined_p
);
4883 defsubr (&Sx_color_values
);
4884 defsubr (&Sx_server_max_request_size
);
4885 defsubr (&Sx_server_vendor
);
4886 defsubr (&Sx_server_version
);
4887 defsubr (&Sx_display_pixel_width
);
4888 defsubr (&Sx_display_pixel_height
);
4889 defsubr (&Sx_display_mm_width
);
4890 defsubr (&Sx_display_mm_height
);
4891 defsubr (&Sx_display_screens
);
4892 defsubr (&Sx_display_planes
);
4893 defsubr (&Sx_display_color_cells
);
4894 defsubr (&Sx_display_visual_class
);
4895 defsubr (&Sx_display_backing_store
);
4896 defsubr (&Sx_display_save_under
);
4898 defsubr (&Sx_rebind_key
);
4899 defsubr (&Sx_rebind_keys
);
4900 defsubr (&Sx_track_pointer
);
4901 defsubr (&Sx_grab_pointer
);
4902 defsubr (&Sx_ungrab_pointer
);
4904 defsubr (&Sx_parse_geometry
);
4905 defsubr (&Sx_create_frame
);
4906 defsubr (&Sfocus_frame
);
4907 defsubr (&Sunfocus_frame
);
4909 defsubr (&Sx_horizontal_line
);
4911 defsubr (&Sx_open_connection
);
4912 defsubr (&Sx_close_connection
);
4913 defsubr (&Sx_display_list
);
4914 defsubr (&Sx_synchronize
);
4917 #endif /* HAVE_X_WINDOWS */