1 /* Functions for the X window system.
2 Copyright (C) 1989, 92, 93, 94, 95, 96, 1997 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, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 /* Completely rewritten by Richard Stallman. */
23 /* Rewritten for X11 by Joseph Arceneaux */
28 /* This makes the fields of a Display accessible, in Xlib header files. */
29 #define XLIB_ILLEGAL_ACCESS
36 #include "dispextern.h"
38 #include "blockinput.h"
46 /* On some systems, the character-composition stuff is broken in X11R5. */
47 #if defined (HAVE_X11R5) && ! defined (HAVE_X11R6)
48 #ifdef X11R5_INHIBIT_I18N
49 #define X_I18N_INHIBITED
54 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */
55 #include "bitmaps/gray.xbm"
57 #include <X11/bitmaps/gray>
60 #include "[.bitmaps]gray.xbm"
64 #include <X11/Shell.h>
67 #include <X11/Xaw/Paned.h>
68 #include <X11/Xaw/Label.h>
69 #endif /* USE_MOTIF */
72 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
81 #include "../lwlib/lwlib.h"
83 /* Do the EDITRES protocol if running X11R5
84 Exception: HP-UX (at least version A.09.05) has X11R5 without EditRes */
85 #if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES)
87 extern void _XEditResCheckMessages ();
88 #endif /* R5 + Athena */
90 /* Unique id counter for widgets created by the Lucid Widget
92 extern LWLIB_ID widget_id_tick
;
95 /* This is part of a kludge--see lwlib/xlwmenu.c. */
96 extern XFontStruct
*xlwmenu_default_font
;
99 extern void free_frame_menubar ();
100 #endif /* USE_X_TOOLKIT */
102 #define min(a,b) ((a) < (b) ? (a) : (b))
103 #define max(a,b) ((a) > (b) ? (a) : (b))
106 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
108 #define MAXREQUEST(dpy) ((dpy)->max_request_size)
111 /* The name we're using in resource queries. Most often "emacs". */
112 Lisp_Object Vx_resource_name
;
114 /* The application class we're using in resource queries.
116 Lisp_Object Vx_resource_class
;
118 /* The background and shape of the mouse pointer, and shape when not
119 over text or in the modeline. */
120 Lisp_Object Vx_pointer_shape
, Vx_nontext_pointer_shape
, Vx_mode_pointer_shape
;
121 /* The shape when over mouse-sensitive text. */
122 Lisp_Object Vx_sensitive_text_pointer_shape
;
124 /* Color of chars displayed in cursor box. */
125 Lisp_Object Vx_cursor_fore_pixel
;
127 /* Nonzero if using X. */
130 /* Non nil if no window manager is in use. */
131 Lisp_Object Vx_no_window_manager
;
133 /* Search path for bitmap files. */
134 Lisp_Object Vx_bitmap_file_path
;
136 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
137 Lisp_Object Vx_pixel_size_width_font_regexp
;
139 /* Evaluate this expression to rebuild the section of syms_of_xfns
140 that initializes and staticpros the symbols declared below. Note
141 that Emacs 18 has a bug that keeps C-x C-e from being able to
142 evaluate this expression.
145 ;; Accumulate a list of the symbols we want to initialize from the
146 ;; declarations at the top of the file.
147 (goto-char (point-min))
148 (search-forward "/\*&&& symbols declared here &&&*\/\n")
150 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
152 (cons (buffer-substring (match-beginning 1) (match-end 1))
155 (setq symbol-list (nreverse symbol-list))
156 ;; Delete the section of syms_of_... where we initialize the symbols.
157 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
158 (let ((start (point)))
159 (while (looking-at "^ Q")
161 (kill-region start (point)))
162 ;; Write a new symbol initialization section.
164 (insert (format " %s = intern (\"" (car symbol-list)))
165 (let ((start (point)))
166 (insert (substring (car symbol-list) 1))
167 (subst-char-in-region start (point) ?_ ?-))
168 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
169 (setq symbol-list (cdr symbol-list)))))
173 /*&&& symbols declared here &&&*/
174 Lisp_Object Qauto_raise
;
175 Lisp_Object Qauto_lower
;
176 Lisp_Object Qbackground_color
;
178 Lisp_Object Qborder_color
;
179 Lisp_Object Qborder_width
;
181 Lisp_Object Qcursor_color
;
182 Lisp_Object Qcursor_type
;
183 Lisp_Object Qforeground_color
;
184 Lisp_Object Qgeometry
;
185 Lisp_Object Qicon_left
;
186 Lisp_Object Qicon_top
;
187 Lisp_Object Qicon_type
;
188 Lisp_Object Qicon_name
;
189 Lisp_Object Qinternal_border_width
;
192 Lisp_Object Qmouse_color
;
194 Lisp_Object Qparent_id
;
195 Lisp_Object Qscroll_bar_width
;
196 Lisp_Object Qsuppress_icon
;
198 Lisp_Object Qundefined_color
;
199 Lisp_Object Qvertical_scroll_bars
;
200 Lisp_Object Qvisibility
;
201 Lisp_Object Qwindow_id
;
202 Lisp_Object Qx_frame_parameter
;
203 Lisp_Object Qx_resource_name
;
204 Lisp_Object Quser_position
;
205 Lisp_Object Quser_size
;
206 Lisp_Object Qdisplay
;
208 /* The below are defined in frame.c. */
209 extern Lisp_Object Qheight
, Qminibuffer
, Qname
, Qonly
, Qwidth
;
210 extern Lisp_Object Qunsplittable
, Qmenu_bar_lines
, Qbuffer_predicate
, Qtitle
;
212 extern Lisp_Object Vwindow_system_version
;
214 Lisp_Object Qface_set_after_frame_default
;
216 /* Error if we are not connected to X. */
221 error ("X windows are not in use or not initialized");
224 /* Nonzero if we can use mouse menus.
225 You should not call this unless HAVE_MENUS is defined. */
233 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
234 and checking validity for X. */
237 check_x_frame (frame
)
246 CHECK_LIVE_FRAME (frame
, 0);
250 error ("Non-X frame used");
254 /* Let the user specify an X display with a frame.
255 nil stands for the selected frame--or, if that is not an X frame,
256 the first X display on the list. */
258 static struct x_display_info
*
259 check_x_display_info (frame
)
264 if (FRAME_X_P (selected_frame
))
265 return FRAME_X_DISPLAY_INFO (selected_frame
);
266 else if (x_display_list
!= 0)
267 return x_display_list
;
269 error ("X windows are not in use or not initialized");
271 else if (STRINGP (frame
))
272 return x_display_info_for_name (frame
);
277 CHECK_LIVE_FRAME (frame
, 0);
280 error ("Non-X frame used");
281 return FRAME_X_DISPLAY_INFO (f
);
285 /* Return the Emacs frame-object corresponding to an X window.
286 It could be the frame's main window or an icon window. */
288 /* This function can be called during GC, so use GC_xxx type test macros. */
291 x_window_to_frame (dpyinfo
, wdesc
)
292 struct x_display_info
*dpyinfo
;
295 Lisp_Object tail
, frame
;
298 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
300 frame
= XCONS (tail
)->car
;
301 if (!GC_FRAMEP (frame
))
304 if (f
->output_data
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
307 if ((f
->output_data
.x
->edit_widget
308 && XtWindow (f
->output_data
.x
->edit_widget
) == wdesc
)
309 || f
->output_data
.x
->icon_desc
== wdesc
)
311 #else /* not USE_X_TOOLKIT */
312 if (FRAME_X_WINDOW (f
) == wdesc
313 || f
->output_data
.x
->icon_desc
== wdesc
)
315 #endif /* not USE_X_TOOLKIT */
321 /* Like x_window_to_frame but also compares the window with the widget's
325 x_any_window_to_frame (dpyinfo
, wdesc
)
326 struct x_display_info
*dpyinfo
;
329 Lisp_Object tail
, frame
;
333 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
335 frame
= XCONS (tail
)->car
;
336 if (!GC_FRAMEP (frame
))
339 if (f
->output_data
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
341 x
= f
->output_data
.x
;
342 /* This frame matches if the window is any of its widgets. */
343 if (wdesc
== XtWindow (x
->widget
)
344 || wdesc
== XtWindow (x
->column_widget
)
345 || wdesc
== XtWindow (x
->edit_widget
))
347 /* Match if the window is this frame's menubar. */
348 if (lw_window_is_in_menubar (wdesc
, x
->menubar_widget
))
354 /* Likewise, but exclude the menu bar widget. */
357 x_non_menubar_window_to_frame (dpyinfo
, wdesc
)
358 struct x_display_info
*dpyinfo
;
361 Lisp_Object tail
, frame
;
365 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
367 frame
= XCONS (tail
)->car
;
368 if (!GC_FRAMEP (frame
))
371 if (f
->output_data
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
373 x
= f
->output_data
.x
;
374 /* This frame matches if the window is any of its widgets. */
375 if (wdesc
== XtWindow (x
->widget
)
376 || wdesc
== XtWindow (x
->column_widget
)
377 || wdesc
== XtWindow (x
->edit_widget
))
383 /* Likewise, but consider only the menu bar widget. */
386 x_menubar_window_to_frame (dpyinfo
, wdesc
)
387 struct x_display_info
*dpyinfo
;
390 Lisp_Object tail
, frame
;
394 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
396 frame
= XCONS (tail
)->car
;
397 if (!GC_FRAMEP (frame
))
400 if (f
->output_data
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
402 x
= f
->output_data
.x
;
403 /* Match if the window is this frame's menubar. */
404 if (lw_window_is_in_menubar (wdesc
, x
->menubar_widget
))
410 /* Return the frame whose principal (outermost) window is WDESC.
411 If WDESC is some other (smaller) window, we return 0. */
414 x_top_window_to_frame (dpyinfo
, wdesc
)
415 struct x_display_info
*dpyinfo
;
418 Lisp_Object tail
, frame
;
422 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
424 frame
= XCONS (tail
)->car
;
425 if (!GC_FRAMEP (frame
))
428 if (f
->output_data
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
430 x
= f
->output_data
.x
;
431 /* This frame matches if the window is its topmost widget. */
432 if (wdesc
== XtWindow (x
->widget
))
434 #if 0 /* I don't know why it did this,
435 but it seems logically wrong,
436 and it causes trouble for MapNotify events. */
437 /* Match if the window is this frame's menubar. */
438 if (x
->menubar_widget
439 && wdesc
== XtWindow (x
->menubar_widget
))
445 #endif /* USE_X_TOOLKIT */
449 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
450 id, which is just an int that this section returns. Bitmaps are
451 reference counted so they can be shared among frames.
453 Bitmap indices are guaranteed to be > 0, so a negative number can
454 be used to indicate no bitmap.
456 If you use x_create_bitmap_from_data, then you must keep track of
457 the bitmaps yourself. That is, creating a bitmap from the same
458 data more than once will not be caught. */
461 /* Functions to access the contents of a bitmap, given an id. */
464 x_bitmap_height (f
, id
)
468 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].height
;
472 x_bitmap_width (f
, id
)
476 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].width
;
480 x_bitmap_pixmap (f
, id
)
484 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].pixmap
;
488 /* Allocate a new bitmap record. Returns index of new record. */
491 x_allocate_bitmap_record (f
)
494 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
497 if (dpyinfo
->bitmaps
== NULL
)
499 dpyinfo
->bitmaps_size
= 10;
501 = (struct x_bitmap_record
*) xmalloc (dpyinfo
->bitmaps_size
* sizeof (struct x_bitmap_record
));
502 dpyinfo
->bitmaps_last
= 1;
506 if (dpyinfo
->bitmaps_last
< dpyinfo
->bitmaps_size
)
507 return ++dpyinfo
->bitmaps_last
;
509 for (i
= 0; i
< dpyinfo
->bitmaps_size
; ++i
)
510 if (dpyinfo
->bitmaps
[i
].refcount
== 0)
513 dpyinfo
->bitmaps_size
*= 2;
515 = (struct x_bitmap_record
*) xrealloc (dpyinfo
->bitmaps
,
516 dpyinfo
->bitmaps_size
* sizeof (struct x_bitmap_record
));
517 return ++dpyinfo
->bitmaps_last
;
520 /* Add one reference to the reference count of the bitmap with id ID. */
523 x_reference_bitmap (f
, id
)
527 ++FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].refcount
;
530 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
533 x_create_bitmap_from_data (f
, bits
, width
, height
)
536 unsigned int width
, height
;
538 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
542 bitmap
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
543 bits
, width
, height
);
548 id
= x_allocate_bitmap_record (f
);
549 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
550 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
551 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
552 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
553 dpyinfo
->bitmaps
[id
- 1].height
= height
;
554 dpyinfo
->bitmaps
[id
- 1].width
= width
;
559 /* Create bitmap from file FILE for frame F. */
562 x_create_bitmap_from_file (f
, file
)
566 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
567 unsigned int width
, height
;
569 int xhot
, yhot
, result
, id
;
574 /* Look for an existing bitmap with the same name. */
575 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
577 if (dpyinfo
->bitmaps
[id
].refcount
578 && dpyinfo
->bitmaps
[id
].file
579 && !strcmp (dpyinfo
->bitmaps
[id
].file
, (char *) XSTRING (file
)->data
))
581 ++dpyinfo
->bitmaps
[id
].refcount
;
586 /* Search bitmap-file-path for the file, if appropriate. */
587 fd
= openp (Vx_bitmap_file_path
, file
, "", &found
, 0);
592 filename
= (char *) XSTRING (found
)->data
;
594 result
= XReadBitmapFile (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
595 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
596 if (result
!= BitmapSuccess
)
599 id
= x_allocate_bitmap_record (f
);
600 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
601 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
602 dpyinfo
->bitmaps
[id
- 1].file
603 = (char *) xmalloc (STRING_BYTES (XSTRING (file
)) + 1);
604 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
605 dpyinfo
->bitmaps
[id
- 1].height
= height
;
606 dpyinfo
->bitmaps
[id
- 1].width
= width
;
607 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, XSTRING (file
)->data
);
612 /* Remove reference to bitmap with id number ID. */
615 x_destroy_bitmap (f
, id
)
619 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
623 --dpyinfo
->bitmaps
[id
- 1].refcount
;
624 if (dpyinfo
->bitmaps
[id
- 1].refcount
== 0)
627 XFreePixmap (FRAME_X_DISPLAY (f
), dpyinfo
->bitmaps
[id
- 1].pixmap
);
628 if (dpyinfo
->bitmaps
[id
- 1].file
)
630 free (dpyinfo
->bitmaps
[id
- 1].file
);
631 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
638 /* Free all the bitmaps for the display specified by DPYINFO. */
641 x_destroy_all_bitmaps (dpyinfo
)
642 struct x_display_info
*dpyinfo
;
645 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++)
646 if (dpyinfo
->bitmaps
[i
].refcount
> 0)
648 XFreePixmap (dpyinfo
->display
, dpyinfo
->bitmaps
[i
].pixmap
);
649 if (dpyinfo
->bitmaps
[i
].file
)
650 free (dpyinfo
->bitmaps
[i
].file
);
652 dpyinfo
->bitmaps_last
= 0;
655 /* Connect the frame-parameter names for X frames
656 to the ways of passing the parameter values to the window system.
658 The name of a parameter, as a Lisp symbol,
659 has an `x-frame-parameter' property which is an integer in Lisp
660 that is an index in this table. */
662 struct x_frame_parm_table
665 void (*setter
)( /* struct frame *frame, Lisp_Object val, oldval */ );
668 void x_set_foreground_color ();
669 void x_set_background_color ();
670 void x_set_mouse_color ();
671 void x_set_cursor_color ();
672 void x_set_border_color ();
673 void x_set_cursor_type ();
674 void x_set_icon_type ();
675 void x_set_icon_name ();
677 void x_set_border_width ();
678 void x_set_internal_border_width ();
679 void x_explicitly_set_name ();
680 void x_set_autoraise ();
681 void x_set_autolower ();
682 void x_set_vertical_scroll_bars ();
683 void x_set_visibility ();
684 void x_set_menu_bar_lines ();
685 void x_set_scroll_bar_width ();
687 void x_set_unsplittable ();
689 static struct x_frame_parm_table x_frame_parms
[] =
691 "auto-raise", x_set_autoraise
,
692 "auto-lower", x_set_autolower
,
693 "background-color", x_set_background_color
,
694 "border-color", x_set_border_color
,
695 "border-width", x_set_border_width
,
696 "cursor-color", x_set_cursor_color
,
697 "cursor-type", x_set_cursor_type
,
699 "foreground-color", x_set_foreground_color
,
700 "icon-name", x_set_icon_name
,
701 "icon-type", x_set_icon_type
,
702 "internal-border-width", x_set_internal_border_width
,
703 "menu-bar-lines", x_set_menu_bar_lines
,
704 "mouse-color", x_set_mouse_color
,
705 "name", x_explicitly_set_name
,
706 "scroll-bar-width", x_set_scroll_bar_width
,
707 "title", x_set_title
,
708 "unsplittable", x_set_unsplittable
,
709 "vertical-scroll-bars", x_set_vertical_scroll_bars
,
710 "visibility", x_set_visibility
,
713 /* Attach the `x-frame-parameter' properties to
714 the Lisp symbol names of parameters relevant to X. */
716 init_x_parm_symbols ()
720 for (i
= 0; i
< sizeof (x_frame_parms
) / sizeof (x_frame_parms
[0]); i
++)
721 Fput (intern (x_frame_parms
[i
].name
), Qx_frame_parameter
,
725 /* Change the parameters of frame F as specified by ALIST.
726 If a parameter is not specially recognized, do nothing;
727 otherwise call the `x_set_...' function for that parameter. */
730 x_set_frame_parameters (f
, alist
)
736 /* If both of these parameters are present, it's more efficient to
737 set them both at once. So we wait until we've looked at the
738 entire list before we set them. */
742 Lisp_Object left
, top
;
744 /* Same with these. */
745 Lisp_Object icon_left
, icon_top
;
747 /* Record in these vectors all the parms specified. */
751 int left_no_change
= 0, top_no_change
= 0;
752 int icon_left_no_change
= 0, icon_top_no_change
= 0;
755 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
758 parms
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
759 values
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
761 /* Extract parm names and values into those vectors. */
764 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
766 Lisp_Object elt
, prop
, val
;
769 parms
[i
] = Fcar (elt
);
770 values
[i
] = Fcdr (elt
);
774 top
= left
= Qunbound
;
775 icon_left
= icon_top
= Qunbound
;
777 /* Provide default values for HEIGHT and WIDTH. */
778 if (FRAME_NEW_WIDTH (f
))
779 width
= FRAME_NEW_WIDTH (f
);
781 width
= FRAME_WIDTH (f
);
783 if (FRAME_NEW_HEIGHT (f
))
784 height
= FRAME_NEW_HEIGHT (f
);
786 height
= FRAME_HEIGHT (f
);
788 /* Now process them in reverse of specified order. */
789 for (i
--; i
>= 0; i
--)
791 Lisp_Object prop
, val
;
796 if (EQ (prop
, Qwidth
) && NUMBERP (val
))
797 width
= XFASTINT (val
);
798 else if (EQ (prop
, Qheight
) && NUMBERP (val
))
799 height
= XFASTINT (val
);
800 else if (EQ (prop
, Qtop
))
802 else if (EQ (prop
, Qleft
))
804 else if (EQ (prop
, Qicon_top
))
806 else if (EQ (prop
, Qicon_left
))
810 register Lisp_Object param_index
, old_value
;
812 param_index
= Fget (prop
, Qx_frame_parameter
);
813 old_value
= get_frame_param (f
, prop
);
814 store_frame_param (f
, prop
, val
);
815 if (NATNUMP (param_index
)
816 && (XFASTINT (param_index
)
817 < sizeof (x_frame_parms
)/sizeof (x_frame_parms
[0])))
818 (*x_frame_parms
[XINT (param_index
)].setter
)(f
, val
, old_value
);
822 /* Don't die if just one of these was set. */
823 if (EQ (left
, Qunbound
))
826 if (f
->output_data
.x
->left_pos
< 0)
827 left
= Fcons (Qplus
, Fcons (make_number (f
->output_data
.x
->left_pos
), Qnil
));
829 XSETINT (left
, f
->output_data
.x
->left_pos
);
831 if (EQ (top
, Qunbound
))
834 if (f
->output_data
.x
->top_pos
< 0)
835 top
= Fcons (Qplus
, Fcons (make_number (f
->output_data
.x
->top_pos
), Qnil
));
837 XSETINT (top
, f
->output_data
.x
->top_pos
);
840 /* If one of the icon positions was not set, preserve or default it. */
841 if (EQ (icon_left
, Qunbound
) || ! INTEGERP (icon_left
))
843 icon_left_no_change
= 1;
844 icon_left
= Fcdr (Fassq (Qicon_left
, f
->param_alist
));
845 if (NILP (icon_left
))
846 XSETINT (icon_left
, 0);
848 if (EQ (icon_top
, Qunbound
) || ! INTEGERP (icon_top
))
850 icon_top_no_change
= 1;
851 icon_top
= Fcdr (Fassq (Qicon_top
, f
->param_alist
));
853 XSETINT (icon_top
, 0);
856 /* Don't set these parameters unless they've been explicitly
857 specified. The window might be mapped or resized while we're in
858 this function, and we don't want to override that unless the lisp
859 code has asked for it.
861 Don't set these parameters unless they actually differ from the
862 window's current parameters; the window may not actually exist
867 check_frame_size (f
, &height
, &width
);
869 XSETFRAME (frame
, f
);
871 if (width
!= FRAME_WIDTH (f
)
872 || height
!= FRAME_HEIGHT (f
)
873 || FRAME_NEW_HEIGHT (f
) || FRAME_NEW_WIDTH (f
))
874 Fset_frame_size (frame
, make_number (width
), make_number (height
));
876 if ((!NILP (left
) || !NILP (top
))
877 && ! (left_no_change
&& top_no_change
)
878 && ! (NUMBERP (left
) && XINT (left
) == f
->output_data
.x
->left_pos
879 && NUMBERP (top
) && XINT (top
) == f
->output_data
.x
->top_pos
))
884 /* Record the signs. */
885 f
->output_data
.x
->size_hint_flags
&= ~ (XNegative
| YNegative
);
886 if (EQ (left
, Qminus
))
887 f
->output_data
.x
->size_hint_flags
|= XNegative
;
888 else if (INTEGERP (left
))
890 leftpos
= XINT (left
);
892 f
->output_data
.x
->size_hint_flags
|= XNegative
;
894 else if (CONSP (left
) && EQ (XCONS (left
)->car
, Qminus
)
895 && CONSP (XCONS (left
)->cdr
)
896 && INTEGERP (XCONS (XCONS (left
)->cdr
)->car
))
898 leftpos
= - XINT (XCONS (XCONS (left
)->cdr
)->car
);
899 f
->output_data
.x
->size_hint_flags
|= XNegative
;
901 else if (CONSP (left
) && EQ (XCONS (left
)->car
, Qplus
)
902 && CONSP (XCONS (left
)->cdr
)
903 && INTEGERP (XCONS (XCONS (left
)->cdr
)->car
))
905 leftpos
= XINT (XCONS (XCONS (left
)->cdr
)->car
);
908 if (EQ (top
, Qminus
))
909 f
->output_data
.x
->size_hint_flags
|= YNegative
;
910 else if (INTEGERP (top
))
914 f
->output_data
.x
->size_hint_flags
|= YNegative
;
916 else if (CONSP (top
) && EQ (XCONS (top
)->car
, Qminus
)
917 && CONSP (XCONS (top
)->cdr
)
918 && INTEGERP (XCONS (XCONS (top
)->cdr
)->car
))
920 toppos
= - XINT (XCONS (XCONS (top
)->cdr
)->car
);
921 f
->output_data
.x
->size_hint_flags
|= YNegative
;
923 else if (CONSP (top
) && EQ (XCONS (top
)->car
, Qplus
)
924 && CONSP (XCONS (top
)->cdr
)
925 && INTEGERP (XCONS (XCONS (top
)->cdr
)->car
))
927 toppos
= XINT (XCONS (XCONS (top
)->cdr
)->car
);
931 /* Store the numeric value of the position. */
932 f
->output_data
.x
->top_pos
= toppos
;
933 f
->output_data
.x
->left_pos
= leftpos
;
935 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
937 /* Actually set that position, and convert to absolute. */
938 x_set_offset (f
, leftpos
, toppos
, -1);
941 if ((!NILP (icon_left
) || !NILP (icon_top
))
942 && ! (icon_left_no_change
&& icon_top_no_change
))
943 x_wm_set_icon_position (f
, XINT (icon_left
), XINT (icon_top
));
947 /* Store the screen positions of frame F into XPTR and YPTR.
948 These are the positions of the containing window manager window,
949 not Emacs's own window. */
952 x_real_positions (f
, xptr
, yptr
)
959 /* This is pretty gross, but seems to be the easiest way out of
960 the problem that arises when restarting window-managers. */
963 Window outer
= XtWindow (f
->output_data
.x
->widget
);
965 Window outer
= f
->output_data
.x
->window_desc
;
967 Window tmp_root_window
;
968 Window
*tmp_children
;
973 int count
= x_catch_errors (FRAME_X_DISPLAY (f
));
976 XQueryTree (FRAME_X_DISPLAY (f
), outer
, &tmp_root_window
,
977 &f
->output_data
.x
->parent_desc
,
978 &tmp_children
, &tmp_nchildren
);
979 XFree ((char *) tmp_children
);
983 /* Find the position of the outside upper-left corner of
984 the inner window, with respect to the outer window. */
985 if (f
->output_data
.x
->parent_desc
!= FRAME_X_DISPLAY_INFO (f
)->root_window
)
986 outer_window
= f
->output_data
.x
->parent_desc
;
988 outer_window
= outer
;
990 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
992 /* From-window, to-window. */
994 FRAME_X_DISPLAY_INFO (f
)->root_window
,
996 /* From-position, to-position. */
997 0, 0, &win_x
, &win_y
,
1002 /* It is possible for the window returned by the XQueryNotify
1003 to become invalid by the time we call XTranslateCoordinates.
1004 That can happen when you restart some window managers.
1005 If so, we get an error in XTranslateCoordinates.
1006 Detect that and try the whole thing over. */
1007 if (! x_had_errors_p (FRAME_X_DISPLAY (f
)))
1009 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
1013 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
1016 *xptr
= win_x
- f
->output_data
.x
->border_width
;
1017 *yptr
= win_y
- f
->output_data
.x
->border_width
;
1020 /* Insert a description of internally-recorded parameters of frame X
1021 into the parameter alist *ALISTPTR that is to be given to the user.
1022 Only parameters that are specific to the X window system
1023 and whose values are not correctly recorded in the frame's
1024 param_alist need to be considered here. */
1027 x_report_frame_params (f
, alistptr
)
1029 Lisp_Object
*alistptr
;
1034 /* Represent negative positions (off the top or left screen edge)
1035 in a way that Fmodify_frame_parameters will understand correctly. */
1036 XSETINT (tem
, f
->output_data
.x
->left_pos
);
1037 if (f
->output_data
.x
->left_pos
>= 0)
1038 store_in_alist (alistptr
, Qleft
, tem
);
1040 store_in_alist (alistptr
, Qleft
, Fcons (Qplus
, Fcons (tem
, Qnil
)));
1042 XSETINT (tem
, f
->output_data
.x
->top_pos
);
1043 if (f
->output_data
.x
->top_pos
>= 0)
1044 store_in_alist (alistptr
, Qtop
, tem
);
1046 store_in_alist (alistptr
, Qtop
, Fcons (Qplus
, Fcons (tem
, Qnil
)));
1048 store_in_alist (alistptr
, Qborder_width
,
1049 make_number (f
->output_data
.x
->border_width
));
1050 store_in_alist (alistptr
, Qinternal_border_width
,
1051 make_number (f
->output_data
.x
->internal_border_width
));
1052 sprintf (buf
, "%ld", (long) FRAME_X_WINDOW (f
));
1053 store_in_alist (alistptr
, Qwindow_id
,
1054 build_string (buf
));
1055 store_in_alist (alistptr
, Qicon_name
, f
->icon_name
);
1056 FRAME_SAMPLE_VISIBILITY (f
);
1057 store_in_alist (alistptr
, Qvisibility
,
1058 (FRAME_VISIBLE_P (f
) ? Qt
1059 : FRAME_ICONIFIED_P (f
) ? Qicon
: Qnil
));
1060 store_in_alist (alistptr
, Qdisplay
,
1061 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->car
);
1063 if (f
->output_data
.x
->parent_desc
== FRAME_X_DISPLAY_INFO (f
)->root_window
)
1066 XSETFASTINT (tem
, f
->output_data
.x
->parent_desc
);
1067 store_in_alist (alistptr
, Qparent_id
, tem
);
1071 /* Decide if color named COLOR is valid for the display associated with
1072 the selected frame; if so, return the rgb values in COLOR_DEF.
1073 If ALLOC is nonzero, allocate a new colormap cell. */
1076 defined_color (f
, color
, color_def
, alloc
)
1082 register int status
;
1083 Colormap screen_colormap
;
1084 Display
*display
= FRAME_X_DISPLAY (f
);
1087 screen_colormap
= DefaultColormap (display
, XDefaultScreen (display
));
1089 status
= XParseColor (display
, screen_colormap
, color
, color_def
);
1090 if (status
&& alloc
)
1092 status
= XAllocColor (display
, screen_colormap
, color_def
);
1095 /* If we got to this point, the colormap is full, so we're
1096 going to try and get the next closest color.
1097 The algorithm used is a least-squares matching, which is
1098 what X uses for closest color matching with StaticColor visuals. */
1103 long nearest_delta
, trial_delta
;
1106 no_cells
= XDisplayCells (display
, XDefaultScreen (display
));
1107 cells
= (XColor
*) alloca (sizeof (XColor
) * no_cells
);
1109 for (x
= 0; x
< no_cells
; x
++)
1112 XQueryColors (display
, screen_colormap
, cells
, no_cells
);
1114 /* I'm assuming CSE so I'm not going to condense this. */
1115 nearest_delta
= ((((color_def
->red
>> 8) - (cells
[0].red
>> 8))
1116 * ((color_def
->red
>> 8) - (cells
[0].red
>> 8)))
1118 (((color_def
->green
>> 8) - (cells
[0].green
>> 8))
1119 * ((color_def
->green
>> 8) - (cells
[0].green
>> 8)))
1121 (((color_def
->blue
>> 8) - (cells
[0].blue
>> 8))
1122 * ((color_def
->blue
>> 8) - (cells
[0].blue
>> 8))));
1123 for (x
= 1; x
< no_cells
; x
++)
1125 trial_delta
= ((((color_def
->red
>> 8) - (cells
[x
].red
>> 8))
1126 * ((color_def
->red
>> 8) - (cells
[x
].red
>> 8)))
1128 (((color_def
->green
>> 8) - (cells
[x
].green
>> 8))
1129 * ((color_def
->green
>> 8) - (cells
[x
].green
>> 8)))
1131 (((color_def
->blue
>> 8) - (cells
[x
].blue
>> 8))
1132 * ((color_def
->blue
>> 8) - (cells
[x
].blue
>> 8))));
1133 if (trial_delta
< nearest_delta
)
1136 temp
.red
= cells
[x
].red
;
1137 temp
.green
= cells
[x
].green
;
1138 temp
.blue
= cells
[x
].blue
;
1139 status
= XAllocColor (display
, screen_colormap
, &temp
);
1143 nearest_delta
= trial_delta
;
1147 color_def
->red
= cells
[nearest
].red
;
1148 color_def
->green
= cells
[nearest
].green
;
1149 color_def
->blue
= cells
[nearest
].blue
;
1150 status
= XAllocColor (display
, screen_colormap
, color_def
);
1161 /* Given a string ARG naming a color, compute a pixel value from it
1162 suitable for screen F.
1163 If F is not a color screen, return DEF (default) regardless of what
1167 x_decode_color (f
, arg
, def
)
1174 CHECK_STRING (arg
, 0);
1176 if (strcmp (XSTRING (arg
)->data
, "black") == 0)
1177 return BLACK_PIX_DEFAULT (f
);
1178 else if (strcmp (XSTRING (arg
)->data
, "white") == 0)
1179 return WHITE_PIX_DEFAULT (f
);
1181 if (FRAME_X_DISPLAY_INFO (f
)->n_planes
== 1)
1184 /* defined_color is responsible for coping with failures
1185 by looking for a near-miss. */
1186 if (defined_color (f
, XSTRING (arg
)->data
, &cdef
, 1))
1189 Fsignal (Qerror
, Fcons (build_string ("undefined color"),
1190 Fcons (arg
, Qnil
)));
1193 /* Functions called only from `x_set_frame_param'
1194 to set individual parameters.
1196 If FRAME_X_WINDOW (f) is 0,
1197 the frame is being created and its X-window does not exist yet.
1198 In that case, just record the parameter's new value
1199 in the standard place; do not attempt to change the window. */
1202 x_set_foreground_color (f
, arg
, oldval
)
1204 Lisp_Object arg
, oldval
;
1206 f
->output_data
.x
->foreground_pixel
1207 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1208 if (FRAME_X_WINDOW (f
) != 0)
1211 XSetForeground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->normal_gc
,
1212 f
->output_data
.x
->foreground_pixel
);
1213 XSetBackground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->reverse_gc
,
1214 f
->output_data
.x
->foreground_pixel
);
1216 recompute_basic_faces (f
);
1217 if (FRAME_VISIBLE_P (f
))
1223 x_set_background_color (f
, arg
, oldval
)
1225 Lisp_Object arg
, oldval
;
1230 f
->output_data
.x
->background_pixel
1231 = x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
1233 if (FRAME_X_WINDOW (f
) != 0)
1236 /* The main frame area. */
1237 XSetBackground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->normal_gc
,
1238 f
->output_data
.x
->background_pixel
);
1239 XSetForeground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->reverse_gc
,
1240 f
->output_data
.x
->background_pixel
);
1241 XSetForeground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->cursor_gc
,
1242 f
->output_data
.x
->background_pixel
);
1243 XSetWindowBackground (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1244 f
->output_data
.x
->background_pixel
);
1247 for (bar
= FRAME_SCROLL_BARS (f
); !NILP (bar
);
1248 bar
= XSCROLL_BAR (bar
)->next
)
1249 XSetWindowBackground (FRAME_X_DISPLAY (f
),
1250 SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
)),
1251 f
->output_data
.x
->background_pixel
);
1255 recompute_basic_faces (f
);
1257 if (FRAME_VISIBLE_P (f
))
1263 x_set_mouse_color (f
, arg
, oldval
)
1265 Lisp_Object arg
, oldval
;
1267 Cursor cursor
, nontext_cursor
, mode_cursor
, cross_cursor
;
1271 if (!EQ (Qnil
, arg
))
1272 f
->output_data
.x
->mouse_pixel
1273 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1274 mask_color
= f
->output_data
.x
->background_pixel
;
1275 /* No invisible pointers. */
1276 if (mask_color
== f
->output_data
.x
->mouse_pixel
1277 && mask_color
== f
->output_data
.x
->background_pixel
)
1278 f
->output_data
.x
->mouse_pixel
= f
->output_data
.x
->foreground_pixel
;
1282 /* It's not okay to crash if the user selects a screwy cursor. */
1283 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
1285 if (!EQ (Qnil
, Vx_pointer_shape
))
1287 CHECK_NUMBER (Vx_pointer_shape
, 0);
1288 cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XINT (Vx_pointer_shape
));
1291 cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_xterm
);
1292 x_check_errors (FRAME_X_DISPLAY (f
), "bad text pointer cursor: %s");
1294 if (!EQ (Qnil
, Vx_nontext_pointer_shape
))
1296 CHECK_NUMBER (Vx_nontext_pointer_shape
, 0);
1297 nontext_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
),
1298 XINT (Vx_nontext_pointer_shape
));
1301 nontext_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_left_ptr
);
1302 x_check_errors (FRAME_X_DISPLAY (f
), "bad nontext pointer cursor: %s");
1304 if (!EQ (Qnil
, Vx_mode_pointer_shape
))
1306 CHECK_NUMBER (Vx_mode_pointer_shape
, 0);
1307 mode_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
),
1308 XINT (Vx_mode_pointer_shape
));
1311 mode_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_xterm
);
1312 x_check_errors (FRAME_X_DISPLAY (f
), "bad modeline pointer cursor: %s");
1314 if (!EQ (Qnil
, Vx_sensitive_text_pointer_shape
))
1316 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
, 0);
1318 = XCreateFontCursor (FRAME_X_DISPLAY (f
),
1319 XINT (Vx_sensitive_text_pointer_shape
));
1322 cross_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_crosshair
);
1324 /* Check and report errors with the above calls. */
1325 x_check_errors (FRAME_X_DISPLAY (f
), "can't set cursor shape: %s");
1326 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
1329 XColor fore_color
, back_color
;
1331 fore_color
.pixel
= f
->output_data
.x
->mouse_pixel
;
1332 back_color
.pixel
= mask_color
;
1333 XQueryColor (FRAME_X_DISPLAY (f
),
1334 DefaultColormap (FRAME_X_DISPLAY (f
),
1335 DefaultScreen (FRAME_X_DISPLAY (f
))),
1337 XQueryColor (FRAME_X_DISPLAY (f
),
1338 DefaultColormap (FRAME_X_DISPLAY (f
),
1339 DefaultScreen (FRAME_X_DISPLAY (f
))),
1341 XRecolorCursor (FRAME_X_DISPLAY (f
), cursor
,
1342 &fore_color
, &back_color
);
1343 XRecolorCursor (FRAME_X_DISPLAY (f
), nontext_cursor
,
1344 &fore_color
, &back_color
);
1345 XRecolorCursor (FRAME_X_DISPLAY (f
), mode_cursor
,
1346 &fore_color
, &back_color
);
1347 XRecolorCursor (FRAME_X_DISPLAY (f
), cross_cursor
,
1348 &fore_color
, &back_color
);
1351 if (FRAME_X_WINDOW (f
) != 0)
1353 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
1356 if (cursor
!= f
->output_data
.x
->text_cursor
&& f
->output_data
.x
->text_cursor
!= 0)
1357 XFreeCursor (FRAME_X_DISPLAY (f
), f
->output_data
.x
->text_cursor
);
1358 f
->output_data
.x
->text_cursor
= cursor
;
1360 if (nontext_cursor
!= f
->output_data
.x
->nontext_cursor
1361 && f
->output_data
.x
->nontext_cursor
!= 0)
1362 XFreeCursor (FRAME_X_DISPLAY (f
), f
->output_data
.x
->nontext_cursor
);
1363 f
->output_data
.x
->nontext_cursor
= nontext_cursor
;
1365 if (mode_cursor
!= f
->output_data
.x
->modeline_cursor
1366 && f
->output_data
.x
->modeline_cursor
!= 0)
1367 XFreeCursor (FRAME_X_DISPLAY (f
), f
->output_data
.x
->modeline_cursor
);
1368 f
->output_data
.x
->modeline_cursor
= mode_cursor
;
1369 if (cross_cursor
!= f
->output_data
.x
->cross_cursor
1370 && f
->output_data
.x
->cross_cursor
!= 0)
1371 XFreeCursor (FRAME_X_DISPLAY (f
), f
->output_data
.x
->cross_cursor
);
1372 f
->output_data
.x
->cross_cursor
= cross_cursor
;
1374 XFlush (FRAME_X_DISPLAY (f
));
1379 x_set_cursor_color (f
, arg
, oldval
)
1381 Lisp_Object arg
, oldval
;
1383 unsigned long fore_pixel
;
1385 if (!EQ (Vx_cursor_fore_pixel
, Qnil
))
1386 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
1387 WHITE_PIX_DEFAULT (f
));
1389 fore_pixel
= f
->output_data
.x
->background_pixel
;
1390 f
->output_data
.x
->cursor_pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1392 /* Make sure that the cursor color differs from the background color. */
1393 if (f
->output_data
.x
->cursor_pixel
== f
->output_data
.x
->background_pixel
)
1395 f
->output_data
.x
->cursor_pixel
= f
->output_data
.x
->mouse_pixel
;
1396 if (f
->output_data
.x
->cursor_pixel
== fore_pixel
)
1397 fore_pixel
= f
->output_data
.x
->background_pixel
;
1399 f
->output_data
.x
->cursor_foreground_pixel
= fore_pixel
;
1401 if (FRAME_X_WINDOW (f
) != 0)
1404 XSetBackground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->cursor_gc
,
1405 f
->output_data
.x
->cursor_pixel
);
1406 XSetForeground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->cursor_gc
,
1410 if (FRAME_VISIBLE_P (f
))
1412 x_update_cursor (f
, 0);
1413 x_update_cursor (f
, 1);
1418 /* Set the border-color of frame F to value described by ARG.
1419 ARG can be a string naming a color.
1420 The border-color is used for the border that is drawn by the X server.
1421 Note that this does not fully take effect if done before
1422 F has an x-window; it must be redone when the window is created.
1424 Note: this is done in two routines because of the way X10 works.
1426 Note: under X11, this is normally the province of the window manager,
1427 and so emacs' border colors may be overridden. */
1430 x_set_border_color (f
, arg
, oldval
)
1432 Lisp_Object arg
, oldval
;
1437 CHECK_STRING (arg
, 0);
1438 str
= XSTRING (arg
)->data
;
1440 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1442 x_set_border_pixel (f
, pix
);
1445 /* Set the border-color of frame F to pixel value PIX.
1446 Note that this does not fully take effect if done before
1447 F has an x-window. */
1450 x_set_border_pixel (f
, pix
)
1454 f
->output_data
.x
->border_pixel
= pix
;
1456 if (FRAME_X_WINDOW (f
) != 0 && f
->output_data
.x
->border_width
> 0)
1462 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1463 (unsigned long)pix
);
1466 if (FRAME_VISIBLE_P (f
))
1472 x_set_cursor_type (f
, arg
, oldval
)
1474 Lisp_Object arg
, oldval
;
1478 FRAME_DESIRED_CURSOR (f
) = bar_cursor
;
1479 f
->output_data
.x
->cursor_width
= 2;
1481 else if (CONSP (arg
) && EQ (XCONS (arg
)->car
, Qbar
)
1482 && INTEGERP (XCONS (arg
)->cdr
))
1484 FRAME_DESIRED_CURSOR (f
) = bar_cursor
;
1485 f
->output_data
.x
->cursor_width
= XINT (XCONS (arg
)->cdr
);
1488 /* Treat anything unknown as "box cursor".
1489 It was bad to signal an error; people have trouble fixing
1490 .Xdefaults with Emacs, when it has something bad in it. */
1491 FRAME_DESIRED_CURSOR (f
) = filled_box_cursor
;
1493 /* Make sure the cursor gets redrawn. This is overkill, but how
1494 often do people change cursor types? */
1495 update_mode_lines
++;
1499 x_set_icon_type (f
, arg
, oldval
)
1501 Lisp_Object arg
, oldval
;
1508 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1511 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1516 result
= x_text_icon (f
,
1517 (char *) XSTRING ((!NILP (f
->icon_name
)
1521 result
= x_bitmap_icon (f
, arg
);
1526 error ("No icon window available");
1529 XFlush (FRAME_X_DISPLAY (f
));
1533 /* Return non-nil if frame F wants a bitmap icon. */
1541 tem
= assq_no_quit (Qicon_type
, f
->param_alist
);
1543 return XCONS (tem
)->cdr
;
1549 x_set_icon_name (f
, arg
, oldval
)
1551 Lisp_Object arg
, oldval
;
1558 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1561 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1566 if (f
->output_data
.x
->icon_bitmap
!= 0)
1571 result
= x_text_icon (f
,
1572 (char *) XSTRING ((!NILP (f
->icon_name
)
1581 error ("No icon window available");
1584 XFlush (FRAME_X_DISPLAY (f
));
1588 extern Lisp_Object
x_new_font ();
1589 extern Lisp_Object
x_new_fontset ();
1590 extern Lisp_Object
Fquery_fontset ();
1593 x_set_font (f
, arg
, oldval
)
1595 Lisp_Object arg
, oldval
;
1598 Lisp_Object fontset_name
;
1601 CHECK_STRING (arg
, 1);
1603 fontset_name
= Fquery_fontset (arg
, Qnil
);
1606 result
= (STRINGP (fontset_name
)
1607 ? x_new_fontset (f
, XSTRING (fontset_name
)->data
)
1608 : x_new_font (f
, XSTRING (arg
)->data
));
1611 if (EQ (result
, Qnil
))
1612 error ("Font `%s' is not defined", XSTRING (arg
)->data
);
1613 else if (EQ (result
, Qt
))
1614 error ("the characters of the given font have varying widths");
1615 else if (STRINGP (result
))
1617 recompute_basic_faces (f
);
1618 store_frame_param (f
, Qfont
, result
);
1623 XSETFRAME (frame
, f
);
1624 call1 (Qface_set_after_frame_default
, frame
);
1628 x_set_border_width (f
, arg
, oldval
)
1630 Lisp_Object arg
, oldval
;
1632 CHECK_NUMBER (arg
, 0);
1634 if (XINT (arg
) == f
->output_data
.x
->border_width
)
1637 if (FRAME_X_WINDOW (f
) != 0)
1638 error ("Cannot change the border width of a window");
1640 f
->output_data
.x
->border_width
= XINT (arg
);
1644 x_set_internal_border_width (f
, arg
, oldval
)
1646 Lisp_Object arg
, oldval
;
1649 int old
= f
->output_data
.x
->internal_border_width
;
1651 CHECK_NUMBER (arg
, 0);
1652 f
->output_data
.x
->internal_border_width
= XINT (arg
);
1653 if (f
->output_data
.x
->internal_border_width
< 0)
1654 f
->output_data
.x
->internal_border_width
= 0;
1656 #ifdef USE_X_TOOLKIT
1657 if (f
->output_data
.x
->edit_widget
)
1658 widget_store_internal_border (f
->output_data
.x
->edit_widget
);
1661 if (f
->output_data
.x
->internal_border_width
== old
)
1664 if (FRAME_X_WINDOW (f
) != 0)
1667 x_set_window_size (f
, 0, f
->width
, f
->height
);
1669 x_set_resize_hint (f
);
1671 XFlush (FRAME_X_DISPLAY (f
));
1673 SET_FRAME_GARBAGED (f
);
1678 x_set_visibility (f
, value
, oldval
)
1680 Lisp_Object value
, oldval
;
1683 XSETFRAME (frame
, f
);
1686 Fmake_frame_invisible (frame
, Qt
);
1687 else if (EQ (value
, Qicon
))
1688 Ficonify_frame (frame
);
1690 Fmake_frame_visible (frame
);
1694 x_set_menu_bar_lines_1 (window
, n
)
1698 struct window
*w
= XWINDOW (window
);
1700 XSETFASTINT (w
->top
, XFASTINT (w
->top
) + n
);
1701 XSETFASTINT (w
->height
, XFASTINT (w
->height
) - n
);
1703 /* Handle just the top child in a vertical split. */
1704 if (!NILP (w
->vchild
))
1705 x_set_menu_bar_lines_1 (w
->vchild
, n
);
1707 /* Adjust all children in a horizontal split. */
1708 for (window
= w
->hchild
; !NILP (window
); window
= w
->next
)
1710 w
= XWINDOW (window
);
1711 x_set_menu_bar_lines_1 (window
, n
);
1716 x_set_menu_bar_lines (f
, value
, oldval
)
1718 Lisp_Object value
, oldval
;
1721 int olines
= FRAME_MENU_BAR_LINES (f
);
1723 /* Right now, menu bars don't work properly in minibuf-only frames;
1724 most of the commands try to apply themselves to the minibuffer
1725 frame itslef, and get an error because you can't switch buffers
1726 in or split the minibuffer window. */
1727 if (FRAME_MINIBUF_ONLY_P (f
))
1730 if (INTEGERP (value
))
1731 nlines
= XINT (value
);
1735 /* Make sure we redisplay all windows in this frame. */
1736 windows_or_buffers_changed
++;
1738 #ifdef USE_X_TOOLKIT
1739 FRAME_MENU_BAR_LINES (f
) = 0;
1742 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
1743 if (FRAME_X_P (f
) && f
->output_data
.x
->menubar_widget
== 0)
1744 /* Make sure next redisplay shows the menu bar. */
1745 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= Qt
;
1749 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
1750 free_frame_menubar (f
);
1751 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
1753 f
->output_data
.x
->menubar_widget
= 0;
1755 #else /* not USE_X_TOOLKIT */
1756 FRAME_MENU_BAR_LINES (f
) = nlines
;
1757 x_set_menu_bar_lines_1 (f
->root_window
, nlines
- olines
);
1758 #endif /* not USE_X_TOOLKIT */
1761 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1764 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1765 name; if NAME is a string, set F's name to NAME and set
1766 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1768 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1769 suggesting a new name, which lisp code should override; if
1770 F->explicit_name is set, ignore the new name; otherwise, set it. */
1773 x_set_name (f
, name
, explicit)
1778 /* Make sure that requests from lisp code override requests from
1779 Emacs redisplay code. */
1782 /* If we're switching from explicit to implicit, we had better
1783 update the mode lines and thereby update the title. */
1784 if (f
->explicit_name
&& NILP (name
))
1785 update_mode_lines
= 1;
1787 f
->explicit_name
= ! NILP (name
);
1789 else if (f
->explicit_name
)
1792 /* If NAME is nil, set the name to the x_id_name. */
1795 /* Check for no change needed in this very common case
1796 before we do any consing. */
1797 if (!strcmp (FRAME_X_DISPLAY_INFO (f
)->x_id_name
,
1798 XSTRING (f
->name
)->data
))
1800 name
= build_string (FRAME_X_DISPLAY_INFO (f
)->x_id_name
);
1803 CHECK_STRING (name
, 0);
1805 /* Don't change the name if it's already NAME. */
1806 if (! NILP (Fstring_equal (name
, f
->name
)))
1811 /* For setting the frame title, the title parameter should override
1812 the name parameter. */
1813 if (! NILP (f
->title
))
1816 if (FRAME_X_WINDOW (f
))
1821 XTextProperty text
, icon
;
1822 Lisp_Object icon_name
;
1824 text
.value
= XSTRING (name
)->data
;
1825 text
.encoding
= XA_STRING
;
1827 text
.nitems
= STRING_BYTES (XSTRING (name
));
1829 icon_name
= (!NILP (f
->icon_name
) ? f
->icon_name
: name
);
1831 icon
.value
= XSTRING (icon_name
)->data
;
1832 icon
.encoding
= XA_STRING
;
1834 icon
.nitems
= STRING_BYTES (XSTRING (icon_name
));
1835 #ifdef USE_X_TOOLKIT
1836 XSetWMName (FRAME_X_DISPLAY (f
),
1837 XtWindow (f
->output_data
.x
->widget
), &text
);
1838 XSetWMIconName (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
),
1840 #else /* not USE_X_TOOLKIT */
1841 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &text
);
1842 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &icon
);
1843 #endif /* not USE_X_TOOLKIT */
1845 #else /* not HAVE_X11R4 */
1846 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1847 XSTRING (name
)->data
);
1848 XStoreName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1849 XSTRING (name
)->data
);
1850 #endif /* not HAVE_X11R4 */
1855 /* This function should be called when the user's lisp code has
1856 specified a name for the frame; the name will override any set by the
1859 x_explicitly_set_name (f
, arg
, oldval
)
1861 Lisp_Object arg
, oldval
;
1863 x_set_name (f
, arg
, 1);
1866 /* This function should be called by Emacs redisplay code to set the
1867 name; names set this way will never override names set by the user's
1870 x_implicitly_set_name (f
, arg
, oldval
)
1872 Lisp_Object arg
, oldval
;
1874 x_set_name (f
, arg
, 0);
1877 /* Change the title of frame F to NAME.
1878 If NAME is nil, use the frame name as the title.
1880 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1881 name; if NAME is a string, set F's name to NAME and set
1882 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1884 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1885 suggesting a new name, which lisp code should override; if
1886 F->explicit_name is set, ignore the new name; otherwise, set it. */
1889 x_set_title (f
, name
)
1893 /* Don't change the title if it's already NAME. */
1894 if (EQ (name
, f
->title
))
1897 update_mode_lines
= 1;
1904 CHECK_STRING (name
, 0);
1906 if (FRAME_X_WINDOW (f
))
1911 XTextProperty text
, icon
;
1912 Lisp_Object icon_name
;
1914 text
.value
= XSTRING (name
)->data
;
1915 text
.encoding
= XA_STRING
;
1917 text
.nitems
= STRING_BYTES (XSTRING (name
));
1919 icon_name
= (!NILP (f
->icon_name
) ? f
->icon_name
: name
);
1921 icon
.value
= XSTRING (icon_name
)->data
;
1922 icon
.encoding
= XA_STRING
;
1924 icon
.nitems
= STRING_BYTES (XSTRING (icon_name
));
1925 #ifdef USE_X_TOOLKIT
1926 XSetWMName (FRAME_X_DISPLAY (f
),
1927 XtWindow (f
->output_data
.x
->widget
), &text
);
1928 XSetWMIconName (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
),
1930 #else /* not USE_X_TOOLKIT */
1931 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &text
);
1932 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &icon
);
1933 #endif /* not USE_X_TOOLKIT */
1935 #else /* not HAVE_X11R4 */
1936 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1937 XSTRING (name
)->data
);
1938 XStoreName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1939 XSTRING (name
)->data
);
1940 #endif /* not HAVE_X11R4 */
1946 x_set_autoraise (f
, arg
, oldval
)
1948 Lisp_Object arg
, oldval
;
1950 f
->auto_raise
= !EQ (Qnil
, arg
);
1954 x_set_autolower (f
, arg
, oldval
)
1956 Lisp_Object arg
, oldval
;
1958 f
->auto_lower
= !EQ (Qnil
, arg
);
1962 x_set_unsplittable (f
, arg
, oldval
)
1964 Lisp_Object arg
, oldval
;
1966 f
->no_split
= !NILP (arg
);
1970 x_set_vertical_scroll_bars (f
, arg
, oldval
)
1972 Lisp_Object arg
, oldval
;
1974 if ((EQ (arg
, Qleft
) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
1975 || (EQ (arg
, Qright
) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f
))
1976 || (NILP (arg
) && FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
1977 || (!NILP (arg
) && ! FRAME_HAS_VERTICAL_SCROLL_BARS (f
)))
1979 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
)
1981 ? vertical_scroll_bar_none
1983 ? vertical_scroll_bar_right
1984 : vertical_scroll_bar_left
);
1986 /* We set this parameter before creating the X window for the
1987 frame, so we can get the geometry right from the start.
1988 However, if the window hasn't been created yet, we shouldn't
1989 call x_set_window_size. */
1990 if (FRAME_X_WINDOW (f
))
1991 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
1996 x_set_scroll_bar_width (f
, arg
, oldval
)
1998 Lisp_Object arg
, oldval
;
2000 int wid
= FONT_WIDTH (f
->output_data
.x
->font
);
2004 /* Make the actual width at least 14 pixels
2005 and a multiple of a character width. */
2006 FRAME_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
2007 /* Use all of that space (aside from required margins)
2008 for the scroll bar. */
2009 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = 0;
2011 if (FRAME_X_WINDOW (f
))
2012 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
2014 else if (INTEGERP (arg
) && XINT (arg
) > 0
2015 && XFASTINT (arg
) != FRAME_SCROLL_BAR_PIXEL_WIDTH (f
))
2017 if (XFASTINT (arg
) <= 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM
)
2018 XSETINT (arg
, 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM
+ 1);
2020 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = XFASTINT (arg
);
2021 FRAME_SCROLL_BAR_COLS (f
) = (XFASTINT (arg
) + wid
-1) / wid
;
2022 if (FRAME_X_WINDOW (f
))
2023 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
2026 change_frame_size (f
, 0, FRAME_WIDTH (f
), 0, 0);
2027 FRAME_CURSOR_X (f
) = FRAME_LEFT_SCROLL_BAR_WIDTH (f
);
2030 /* Subroutines of creating an X frame. */
2032 /* Make sure that Vx_resource_name is set to a reasonable value.
2033 Fix it up, or set it to `emacs' if it is too hopeless. */
2036 validate_x_resource_name ()
2039 /* Number of valid characters in the resource name. */
2041 /* Number of invalid characters in the resource name. */
2046 if (!STRINGP (Vx_resource_class
))
2047 Vx_resource_class
= build_string (EMACS_CLASS
);
2049 if (STRINGP (Vx_resource_name
))
2051 unsigned char *p
= XSTRING (Vx_resource_name
)->data
;
2054 len
= STRING_BYTES (XSTRING (Vx_resource_name
));
2056 /* Only letters, digits, - and _ are valid in resource names.
2057 Count the valid characters and count the invalid ones. */
2058 for (i
= 0; i
< len
; i
++)
2061 if (! ((c
>= 'a' && c
<= 'z')
2062 || (c
>= 'A' && c
<= 'Z')
2063 || (c
>= '0' && c
<= '9')
2064 || c
== '-' || c
== '_'))
2071 /* Not a string => completely invalid. */
2072 bad_count
= 5, good_count
= 0;
2074 /* If name is valid already, return. */
2078 /* If name is entirely invalid, or nearly so, use `emacs'. */
2080 || (good_count
== 1 && bad_count
> 0))
2082 Vx_resource_name
= build_string ("emacs");
2086 /* Name is partly valid. Copy it and replace the invalid characters
2087 with underscores. */
2089 Vx_resource_name
= new = Fcopy_sequence (Vx_resource_name
);
2091 for (i
= 0; i
< len
; i
++)
2093 int c
= XSTRING (new)->data
[i
];
2094 if (! ((c
>= 'a' && c
<= 'z')
2095 || (c
>= 'A' && c
<= 'Z')
2096 || (c
>= '0' && c
<= '9')
2097 || c
== '-' || c
== '_'))
2098 XSTRING (new)->data
[i
] = '_';
2103 extern char *x_get_string_resource ();
2105 DEFUN ("x-get-resource", Fx_get_resource
, Sx_get_resource
, 2, 4, 0,
2106 "Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.\n\
2107 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the\n\
2108 class, where INSTANCE is the name under which Emacs was invoked, or\n\
2109 the name specified by the `-name' or `-rn' command-line arguments.\n\
2111 The optional arguments COMPONENT and SUBCLASS add to the key and the\n\
2112 class, respectively. You must specify both of them or neither.\n\
2113 If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'\n\
2114 and the class is `Emacs.CLASS.SUBCLASS'.")
2115 (attribute
, class, component
, subclass
)
2116 Lisp_Object attribute
, class, component
, subclass
;
2118 register char *value
;
2124 CHECK_STRING (attribute
, 0);
2125 CHECK_STRING (class, 0);
2127 if (!NILP (component
))
2128 CHECK_STRING (component
, 1);
2129 if (!NILP (subclass
))
2130 CHECK_STRING (subclass
, 2);
2131 if (NILP (component
) != NILP (subclass
))
2132 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
2134 validate_x_resource_name ();
2136 /* Allocate space for the components, the dots which separate them,
2137 and the final '\0'. Make them big enough for the worst case. */
2138 name_key
= (char *) alloca (STRING_BYTES (XSTRING (Vx_resource_name
))
2139 + (STRINGP (component
)
2140 ? STRING_BYTES (XSTRING (component
)) : 0)
2141 + STRING_BYTES (XSTRING (attribute
))
2144 class_key
= (char *) alloca (STRING_BYTES (XSTRING (Vx_resource_class
))
2145 + STRING_BYTES (XSTRING (class))
2146 + (STRINGP (subclass
)
2147 ? STRING_BYTES (XSTRING (subclass
)) : 0)
2150 /* Start with emacs.FRAMENAME for the name (the specific one)
2151 and with `Emacs' for the class key (the general one). */
2152 strcpy (name_key
, XSTRING (Vx_resource_name
)->data
);
2153 strcpy (class_key
, XSTRING (Vx_resource_class
)->data
);
2155 strcat (class_key
, ".");
2156 strcat (class_key
, XSTRING (class)->data
);
2158 if (!NILP (component
))
2160 strcat (class_key
, ".");
2161 strcat (class_key
, XSTRING (subclass
)->data
);
2163 strcat (name_key
, ".");
2164 strcat (name_key
, XSTRING (component
)->data
);
2167 strcat (name_key
, ".");
2168 strcat (name_key
, XSTRING (attribute
)->data
);
2170 value
= x_get_string_resource (check_x_display_info (Qnil
)->xrdb
,
2171 name_key
, class_key
);
2173 if (value
!= (char *) 0)
2174 return build_string (value
);
2179 /* Get an X resource, like Fx_get_resource, but for display DPYINFO. */
2182 display_x_get_resource (dpyinfo
, attribute
, class, component
, subclass
)
2183 struct x_display_info
*dpyinfo
;
2184 Lisp_Object attribute
, class, component
, subclass
;
2186 register char *value
;
2192 CHECK_STRING (attribute
, 0);
2193 CHECK_STRING (class, 0);
2195 if (!NILP (component
))
2196 CHECK_STRING (component
, 1);
2197 if (!NILP (subclass
))
2198 CHECK_STRING (subclass
, 2);
2199 if (NILP (component
) != NILP (subclass
))
2200 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
2202 validate_x_resource_name ();
2204 /* Allocate space for the components, the dots which separate them,
2205 and the final '\0'. Make them big enough for the worst case. */
2206 name_key
= (char *) alloca (STRING_BYTES (XSTRING (Vx_resource_name
))
2207 + (STRINGP (component
)
2208 ? STRING_BYTES (XSTRING (component
)) : 0)
2209 + STRING_BYTES (XSTRING (attribute
))
2212 class_key
= (char *) alloca (STRING_BYTES (XSTRING (Vx_resource_class
))
2213 + STRING_BYTES (XSTRING (class))
2214 + (STRINGP (subclass
)
2215 ? STRING_BYTES (XSTRING (subclass
)) : 0)
2218 /* Start with emacs.FRAMENAME for the name (the specific one)
2219 and with `Emacs' for the class key (the general one). */
2220 strcpy (name_key
, XSTRING (Vx_resource_name
)->data
);
2221 strcpy (class_key
, XSTRING (Vx_resource_class
)->data
);
2223 strcat (class_key
, ".");
2224 strcat (class_key
, XSTRING (class)->data
);
2226 if (!NILP (component
))
2228 strcat (class_key
, ".");
2229 strcat (class_key
, XSTRING (subclass
)->data
);
2231 strcat (name_key
, ".");
2232 strcat (name_key
, XSTRING (component
)->data
);
2235 strcat (name_key
, ".");
2236 strcat (name_key
, XSTRING (attribute
)->data
);
2238 value
= x_get_string_resource (dpyinfo
->xrdb
, name_key
, class_key
);
2240 if (value
!= (char *) 0)
2241 return build_string (value
);
2246 /* Used when C code wants a resource value. */
2249 x_get_resource_string (attribute
, class)
2250 char *attribute
, *class;
2252 register char *value
;
2256 /* Allocate space for the components, the dots which separate them,
2257 and the final '\0'. */
2258 name_key
= (char *) alloca (STRING_BYTES (XSTRING (Vinvocation_name
))
2259 + strlen (attribute
) + 2);
2260 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
2261 + strlen (class) + 2);
2263 sprintf (name_key
, "%s.%s",
2264 XSTRING (Vinvocation_name
)->data
,
2266 sprintf (class_key
, "%s.%s", EMACS_CLASS
, class);
2268 return x_get_string_resource (FRAME_X_DISPLAY_INFO (selected_frame
)->xrdb
,
2269 name_key
, class_key
);
2272 /* Types we might convert a resource string into. */
2275 number
, boolean
, string
, symbol
2278 /* Return the value of parameter PARAM.
2280 First search ALIST, then Vdefault_frame_alist, then the X defaults
2281 database, using ATTRIBUTE as the attribute name and CLASS as its class.
2283 Convert the resource to the type specified by desired_type.
2285 If no default is specified, return Qunbound. If you call
2286 x_get_arg, make sure you deal with Qunbound in a reasonable way,
2287 and don't let it get stored in any Lisp-visible variables! */
2290 x_get_arg (dpyinfo
, alist
, param
, attribute
, class, type
)
2291 struct x_display_info
*dpyinfo
;
2292 Lisp_Object alist
, param
;
2295 enum resource_types type
;
2297 register Lisp_Object tem
;
2299 tem
= Fassq (param
, alist
);
2301 tem
= Fassq (param
, Vdefault_frame_alist
);
2307 tem
= display_x_get_resource (dpyinfo
,
2308 build_string (attribute
),
2309 build_string (class),
2318 return make_number (atoi (XSTRING (tem
)->data
));
2321 tem
= Fdowncase (tem
);
2322 if (!strcmp (XSTRING (tem
)->data
, "on")
2323 || !strcmp (XSTRING (tem
)->data
, "true"))
2332 /* As a special case, we map the values `true' and `on'
2333 to Qt, and `false' and `off' to Qnil. */
2336 lower
= Fdowncase (tem
);
2337 if (!strcmp (XSTRING (lower
)->data
, "on")
2338 || !strcmp (XSTRING (lower
)->data
, "true"))
2340 else if (!strcmp (XSTRING (lower
)->data
, "off")
2341 || !strcmp (XSTRING (lower
)->data
, "false"))
2344 return Fintern (tem
, Qnil
);
2357 /* Like x_get_arg, but also record the value in f->param_alist. */
2360 x_get_and_record_arg (f
, alist
, param
, attribute
, class, type
)
2362 Lisp_Object alist
, param
;
2365 enum resource_types type
;
2369 value
= x_get_arg (FRAME_X_DISPLAY_INFO (f
), alist
, param
,
2370 attribute
, class, type
);
2372 store_frame_param (f
, param
, value
);
2377 /* Record in frame F the specified or default value according to ALIST
2378 of the parameter named PROP (a Lisp symbol).
2379 If no value is specified for PROP, look for an X default for XPROP
2380 on the frame named NAME.
2381 If that is not found either, use the value DEFLT. */
2384 x_default_parameter (f
, alist
, prop
, deflt
, xprop
, xclass
, type
)
2391 enum resource_types type
;
2395 tem
= x_get_arg (FRAME_X_DISPLAY_INFO (f
), alist
, prop
, xprop
, xclass
, type
);
2396 if (EQ (tem
, Qunbound
))
2398 x_set_frame_parameters (f
, Fcons (Fcons (prop
, tem
), Qnil
));
2402 DEFUN ("x-parse-geometry", Fx_parse_geometry
, Sx_parse_geometry
, 1, 1, 0,
2403 "Parse an X-style geometry string STRING.\n\
2404 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).\n\
2405 The properties returned may include `top', `left', `height', and `width'.\n\
2406 The value of `left' or `top' may be an integer,\n\
2407 or a list (+ N) meaning N pixels relative to top/left corner,\n\
2408 or a list (- N) meaning -N pixels relative to bottom/right corner.")
2413 unsigned int width
, height
;
2416 CHECK_STRING (string
, 0);
2418 geometry
= XParseGeometry ((char *) XSTRING (string
)->data
,
2419 &x
, &y
, &width
, &height
);
2422 if (!!(geometry
& XValue
) != !!(geometry
& YValue
))
2423 error ("Must specify both x and y position, or neither");
2427 if (geometry
& XValue
)
2429 Lisp_Object element
;
2431 if (x
>= 0 && (geometry
& XNegative
))
2432 element
= Fcons (Qleft
, Fcons (Qminus
, Fcons (make_number (-x
), Qnil
)));
2433 else if (x
< 0 && ! (geometry
& XNegative
))
2434 element
= Fcons (Qleft
, Fcons (Qplus
, Fcons (make_number (x
), Qnil
)));
2436 element
= Fcons (Qleft
, make_number (x
));
2437 result
= Fcons (element
, result
);
2440 if (geometry
& YValue
)
2442 Lisp_Object element
;
2444 if (y
>= 0 && (geometry
& YNegative
))
2445 element
= Fcons (Qtop
, Fcons (Qminus
, Fcons (make_number (-y
), Qnil
)));
2446 else if (y
< 0 && ! (geometry
& YNegative
))
2447 element
= Fcons (Qtop
, Fcons (Qplus
, Fcons (make_number (y
), Qnil
)));
2449 element
= Fcons (Qtop
, make_number (y
));
2450 result
= Fcons (element
, result
);
2453 if (geometry
& WidthValue
)
2454 result
= Fcons (Fcons (Qwidth
, make_number (width
)), result
);
2455 if (geometry
& HeightValue
)
2456 result
= Fcons (Fcons (Qheight
, make_number (height
)), result
);
2461 /* Calculate the desired size and position of this window,
2462 and return the flags saying which aspects were specified.
2464 This function does not make the coordinates positive. */
2466 #define DEFAULT_ROWS 40
2467 #define DEFAULT_COLS 80
2470 x_figure_window_size (f
, parms
)
2474 register Lisp_Object tem0
, tem1
, tem2
;
2475 int height
, width
, left
, top
;
2476 register int geometry
;
2477 long window_prompting
= 0;
2478 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
2480 /* Default values if we fall through.
2481 Actually, if that happens we should get
2482 window manager prompting. */
2483 SET_FRAME_WIDTH (f
, DEFAULT_COLS
);
2484 f
->height
= DEFAULT_ROWS
;
2485 /* Window managers expect that if program-specified
2486 positions are not (0,0), they're intentional, not defaults. */
2487 f
->output_data
.x
->top_pos
= 0;
2488 f
->output_data
.x
->left_pos
= 0;
2490 tem0
= x_get_arg (dpyinfo
, parms
, Qheight
, 0, 0, number
);
2491 tem1
= x_get_arg (dpyinfo
, parms
, Qwidth
, 0, 0, number
);
2492 tem2
= x_get_arg (dpyinfo
, parms
, Quser_size
, 0, 0, number
);
2493 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
2495 if (!EQ (tem0
, Qunbound
))
2497 CHECK_NUMBER (tem0
, 0);
2498 f
->height
= XINT (tem0
);
2500 if (!EQ (tem1
, Qunbound
))
2502 CHECK_NUMBER (tem1
, 0);
2503 SET_FRAME_WIDTH (f
, XINT (tem1
));
2505 if (!NILP (tem2
) && !EQ (tem2
, Qunbound
))
2506 window_prompting
|= USSize
;
2508 window_prompting
|= PSize
;
2511 f
->output_data
.x
->vertical_scroll_bar_extra
2512 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
2514 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0
2515 ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f
)
2516 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.x
->font
)));
2517 f
->output_data
.x
->pixel_width
= CHAR_TO_PIXEL_WIDTH (f
, f
->width
);
2518 f
->output_data
.x
->pixel_height
= CHAR_TO_PIXEL_HEIGHT (f
, f
->height
);
2520 tem0
= x_get_arg (dpyinfo
, parms
, Qtop
, 0, 0, number
);
2521 tem1
= x_get_arg (dpyinfo
, parms
, Qleft
, 0, 0, number
);
2522 tem2
= x_get_arg (dpyinfo
, parms
, Quser_position
, 0, 0, number
);
2523 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
2525 if (EQ (tem0
, Qminus
))
2527 f
->output_data
.x
->top_pos
= 0;
2528 window_prompting
|= YNegative
;
2530 else if (CONSP (tem0
) && EQ (XCONS (tem0
)->car
, Qminus
)
2531 && CONSP (XCONS (tem0
)->cdr
)
2532 && INTEGERP (XCONS (XCONS (tem0
)->cdr
)->car
))
2534 f
->output_data
.x
->top_pos
= - XINT (XCONS (XCONS (tem0
)->cdr
)->car
);
2535 window_prompting
|= YNegative
;
2537 else if (CONSP (tem0
) && EQ (XCONS (tem0
)->car
, Qplus
)
2538 && CONSP (XCONS (tem0
)->cdr
)
2539 && INTEGERP (XCONS (XCONS (tem0
)->cdr
)->car
))
2541 f
->output_data
.x
->top_pos
= XINT (XCONS (XCONS (tem0
)->cdr
)->car
);
2543 else if (EQ (tem0
, Qunbound
))
2544 f
->output_data
.x
->top_pos
= 0;
2547 CHECK_NUMBER (tem0
, 0);
2548 f
->output_data
.x
->top_pos
= XINT (tem0
);
2549 if (f
->output_data
.x
->top_pos
< 0)
2550 window_prompting
|= YNegative
;
2553 if (EQ (tem1
, Qminus
))
2555 f
->output_data
.x
->left_pos
= 0;
2556 window_prompting
|= XNegative
;
2558 else if (CONSP (tem1
) && EQ (XCONS (tem1
)->car
, Qminus
)
2559 && CONSP (XCONS (tem1
)->cdr
)
2560 && INTEGERP (XCONS (XCONS (tem1
)->cdr
)->car
))
2562 f
->output_data
.x
->left_pos
= - XINT (XCONS (XCONS (tem1
)->cdr
)->car
);
2563 window_prompting
|= XNegative
;
2565 else if (CONSP (tem1
) && EQ (XCONS (tem1
)->car
, Qplus
)
2566 && CONSP (XCONS (tem1
)->cdr
)
2567 && INTEGERP (XCONS (XCONS (tem1
)->cdr
)->car
))
2569 f
->output_data
.x
->left_pos
= XINT (XCONS (XCONS (tem1
)->cdr
)->car
);
2571 else if (EQ (tem1
, Qunbound
))
2572 f
->output_data
.x
->left_pos
= 0;
2575 CHECK_NUMBER (tem1
, 0);
2576 f
->output_data
.x
->left_pos
= XINT (tem1
);
2577 if (f
->output_data
.x
->left_pos
< 0)
2578 window_prompting
|= XNegative
;
2581 if (!NILP (tem2
) && ! EQ (tem2
, Qunbound
))
2582 window_prompting
|= USPosition
;
2584 window_prompting
|= PPosition
;
2587 return window_prompting
;
2590 #if !defined (HAVE_X11R4) && !defined (HAVE_XSETWMPROTOCOLS)
2593 XSetWMProtocols (dpy
, w
, protocols
, count
)
2600 prop
= XInternAtom (dpy
, "WM_PROTOCOLS", False
);
2601 if (prop
== None
) return False
;
2602 XChangeProperty (dpy
, w
, prop
, XA_ATOM
, 32, PropModeReplace
,
2603 (unsigned char *) protocols
, count
);
2606 #endif /* not HAVE_X11R4 && not HAVE_XSETWMPROTOCOLS */
2608 #ifdef USE_X_TOOLKIT
2610 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
2611 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
2612 already be present because of the toolkit (Motif adds some of them,
2613 for example, but Xt doesn't). */
2616 hack_wm_protocols (f
, widget
)
2620 Display
*dpy
= XtDisplay (widget
);
2621 Window w
= XtWindow (widget
);
2622 int need_delete
= 1;
2628 Atom type
, *atoms
= 0;
2630 unsigned long nitems
= 0;
2631 unsigned long bytes_after
;
2633 if ((XGetWindowProperty (dpy
, w
,
2634 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2635 (long)0, (long)100, False
, XA_ATOM
,
2636 &type
, &format
, &nitems
, &bytes_after
,
2637 (unsigned char **) &atoms
)
2639 && format
== 32 && type
== XA_ATOM
)
2643 if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
)
2645 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
)
2647 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
)
2650 if (atoms
) XFree ((char *) atoms
);
2656 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2658 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
;
2660 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2662 XChangeProperty (dpy
, w
, FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2663 XA_ATOM
, 32, PropModeAppend
,
2664 (unsigned char *) props
, count
);
2670 #ifdef USE_X_TOOLKIT
2672 /* Create and set up the X widget for frame F. */
2675 x_window (f
, window_prompting
, minibuffer_only
)
2677 long window_prompting
;
2678 int minibuffer_only
;
2680 XClassHint class_hints
;
2681 XSetWindowAttributes attributes
;
2682 unsigned long attribute_mask
;
2684 Widget shell_widget
;
2686 Widget frame_widget
;
2692 /* Use the resource name as the top-level widget name
2693 for looking up resources. Make a non-Lisp copy
2694 for the window manager, so GC relocation won't bother it.
2696 Elsewhere we specify the window name for the window manager. */
2699 char *str
= (char *) XSTRING (Vx_resource_name
)->data
;
2700 f
->namebuf
= (char *) xmalloc (strlen (str
) + 1);
2701 strcpy (f
->namebuf
, str
);
2705 XtSetArg (al
[ac
], XtNallowShellResize
, 1); ac
++;
2706 XtSetArg (al
[ac
], XtNinput
, 1); ac
++;
2707 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2708 XtSetArg (al
[ac
], XtNborderWidth
, f
->output_data
.x
->border_width
); ac
++;
2709 shell_widget
= XtAppCreateShell (f
->namebuf
, EMACS_CLASS
,
2710 applicationShellWidgetClass
,
2711 FRAME_X_DISPLAY (f
), al
, ac
);
2713 f
->output_data
.x
->widget
= shell_widget
;
2714 /* maybe_set_screen_title_format (shell_widget); */
2716 pane_widget
= lw_create_widget ("main", "pane", widget_id_tick
++,
2717 (widget_value
*) NULL
,
2718 shell_widget
, False
,
2721 (lw_callback
) NULL
);
2723 f
->output_data
.x
->column_widget
= pane_widget
;
2725 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2726 the emacs screen when changing menubar. This reduces flickering. */
2729 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2730 XtSetArg (al
[ac
], XtNshowGrip
, 0); ac
++;
2731 XtSetArg (al
[ac
], XtNallowResize
, 1); ac
++;
2732 XtSetArg (al
[ac
], XtNresizeToPreferred
, 1); ac
++;
2733 XtSetArg (al
[ac
], XtNemacsFrame
, f
); ac
++;
2734 frame_widget
= XtCreateWidget (f
->namebuf
,
2736 pane_widget
, al
, ac
);
2738 f
->output_data
.x
->edit_widget
= frame_widget
;
2740 XtManageChild (frame_widget
);
2742 /* Do some needed geometry management. */
2745 char *tem
, shell_position
[32];
2748 int extra_borders
= 0;
2750 = (f
->output_data
.x
->menubar_widget
2751 ? (f
->output_data
.x
->menubar_widget
->core
.height
2752 + f
->output_data
.x
->menubar_widget
->core
.border_width
)
2754 extern char *lwlib_toolkit_type
;
2756 #if 0 /* Experimentally, we now get the right results
2757 for -geometry -0-0 without this. 24 Aug 96, rms. */
2758 if (FRAME_EXTERNAL_MENU_BAR (f
))
2761 XtVaGetValues (pane_widget
, XtNinternalBorderWidth
, &ibw
, NULL
);
2762 menubar_size
+= ibw
;
2766 f
->output_data
.x
->menubar_height
= menubar_size
;
2769 /* Motif seems to need this amount added to the sizes
2770 specified for the shell widget. The Athena/Lucid widgets don't.
2771 Both conclusions reached experimentally. -- rms. */
2772 XtVaGetValues (f
->output_data
.x
->edit_widget
, XtNinternalBorderWidth
,
2773 &extra_borders
, NULL
);
2777 /* Convert our geometry parameters into a geometry string
2779 Note that we do not specify here whether the position
2780 is a user-specified or program-specified one.
2781 We pass that information later, in x_wm_set_size_hints. */
2783 int left
= f
->output_data
.x
->left_pos
;
2784 int xneg
= window_prompting
& XNegative
;
2785 int top
= f
->output_data
.x
->top_pos
;
2786 int yneg
= window_prompting
& YNegative
;
2792 if (window_prompting
& USPosition
)
2793 sprintf (shell_position
, "=%dx%d%c%d%c%d",
2794 PIXEL_WIDTH (f
) + extra_borders
,
2795 PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
,
2796 (xneg
? '-' : '+'), left
,
2797 (yneg
? '-' : '+'), top
);
2799 sprintf (shell_position
, "=%dx%d",
2800 PIXEL_WIDTH (f
) + extra_borders
,
2801 PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
);
2804 len
= strlen (shell_position
) + 1;
2805 /* We don't free this because we don't know whether
2806 it is safe to free it while the frame exists.
2807 It isn't worth the trouble of arranging to free it
2808 when the frame is deleted. */
2809 tem
= (char *) xmalloc (len
);
2810 strncpy (tem
, shell_position
, len
);
2811 XtSetArg (al
[ac
], XtNgeometry
, tem
); ac
++;
2812 XtSetValues (shell_widget
, al
, ac
);
2815 XtManageChild (pane_widget
);
2816 XtRealizeWidget (shell_widget
);
2818 FRAME_X_WINDOW (f
) = XtWindow (frame_widget
);
2820 validate_x_resource_name ();
2822 class_hints
.res_name
= (char *) XSTRING (Vx_resource_name
)->data
;
2823 class_hints
.res_class
= (char *) XSTRING (Vx_resource_class
)->data
;
2824 XSetClassHint (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
), &class_hints
);
2827 #ifndef X_I18N_INHIBITED
2832 xim
= XOpenIM (FRAME_X_DISPLAY (f
), NULL
, NULL
, NULL
);
2836 xic
= XCreateIC (xim
,
2837 XNInputStyle
, XIMPreeditNothing
| XIMStatusNothing
,
2838 XNClientWindow
, FRAME_X_WINDOW(f
),
2839 XNFocusWindow
, FRAME_X_WINDOW(f
),
2848 FRAME_XIM (f
) = xim
;
2849 FRAME_XIC (f
) = xic
;
2851 #else /* X_I18N_INHIBITED */
2854 #endif /* X_I18N_INHIBITED */
2855 #endif /* HAVE_X_I18N */
2857 f
->output_data
.x
->wm_hints
.input
= True
;
2858 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2859 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2860 &f
->output_data
.x
->wm_hints
);
2862 hack_wm_protocols (f
, shell_widget
);
2865 XtAddEventHandler (shell_widget
, 0, True
, _XEditResCheckMessages
, 0);
2868 /* Do a stupid property change to force the server to generate a
2869 propertyNotify event so that the event_stream server timestamp will
2870 be initialized to something relevant to the time we created the window.
2872 XChangeProperty (XtDisplay (frame_widget
), XtWindow (frame_widget
),
2873 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2874 XA_ATOM
, 32, PropModeAppend
,
2875 (unsigned char*) NULL
, 0);
2877 /* Make all the standard events reach the Emacs frame. */
2878 attributes
.event_mask
= STANDARD_EVENT_SET
;
2879 attribute_mask
= CWEventMask
;
2880 XChangeWindowAttributes (XtDisplay (shell_widget
), XtWindow (shell_widget
),
2881 attribute_mask
, &attributes
);
2883 XtMapWidget (frame_widget
);
2885 /* x_set_name normally ignores requests to set the name if the
2886 requested name is the same as the current name. This is the one
2887 place where that assumption isn't correct; f->name is set, but
2888 the X server hasn't been told. */
2891 int explicit = f
->explicit_name
;
2893 f
->explicit_name
= 0;
2896 x_set_name (f
, name
, explicit);
2899 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2900 f
->output_data
.x
->text_cursor
);
2904 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
2905 initialize_frame_menubar (f
);
2906 lw_set_main_areas (pane_widget
, f
->output_data
.x
->menubar_widget
, frame_widget
);
2908 if (FRAME_X_WINDOW (f
) == 0)
2909 error ("Unable to create window");
2912 #else /* not USE_X_TOOLKIT */
2914 /* Create and set up the X window for frame F. */
2920 XClassHint class_hints
;
2921 XSetWindowAttributes attributes
;
2922 unsigned long attribute_mask
;
2924 attributes
.background_pixel
= f
->output_data
.x
->background_pixel
;
2925 attributes
.border_pixel
= f
->output_data
.x
->border_pixel
;
2926 attributes
.bit_gravity
= StaticGravity
;
2927 attributes
.backing_store
= NotUseful
;
2928 attributes
.save_under
= True
;
2929 attributes
.event_mask
= STANDARD_EVENT_SET
;
2930 attribute_mask
= (CWBackPixel
| CWBorderPixel
| CWBitGravity
2932 | CWBackingStore
| CWSaveUnder
2938 = XCreateWindow (FRAME_X_DISPLAY (f
),
2939 f
->output_data
.x
->parent_desc
,
2940 f
->output_data
.x
->left_pos
,
2941 f
->output_data
.x
->top_pos
,
2942 PIXEL_WIDTH (f
), PIXEL_HEIGHT (f
),
2943 f
->output_data
.x
->border_width
,
2944 CopyFromParent
, /* depth */
2945 InputOutput
, /* class */
2946 FRAME_X_DISPLAY_INFO (f
)->visual
,
2947 attribute_mask
, &attributes
);
2949 #ifndef X_I18N_INHIBITED
2954 xim
= XOpenIM (FRAME_X_DISPLAY(f
), NULL
, NULL
, NULL
);
2958 xic
= XCreateIC (xim
,
2959 XNInputStyle
, XIMPreeditNothing
| XIMStatusNothing
,
2960 XNClientWindow
, FRAME_X_WINDOW(f
),
2961 XNFocusWindow
, FRAME_X_WINDOW(f
),
2971 FRAME_XIM (f
) = xim
;
2972 FRAME_XIC (f
) = xic
;
2974 #else /* X_I18N_INHIBITED */
2977 #endif /* X_I18N_INHIBITED */
2978 #endif /* HAVE_X_I18N */
2980 validate_x_resource_name ();
2982 class_hints
.res_name
= (char *) XSTRING (Vx_resource_name
)->data
;
2983 class_hints
.res_class
= (char *) XSTRING (Vx_resource_class
)->data
;
2984 XSetClassHint (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &class_hints
);
2986 /* The menubar is part of the ordinary display;
2987 it does not count in addition to the height of the window. */
2988 f
->output_data
.x
->menubar_height
= 0;
2990 /* This indicates that we use the "Passive Input" input model.
2991 Unless we do this, we don't get the Focus{In,Out} events that we
2992 need to draw the cursor correctly. Accursed bureaucrats.
2993 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2995 f
->output_data
.x
->wm_hints
.input
= True
;
2996 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2997 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2998 &f
->output_data
.x
->wm_hints
);
2999 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
3001 /* Request "save yourself" and "delete window" commands from wm. */
3004 protocols
[0] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
3005 protocols
[1] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
3006 XSetWMProtocols (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), protocols
, 2);
3009 /* x_set_name normally ignores requests to set the name if the
3010 requested name is the same as the current name. This is the one
3011 place where that assumption isn't correct; f->name is set, but
3012 the X server hasn't been told. */
3015 int explicit = f
->explicit_name
;
3017 f
->explicit_name
= 0;
3020 x_set_name (f
, name
, explicit);
3023 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3024 f
->output_data
.x
->text_cursor
);
3028 if (FRAME_X_WINDOW (f
) == 0)
3029 error ("Unable to create window");
3032 #endif /* not USE_X_TOOLKIT */
3034 /* Handle the icon stuff for this window. Perhaps later we might
3035 want an x_set_icon_position which can be called interactively as
3043 Lisp_Object icon_x
, icon_y
;
3044 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3046 /* Set the position of the icon. Note that twm groups all
3047 icons in an icon window. */
3048 icon_x
= x_get_and_record_arg (f
, parms
, Qicon_left
, 0, 0, number
);
3049 icon_y
= x_get_and_record_arg (f
, parms
, Qicon_top
, 0, 0, number
);
3050 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
3052 CHECK_NUMBER (icon_x
, 0);
3053 CHECK_NUMBER (icon_y
, 0);
3055 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
3056 error ("Both left and top icon corners of icon must be specified");
3060 if (! EQ (icon_x
, Qunbound
))
3061 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
3063 /* Start up iconic or window? */
3064 x_wm_set_window_state
3065 (f
, (EQ (x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0, symbol
), Qicon
)
3069 x_text_icon (f
, (char *) XSTRING ((!NILP (f
->icon_name
)
3076 /* Make the GC's needed for this window, setting the
3077 background, border and mouse colors; also create the
3078 mouse cursor and the gray border tile. */
3080 static char cursor_bits
[] =
3082 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3083 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3084 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3085 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3092 XGCValues gc_values
;
3098 /* Create the GC's of this frame.
3099 Note that many default values are used. */
3102 gc_values
.font
= f
->output_data
.x
->font
->fid
;
3103 gc_values
.foreground
= f
->output_data
.x
->foreground_pixel
;
3104 gc_values
.background
= f
->output_data
.x
->background_pixel
;
3105 gc_values
.line_width
= 0; /* Means 1 using fast algorithm. */
3106 f
->output_data
.x
->normal_gc
= XCreateGC (FRAME_X_DISPLAY (f
),
3108 GCLineWidth
| GCFont
3109 | GCForeground
| GCBackground
,
3112 /* Reverse video style. */
3113 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
3114 gc_values
.background
= f
->output_data
.x
->foreground_pixel
;
3115 f
->output_data
.x
->reverse_gc
= XCreateGC (FRAME_X_DISPLAY (f
),
3117 GCFont
| GCForeground
| GCBackground
3121 /* Cursor has cursor-color background, background-color foreground. */
3122 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
3123 gc_values
.background
= f
->output_data
.x
->cursor_pixel
;
3124 gc_values
.fill_style
= FillOpaqueStippled
;
3126 = XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
3127 FRAME_X_DISPLAY_INFO (f
)->root_window
,
3128 cursor_bits
, 16, 16);
3129 f
->output_data
.x
->cursor_gc
3130 = XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3131 (GCFont
| GCForeground
| GCBackground
3132 | GCFillStyle
| GCStipple
| GCLineWidth
),
3135 /* Create the gray border tile used when the pointer is not in
3136 the frame. Since this depends on the frame's pixel values,
3137 this must be done on a per-frame basis. */
3138 f
->output_data
.x
->border_tile
3139 = (XCreatePixmapFromBitmapData
3140 (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
3141 gray_bits
, gray_width
, gray_height
,
3142 f
->output_data
.x
->foreground_pixel
,
3143 f
->output_data
.x
->background_pixel
,
3144 DefaultDepth (FRAME_X_DISPLAY (f
),
3145 XScreenNumberOfScreen (FRAME_X_SCREEN (f
)))));
3150 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
3152 "Make a new X window, which is called a \"frame\" in Emacs terms.\n\
3153 Returns an Emacs frame object.\n\
3154 ALIST is an alist of frame parameters.\n\
3155 If the parameters specify that the frame should not have a minibuffer,\n\
3156 and do not specify a specific minibuffer window to use,\n\
3157 then `default-minibuffer-frame' must be a frame whose minibuffer can\n\
3158 be shared by the new frame.\n\
3160 This function is an internal primitive--use `make-frame' instead.")
3165 Lisp_Object frame
, tem
;
3167 int minibuffer_only
= 0;
3168 long window_prompting
= 0;
3170 int count
= specpdl_ptr
- specpdl
;
3171 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
3172 Lisp_Object display
;
3173 struct x_display_info
*dpyinfo
;
3179 /* Use this general default value to start with
3180 until we know if this frame has a specified name. */
3181 Vx_resource_name
= Vinvocation_name
;
3183 display
= x_get_arg (dpyinfo
, parms
, Qdisplay
, 0, 0, string
);
3184 if (EQ (display
, Qunbound
))
3186 dpyinfo
= check_x_display_info (display
);
3188 kb
= dpyinfo
->kboard
;
3190 kb
= &the_only_kboard
;
3193 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", string
);
3195 && ! EQ (name
, Qunbound
)
3197 error ("Invalid frame name--not a string or nil");
3200 Vx_resource_name
= name
;
3202 /* See if parent window is specified. */
3203 parent
= x_get_arg (dpyinfo
, parms
, Qparent_id
, NULL
, NULL
, number
);
3204 if (EQ (parent
, Qunbound
))
3206 if (! NILP (parent
))
3207 CHECK_NUMBER (parent
, 0);
3209 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
3210 /* No need to protect DISPLAY because that's not used after passing
3211 it to make_frame_without_minibuffer. */
3213 GCPRO4 (parms
, parent
, name
, frame
);
3214 tem
= x_get_arg (dpyinfo
, parms
, Qminibuffer
, "minibuffer", "Minibuffer", symbol
);
3215 if (EQ (tem
, Qnone
) || NILP (tem
))
3216 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
3217 else if (EQ (tem
, Qonly
))
3219 f
= make_minibuffer_frame ();
3220 minibuffer_only
= 1;
3222 else if (WINDOWP (tem
))
3223 f
= make_frame_without_minibuffer (tem
, kb
, display
);
3227 XSETFRAME (frame
, f
);
3229 /* Note that X Windows does support scroll bars. */
3230 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
3232 f
->output_method
= output_x_window
;
3233 f
->output_data
.x
= (struct x_output
*) xmalloc (sizeof (struct x_output
));
3234 bzero (f
->output_data
.x
, sizeof (struct x_output
));
3235 f
->output_data
.x
->icon_bitmap
= -1;
3236 f
->output_data
.x
->fontset
= -1;
3239 = x_get_arg (dpyinfo
, parms
, Qicon_name
, "iconName", "Title", string
);
3240 if (! STRINGP (f
->icon_name
))
3241 f
->icon_name
= Qnil
;
3243 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
3245 FRAME_KBOARD (f
) = kb
;
3248 /* Specify the parent under which to make this X window. */
3252 f
->output_data
.x
->parent_desc
= (Window
) XFASTINT (parent
);
3253 f
->output_data
.x
->explicit_parent
= 1;
3257 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3258 f
->output_data
.x
->explicit_parent
= 0;
3261 /* Note that the frame has no physical cursor right now. */
3262 f
->phys_cursor_x
= -1;
3264 /* Set the name; the functions to which we pass f expect the name to
3266 if (EQ (name
, Qunbound
) || NILP (name
))
3268 f
->name
= build_string (dpyinfo
->x_id_name
);
3269 f
->explicit_name
= 0;
3274 f
->explicit_name
= 1;
3275 /* use the frame's title when getting resources for this frame. */
3276 specbind (Qx_resource_name
, name
);
3279 /* Create fontsets from `global_fontset_alist' before handling fonts. */
3280 for (tem
= Vglobal_fontset_alist
; CONSP (tem
); tem
= XCONS (tem
)->cdr
)
3281 fs_register_fontset (f
, XCONS (tem
)->car
);
3283 /* Extract the window parameters from the supplied values
3284 that are needed to determine window geometry. */
3288 font
= x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", string
);
3291 /* First, try whatever font the caller has specified. */
3294 tem
= Fquery_fontset (font
, Qnil
);
3296 font
= x_new_fontset (f
, XSTRING (tem
)->data
);
3298 font
= x_new_font (f
, XSTRING (font
)->data
);
3300 /* Try out a font which we hope has bold and italic variations. */
3301 if (!STRINGP (font
))
3302 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3303 if (! STRINGP (font
))
3304 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3305 if (! STRINGP (font
))
3306 /* This was formerly the first thing tried, but it finds too many fonts
3307 and takes too long. */
3308 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
3309 /* If those didn't work, look for something which will at least work. */
3310 if (! STRINGP (font
))
3311 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
3313 if (! STRINGP (font
))
3314 font
= build_string ("fixed");
3316 x_default_parameter (f
, parms
, Qfont
, font
,
3317 "font", "Font", string
);
3321 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
3322 whereby it fails to get any font. */
3323 xlwmenu_default_font
= f
->output_data
.x
->font
;
3326 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
3327 "borderWidth", "BorderWidth", number
);
3328 /* This defaults to 2 in order to match xterm. We recognize either
3329 internalBorderWidth or internalBorder (which is what xterm calls
3331 if (NILP (Fassq (Qinternal_border_width
, parms
)))
3335 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
3336 "internalBorder", "internalBorder", number
);
3337 if (! EQ (value
, Qunbound
))
3338 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
3341 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
3342 "internalBorderWidth", "internalBorderWidth", number
);
3343 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qleft
,
3344 "verticalScrollBars", "ScrollBars", symbol
);
3346 /* Also do the stuff which must be set before the window exists. */
3347 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
3348 "foreground", "Foreground", string
);
3349 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
3350 "background", "Background", string
);
3351 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
3352 "pointerColor", "Foreground", string
);
3353 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
3354 "cursorColor", "Foreground", string
);
3355 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
3356 "borderColor", "BorderColor", string
);
3358 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
3359 "menuBar", "MenuBar", number
);
3360 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
3361 "scrollBarWidth", "ScrollBarWidth", number
);
3362 x_default_parameter (f
, parms
, Qbuffer_predicate
, Qnil
,
3363 "bufferPredicate", "BufferPredicate", symbol
);
3364 x_default_parameter (f
, parms
, Qtitle
, Qnil
,
3365 "title", "Title", string
);
3367 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3368 window_prompting
= x_figure_window_size (f
, parms
);
3370 if (window_prompting
& XNegative
)
3372 if (window_prompting
& YNegative
)
3373 f
->output_data
.x
->win_gravity
= SouthEastGravity
;
3375 f
->output_data
.x
->win_gravity
= NorthEastGravity
;
3379 if (window_prompting
& YNegative
)
3380 f
->output_data
.x
->win_gravity
= SouthWestGravity
;
3382 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
3385 f
->output_data
.x
->size_hint_flags
= window_prompting
;
3387 #ifdef USE_X_TOOLKIT
3388 x_window (f
, window_prompting
, minibuffer_only
);
3394 init_frame_faces (f
);
3396 /* We need to do this after creating the X window, so that the
3397 icon-creation functions can say whose icon they're describing. */
3398 x_default_parameter (f
, parms
, Qicon_type
, Qnil
,
3399 "bitmapIcon", "BitmapIcon", symbol
);
3401 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
3402 "autoRaise", "AutoRaiseLower", boolean
);
3403 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
3404 "autoLower", "AutoRaiseLower", boolean
);
3405 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
3406 "cursorType", "CursorType", symbol
);
3408 /* Dimensions, especially f->height, must be done via change_frame_size.
3409 Change will not be effected unless different from the current
3414 SET_FRAME_WIDTH (f
, 0);
3415 change_frame_size (f
, height
, width
, 1, 0);
3417 /* Tell the server what size and position, etc, we want,
3418 and how badly we want them. */
3420 x_wm_set_size_hint (f
, window_prompting
, 0);
3423 tem
= x_get_arg (dpyinfo
, parms
, Qunsplittable
, 0, 0, boolean
);
3424 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
3428 /* It is now ok to make the frame official
3429 even if we get an error below.
3430 And the frame needs to be on Vframe_list
3431 or making it visible won't work. */
3432 Vframe_list
= Fcons (frame
, Vframe_list
);
3434 /* Now that the frame is official, it counts as a reference to
3436 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
3438 /* Make the window appear on the frame and enable display,
3439 unless the caller says not to. However, with explicit parent,
3440 Emacs cannot control visibility, so don't try. */
3441 if (! f
->output_data
.x
->explicit_parent
)
3443 Lisp_Object visibility
;
3445 visibility
= x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0, symbol
);
3446 if (EQ (visibility
, Qunbound
))
3449 if (EQ (visibility
, Qicon
))
3450 x_iconify_frame (f
);
3451 else if (! NILP (visibility
))
3452 x_make_frame_visible (f
);
3454 /* Must have been Qnil. */
3458 return unbind_to (count
, frame
);
3461 /* FRAME is used only to get a handle on the X display. We don't pass the
3462 display info directly because we're called from frame.c, which doesn't
3463 know about that structure. */
3466 x_get_focus_frame (frame
)
3467 struct frame
*frame
;
3469 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (frame
);
3471 if (! dpyinfo
->x_focus_frame
)
3474 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
3479 #include "x-list-font.c"
3481 DEFUN ("x-list-fonts", Fx_list_fonts
, Sx_list_fonts
, 1, 4, 0,
3482 "Return a list of the names of available fonts matching PATTERN.\n\
3483 If optional arguments FACE and FRAME are specified, return only fonts\n\
3484 the same size as FACE on FRAME.\n\
3486 PATTERN is a string, perhaps with wildcard characters;\n\
3487 the * character matches any substring, and\n\
3488 the ? character matches any single character.\n\
3489 PATTERN is case-insensitive.\n\
3490 FACE is a face name--a symbol.\n\
3492 The return value is a list of strings, suitable as arguments to\n\
3495 Fonts Emacs can't use (i.e. proportional fonts) may or may not be excluded\n\
3496 even if they match PATTERN and FACE.\n\
3498 The optional fourth argument MAXIMUM sets a limit on how many\n\
3499 fonts to match. The first MAXIMUM fonts are reported.")
3500 (pattern
, face
, frame
, maximum
)
3501 Lisp_Object pattern
, face
, frame
, maximum
;
3505 #ifndef BROKEN_XLISTFONTSWITHINFO
3508 XFontStruct
*size_ref
;
3516 CHECK_STRING (pattern
, 0);
3518 CHECK_SYMBOL (face
, 1);
3524 CHECK_NATNUM (maximum
, 0);
3525 maxnames
= XINT (maximum
);
3528 f
= check_x_frame (frame
);
3530 /* Determine the width standard for comparison with the fonts we find. */
3538 /* Don't die if we get called with a terminal frame. */
3539 if (! FRAME_X_P (f
))
3540 error ("Non-X frame used in `x-list-fonts'");
3542 face_id
= face_name_id_number (f
, face
);
3544 if (face_id
< 0 || face_id
>= FRAME_N_PARAM_FACES (f
)
3545 || FRAME_PARAM_FACES (f
) [face_id
] == 0)
3546 size_ref
= f
->output_data
.x
->font
;
3549 size_ref
= FRAME_PARAM_FACES (f
) [face_id
]->font
;
3550 if (size_ref
== (XFontStruct
*) (~0))
3551 size_ref
= f
->output_data
.x
->font
;
3555 /* See if we cached the result for this particular query. */
3556 key
= Fcons (pattern
, maximum
);
3558 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
);
3560 /* We have info in the cache for this PATTERN. */
3563 Lisp_Object tem
, newlist
;
3565 /* We have info about this pattern. */
3566 list
= XCONS (list
)->cdr
;
3573 /* Filter the cached info and return just the fonts that match FACE. */
3575 for (tem
= list
; CONSP (tem
); tem
= XCONS (tem
)->cdr
)
3577 XFontStruct
*thisinfo
;
3579 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
3581 thisinfo
= XLoadQueryFont (FRAME_X_DISPLAY (f
),
3582 XSTRING (XCONS (tem
)->car
)->data
);
3584 x_check_errors (FRAME_X_DISPLAY (f
), "XLoadQueryFont failure: %s");
3585 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
3587 if (thisinfo
&& same_size_fonts (thisinfo
, size_ref
))
3588 newlist
= Fcons (XCONS (tem
)->car
, newlist
);
3591 XFreeFont (FRAME_X_DISPLAY (f
), thisinfo
);
3601 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
3603 /* Solaris 2.3 has a bug in XListFontsWithInfo. */
3604 #ifndef BROKEN_XLISTFONTSWITHINFO
3606 names
= XListFontsWithInfo (FRAME_X_DISPLAY (f
),
3607 XSTRING (pattern
)->data
,
3609 &num_fonts
, /* count_return */
3610 &info
); /* info_return */
3613 names
= XListFonts (FRAME_X_DISPLAY (f
),
3614 XSTRING (pattern
)->data
,
3616 &num_fonts
); /* count_return */
3618 x_check_errors (FRAME_X_DISPLAY (f
), "XListFonts failure: %s");
3619 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
3628 Lisp_Object full_list
;
3630 /* Make a list of all the fonts we got back.
3631 Store that in the font cache for the display. */
3633 for (i
= 0; i
< num_fonts
; i
++)
3634 full_list
= Fcons (build_string (names
[i
]), full_list
);
3635 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
3636 = Fcons (Fcons (key
, full_list
),
3637 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
);
3639 /* Make a list of the fonts that have the right width. */
3641 for (i
= 0; i
< num_fonts
; i
++)
3649 #ifdef BROKEN_XLISTFONTSWITHINFO
3650 XFontStruct
*thisinfo
;
3654 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
3655 thisinfo
= XLoadQueryFont (FRAME_X_DISPLAY (f
), names
[i
]);
3656 x_check_errors (FRAME_X_DISPLAY (f
),
3657 "XLoadQueryFont failure: %s");
3658 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
3662 keeper
= thisinfo
&& same_size_fonts (thisinfo
, size_ref
);
3664 if (thisinfo
&& ! keeper
)
3665 XFreeFont (FRAME_X_DISPLAY (f
), thisinfo
);
3667 XFreeFontInfo (NULL
, thisinfo
, 1);
3670 keeper
= same_size_fonts (&info
[i
], size_ref
);
3674 list
= Fcons (build_string (names
[i
]), list
);
3676 list
= Fnreverse (list
);
3679 #ifndef BROKEN_XLISTFONTSWITHINFO
3681 XFreeFontInfo (names
, info
, num_fonts
);
3684 XFreeFontNames (names
);
3693 DEFUN ("x-color-defined-p", Fx_color_defined_p
, Sx_color_defined_p
, 1, 2, 0,
3694 "Return non-nil if color COLOR is supported on frame FRAME.\n\
3695 If FRAME is omitted or nil, use the selected frame.")
3697 Lisp_Object color
, frame
;
3700 FRAME_PTR f
= check_x_frame (frame
);
3702 CHECK_STRING (color
, 1);
3704 if (defined_color (f
, XSTRING (color
)->data
, &foo
, 0))
3710 DEFUN ("x-color-values", Fx_color_values
, Sx_color_values
, 1, 2, 0,
3711 "Return a description of the color named COLOR on frame FRAME.\n\
3712 The value is a list of integer RGB values--(RED GREEN BLUE).\n\
3713 These values appear to range from 0 to 65280 or 65535, depending\n\
3714 on the system; white is (65280 65280 65280) or (65535 65535 65535).\n\
3715 If FRAME is omitted or nil, use the selected frame.")
3717 Lisp_Object color
, frame
;
3720 FRAME_PTR f
= check_x_frame (frame
);
3722 CHECK_STRING (color
, 1);
3724 if (defined_color (f
, XSTRING (color
)->data
, &foo
, 0))
3728 rgb
[0] = make_number (foo
.red
);
3729 rgb
[1] = make_number (foo
.green
);
3730 rgb
[2] = make_number (foo
.blue
);
3731 return Flist (3, rgb
);
3737 DEFUN ("x-display-color-p", Fx_display_color_p
, Sx_display_color_p
, 0, 1, 0,
3738 "Return t if the X display supports color.\n\
3739 The optional argument DISPLAY specifies which display to ask about.\n\
3740 DISPLAY should be either a frame or a display name (a string).\n\
3741 If omitted or nil, that stands for the selected frame's display.")
3743 Lisp_Object display
;
3745 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3747 if (dpyinfo
->n_planes
<= 2)
3750 switch (dpyinfo
->visual
->class)
3763 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
3765 "Return t if the X display supports shades of gray.\n\
3766 Note that color displays do support shades of gray.\n\
3767 The optional argument DISPLAY specifies which display to ask about.\n\
3768 DISPLAY should be either a frame or a display name (a string).\n\
3769 If omitted or nil, that stands for the selected frame's display.")
3771 Lisp_Object display
;
3773 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3775 if (dpyinfo
->n_planes
<= 1)
3778 switch (dpyinfo
->visual
->class)
3793 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
3795 "Returns the width in pixels of the X display DISPLAY.\n\
3796 The optional argument DISPLAY specifies which display to ask about.\n\
3797 DISPLAY should be either a frame or a display name (a string).\n\
3798 If omitted or nil, that stands for the selected frame's display.")
3800 Lisp_Object display
;
3802 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3804 return make_number (dpyinfo
->width
);
3807 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
3808 Sx_display_pixel_height
, 0, 1, 0,
3809 "Returns the height in pixels of the X display DISPLAY.\n\
3810 The optional argument DISPLAY specifies which display to ask about.\n\
3811 DISPLAY should be either a frame or a display name (a string).\n\
3812 If omitted or nil, that stands for the selected frame's display.")
3814 Lisp_Object display
;
3816 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3818 return make_number (dpyinfo
->height
);
3821 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
3823 "Returns the number of bitplanes of the X display DISPLAY.\n\
3824 The optional argument DISPLAY specifies which display to ask about.\n\
3825 DISPLAY should be either a frame or a display name (a string).\n\
3826 If omitted or nil, that stands for the selected frame's display.")
3828 Lisp_Object display
;
3830 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3832 return make_number (dpyinfo
->n_planes
);
3835 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
3837 "Returns the number of color cells of the X display DISPLAY.\n\
3838 The optional argument DISPLAY specifies which display to ask about.\n\
3839 DISPLAY should be either a frame or a display name (a string).\n\
3840 If omitted or nil, that stands for the selected frame's display.")
3842 Lisp_Object display
;
3844 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3846 return make_number (DisplayCells (dpyinfo
->display
,
3847 XScreenNumberOfScreen (dpyinfo
->screen
)));
3850 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
3851 Sx_server_max_request_size
,
3853 "Returns the maximum request size of the X server of display DISPLAY.\n\
3854 The optional argument DISPLAY specifies which display to ask about.\n\
3855 DISPLAY should be either a frame or a display name (a string).\n\
3856 If omitted or nil, that stands for the selected frame's display.")
3858 Lisp_Object display
;
3860 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3862 return make_number (MAXREQUEST (dpyinfo
->display
));
3865 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
3866 "Returns the vendor ID string of the X server of display DISPLAY.\n\
3867 The optional argument DISPLAY specifies which display to ask about.\n\
3868 DISPLAY should be either a frame or a display name (a string).\n\
3869 If omitted or nil, that stands for the selected frame's display.")
3871 Lisp_Object display
;
3873 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3874 char *vendor
= ServerVendor (dpyinfo
->display
);
3876 if (! vendor
) vendor
= "";
3877 return build_string (vendor
);
3880 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
3881 "Returns the version numbers of the X server of display DISPLAY.\n\
3882 The value is a list of three integers: the major and minor\n\
3883 version numbers of the X Protocol in use, and the vendor-specific release\n\
3884 number. See also the function `x-server-vendor'.\n\n\
3885 The optional argument DISPLAY specifies which display to ask about.\n\
3886 DISPLAY should be either a frame or a display name (a string).\n\
3887 If omitted or nil, that stands for the selected frame's display.")
3889 Lisp_Object display
;
3891 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3892 Display
*dpy
= dpyinfo
->display
;
3894 return Fcons (make_number (ProtocolVersion (dpy
)),
3895 Fcons (make_number (ProtocolRevision (dpy
)),
3896 Fcons (make_number (VendorRelease (dpy
)), Qnil
)));
3899 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
3900 "Returns the number of screens on the X server of display DISPLAY.\n\
3901 The optional argument DISPLAY specifies which display to ask about.\n\
3902 DISPLAY should be either a frame or a display name (a string).\n\
3903 If omitted or nil, that stands for the selected frame's display.")
3905 Lisp_Object display
;
3907 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3909 return make_number (ScreenCount (dpyinfo
->display
));
3912 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
3913 "Returns the height in millimeters of the X display DISPLAY.\n\
3914 The optional argument DISPLAY specifies which display to ask about.\n\
3915 DISPLAY should be either a frame or a display name (a string).\n\
3916 If omitted or nil, that stands for the selected frame's display.")
3918 Lisp_Object display
;
3920 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3922 return make_number (HeightMMOfScreen (dpyinfo
->screen
));
3925 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
3926 "Returns the width in millimeters of the X display DISPLAY.\n\
3927 The optional argument DISPLAY specifies which display to ask about.\n\
3928 DISPLAY should be either a frame or a display name (a string).\n\
3929 If omitted or nil, that stands for the selected frame's display.")
3931 Lisp_Object display
;
3933 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3935 return make_number (WidthMMOfScreen (dpyinfo
->screen
));
3938 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
3939 Sx_display_backing_store
, 0, 1, 0,
3940 "Returns an indication of whether X display DISPLAY does backing store.\n\
3941 The value may be `always', `when-mapped', or `not-useful'.\n\
3942 The optional argument DISPLAY specifies which display to ask about.\n\
3943 DISPLAY should be either a frame or a display name (a string).\n\
3944 If omitted or nil, that stands for the selected frame's display.")
3946 Lisp_Object display
;
3948 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3950 switch (DoesBackingStore (dpyinfo
->screen
))
3953 return intern ("always");
3956 return intern ("when-mapped");
3959 return intern ("not-useful");
3962 error ("Strange value for BackingStore parameter of screen");
3966 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
3967 Sx_display_visual_class
, 0, 1, 0,
3968 "Returns the visual class of the X display DISPLAY.\n\
3969 The value is one of the symbols `static-gray', `gray-scale',\n\
3970 `static-color', `pseudo-color', `true-color', or `direct-color'.\n\n\
3971 The optional argument DISPLAY specifies which display to ask about.\n\
3972 DISPLAY should be either a frame or a display name (a string).\n\
3973 If omitted or nil, that stands for the selected frame's display.")
3975 Lisp_Object display
;
3977 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3979 switch (dpyinfo
->visual
->class)
3981 case StaticGray
: return (intern ("static-gray"));
3982 case GrayScale
: return (intern ("gray-scale"));
3983 case StaticColor
: return (intern ("static-color"));
3984 case PseudoColor
: return (intern ("pseudo-color"));
3985 case TrueColor
: return (intern ("true-color"));
3986 case DirectColor
: return (intern ("direct-color"));
3988 error ("Display has an unknown visual class");
3992 DEFUN ("x-display-save-under", Fx_display_save_under
,
3993 Sx_display_save_under
, 0, 1, 0,
3994 "Returns t if the X display DISPLAY supports the save-under feature.\n\
3995 The optional argument DISPLAY specifies which display to ask about.\n\
3996 DISPLAY should be either a frame or a display name (a string).\n\
3997 If omitted or nil, that stands for the selected frame's display.")
3999 Lisp_Object display
;
4001 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4003 if (DoesSaveUnders (dpyinfo
->screen
) == True
)
4011 register struct frame
*f
;
4013 return PIXEL_WIDTH (f
);
4018 register struct frame
*f
;
4020 return PIXEL_HEIGHT (f
);
4025 register struct frame
*f
;
4027 return FONT_WIDTH (f
->output_data
.x
->font
);
4032 register struct frame
*f
;
4034 return f
->output_data
.x
->line_height
;
4039 register struct frame
*f
;
4041 return FRAME_X_DISPLAY_INFO (f
)->n_planes
;
4044 #if 0 /* These no longer seem like the right way to do things. */
4046 /* Draw a rectangle on the frame with left top corner including
4047 the character specified by LEFT_CHAR and TOP_CHAR. The rectangle is
4048 CHARS by LINES wide and long and is the color of the cursor. */
4051 x_rectangle (f
, gc
, left_char
, top_char
, chars
, lines
)
4052 register struct frame
*f
;
4054 register int top_char
, left_char
, chars
, lines
;
4058 int left
= (left_char
* FONT_WIDTH (f
->output_data
.x
->font
)
4059 + f
->output_data
.x
->internal_border_width
);
4060 int top
= (top_char
* f
->output_data
.x
->line_height
4061 + f
->output_data
.x
->internal_border_width
);
4064 width
= FONT_WIDTH (f
->output_data
.x
->font
) / 2;
4066 width
= FONT_WIDTH (f
->output_data
.x
->font
) * chars
;
4068 height
= f
->output_data
.x
->line_height
/ 2;
4070 height
= f
->output_data
.x
->line_height
* lines
;
4072 XDrawRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4073 gc
, left
, top
, width
, height
);
4076 DEFUN ("x-draw-rectangle", Fx_draw_rectangle
, Sx_draw_rectangle
, 5, 5, 0,
4077 "Draw a rectangle on FRAME between coordinates specified by\n\
4078 numbers X0, Y0, X1, Y1 in the cursor pixel.")
4079 (frame
, X0
, Y0
, X1
, Y1
)
4080 register Lisp_Object frame
, X0
, X1
, Y0
, Y1
;
4082 register int x0
, y0
, x1
, y1
, top
, left
, n_chars
, n_lines
;
4084 CHECK_LIVE_FRAME (frame
, 0);
4085 CHECK_NUMBER (X0
, 0);
4086 CHECK_NUMBER (Y0
, 1);
4087 CHECK_NUMBER (X1
, 2);
4088 CHECK_NUMBER (Y1
, 3);
4098 n_lines
= y1
- y0
+ 1;
4103 n_lines
= y0
- y1
+ 1;
4109 n_chars
= x1
- x0
+ 1;
4114 n_chars
= x0
- x1
+ 1;
4118 x_rectangle (XFRAME (frame
), XFRAME (frame
)->output_data
.x
->cursor_gc
,
4119 left
, top
, n_chars
, n_lines
);
4125 DEFUN ("x-erase-rectangle", Fx_erase_rectangle
, Sx_erase_rectangle
, 5, 5, 0,
4126 "Draw a rectangle drawn on FRAME between coordinates\n\
4127 X0, Y0, X1, Y1 in the regular background-pixel.")
4128 (frame
, X0
, Y0
, X1
, Y1
)
4129 register Lisp_Object frame
, X0
, Y0
, X1
, Y1
;
4131 register int x0
, y0
, x1
, y1
, top
, left
, n_chars
, n_lines
;
4133 CHECK_LIVE_FRAME (frame
, 0);
4134 CHECK_NUMBER (X0
, 0);
4135 CHECK_NUMBER (Y0
, 1);
4136 CHECK_NUMBER (X1
, 2);
4137 CHECK_NUMBER (Y1
, 3);
4147 n_lines
= y1
- y0
+ 1;
4152 n_lines
= y0
- y1
+ 1;
4158 n_chars
= x1
- x0
+ 1;
4163 n_chars
= x0
- x1
+ 1;
4167 x_rectangle (XFRAME (frame
), XFRAME (frame
)->output_data
.x
->reverse_gc
,
4168 left
, top
, n_chars
, n_lines
);
4174 /* Draw lines around the text region beginning at the character position
4175 TOP_X, TOP_Y and ending at BOTTOM_X and BOTTOM_Y. GC specifies the
4176 pixel and line characteristics. */
4178 #define line_len(line) (FRAME_CURRENT_GLYPHS (f)->used[(line)])
4181 outline_region (f
, gc
, top_x
, top_y
, bottom_x
, bottom_y
)
4182 register struct frame
*f
;
4184 int top_x
, top_y
, bottom_x
, bottom_y
;
4186 register int ibw
= f
->output_data
.x
->internal_border_width
;
4187 register int font_w
= FONT_WIDTH (f
->output_data
.x
->font
);
4188 register int font_h
= f
->output_data
.x
->line_height
;
4190 int x
= line_len (y
);
4191 XPoint
*pixel_points
4192 = (XPoint
*) alloca (((bottom_y
- top_y
+ 2) * 4) * sizeof (XPoint
));
4193 register XPoint
*this_point
= pixel_points
;
4195 /* Do the horizontal top line/lines */
4198 this_point
->x
= ibw
;
4199 this_point
->y
= ibw
+ (font_h
* top_y
);
4202 this_point
->x
= ibw
+ (font_w
/ 2); /* Half-size for newline chars. */
4204 this_point
->x
= ibw
+ (font_w
* x
);
4205 this_point
->y
= (this_point
- 1)->y
;
4209 this_point
->x
= ibw
;
4210 this_point
->y
= ibw
+ (font_h
* (top_y
+ 1));
4212 this_point
->x
= ibw
+ (font_w
* top_x
);
4213 this_point
->y
= (this_point
- 1)->y
;
4215 this_point
->x
= (this_point
- 1)->x
;
4216 this_point
->y
= ibw
+ (font_h
* top_y
);
4218 this_point
->x
= ibw
+ (font_w
* x
);
4219 this_point
->y
= (this_point
- 1)->y
;
4222 /* Now do the right side. */
4223 while (y
< bottom_y
)
4224 { /* Right vertical edge */
4226 this_point
->x
= (this_point
- 1)->x
;
4227 this_point
->y
= ibw
+ (font_h
* (y
+ 1));
4230 y
++; /* Horizontal connection to next line */
4233 this_point
->x
= ibw
+ (font_w
/ 2);
4235 this_point
->x
= ibw
+ (font_w
* x
);
4237 this_point
->y
= (this_point
- 1)->y
;
4240 /* Now do the bottom and connect to the top left point. */
4241 this_point
->x
= ibw
+ (font_w
* (bottom_x
+ 1));
4244 this_point
->x
= (this_point
- 1)->x
;
4245 this_point
->y
= ibw
+ (font_h
* (bottom_y
+ 1));
4247 this_point
->x
= ibw
;
4248 this_point
->y
= (this_point
- 1)->y
;
4250 this_point
->x
= pixel_points
->x
;
4251 this_point
->y
= pixel_points
->y
;
4253 XDrawLines (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4255 (this_point
- pixel_points
+ 1), CoordModeOrigin
);
4258 DEFUN ("x-contour-region", Fx_contour_region
, Sx_contour_region
, 1, 1, 0,
4259 "Highlight the region between point and the character under the mouse\n\
4262 register Lisp_Object event
;
4264 register int x0
, y0
, x1
, y1
;
4265 register struct frame
*f
= selected_frame
;
4266 register int p1
, p2
;
4268 CHECK_CONS (event
, 0);
4271 x0
= XINT (Fcar (Fcar (event
)));
4272 y0
= XINT (Fcar (Fcdr (Fcar (event
))));
4274 /* If the mouse is past the end of the line, don't that area. */
4275 /* ReWrite this... */
4280 if (y1
> y0
) /* point below mouse */
4281 outline_region (f
, f
->output_data
.x
->cursor_gc
,
4283 else if (y1
< y0
) /* point above mouse */
4284 outline_region (f
, f
->output_data
.x
->cursor_gc
,
4286 else /* same line: draw horizontal rectangle */
4289 x_rectangle (f
, f
->output_data
.x
->cursor_gc
,
4290 x0
, y0
, (x1
- x0
+ 1), 1);
4292 x_rectangle (f
, f
->output_data
.x
->cursor_gc
,
4293 x1
, y1
, (x0
- x1
+ 1), 1);
4296 XFlush (FRAME_X_DISPLAY (f
));
4302 DEFUN ("x-uncontour-region", Fx_uncontour_region
, Sx_uncontour_region
, 1, 1, 0,
4303 "Erase any highlighting of the region between point and the character\n\
4304 at X, Y on the selected frame.")
4306 register Lisp_Object event
;
4308 register int x0
, y0
, x1
, y1
;
4309 register struct frame
*f
= selected_frame
;
4312 x0
= XINT (Fcar (Fcar (event
)));
4313 y0
= XINT (Fcar (Fcdr (Fcar (event
))));
4317 if (y1
> y0
) /* point below mouse */
4318 outline_region (f
, f
->output_data
.x
->reverse_gc
,
4320 else if (y1
< y0
) /* point above mouse */
4321 outline_region (f
, f
->output_data
.x
->reverse_gc
,
4323 else /* same line: draw horizontal rectangle */
4326 x_rectangle (f
, f
->output_data
.x
->reverse_gc
,
4327 x0
, y0
, (x1
- x0
+ 1), 1);
4329 x_rectangle (f
, f
->output_data
.x
->reverse_gc
,
4330 x1
, y1
, (x0
- x1
+ 1), 1);
4338 int contour_begin_x
, contour_begin_y
;
4339 int contour_end_x
, contour_end_y
;
4340 int contour_npoints
;
4342 /* Clip the top part of the contour lines down (and including) line Y_POS.
4343 If X_POS is in the middle (rather than at the end) of the line, drop
4344 down a line at that character. */
4347 clip_contour_top (y_pos
, x_pos
)
4349 register XPoint
*begin
= contour_lines
[y_pos
].top_left
;
4350 register XPoint
*end
;
4351 register int npoints
;
4352 register struct display_line
*line
= selected_frame
->phys_lines
[y_pos
+ 1];
4354 if (x_pos
>= line
->len
- 1) /* Draw one, straight horizontal line. */
4356 end
= contour_lines
[y_pos
].top_right
;
4357 npoints
= (end
- begin
+ 1);
4358 XDrawLines (x_current_display
, contour_window
,
4359 contour_erase_gc
, begin_erase
, npoints
, CoordModeOrigin
);
4361 bcopy (end
, begin
+ 1, contour_last_point
- end
+ 1);
4362 contour_last_point
-= (npoints
- 2);
4363 XDrawLines (x_current_display
, contour_window
,
4364 contour_erase_gc
, begin
, 2, CoordModeOrigin
);
4365 XFlush (x_current_display
);
4367 /* Now, update contour_lines structure. */
4372 register XPoint
*p
= begin
+ 1;
4373 end
= contour_lines
[y_pos
].bottom_right
;
4374 npoints
= (end
- begin
+ 1);
4375 XDrawLines (x_current_display
, contour_window
,
4376 contour_erase_gc
, begin_erase
, npoints
, CoordModeOrigin
);
4379 p
->x
= ibw
+ (font_w
* (x_pos
+ 1));
4381 p
->y
= begin
->y
+ font_h
;
4383 bcopy (end
, begin
+ 3, contour_last_point
- end
+ 1);
4384 contour_last_point
-= (npoints
- 5);
4385 XDrawLines (x_current_display
, contour_window
,
4386 contour_erase_gc
, begin
, 4, CoordModeOrigin
);
4387 XFlush (x_current_display
);
4389 /* Now, update contour_lines structure. */
4393 /* Erase the top horizontal lines of the contour, and then extend
4394 the contour upwards. */
4397 extend_contour_top (line
)
4402 clip_contour_bottom (x_pos
, y_pos
)
4408 extend_contour_bottom (x_pos
, y_pos
)
4412 DEFUN ("x-select-region", Fx_select_region
, Sx_select_region
, 1, 1, "e",
4417 register struct frame
*f
= selected_frame
;
4418 register int point_x
= f
->cursor_x
;
4419 register int point_y
= f
->cursor_y
;
4420 register int mouse_below_point
;
4421 register Lisp_Object obj
;
4422 register int x_contour_x
, x_contour_y
;
4424 x_contour_x
= x_mouse_x
;
4425 x_contour_y
= x_mouse_y
;
4426 if (x_contour_y
> point_y
|| (x_contour_y
== point_y
4427 && x_contour_x
> point_x
))
4429 mouse_below_point
= 1;
4430 outline_region (f
, f
->output_data
.x
->cursor_gc
, point_x
, point_y
,
4431 x_contour_x
, x_contour_y
);
4435 mouse_below_point
= 0;
4436 outline_region (f
, f
->output_data
.x
->cursor_gc
, x_contour_x
, x_contour_y
,
4442 obj
= read_char (-1, 0, 0, Qnil
, 0);
4446 if (mouse_below_point
)
4448 if (x_mouse_y
<= point_y
) /* Flipped. */
4450 mouse_below_point
= 0;
4452 outline_region (f
, f
->output_data
.x
->reverse_gc
, point_x
, point_y
,
4453 x_contour_x
, x_contour_y
);
4454 outline_region (f
, f
->output_data
.x
->cursor_gc
, x_mouse_x
, x_mouse_y
,
4457 else if (x_mouse_y
< x_contour_y
) /* Bottom clipped. */
4459 clip_contour_bottom (x_mouse_y
);
4461 else if (x_mouse_y
> x_contour_y
) /* Bottom extended. */
4463 extend_bottom_contour (x_mouse_y
);
4466 x_contour_x
= x_mouse_x
;
4467 x_contour_y
= x_mouse_y
;
4469 else /* mouse above or same line as point */
4471 if (x_mouse_y
>= point_y
) /* Flipped. */
4473 mouse_below_point
= 1;
4475 outline_region (f
, f
->output_data
.x
->reverse_gc
,
4476 x_contour_x
, x_contour_y
, point_x
, point_y
);
4477 outline_region (f
, f
->output_data
.x
->cursor_gc
, point_x
, point_y
,
4478 x_mouse_x
, x_mouse_y
);
4480 else if (x_mouse_y
> x_contour_y
) /* Top clipped. */
4482 clip_contour_top (x_mouse_y
);
4484 else if (x_mouse_y
< x_contour_y
) /* Top extended. */
4486 extend_contour_top (x_mouse_y
);
4491 unread_command_event
= obj
;
4492 if (mouse_below_point
)
4494 contour_begin_x
= point_x
;
4495 contour_begin_y
= point_y
;
4496 contour_end_x
= x_contour_x
;
4497 contour_end_y
= x_contour_y
;
4501 contour_begin_x
= x_contour_x
;
4502 contour_begin_y
= x_contour_y
;
4503 contour_end_x
= point_x
;
4504 contour_end_y
= point_y
;
4509 DEFUN ("x-horizontal-line", Fx_horizontal_line
, Sx_horizontal_line
, 1, 1, "e",
4514 register Lisp_Object obj
;
4515 struct frame
*f
= selected_frame
;
4516 register struct window
*w
= XWINDOW (selected_window
);
4517 register GC line_gc
= f
->output_data
.x
->cursor_gc
;
4518 register GC erase_gc
= f
->output_data
.x
->reverse_gc
;
4520 char dash_list
[] = {6, 4, 6, 4};
4522 XGCValues gc_values
;
4524 register int previous_y
;
4525 register int line
= (x_mouse_y
+ 1) * f
->output_data
.x
->line_height
4526 + f
->output_data
.x
->internal_border_width
;
4527 register int left
= f
->output_data
.x
->internal_border_width
4528 + (WINDOW_LEFT_MARGIN (w
)
4529 * FONT_WIDTH (f
->output_data
.x
->font
));
4530 register int right
= left
+ (w
->width
4531 * FONT_WIDTH (f
->output_data
.x
->font
))
4532 - f
->output_data
.x
->internal_border_width
;
4536 gc_values
.foreground
= f
->output_data
.x
->cursor_pixel
;
4537 gc_values
.background
= f
->output_data
.x
->background_pixel
;
4538 gc_values
.line_width
= 1;
4539 gc_values
.line_style
= LineOnOffDash
;
4540 gc_values
.cap_style
= CapRound
;
4541 gc_values
.join_style
= JoinRound
;
4543 line_gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4544 GCLineStyle
| GCJoinStyle
| GCCapStyle
4545 | GCLineWidth
| GCForeground
| GCBackground
,
4547 XSetDashes (FRAME_X_DISPLAY (f
), line_gc
, 0, dash_list
, dashes
);
4548 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
4549 gc_values
.background
= f
->output_data
.x
->foreground_pixel
;
4550 erase_gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4551 GCLineStyle
| GCJoinStyle
| GCCapStyle
4552 | GCLineWidth
| GCForeground
| GCBackground
,
4554 XSetDashes (FRAME_X_DISPLAY (f
), erase_gc
, 0, dash_list
, dashes
);
4561 if (x_mouse_y
>= XINT (w
->top
)
4562 && x_mouse_y
< XINT (w
->top
) + XINT (w
->height
) - 1)
4564 previous_y
= x_mouse_y
;
4565 line
= (x_mouse_y
+ 1) * f
->output_data
.x
->line_height
4566 + f
->output_data
.x
->internal_border_width
;
4567 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4568 line_gc
, left
, line
, right
, line
);
4570 XFlush (FRAME_X_DISPLAY (f
));
4575 obj
= read_char (-1, 0, 0, Qnil
, 0);
4577 || (! EQ (Fcar (Fcdr (Fcdr (obj
))),
4578 Qvertical_scroll_bar
))
4582 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4583 erase_gc
, left
, line
, right
, line
);
4584 unread_command_event
= obj
;
4586 XFreeGC (FRAME_X_DISPLAY (f
), line_gc
);
4587 XFreeGC (FRAME_X_DISPLAY (f
), erase_gc
);
4593 while (x_mouse_y
== previous_y
);
4596 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4597 erase_gc
, left
, line
, right
, line
);
4604 /* These keep track of the rectangle following the pointer. */
4605 int mouse_track_top
, mouse_track_left
, mouse_track_width
;
4607 /* Offset in buffer of character under the pointer, or 0. */
4608 int mouse_buffer_offset
;
4610 DEFUN ("x-track-pointer", Fx_track_pointer
, Sx_track_pointer
, 0, 0, 0,
4611 "Track the pointer.")
4614 static Cursor current_pointer_shape
;
4615 FRAME_PTR f
= x_mouse_frame
;
4618 if (EQ (Vmouse_frame_part
, Qtext_part
)
4619 && (current_pointer_shape
!= f
->output_data
.x
->nontext_cursor
))
4624 current_pointer_shape
= f
->output_data
.x
->nontext_cursor
;
4625 XDefineCursor (FRAME_X_DISPLAY (f
),
4627 current_pointer_shape
);
4629 buf
= XBUFFER (XWINDOW (Vmouse_window
)->buffer
);
4630 c
= *(BUF_CHAR_ADDRESS (buf
, mouse_buffer_offset
));
4632 else if (EQ (Vmouse_frame_part
, Qmodeline_part
)
4633 && (current_pointer_shape
!= f
->output_data
.x
->modeline_cursor
))
4635 current_pointer_shape
= f
->output_data
.x
->modeline_cursor
;
4636 XDefineCursor (FRAME_X_DISPLAY (f
),
4638 current_pointer_shape
);
4641 XFlush (FRAME_X_DISPLAY (f
));
4647 DEFUN ("x-track-pointer", Fx_track_pointer
, Sx_track_pointer
, 1, 1, "e",
4648 "Draw rectangle around character under mouse pointer, if there is one.")
4652 struct window
*w
= XWINDOW (Vmouse_window
);
4653 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4654 struct buffer
*b
= XBUFFER (w
->buffer
);
4657 if (! EQ (Vmouse_window
, selected_window
))
4660 if (EQ (event
, Qnil
))
4664 x_read_mouse_position (selected_frame
, &x
, &y
);
4668 mouse_track_width
= 0;
4669 mouse_track_left
= mouse_track_top
= -1;
4673 if ((x_mouse_x
!= mouse_track_left
4674 && (x_mouse_x
< mouse_track_left
4675 || x_mouse_x
> (mouse_track_left
+ mouse_track_width
)))
4676 || x_mouse_y
!= mouse_track_top
)
4678 int hp
= 0; /* Horizontal position */
4679 int len
= FRAME_CURRENT_GLYPHS (f
)->used
[x_mouse_y
];
4680 int p
= FRAME_CURRENT_GLYPHS (f
)->bufp
[x_mouse_y
];
4681 int tab_width
= XINT (b
->tab_width
);
4682 int ctl_arrow_p
= !NILP (b
->ctl_arrow
);
4684 int mode_line_vpos
= XFASTINT (w
->height
) + XFASTINT (w
->top
) - 1;
4685 int in_mode_line
= 0;
4687 if (! FRAME_CURRENT_GLYPHS (f
)->enable
[x_mouse_y
])
4690 /* Erase previous rectangle. */
4691 if (mouse_track_width
)
4693 x_rectangle (f
, f
->output_data
.x
->reverse_gc
,
4694 mouse_track_left
, mouse_track_top
,
4695 mouse_track_width
, 1);
4697 if ((mouse_track_left
== f
->phys_cursor_x
4698 || mouse_track_left
== f
->phys_cursor_x
- 1)
4699 && mouse_track_top
== f
->phys_cursor_y
)
4701 x_display_cursor (f
, 1);
4705 mouse_track_left
= x_mouse_x
;
4706 mouse_track_top
= x_mouse_y
;
4707 mouse_track_width
= 0;
4709 if (mouse_track_left
> len
) /* Past the end of line. */
4712 if (mouse_track_top
== mode_line_vpos
)
4718 if (tab_width
<= 0 || tab_width
> 20) tab_width
= 8;
4722 if (len
== f
->width
&& hp
== len
- 1 && c
!= '\n')
4728 mouse_track_width
= tab_width
- (hp
% tab_width
);
4730 hp
+= mouse_track_width
;
4733 mouse_track_left
= hp
- mouse_track_width
;
4739 mouse_track_width
= -1;
4743 if (ctl_arrow_p
&& (c
< 040 || c
== 0177))
4748 mouse_track_width
= 2;
4753 mouse_track_left
= hp
- mouse_track_width
;
4759 mouse_track_width
= 1;
4766 while (hp
<= x_mouse_x
);
4769 if (mouse_track_width
) /* Over text; use text pointer shape. */
4771 XDefineCursor (FRAME_X_DISPLAY (f
),
4773 f
->output_data
.x
->text_cursor
);
4774 x_rectangle (f
, f
->output_data
.x
->cursor_gc
,
4775 mouse_track_left
, mouse_track_top
,
4776 mouse_track_width
, 1);
4778 else if (in_mode_line
)
4779 XDefineCursor (FRAME_X_DISPLAY (f
),
4781 f
->output_data
.x
->modeline_cursor
);
4783 XDefineCursor (FRAME_X_DISPLAY (f
),
4785 f
->output_data
.x
->nontext_cursor
);
4788 XFlush (FRAME_X_DISPLAY (f
));
4791 obj
= read_char (-1, 0, 0, Qnil
, 0);
4794 while (CONSP (obj
) /* Mouse event */
4795 && EQ (Fcar (Fcdr (Fcdr (obj
))), Qnil
) /* Not scroll bar */
4796 && EQ (Vmouse_depressed
, Qnil
) /* Only motion events */
4797 && EQ (Vmouse_window
, selected_window
) /* In this window */
4800 unread_command_event
= obj
;
4802 if (mouse_track_width
)
4804 x_rectangle (f
, f
->output_data
.x
->reverse_gc
,
4805 mouse_track_left
, mouse_track_top
,
4806 mouse_track_width
, 1);
4807 mouse_track_width
= 0;
4808 if ((mouse_track_left
== f
->phys_cursor_x
4809 || mouse_track_left
- 1 == f
->phys_cursor_x
)
4810 && mouse_track_top
== f
->phys_cursor_y
)
4812 x_display_cursor (f
, 1);
4815 XDefineCursor (FRAME_X_DISPLAY (f
),
4817 f
->output_data
.x
->nontext_cursor
);
4818 XFlush (FRAME_X_DISPLAY (f
));
4828 /* Draw a pixmap specified by IMAGE_DATA of dimensions WIDTH and HEIGHT
4829 on the frame F at position X, Y. */
4831 x_draw_pixmap (f
, x
, y
, image_data
, width
, height
)
4833 int x
, y
, width
, height
;
4838 image
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
4839 FRAME_X_WINDOW (f
), image_data
,
4841 XCopyPlane (FRAME_X_DISPLAY (f
), image
, FRAME_X_WINDOW (f
),
4842 f
->output_data
.x
->normal_gc
, 0, 0, width
, height
, x
, y
);
4846 #if 0 /* I'm told these functions are superfluous
4847 given the ability to bind function keys. */
4850 DEFUN ("x-rebind-key", Fx_rebind_key
, Sx_rebind_key
, 3, 3, 0,
4851 "Rebind X keysym KEYSYM, with MODIFIERS, to generate NEWSTRING.\n\
4852 KEYSYM is a string which conforms to the X keysym definitions found\n\
4853 in X11/keysymdef.h, sans the initial XK_. MODIFIERS is nil or a\n\
4854 list of strings specifying modifier keys such as Control_L, which must\n\
4855 also be depressed for NEWSTRING to appear.")
4856 (x_keysym
, modifiers
, newstring
)
4857 register Lisp_Object x_keysym
;
4858 register Lisp_Object modifiers
;
4859 register Lisp_Object newstring
;
4862 register KeySym keysym
;
4863 KeySym modifier_list
[16];
4866 CHECK_STRING (x_keysym
, 1);
4867 CHECK_STRING (newstring
, 3);
4869 keysym
= XStringToKeysym ((char *) XSTRING (x_keysym
)->data
);
4870 if (keysym
== NoSymbol
)
4871 error ("Keysym does not exist");
4873 if (NILP (modifiers
))
4874 XRebindKeysym (x_current_display
, keysym
, modifier_list
, 0,
4875 XSTRING (newstring
)->data
,
4876 STRING_BYTES (XSTRING (newstring
)));
4879 register Lisp_Object rest
, mod
;
4882 for (rest
= modifiers
; !NILP (rest
); rest
= Fcdr (rest
))
4885 error ("Can't have more than 16 modifiers");
4888 CHECK_STRING (mod
, 3);
4889 modifier_list
[i
] = XStringToKeysym ((char *) XSTRING (mod
)->data
);
4891 if (modifier_list
[i
] == NoSymbol
4892 || !(IsModifierKey (modifier_list
[i
])
4893 || ((unsigned)(modifier_list
[i
]) == XK_Mode_switch
)
4894 || ((unsigned)(modifier_list
[i
]) == XK_Num_Lock
)))
4896 if (modifier_list
[i
] == NoSymbol
4897 || !IsModifierKey (modifier_list
[i
]))
4899 error ("Element is not a modifier keysym");
4903 XRebindKeysym (x_current_display
, keysym
, modifier_list
, i
,
4904 XSTRING (newstring
)->data
,
4905 STRING_BYTES (XSTRING (newstring
)));
4911 DEFUN ("x-rebind-keys", Fx_rebind_keys
, Sx_rebind_keys
, 2, 2, 0,
4912 "Rebind KEYCODE to list of strings STRINGS.\n\
4913 STRINGS should be a list of 16 elements, one for each shift combination.\n\
4914 nil as element means don't change.\n\
4915 See the documentation of `x-rebind-key' for more information.")
4917 register Lisp_Object keycode
;
4918 register Lisp_Object strings
;
4920 register Lisp_Object item
;
4921 register unsigned char *rawstring
;
4922 KeySym rawkey
, modifier
[1];
4924 register unsigned i
;
4927 CHECK_NUMBER (keycode
, 1);
4928 CHECK_CONS (strings
, 2);
4929 rawkey
= (KeySym
) ((unsigned) (XINT (keycode
))) & 255;
4930 for (i
= 0; i
<= 15; strings
= Fcdr (strings
), i
++)
4932 item
= Fcar (strings
);
4935 CHECK_STRING (item
, 2);
4936 strsize
= STRING_BYTES (XSTRING (item
));
4937 rawstring
= (unsigned char *) xmalloc (strsize
);
4938 bcopy (XSTRING (item
)->data
, rawstring
, strsize
);
4939 modifier
[1] = 1 << i
;
4940 XRebindKeysym (x_current_display
, rawkey
, modifier
, 1,
4941 rawstring
, strsize
);
4946 #endif /* HAVE_X11 */
4949 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4951 XScreenNumberOfScreen (scr
)
4952 register Screen
*scr
;
4954 register Display
*dpy
;
4955 register Screen
*dpyscr
;
4959 dpyscr
= dpy
->screens
;
4961 for (i
= 0; i
< dpy
->nscreens
; i
++, dpyscr
++)
4967 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4970 select_visual (dpy
, screen
, depth
)
4973 unsigned int *depth
;
4976 XVisualInfo
*vinfo
, vinfo_template
;
4979 v
= DefaultVisualOfScreen (screen
);
4982 vinfo_template
.visualid
= XVisualIDFromVisual (v
);
4984 vinfo_template
.visualid
= v
->visualid
;
4987 vinfo_template
.screen
= XScreenNumberOfScreen (screen
);
4989 vinfo
= XGetVisualInfo (dpy
,
4990 VisualIDMask
| VisualScreenMask
, &vinfo_template
,
4993 fatal ("Can't get proper X visual info");
4995 if ((1 << vinfo
->depth
) == vinfo
->colormap_size
)
4996 *depth
= vinfo
->depth
;
5000 int n
= vinfo
->colormap_size
- 1;
5009 XFree ((char *) vinfo
);
5013 /* Return the X display structure for the display named NAME.
5014 Open a new connection if necessary. */
5016 struct x_display_info
*
5017 x_display_info_for_name (name
)
5021 struct x_display_info
*dpyinfo
;
5023 CHECK_STRING (name
, 0);
5025 if (! EQ (Vwindow_system
, intern ("x")))
5026 error ("Not using X Windows");
5028 for (dpyinfo
= x_display_list
, names
= x_display_name_list
;
5030 dpyinfo
= dpyinfo
->next
, names
= XCONS (names
)->cdr
)
5033 tem
= Fstring_equal (XCONS (XCONS (names
)->car
)->car
, name
);
5038 /* Use this general default value to start with. */
5039 Vx_resource_name
= Vinvocation_name
;
5041 validate_x_resource_name ();
5043 dpyinfo
= x_term_init (name
, (unsigned char *)0,
5044 (char *) XSTRING (Vx_resource_name
)->data
);
5047 error ("Cannot connect to X server %s", XSTRING (name
)->data
);
5050 XSETFASTINT (Vwindow_system_version
, 11);
5055 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
5056 1, 3, 0, "Open a connection to an X server.\n\
5057 DISPLAY is the name of the display to connect to.\n\
5058 Optional second arg XRM-STRING is a string of resources in xrdb format.\n\
5059 If the optional third arg MUST-SUCCEED is non-nil,\n\
5060 terminate Emacs if we can't open the connection.")
5061 (display
, xrm_string
, must_succeed
)
5062 Lisp_Object display
, xrm_string
, must_succeed
;
5064 unsigned int n_planes
;
5065 unsigned char *xrm_option
;
5066 struct x_display_info
*dpyinfo
;
5068 CHECK_STRING (display
, 0);
5069 if (! NILP (xrm_string
))
5070 CHECK_STRING (xrm_string
, 1);
5072 if (! EQ (Vwindow_system
, intern ("x")))
5073 error ("Not using X Windows");
5075 if (! NILP (xrm_string
))
5076 xrm_option
= (unsigned char *) XSTRING (xrm_string
)->data
;
5078 xrm_option
= (unsigned char *) 0;
5080 validate_x_resource_name ();
5082 /* This is what opens the connection and sets x_current_display.
5083 This also initializes many symbols, such as those used for input. */
5084 dpyinfo
= x_term_init (display
, xrm_option
,
5085 (char *) XSTRING (Vx_resource_name
)->data
);
5089 if (!NILP (must_succeed
))
5090 fatal ("Cannot connect to X server %s.\n\
5091 Check the DISPLAY environment variable or use `-d'.\n\
5092 Also use the `xhost' program to verify that it is set to permit\n\
5093 connections from your machine.\n",
5094 XSTRING (display
)->data
);
5096 error ("Cannot connect to X server %s", XSTRING (display
)->data
);
5101 XSETFASTINT (Vwindow_system_version
, 11);
5105 DEFUN ("x-close-connection", Fx_close_connection
,
5106 Sx_close_connection
, 1, 1, 0,
5107 "Close the connection to DISPLAY's X server.\n\
5108 For DISPLAY, specify either a frame or a display name (a string).\n\
5109 If DISPLAY is nil, that stands for the selected frame's display.")
5111 Lisp_Object display
;
5113 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
5114 struct x_display_info
*tail
;
5117 if (dpyinfo
->reference_count
> 0)
5118 error ("Display still has frames on it");
5121 /* Free the fonts in the font table. */
5122 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
5124 if (dpyinfo
->font_table
[i
].name
)
5125 free (dpyinfo
->font_table
[i
].name
);
5126 /* Don't free the full_name string;
5127 it is always shared with something else. */
5128 XFreeFont (dpyinfo
->display
, dpyinfo
->font_table
[i
].font
);
5130 x_destroy_all_bitmaps (dpyinfo
);
5131 XSetCloseDownMode (dpyinfo
->display
, DestroyAll
);
5133 #ifdef USE_X_TOOLKIT
5134 XtCloseDisplay (dpyinfo
->display
);
5136 XCloseDisplay (dpyinfo
->display
);
5139 x_delete_display (dpyinfo
);
5145 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
5146 "Return the list of display names that Emacs has connections to.")
5149 Lisp_Object tail
, result
;
5152 for (tail
= x_display_name_list
; ! NILP (tail
); tail
= XCONS (tail
)->cdr
)
5153 result
= Fcons (XCONS (XCONS (tail
)->car
)->car
, result
);
5158 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
5159 "If ON is non-nil, report X errors as soon as the erring request is made.\n\
5160 If ON is nil, allow buffering of requests.\n\
5161 Turning on synchronization prohibits the Xlib routines from buffering\n\
5162 requests and seriously degrades performance, but makes debugging much\n\
5164 The optional second argument DISPLAY specifies which display to act on.\n\
5165 DISPLAY should be either a frame or a display name (a string).\n\
5166 If DISPLAY is omitted or nil, that stands for the selected frame's display.")
5168 Lisp_Object display
, on
;
5170 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
5172 XSynchronize (dpyinfo
->display
, !EQ (on
, Qnil
));
5177 /* Wait for responses to all X commands issued so far for frame F. */
5184 XSync (FRAME_X_DISPLAY (f
), False
);
5190 /* This is zero if not using X windows. */
5193 /* The section below is built by the lisp expression at the top of the file,
5194 just above where these variables are declared. */
5195 /*&&& init symbols here &&&*/
5196 Qauto_raise
= intern ("auto-raise");
5197 staticpro (&Qauto_raise
);
5198 Qauto_lower
= intern ("auto-lower");
5199 staticpro (&Qauto_lower
);
5200 Qbackground_color
= intern ("background-color");
5201 staticpro (&Qbackground_color
);
5202 Qbar
= intern ("bar");
5204 Qborder_color
= intern ("border-color");
5205 staticpro (&Qborder_color
);
5206 Qborder_width
= intern ("border-width");
5207 staticpro (&Qborder_width
);
5208 Qbox
= intern ("box");
5210 Qcursor_color
= intern ("cursor-color");
5211 staticpro (&Qcursor_color
);
5212 Qcursor_type
= intern ("cursor-type");
5213 staticpro (&Qcursor_type
);
5214 Qforeground_color
= intern ("foreground-color");
5215 staticpro (&Qforeground_color
);
5216 Qgeometry
= intern ("geometry");
5217 staticpro (&Qgeometry
);
5218 Qicon_left
= intern ("icon-left");
5219 staticpro (&Qicon_left
);
5220 Qicon_top
= intern ("icon-top");
5221 staticpro (&Qicon_top
);
5222 Qicon_type
= intern ("icon-type");
5223 staticpro (&Qicon_type
);
5224 Qicon_name
= intern ("icon-name");
5225 staticpro (&Qicon_name
);
5226 Qinternal_border_width
= intern ("internal-border-width");
5227 staticpro (&Qinternal_border_width
);
5228 Qleft
= intern ("left");
5230 Qright
= intern ("right");
5231 staticpro (&Qright
);
5232 Qmouse_color
= intern ("mouse-color");
5233 staticpro (&Qmouse_color
);
5234 Qnone
= intern ("none");
5236 Qparent_id
= intern ("parent-id");
5237 staticpro (&Qparent_id
);
5238 Qscroll_bar_width
= intern ("scroll-bar-width");
5239 staticpro (&Qscroll_bar_width
);
5240 Qsuppress_icon
= intern ("suppress-icon");
5241 staticpro (&Qsuppress_icon
);
5242 Qtop
= intern ("top");
5244 Qundefined_color
= intern ("undefined-color");
5245 staticpro (&Qundefined_color
);
5246 Qvertical_scroll_bars
= intern ("vertical-scroll-bars");
5247 staticpro (&Qvertical_scroll_bars
);
5248 Qvisibility
= intern ("visibility");
5249 staticpro (&Qvisibility
);
5250 Qwindow_id
= intern ("window-id");
5251 staticpro (&Qwindow_id
);
5252 Qx_frame_parameter
= intern ("x-frame-parameter");
5253 staticpro (&Qx_frame_parameter
);
5254 Qx_resource_name
= intern ("x-resource-name");
5255 staticpro (&Qx_resource_name
);
5256 Quser_position
= intern ("user-position");
5257 staticpro (&Quser_position
);
5258 Quser_size
= intern ("user-size");
5259 staticpro (&Quser_size
);
5260 Qdisplay
= intern ("display");
5261 staticpro (&Qdisplay
);
5262 /* This is the end of symbol initialization. */
5264 Qface_set_after_frame_default
= intern ("face-set-after-frame-default");
5265 staticpro (&Qface_set_after_frame_default
);
5267 Fput (Qundefined_color
, Qerror_conditions
,
5268 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
5269 Fput (Qundefined_color
, Qerror_message
,
5270 build_string ("Undefined color"));
5272 init_x_parm_symbols ();
5274 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path
,
5275 "List of directories to search for bitmap files for X.");
5276 Vx_bitmap_file_path
= decode_env_path ((char *) 0, PATH_BITMAPS
);
5278 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
5279 "The shape of the pointer when over text.\n\
5280 Changing the value does not affect existing frames\n\
5281 unless you set the mouse color.");
5282 Vx_pointer_shape
= Qnil
;
5284 DEFVAR_LISP ("x-resource-name", &Vx_resource_name
,
5285 "The name Emacs uses to look up X resources.\n\
5286 `x-get-resource' uses this as the first component of the instance name\n\
5287 when requesting resource values.\n\
5288 Emacs initially sets `x-resource-name' to the name under which Emacs\n\
5289 was invoked, or to the value specified with the `-name' or `-rn'\n\
5290 switches, if present.\n\
5292 It may be useful to bind this variable locally around a call\n\
5293 to `x-get-resource'. See also the variable `x-resource-class'.");
5294 Vx_resource_name
= Qnil
;
5296 DEFVAR_LISP ("x-resource-class", &Vx_resource_class
,
5297 "The class Emacs uses to look up X resources.\n\
5298 `x-get-resource' uses this as the first component of the instance class\n\
5299 when requesting resource values.\n\
5300 Emacs initially sets `x-resource-class' to \"Emacs\".\n\
5302 Setting this variable permanently is not a reasonable thing to do,\n\
5303 but binding this variable locally around a call to `x-get-resource'\n\
5304 is a reasonabvle practice. See also the variable `x-resource-name'.");
5305 Vx_resource_class
= build_string (EMACS_CLASS
);
5307 #if 0 /* This doesn't really do anything. */
5308 DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape
,
5309 "The shape of the pointer when not over text.\n\
5310 This variable takes effect when you create a new frame\n\
5311 or when you set the mouse color.");
5313 Vx_nontext_pointer_shape
= Qnil
;
5315 #if 0 /* This doesn't really do anything. */
5316 DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape
,
5317 "The shape of the pointer when over the mode line.\n\
5318 This variable takes effect when you create a new frame\n\
5319 or when you set the mouse color.");
5321 Vx_mode_pointer_shape
= Qnil
;
5323 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
5324 &Vx_sensitive_text_pointer_shape
,
5325 "The shape of the pointer when over mouse-sensitive text.\n\
5326 This variable takes effect when you create a new frame\n\
5327 or when you set the mouse color.");
5328 Vx_sensitive_text_pointer_shape
= Qnil
;
5330 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
5331 "A string indicating the foreground color of the cursor box.");
5332 Vx_cursor_fore_pixel
= Qnil
;
5334 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
5335 "Non-nil if no X window manager is in use.\n\
5336 Emacs doesn't try to figure this out; this is always nil\n\
5337 unless you set it to something else.");
5338 /* We don't have any way to find this out, so set it to nil
5339 and maybe the user would like to set it to t. */
5340 Vx_no_window_manager
= Qnil
;
5342 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
5343 &Vx_pixel_size_width_font_regexp
,
5344 "Regexp matching a font name whose width is the same as `PIXEL_SIZE'.\n\
5346 Since Emacs gets width of a font matching with this regexp from\n\
5347 PIXEL_SIZE field of the name, font finding mechanism gets faster for\n\
5348 such a font. This is especially effective for such large fonts as\n\
5349 Chinese, Japanese, and Korean.");
5350 Vx_pixel_size_width_font_regexp
= Qnil
;
5352 #ifdef USE_X_TOOLKIT
5353 Fprovide (intern ("x-toolkit"));
5356 Fprovide (intern ("motif"));
5359 defsubr (&Sx_get_resource
);
5361 defsubr (&Sx_draw_rectangle
);
5362 defsubr (&Sx_erase_rectangle
);
5363 defsubr (&Sx_contour_region
);
5364 defsubr (&Sx_uncontour_region
);
5366 defsubr (&Sx_list_fonts
);
5367 defsubr (&Sx_display_color_p
);
5368 defsubr (&Sx_display_grayscale_p
);
5369 defsubr (&Sx_color_defined_p
);
5370 defsubr (&Sx_color_values
);
5371 defsubr (&Sx_server_max_request_size
);
5372 defsubr (&Sx_server_vendor
);
5373 defsubr (&Sx_server_version
);
5374 defsubr (&Sx_display_pixel_width
);
5375 defsubr (&Sx_display_pixel_height
);
5376 defsubr (&Sx_display_mm_width
);
5377 defsubr (&Sx_display_mm_height
);
5378 defsubr (&Sx_display_screens
);
5379 defsubr (&Sx_display_planes
);
5380 defsubr (&Sx_display_color_cells
);
5381 defsubr (&Sx_display_visual_class
);
5382 defsubr (&Sx_display_backing_store
);
5383 defsubr (&Sx_display_save_under
);
5385 defsubr (&Sx_rebind_key
);
5386 defsubr (&Sx_rebind_keys
);
5387 defsubr (&Sx_track_pointer
);
5388 defsubr (&Sx_grab_pointer
);
5389 defsubr (&Sx_ungrab_pointer
);
5391 defsubr (&Sx_parse_geometry
);
5392 defsubr (&Sx_create_frame
);
5394 defsubr (&Sx_horizontal_line
);
5396 defsubr (&Sx_open_connection
);
5397 defsubr (&Sx_close_connection
);
5398 defsubr (&Sx_display_list
);
5399 defsubr (&Sx_synchronize
);
5401 /* Setting callback functions for fontset handler. */
5402 get_font_info_func
= x_get_font_info
;
5403 list_fonts_func
= x_list_fonts
;
5404 load_font_func
= x_load_font
;
5405 find_ccl_program_func
= x_find_ccl_program
;
5406 query_font_func
= x_query_font
;
5407 set_frame_fontset_func
= x_set_font
;
5408 check_window_system_func
= check_x
;
5411 #endif /* HAVE_X_WINDOWS */