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 Qicon_name
;
168 Lisp_Object Qinternal_border_width
;
170 Lisp_Object Qmouse_color
;
172 Lisp_Object Qparent_id
;
173 Lisp_Object Qscroll_bar_width
;
174 Lisp_Object Qsuppress_icon
;
176 Lisp_Object Qundefined_color
;
177 Lisp_Object Qvertical_scroll_bars
;
178 Lisp_Object Qvisibility
;
179 Lisp_Object Qwindow_id
;
180 Lisp_Object Qx_frame_parameter
;
181 Lisp_Object Qx_resource_name
;
182 Lisp_Object Quser_position
;
183 Lisp_Object Quser_size
;
184 Lisp_Object Qdisplay
;
186 /* The below are defined in frame.c. */
187 extern Lisp_Object Qheight
, Qminibuffer
, Qname
, Qonly
, Qwidth
;
188 extern Lisp_Object Qunsplittable
, Qmenu_bar_lines
;
190 extern Lisp_Object Vwindow_system_version
;
193 /* Error if we are not connected to X. */
198 error ("X windows are not in use or not initialized");
201 /* Nonzero if using X for display. */
209 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
210 and checking validity for X. */
213 check_x_frame (frame
)
222 CHECK_LIVE_FRAME (frame
, 0);
226 error ("non-X frame used");
230 /* Let the user specify an X display with a frame.
231 nil stands for the selected frame--or, if that is not an X frame,
232 the first X display on the list. */
234 static struct x_display_info
*
235 check_x_display_info (frame
)
240 if (FRAME_X_P (selected_frame
))
241 return FRAME_X_DISPLAY_INFO (selected_frame
);
242 else if (x_display_list
!= 0)
243 return x_display_list
;
245 error ("X windows are not in use or not initialized");
247 else if (STRINGP (frame
))
248 return x_display_info_for_name (frame
);
253 CHECK_LIVE_FRAME (frame
, 0);
256 error ("non-X frame used");
257 return FRAME_X_DISPLAY_INFO (f
);
261 /* Return the Emacs frame-object corresponding to an X window.
262 It could be the frame's main window or an icon window. */
264 /* This function can be called during GC, so use GC_xxx type test macros. */
267 x_window_to_frame (dpyinfo
, wdesc
)
268 struct x_display_info
*dpyinfo
;
271 Lisp_Object tail
, frame
;
274 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
276 frame
= XCONS (tail
)->car
;
277 if (!GC_FRAMEP (frame
))
280 if (f
->display
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
283 if ((f
->display
.x
->edit_widget
284 && XtWindow (f
->display
.x
->edit_widget
) == wdesc
)
285 || f
->display
.x
->icon_desc
== wdesc
)
287 #else /* not USE_X_TOOLKIT */
288 if (FRAME_X_WINDOW (f
) == wdesc
289 || f
->display
.x
->icon_desc
== wdesc
)
291 #endif /* not USE_X_TOOLKIT */
297 /* Like x_window_to_frame but also compares the window with the widget's
301 x_any_window_to_frame (dpyinfo
, wdesc
)
302 struct x_display_info
*dpyinfo
;
305 Lisp_Object tail
, frame
;
309 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
311 frame
= XCONS (tail
)->car
;
312 if (!GC_FRAMEP (frame
))
315 if (f
->display
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
318 /* This frame matches if the window is any of its widgets. */
319 if (wdesc
== XtWindow (x
->widget
)
320 || wdesc
== XtWindow (x
->column_widget
)
321 || wdesc
== XtWindow (x
->edit_widget
))
323 /* Match if the window is this frame's menubar. */
324 if (lw_window_is_in_menubar (wdesc
, x
->menubar_widget
))
330 /* Likewise, but exclude the menu bar widget. */
333 x_non_menubar_window_to_frame (dpyinfo
, wdesc
)
334 struct x_display_info
*dpyinfo
;
337 Lisp_Object tail
, frame
;
341 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
343 frame
= XCONS (tail
)->car
;
344 if (!GC_FRAMEP (frame
))
347 if (f
->display
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
350 /* This frame matches if the window is any of its widgets. */
351 if (wdesc
== XtWindow (x
->widget
)
352 || wdesc
== XtWindow (x
->column_widget
)
353 || wdesc
== XtWindow (x
->edit_widget
))
359 /* Return the frame whose principal (outermost) window is WDESC.
360 If WDESC is some other (smaller) window, we return 0. */
363 x_top_window_to_frame (dpyinfo
, wdesc
)
364 struct x_display_info
*dpyinfo
;
367 Lisp_Object tail
, frame
;
371 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
373 frame
= XCONS (tail
)->car
;
374 if (!GC_FRAMEP (frame
))
377 if (f
->display
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
380 /* This frame matches if the window is its topmost widget. */
381 if (wdesc
== XtWindow (x
->widget
))
383 #if 0 /* I don't know why it did this,
384 but it seems logically wrong,
385 and it causes trouble for MapNotify events. */
386 /* Match if the window is this frame's menubar. */
387 if (x
->menubar_widget
388 && wdesc
== XtWindow (x
->menubar_widget
))
394 #endif /* USE_X_TOOLKIT */
398 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
399 id, which is just an int that this section returns. Bitmaps are
400 reference counted so they can be shared among frames.
402 Bitmap indices are guaranteed to be > 0, so a negative number can
403 be used to indicate no bitmap.
405 If you use x_create_bitmap_from_data, then you must keep track of
406 the bitmaps yourself. That is, creating a bitmap from the same
407 data more than once will not be caught. */
410 /* Functions to access the contents of a bitmap, given an id. */
413 x_bitmap_height (f
, id
)
417 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].height
;
421 x_bitmap_width (f
, id
)
425 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].width
;
429 x_bitmap_pixmap (f
, id
)
433 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].pixmap
;
437 /* Allocate a new bitmap record. Returns index of new record. */
440 x_allocate_bitmap_record (f
)
443 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
446 if (dpyinfo
->bitmaps
== NULL
)
448 dpyinfo
->bitmaps_size
= 10;
450 = (struct x_bitmap_record
*) xmalloc (dpyinfo
->bitmaps_size
* sizeof (struct x_bitmap_record
));
451 dpyinfo
->bitmaps_last
= 1;
455 if (dpyinfo
->bitmaps_last
< dpyinfo
->bitmaps_size
)
456 return ++dpyinfo
->bitmaps_last
;
458 for (i
= 0; i
< dpyinfo
->bitmaps_size
; ++i
)
459 if (dpyinfo
->bitmaps
[i
].refcount
== 0)
462 dpyinfo
->bitmaps_size
*= 2;
464 = (struct x_bitmap_record
*) xrealloc (dpyinfo
->bitmaps
,
465 dpyinfo
->bitmaps_size
* sizeof (struct x_bitmap_record
));
466 return ++dpyinfo
->bitmaps_last
;
469 /* Add one reference to the reference count of the bitmap with id ID. */
472 x_reference_bitmap (f
, id
)
476 ++FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].refcount
;
479 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
482 x_create_bitmap_from_data (f
, bits
, width
, height
)
485 unsigned int width
, height
;
487 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
491 bitmap
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
492 bits
, width
, height
);
497 id
= x_allocate_bitmap_record (f
);
498 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
499 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
500 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
501 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
502 dpyinfo
->bitmaps
[id
- 1].height
= height
;
503 dpyinfo
->bitmaps
[id
- 1].width
= width
;
508 /* Create bitmap from file FILE for frame F. */
511 x_create_bitmap_from_file (f
, file
)
515 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
516 unsigned int width
, height
;
518 int xhot
, yhot
, result
, id
;
523 /* Look for an existing bitmap with the same name. */
524 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
526 if (dpyinfo
->bitmaps
[id
].refcount
527 && dpyinfo
->bitmaps
[id
].file
528 && !strcmp (dpyinfo
->bitmaps
[id
].file
, (char *) XSTRING (file
)->data
))
530 ++dpyinfo
->bitmaps
[id
].refcount
;
535 /* Search bitmap-file-path for the file, if appropriate. */
536 fd
= openp (Vx_bitmap_file_path
, file
, "", &found
, 0);
541 filename
= (char *) XSTRING (found
)->data
;
543 result
= XReadBitmapFile (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
544 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
545 if (result
!= BitmapSuccess
)
548 id
= x_allocate_bitmap_record (f
);
549 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
550 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
551 dpyinfo
->bitmaps
[id
- 1].file
= (char *) xmalloc (XSTRING (file
)->size
+ 1);
552 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
553 dpyinfo
->bitmaps
[id
- 1].height
= height
;
554 dpyinfo
->bitmaps
[id
- 1].width
= width
;
555 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, XSTRING (file
)->data
);
560 /* Remove reference to bitmap with id number ID. */
563 x_destroy_bitmap (f
, id
)
567 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
571 --dpyinfo
->bitmaps
[id
- 1].refcount
;
572 if (dpyinfo
->bitmaps
[id
- 1].refcount
== 0)
575 XFreePixmap (FRAME_X_DISPLAY (f
), dpyinfo
->bitmaps
[id
- 1].pixmap
);
576 if (dpyinfo
->bitmaps
[id
- 1].file
)
578 free (dpyinfo
->bitmaps
[id
- 1].file
);
579 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
586 /* Free all the bitmaps for the display specified by DPYINFO. */
589 x_destroy_all_bitmaps (dpyinfo
)
590 struct x_display_info
*dpyinfo
;
593 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++)
594 if (dpyinfo
->bitmaps
[i
].refcount
> 0)
596 XFreePixmap (dpyinfo
->display
, dpyinfo
->bitmaps
[i
].pixmap
);
597 if (dpyinfo
->bitmaps
[i
].file
)
598 free (dpyinfo
->bitmaps
[i
].file
);
600 dpyinfo
->bitmaps_last
= 0;
603 /* Connect the frame-parameter names for X frames
604 to the ways of passing the parameter values to the window system.
606 The name of a parameter, as a Lisp symbol,
607 has an `x-frame-parameter' property which is an integer in Lisp
608 but can be interpreted as an `enum x_frame_parm' in C. */
612 X_PARM_FOREGROUND_COLOR
,
613 X_PARM_BACKGROUND_COLOR
,
620 X_PARM_INTERNAL_BORDER_WIDTH
,
624 X_PARM_VERT_SCROLL_BAR
,
626 X_PARM_MENU_BAR_LINES
630 struct x_frame_parm_table
633 void (*setter
)( /* struct frame *frame, Lisp_Object val, oldval */ );
636 void x_set_foreground_color ();
637 void x_set_background_color ();
638 void x_set_mouse_color ();
639 void x_set_cursor_color ();
640 void x_set_border_color ();
641 void x_set_cursor_type ();
642 void x_set_icon_type ();
643 void x_set_icon_name ();
645 void x_set_border_width ();
646 void x_set_internal_border_width ();
647 void x_explicitly_set_name ();
648 void x_set_autoraise ();
649 void x_set_autolower ();
650 void x_set_vertical_scroll_bars ();
651 void x_set_visibility ();
652 void x_set_menu_bar_lines ();
653 void x_set_scroll_bar_width ();
654 void x_set_unsplittable ();
656 static struct x_frame_parm_table x_frame_parms
[] =
658 "foreground-color", x_set_foreground_color
,
659 "background-color", x_set_background_color
,
660 "mouse-color", x_set_mouse_color
,
661 "cursor-color", x_set_cursor_color
,
662 "border-color", x_set_border_color
,
663 "cursor-type", x_set_cursor_type
,
664 "icon-type", x_set_icon_type
,
665 "icon-name", x_set_icon_name
,
667 "border-width", x_set_border_width
,
668 "internal-border-width", x_set_internal_border_width
,
669 "name", x_explicitly_set_name
,
670 "auto-raise", x_set_autoraise
,
671 "auto-lower", x_set_autolower
,
672 "vertical-scroll-bars", x_set_vertical_scroll_bars
,
673 "visibility", x_set_visibility
,
674 "menu-bar-lines", x_set_menu_bar_lines
,
675 "scroll-bar-width", x_set_scroll_bar_width
,
676 "unsplittable", x_set_unsplittable
,
679 /* Attach the `x-frame-parameter' properties to
680 the Lisp symbol names of parameters relevant to X. */
682 init_x_parm_symbols ()
686 for (i
= 0; i
< sizeof (x_frame_parms
) / sizeof (x_frame_parms
[0]); i
++)
687 Fput (intern (x_frame_parms
[i
].name
), Qx_frame_parameter
,
691 /* Change the parameters of FRAME as specified by ALIST.
692 If a parameter is not specially recognized, do nothing;
693 otherwise call the `x_set_...' function for that parameter. */
696 x_set_frame_parameters (f
, alist
)
702 /* If both of these parameters are present, it's more efficient to
703 set them both at once. So we wait until we've looked at the
704 entire list before we set them. */
705 Lisp_Object width
, height
;
708 Lisp_Object left
, top
;
710 /* Same with these. */
711 Lisp_Object icon_left
, icon_top
;
713 /* Record in these vectors all the parms specified. */
717 int left_no_change
= 0, top_no_change
= 0;
718 int icon_left_no_change
= 0, icon_top_no_change
= 0;
721 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
724 parms
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
725 values
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
727 /* Extract parm names and values into those vectors. */
730 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
732 Lisp_Object elt
, prop
, val
;
735 parms
[i
] = Fcar (elt
);
736 values
[i
] = Fcdr (elt
);
740 width
= height
= top
= left
= Qunbound
;
741 icon_left
= icon_top
= Qunbound
;
743 /* Now process them in reverse of specified order. */
744 for (i
--; i
>= 0; i
--)
746 Lisp_Object prop
, val
;
751 if (EQ (prop
, Qwidth
))
753 else if (EQ (prop
, Qheight
))
755 else if (EQ (prop
, Qtop
))
757 else if (EQ (prop
, Qleft
))
759 else if (EQ (prop
, Qicon_top
))
761 else if (EQ (prop
, Qicon_left
))
765 register Lisp_Object param_index
, old_value
;
767 param_index
= Fget (prop
, Qx_frame_parameter
);
768 old_value
= get_frame_param (f
, prop
);
769 store_frame_param (f
, prop
, val
);
770 if (NATNUMP (param_index
)
771 && (XFASTINT (param_index
)
772 < sizeof (x_frame_parms
)/sizeof (x_frame_parms
[0])))
773 (*x_frame_parms
[XINT (param_index
)].setter
)(f
, val
, old_value
);
777 /* Don't die if just one of these was set. */
778 if (EQ (left
, Qunbound
))
781 if (f
->display
.x
->left_pos
< 0)
782 left
= Fcons (Qplus
, Fcons (make_number (f
->display
.x
->left_pos
), Qnil
));
784 XSETINT (left
, f
->display
.x
->left_pos
);
786 if (EQ (top
, Qunbound
))
789 if (f
->display
.x
->top_pos
< 0)
790 top
= Fcons (Qplus
, Fcons (make_number (f
->display
.x
->top_pos
), Qnil
));
792 XSETINT (top
, f
->display
.x
->top_pos
);
795 /* If one of the icon positions was not set, preserve or default it. */
796 if (EQ (icon_left
, Qunbound
) || ! INTEGERP (icon_left
))
798 icon_left_no_change
= 1;
799 icon_left
= Fcdr (Fassq (Qicon_left
, f
->param_alist
));
800 if (NILP (icon_left
))
801 XSETINT (icon_left
, 0);
803 if (EQ (icon_top
, Qunbound
) || ! INTEGERP (icon_top
))
805 icon_top_no_change
= 1;
806 icon_top
= Fcdr (Fassq (Qicon_top
, f
->param_alist
));
808 XSETINT (icon_top
, 0);
811 /* Don't die if just one of these was set. */
812 if (EQ (width
, Qunbound
))
813 XSETINT (width
, FRAME_WIDTH (f
));
814 if (EQ (height
, Qunbound
))
815 XSETINT (height
, FRAME_HEIGHT (f
));
817 /* Don't set these parameters unless they've been explicitly
818 specified. The window might be mapped or resized while we're in
819 this function, and we don't want to override that unless the lisp
820 code has asked for it.
822 Don't set these parameters unless they actually differ from the
823 window's current parameters; the window may not actually exist
828 check_frame_size (f
, &height
, &width
);
830 XSETFRAME (frame
, f
);
832 if ((NUMBERP (width
) && XINT (width
) != FRAME_WIDTH (f
))
833 || (NUMBERP (height
) && XINT (height
) != FRAME_HEIGHT (f
)))
834 Fset_frame_size (frame
, width
, height
);
836 if ((!NILP (left
) || !NILP (top
))
837 && ! (left_no_change
&& top_no_change
)
838 && ! (NUMBERP (left
) && XINT (left
) == f
->display
.x
->left_pos
839 && NUMBERP (top
) && XINT (top
) == f
->display
.x
->top_pos
))
844 /* Record the signs. */
845 f
->display
.x
->size_hint_flags
&= ~ (XNegative
| YNegative
);
846 if (EQ (left
, Qminus
))
847 f
->display
.x
->size_hint_flags
|= XNegative
;
848 else if (INTEGERP (left
))
850 leftpos
= XINT (left
);
852 f
->display
.x
->size_hint_flags
|= XNegative
;
854 else if (CONSP (left
) && EQ (XCONS (left
)->car
, Qminus
)
855 && CONSP (XCONS (left
)->cdr
)
856 && INTEGERP (XCONS (XCONS (left
)->cdr
)->car
))
858 leftpos
= - XINT (XCONS (XCONS (left
)->cdr
)->car
);
859 f
->display
.x
->size_hint_flags
|= XNegative
;
861 else if (CONSP (left
) && EQ (XCONS (left
)->car
, Qplus
)
862 && CONSP (XCONS (left
)->cdr
)
863 && INTEGERP (XCONS (XCONS (left
)->cdr
)->car
))
865 leftpos
= XINT (XCONS (XCONS (left
)->cdr
)->car
);
868 if (EQ (top
, Qminus
))
869 f
->display
.x
->size_hint_flags
|= YNegative
;
870 else if (INTEGERP (top
))
874 f
->display
.x
->size_hint_flags
|= YNegative
;
876 else if (CONSP (top
) && EQ (XCONS (top
)->car
, Qminus
)
877 && CONSP (XCONS (top
)->cdr
)
878 && INTEGERP (XCONS (XCONS (top
)->cdr
)->car
))
880 toppos
= - XINT (XCONS (XCONS (top
)->cdr
)->car
);
881 f
->display
.x
->size_hint_flags
|= YNegative
;
883 else if (CONSP (top
) && EQ (XCONS (top
)->car
, Qplus
)
884 && CONSP (XCONS (top
)->cdr
)
885 && INTEGERP (XCONS (XCONS (top
)->cdr
)->car
))
887 toppos
= XINT (XCONS (XCONS (top
)->cdr
)->car
);
891 /* Store the numeric value of the position. */
892 f
->display
.x
->top_pos
= toppos
;
893 f
->display
.x
->left_pos
= leftpos
;
895 f
->display
.x
->win_gravity
= NorthWestGravity
;
897 /* Actually set that position, and convert to absolute. */
898 x_set_offset (f
, leftpos
, toppos
, -1);
901 if ((!NILP (icon_left
) || !NILP (icon_top
))
902 && ! (icon_left_no_change
&& icon_top_no_change
))
903 x_wm_set_icon_position (f
, XINT (icon_left
), XINT (icon_top
));
907 /* Store the screen positions of frame F into XPTR and YPTR.
908 These are the positions of the containing window manager window,
909 not Emacs's own window. */
912 x_real_positions (f
, xptr
, yptr
)
919 /* This is pretty gross, but seems to be the easiest way out of
920 the problem that arises when restarting window-managers. */
923 Window outer
= XtWindow (f
->display
.x
->widget
);
925 Window outer
= f
->display
.x
->window_desc
;
927 Window tmp_root_window
;
928 Window
*tmp_children
;
933 x_catch_errors (FRAME_X_DISPLAY (f
));
935 XQueryTree (FRAME_X_DISPLAY (f
), outer
, &tmp_root_window
,
936 &f
->display
.x
->parent_desc
,
937 &tmp_children
, &tmp_nchildren
);
938 xfree (tmp_children
);
942 /* Find the position of the outside upper-left corner of
943 the inner window, with respect to the outer window. */
944 if (f
->display
.x
->parent_desc
!= FRAME_X_DISPLAY_INFO (f
)->root_window
)
946 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
948 /* From-window, to-window. */
950 XtWindow (f
->display
.x
->widget
),
952 f
->display
.x
->window_desc
,
954 f
->display
.x
->parent_desc
,
956 /* From-position, to-position. */
957 0, 0, &win_x
, &win_y
,
962 #if 0 /* The values seem to be right without this and wrong with. */
963 win_x
+= f
->display
.x
->border_width
;
964 win_y
+= f
->display
.x
->border_width
;
968 /* It is possible for the window returned by the XQueryNotify
969 to become invalid by the time we call XTranslateCoordinates.
970 That can happen when you restart some window managers.
971 If so, we get an error in XTranslateCoordinates.
972 Detect that and try the whole thing over. */
973 if (! x_had_errors_p (FRAME_X_DISPLAY (f
)))
976 x_uncatch_errors (FRAME_X_DISPLAY (f
));
979 x_uncatch_errors (FRAME_X_DISPLAY (f
));
981 *xptr
= f
->display
.x
->left_pos
- win_x
;
982 *yptr
= f
->display
.x
->top_pos
- win_y
;
985 /* Insert a description of internally-recorded parameters of frame X
986 into the parameter alist *ALISTPTR that is to be given to the user.
987 Only parameters that are specific to the X window system
988 and whose values are not correctly recorded in the frame's
989 param_alist need to be considered here. */
991 x_report_frame_params (f
, alistptr
)
993 Lisp_Object
*alistptr
;
998 /* Represent negative positions (off the top or left screen edge)
999 in a way that Fmodify_frame_parameters will understand correctly. */
1000 XSETINT (tem
, f
->display
.x
->left_pos
);
1001 if (f
->display
.x
->left_pos
>= 0)
1002 store_in_alist (alistptr
, Qleft
, tem
);
1004 store_in_alist (alistptr
, Qleft
, Fcons (Qplus
, Fcons (tem
, Qnil
)));
1006 XSETINT (tem
, f
->display
.x
->top_pos
);
1007 if (f
->display
.x
->top_pos
>= 0)
1008 store_in_alist (alistptr
, Qtop
, tem
);
1010 store_in_alist (alistptr
, Qtop
, Fcons (Qplus
, Fcons (tem
, Qnil
)));
1012 store_in_alist (alistptr
, Qborder_width
,
1013 make_number (f
->display
.x
->border_width
));
1014 store_in_alist (alistptr
, Qinternal_border_width
,
1015 make_number (f
->display
.x
->internal_border_width
));
1016 sprintf (buf
, "%ld", (long) FRAME_X_WINDOW (f
));
1017 store_in_alist (alistptr
, Qwindow_id
,
1018 build_string (buf
));
1019 store_in_alist (alistptr
, Qicon_name
, f
->display
.x
->icon_name
);
1020 FRAME_SAMPLE_VISIBILITY (f
);
1021 store_in_alist (alistptr
, Qvisibility
,
1022 (FRAME_VISIBLE_P (f
) ? Qt
1023 : FRAME_ICONIFIED_P (f
) ? Qicon
: Qnil
));
1024 store_in_alist (alistptr
, Qdisplay
,
1025 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->car
);
1029 /* Decide if color named COLOR is valid for the display associated with
1030 the selected frame; if so, return the rgb values in COLOR_DEF.
1031 If ALLOC is nonzero, allocate a new colormap cell. */
1034 defined_color (f
, color
, color_def
, alloc
)
1040 register int status
;
1041 Colormap screen_colormap
;
1042 Display
*display
= FRAME_X_DISPLAY (f
);
1045 screen_colormap
= DefaultColormap (display
, XDefaultScreen (display
));
1047 status
= XParseColor (display
, screen_colormap
, color
, color_def
);
1048 if (status
&& alloc
)
1050 status
= XAllocColor (display
, screen_colormap
, color_def
);
1053 /* If we got to this point, the colormap is full, so we're
1054 going to try and get the next closest color.
1055 The algorithm used is a least-squares matching, which is
1056 what X uses for closest color matching with StaticColor visuals. */
1061 long nearest_delta
, trial_delta
;
1064 no_cells
= XDisplayCells (display
, XDefaultScreen (display
));
1065 cells
= (XColor
*) alloca (sizeof (XColor
) * no_cells
);
1067 for (x
= 0; x
< no_cells
; x
++)
1070 XQueryColors (display
, screen_colormap
, cells
, no_cells
);
1072 /* I'm assuming CSE so I'm not going to condense this. */
1073 nearest_delta
= ((((color_def
->red
>> 8) - (cells
[0].red
>> 8))
1074 * ((color_def
->red
>> 8) - (cells
[0].red
>> 8)))
1076 (((color_def
->green
>> 8) - (cells
[0].green
>> 8))
1077 * ((color_def
->green
>> 8) - (cells
[0].green
>> 8)))
1079 (((color_def
->blue
>> 8) - (cells
[0].blue
>> 8))
1080 * ((color_def
->blue
>> 8) - (cells
[0].blue
>> 8))));
1081 for (x
= 1; x
< no_cells
; x
++)
1083 trial_delta
= ((((color_def
->red
>> 8) - (cells
[x
].red
>> 8))
1084 * ((color_def
->red
>> 8) - (cells
[x
].red
>> 8)))
1086 (((color_def
->green
>> 8) - (cells
[x
].green
>> 8))
1087 * ((color_def
->green
>> 8) - (cells
[x
].green
>> 8)))
1089 (((color_def
->blue
>> 8) - (cells
[x
].blue
>> 8))
1090 * ((color_def
->blue
>> 8) - (cells
[x
].blue
>> 8))));
1091 if (trial_delta
< nearest_delta
)
1094 nearest_delta
= trial_delta
;
1097 color_def
->red
= cells
[nearest
].red
;
1098 color_def
->green
= cells
[nearest
].green
;
1099 color_def
->blue
= cells
[nearest
].blue
;
1100 status
= XAllocColor (display
, screen_colormap
, color_def
);
1111 /* Given a string ARG naming a color, compute a pixel value from it
1112 suitable for screen F.
1113 If F is not a color screen, return DEF (default) regardless of what
1117 x_decode_color (f
, arg
, def
)
1124 CHECK_STRING (arg
, 0);
1126 if (strcmp (XSTRING (arg
)->data
, "black") == 0)
1127 return BLACK_PIX_DEFAULT (f
);
1128 else if (strcmp (XSTRING (arg
)->data
, "white") == 0)
1129 return WHITE_PIX_DEFAULT (f
);
1131 if (FRAME_X_DISPLAY_INFO (f
)->n_planes
== 1)
1134 /* defined_color is responsible for coping with failures
1135 by looking for a near-miss. */
1136 if (defined_color (f
, XSTRING (arg
)->data
, &cdef
, 1))
1139 /* defined_color failed; return an ultimate default. */
1143 /* Functions called only from `x_set_frame_param'
1144 to set individual parameters.
1146 If FRAME_X_WINDOW (f) is 0,
1147 the frame is being created and its X-window does not exist yet.
1148 In that case, just record the parameter's new value
1149 in the standard place; do not attempt to change the window. */
1152 x_set_foreground_color (f
, arg
, oldval
)
1154 Lisp_Object arg
, oldval
;
1156 f
->display
.x
->foreground_pixel
1157 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1158 if (FRAME_X_WINDOW (f
) != 0)
1161 XSetForeground (FRAME_X_DISPLAY (f
), f
->display
.x
->normal_gc
,
1162 f
->display
.x
->foreground_pixel
);
1163 XSetBackground (FRAME_X_DISPLAY (f
), f
->display
.x
->reverse_gc
,
1164 f
->display
.x
->foreground_pixel
);
1166 recompute_basic_faces (f
);
1167 if (FRAME_VISIBLE_P (f
))
1173 x_set_background_color (f
, arg
, oldval
)
1175 Lisp_Object arg
, oldval
;
1180 f
->display
.x
->background_pixel
1181 = x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
1183 if (FRAME_X_WINDOW (f
) != 0)
1186 /* The main frame area. */
1187 XSetBackground (FRAME_X_DISPLAY (f
), f
->display
.x
->normal_gc
,
1188 f
->display
.x
->background_pixel
);
1189 XSetForeground (FRAME_X_DISPLAY (f
), f
->display
.x
->reverse_gc
,
1190 f
->display
.x
->background_pixel
);
1191 XSetForeground (FRAME_X_DISPLAY (f
), f
->display
.x
->cursor_gc
,
1192 f
->display
.x
->background_pixel
);
1193 XSetWindowBackground (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1194 f
->display
.x
->background_pixel
);
1197 for (bar
= FRAME_SCROLL_BARS (f
); !NILP (bar
);
1198 bar
= XSCROLL_BAR (bar
)->next
)
1199 XSetWindowBackground (FRAME_X_DISPLAY (f
),
1200 SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
)),
1201 f
->display
.x
->background_pixel
);
1205 recompute_basic_faces (f
);
1207 if (FRAME_VISIBLE_P (f
))
1213 x_set_mouse_color (f
, arg
, oldval
)
1215 Lisp_Object arg
, oldval
;
1217 Cursor cursor
, nontext_cursor
, mode_cursor
, cross_cursor
;
1220 if (!EQ (Qnil
, arg
))
1221 f
->display
.x
->mouse_pixel
1222 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1223 mask_color
= f
->display
.x
->background_pixel
;
1224 /* No invisible pointers. */
1225 if (mask_color
== f
->display
.x
->mouse_pixel
1226 && mask_color
== f
->display
.x
->background_pixel
)
1227 f
->display
.x
->mouse_pixel
= f
->display
.x
->foreground_pixel
;
1231 /* It's not okay to crash if the user selects a screwy cursor. */
1232 x_catch_errors (FRAME_X_DISPLAY (f
));
1234 if (!EQ (Qnil
, Vx_pointer_shape
))
1236 CHECK_NUMBER (Vx_pointer_shape
, 0);
1237 cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XINT (Vx_pointer_shape
));
1240 cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_xterm
);
1241 x_check_errors (FRAME_X_DISPLAY (f
), "bad text pointer cursor: %s");
1243 if (!EQ (Qnil
, Vx_nontext_pointer_shape
))
1245 CHECK_NUMBER (Vx_nontext_pointer_shape
, 0);
1246 nontext_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
),
1247 XINT (Vx_nontext_pointer_shape
));
1250 nontext_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_left_ptr
);
1251 x_check_errors (FRAME_X_DISPLAY (f
), "bad nontext pointer cursor: %s");
1253 if (!EQ (Qnil
, Vx_mode_pointer_shape
))
1255 CHECK_NUMBER (Vx_mode_pointer_shape
, 0);
1256 mode_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
),
1257 XINT (Vx_mode_pointer_shape
));
1260 mode_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_xterm
);
1261 x_check_errors (FRAME_X_DISPLAY (f
), "bad modeline pointer cursor: %s");
1263 if (!EQ (Qnil
, Vx_sensitive_text_pointer_shape
))
1265 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
, 0);
1267 = XCreateFontCursor (FRAME_X_DISPLAY (f
),
1268 XINT (Vx_sensitive_text_pointer_shape
));
1271 cross_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_crosshair
);
1273 /* Check and report errors with the above calls. */
1274 x_check_errors (FRAME_X_DISPLAY (f
), "can't set cursor shape: %s");
1275 x_uncatch_errors (FRAME_X_DISPLAY (f
));
1278 XColor fore_color
, back_color
;
1280 fore_color
.pixel
= f
->display
.x
->mouse_pixel
;
1281 back_color
.pixel
= mask_color
;
1282 XQueryColor (FRAME_X_DISPLAY (f
),
1283 DefaultColormap (FRAME_X_DISPLAY (f
),
1284 DefaultScreen (FRAME_X_DISPLAY (f
))),
1286 XQueryColor (FRAME_X_DISPLAY (f
),
1287 DefaultColormap (FRAME_X_DISPLAY (f
),
1288 DefaultScreen (FRAME_X_DISPLAY (f
))),
1290 XRecolorCursor (FRAME_X_DISPLAY (f
), cursor
,
1291 &fore_color
, &back_color
);
1292 XRecolorCursor (FRAME_X_DISPLAY (f
), nontext_cursor
,
1293 &fore_color
, &back_color
);
1294 XRecolorCursor (FRAME_X_DISPLAY (f
), mode_cursor
,
1295 &fore_color
, &back_color
);
1296 XRecolorCursor (FRAME_X_DISPLAY (f
), cross_cursor
,
1297 &fore_color
, &back_color
);
1300 if (FRAME_X_WINDOW (f
) != 0)
1302 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
1305 if (cursor
!= f
->display
.x
->text_cursor
&& f
->display
.x
->text_cursor
!= 0)
1306 XFreeCursor (FRAME_X_DISPLAY (f
), f
->display
.x
->text_cursor
);
1307 f
->display
.x
->text_cursor
= cursor
;
1309 if (nontext_cursor
!= f
->display
.x
->nontext_cursor
1310 && f
->display
.x
->nontext_cursor
!= 0)
1311 XFreeCursor (FRAME_X_DISPLAY (f
), f
->display
.x
->nontext_cursor
);
1312 f
->display
.x
->nontext_cursor
= nontext_cursor
;
1314 if (mode_cursor
!= f
->display
.x
->modeline_cursor
1315 && f
->display
.x
->modeline_cursor
!= 0)
1316 XFreeCursor (FRAME_X_DISPLAY (f
), f
->display
.x
->modeline_cursor
);
1317 f
->display
.x
->modeline_cursor
= mode_cursor
;
1318 if (cross_cursor
!= f
->display
.x
->cross_cursor
1319 && f
->display
.x
->cross_cursor
!= 0)
1320 XFreeCursor (FRAME_X_DISPLAY (f
), f
->display
.x
->cross_cursor
);
1321 f
->display
.x
->cross_cursor
= cross_cursor
;
1323 XFlush (FRAME_X_DISPLAY (f
));
1328 x_set_cursor_color (f
, arg
, oldval
)
1330 Lisp_Object arg
, oldval
;
1332 unsigned long fore_pixel
;
1334 if (!EQ (Vx_cursor_fore_pixel
, Qnil
))
1335 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
1336 WHITE_PIX_DEFAULT (f
));
1338 fore_pixel
= f
->display
.x
->background_pixel
;
1339 f
->display
.x
->cursor_pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1341 /* Make sure that the cursor color differs from the background color. */
1342 if (f
->display
.x
->cursor_pixel
== f
->display
.x
->background_pixel
)
1344 f
->display
.x
->cursor_pixel
= f
->display
.x
->mouse_pixel
;
1345 if (f
->display
.x
->cursor_pixel
== fore_pixel
)
1346 fore_pixel
= f
->display
.x
->background_pixel
;
1348 f
->display
.x
->cursor_foreground_pixel
= fore_pixel
;
1350 if (FRAME_X_WINDOW (f
) != 0)
1353 XSetBackground (FRAME_X_DISPLAY (f
), f
->display
.x
->cursor_gc
,
1354 f
->display
.x
->cursor_pixel
);
1355 XSetForeground (FRAME_X_DISPLAY (f
), f
->display
.x
->cursor_gc
,
1359 if (FRAME_VISIBLE_P (f
))
1361 x_display_cursor (f
, 0);
1362 x_display_cursor (f
, 1);
1367 /* Set the border-color of frame F to value described by ARG.
1368 ARG can be a string naming a color.
1369 The border-color is used for the border that is drawn by the X server.
1370 Note that this does not fully take effect if done before
1371 F has an x-window; it must be redone when the window is created.
1373 Note: this is done in two routines because of the way X10 works.
1375 Note: under X11, this is normally the province of the window manager,
1376 and so emacs' border colors may be overridden. */
1379 x_set_border_color (f
, arg
, oldval
)
1381 Lisp_Object arg
, oldval
;
1386 CHECK_STRING (arg
, 0);
1387 str
= XSTRING (arg
)->data
;
1389 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1391 x_set_border_pixel (f
, pix
);
1394 /* Set the border-color of frame F to pixel value PIX.
1395 Note that this does not fully take effect if done before
1396 F has an x-window. */
1398 x_set_border_pixel (f
, pix
)
1402 f
->display
.x
->border_pixel
= pix
;
1404 if (FRAME_X_WINDOW (f
) != 0 && f
->display
.x
->border_width
> 0)
1410 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1411 (unsigned long)pix
);
1414 if (FRAME_VISIBLE_P (f
))
1420 x_set_cursor_type (f
, arg
, oldval
)
1422 Lisp_Object arg
, oldval
;
1426 FRAME_DESIRED_CURSOR (f
) = bar_cursor
;
1427 f
->display
.x
->cursor_width
= 2;
1429 else if (CONSP (arg
) && EQ (XCONS (arg
)->car
, Qbar
)
1430 && INTEGERP (XCONS (arg
)->cdr
))
1432 FRAME_DESIRED_CURSOR (f
) = bar_cursor
;
1433 f
->display
.x
->cursor_width
= XINT (XCONS (arg
)->cdr
);
1436 /* Treat anything unknown as "box cursor".
1437 It was bad to signal an error; people have trouble fixing
1438 .Xdefaults with Emacs, when it has something bad in it. */
1439 FRAME_DESIRED_CURSOR (f
) = filled_box_cursor
;
1441 /* Make sure the cursor gets redrawn. This is overkill, but how
1442 often do people change cursor types? */
1443 update_mode_lines
++;
1447 x_set_icon_type (f
, arg
, oldval
)
1449 Lisp_Object arg
, oldval
;
1456 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1459 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1464 result
= x_text_icon (f
,
1465 (char *) XSTRING ((!NILP (f
->display
.x
->icon_name
)
1466 ? f
->display
.x
->icon_name
1469 result
= x_bitmap_icon (f
, arg
);
1474 error ("No icon window available");
1477 /* If the window was unmapped (and its icon was mapped),
1478 the new icon is not mapped, so map the window in its stead. */
1479 if (FRAME_VISIBLE_P (f
))
1481 #ifdef USE_X_TOOLKIT
1482 XtPopup (f
->display
.x
->widget
, XtGrabNone
);
1484 XMapWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
1487 XFlush (FRAME_X_DISPLAY (f
));
1491 /* Return non-nil if frame F wants a bitmap icon. */
1499 tem
= assq_no_quit (Qicon_type
, f
->param_alist
);
1501 return XCONS (tem
)->cdr
;
1507 x_set_icon_name (f
, arg
, oldval
)
1509 Lisp_Object arg
, oldval
;
1516 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1519 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1522 f
->display
.x
->icon_name
= arg
;
1524 if (f
->display
.x
->icon_bitmap
!= 0)
1529 result
= x_text_icon (f
,
1530 (char *) XSTRING ((!NILP (f
->display
.x
->icon_name
)
1531 ? f
->display
.x
->icon_name
1537 error ("No icon window available");
1540 /* If the window was unmapped (and its icon was mapped),
1541 the new icon is not mapped, so map the window in its stead. */
1542 if (FRAME_VISIBLE_P (f
))
1544 #ifdef USE_X_TOOLKIT
1545 XtPopup (f
->display
.x
->widget
, XtGrabNone
);
1547 XMapWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
1550 XFlush (FRAME_X_DISPLAY (f
));
1554 extern Lisp_Object
x_new_font ();
1557 x_set_font (f
, arg
, oldval
)
1559 Lisp_Object arg
, oldval
;
1563 CHECK_STRING (arg
, 1);
1566 result
= x_new_font (f
, XSTRING (arg
)->data
);
1569 if (EQ (result
, Qnil
))
1570 error ("Font \"%s\" is not defined", XSTRING (arg
)->data
);
1571 else if (EQ (result
, Qt
))
1572 error ("the characters of the given font have varying widths");
1573 else if (STRINGP (result
))
1575 recompute_basic_faces (f
);
1576 store_frame_param (f
, Qfont
, result
);
1583 x_set_border_width (f
, arg
, oldval
)
1585 Lisp_Object arg
, oldval
;
1587 CHECK_NUMBER (arg
, 0);
1589 if (XINT (arg
) == f
->display
.x
->border_width
)
1592 if (FRAME_X_WINDOW (f
) != 0)
1593 error ("Cannot change the border width of a window");
1595 f
->display
.x
->border_width
= XINT (arg
);
1599 x_set_internal_border_width (f
, arg
, oldval
)
1601 Lisp_Object arg
, oldval
;
1604 int old
= f
->display
.x
->internal_border_width
;
1606 CHECK_NUMBER (arg
, 0);
1607 f
->display
.x
->internal_border_width
= XINT (arg
);
1608 if (f
->display
.x
->internal_border_width
< 0)
1609 f
->display
.x
->internal_border_width
= 0;
1611 if (f
->display
.x
->internal_border_width
== old
)
1614 if (FRAME_X_WINDOW (f
) != 0)
1617 x_set_window_size (f
, 0, f
->width
, f
->height
);
1619 x_set_resize_hint (f
);
1621 XFlush (FRAME_X_DISPLAY (f
));
1623 SET_FRAME_GARBAGED (f
);
1628 x_set_visibility (f
, value
, oldval
)
1630 Lisp_Object value
, oldval
;
1633 XSETFRAME (frame
, f
);
1636 Fmake_frame_invisible (frame
, Qt
);
1637 else if (EQ (value
, Qicon
))
1638 Ficonify_frame (frame
);
1640 Fmake_frame_visible (frame
);
1644 x_set_menu_bar_lines_1 (window
, n
)
1648 struct window
*w
= XWINDOW (window
);
1650 XSETFASTINT (w
->top
, XFASTINT (w
->top
) + n
);
1651 XSETFASTINT (w
->height
, XFASTINT (w
->height
) - n
);
1653 /* Handle just the top child in a vertical split. */
1654 if (!NILP (w
->vchild
))
1655 x_set_menu_bar_lines_1 (w
->vchild
, n
);
1657 /* Adjust all children in a horizontal split. */
1658 for (window
= w
->hchild
; !NILP (window
); window
= w
->next
)
1660 w
= XWINDOW (window
);
1661 x_set_menu_bar_lines_1 (window
, n
);
1666 x_set_menu_bar_lines (f
, value
, oldval
)
1668 Lisp_Object value
, oldval
;
1671 int olines
= FRAME_MENU_BAR_LINES (f
);
1673 /* Right now, menu bars don't work properly in minibuf-only frames;
1674 most of the commands try to apply themselves to the minibuffer
1675 frame itslef, and get an error because you can't switch buffers
1676 in or split the minibuffer window. */
1677 if (FRAME_MINIBUF_ONLY_P (f
))
1680 if (INTEGERP (value
))
1681 nlines
= XINT (value
);
1685 #ifdef USE_X_TOOLKIT
1686 FRAME_MENU_BAR_LINES (f
) = 0;
1688 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
1691 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
1692 free_frame_menubar (f
);
1693 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
1694 f
->display
.x
->menubar_widget
= 0;
1696 #else /* not USE_X_TOOLKIT */
1697 FRAME_MENU_BAR_LINES (f
) = nlines
;
1698 x_set_menu_bar_lines_1 (f
->root_window
, nlines
- olines
);
1699 #endif /* not USE_X_TOOLKIT */
1702 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1705 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1706 name; if NAME is a string, set F's name to NAME and set
1707 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1709 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1710 suggesting a new name, which lisp code should override; if
1711 F->explicit_name is set, ignore the new name; otherwise, set it. */
1714 x_set_name (f
, name
, explicit)
1719 /* Make sure that requests from lisp code override requests from
1720 Emacs redisplay code. */
1723 /* If we're switching from explicit to implicit, we had better
1724 update the mode lines and thereby update the title. */
1725 if (f
->explicit_name
&& NILP (name
))
1726 update_mode_lines
= 1;
1728 f
->explicit_name
= ! NILP (name
);
1730 else if (f
->explicit_name
)
1733 /* If NAME is nil, set the name to the x_id_name. */
1736 /* Check for no change needed in this very common case
1737 before we do any consing. */
1738 if (!strcmp (FRAME_X_DISPLAY_INFO (f
)->x_id_name
,
1739 XSTRING (f
->name
)->data
))
1741 name
= build_string (FRAME_X_DISPLAY_INFO (f
)->x_id_name
);
1744 CHECK_STRING (name
, 0);
1746 /* Don't change the name if it's already NAME. */
1747 if (! NILP (Fstring_equal (name
, f
->name
)))
1750 if (FRAME_X_WINDOW (f
))
1755 XTextProperty text
, icon
;
1756 Lisp_Object icon_name
;
1758 text
.value
= XSTRING (name
)->data
;
1759 text
.encoding
= XA_STRING
;
1761 text
.nitems
= XSTRING (name
)->size
;
1763 icon_name
= (!NILP (f
->display
.x
->icon_name
)
1764 ? f
->display
.x
->icon_name
1767 icon
.value
= XSTRING (icon_name
)->data
;
1768 icon
.encoding
= XA_STRING
;
1770 icon
.nitems
= XSTRING (icon_name
)->size
;
1771 #ifdef USE_X_TOOLKIT
1772 XSetWMName (FRAME_X_DISPLAY (f
),
1773 XtWindow (f
->display
.x
->widget
), &text
);
1774 XSetWMIconName (FRAME_X_DISPLAY (f
), XtWindow (f
->display
.x
->widget
),
1776 #else /* not USE_X_TOOLKIT */
1777 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &text
);
1778 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &icon
);
1779 #endif /* not USE_X_TOOLKIT */
1781 #else /* not HAVE_X11R4 */
1782 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1783 XSTRING (name
)->data
);
1784 XStoreName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1785 XSTRING (name
)->data
);
1786 #endif /* not HAVE_X11R4 */
1793 /* This function should be called when the user's lisp code has
1794 specified a name for the frame; the name will override any set by the
1797 x_explicitly_set_name (f
, arg
, oldval
)
1799 Lisp_Object arg
, oldval
;
1801 x_set_name (f
, arg
, 1);
1804 /* This function should be called by Emacs redisplay code to set the
1805 name; names set this way will never override names set by the user's
1808 x_implicitly_set_name (f
, arg
, oldval
)
1810 Lisp_Object arg
, oldval
;
1812 x_set_name (f
, arg
, 0);
1816 x_set_autoraise (f
, arg
, oldval
)
1818 Lisp_Object arg
, oldval
;
1820 f
->auto_raise
= !EQ (Qnil
, arg
);
1824 x_set_autolower (f
, arg
, oldval
)
1826 Lisp_Object arg
, oldval
;
1828 f
->auto_lower
= !EQ (Qnil
, arg
);
1832 x_set_unsplittable (f
, arg
, oldval
)
1834 Lisp_Object arg
, oldval
;
1836 f
->no_split
= !NILP (arg
);
1840 x_set_vertical_scroll_bars (f
, arg
, oldval
)
1842 Lisp_Object arg
, oldval
;
1844 if (NILP (arg
) != ! FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
1846 FRAME_HAS_VERTICAL_SCROLL_BARS (f
) = ! NILP (arg
);
1848 /* We set this parameter before creating the X window for the
1849 frame, so we can get the geometry right from the start.
1850 However, if the window hasn't been created yet, we shouldn't
1851 call x_set_window_size. */
1852 if (FRAME_X_WINDOW (f
))
1853 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
1858 x_set_scroll_bar_width (f
, arg
, oldval
)
1860 Lisp_Object arg
, oldval
;
1864 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = 0;
1865 FRAME_SCROLL_BAR_COLS (f
) = 2;
1867 else if (INTEGERP (arg
) && XINT (arg
) > 0
1868 && XFASTINT (arg
) != FRAME_SCROLL_BAR_PIXEL_WIDTH (f
))
1870 int wid
= FONT_WIDTH (f
->display
.x
->font
);
1871 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = XFASTINT (arg
);
1872 FRAME_SCROLL_BAR_COLS (f
) = (XFASTINT (arg
) + wid
-1) / wid
;
1873 if (FRAME_X_WINDOW (f
))
1874 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
1878 /* Subroutines of creating an X frame. */
1880 /* Make sure that Vx_resource_name is set to a reasonable value.
1881 Fix it up, or set it to `emacs' if it is too hopeless. */
1884 validate_x_resource_name ()
1887 /* Number of valid characters in the resource name. */
1889 /* Number of invalid characters in the resource name. */
1894 if (STRINGP (Vx_resource_name
))
1896 unsigned char *p
= XSTRING (Vx_resource_name
)->data
;
1899 len
= XSTRING (Vx_resource_name
)->size
;
1901 /* Only letters, digits, - and _ are valid in resource names.
1902 Count the valid characters and count the invalid ones. */
1903 for (i
= 0; i
< len
; i
++)
1906 if (! ((c
>= 'a' && c
<= 'z')
1907 || (c
>= 'A' && c
<= 'Z')
1908 || (c
>= '0' && c
<= '9')
1909 || c
== '-' || c
== '_'))
1916 /* Not a string => completely invalid. */
1917 bad_count
= 5, good_count
= 0;
1919 /* If name is valid already, return. */
1923 /* If name is entirely invalid, or nearly so, use `emacs'. */
1925 || (good_count
== 1 && bad_count
> 0))
1927 Vx_resource_name
= build_string ("emacs");
1931 /* Name is partly valid. Copy it and replace the invalid characters
1932 with underscores. */
1934 Vx_resource_name
= new = Fcopy_sequence (Vx_resource_name
);
1936 for (i
= 0; i
< len
; i
++)
1938 int c
= XSTRING (new)->data
[i
];
1939 if (! ((c
>= 'a' && c
<= 'z')
1940 || (c
>= 'A' && c
<= 'Z')
1941 || (c
>= '0' && c
<= '9')
1942 || c
== '-' || c
== '_'))
1943 XSTRING (new)->data
[i
] = '_';
1948 extern char *x_get_string_resource ();
1950 DEFUN ("x-get-resource", Fx_get_resource
, Sx_get_resource
, 2, 4, 0,
1951 "Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.\n\
1952 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the\n\
1953 class, where INSTANCE is the name under which Emacs was invoked, or\n\
1954 the name specified by the `-name' or `-rn' command-line arguments.\n\
1956 The optional arguments COMPONENT and SUBCLASS add to the key and the\n\
1957 class, respectively. You must specify both of them or neither.\n\
1958 If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'\n\
1959 and the class is `Emacs.CLASS.SUBCLASS'.")
1960 (attribute
, class, component
, subclass
)
1961 Lisp_Object attribute
, class, component
, subclass
;
1963 register char *value
;
1969 CHECK_STRING (attribute
, 0);
1970 CHECK_STRING (class, 0);
1972 if (!NILP (component
))
1973 CHECK_STRING (component
, 1);
1974 if (!NILP (subclass
))
1975 CHECK_STRING (subclass
, 2);
1976 if (NILP (component
) != NILP (subclass
))
1977 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
1979 validate_x_resource_name ();
1981 /* Allocate space for the components, the dots which separate them,
1982 and the final '\0'. Make them big enough for the worst case. */
1983 name_key
= (char *) alloca (XSTRING (Vx_resource_name
)->size
1984 + (STRINGP (component
)
1985 ? XSTRING (component
)->size
: 0)
1986 + XSTRING (attribute
)->size
1989 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
1990 + XSTRING (class)->size
1991 + (STRINGP (subclass
)
1992 ? XSTRING (subclass
)->size
: 0)
1995 /* Start with emacs.FRAMENAME for the name (the specific one)
1996 and with `Emacs' for the class key (the general one). */
1997 strcpy (name_key
, XSTRING (Vx_resource_name
)->data
);
1998 strcpy (class_key
, EMACS_CLASS
);
2000 strcat (class_key
, ".");
2001 strcat (class_key
, XSTRING (class)->data
);
2003 if (!NILP (component
))
2005 strcat (class_key
, ".");
2006 strcat (class_key
, XSTRING (subclass
)->data
);
2008 strcat (name_key
, ".");
2009 strcat (name_key
, XSTRING (component
)->data
);
2012 strcat (name_key
, ".");
2013 strcat (name_key
, XSTRING (attribute
)->data
);
2015 value
= x_get_string_resource (check_x_display_info (Qnil
)->xrdb
,
2016 name_key
, class_key
);
2018 if (value
!= (char *) 0)
2019 return build_string (value
);
2024 /* Used when C code wants a resource value. */
2027 x_get_resource_string (attribute
, class)
2028 char *attribute
, *class;
2030 register char *value
;
2034 /* Allocate space for the components, the dots which separate them,
2035 and the final '\0'. */
2036 name_key
= (char *) alloca (XSTRING (Vinvocation_name
)->size
2037 + strlen (attribute
) + 2);
2038 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
2039 + strlen (class) + 2);
2041 sprintf (name_key
, "%s.%s",
2042 XSTRING (Vinvocation_name
)->data
,
2044 sprintf (class_key
, "%s.%s", EMACS_CLASS
, class);
2046 return x_get_string_resource (FRAME_X_DISPLAY_INFO (selected_frame
)->xrdb
,
2047 name_key
, class_key
);
2050 /* Types we might convert a resource string into. */
2053 number
, boolean
, string
, symbol
2056 /* Return the value of parameter PARAM.
2058 First search ALIST, then Vdefault_frame_alist, then the X defaults
2059 database, using ATTRIBUTE as the attribute name and CLASS as its class.
2061 Convert the resource to the type specified by desired_type.
2063 If no default is specified, return Qunbound. If you call
2064 x_get_arg, make sure you deal with Qunbound in a reasonable way,
2065 and don't let it get stored in any Lisp-visible variables! */
2068 x_get_arg (alist
, param
, attribute
, class, type
)
2069 Lisp_Object alist
, param
;
2072 enum resource_types type
;
2074 register Lisp_Object tem
;
2076 tem
= Fassq (param
, alist
);
2078 tem
= Fassq (param
, Vdefault_frame_alist
);
2084 tem
= Fx_get_resource (build_string (attribute
),
2085 build_string (class),
2094 return make_number (atoi (XSTRING (tem
)->data
));
2097 tem
= Fdowncase (tem
);
2098 if (!strcmp (XSTRING (tem
)->data
, "on")
2099 || !strcmp (XSTRING (tem
)->data
, "true"))
2108 /* As a special case, we map the values `true' and `on'
2109 to Qt, and `false' and `off' to Qnil. */
2112 lower
= Fdowncase (tem
);
2113 if (!strcmp (XSTRING (lower
)->data
, "on")
2114 || !strcmp (XSTRING (lower
)->data
, "true"))
2116 else if (!strcmp (XSTRING (lower
)->data
, "off")
2117 || !strcmp (XSTRING (lower
)->data
, "false"))
2120 return Fintern (tem
, Qnil
);
2133 /* Record in frame F the specified or default value according to ALIST
2134 of the parameter named PARAM (a Lisp symbol).
2135 If no value is specified for PARAM, look for an X default for XPROP
2136 on the frame named NAME.
2137 If that is not found either, use the value DEFLT. */
2140 x_default_parameter (f
, alist
, prop
, deflt
, xprop
, xclass
, type
)
2147 enum resource_types type
;
2151 tem
= x_get_arg (alist
, prop
, xprop
, xclass
, type
);
2152 if (EQ (tem
, Qunbound
))
2154 x_set_frame_parameters (f
, Fcons (Fcons (prop
, tem
), Qnil
));
2158 DEFUN ("x-parse-geometry", Fx_parse_geometry
, Sx_parse_geometry
, 1, 1, 0,
2159 "Parse an X-style geometry string STRING.\n\
2160 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).\n\
2161 The properties returned may include `top', `left', `height', and `width'.\n\
2162 The value of `left' or `top' may be an integer,\n\
2163 or a list (+ N) meaning N pixels relative to top/left corner,\n\
2164 or a list (- N) meaning -N pixels relative to bottom/right corner.")
2169 unsigned int width
, height
;
2172 CHECK_STRING (string
, 0);
2174 geometry
= XParseGeometry ((char *) XSTRING (string
)->data
,
2175 &x
, &y
, &width
, &height
);
2178 if (!!(geometry
& XValue
) != !!(geometry
& YValue
))
2179 error ("Must specify both x and y position, or neither");
2183 if (geometry
& XValue
)
2185 Lisp_Object element
;
2187 if (x
>= 0 && (geometry
& XNegative
))
2188 element
= Fcons (Qleft
, Fcons (Qminus
, Fcons (make_number (-x
), Qnil
)));
2189 else if (x
< 0 && ! (geometry
& XNegative
))
2190 element
= Fcons (Qleft
, Fcons (Qplus
, Fcons (make_number (x
), Qnil
)));
2192 element
= Fcons (Qleft
, make_number (x
));
2193 result
= Fcons (element
, result
);
2196 if (geometry
& YValue
)
2198 Lisp_Object element
;
2200 if (y
>= 0 && (geometry
& YNegative
))
2201 element
= Fcons (Qtop
, Fcons (Qminus
, Fcons (make_number (-y
), Qnil
)));
2202 else if (y
< 0 && ! (geometry
& YNegative
))
2203 element
= Fcons (Qtop
, Fcons (Qplus
, Fcons (make_number (y
), Qnil
)));
2205 element
= Fcons (Qtop
, make_number (y
));
2206 result
= Fcons (element
, result
);
2209 if (geometry
& WidthValue
)
2210 result
= Fcons (Fcons (Qwidth
, make_number (width
)), result
);
2211 if (geometry
& HeightValue
)
2212 result
= Fcons (Fcons (Qheight
, make_number (height
)), result
);
2217 /* Calculate the desired size and position of this window,
2218 and return the flags saying which aspects were specified.
2220 This function does not make the coordinates positive. */
2222 #define DEFAULT_ROWS 40
2223 #define DEFAULT_COLS 80
2226 x_figure_window_size (f
, parms
)
2230 register Lisp_Object tem0
, tem1
, tem2
;
2231 int height
, width
, left
, top
;
2232 register int geometry
;
2233 long window_prompting
= 0;
2235 /* Default values if we fall through.
2236 Actually, if that happens we should get
2237 window manager prompting. */
2238 f
->width
= DEFAULT_COLS
;
2239 f
->height
= DEFAULT_ROWS
;
2240 /* Window managers expect that if program-specified
2241 positions are not (0,0), they're intentional, not defaults. */
2242 f
->display
.x
->top_pos
= 0;
2243 f
->display
.x
->left_pos
= 0;
2245 tem0
= x_get_arg (parms
, Qheight
, 0, 0, number
);
2246 tem1
= x_get_arg (parms
, Qwidth
, 0, 0, number
);
2247 tem2
= x_get_arg (parms
, Quser_size
, 0, 0, number
);
2248 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
2250 if (!EQ (tem0
, Qunbound
))
2252 CHECK_NUMBER (tem0
, 0);
2253 f
->height
= XINT (tem0
);
2255 if (!EQ (tem1
, Qunbound
))
2257 CHECK_NUMBER (tem1
, 0);
2258 f
->width
= XINT (tem1
);
2260 if (!NILP (tem2
) && !EQ (tem2
, Qunbound
))
2261 window_prompting
|= USSize
;
2263 window_prompting
|= PSize
;
2266 f
->display
.x
->vertical_scroll_bar_extra
2267 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
2269 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0
2270 ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f
)
2271 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->display
.x
->font
)));
2272 f
->display
.x
->pixel_width
= CHAR_TO_PIXEL_WIDTH (f
, f
->width
);
2273 f
->display
.x
->pixel_height
= CHAR_TO_PIXEL_HEIGHT (f
, f
->height
);
2275 tem0
= x_get_arg (parms
, Qtop
, 0, 0, number
);
2276 tem1
= x_get_arg (parms
, Qleft
, 0, 0, number
);
2277 tem2
= x_get_arg (parms
, Quser_position
, 0, 0, number
);
2278 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
2280 if (EQ (tem0
, Qminus
))
2282 f
->display
.x
->top_pos
= 0;
2283 window_prompting
|= YNegative
;
2285 else if (CONSP (tem0
) && EQ (XCONS (tem0
)->car
, Qminus
)
2286 && CONSP (XCONS (tem0
)->cdr
)
2287 && INTEGERP (XCONS (XCONS (tem0
)->cdr
)->car
))
2289 f
->display
.x
->top_pos
= - XINT (XCONS (XCONS (tem0
)->cdr
)->car
);
2290 window_prompting
|= YNegative
;
2292 else if (CONSP (tem0
) && EQ (XCONS (tem0
)->car
, Qplus
)
2293 && CONSP (XCONS (tem0
)->cdr
)
2294 && INTEGERP (XCONS (XCONS (tem0
)->cdr
)->car
))
2296 f
->display
.x
->top_pos
= XINT (XCONS (XCONS (tem0
)->cdr
)->car
);
2298 else if (EQ (tem0
, Qunbound
))
2299 f
->display
.x
->top_pos
= 0;
2302 CHECK_NUMBER (tem0
, 0);
2303 f
->display
.x
->top_pos
= XINT (tem0
);
2304 if (f
->display
.x
->top_pos
< 0)
2305 window_prompting
|= YNegative
;
2308 if (EQ (tem1
, Qminus
))
2310 f
->display
.x
->left_pos
= 0;
2311 window_prompting
|= XNegative
;
2313 else if (CONSP (tem1
) && EQ (XCONS (tem1
)->car
, Qminus
)
2314 && CONSP (XCONS (tem1
)->cdr
)
2315 && INTEGERP (XCONS (XCONS (tem1
)->cdr
)->car
))
2317 f
->display
.x
->left_pos
= - XINT (XCONS (XCONS (tem1
)->cdr
)->car
);
2318 window_prompting
|= XNegative
;
2320 else if (CONSP (tem1
) && EQ (XCONS (tem1
)->car
, Qplus
)
2321 && CONSP (XCONS (tem1
)->cdr
)
2322 && INTEGERP (XCONS (XCONS (tem1
)->cdr
)->car
))
2324 f
->display
.x
->left_pos
= XINT (XCONS (XCONS (tem1
)->cdr
)->car
);
2326 else if (EQ (tem1
, Qunbound
))
2327 f
->display
.x
->left_pos
= 0;
2330 CHECK_NUMBER (tem1
, 0);
2331 f
->display
.x
->left_pos
= XINT (tem1
);
2332 if (f
->display
.x
->left_pos
< 0)
2333 window_prompting
|= XNegative
;
2336 if (!NILP (tem2
) && ! EQ (tem2
, Qunbound
))
2337 window_prompting
|= USPosition
;
2339 window_prompting
|= PPosition
;
2342 return window_prompting
;
2345 #if !defined (HAVE_X11R4) && !defined (HAVE_XSETWMPROTOCOLS)
2348 XSetWMProtocols (dpy
, w
, protocols
, count
)
2355 prop
= XInternAtom (dpy
, "WM_PROTOCOLS", False
);
2356 if (prop
== None
) return False
;
2357 XChangeProperty (dpy
, w
, prop
, XA_ATOM
, 32, PropModeReplace
,
2358 (unsigned char *) protocols
, count
);
2361 #endif /* not HAVE_X11R4 && not HAVE_XSETWMPROTOCOLS */
2363 #ifdef USE_X_TOOLKIT
2365 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
2366 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
2367 already be present because of the toolkit (Motif adds some of them,
2368 for example, but Xt doesn't). */
2371 hack_wm_protocols (f
, widget
)
2375 Display
*dpy
= XtDisplay (widget
);
2376 Window w
= XtWindow (widget
);
2377 int need_delete
= 1;
2383 Atom type
, *atoms
= 0;
2385 unsigned long nitems
= 0;
2386 unsigned long bytes_after
;
2388 if ((XGetWindowProperty (dpy
, w
,
2389 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2390 (long)0, (long)100, False
, XA_ATOM
,
2391 &type
, &format
, &nitems
, &bytes_after
,
2392 (unsigned char **) &atoms
)
2394 && format
== 32 && type
== XA_ATOM
)
2398 if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
)
2400 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
)
2402 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
)
2405 if (atoms
) XFree ((char *) atoms
);
2411 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2413 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
;
2415 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2417 XChangeProperty (dpy
, w
, FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2418 XA_ATOM
, 32, PropModeAppend
,
2419 (unsigned char *) props
, count
);
2425 #ifdef USE_X_TOOLKIT
2427 /* Create and set up the X widget for frame F. */
2430 x_window (f
, window_prompting
, minibuffer_only
)
2432 long window_prompting
;
2433 int minibuffer_only
;
2435 XClassHint class_hints
;
2436 XSetWindowAttributes attributes
;
2437 unsigned long attribute_mask
;
2439 Widget shell_widget
;
2441 Widget frame_widget
;
2447 /* Use the resource name as the top-level widget name
2448 for looking up resources. Make a non-Lisp copy
2449 for the window manager, so GC relocation won't bother it.
2451 Elsewhere we specify the window name for the window manager. */
2454 char *str
= (char *) XSTRING (Vx_resource_name
)->data
;
2455 f
->namebuf
= (char *) xmalloc (strlen (str
) + 1);
2456 strcpy (f
->namebuf
, str
);
2460 XtSetArg (al
[ac
], XtNallowShellResize
, 1); ac
++;
2461 XtSetArg (al
[ac
], XtNinput
, 1); ac
++;
2462 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2463 XtSetArg (al
[ac
], XtNborderWidth
, f
->display
.x
->border_width
); ac
++;
2464 shell_widget
= XtAppCreateShell (f
->namebuf
, EMACS_CLASS
,
2465 applicationShellWidgetClass
,
2466 FRAME_X_DISPLAY (f
), al
, ac
);
2468 f
->display
.x
->widget
= shell_widget
;
2469 /* maybe_set_screen_title_format (shell_widget); */
2471 pane_widget
= lw_create_widget ("main", "pane", widget_id_tick
++,
2472 (widget_value
*) NULL
,
2473 shell_widget
, False
,
2476 (lw_callback
) NULL
);
2478 f
->display
.x
->column_widget
= pane_widget
;
2480 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2481 the emacs screen when changing menubar. This reduces flickering. */
2484 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2485 XtSetArg (al
[ac
], XtNshowGrip
, 0); ac
++;
2486 XtSetArg (al
[ac
], XtNallowResize
, 1); ac
++;
2487 XtSetArg (al
[ac
], XtNresizeToPreferred
, 1); ac
++;
2488 XtSetArg (al
[ac
], XtNemacsFrame
, f
); ac
++;
2489 frame_widget
= XtCreateWidget (f
->namebuf
,
2491 pane_widget
, al
, ac
);
2493 f
->display
.x
->edit_widget
= frame_widget
;
2495 XtManageChild (frame_widget
);
2497 /* Do some needed geometry management. */
2500 char *tem
, shell_position
[32];
2503 int extra_borders
= 0;
2505 = (f
->display
.x
->menubar_widget
2506 ? (f
->display
.x
->menubar_widget
->core
.height
2507 + f
->display
.x
->menubar_widget
->core
.border_width
)
2509 extern char *lwlib_toolkit_type
;
2511 if (FRAME_EXTERNAL_MENU_BAR (f
))
2514 XtVaGetValues (pane_widget
, XtNinternalBorderWidth
, &ibw
, NULL
);
2515 menubar_size
+= ibw
;
2518 f
->display
.x
->menubar_height
= menubar_size
;
2520 /* Motif seems to need this amount added to the sizes
2521 specified for the shell widget. The Athena/Lucid widgets don't.
2522 Both conclusions reached experimentally. -- rms. */
2523 if (!strcmp (lwlib_toolkit_type
, "motif"))
2524 XtVaGetValues (f
->display
.x
->edit_widget
, XtNinternalBorderWidth
,
2525 &extra_borders
, NULL
);
2527 /* Convert our geometry parameters into a geometry string
2529 Note that we do not specify here whether the position
2530 is a user-specified or program-specified one.
2531 We pass that information later, in x_wm_set_size_hints. */
2533 int left
= f
->display
.x
->left_pos
;
2534 int xneg
= window_prompting
& XNegative
;
2535 int top
= f
->display
.x
->top_pos
;
2536 int yneg
= window_prompting
& YNegative
;
2542 if (window_prompting
& USPosition
)
2543 sprintf (shell_position
, "=%dx%d%c%d%c%d",
2544 PIXEL_WIDTH (f
) + extra_borders
,
2545 PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
,
2546 (xneg
? '-' : '+'), left
,
2547 (yneg
? '-' : '+'), top
);
2549 sprintf (shell_position
, "=%dx%d",
2550 PIXEL_WIDTH (f
) + extra_borders
,
2551 PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
);
2554 len
= strlen (shell_position
) + 1;
2555 tem
= (char *) xmalloc (len
);
2556 strncpy (tem
, shell_position
, len
);
2557 XtSetArg (al
[ac
], XtNgeometry
, tem
); ac
++;
2558 XtSetValues (shell_widget
, al
, ac
);
2561 XtManageChild (pane_widget
);
2562 XtRealizeWidget (shell_widget
);
2564 FRAME_X_WINDOW (f
) = XtWindow (frame_widget
);
2566 validate_x_resource_name ();
2568 class_hints
.res_name
= (char *) XSTRING (Vx_resource_name
)->data
;
2569 class_hints
.res_class
= EMACS_CLASS
;
2570 XSetClassHint (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
), &class_hints
);
2572 f
->display
.x
->wm_hints
.input
= True
;
2573 f
->display
.x
->wm_hints
.flags
|= InputHint
;
2574 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2575 &f
->display
.x
->wm_hints
);
2577 hack_wm_protocols (f
, shell_widget
);
2580 XtAddEventHandler (shell_widget
, 0, True
, _XEditResCheckMessages
, 0);
2583 /* Do a stupid property change to force the server to generate a
2584 propertyNotify event so that the event_stream server timestamp will
2585 be initialized to something relevant to the time we created the window.
2587 XChangeProperty (XtDisplay (frame_widget
), XtWindow (frame_widget
),
2588 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2589 XA_ATOM
, 32, PropModeAppend
,
2590 (unsigned char*) NULL
, 0);
2592 /* Make all the standard events reach the Emacs frame. */
2593 attributes
.event_mask
= STANDARD_EVENT_SET
;
2594 attribute_mask
= CWEventMask
;
2595 XChangeWindowAttributes (XtDisplay (shell_widget
), XtWindow (shell_widget
),
2596 attribute_mask
, &attributes
);
2598 XtMapWidget (frame_widget
);
2600 /* x_set_name normally ignores requests to set the name if the
2601 requested name is the same as the current name. This is the one
2602 place where that assumption isn't correct; f->name is set, but
2603 the X server hasn't been told. */
2606 int explicit = f
->explicit_name
;
2608 f
->explicit_name
= 0;
2611 x_set_name (f
, name
, explicit);
2614 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2615 f
->display
.x
->text_cursor
);
2619 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
2620 initialize_frame_menubar (f
);
2621 lw_set_main_areas (pane_widget
, f
->display
.x
->menubar_widget
, frame_widget
);
2623 if (FRAME_X_WINDOW (f
) == 0)
2624 error ("Unable to create window");
2627 #else /* not USE_X_TOOLKIT */
2629 /* Create and set up the X window for frame F. */
2635 XClassHint class_hints
;
2636 XSetWindowAttributes attributes
;
2637 unsigned long attribute_mask
;
2639 attributes
.background_pixel
= f
->display
.x
->background_pixel
;
2640 attributes
.border_pixel
= f
->display
.x
->border_pixel
;
2641 attributes
.bit_gravity
= StaticGravity
;
2642 attributes
.backing_store
= NotUseful
;
2643 attributes
.save_under
= True
;
2644 attributes
.event_mask
= STANDARD_EVENT_SET
;
2645 attribute_mask
= (CWBackPixel
| CWBorderPixel
| CWBitGravity
2647 | CWBackingStore
| CWSaveUnder
2653 = XCreateWindow (FRAME_X_DISPLAY (f
),
2654 f
->display
.x
->parent_desc
,
2655 f
->display
.x
->left_pos
,
2656 f
->display
.x
->top_pos
,
2657 PIXEL_WIDTH (f
), PIXEL_HEIGHT (f
),
2658 f
->display
.x
->border_width
,
2659 CopyFromParent
, /* depth */
2660 InputOutput
, /* class */
2661 FRAME_X_DISPLAY_INFO (f
)->visual
,
2662 attribute_mask
, &attributes
);
2664 validate_x_resource_name ();
2666 class_hints
.res_name
= (char *) XSTRING (Vx_resource_name
)->data
;
2667 class_hints
.res_class
= EMACS_CLASS
;
2668 XSetClassHint (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &class_hints
);
2670 /* The menubar is part of the ordinary display;
2671 it does not count in addition to the height of the window. */
2672 f
->display
.x
->menubar_height
= 0;
2674 /* This indicates that we use the "Passive Input" input model.
2675 Unless we do this, we don't get the Focus{In,Out} events that we
2676 need to draw the cursor correctly. Accursed bureaucrats.
2677 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2679 f
->display
.x
->wm_hints
.input
= True
;
2680 f
->display
.x
->wm_hints
.flags
|= InputHint
;
2681 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2682 &f
->display
.x
->wm_hints
);
2684 /* Request "save yourself" and "delete window" commands from wm. */
2687 protocols
[0] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2688 protocols
[1] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2689 XSetWMProtocols (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), protocols
, 2);
2692 /* x_set_name normally ignores requests to set the name if the
2693 requested name is the same as the current name. This is the one
2694 place where that assumption isn't correct; f->name is set, but
2695 the X server hasn't been told. */
2698 int explicit = f
->explicit_name
;
2700 f
->explicit_name
= 0;
2703 x_set_name (f
, name
, explicit);
2706 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2707 f
->display
.x
->text_cursor
);
2711 if (FRAME_X_WINDOW (f
) == 0)
2712 error ("Unable to create window");
2715 #endif /* not USE_X_TOOLKIT */
2717 /* Handle the icon stuff for this window. Perhaps later we might
2718 want an x_set_icon_position which can be called interactively as
2726 Lisp_Object icon_x
, icon_y
;
2728 /* Set the position of the icon. Note that twm groups all
2729 icons in an icon window. */
2730 icon_x
= x_get_arg (parms
, Qicon_left
, 0, 0, number
);
2731 icon_y
= x_get_arg (parms
, Qicon_top
, 0, 0, number
);
2732 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2734 CHECK_NUMBER (icon_x
, 0);
2735 CHECK_NUMBER (icon_y
, 0);
2737 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2738 error ("Both left and top icon corners of icon must be specified");
2742 if (! EQ (icon_x
, Qunbound
))
2743 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
2745 /* Start up iconic or window? */
2746 x_wm_set_window_state
2747 (f
, (EQ (x_get_arg (parms
, Qvisibility
, 0, 0, symbol
), Qicon
)
2752 (char *) XSTRING ((!NILP (f
->display
.x
->icon_name
)
2753 ? f
->display
.x
->icon_name
2759 /* Make the GC's needed for this window, setting the
2760 background, border and mouse colors; also create the
2761 mouse cursor and the gray border tile. */
2763 static char cursor_bits
[] =
2765 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2766 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2767 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2768 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2775 XGCValues gc_values
;
2781 /* Create the GC's of this frame.
2782 Note that many default values are used. */
2785 gc_values
.font
= f
->display
.x
->font
->fid
;
2786 gc_values
.foreground
= f
->display
.x
->foreground_pixel
;
2787 gc_values
.background
= f
->display
.x
->background_pixel
;
2788 gc_values
.line_width
= 0; /* Means 1 using fast algorithm. */
2789 f
->display
.x
->normal_gc
= XCreateGC (FRAME_X_DISPLAY (f
),
2791 GCLineWidth
| GCFont
2792 | GCForeground
| GCBackground
,
2795 /* Reverse video style. */
2796 gc_values
.foreground
= f
->display
.x
->background_pixel
;
2797 gc_values
.background
= f
->display
.x
->foreground_pixel
;
2798 f
->display
.x
->reverse_gc
= XCreateGC (FRAME_X_DISPLAY (f
),
2800 GCFont
| GCForeground
| GCBackground
2804 /* Cursor has cursor-color background, background-color foreground. */
2805 gc_values
.foreground
= f
->display
.x
->background_pixel
;
2806 gc_values
.background
= f
->display
.x
->cursor_pixel
;
2807 gc_values
.fill_style
= FillOpaqueStippled
;
2809 = XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
2810 FRAME_X_DISPLAY_INFO (f
)->root_window
,
2811 cursor_bits
, 16, 16);
2812 f
->display
.x
->cursor_gc
2813 = XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2814 (GCFont
| GCForeground
| GCBackground
2815 | GCFillStyle
| GCStipple
| GCLineWidth
),
2818 /* Create the gray border tile used when the pointer is not in
2819 the frame. Since this depends on the frame's pixel values,
2820 this must be done on a per-frame basis. */
2821 f
->display
.x
->border_tile
2822 = (XCreatePixmapFromBitmapData
2823 (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
2824 gray_bits
, gray_width
, gray_height
,
2825 f
->display
.x
->foreground_pixel
,
2826 f
->display
.x
->background_pixel
,
2827 DefaultDepth (FRAME_X_DISPLAY (f
),
2828 XScreenNumberOfScreen (FRAME_X_SCREEN (f
)))));
2833 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
2835 "Make a new X window, which is called a \"frame\" in Emacs terms.\n\
2836 Returns an Emacs frame object.\n\
2837 ALIST is an alist of frame parameters.\n\
2838 If the parameters specify that the frame should not have a minibuffer,\n\
2839 and do not specify a specific minibuffer window to use,\n\
2840 then `default-minibuffer-frame' must be a frame whose minibuffer can\n\
2841 be shared by the new frame.\n\
2843 This function is an internal primitive--use `make-frame' instead.")
2848 Lisp_Object frame
, tem
;
2850 int minibuffer_only
= 0;
2851 long window_prompting
= 0;
2853 int count
= specpdl_ptr
- specpdl
;
2854 struct gcpro gcpro1
;
2855 Lisp_Object display
;
2856 struct x_display_info
*dpyinfo
;
2862 /* Use this general default value to start with
2863 until we know if this frame has a specified name. */
2864 Vx_resource_name
= Vinvocation_name
;
2866 display
= x_get_arg (parms
, Qdisplay
, 0, 0, 0);
2867 if (EQ (display
, Qunbound
))
2869 dpyinfo
= check_x_display_info (display
);
2871 kb
= dpyinfo
->kboard
;
2873 kb
= &the_only_kboard
;
2876 name
= x_get_arg (parms
, Qname
, "title", "Title", string
);
2878 && ! EQ (name
, Qunbound
)
2880 error ("Invalid frame name--not a string or nil");
2883 Vx_resource_name
= name
;
2885 /* See if parent window is specified. */
2886 parent
= x_get_arg (parms
, Qparent_id
, NULL
, NULL
, number
);
2887 if (EQ (parent
, Qunbound
))
2889 if (! NILP (parent
))
2890 CHECK_NUMBER (parent
, 0);
2892 tem
= x_get_arg (parms
, Qminibuffer
, 0, 0, symbol
);
2893 if (EQ (tem
, Qnone
) || NILP (tem
))
2894 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
2895 else if (EQ (tem
, Qonly
))
2897 f
= make_minibuffer_frame ();
2898 minibuffer_only
= 1;
2900 else if (WINDOWP (tem
))
2901 f
= make_frame_without_minibuffer (tem
, kb
, display
);
2905 /* Note that X Windows does support scroll bars. */
2906 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
2908 XSETFRAME (frame
, f
);
2911 f
->output_method
= output_x_window
;
2912 f
->display
.x
= (struct x_display
*) xmalloc (sizeof (struct x_display
));
2913 bzero (f
->display
.x
, sizeof (struct x_display
));
2914 f
->display
.x
->icon_bitmap
= -1;
2916 f
->display
.x
->icon_name
2917 = x_get_arg (parms
, Qicon_name
, "iconName", "Title", string
);
2918 if (! STRINGP (f
->display
.x
->icon_name
))
2919 f
->display
.x
->icon_name
= Qnil
;
2921 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
2923 FRAME_KBOARD (f
) = kb
;
2926 /* Specify the parent under which to make this X window. */
2930 f
->display
.x
->parent_desc
= parent
;
2931 f
->display
.x
->explicit_parent
= 1;
2935 f
->display
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
2936 f
->display
.x
->explicit_parent
= 0;
2939 /* Note that the frame has no physical cursor right now. */
2940 f
->phys_cursor_x
= -1;
2942 /* Set the name; the functions to which we pass f expect the name to
2944 if (EQ (name
, Qunbound
) || NILP (name
))
2946 f
->name
= build_string (dpyinfo
->x_id_name
);
2947 f
->explicit_name
= 0;
2952 f
->explicit_name
= 1;
2953 /* use the frame's title when getting resources for this frame. */
2954 specbind (Qx_resource_name
, name
);
2957 /* Extract the window parameters from the supplied values
2958 that are needed to determine window geometry. */
2962 font
= x_get_arg (parms
, Qfont
, "font", "Font", string
);
2964 /* First, try whatever font the caller has specified. */
2966 font
= x_new_font (f
, XSTRING (font
)->data
);
2967 /* Try out a font which we hope has bold and italic variations. */
2968 if (!STRINGP (font
))
2969 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
2970 if (! STRINGP (font
))
2971 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
2972 if (! STRINGP (font
))
2973 /* This was formerly the first thing tried, but it finds too many fonts
2974 and takes too long. */
2975 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
2976 /* If those didn't work, look for something which will at least work. */
2977 if (! STRINGP (font
))
2978 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
2980 if (! STRINGP (font
))
2981 font
= build_string ("fixed");
2983 x_default_parameter (f
, parms
, Qfont
, font
,
2984 "font", "Font", string
);
2987 #ifdef USE_X_TOOLKIT
2988 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
2989 whereby it fails to get any font. */
2990 xlwmenu_default_font
= f
->display
.x
->font
;
2993 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
2994 "borderwidth", "BorderWidth", number
);
2995 /* This defaults to 2 in order to match xterm. We recognize either
2996 internalBorderWidth or internalBorder (which is what xterm calls
2998 if (NILP (Fassq (Qinternal_border_width
, parms
)))
3002 value
= x_get_arg (parms
, Qinternal_border_width
,
3003 "internalBorder", "BorderWidth", number
);
3004 if (! EQ (value
, Qunbound
))
3005 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
3008 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (2),
3009 "internalBorderWidth", "BorderWidth", number
);
3010 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qt
,
3011 "verticalScrollBars", "ScrollBars", boolean
);
3013 /* Also do the stuff which must be set before the window exists. */
3014 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
3015 "foreground", "Foreground", string
);
3016 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
3017 "background", "Background", string
);
3018 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
3019 "pointerColor", "Foreground", string
);
3020 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
3021 "cursorColor", "Foreground", string
);
3022 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
3023 "borderColor", "BorderColor", string
);
3025 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
3026 "menuBar", "MenuBar", number
);
3027 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
3028 "scrollBarWidth", "ScrollBarWidth", number
);
3030 f
->display
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3031 window_prompting
= x_figure_window_size (f
, parms
);
3033 if (window_prompting
& XNegative
)
3035 if (window_prompting
& YNegative
)
3036 f
->display
.x
->win_gravity
= SouthEastGravity
;
3038 f
->display
.x
->win_gravity
= NorthEastGravity
;
3042 if (window_prompting
& YNegative
)
3043 f
->display
.x
->win_gravity
= SouthWestGravity
;
3045 f
->display
.x
->win_gravity
= NorthWestGravity
;
3048 f
->display
.x
->size_hint_flags
= window_prompting
;
3050 #ifdef USE_X_TOOLKIT
3051 x_window (f
, window_prompting
, minibuffer_only
);
3057 init_frame_faces (f
);
3059 /* We need to do this after creating the X window, so that the
3060 icon-creation functions can say whose icon they're describing. */
3061 x_default_parameter (f
, parms
, Qicon_type
, Qnil
,
3062 "bitmapIcon", "BitmapIcon", symbol
);
3064 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
3065 "autoRaise", "AutoRaiseLower", boolean
);
3066 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
3067 "autoLower", "AutoRaiseLower", boolean
);
3068 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
3069 "cursorType", "CursorType", symbol
);
3071 /* Dimensions, especially f->height, must be done via change_frame_size.
3072 Change will not be effected unless different from the current
3076 f
->height
= f
->width
= 0;
3077 change_frame_size (f
, height
, width
, 1, 0);
3079 /* Tell the server what size and position, etc, we want,
3080 and how badly we want them. */
3082 x_wm_set_size_hint (f
, window_prompting
, 0);
3085 tem
= x_get_arg (parms
, Qunsplittable
, 0, 0, boolean
);
3086 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
3090 /* It is now ok to make the frame official
3091 even if we get an error below.
3092 And the frame needs to be on Vframe_list
3093 or making it visible won't work. */
3094 Vframe_list
= Fcons (frame
, Vframe_list
);
3096 /* Now that the frame is official, it counts as a reference to
3098 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
3100 /* Make the window appear on the frame and enable display,
3101 unless the caller says not to. However, with explicit parent,
3102 Emacs cannot control visibility, so don't try. */
3103 if (! f
->display
.x
->explicit_parent
)
3105 Lisp_Object visibility
;
3107 visibility
= x_get_arg (parms
, Qvisibility
, 0, 0, symbol
);
3108 if (EQ (visibility
, Qunbound
))
3111 if (EQ (visibility
, Qicon
))
3112 x_iconify_frame (f
);
3113 else if (! NILP (visibility
))
3114 x_make_frame_visible (f
);
3116 /* Must have been Qnil. */
3120 return unbind_to (count
, frame
);
3123 /* FRAME is used only to get a handle on the X display. We don't pass the
3124 display info directly because we're called from frame.c, which doesn't
3125 know about that structure. */
3127 x_get_focus_frame (frame
)
3128 struct frame
*frame
;
3130 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (frame
);
3132 if (! dpyinfo
->x_focus_frame
)
3135 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
3139 DEFUN ("focus-frame", Ffocus_frame
, Sfocus_frame
, 1, 1, 0,
3140 "Set the focus on FRAME.")
3144 CHECK_LIVE_FRAME (frame
, 0);
3146 if (FRAME_X_P (XFRAME (frame
)))
3149 x_focus_on_frame (XFRAME (frame
));
3157 DEFUN ("unfocus-frame", Funfocus_frame
, Sunfocus_frame
, 0, 0, 0,
3158 "If a frame has been focused, release it.")
3161 if (FRAME_X_P (selected_frame
))
3163 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (selected_frame
);
3165 if (dpyinfo
->x_focus_frame
)
3168 x_unfocus_frame (dpyinfo
->x_focus_frame
);
3176 DEFUN ("x-list-fonts", Fx_list_fonts
, Sx_list_fonts
, 1, 3, 0,
3177 "Return a list of the names of available fonts matching PATTERN.\n\
3178 If optional arguments FACE and FRAME are specified, return only fonts\n\
3179 the same size as FACE on FRAME.\n\
3181 PATTERN is a string, perhaps with wildcard characters;\n\
3182 the * character matches any substring, and\n\
3183 the ? character matches any single character.\n\
3184 PATTERN is case-insensitive.\n\
3185 FACE is a face name--a symbol.\n\
3187 The return value is a list of strings, suitable as arguments to\n\
3190 Fonts Emacs can't use (i.e. proportional fonts) may or may not be excluded\n\
3191 even if they match PATTERN and FACE.")
3192 (pattern
, face
, frame
)
3193 Lisp_Object pattern
, face
, frame
;
3197 #ifndef BROKEN_XLISTFONTSWITHINFO
3200 XFontStruct
*size_ref
;
3205 CHECK_STRING (pattern
, 0);
3207 CHECK_SYMBOL (face
, 1);
3209 f
= check_x_frame (frame
);
3211 /* Determine the width standard for comparison with the fonts we find. */
3219 /* Don't die if we get called with a terminal frame. */
3220 if (! FRAME_X_P (f
))
3221 error ("non-X frame used in `x-list-fonts'");
3223 face_id
= face_name_id_number (f
, face
);
3225 if (face_id
< 0 || face_id
>= FRAME_N_PARAM_FACES (f
)
3226 || FRAME_PARAM_FACES (f
) [face_id
] == 0)
3227 size_ref
= f
->display
.x
->font
;
3230 size_ref
= FRAME_PARAM_FACES (f
) [face_id
]->font
;
3231 if (size_ref
== (XFontStruct
*) (~0))
3232 size_ref
= f
->display
.x
->font
;
3236 /* See if we cached the result for this particular query. */
3237 list
= Fassoc (pattern
,
3238 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
);
3240 /* We have info in the cache for this PATTERN. */
3243 Lisp_Object tem
, newlist
;
3245 /* We have info about this pattern. */
3246 list
= XCONS (list
)->cdr
;
3253 /* Filter the cached info and return just the fonts that match FACE. */
3255 for (tem
= list
; CONSP (tem
); tem
= XCONS (tem
)->cdr
)
3257 XFontStruct
*thisinfo
;
3259 thisinfo
= XLoadQueryFont (FRAME_X_DISPLAY (f
),
3260 XSTRING (XCONS (tem
)->car
)->data
);
3262 if (thisinfo
&& same_size_fonts (thisinfo
, size_ref
))
3263 newlist
= Fcons (XCONS (tem
)->car
, newlist
);
3265 XFreeFont (FRAME_X_DISPLAY (f
), thisinfo
);
3275 /* Solaris 2.3 has a bug in XListFontsWithInfo. */
3276 #ifndef BROKEN_XLISTFONTSWITHINFO
3278 names
= XListFontsWithInfo (FRAME_X_DISPLAY (f
),
3279 XSTRING (pattern
)->data
,
3280 2000, /* maxnames */
3281 &num_fonts
, /* count_return */
3282 &info
); /* info_return */
3285 names
= XListFonts (FRAME_X_DISPLAY (f
),
3286 XSTRING (pattern
)->data
,
3287 2000, /* maxnames */
3288 &num_fonts
); /* count_return */
3297 Lisp_Object full_list
;
3299 /* Make a list of all the fonts we got back.
3300 Store that in the font cache for the display. */
3302 for (i
= 0; i
< num_fonts
; i
++)
3303 full_list
= Fcons (build_string (names
[i
]), full_list
);
3304 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
3305 = Fcons (Fcons (pattern
, full_list
),
3306 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
);
3308 /* Make a list of the fonts that have the right width. */
3310 for (i
= 0; i
< num_fonts
; i
++)
3318 #ifdef BROKEN_XLISTFONTSWITHINFO
3319 XFontStruct
*thisinfo
;
3322 thisinfo
= XLoadQueryFont (FRAME_X_DISPLAY (f
), names
[i
]);
3325 keeper
= thisinfo
&& same_size_fonts (thisinfo
, size_ref
);
3327 keeper
= same_size_fonts (&info
[i
], size_ref
);
3331 list
= Fcons (build_string (names
[i
]), list
);
3333 list
= Fnreverse (list
);
3336 #ifndef BROKEN_XLISTFONTSWITHINFO
3338 XFreeFontInfo (names
, info
, num_fonts
);
3341 XFreeFontNames (names
);
3349 DEFUN ("x-color-defined-p", Fx_color_defined_p
, Sx_color_defined_p
, 1, 2, 0,
3350 "Return non-nil if color COLOR is supported on frame FRAME.\n\
3351 If FRAME is omitted or nil, use the selected frame.")
3353 Lisp_Object color
, frame
;
3356 FRAME_PTR f
= check_x_frame (frame
);
3358 CHECK_STRING (color
, 1);
3360 if (defined_color (f
, XSTRING (color
)->data
, &foo
, 0))
3366 DEFUN ("x-color-values", Fx_color_values
, Sx_color_values
, 1, 2, 0,
3367 "Return a description of the color named COLOR on frame FRAME.\n\
3368 The value is a list of integer RGB values--(RED GREEN BLUE).\n\
3369 These values appear to range from 0 to 65280 or 65535, depending\n\
3370 on the system; white is (65280 65280 65280) or (65535 65535 65535).\n\
3371 If FRAME is omitted or nil, use the selected frame.")
3373 Lisp_Object color
, frame
;
3376 FRAME_PTR f
= check_x_frame (frame
);
3378 CHECK_STRING (color
, 1);
3380 if (defined_color (f
, XSTRING (color
)->data
, &foo
, 0))
3384 rgb
[0] = make_number (foo
.red
);
3385 rgb
[1] = make_number (foo
.green
);
3386 rgb
[2] = make_number (foo
.blue
);
3387 return Flist (3, rgb
);
3393 DEFUN ("x-display-color-p", Fx_display_color_p
, Sx_display_color_p
, 0, 1, 0,
3394 "Return t if the X display supports color.\n\
3395 The optional argument DISPLAY specifies which display to ask about.\n\
3396 DISPLAY should be either a frame or a display name (a string).\n\
3397 If omitted or nil, that stands for the selected frame's display.")
3399 Lisp_Object display
;
3401 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3403 if (dpyinfo
->n_planes
<= 2)
3406 switch (dpyinfo
->visual
->class)
3419 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
3421 "Return t if the X display supports shades of gray.\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
);
3430 if (dpyinfo
->n_planes
<= 2)
3433 return (dpyinfo
->n_planes
> 1
3434 && (dpyinfo
->visual
->class == StaticGray
3435 || dpyinfo
->visual
->class == GrayScale
));
3438 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
3440 "Returns the width in pixels of the X display DISPLAY.\n\
3441 The optional argument DISPLAY specifies which display to ask about.\n\
3442 DISPLAY should be either a frame or a display name (a string).\n\
3443 If omitted or nil, that stands for the selected frame's display.")
3445 Lisp_Object display
;
3447 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3449 return make_number (dpyinfo
->width
);
3452 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
3453 Sx_display_pixel_height
, 0, 1, 0,
3454 "Returns the height in pixels of the X display DISPLAY.\n\
3455 The optional argument DISPLAY specifies which display to ask about.\n\
3456 DISPLAY should be either a frame or a display name (a string).\n\
3457 If omitted or nil, that stands for the selected frame's display.")
3459 Lisp_Object display
;
3461 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3463 return make_number (dpyinfo
->height
);
3466 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
3468 "Returns the number of bitplanes 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 (dpyinfo
->n_planes
);
3480 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
3482 "Returns the number of color cells of the X display DISPLAY.\n\
3483 The optional argument DISPLAY specifies which display to ask about.\n\
3484 DISPLAY should be either a frame or a display name (a string).\n\
3485 If omitted or nil, that stands for the selected frame's display.")
3487 Lisp_Object display
;
3489 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3491 return make_number (DisplayCells (dpyinfo
->display
,
3492 XScreenNumberOfScreen (dpyinfo
->screen
)));
3495 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
3496 Sx_server_max_request_size
,
3498 "Returns the maximum request size of the X server of display DISPLAY.\n\
3499 The optional argument DISPLAY specifies which display to ask about.\n\
3500 DISPLAY should be either a frame or a display name (a string).\n\
3501 If omitted or nil, that stands for the selected frame's display.")
3503 Lisp_Object display
;
3505 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3507 return make_number (MAXREQUEST (dpyinfo
->display
));
3510 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
3511 "Returns the vendor ID string of the X server of display DISPLAY.\n\
3512 The optional argument DISPLAY specifies which display to ask about.\n\
3513 DISPLAY should be either a frame or a display name (a string).\n\
3514 If omitted or nil, that stands for the selected frame's display.")
3516 Lisp_Object display
;
3518 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3519 char *vendor
= ServerVendor (dpyinfo
->display
);
3521 if (! vendor
) vendor
= "";
3522 return build_string (vendor
);
3525 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
3526 "Returns the version numbers of the X server of display DISPLAY.\n\
3527 The value is a list of three integers: the major and minor\n\
3528 version numbers of the X Protocol in use, and the vendor-specific release\n\
3529 number. See also the function `x-server-vendor'.\n\n\
3530 The optional argument DISPLAY specifies which display to ask about.\n\
3531 DISPLAY should be either a frame or a display name (a string).\n\
3532 If omitted or nil, that stands for the selected frame's display.")
3534 Lisp_Object display
;
3536 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3537 Display
*dpy
= dpyinfo
->display
;
3539 return Fcons (make_number (ProtocolVersion (dpy
)),
3540 Fcons (make_number (ProtocolRevision (dpy
)),
3541 Fcons (make_number (VendorRelease (dpy
)), Qnil
)));
3544 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
3545 "Returns the number of screens on the X server of display DISPLAY.\n\
3546 The optional argument DISPLAY specifies which display to ask about.\n\
3547 DISPLAY should be either a frame or a display name (a string).\n\
3548 If omitted or nil, that stands for the selected frame's display.")
3550 Lisp_Object display
;
3552 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3554 return make_number (ScreenCount (dpyinfo
->display
));
3557 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
3558 "Returns the height in millimeters of the X display DISPLAY.\n\
3559 The optional argument DISPLAY specifies which display to ask about.\n\
3560 DISPLAY should be either a frame or a display name (a string).\n\
3561 If omitted or nil, that stands for the selected frame's display.")
3563 Lisp_Object display
;
3565 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3567 return make_number (HeightMMOfScreen (dpyinfo
->screen
));
3570 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
3571 "Returns the width in millimeters of the X display DISPLAY.\n\
3572 The optional argument DISPLAY specifies which display to ask about.\n\
3573 DISPLAY should be either a frame or a display name (a string).\n\
3574 If omitted or nil, that stands for the selected frame's display.")
3576 Lisp_Object display
;
3578 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3580 return make_number (WidthMMOfScreen (dpyinfo
->screen
));
3583 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
3584 Sx_display_backing_store
, 0, 1, 0,
3585 "Returns an indication of whether X display DISPLAY does backing store.\n\
3586 The value may be `always', `when-mapped', or `not-useful'.\n\
3587 The optional argument DISPLAY specifies which display to ask about.\n\
3588 DISPLAY should be either a frame or a display name (a string).\n\
3589 If omitted or nil, that stands for the selected frame's display.")
3591 Lisp_Object display
;
3593 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3595 switch (DoesBackingStore (dpyinfo
->screen
))
3598 return intern ("always");
3601 return intern ("when-mapped");
3604 return intern ("not-useful");
3607 error ("Strange value for BackingStore parameter of screen");
3611 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
3612 Sx_display_visual_class
, 0, 1, 0,
3613 "Returns the visual class of the X display DISPLAY.\n\
3614 The value is one of the symbols `static-gray', `gray-scale',\n\
3615 `static-color', `pseudo-color', `true-color', or `direct-color'.\n\n\
3616 The optional argument DISPLAY specifies which display to ask about.\n\
3617 DISPLAY should be either a frame or a display name (a string).\n\
3618 If omitted or nil, that stands for the selected frame's display.")
3620 Lisp_Object display
;
3622 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3624 switch (dpyinfo
->visual
->class)
3626 case StaticGray
: return (intern ("static-gray"));
3627 case GrayScale
: return (intern ("gray-scale"));
3628 case StaticColor
: return (intern ("static-color"));
3629 case PseudoColor
: return (intern ("pseudo-color"));
3630 case TrueColor
: return (intern ("true-color"));
3631 case DirectColor
: return (intern ("direct-color"));
3633 error ("Display has an unknown visual class");
3637 DEFUN ("x-display-save-under", Fx_display_save_under
,
3638 Sx_display_save_under
, 0, 1, 0,
3639 "Returns t if the X display DISPLAY supports the save-under feature.\n\
3640 The optional argument DISPLAY specifies which display to ask about.\n\
3641 DISPLAY should be either a frame or a display name (a string).\n\
3642 If omitted or nil, that stands for the selected frame's display.")
3644 Lisp_Object display
;
3646 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3648 if (DoesSaveUnders (dpyinfo
->screen
) == True
)
3656 register struct frame
*f
;
3658 return PIXEL_WIDTH (f
);
3663 register struct frame
*f
;
3665 return PIXEL_HEIGHT (f
);
3670 register struct frame
*f
;
3672 return FONT_WIDTH (f
->display
.x
->font
);
3677 register struct frame
*f
;
3679 return f
->display
.x
->line_height
;
3683 x_screen_planes (frame
)
3686 return FRAME_X_DISPLAY_INFO (XFRAME (frame
))->n_planes
;
3689 #if 0 /* These no longer seem like the right way to do things. */
3691 /* Draw a rectangle on the frame with left top corner including
3692 the character specified by LEFT_CHAR and TOP_CHAR. The rectangle is
3693 CHARS by LINES wide and long and is the color of the cursor. */
3696 x_rectangle (f
, gc
, left_char
, top_char
, chars
, lines
)
3697 register struct frame
*f
;
3699 register int top_char
, left_char
, chars
, lines
;
3703 int left
= (left_char
* FONT_WIDTH (f
->display
.x
->font
)
3704 + f
->display
.x
->internal_border_width
);
3705 int top
= (top_char
* f
->display
.x
->line_height
3706 + f
->display
.x
->internal_border_width
);
3709 width
= FONT_WIDTH (f
->display
.x
->font
) / 2;
3711 width
= FONT_WIDTH (f
->display
.x
->font
) * chars
;
3713 height
= f
->display
.x
->line_height
/ 2;
3715 height
= f
->display
.x
->line_height
* lines
;
3717 XDrawRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3718 gc
, left
, top
, width
, height
);
3721 DEFUN ("x-draw-rectangle", Fx_draw_rectangle
, Sx_draw_rectangle
, 5, 5, 0,
3722 "Draw a rectangle on FRAME between coordinates specified by\n\
3723 numbers X0, Y0, X1, Y1 in the cursor pixel.")
3724 (frame
, X0
, Y0
, X1
, Y1
)
3725 register Lisp_Object frame
, X0
, X1
, Y0
, Y1
;
3727 register int x0
, y0
, x1
, y1
, top
, left
, n_chars
, n_lines
;
3729 CHECK_LIVE_FRAME (frame
, 0);
3730 CHECK_NUMBER (X0
, 0);
3731 CHECK_NUMBER (Y0
, 1);
3732 CHECK_NUMBER (X1
, 2);
3733 CHECK_NUMBER (Y1
, 3);
3743 n_lines
= y1
- y0
+ 1;
3748 n_lines
= y0
- y1
+ 1;
3754 n_chars
= x1
- x0
+ 1;
3759 n_chars
= x0
- x1
+ 1;
3763 x_rectangle (XFRAME (frame
), XFRAME (frame
)->display
.x
->cursor_gc
,
3764 left
, top
, n_chars
, n_lines
);
3770 DEFUN ("x-erase-rectangle", Fx_erase_rectangle
, Sx_erase_rectangle
, 5, 5, 0,
3771 "Draw a rectangle drawn on FRAME between coordinates\n\
3772 X0, Y0, X1, Y1 in the regular background-pixel.")
3773 (frame
, X0
, Y0
, X1
, Y1
)
3774 register Lisp_Object frame
, X0
, Y0
, X1
, Y1
;
3776 register int x0
, y0
, x1
, y1
, top
, left
, n_chars
, n_lines
;
3778 CHECK_LIVE_FRAME (frame
, 0);
3779 CHECK_NUMBER (X0
, 0);
3780 CHECK_NUMBER (Y0
, 1);
3781 CHECK_NUMBER (X1
, 2);
3782 CHECK_NUMBER (Y1
, 3);
3792 n_lines
= y1
- y0
+ 1;
3797 n_lines
= y0
- y1
+ 1;
3803 n_chars
= x1
- x0
+ 1;
3808 n_chars
= x0
- x1
+ 1;
3812 x_rectangle (XFRAME (frame
), XFRAME (frame
)->display
.x
->reverse_gc
,
3813 left
, top
, n_chars
, n_lines
);
3819 /* Draw lines around the text region beginning at the character position
3820 TOP_X, TOP_Y and ending at BOTTOM_X and BOTTOM_Y. GC specifies the
3821 pixel and line characteristics. */
3823 #define line_len(line) (FRAME_CURRENT_GLYPHS (f)->used[(line)])
3826 outline_region (f
, gc
, top_x
, top_y
, bottom_x
, bottom_y
)
3827 register struct frame
*f
;
3829 int top_x
, top_y
, bottom_x
, bottom_y
;
3831 register int ibw
= f
->display
.x
->internal_border_width
;
3832 register int font_w
= FONT_WIDTH (f
->display
.x
->font
);
3833 register int font_h
= f
->display
.x
->line_height
;
3835 int x
= line_len (y
);
3836 XPoint
*pixel_points
3837 = (XPoint
*) alloca (((bottom_y
- top_y
+ 2) * 4) * sizeof (XPoint
));
3838 register XPoint
*this_point
= pixel_points
;
3840 /* Do the horizontal top line/lines */
3843 this_point
->x
= ibw
;
3844 this_point
->y
= ibw
+ (font_h
* top_y
);
3847 this_point
->x
= ibw
+ (font_w
/ 2); /* Half-size for newline chars. */
3849 this_point
->x
= ibw
+ (font_w
* x
);
3850 this_point
->y
= (this_point
- 1)->y
;
3854 this_point
->x
= ibw
;
3855 this_point
->y
= ibw
+ (font_h
* (top_y
+ 1));
3857 this_point
->x
= ibw
+ (font_w
* top_x
);
3858 this_point
->y
= (this_point
- 1)->y
;
3860 this_point
->x
= (this_point
- 1)->x
;
3861 this_point
->y
= ibw
+ (font_h
* top_y
);
3863 this_point
->x
= ibw
+ (font_w
* x
);
3864 this_point
->y
= (this_point
- 1)->y
;
3867 /* Now do the right side. */
3868 while (y
< bottom_y
)
3869 { /* Right vertical edge */
3871 this_point
->x
= (this_point
- 1)->x
;
3872 this_point
->y
= ibw
+ (font_h
* (y
+ 1));
3875 y
++; /* Horizontal connection to next line */
3878 this_point
->x
= ibw
+ (font_w
/ 2);
3880 this_point
->x
= ibw
+ (font_w
* x
);
3882 this_point
->y
= (this_point
- 1)->y
;
3885 /* Now do the bottom and connect to the top left point. */
3886 this_point
->x
= ibw
+ (font_w
* (bottom_x
+ 1));
3889 this_point
->x
= (this_point
- 1)->x
;
3890 this_point
->y
= ibw
+ (font_h
* (bottom_y
+ 1));
3892 this_point
->x
= ibw
;
3893 this_point
->y
= (this_point
- 1)->y
;
3895 this_point
->x
= pixel_points
->x
;
3896 this_point
->y
= pixel_points
->y
;
3898 XDrawLines (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3900 (this_point
- pixel_points
+ 1), CoordModeOrigin
);
3903 DEFUN ("x-contour-region", Fx_contour_region
, Sx_contour_region
, 1, 1, 0,
3904 "Highlight the region between point and the character under the mouse\n\
3907 register Lisp_Object event
;
3909 register int x0
, y0
, x1
, y1
;
3910 register struct frame
*f
= selected_frame
;
3911 register int p1
, p2
;
3913 CHECK_CONS (event
, 0);
3916 x0
= XINT (Fcar (Fcar (event
)));
3917 y0
= XINT (Fcar (Fcdr (Fcar (event
))));
3919 /* If the mouse is past the end of the line, don't that area. */
3920 /* ReWrite this... */
3925 if (y1
> y0
) /* point below mouse */
3926 outline_region (f
, f
->display
.x
->cursor_gc
,
3928 else if (y1
< y0
) /* point above mouse */
3929 outline_region (f
, f
->display
.x
->cursor_gc
,
3931 else /* same line: draw horizontal rectangle */
3934 x_rectangle (f
, f
->display
.x
->cursor_gc
,
3935 x0
, y0
, (x1
- x0
+ 1), 1);
3937 x_rectangle (f
, f
->display
.x
->cursor_gc
,
3938 x1
, y1
, (x0
- x1
+ 1), 1);
3941 XFlush (FRAME_X_DISPLAY (f
));
3947 DEFUN ("x-uncontour-region", Fx_uncontour_region
, Sx_uncontour_region
, 1, 1, 0,
3948 "Erase any highlighting of the region between point and the character\n\
3949 at X, Y on the selected frame.")
3951 register Lisp_Object event
;
3953 register int x0
, y0
, x1
, y1
;
3954 register struct frame
*f
= selected_frame
;
3957 x0
= XINT (Fcar (Fcar (event
)));
3958 y0
= XINT (Fcar (Fcdr (Fcar (event
))));
3962 if (y1
> y0
) /* point below mouse */
3963 outline_region (f
, f
->display
.x
->reverse_gc
,
3965 else if (y1
< y0
) /* point above mouse */
3966 outline_region (f
, f
->display
.x
->reverse_gc
,
3968 else /* same line: draw horizontal rectangle */
3971 x_rectangle (f
, f
->display
.x
->reverse_gc
,
3972 x0
, y0
, (x1
- x0
+ 1), 1);
3974 x_rectangle (f
, f
->display
.x
->reverse_gc
,
3975 x1
, y1
, (x0
- x1
+ 1), 1);
3983 int contour_begin_x
, contour_begin_y
;
3984 int contour_end_x
, contour_end_y
;
3985 int contour_npoints
;
3987 /* Clip the top part of the contour lines down (and including) line Y_POS.
3988 If X_POS is in the middle (rather than at the end) of the line, drop
3989 down a line at that character. */
3992 clip_contour_top (y_pos
, x_pos
)
3994 register XPoint
*begin
= contour_lines
[y_pos
].top_left
;
3995 register XPoint
*end
;
3996 register int npoints
;
3997 register struct display_line
*line
= selected_frame
->phys_lines
[y_pos
+ 1];
3999 if (x_pos
>= line
->len
- 1) /* Draw one, straight horizontal line. */
4001 end
= contour_lines
[y_pos
].top_right
;
4002 npoints
= (end
- begin
+ 1);
4003 XDrawLines (x_current_display
, contour_window
,
4004 contour_erase_gc
, begin_erase
, npoints
, CoordModeOrigin
);
4006 bcopy (end
, begin
+ 1, contour_last_point
- end
+ 1);
4007 contour_last_point
-= (npoints
- 2);
4008 XDrawLines (x_current_display
, contour_window
,
4009 contour_erase_gc
, begin
, 2, CoordModeOrigin
);
4010 XFlush (x_current_display
);
4012 /* Now, update contour_lines structure. */
4017 register XPoint
*p
= begin
+ 1;
4018 end
= contour_lines
[y_pos
].bottom_right
;
4019 npoints
= (end
- begin
+ 1);
4020 XDrawLines (x_current_display
, contour_window
,
4021 contour_erase_gc
, begin_erase
, npoints
, CoordModeOrigin
);
4024 p
->x
= ibw
+ (font_w
* (x_pos
+ 1));
4026 p
->y
= begin
->y
+ font_h
;
4028 bcopy (end
, begin
+ 3, contour_last_point
- end
+ 1);
4029 contour_last_point
-= (npoints
- 5);
4030 XDrawLines (x_current_display
, contour_window
,
4031 contour_erase_gc
, begin
, 4, CoordModeOrigin
);
4032 XFlush (x_current_display
);
4034 /* Now, update contour_lines structure. */
4038 /* Erase the top horizontal lines of the contour, and then extend
4039 the contour upwards. */
4042 extend_contour_top (line
)
4047 clip_contour_bottom (x_pos
, y_pos
)
4053 extend_contour_bottom (x_pos
, y_pos
)
4057 DEFUN ("x-select-region", Fx_select_region
, Sx_select_region
, 1, 1, "e",
4062 register struct frame
*f
= selected_frame
;
4063 register int point_x
= f
->cursor_x
;
4064 register int point_y
= f
->cursor_y
;
4065 register int mouse_below_point
;
4066 register Lisp_Object obj
;
4067 register int x_contour_x
, x_contour_y
;
4069 x_contour_x
= x_mouse_x
;
4070 x_contour_y
= x_mouse_y
;
4071 if (x_contour_y
> point_y
|| (x_contour_y
== point_y
4072 && x_contour_x
> point_x
))
4074 mouse_below_point
= 1;
4075 outline_region (f
, f
->display
.x
->cursor_gc
, point_x
, point_y
,
4076 x_contour_x
, x_contour_y
);
4080 mouse_below_point
= 0;
4081 outline_region (f
, f
->display
.x
->cursor_gc
, x_contour_x
, x_contour_y
,
4087 obj
= read_char (-1, 0, 0, Qnil
, 0);
4091 if (mouse_below_point
)
4093 if (x_mouse_y
<= point_y
) /* Flipped. */
4095 mouse_below_point
= 0;
4097 outline_region (f
, f
->display
.x
->reverse_gc
, point_x
, point_y
,
4098 x_contour_x
, x_contour_y
);
4099 outline_region (f
, f
->display
.x
->cursor_gc
, x_mouse_x
, x_mouse_y
,
4102 else if (x_mouse_y
< x_contour_y
) /* Bottom clipped. */
4104 clip_contour_bottom (x_mouse_y
);
4106 else if (x_mouse_y
> x_contour_y
) /* Bottom extended. */
4108 extend_bottom_contour (x_mouse_y
);
4111 x_contour_x
= x_mouse_x
;
4112 x_contour_y
= x_mouse_y
;
4114 else /* mouse above or same line as point */
4116 if (x_mouse_y
>= point_y
) /* Flipped. */
4118 mouse_below_point
= 1;
4120 outline_region (f
, f
->display
.x
->reverse_gc
,
4121 x_contour_x
, x_contour_y
, point_x
, point_y
);
4122 outline_region (f
, f
->display
.x
->cursor_gc
, point_x
, point_y
,
4123 x_mouse_x
, x_mouse_y
);
4125 else if (x_mouse_y
> x_contour_y
) /* Top clipped. */
4127 clip_contour_top (x_mouse_y
);
4129 else if (x_mouse_y
< x_contour_y
) /* Top extended. */
4131 extend_contour_top (x_mouse_y
);
4136 unread_command_event
= obj
;
4137 if (mouse_below_point
)
4139 contour_begin_x
= point_x
;
4140 contour_begin_y
= point_y
;
4141 contour_end_x
= x_contour_x
;
4142 contour_end_y
= x_contour_y
;
4146 contour_begin_x
= x_contour_x
;
4147 contour_begin_y
= x_contour_y
;
4148 contour_end_x
= point_x
;
4149 contour_end_y
= point_y
;
4154 DEFUN ("x-horizontal-line", Fx_horizontal_line
, Sx_horizontal_line
, 1, 1, "e",
4159 register Lisp_Object obj
;
4160 struct frame
*f
= selected_frame
;
4161 register struct window
*w
= XWINDOW (selected_window
);
4162 register GC line_gc
= f
->display
.x
->cursor_gc
;
4163 register GC erase_gc
= f
->display
.x
->reverse_gc
;
4165 char dash_list
[] = {6, 4, 6, 4};
4167 XGCValues gc_values
;
4169 register int previous_y
;
4170 register int line
= (x_mouse_y
+ 1) * f
->display
.x
->line_height
4171 + f
->display
.x
->internal_border_width
;
4172 register int left
= f
->display
.x
->internal_border_width
4174 * FONT_WIDTH (f
->display
.x
->font
));
4175 register int right
= left
+ (w
->width
4176 * FONT_WIDTH (f
->display
.x
->font
))
4177 - f
->display
.x
->internal_border_width
;
4181 gc_values
.foreground
= f
->display
.x
->cursor_pixel
;
4182 gc_values
.background
= f
->display
.x
->background_pixel
;
4183 gc_values
.line_width
= 1;
4184 gc_values
.line_style
= LineOnOffDash
;
4185 gc_values
.cap_style
= CapRound
;
4186 gc_values
.join_style
= JoinRound
;
4188 line_gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4189 GCLineStyle
| GCJoinStyle
| GCCapStyle
4190 | GCLineWidth
| GCForeground
| GCBackground
,
4192 XSetDashes (FRAME_X_DISPLAY (f
), line_gc
, 0, dash_list
, dashes
);
4193 gc_values
.foreground
= f
->display
.x
->background_pixel
;
4194 gc_values
.background
= f
->display
.x
->foreground_pixel
;
4195 erase_gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4196 GCLineStyle
| GCJoinStyle
| GCCapStyle
4197 | GCLineWidth
| GCForeground
| GCBackground
,
4199 XSetDashes (FRAME_X_DISPLAY (f
), erase_gc
, 0, dash_list
, dashes
);
4206 if (x_mouse_y
>= XINT (w
->top
)
4207 && x_mouse_y
< XINT (w
->top
) + XINT (w
->height
) - 1)
4209 previous_y
= x_mouse_y
;
4210 line
= (x_mouse_y
+ 1) * f
->display
.x
->line_height
4211 + f
->display
.x
->internal_border_width
;
4212 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4213 line_gc
, left
, line
, right
, line
);
4215 XFlush (FRAME_X_DISPLAY (f
));
4220 obj
= read_char (-1, 0, 0, Qnil
, 0);
4222 || (! EQ (Fcar (Fcdr (Fcdr (obj
))),
4223 Qvertical_scroll_bar
))
4227 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4228 erase_gc
, left
, line
, right
, line
);
4229 unread_command_event
= obj
;
4231 XFreeGC (FRAME_X_DISPLAY (f
), line_gc
);
4232 XFreeGC (FRAME_X_DISPLAY (f
), erase_gc
);
4238 while (x_mouse_y
== previous_y
);
4241 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4242 erase_gc
, left
, line
, right
, line
);
4249 /* These keep track of the rectangle following the pointer. */
4250 int mouse_track_top
, mouse_track_left
, mouse_track_width
;
4252 /* Offset in buffer of character under the pointer, or 0. */
4253 int mouse_buffer_offset
;
4255 DEFUN ("x-track-pointer", Fx_track_pointer
, Sx_track_pointer
, 0, 0, 0,
4256 "Track the pointer.")
4259 static Cursor current_pointer_shape
;
4260 FRAME_PTR f
= x_mouse_frame
;
4263 if (EQ (Vmouse_frame_part
, Qtext_part
)
4264 && (current_pointer_shape
!= f
->display
.x
->nontext_cursor
))
4269 current_pointer_shape
= f
->display
.x
->nontext_cursor
;
4270 XDefineCursor (FRAME_X_DISPLAY (f
),
4272 current_pointer_shape
);
4274 buf
= XBUFFER (XWINDOW (Vmouse_window
)->buffer
);
4275 c
= *(BUF_CHAR_ADDRESS (buf
, mouse_buffer_offset
));
4277 else if (EQ (Vmouse_frame_part
, Qmodeline_part
)
4278 && (current_pointer_shape
!= f
->display
.x
->modeline_cursor
))
4280 current_pointer_shape
= f
->display
.x
->modeline_cursor
;
4281 XDefineCursor (FRAME_X_DISPLAY (f
),
4283 current_pointer_shape
);
4286 XFlush (FRAME_X_DISPLAY (f
));
4292 DEFUN ("x-track-pointer", Fx_track_pointer
, Sx_track_pointer
, 1, 1, "e",
4293 "Draw rectangle around character under mouse pointer, if there is one.")
4297 struct window
*w
= XWINDOW (Vmouse_window
);
4298 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4299 struct buffer
*b
= XBUFFER (w
->buffer
);
4302 if (! EQ (Vmouse_window
, selected_window
))
4305 if (EQ (event
, Qnil
))
4309 x_read_mouse_position (selected_frame
, &x
, &y
);
4313 mouse_track_width
= 0;
4314 mouse_track_left
= mouse_track_top
= -1;
4318 if ((x_mouse_x
!= mouse_track_left
4319 && (x_mouse_x
< mouse_track_left
4320 || x_mouse_x
> (mouse_track_left
+ mouse_track_width
)))
4321 || x_mouse_y
!= mouse_track_top
)
4323 int hp
= 0; /* Horizontal position */
4324 int len
= FRAME_CURRENT_GLYPHS (f
)->used
[x_mouse_y
];
4325 int p
= FRAME_CURRENT_GLYPHS (f
)->bufp
[x_mouse_y
];
4326 int tab_width
= XINT (b
->tab_width
);
4327 int ctl_arrow_p
= !NILP (b
->ctl_arrow
);
4329 int mode_line_vpos
= XFASTINT (w
->height
) + XFASTINT (w
->top
) - 1;
4330 int in_mode_line
= 0;
4332 if (! FRAME_CURRENT_GLYPHS (f
)->enable
[x_mouse_y
])
4335 /* Erase previous rectangle. */
4336 if (mouse_track_width
)
4338 x_rectangle (f
, f
->display
.x
->reverse_gc
,
4339 mouse_track_left
, mouse_track_top
,
4340 mouse_track_width
, 1);
4342 if ((mouse_track_left
== f
->phys_cursor_x
4343 || mouse_track_left
== f
->phys_cursor_x
- 1)
4344 && mouse_track_top
== f
->phys_cursor_y
)
4346 x_display_cursor (f
, 1);
4350 mouse_track_left
= x_mouse_x
;
4351 mouse_track_top
= x_mouse_y
;
4352 mouse_track_width
= 0;
4354 if (mouse_track_left
> len
) /* Past the end of line. */
4357 if (mouse_track_top
== mode_line_vpos
)
4363 if (tab_width
<= 0 || tab_width
> 20) tab_width
= 8;
4367 if (len
== f
->width
&& hp
== len
- 1 && c
!= '\n')
4373 mouse_track_width
= tab_width
- (hp
% tab_width
);
4375 hp
+= mouse_track_width
;
4378 mouse_track_left
= hp
- mouse_track_width
;
4384 mouse_track_width
= -1;
4388 if (ctl_arrow_p
&& (c
< 040 || c
== 0177))
4393 mouse_track_width
= 2;
4398 mouse_track_left
= hp
- mouse_track_width
;
4404 mouse_track_width
= 1;
4411 while (hp
<= x_mouse_x
);
4414 if (mouse_track_width
) /* Over text; use text pointer shape. */
4416 XDefineCursor (FRAME_X_DISPLAY (f
),
4418 f
->display
.x
->text_cursor
);
4419 x_rectangle (f
, f
->display
.x
->cursor_gc
,
4420 mouse_track_left
, mouse_track_top
,
4421 mouse_track_width
, 1);
4423 else if (in_mode_line
)
4424 XDefineCursor (FRAME_X_DISPLAY (f
),
4426 f
->display
.x
->modeline_cursor
);
4428 XDefineCursor (FRAME_X_DISPLAY (f
),
4430 f
->display
.x
->nontext_cursor
);
4433 XFlush (FRAME_X_DISPLAY (f
));
4436 obj
= read_char (-1, 0, 0, Qnil
, 0);
4439 while (CONSP (obj
) /* Mouse event */
4440 && EQ (Fcar (Fcdr (Fcdr (obj
))), Qnil
) /* Not scroll bar */
4441 && EQ (Vmouse_depressed
, Qnil
) /* Only motion events */
4442 && EQ (Vmouse_window
, selected_window
) /* In this window */
4445 unread_command_event
= obj
;
4447 if (mouse_track_width
)
4449 x_rectangle (f
, f
->display
.x
->reverse_gc
,
4450 mouse_track_left
, mouse_track_top
,
4451 mouse_track_width
, 1);
4452 mouse_track_width
= 0;
4453 if ((mouse_track_left
== f
->phys_cursor_x
4454 || mouse_track_left
- 1 == f
->phys_cursor_x
)
4455 && mouse_track_top
== f
->phys_cursor_y
)
4457 x_display_cursor (f
, 1);
4460 XDefineCursor (FRAME_X_DISPLAY (f
),
4462 f
->display
.x
->nontext_cursor
);
4463 XFlush (FRAME_X_DISPLAY (f
));
4473 /* Draw a pixmap specified by IMAGE_DATA of dimensions WIDTH and HEIGHT
4474 on the frame F at position X, Y. */
4476 x_draw_pixmap (f
, x
, y
, image_data
, width
, height
)
4478 int x
, y
, width
, height
;
4483 image
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
4484 FRAME_X_WINDOW (f
), image_data
,
4486 XCopyPlane (FRAME_X_DISPLAY (f
), image
, FRAME_X_WINDOW (f
),
4487 f
->display
.x
->normal_gc
, 0, 0, width
, height
, x
, y
);
4491 #if 0 /* I'm told these functions are superfluous
4492 given the ability to bind function keys. */
4495 DEFUN ("x-rebind-key", Fx_rebind_key
, Sx_rebind_key
, 3, 3, 0,
4496 "Rebind X keysym KEYSYM, with MODIFIERS, to generate NEWSTRING.\n\
4497 KEYSYM is a string which conforms to the X keysym definitions found\n\
4498 in X11/keysymdef.h, sans the initial XK_. MODIFIERS is nil or a\n\
4499 list of strings specifying modifier keys such as Control_L, which must\n\
4500 also be depressed for NEWSTRING to appear.")
4501 (x_keysym
, modifiers
, newstring
)
4502 register Lisp_Object x_keysym
;
4503 register Lisp_Object modifiers
;
4504 register Lisp_Object newstring
;
4507 register KeySym keysym
;
4508 KeySym modifier_list
[16];
4511 CHECK_STRING (x_keysym
, 1);
4512 CHECK_STRING (newstring
, 3);
4514 keysym
= XStringToKeysym ((char *) XSTRING (x_keysym
)->data
);
4515 if (keysym
== NoSymbol
)
4516 error ("Keysym does not exist");
4518 if (NILP (modifiers
))
4519 XRebindKeysym (x_current_display
, keysym
, modifier_list
, 0,
4520 XSTRING (newstring
)->data
, XSTRING (newstring
)->size
);
4523 register Lisp_Object rest
, mod
;
4526 for (rest
= modifiers
; !NILP (rest
); rest
= Fcdr (rest
))
4529 error ("Can't have more than 16 modifiers");
4532 CHECK_STRING (mod
, 3);
4533 modifier_list
[i
] = XStringToKeysym ((char *) XSTRING (mod
)->data
);
4535 if (modifier_list
[i
] == NoSymbol
4536 || !(IsModifierKey (modifier_list
[i
])
4537 || ((unsigned)(modifier_list
[i
]) == XK_Mode_switch
)
4538 || ((unsigned)(modifier_list
[i
]) == XK_Num_Lock
)))
4540 if (modifier_list
[i
] == NoSymbol
4541 || !IsModifierKey (modifier_list
[i
]))
4543 error ("Element is not a modifier keysym");
4547 XRebindKeysym (x_current_display
, keysym
, modifier_list
, i
,
4548 XSTRING (newstring
)->data
, XSTRING (newstring
)->size
);
4554 DEFUN ("x-rebind-keys", Fx_rebind_keys
, Sx_rebind_keys
, 2, 2, 0,
4555 "Rebind KEYCODE to list of strings STRINGS.\n\
4556 STRINGS should be a list of 16 elements, one for each shift combination.\n\
4557 nil as element means don't change.\n\
4558 See the documentation of `x-rebind-key' for more information.")
4560 register Lisp_Object keycode
;
4561 register Lisp_Object strings
;
4563 register Lisp_Object item
;
4564 register unsigned char *rawstring
;
4565 KeySym rawkey
, modifier
[1];
4567 register unsigned i
;
4570 CHECK_NUMBER (keycode
, 1);
4571 CHECK_CONS (strings
, 2);
4572 rawkey
= (KeySym
) ((unsigned) (XINT (keycode
))) & 255;
4573 for (i
= 0; i
<= 15; strings
= Fcdr (strings
), i
++)
4575 item
= Fcar (strings
);
4578 CHECK_STRING (item
, 2);
4579 strsize
= XSTRING (item
)->size
;
4580 rawstring
= (unsigned char *) xmalloc (strsize
);
4581 bcopy (XSTRING (item
)->data
, rawstring
, strsize
);
4582 modifier
[1] = 1 << i
;
4583 XRebindKeysym (x_current_display
, rawkey
, modifier
, 1,
4584 rawstring
, strsize
);
4589 #endif /* HAVE_X11 */
4592 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4594 XScreenNumberOfScreen (scr
)
4595 register Screen
*scr
;
4597 register Display
*dpy
;
4598 register Screen
*dpyscr
;
4602 dpyscr
= dpy
->screens
;
4604 for (i
= 0; i
< dpy
->nscreens
; i
++, dpyscr
++)
4610 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4613 select_visual (dpy
, screen
, depth
)
4616 unsigned int *depth
;
4619 XVisualInfo
*vinfo
, vinfo_template
;
4622 v
= DefaultVisualOfScreen (screen
);
4625 vinfo_template
.visualid
= XVisualIDFromVisual (v
);
4627 vinfo_template
.visualid
= v
->visualid
;
4630 vinfo_template
.screen
= XScreenNumberOfScreen (screen
);
4632 vinfo
= XGetVisualInfo (dpy
,
4633 VisualIDMask
| VisualScreenMask
, &vinfo_template
,
4636 fatal ("Can't get proper X visual info");
4638 if ((1 << vinfo
->depth
) == vinfo
->colormap_size
)
4639 *depth
= vinfo
->depth
;
4643 int n
= vinfo
->colormap_size
- 1;
4652 XFree ((char *) vinfo
);
4656 /* Return the X display structure for the display named NAME.
4657 Open a new connection if necessary. */
4659 struct x_display_info
*
4660 x_display_info_for_name (name
)
4664 struct x_display_info
*dpyinfo
;
4666 CHECK_STRING (name
, 0);
4668 for (dpyinfo
= x_display_list
, names
= x_display_name_list
;
4670 dpyinfo
= dpyinfo
->next
, names
= XCONS (names
)->cdr
)
4673 tem
= Fstring_equal (XCONS (XCONS (names
)->car
)->car
, name
);
4678 /* Use this general default value to start with. */
4679 Vx_resource_name
= Vinvocation_name
;
4681 validate_x_resource_name ();
4683 dpyinfo
= x_term_init (name
, (unsigned char *)0,
4684 (char *) XSTRING (Vx_resource_name
)->data
);
4687 error ("Cannot connect to X server %s", XSTRING (name
)->data
);
4690 XSETFASTINT (Vwindow_system_version
, 11);
4695 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
4696 1, 3, 0, "Open a connection to an X server.\n\
4697 DISPLAY is the name of the display to connect to.\n\
4698 Optional second arg XRM-STRING is a string of resources in xrdb format.\n\
4699 If the optional third arg MUST-SUCCEED is non-nil,\n\
4700 terminate Emacs if we can't open the connection.")
4701 (display
, xrm_string
, must_succeed
)
4702 Lisp_Object display
, xrm_string
, must_succeed
;
4704 unsigned int n_planes
;
4705 unsigned char *xrm_option
;
4706 struct x_display_info
*dpyinfo
;
4708 CHECK_STRING (display
, 0);
4709 if (! NILP (xrm_string
))
4710 CHECK_STRING (xrm_string
, 1);
4712 if (! NILP (xrm_string
))
4713 xrm_option
= (unsigned char *) XSTRING (xrm_string
)->data
;
4715 xrm_option
= (unsigned char *) 0;
4717 /* Use this general default value to start with. */
4718 Vx_resource_name
= Vinvocation_name
;
4720 validate_x_resource_name ();
4722 /* This is what opens the connection and sets x_current_display.
4723 This also initializes many symbols, such as those used for input. */
4724 dpyinfo
= x_term_init (display
, xrm_option
,
4725 (char *) XSTRING (Vx_resource_name
)->data
);
4729 if (!NILP (must_succeed
))
4730 fatal ("Cannot connect to X server %s.\n\
4731 Check the DISPLAY environment variable or use `-d'.\n\
4732 Also use the `xhost' program to verify that it is set to permit\n\
4733 connections from your machine.\n",
4734 XSTRING (display
)->data
);
4736 error ("Cannot connect to X server %s", XSTRING (display
)->data
);
4741 XSETFASTINT (Vwindow_system_version
, 11);
4745 DEFUN ("x-close-connection", Fx_close_connection
,
4746 Sx_close_connection
, 1, 1, 0,
4747 "Close the connection to DISPLAY's X server.\n\
4748 For DISPLAY, specify either a frame or a display name (a string).\n\
4749 If DISPLAY is nil, that stands for the selected frame's display.")
4751 Lisp_Object display
;
4753 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4754 struct x_display_info
*tail
;
4757 if (dpyinfo
->reference_count
> 0)
4758 error ("Display still has frames on it");
4761 /* Free the fonts in the font table. */
4762 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
4764 if (dpyinfo
->font_table
[i
].name
)
4765 free (dpyinfo
->font_table
[i
].name
);
4766 /* Don't free the full_name string;
4767 it is always shared with something else. */
4768 XFreeFont (dpyinfo
->display
, dpyinfo
->font_table
[i
].font
);
4770 x_destroy_all_bitmaps (dpyinfo
);
4771 XSetCloseDownMode (dpyinfo
->display
, DestroyAll
);
4773 #ifdef USE_X_TOOLKIT
4774 XtCloseDisplay (dpyinfo
->display
);
4776 XCloseDisplay (dpyinfo
->display
);
4779 x_delete_display (dpyinfo
);
4785 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
4786 "Return the list of display names that Emacs has connections to.")
4789 Lisp_Object tail
, result
;
4792 for (tail
= x_display_name_list
; ! NILP (tail
); tail
= XCONS (tail
)->cdr
)
4793 result
= Fcons (XCONS (XCONS (tail
)->car
)->car
, result
);
4798 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
4799 "If ON is non-nil, report X errors as soon as the erring request is made.\n\
4800 If ON is nil, allow buffering of requests.\n\
4801 Turning on synchronization prohibits the Xlib routines from buffering\n\
4802 requests and seriously degrades performance, but makes debugging much\n\
4804 The optional second argument DISPLAY specifies which display to act on.\n\
4805 DISPLAY should be either a frame or a display name (a string).\n\
4806 If DISPLAY is omitted or nil, that stands for the selected frame's display.")
4808 Lisp_Object display
, on
;
4810 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4812 XSynchronize (dpyinfo
->display
, !EQ (on
, Qnil
));
4817 /* Wait for responses to all X commands issued so far for frame F. */
4824 XSync (FRAME_X_DISPLAY (f
), False
);
4830 /* This is zero if not using X windows. */
4833 /* The section below is built by the lisp expression at the top of the file,
4834 just above where these variables are declared. */
4835 /*&&& init symbols here &&&*/
4836 Qauto_raise
= intern ("auto-raise");
4837 staticpro (&Qauto_raise
);
4838 Qauto_lower
= intern ("auto-lower");
4839 staticpro (&Qauto_lower
);
4840 Qbackground_color
= intern ("background-color");
4841 staticpro (&Qbackground_color
);
4842 Qbar
= intern ("bar");
4844 Qborder_color
= intern ("border-color");
4845 staticpro (&Qborder_color
);
4846 Qborder_width
= intern ("border-width");
4847 staticpro (&Qborder_width
);
4848 Qbox
= intern ("box");
4850 Qcursor_color
= intern ("cursor-color");
4851 staticpro (&Qcursor_color
);
4852 Qcursor_type
= intern ("cursor-type");
4853 staticpro (&Qcursor_type
);
4854 Qfont
= intern ("font");
4856 Qforeground_color
= intern ("foreground-color");
4857 staticpro (&Qforeground_color
);
4858 Qgeometry
= intern ("geometry");
4859 staticpro (&Qgeometry
);
4860 Qicon_left
= intern ("icon-left");
4861 staticpro (&Qicon_left
);
4862 Qicon_top
= intern ("icon-top");
4863 staticpro (&Qicon_top
);
4864 Qicon_type
= intern ("icon-type");
4865 staticpro (&Qicon_type
);
4866 Qicon_name
= intern ("icon-name");
4867 staticpro (&Qicon_name
);
4868 Qinternal_border_width
= intern ("internal-border-width");
4869 staticpro (&Qinternal_border_width
);
4870 Qleft
= intern ("left");
4872 Qmouse_color
= intern ("mouse-color");
4873 staticpro (&Qmouse_color
);
4874 Qnone
= intern ("none");
4876 Qparent_id
= intern ("parent-id");
4877 staticpro (&Qparent_id
);
4878 Qscroll_bar_width
= intern ("scroll-bar-width");
4879 staticpro (&Qscroll_bar_width
);
4880 Qsuppress_icon
= intern ("suppress-icon");
4881 staticpro (&Qsuppress_icon
);
4882 Qtop
= intern ("top");
4884 Qundefined_color
= intern ("undefined-color");
4885 staticpro (&Qundefined_color
);
4886 Qvertical_scroll_bars
= intern ("vertical-scroll-bars");
4887 staticpro (&Qvertical_scroll_bars
);
4888 Qvisibility
= intern ("visibility");
4889 staticpro (&Qvisibility
);
4890 Qwindow_id
= intern ("window-id");
4891 staticpro (&Qwindow_id
);
4892 Qx_frame_parameter
= intern ("x-frame-parameter");
4893 staticpro (&Qx_frame_parameter
);
4894 Qx_resource_name
= intern ("x-resource-name");
4895 staticpro (&Qx_resource_name
);
4896 Quser_position
= intern ("user-position");
4897 staticpro (&Quser_position
);
4898 Quser_size
= intern ("user-size");
4899 staticpro (&Quser_size
);
4900 Qdisplay
= intern ("display");
4901 staticpro (&Qdisplay
);
4902 /* This is the end of symbol initialization. */
4904 Fput (Qundefined_color
, Qerror_conditions
,
4905 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
4906 Fput (Qundefined_color
, Qerror_message
,
4907 build_string ("Undefined color"));
4909 init_x_parm_symbols ();
4911 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path
,
4912 "List of directories to search for bitmap files for X.");
4913 Vx_bitmap_file_path
= decode_env_path ((char *) 0, PATH_BITMAPS
);
4915 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
4916 "The shape of the pointer when over text.\n\
4917 Changing the value does not affect existing frames\n\
4918 unless you set the mouse color.");
4919 Vx_pointer_shape
= Qnil
;
4921 DEFVAR_LISP ("x-resource-name", &Vx_resource_name
,
4922 "The name Emacs uses to look up X resources; for internal use only.\n\
4923 `x-get-resource' uses this as the first component of the instance name\n\
4924 when requesting resource values.\n\
4925 Emacs initially sets `x-resource-name' to the name under which Emacs\n\
4926 was invoked, or to the value specified with the `-name' or `-rn'\n\
4927 switches, if present.");
4928 Vx_resource_name
= Qnil
;
4930 #if 0 /* This doesn't really do anything. */
4931 DEFVAR_INT ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape
,
4932 "The shape of the pointer when not over text.\n\
4933 This variable takes effect when you create a new frame\n\
4934 or when you set the mouse color.");
4936 Vx_nontext_pointer_shape
= Qnil
;
4938 #if 0 /* This doesn't really do anything. */
4939 DEFVAR_INT ("x-mode-pointer-shape", &Vx_mode_pointer_shape
,
4940 "The shape of the pointer when over the mode line.\n\
4941 This variable takes effect when you create a new frame\n\
4942 or when you set the mouse color.");
4944 Vx_mode_pointer_shape
= Qnil
;
4946 DEFVAR_INT ("x-sensitive-text-pointer-shape",
4947 &Vx_sensitive_text_pointer_shape
,
4948 "The shape of the pointer when over mouse-sensitive text.\n\
4949 This variable takes effect when you create a new frame\n\
4950 or when you set the mouse color.");
4951 Vx_sensitive_text_pointer_shape
= Qnil
;
4953 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
4954 "A string indicating the foreground color of the cursor box.");
4955 Vx_cursor_fore_pixel
= Qnil
;
4957 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
4958 "Non-nil if no X window manager is in use.");
4960 #ifdef USE_X_TOOLKIT
4961 Fprovide (intern ("x-toolkit"));
4964 Fprovide (intern ("motif"));
4967 defsubr (&Sx_get_resource
);
4969 defsubr (&Sx_draw_rectangle
);
4970 defsubr (&Sx_erase_rectangle
);
4971 defsubr (&Sx_contour_region
);
4972 defsubr (&Sx_uncontour_region
);
4974 defsubr (&Sx_list_fonts
);
4975 defsubr (&Sx_display_color_p
);
4976 defsubr (&Sx_display_grayscale_p
);
4977 defsubr (&Sx_color_defined_p
);
4978 defsubr (&Sx_color_values
);
4979 defsubr (&Sx_server_max_request_size
);
4980 defsubr (&Sx_server_vendor
);
4981 defsubr (&Sx_server_version
);
4982 defsubr (&Sx_display_pixel_width
);
4983 defsubr (&Sx_display_pixel_height
);
4984 defsubr (&Sx_display_mm_width
);
4985 defsubr (&Sx_display_mm_height
);
4986 defsubr (&Sx_display_screens
);
4987 defsubr (&Sx_display_planes
);
4988 defsubr (&Sx_display_color_cells
);
4989 defsubr (&Sx_display_visual_class
);
4990 defsubr (&Sx_display_backing_store
);
4991 defsubr (&Sx_display_save_under
);
4993 defsubr (&Sx_rebind_key
);
4994 defsubr (&Sx_rebind_keys
);
4995 defsubr (&Sx_track_pointer
);
4996 defsubr (&Sx_grab_pointer
);
4997 defsubr (&Sx_ungrab_pointer
);
4999 defsubr (&Sx_parse_geometry
);
5000 defsubr (&Sx_create_frame
);
5001 defsubr (&Sfocus_frame
);
5002 defsubr (&Sunfocus_frame
);
5004 defsubr (&Sx_horizontal_line
);
5006 defsubr (&Sx_open_connection
);
5007 defsubr (&Sx_close_connection
);
5008 defsubr (&Sx_display_list
);
5009 defsubr (&Sx_synchronize
);
5012 #endif /* HAVE_X_WINDOWS */