1 /* Functions for the X window system.
2 Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996 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"
44 /* On some systems, the character-composition stuff is broken in X11R5. */
45 #if defined (HAVE_X11R5) && ! defined (HAVE_X11R6)
46 #ifdef X11R5_INHIBIT_I18N
47 #define X_I18N_INHIBITED
52 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */
53 #include "bitmaps/gray.xbm"
55 #include <X11/bitmaps/gray>
58 #include "[.bitmaps]gray.xbm"
62 #include <X11/Shell.h>
65 #include <X11/Xaw/Paned.h>
66 #include <X11/Xaw/Label.h>
67 #endif /* USE_MOTIF */
70 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
79 #include "../lwlib/lwlib.h"
81 /* Do the EDITRES protocol if running X11R5
82 Exception: HP-UX (at least version A.09.05) has X11R5 without EditRes */
83 #if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES)
85 extern void _XEditResCheckMessages ();
86 #endif /* R5 + Athena */
88 /* Unique id counter for widgets created by the Lucid Widget
90 extern LWLIB_ID widget_id_tick
;
92 /* This is part of a kludge--see lwlib/xlwmenu.c. */
93 XFontStruct
*xlwmenu_default_font
;
95 extern void free_frame_menubar ();
96 #endif /* USE_X_TOOLKIT */
98 #define min(a,b) ((a) < (b) ? (a) : (b))
99 #define max(a,b) ((a) > (b) ? (a) : (b))
102 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
104 #define MAXREQUEST(dpy) ((dpy)->max_request_size)
107 /* The name we're using in resource queries. */
108 Lisp_Object Vx_resource_name
;
110 /* The background and shape of the mouse pointer, and shape when not
111 over text or in the modeline. */
112 Lisp_Object Vx_pointer_shape
, Vx_nontext_pointer_shape
, Vx_mode_pointer_shape
;
113 /* The shape when over mouse-sensitive text. */
114 Lisp_Object Vx_sensitive_text_pointer_shape
;
116 /* Color of chars displayed in cursor box. */
117 Lisp_Object Vx_cursor_fore_pixel
;
119 /* Nonzero if using X. */
122 /* Non nil if no window manager is in use. */
123 Lisp_Object Vx_no_window_manager
;
125 /* Search path for bitmap files. */
126 Lisp_Object Vx_bitmap_file_path
;
128 /* Evaluate this expression to rebuild the section of syms_of_xfns
129 that initializes and staticpros the symbols declared below. Note
130 that Emacs 18 has a bug that keeps C-x C-e from being able to
131 evaluate this expression.
134 ;; Accumulate a list of the symbols we want to initialize from the
135 ;; declarations at the top of the file.
136 (goto-char (point-min))
137 (search-forward "/\*&&& symbols declared here &&&*\/\n")
139 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
141 (cons (buffer-substring (match-beginning 1) (match-end 1))
144 (setq symbol-list (nreverse symbol-list))
145 ;; Delete the section of syms_of_... where we initialize the symbols.
146 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
147 (let ((start (point)))
148 (while (looking-at "^ Q")
150 (kill-region start (point)))
151 ;; Write a new symbol initialization section.
153 (insert (format " %s = intern (\"" (car symbol-list)))
154 (let ((start (point)))
155 (insert (substring (car symbol-list) 1))
156 (subst-char-in-region start (point) ?_ ?-))
157 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
158 (setq symbol-list (cdr symbol-list)))))
162 /*&&& symbols declared here &&&*/
163 Lisp_Object Qauto_raise
;
164 Lisp_Object Qauto_lower
;
165 Lisp_Object Qbackground_color
;
167 Lisp_Object Qborder_color
;
168 Lisp_Object Qborder_width
;
170 Lisp_Object Qcursor_color
;
171 Lisp_Object Qcursor_type
;
173 Lisp_Object Qforeground_color
;
174 Lisp_Object Qgeometry
;
175 Lisp_Object Qicon_left
;
176 Lisp_Object Qicon_top
;
177 Lisp_Object Qicon_type
;
178 Lisp_Object Qicon_name
;
179 Lisp_Object Qinternal_border_width
;
181 Lisp_Object Qmouse_color
;
183 Lisp_Object Qparent_id
;
184 Lisp_Object Qscroll_bar_width
;
185 Lisp_Object Qsuppress_icon
;
187 Lisp_Object Qundefined_color
;
188 Lisp_Object Qvertical_scroll_bars
;
189 Lisp_Object Qvisibility
;
190 Lisp_Object Qwindow_id
;
191 Lisp_Object Qx_frame_parameter
;
192 Lisp_Object Qx_resource_name
;
193 Lisp_Object Quser_position
;
194 Lisp_Object Quser_size
;
195 Lisp_Object Qdisplay
;
197 /* The below are defined in frame.c. */
198 extern Lisp_Object Qheight
, Qminibuffer
, Qname
, Qonly
, Qwidth
;
199 extern Lisp_Object Qunsplittable
, Qmenu_bar_lines
, Qbuffer_predicate
, Qtitle
;
201 extern Lisp_Object Vwindow_system_version
;
204 /* Error if we are not connected to X. */
209 error ("X windows are not in use or not initialized");
212 /* Nonzero if we can use mouse menus.
213 You should not call this unless HAVE_MENUS is defined. */
221 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
222 and checking validity for X. */
225 check_x_frame (frame
)
234 CHECK_LIVE_FRAME (frame
, 0);
238 error ("Non-X frame used");
242 /* Let the user specify an X display with a frame.
243 nil stands for the selected frame--or, if that is not an X frame,
244 the first X display on the list. */
246 static struct x_display_info
*
247 check_x_display_info (frame
)
252 if (FRAME_X_P (selected_frame
))
253 return FRAME_X_DISPLAY_INFO (selected_frame
);
254 else if (x_display_list
!= 0)
255 return x_display_list
;
257 error ("X windows are not in use or not initialized");
259 else if (STRINGP (frame
))
260 return x_display_info_for_name (frame
);
265 CHECK_LIVE_FRAME (frame
, 0);
268 error ("Non-X frame used");
269 return FRAME_X_DISPLAY_INFO (f
);
273 /* Return the Emacs frame-object corresponding to an X window.
274 It could be the frame's main window or an icon window. */
276 /* This function can be called during GC, so use GC_xxx type test macros. */
279 x_window_to_frame (dpyinfo
, wdesc
)
280 struct x_display_info
*dpyinfo
;
283 Lisp_Object tail
, frame
;
286 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
288 frame
= XCONS (tail
)->car
;
289 if (!GC_FRAMEP (frame
))
292 if (f
->output_data
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
295 if ((f
->output_data
.x
->edit_widget
296 && XtWindow (f
->output_data
.x
->edit_widget
) == wdesc
)
297 || f
->output_data
.x
->icon_desc
== wdesc
)
299 #else /* not USE_X_TOOLKIT */
300 if (FRAME_X_WINDOW (f
) == wdesc
301 || f
->output_data
.x
->icon_desc
== wdesc
)
303 #endif /* not USE_X_TOOLKIT */
309 /* Like x_window_to_frame but also compares the window with the widget's
313 x_any_window_to_frame (dpyinfo
, wdesc
)
314 struct x_display_info
*dpyinfo
;
317 Lisp_Object tail
, frame
;
321 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
323 frame
= XCONS (tail
)->car
;
324 if (!GC_FRAMEP (frame
))
327 if (f
->output_data
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
329 x
= f
->output_data
.x
;
330 /* This frame matches if the window is any of its widgets. */
331 if (wdesc
== XtWindow (x
->widget
)
332 || wdesc
== XtWindow (x
->column_widget
)
333 || wdesc
== XtWindow (x
->edit_widget
))
335 /* Match if the window is this frame's menubar. */
336 if (lw_window_is_in_menubar (wdesc
, x
->menubar_widget
))
342 /* Likewise, but exclude the menu bar widget. */
345 x_non_menubar_window_to_frame (dpyinfo
, wdesc
)
346 struct x_display_info
*dpyinfo
;
349 Lisp_Object tail
, frame
;
353 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
355 frame
= XCONS (tail
)->car
;
356 if (!GC_FRAMEP (frame
))
359 if (f
->output_data
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
361 x
= f
->output_data
.x
;
362 /* This frame matches if the window is any of its widgets. */
363 if (wdesc
== XtWindow (x
->widget
)
364 || wdesc
== XtWindow (x
->column_widget
)
365 || wdesc
== XtWindow (x
->edit_widget
))
371 /* Likewise, but consider only the menu bar widget. */
374 x_menubar_window_to_frame (dpyinfo
, wdesc
)
375 struct x_display_info
*dpyinfo
;
378 Lisp_Object tail
, frame
;
382 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
384 frame
= XCONS (tail
)->car
;
385 if (!GC_FRAMEP (frame
))
388 if (f
->output_data
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
390 x
= f
->output_data
.x
;
391 /* Match if the window is this frame's menubar. */
392 if (lw_window_is_in_menubar (wdesc
, x
->menubar_widget
))
398 /* Return the frame whose principal (outermost) window is WDESC.
399 If WDESC is some other (smaller) window, we return 0. */
402 x_top_window_to_frame (dpyinfo
, wdesc
)
403 struct x_display_info
*dpyinfo
;
406 Lisp_Object tail
, frame
;
410 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
412 frame
= XCONS (tail
)->car
;
413 if (!GC_FRAMEP (frame
))
416 if (f
->output_data
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
418 x
= f
->output_data
.x
;
419 /* This frame matches if the window is its topmost widget. */
420 if (wdesc
== XtWindow (x
->widget
))
422 #if 0 /* I don't know why it did this,
423 but it seems logically wrong,
424 and it causes trouble for MapNotify events. */
425 /* Match if the window is this frame's menubar. */
426 if (x
->menubar_widget
427 && wdesc
== XtWindow (x
->menubar_widget
))
433 #endif /* USE_X_TOOLKIT */
437 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
438 id, which is just an int that this section returns. Bitmaps are
439 reference counted so they can be shared among frames.
441 Bitmap indices are guaranteed to be > 0, so a negative number can
442 be used to indicate no bitmap.
444 If you use x_create_bitmap_from_data, then you must keep track of
445 the bitmaps yourself. That is, creating a bitmap from the same
446 data more than once will not be caught. */
449 /* Functions to access the contents of a bitmap, given an id. */
452 x_bitmap_height (f
, id
)
456 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].height
;
460 x_bitmap_width (f
, id
)
464 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].width
;
468 x_bitmap_pixmap (f
, id
)
472 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].pixmap
;
476 /* Allocate a new bitmap record. Returns index of new record. */
479 x_allocate_bitmap_record (f
)
482 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
485 if (dpyinfo
->bitmaps
== NULL
)
487 dpyinfo
->bitmaps_size
= 10;
489 = (struct x_bitmap_record
*) xmalloc (dpyinfo
->bitmaps_size
* sizeof (struct x_bitmap_record
));
490 dpyinfo
->bitmaps_last
= 1;
494 if (dpyinfo
->bitmaps_last
< dpyinfo
->bitmaps_size
)
495 return ++dpyinfo
->bitmaps_last
;
497 for (i
= 0; i
< dpyinfo
->bitmaps_size
; ++i
)
498 if (dpyinfo
->bitmaps
[i
].refcount
== 0)
501 dpyinfo
->bitmaps_size
*= 2;
503 = (struct x_bitmap_record
*) xrealloc (dpyinfo
->bitmaps
,
504 dpyinfo
->bitmaps_size
* sizeof (struct x_bitmap_record
));
505 return ++dpyinfo
->bitmaps_last
;
508 /* Add one reference to the reference count of the bitmap with id ID. */
511 x_reference_bitmap (f
, id
)
515 ++FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].refcount
;
518 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
521 x_create_bitmap_from_data (f
, bits
, width
, height
)
524 unsigned int width
, height
;
526 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
530 bitmap
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
531 bits
, width
, height
);
536 id
= x_allocate_bitmap_record (f
);
537 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
538 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
539 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
540 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
541 dpyinfo
->bitmaps
[id
- 1].height
= height
;
542 dpyinfo
->bitmaps
[id
- 1].width
= width
;
547 /* Create bitmap from file FILE for frame F. */
550 x_create_bitmap_from_file (f
, file
)
554 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
555 unsigned int width
, height
;
557 int xhot
, yhot
, result
, id
;
562 /* Look for an existing bitmap with the same name. */
563 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
565 if (dpyinfo
->bitmaps
[id
].refcount
566 && dpyinfo
->bitmaps
[id
].file
567 && !strcmp (dpyinfo
->bitmaps
[id
].file
, (char *) XSTRING (file
)->data
))
569 ++dpyinfo
->bitmaps
[id
].refcount
;
574 /* Search bitmap-file-path for the file, if appropriate. */
575 fd
= openp (Vx_bitmap_file_path
, file
, "", &found
, 0);
580 filename
= (char *) XSTRING (found
)->data
;
582 result
= XReadBitmapFile (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
583 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
584 if (result
!= BitmapSuccess
)
587 id
= x_allocate_bitmap_record (f
);
588 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
589 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
590 dpyinfo
->bitmaps
[id
- 1].file
= (char *) xmalloc (XSTRING (file
)->size
+ 1);
591 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
592 dpyinfo
->bitmaps
[id
- 1].height
= height
;
593 dpyinfo
->bitmaps
[id
- 1].width
= width
;
594 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, XSTRING (file
)->data
);
599 /* Remove reference to bitmap with id number ID. */
602 x_destroy_bitmap (f
, id
)
606 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
610 --dpyinfo
->bitmaps
[id
- 1].refcount
;
611 if (dpyinfo
->bitmaps
[id
- 1].refcount
== 0)
614 XFreePixmap (FRAME_X_DISPLAY (f
), dpyinfo
->bitmaps
[id
- 1].pixmap
);
615 if (dpyinfo
->bitmaps
[id
- 1].file
)
617 free (dpyinfo
->bitmaps
[id
- 1].file
);
618 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
625 /* Free all the bitmaps for the display specified by DPYINFO. */
628 x_destroy_all_bitmaps (dpyinfo
)
629 struct x_display_info
*dpyinfo
;
632 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++)
633 if (dpyinfo
->bitmaps
[i
].refcount
> 0)
635 XFreePixmap (dpyinfo
->display
, dpyinfo
->bitmaps
[i
].pixmap
);
636 if (dpyinfo
->bitmaps
[i
].file
)
637 free (dpyinfo
->bitmaps
[i
].file
);
639 dpyinfo
->bitmaps_last
= 0;
642 /* Connect the frame-parameter names for X frames
643 to the ways of passing the parameter values to the window system.
645 The name of a parameter, as a Lisp symbol,
646 has an `x-frame-parameter' property which is an integer in Lisp
647 that is an index in this table. */
649 struct x_frame_parm_table
652 void (*setter
)( /* struct frame *frame, Lisp_Object val, oldval */ );
655 void x_set_foreground_color ();
656 void x_set_background_color ();
657 void x_set_mouse_color ();
658 void x_set_cursor_color ();
659 void x_set_border_color ();
660 void x_set_cursor_type ();
661 void x_set_icon_type ();
662 void x_set_icon_name ();
664 void x_set_border_width ();
665 void x_set_internal_border_width ();
666 void x_explicitly_set_name ();
667 void x_set_autoraise ();
668 void x_set_autolower ();
669 void x_set_vertical_scroll_bars ();
670 void x_set_visibility ();
671 void x_set_menu_bar_lines ();
672 void x_set_scroll_bar_width ();
674 void x_set_unsplittable ();
676 static struct x_frame_parm_table x_frame_parms
[] =
678 "auto-raise", x_set_autoraise
,
679 "auto-lower", x_set_autolower
,
680 "background-color", x_set_background_color
,
681 "border-color", x_set_border_color
,
682 "border-width", x_set_border_width
,
683 "cursor-color", x_set_cursor_color
,
684 "cursor-type", x_set_cursor_type
,
686 "foreground-color", x_set_foreground_color
,
687 "icon-name", x_set_icon_name
,
688 "icon-type", x_set_icon_type
,
689 "internal-border-width", x_set_internal_border_width
,
690 "menu-bar-lines", x_set_menu_bar_lines
,
691 "mouse-color", x_set_mouse_color
,
692 "name", x_explicitly_set_name
,
693 "scroll-bar-width", x_set_scroll_bar_width
,
694 "title", x_set_title
,
695 "unsplittable", x_set_unsplittable
,
696 "vertical-scroll-bars", x_set_vertical_scroll_bars
,
697 "visibility", x_set_visibility
,
700 /* Attach the `x-frame-parameter' properties to
701 the Lisp symbol names of parameters relevant to X. */
703 init_x_parm_symbols ()
707 for (i
= 0; i
< sizeof (x_frame_parms
) / sizeof (x_frame_parms
[0]); i
++)
708 Fput (intern (x_frame_parms
[i
].name
), Qx_frame_parameter
,
712 /* Change the parameters of FRAME as specified by ALIST.
713 If a parameter is not specially recognized, do nothing;
714 otherwise call the `x_set_...' function for that parameter. */
717 x_set_frame_parameters (f
, alist
)
723 /* If both of these parameters are present, it's more efficient to
724 set them both at once. So we wait until we've looked at the
725 entire list before we set them. */
726 Lisp_Object width
, height
;
729 Lisp_Object left
, top
;
731 /* Same with these. */
732 Lisp_Object icon_left
, icon_top
;
734 /* Record in these vectors all the parms specified. */
738 int left_no_change
= 0, top_no_change
= 0;
739 int icon_left_no_change
= 0, icon_top_no_change
= 0;
742 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
745 parms
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
746 values
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
748 /* Extract parm names and values into those vectors. */
751 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
753 Lisp_Object elt
, prop
, val
;
756 parms
[i
] = Fcar (elt
);
757 values
[i
] = Fcdr (elt
);
761 width
= height
= top
= left
= Qunbound
;
762 icon_left
= icon_top
= Qunbound
;
764 /* Now process them in reverse of specified order. */
765 for (i
--; i
>= 0; i
--)
767 Lisp_Object prop
, val
;
772 if (EQ (prop
, Qwidth
))
774 else if (EQ (prop
, Qheight
))
776 else if (EQ (prop
, Qtop
))
778 else if (EQ (prop
, Qleft
))
780 else if (EQ (prop
, Qicon_top
))
782 else if (EQ (prop
, Qicon_left
))
786 register Lisp_Object param_index
, old_value
;
788 param_index
= Fget (prop
, Qx_frame_parameter
);
789 old_value
= get_frame_param (f
, prop
);
790 store_frame_param (f
, prop
, val
);
791 if (NATNUMP (param_index
)
792 && (XFASTINT (param_index
)
793 < sizeof (x_frame_parms
)/sizeof (x_frame_parms
[0])))
794 (*x_frame_parms
[XINT (param_index
)].setter
)(f
, val
, old_value
);
798 /* Don't die if just one of these was set. */
799 if (EQ (left
, Qunbound
))
802 if (f
->output_data
.x
->left_pos
< 0)
803 left
= Fcons (Qplus
, Fcons (make_number (f
->output_data
.x
->left_pos
), Qnil
));
805 XSETINT (left
, f
->output_data
.x
->left_pos
);
807 if (EQ (top
, Qunbound
))
810 if (f
->output_data
.x
->top_pos
< 0)
811 top
= Fcons (Qplus
, Fcons (make_number (f
->output_data
.x
->top_pos
), Qnil
));
813 XSETINT (top
, f
->output_data
.x
->top_pos
);
816 /* If one of the icon positions was not set, preserve or default it. */
817 if (EQ (icon_left
, Qunbound
) || ! INTEGERP (icon_left
))
819 icon_left_no_change
= 1;
820 icon_left
= Fcdr (Fassq (Qicon_left
, f
->param_alist
));
821 if (NILP (icon_left
))
822 XSETINT (icon_left
, 0);
824 if (EQ (icon_top
, Qunbound
) || ! INTEGERP (icon_top
))
826 icon_top_no_change
= 1;
827 icon_top
= Fcdr (Fassq (Qicon_top
, f
->param_alist
));
829 XSETINT (icon_top
, 0);
832 /* Don't die if just one of these was set. */
833 if (EQ (width
, Qunbound
))
835 if (FRAME_NEW_WIDTH (f
))
836 XSETINT (width
, FRAME_NEW_WIDTH (f
));
838 XSETINT (width
, FRAME_WIDTH (f
));
840 if (EQ (height
, Qunbound
))
842 if (FRAME_NEW_HEIGHT (f
))
843 XSETINT (height
, FRAME_NEW_HEIGHT (f
));
845 XSETINT (height
, FRAME_HEIGHT (f
));
848 /* Don't set these parameters unless they've been explicitly
849 specified. The window might be mapped or resized while we're in
850 this function, and we don't want to override that unless the lisp
851 code has asked for it.
853 Don't set these parameters unless they actually differ from the
854 window's current parameters; the window may not actually exist
859 check_frame_size (f
, &height
, &width
);
861 XSETFRAME (frame
, f
);
863 if ((NUMBERP (width
) && XINT (width
) != FRAME_WIDTH (f
))
864 || (NUMBERP (height
) && XINT (height
) != FRAME_HEIGHT (f
))
865 || FRAME_NEW_HEIGHT (f
) || FRAME_NEW_WIDTH (f
))
866 Fset_frame_size (frame
, width
, height
);
868 if ((!NILP (left
) || !NILP (top
))
869 && ! (left_no_change
&& top_no_change
)
870 && ! (NUMBERP (left
) && XINT (left
) == f
->output_data
.x
->left_pos
871 && NUMBERP (top
) && XINT (top
) == f
->output_data
.x
->top_pos
))
876 /* Record the signs. */
877 f
->output_data
.x
->size_hint_flags
&= ~ (XNegative
| YNegative
);
878 if (EQ (left
, Qminus
))
879 f
->output_data
.x
->size_hint_flags
|= XNegative
;
880 else if (INTEGERP (left
))
882 leftpos
= XINT (left
);
884 f
->output_data
.x
->size_hint_flags
|= XNegative
;
886 else if (CONSP (left
) && EQ (XCONS (left
)->car
, Qminus
)
887 && CONSP (XCONS (left
)->cdr
)
888 && INTEGERP (XCONS (XCONS (left
)->cdr
)->car
))
890 leftpos
= - XINT (XCONS (XCONS (left
)->cdr
)->car
);
891 f
->output_data
.x
->size_hint_flags
|= XNegative
;
893 else if (CONSP (left
) && EQ (XCONS (left
)->car
, Qplus
)
894 && CONSP (XCONS (left
)->cdr
)
895 && INTEGERP (XCONS (XCONS (left
)->cdr
)->car
))
897 leftpos
= XINT (XCONS (XCONS (left
)->cdr
)->car
);
900 if (EQ (top
, Qminus
))
901 f
->output_data
.x
->size_hint_flags
|= YNegative
;
902 else if (INTEGERP (top
))
906 f
->output_data
.x
->size_hint_flags
|= YNegative
;
908 else if (CONSP (top
) && EQ (XCONS (top
)->car
, Qminus
)
909 && CONSP (XCONS (top
)->cdr
)
910 && INTEGERP (XCONS (XCONS (top
)->cdr
)->car
))
912 toppos
= - XINT (XCONS (XCONS (top
)->cdr
)->car
);
913 f
->output_data
.x
->size_hint_flags
|= YNegative
;
915 else if (CONSP (top
) && EQ (XCONS (top
)->car
, Qplus
)
916 && CONSP (XCONS (top
)->cdr
)
917 && INTEGERP (XCONS (XCONS (top
)->cdr
)->car
))
919 toppos
= XINT (XCONS (XCONS (top
)->cdr
)->car
);
923 /* Store the numeric value of the position. */
924 f
->output_data
.x
->top_pos
= toppos
;
925 f
->output_data
.x
->left_pos
= leftpos
;
927 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
929 /* Actually set that position, and convert to absolute. */
930 x_set_offset (f
, leftpos
, toppos
, -1);
933 if ((!NILP (icon_left
) || !NILP (icon_top
))
934 && ! (icon_left_no_change
&& icon_top_no_change
))
935 x_wm_set_icon_position (f
, XINT (icon_left
), XINT (icon_top
));
939 /* Store the screen positions of frame F into XPTR and YPTR.
940 These are the positions of the containing window manager window,
941 not Emacs's own window. */
944 x_real_positions (f
, xptr
, yptr
)
951 /* This is pretty gross, but seems to be the easiest way out of
952 the problem that arises when restarting window-managers. */
955 Window outer
= XtWindow (f
->output_data
.x
->widget
);
957 Window outer
= f
->output_data
.x
->window_desc
;
959 Window tmp_root_window
;
960 Window
*tmp_children
;
965 x_catch_errors (FRAME_X_DISPLAY (f
));
967 XQueryTree (FRAME_X_DISPLAY (f
), outer
, &tmp_root_window
,
968 &f
->output_data
.x
->parent_desc
,
969 &tmp_children
, &tmp_nchildren
);
970 XFree ((char *) tmp_children
);
974 /* Find the position of the outside upper-left corner of
975 the inner window, with respect to the outer window. */
976 if (f
->output_data
.x
->parent_desc
!= FRAME_X_DISPLAY_INFO (f
)->root_window
)
978 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
980 /* From-window, to-window. */
982 XtWindow (f
->output_data
.x
->widget
),
984 f
->output_data
.x
->window_desc
,
986 f
->output_data
.x
->parent_desc
,
988 /* From-position, to-position. */
989 0, 0, &win_x
, &win_y
,
994 #if 0 /* The values seem to be right without this and wrong with. */
995 win_x
+= f
->output_data
.x
->border_width
;
996 win_y
+= f
->output_data
.x
->border_width
;
1000 /* It is possible for the window returned by the XQueryNotify
1001 to become invalid by the time we call XTranslateCoordinates.
1002 That can happen when you restart some window managers.
1003 If so, we get an error in XTranslateCoordinates.
1004 Detect that and try the whole thing over. */
1005 if (! x_had_errors_p (FRAME_X_DISPLAY (f
)))
1007 x_uncatch_errors (FRAME_X_DISPLAY (f
));
1011 x_uncatch_errors (FRAME_X_DISPLAY (f
));
1014 *xptr
= f
->output_data
.x
->left_pos
- win_x
;
1015 *yptr
= f
->output_data
.x
->top_pos
- win_y
;
1018 /* Insert a description of internally-recorded parameters of frame X
1019 into the parameter alist *ALISTPTR that is to be given to the user.
1020 Only parameters that are specific to the X window system
1021 and whose values are not correctly recorded in the frame's
1022 param_alist need to be considered here. */
1024 x_report_frame_params (f
, alistptr
)
1026 Lisp_Object
*alistptr
;
1031 /* Represent negative positions (off the top or left screen edge)
1032 in a way that Fmodify_frame_parameters will understand correctly. */
1033 XSETINT (tem
, f
->output_data
.x
->left_pos
);
1034 if (f
->output_data
.x
->left_pos
>= 0)
1035 store_in_alist (alistptr
, Qleft
, tem
);
1037 store_in_alist (alistptr
, Qleft
, Fcons (Qplus
, Fcons (tem
, Qnil
)));
1039 XSETINT (tem
, f
->output_data
.x
->top_pos
);
1040 if (f
->output_data
.x
->top_pos
>= 0)
1041 store_in_alist (alistptr
, Qtop
, tem
);
1043 store_in_alist (alistptr
, Qtop
, Fcons (Qplus
, Fcons (tem
, Qnil
)));
1045 store_in_alist (alistptr
, Qborder_width
,
1046 make_number (f
->output_data
.x
->border_width
));
1047 store_in_alist (alistptr
, Qinternal_border_width
,
1048 make_number (f
->output_data
.x
->internal_border_width
));
1049 sprintf (buf
, "%ld", (long) FRAME_X_WINDOW (f
));
1050 store_in_alist (alistptr
, Qwindow_id
,
1051 build_string (buf
));
1052 store_in_alist (alistptr
, Qicon_name
, f
->icon_name
);
1053 FRAME_SAMPLE_VISIBILITY (f
);
1054 store_in_alist (alistptr
, Qvisibility
,
1055 (FRAME_VISIBLE_P (f
) ? Qt
1056 : FRAME_ICONIFIED_P (f
) ? Qicon
: Qnil
));
1057 store_in_alist (alistptr
, Qdisplay
,
1058 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->car
);
1062 /* Decide if color named COLOR is valid for the display associated with
1063 the selected frame; if so, return the rgb values in COLOR_DEF.
1064 If ALLOC is nonzero, allocate a new colormap cell. */
1067 defined_color (f
, color
, color_def
, alloc
)
1073 register int status
;
1074 Colormap screen_colormap
;
1075 Display
*display
= FRAME_X_DISPLAY (f
);
1078 screen_colormap
= DefaultColormap (display
, XDefaultScreen (display
));
1080 status
= XParseColor (display
, screen_colormap
, color
, color_def
);
1081 if (status
&& alloc
)
1083 status
= XAllocColor (display
, screen_colormap
, color_def
);
1086 /* If we got to this point, the colormap is full, so we're
1087 going to try and get the next closest color.
1088 The algorithm used is a least-squares matching, which is
1089 what X uses for closest color matching with StaticColor visuals. */
1094 long nearest_delta
, trial_delta
;
1097 no_cells
= XDisplayCells (display
, XDefaultScreen (display
));
1098 cells
= (XColor
*) alloca (sizeof (XColor
) * no_cells
);
1100 for (x
= 0; x
< no_cells
; x
++)
1103 XQueryColors (display
, screen_colormap
, cells
, no_cells
);
1105 /* I'm assuming CSE so I'm not going to condense this. */
1106 nearest_delta
= ((((color_def
->red
>> 8) - (cells
[0].red
>> 8))
1107 * ((color_def
->red
>> 8) - (cells
[0].red
>> 8)))
1109 (((color_def
->green
>> 8) - (cells
[0].green
>> 8))
1110 * ((color_def
->green
>> 8) - (cells
[0].green
>> 8)))
1112 (((color_def
->blue
>> 8) - (cells
[0].blue
>> 8))
1113 * ((color_def
->blue
>> 8) - (cells
[0].blue
>> 8))));
1114 for (x
= 1; x
< no_cells
; x
++)
1116 trial_delta
= ((((color_def
->red
>> 8) - (cells
[x
].red
>> 8))
1117 * ((color_def
->red
>> 8) - (cells
[x
].red
>> 8)))
1119 (((color_def
->green
>> 8) - (cells
[x
].green
>> 8))
1120 * ((color_def
->green
>> 8) - (cells
[x
].green
>> 8)))
1122 (((color_def
->blue
>> 8) - (cells
[x
].blue
>> 8))
1123 * ((color_def
->blue
>> 8) - (cells
[x
].blue
>> 8))));
1124 if (trial_delta
< nearest_delta
)
1127 temp
.red
= cells
[x
].red
;
1128 temp
.green
= cells
[x
].green
;
1129 temp
.blue
= cells
[x
].blue
;
1130 status
= XAllocColor (display
, screen_colormap
, &temp
);
1134 nearest_delta
= trial_delta
;
1138 color_def
->red
= cells
[nearest
].red
;
1139 color_def
->green
= cells
[nearest
].green
;
1140 color_def
->blue
= cells
[nearest
].blue
;
1141 status
= XAllocColor (display
, screen_colormap
, color_def
);
1152 /* Given a string ARG naming a color, compute a pixel value from it
1153 suitable for screen F.
1154 If F is not a color screen, return DEF (default) regardless of what
1158 x_decode_color (f
, arg
, def
)
1165 CHECK_STRING (arg
, 0);
1167 if (strcmp (XSTRING (arg
)->data
, "black") == 0)
1168 return BLACK_PIX_DEFAULT (f
);
1169 else if (strcmp (XSTRING (arg
)->data
, "white") == 0)
1170 return WHITE_PIX_DEFAULT (f
);
1172 if (FRAME_X_DISPLAY_INFO (f
)->n_planes
== 1)
1175 /* defined_color is responsible for coping with failures
1176 by looking for a near-miss. */
1177 if (defined_color (f
, XSTRING (arg
)->data
, &cdef
, 1))
1180 Fsignal (Qerror
, Fcons (build_string ("undefined color"),
1181 Fcons (arg
, Qnil
)));
1184 /* Functions called only from `x_set_frame_param'
1185 to set individual parameters.
1187 If FRAME_X_WINDOW (f) is 0,
1188 the frame is being created and its X-window does not exist yet.
1189 In that case, just record the parameter's new value
1190 in the standard place; do not attempt to change the window. */
1193 x_set_foreground_color (f
, arg
, oldval
)
1195 Lisp_Object arg
, oldval
;
1197 f
->output_data
.x
->foreground_pixel
1198 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1199 if (FRAME_X_WINDOW (f
) != 0)
1202 XSetForeground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->normal_gc
,
1203 f
->output_data
.x
->foreground_pixel
);
1204 XSetBackground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->reverse_gc
,
1205 f
->output_data
.x
->foreground_pixel
);
1207 recompute_basic_faces (f
);
1208 if (FRAME_VISIBLE_P (f
))
1214 x_set_background_color (f
, arg
, oldval
)
1216 Lisp_Object arg
, oldval
;
1221 f
->output_data
.x
->background_pixel
1222 = x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
1224 if (FRAME_X_WINDOW (f
) != 0)
1227 /* The main frame area. */
1228 XSetBackground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->normal_gc
,
1229 f
->output_data
.x
->background_pixel
);
1230 XSetForeground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->reverse_gc
,
1231 f
->output_data
.x
->background_pixel
);
1232 XSetForeground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->cursor_gc
,
1233 f
->output_data
.x
->background_pixel
);
1234 XSetWindowBackground (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1235 f
->output_data
.x
->background_pixel
);
1238 for (bar
= FRAME_SCROLL_BARS (f
); !NILP (bar
);
1239 bar
= XSCROLL_BAR (bar
)->next
)
1240 XSetWindowBackground (FRAME_X_DISPLAY (f
),
1241 SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
)),
1242 f
->output_data
.x
->background_pixel
);
1246 recompute_basic_faces (f
);
1248 if (FRAME_VISIBLE_P (f
))
1254 x_set_mouse_color (f
, arg
, oldval
)
1256 Lisp_Object arg
, oldval
;
1258 Cursor cursor
, nontext_cursor
, mode_cursor
, cross_cursor
;
1261 if (!EQ (Qnil
, arg
))
1262 f
->output_data
.x
->mouse_pixel
1263 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1264 mask_color
= f
->output_data
.x
->background_pixel
;
1265 /* No invisible pointers. */
1266 if (mask_color
== f
->output_data
.x
->mouse_pixel
1267 && mask_color
== f
->output_data
.x
->background_pixel
)
1268 f
->output_data
.x
->mouse_pixel
= f
->output_data
.x
->foreground_pixel
;
1272 /* It's not okay to crash if the user selects a screwy cursor. */
1273 x_catch_errors (FRAME_X_DISPLAY (f
));
1275 if (!EQ (Qnil
, Vx_pointer_shape
))
1277 CHECK_NUMBER (Vx_pointer_shape
, 0);
1278 cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XINT (Vx_pointer_shape
));
1281 cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_xterm
);
1282 x_check_errors (FRAME_X_DISPLAY (f
), "bad text pointer cursor: %s");
1284 if (!EQ (Qnil
, Vx_nontext_pointer_shape
))
1286 CHECK_NUMBER (Vx_nontext_pointer_shape
, 0);
1287 nontext_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
),
1288 XINT (Vx_nontext_pointer_shape
));
1291 nontext_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_left_ptr
);
1292 x_check_errors (FRAME_X_DISPLAY (f
), "bad nontext pointer cursor: %s");
1294 if (!EQ (Qnil
, Vx_mode_pointer_shape
))
1296 CHECK_NUMBER (Vx_mode_pointer_shape
, 0);
1297 mode_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
),
1298 XINT (Vx_mode_pointer_shape
));
1301 mode_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_xterm
);
1302 x_check_errors (FRAME_X_DISPLAY (f
), "bad modeline pointer cursor: %s");
1304 if (!EQ (Qnil
, Vx_sensitive_text_pointer_shape
))
1306 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
, 0);
1308 = XCreateFontCursor (FRAME_X_DISPLAY (f
),
1309 XINT (Vx_sensitive_text_pointer_shape
));
1312 cross_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_crosshair
);
1314 /* Check and report errors with the above calls. */
1315 x_check_errors (FRAME_X_DISPLAY (f
), "can't set cursor shape: %s");
1316 x_uncatch_errors (FRAME_X_DISPLAY (f
));
1319 XColor fore_color
, back_color
;
1321 fore_color
.pixel
= f
->output_data
.x
->mouse_pixel
;
1322 back_color
.pixel
= mask_color
;
1323 XQueryColor (FRAME_X_DISPLAY (f
),
1324 DefaultColormap (FRAME_X_DISPLAY (f
),
1325 DefaultScreen (FRAME_X_DISPLAY (f
))),
1327 XQueryColor (FRAME_X_DISPLAY (f
),
1328 DefaultColormap (FRAME_X_DISPLAY (f
),
1329 DefaultScreen (FRAME_X_DISPLAY (f
))),
1331 XRecolorCursor (FRAME_X_DISPLAY (f
), cursor
,
1332 &fore_color
, &back_color
);
1333 XRecolorCursor (FRAME_X_DISPLAY (f
), nontext_cursor
,
1334 &fore_color
, &back_color
);
1335 XRecolorCursor (FRAME_X_DISPLAY (f
), mode_cursor
,
1336 &fore_color
, &back_color
);
1337 XRecolorCursor (FRAME_X_DISPLAY (f
), cross_cursor
,
1338 &fore_color
, &back_color
);
1341 if (FRAME_X_WINDOW (f
) != 0)
1343 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
1346 if (cursor
!= f
->output_data
.x
->text_cursor
&& f
->output_data
.x
->text_cursor
!= 0)
1347 XFreeCursor (FRAME_X_DISPLAY (f
), f
->output_data
.x
->text_cursor
);
1348 f
->output_data
.x
->text_cursor
= cursor
;
1350 if (nontext_cursor
!= f
->output_data
.x
->nontext_cursor
1351 && f
->output_data
.x
->nontext_cursor
!= 0)
1352 XFreeCursor (FRAME_X_DISPLAY (f
), f
->output_data
.x
->nontext_cursor
);
1353 f
->output_data
.x
->nontext_cursor
= nontext_cursor
;
1355 if (mode_cursor
!= f
->output_data
.x
->modeline_cursor
1356 && f
->output_data
.x
->modeline_cursor
!= 0)
1357 XFreeCursor (FRAME_X_DISPLAY (f
), f
->output_data
.x
->modeline_cursor
);
1358 f
->output_data
.x
->modeline_cursor
= mode_cursor
;
1359 if (cross_cursor
!= f
->output_data
.x
->cross_cursor
1360 && f
->output_data
.x
->cross_cursor
!= 0)
1361 XFreeCursor (FRAME_X_DISPLAY (f
), f
->output_data
.x
->cross_cursor
);
1362 f
->output_data
.x
->cross_cursor
= cross_cursor
;
1364 XFlush (FRAME_X_DISPLAY (f
));
1369 x_set_cursor_color (f
, arg
, oldval
)
1371 Lisp_Object arg
, oldval
;
1373 unsigned long fore_pixel
;
1375 if (!EQ (Vx_cursor_fore_pixel
, Qnil
))
1376 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
1377 WHITE_PIX_DEFAULT (f
));
1379 fore_pixel
= f
->output_data
.x
->background_pixel
;
1380 f
->output_data
.x
->cursor_pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1382 /* Make sure that the cursor color differs from the background color. */
1383 if (f
->output_data
.x
->cursor_pixel
== f
->output_data
.x
->background_pixel
)
1385 f
->output_data
.x
->cursor_pixel
= f
->output_data
.x
->mouse_pixel
;
1386 if (f
->output_data
.x
->cursor_pixel
== fore_pixel
)
1387 fore_pixel
= f
->output_data
.x
->background_pixel
;
1389 f
->output_data
.x
->cursor_foreground_pixel
= fore_pixel
;
1391 if (FRAME_X_WINDOW (f
) != 0)
1394 XSetBackground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->cursor_gc
,
1395 f
->output_data
.x
->cursor_pixel
);
1396 XSetForeground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->cursor_gc
,
1400 if (FRAME_VISIBLE_P (f
))
1402 x_display_cursor (f
, 0);
1403 x_display_cursor (f
, 1);
1408 /* Set the border-color of frame F to value described by ARG.
1409 ARG can be a string naming a color.
1410 The border-color is used for the border that is drawn by the X server.
1411 Note that this does not fully take effect if done before
1412 F has an x-window; it must be redone when the window is created.
1414 Note: this is done in two routines because of the way X10 works.
1416 Note: under X11, this is normally the province of the window manager,
1417 and so emacs' border colors may be overridden. */
1420 x_set_border_color (f
, arg
, oldval
)
1422 Lisp_Object arg
, oldval
;
1427 CHECK_STRING (arg
, 0);
1428 str
= XSTRING (arg
)->data
;
1430 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1432 x_set_border_pixel (f
, pix
);
1435 /* Set the border-color of frame F to pixel value PIX.
1436 Note that this does not fully take effect if done before
1437 F has an x-window. */
1439 x_set_border_pixel (f
, pix
)
1443 f
->output_data
.x
->border_pixel
= pix
;
1445 if (FRAME_X_WINDOW (f
) != 0 && f
->output_data
.x
->border_width
> 0)
1451 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1452 (unsigned long)pix
);
1455 if (FRAME_VISIBLE_P (f
))
1461 x_set_cursor_type (f
, arg
, oldval
)
1463 Lisp_Object arg
, oldval
;
1467 FRAME_DESIRED_CURSOR (f
) = bar_cursor
;
1468 f
->output_data
.x
->cursor_width
= 2;
1470 else if (CONSP (arg
) && EQ (XCONS (arg
)->car
, Qbar
)
1471 && INTEGERP (XCONS (arg
)->cdr
))
1473 FRAME_DESIRED_CURSOR (f
) = bar_cursor
;
1474 f
->output_data
.x
->cursor_width
= XINT (XCONS (arg
)->cdr
);
1477 /* Treat anything unknown as "box cursor".
1478 It was bad to signal an error; people have trouble fixing
1479 .Xdefaults with Emacs, when it has something bad in it. */
1480 FRAME_DESIRED_CURSOR (f
) = filled_box_cursor
;
1482 /* Make sure the cursor gets redrawn. This is overkill, but how
1483 often do people change cursor types? */
1484 update_mode_lines
++;
1488 x_set_icon_type (f
, arg
, oldval
)
1490 Lisp_Object arg
, oldval
;
1497 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1500 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1505 result
= x_text_icon (f
,
1506 (char *) XSTRING ((!NILP (f
->icon_name
)
1510 result
= x_bitmap_icon (f
, arg
);
1515 error ("No icon window available");
1518 XFlush (FRAME_X_DISPLAY (f
));
1522 /* Return non-nil if frame F wants a bitmap icon. */
1530 tem
= assq_no_quit (Qicon_type
, f
->param_alist
);
1532 return XCONS (tem
)->cdr
;
1538 x_set_icon_name (f
, arg
, oldval
)
1540 Lisp_Object arg
, oldval
;
1547 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1550 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1555 if (f
->output_data
.x
->icon_bitmap
!= 0)
1560 result
= x_text_icon (f
,
1561 (char *) XSTRING ((!NILP (f
->icon_name
)
1570 error ("No icon window available");
1573 XFlush (FRAME_X_DISPLAY (f
));
1577 extern Lisp_Object
x_new_font ();
1580 x_set_font (f
, arg
, oldval
)
1582 Lisp_Object arg
, oldval
;
1586 CHECK_STRING (arg
, 1);
1589 result
= x_new_font (f
, XSTRING (arg
)->data
);
1592 if (EQ (result
, Qnil
))
1593 error ("Font `%s' is not defined", XSTRING (arg
)->data
);
1594 else if (EQ (result
, Qt
))
1595 error ("the characters of the given font have varying widths");
1596 else if (STRINGP (result
))
1598 recompute_basic_faces (f
);
1599 store_frame_param (f
, Qfont
, result
);
1606 x_set_border_width (f
, arg
, oldval
)
1608 Lisp_Object arg
, oldval
;
1610 CHECK_NUMBER (arg
, 0);
1612 if (XINT (arg
) == f
->output_data
.x
->border_width
)
1615 if (FRAME_X_WINDOW (f
) != 0)
1616 error ("Cannot change the border width of a window");
1618 f
->output_data
.x
->border_width
= XINT (arg
);
1622 x_set_internal_border_width (f
, arg
, oldval
)
1624 Lisp_Object arg
, oldval
;
1627 int old
= f
->output_data
.x
->internal_border_width
;
1629 CHECK_NUMBER (arg
, 0);
1630 f
->output_data
.x
->internal_border_width
= XINT (arg
);
1631 if (f
->output_data
.x
->internal_border_width
< 0)
1632 f
->output_data
.x
->internal_border_width
= 0;
1634 if (f
->output_data
.x
->internal_border_width
== old
)
1637 if (FRAME_X_WINDOW (f
) != 0)
1640 x_set_window_size (f
, 0, f
->width
, f
->height
);
1642 x_set_resize_hint (f
);
1644 XFlush (FRAME_X_DISPLAY (f
));
1646 SET_FRAME_GARBAGED (f
);
1651 x_set_visibility (f
, value
, oldval
)
1653 Lisp_Object value
, oldval
;
1656 XSETFRAME (frame
, f
);
1659 Fmake_frame_invisible (frame
, Qt
);
1660 else if (EQ (value
, Qicon
))
1661 Ficonify_frame (frame
);
1663 Fmake_frame_visible (frame
);
1667 x_set_menu_bar_lines_1 (window
, n
)
1671 struct window
*w
= XWINDOW (window
);
1673 XSETFASTINT (w
->top
, XFASTINT (w
->top
) + n
);
1674 XSETFASTINT (w
->height
, XFASTINT (w
->height
) - n
);
1676 /* Handle just the top child in a vertical split. */
1677 if (!NILP (w
->vchild
))
1678 x_set_menu_bar_lines_1 (w
->vchild
, n
);
1680 /* Adjust all children in a horizontal split. */
1681 for (window
= w
->hchild
; !NILP (window
); window
= w
->next
)
1683 w
= XWINDOW (window
);
1684 x_set_menu_bar_lines_1 (window
, n
);
1689 x_set_menu_bar_lines (f
, value
, oldval
)
1691 Lisp_Object value
, oldval
;
1694 int olines
= FRAME_MENU_BAR_LINES (f
);
1696 /* Right now, menu bars don't work properly in minibuf-only frames;
1697 most of the commands try to apply themselves to the minibuffer
1698 frame itslef, and get an error because you can't switch buffers
1699 in or split the minibuffer window. */
1700 if (FRAME_MINIBUF_ONLY_P (f
))
1703 if (INTEGERP (value
))
1704 nlines
= XINT (value
);
1708 #ifdef USE_X_TOOLKIT
1709 FRAME_MENU_BAR_LINES (f
) = 0;
1712 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
1713 if (FRAME_X_P (f
) && f
->output_data
.x
->menubar_widget
== 0)
1714 /* Make sure next redisplay shows the menu bar. */
1715 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= Qt
;
1719 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
1720 free_frame_menubar (f
);
1721 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
1723 f
->output_data
.x
->menubar_widget
= 0;
1725 #else /* not USE_X_TOOLKIT */
1726 FRAME_MENU_BAR_LINES (f
) = nlines
;
1727 x_set_menu_bar_lines_1 (f
->root_window
, nlines
- olines
);
1728 #endif /* not USE_X_TOOLKIT */
1731 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1734 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1735 name; if NAME is a string, set F's name to NAME and set
1736 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1738 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1739 suggesting a new name, which lisp code should override; if
1740 F->explicit_name is set, ignore the new name; otherwise, set it. */
1743 x_set_name (f
, name
, explicit)
1748 /* Make sure that requests from lisp code override requests from
1749 Emacs redisplay code. */
1752 /* If we're switching from explicit to implicit, we had better
1753 update the mode lines and thereby update the title. */
1754 if (f
->explicit_name
&& NILP (name
))
1755 update_mode_lines
= 1;
1757 f
->explicit_name
= ! NILP (name
);
1759 else if (f
->explicit_name
)
1762 /* If NAME is nil, set the name to the x_id_name. */
1765 /* Check for no change needed in this very common case
1766 before we do any consing. */
1767 if (!strcmp (FRAME_X_DISPLAY_INFO (f
)->x_id_name
,
1768 XSTRING (f
->name
)->data
))
1770 name
= build_string (FRAME_X_DISPLAY_INFO (f
)->x_id_name
);
1773 CHECK_STRING (name
, 0);
1775 /* Don't change the name if it's already NAME. */
1776 if (! NILP (Fstring_equal (name
, f
->name
)))
1781 /* For setting the frame title, the title parameter should override
1782 the name parameter. */
1783 if (! NILP (f
->title
))
1786 if (FRAME_X_WINDOW (f
))
1791 XTextProperty text
, icon
;
1792 Lisp_Object icon_name
;
1794 text
.value
= XSTRING (name
)->data
;
1795 text
.encoding
= XA_STRING
;
1797 text
.nitems
= XSTRING (name
)->size
;
1799 icon_name
= (!NILP (f
->icon_name
) ? f
->icon_name
: name
);
1801 icon
.value
= XSTRING (icon_name
)->data
;
1802 icon
.encoding
= XA_STRING
;
1804 icon
.nitems
= XSTRING (icon_name
)->size
;
1805 #ifdef USE_X_TOOLKIT
1806 XSetWMName (FRAME_X_DISPLAY (f
),
1807 XtWindow (f
->output_data
.x
->widget
), &text
);
1808 XSetWMIconName (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
),
1810 #else /* not USE_X_TOOLKIT */
1811 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &text
);
1812 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &icon
);
1813 #endif /* not USE_X_TOOLKIT */
1815 #else /* not HAVE_X11R4 */
1816 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1817 XSTRING (name
)->data
);
1818 XStoreName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1819 XSTRING (name
)->data
);
1820 #endif /* not HAVE_X11R4 */
1825 /* This function should be called when the user's lisp code has
1826 specified a name for the frame; the name will override any set by the
1829 x_explicitly_set_name (f
, arg
, oldval
)
1831 Lisp_Object arg
, oldval
;
1833 x_set_name (f
, arg
, 1);
1836 /* This function should be called by Emacs redisplay code to set the
1837 name; names set this way will never override names set by the user's
1840 x_implicitly_set_name (f
, arg
, oldval
)
1842 Lisp_Object arg
, oldval
;
1844 x_set_name (f
, arg
, 0);
1847 /* Change the title of frame F to NAME.
1848 If NAME is nil, use the frame name as the title.
1850 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1851 name; if NAME is a string, set F's name to NAME and set
1852 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1854 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1855 suggesting a new name, which lisp code should override; if
1856 F->explicit_name is set, ignore the new name; otherwise, set it. */
1859 x_set_title (f
, name
)
1863 /* Don't change the title if it's already NAME. */
1864 if (EQ (name
, f
->title
))
1867 update_mode_lines
= 1;
1874 if (FRAME_X_WINDOW (f
))
1879 XTextProperty text
, icon
;
1880 Lisp_Object icon_name
;
1882 text
.value
= XSTRING (name
)->data
;
1883 text
.encoding
= XA_STRING
;
1885 text
.nitems
= XSTRING (name
)->size
;
1887 icon_name
= (!NILP (f
->icon_name
) ? f
->icon_name
: name
);
1889 icon
.value
= XSTRING (icon_name
)->data
;
1890 icon
.encoding
= XA_STRING
;
1892 icon
.nitems
= XSTRING (icon_name
)->size
;
1893 #ifdef USE_X_TOOLKIT
1894 XSetWMName (FRAME_X_DISPLAY (f
),
1895 XtWindow (f
->output_data
.x
->widget
), &text
);
1896 XSetWMIconName (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
),
1898 #else /* not USE_X_TOOLKIT */
1899 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &text
);
1900 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &icon
);
1901 #endif /* not USE_X_TOOLKIT */
1903 #else /* not HAVE_X11R4 */
1904 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1905 XSTRING (name
)->data
);
1906 XStoreName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1907 XSTRING (name
)->data
);
1908 #endif /* not HAVE_X11R4 */
1914 x_set_autoraise (f
, arg
, oldval
)
1916 Lisp_Object arg
, oldval
;
1918 f
->auto_raise
= !EQ (Qnil
, arg
);
1922 x_set_autolower (f
, arg
, oldval
)
1924 Lisp_Object arg
, oldval
;
1926 f
->auto_lower
= !EQ (Qnil
, arg
);
1930 x_set_unsplittable (f
, arg
, oldval
)
1932 Lisp_Object arg
, oldval
;
1934 f
->no_split
= !NILP (arg
);
1938 x_set_vertical_scroll_bars (f
, arg
, oldval
)
1940 Lisp_Object arg
, oldval
;
1942 if (NILP (arg
) != ! FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
1944 FRAME_HAS_VERTICAL_SCROLL_BARS (f
) = ! NILP (arg
);
1946 /* We set this parameter before creating the X window for the
1947 frame, so we can get the geometry right from the start.
1948 However, if the window hasn't been created yet, we shouldn't
1949 call x_set_window_size. */
1950 if (FRAME_X_WINDOW (f
))
1951 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
1956 x_set_scroll_bar_width (f
, arg
, oldval
)
1958 Lisp_Object arg
, oldval
;
1962 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = 0;
1963 FRAME_SCROLL_BAR_COLS (f
) = 2;
1965 else if (INTEGERP (arg
) && XINT (arg
) > 0
1966 && XFASTINT (arg
) != FRAME_SCROLL_BAR_PIXEL_WIDTH (f
))
1968 int wid
= FONT_WIDTH (f
->output_data
.x
->font
);
1969 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = XFASTINT (arg
);
1970 FRAME_SCROLL_BAR_COLS (f
) = (XFASTINT (arg
) + wid
-1) / wid
;
1971 if (FRAME_X_WINDOW (f
))
1972 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
1976 /* Subroutines of creating an X frame. */
1978 /* Make sure that Vx_resource_name is set to a reasonable value.
1979 Fix it up, or set it to `emacs' if it is too hopeless. */
1982 validate_x_resource_name ()
1985 /* Number of valid characters in the resource name. */
1987 /* Number of invalid characters in the resource name. */
1992 if (STRINGP (Vx_resource_name
))
1994 unsigned char *p
= XSTRING (Vx_resource_name
)->data
;
1997 len
= XSTRING (Vx_resource_name
)->size
;
1999 /* Only letters, digits, - and _ are valid in resource names.
2000 Count the valid characters and count the invalid ones. */
2001 for (i
= 0; i
< len
; i
++)
2004 if (! ((c
>= 'a' && c
<= 'z')
2005 || (c
>= 'A' && c
<= 'Z')
2006 || (c
>= '0' && c
<= '9')
2007 || c
== '-' || c
== '_'))
2014 /* Not a string => completely invalid. */
2015 bad_count
= 5, good_count
= 0;
2017 /* If name is valid already, return. */
2021 /* If name is entirely invalid, or nearly so, use `emacs'. */
2023 || (good_count
== 1 && bad_count
> 0))
2025 Vx_resource_name
= build_string ("emacs");
2029 /* Name is partly valid. Copy it and replace the invalid characters
2030 with underscores. */
2032 Vx_resource_name
= new = Fcopy_sequence (Vx_resource_name
);
2034 for (i
= 0; i
< len
; i
++)
2036 int c
= XSTRING (new)->data
[i
];
2037 if (! ((c
>= 'a' && c
<= 'z')
2038 || (c
>= 'A' && c
<= 'Z')
2039 || (c
>= '0' && c
<= '9')
2040 || c
== '-' || c
== '_'))
2041 XSTRING (new)->data
[i
] = '_';
2046 extern char *x_get_string_resource ();
2048 DEFUN ("x-get-resource", Fx_get_resource
, Sx_get_resource
, 2, 4, 0,
2049 "Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.\n\
2050 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the\n\
2051 class, where INSTANCE is the name under which Emacs was invoked, or\n\
2052 the name specified by the `-name' or `-rn' command-line arguments.\n\
2054 The optional arguments COMPONENT and SUBCLASS add to the key and the\n\
2055 class, respectively. You must specify both of them or neither.\n\
2056 If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'\n\
2057 and the class is `Emacs.CLASS.SUBCLASS'.")
2058 (attribute
, class, component
, subclass
)
2059 Lisp_Object attribute
, class, component
, subclass
;
2061 register char *value
;
2067 CHECK_STRING (attribute
, 0);
2068 CHECK_STRING (class, 0);
2070 if (!NILP (component
))
2071 CHECK_STRING (component
, 1);
2072 if (!NILP (subclass
))
2073 CHECK_STRING (subclass
, 2);
2074 if (NILP (component
) != NILP (subclass
))
2075 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
2077 validate_x_resource_name ();
2079 /* Allocate space for the components, the dots which separate them,
2080 and the final '\0'. Make them big enough for the worst case. */
2081 name_key
= (char *) alloca (XSTRING (Vx_resource_name
)->size
2082 + (STRINGP (component
)
2083 ? XSTRING (component
)->size
: 0)
2084 + XSTRING (attribute
)->size
2087 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
2088 + XSTRING (class)->size
2089 + (STRINGP (subclass
)
2090 ? XSTRING (subclass
)->size
: 0)
2093 /* Start with emacs.FRAMENAME for the name (the specific one)
2094 and with `Emacs' for the class key (the general one). */
2095 strcpy (name_key
, XSTRING (Vx_resource_name
)->data
);
2096 strcpy (class_key
, EMACS_CLASS
);
2098 strcat (class_key
, ".");
2099 strcat (class_key
, XSTRING (class)->data
);
2101 if (!NILP (component
))
2103 strcat (class_key
, ".");
2104 strcat (class_key
, XSTRING (subclass
)->data
);
2106 strcat (name_key
, ".");
2107 strcat (name_key
, XSTRING (component
)->data
);
2110 strcat (name_key
, ".");
2111 strcat (name_key
, XSTRING (attribute
)->data
);
2113 value
= x_get_string_resource (check_x_display_info (Qnil
)->xrdb
,
2114 name_key
, class_key
);
2116 if (value
!= (char *) 0)
2117 return build_string (value
);
2122 /* Used when C code wants a resource value. */
2125 x_get_resource_string (attribute
, class)
2126 char *attribute
, *class;
2128 register char *value
;
2132 /* Allocate space for the components, the dots which separate them,
2133 and the final '\0'. */
2134 name_key
= (char *) alloca (XSTRING (Vinvocation_name
)->size
2135 + strlen (attribute
) + 2);
2136 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
2137 + strlen (class) + 2);
2139 sprintf (name_key
, "%s.%s",
2140 XSTRING (Vinvocation_name
)->data
,
2142 sprintf (class_key
, "%s.%s", EMACS_CLASS
, class);
2144 return x_get_string_resource (FRAME_X_DISPLAY_INFO (selected_frame
)->xrdb
,
2145 name_key
, class_key
);
2148 /* Types we might convert a resource string into. */
2151 number
, boolean
, string
, symbol
2154 /* Return the value of parameter PARAM.
2156 First search ALIST, then Vdefault_frame_alist, then the X defaults
2157 database, using ATTRIBUTE as the attribute name and CLASS as its class.
2159 Convert the resource to the type specified by desired_type.
2161 If no default is specified, return Qunbound. If you call
2162 x_get_arg, make sure you deal with Qunbound in a reasonable way,
2163 and don't let it get stored in any Lisp-visible variables! */
2166 x_get_arg (alist
, param
, attribute
, class, type
)
2167 Lisp_Object alist
, param
;
2170 enum resource_types type
;
2172 register Lisp_Object tem
;
2174 tem
= Fassq (param
, alist
);
2176 tem
= Fassq (param
, Vdefault_frame_alist
);
2182 tem
= Fx_get_resource (build_string (attribute
),
2183 build_string (class),
2192 return make_number (atoi (XSTRING (tem
)->data
));
2195 tem
= Fdowncase (tem
);
2196 if (!strcmp (XSTRING (tem
)->data
, "on")
2197 || !strcmp (XSTRING (tem
)->data
, "true"))
2206 /* As a special case, we map the values `true' and `on'
2207 to Qt, and `false' and `off' to Qnil. */
2210 lower
= Fdowncase (tem
);
2211 if (!strcmp (XSTRING (lower
)->data
, "on")
2212 || !strcmp (XSTRING (lower
)->data
, "true"))
2214 else if (!strcmp (XSTRING (lower
)->data
, "off")
2215 || !strcmp (XSTRING (lower
)->data
, "false"))
2218 return Fintern (tem
, Qnil
);
2231 /* Record in frame F the specified or default value according to ALIST
2232 of the parameter named PARAM (a Lisp symbol).
2233 If no value is specified for PARAM, look for an X default for XPROP
2234 on the frame named NAME.
2235 If that is not found either, use the value DEFLT. */
2238 x_default_parameter (f
, alist
, prop
, deflt
, xprop
, xclass
, type
)
2245 enum resource_types type
;
2249 tem
= x_get_arg (alist
, prop
, xprop
, xclass
, type
);
2250 if (EQ (tem
, Qunbound
))
2252 x_set_frame_parameters (f
, Fcons (Fcons (prop
, tem
), Qnil
));
2256 DEFUN ("x-parse-geometry", Fx_parse_geometry
, Sx_parse_geometry
, 1, 1, 0,
2257 "Parse an X-style geometry string STRING.\n\
2258 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).\n\
2259 The properties returned may include `top', `left', `height', and `width'.\n\
2260 The value of `left' or `top' may be an integer,\n\
2261 or a list (+ N) meaning N pixels relative to top/left corner,\n\
2262 or a list (- N) meaning -N pixels relative to bottom/right corner.")
2267 unsigned int width
, height
;
2270 CHECK_STRING (string
, 0);
2272 geometry
= XParseGeometry ((char *) XSTRING (string
)->data
,
2273 &x
, &y
, &width
, &height
);
2276 if (!!(geometry
& XValue
) != !!(geometry
& YValue
))
2277 error ("Must specify both x and y position, or neither");
2281 if (geometry
& XValue
)
2283 Lisp_Object element
;
2285 if (x
>= 0 && (geometry
& XNegative
))
2286 element
= Fcons (Qleft
, Fcons (Qminus
, Fcons (make_number (-x
), Qnil
)));
2287 else if (x
< 0 && ! (geometry
& XNegative
))
2288 element
= Fcons (Qleft
, Fcons (Qplus
, Fcons (make_number (x
), Qnil
)));
2290 element
= Fcons (Qleft
, make_number (x
));
2291 result
= Fcons (element
, result
);
2294 if (geometry
& YValue
)
2296 Lisp_Object element
;
2298 if (y
>= 0 && (geometry
& YNegative
))
2299 element
= Fcons (Qtop
, Fcons (Qminus
, Fcons (make_number (-y
), Qnil
)));
2300 else if (y
< 0 && ! (geometry
& YNegative
))
2301 element
= Fcons (Qtop
, Fcons (Qplus
, Fcons (make_number (y
), Qnil
)));
2303 element
= Fcons (Qtop
, make_number (y
));
2304 result
= Fcons (element
, result
);
2307 if (geometry
& WidthValue
)
2308 result
= Fcons (Fcons (Qwidth
, make_number (width
)), result
);
2309 if (geometry
& HeightValue
)
2310 result
= Fcons (Fcons (Qheight
, make_number (height
)), result
);
2315 /* Calculate the desired size and position of this window,
2316 and return the flags saying which aspects were specified.
2318 This function does not make the coordinates positive. */
2320 #define DEFAULT_ROWS 40
2321 #define DEFAULT_COLS 80
2324 x_figure_window_size (f
, parms
)
2328 register Lisp_Object tem0
, tem1
, tem2
;
2329 int height
, width
, left
, top
;
2330 register int geometry
;
2331 long window_prompting
= 0;
2333 /* Default values if we fall through.
2334 Actually, if that happens we should get
2335 window manager prompting. */
2336 f
->width
= DEFAULT_COLS
;
2337 f
->height
= DEFAULT_ROWS
;
2338 /* Window managers expect that if program-specified
2339 positions are not (0,0), they're intentional, not defaults. */
2340 f
->output_data
.x
->top_pos
= 0;
2341 f
->output_data
.x
->left_pos
= 0;
2343 tem0
= x_get_arg (parms
, Qheight
, 0, 0, number
);
2344 tem1
= x_get_arg (parms
, Qwidth
, 0, 0, number
);
2345 tem2
= x_get_arg (parms
, Quser_size
, 0, 0, number
);
2346 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
2348 if (!EQ (tem0
, Qunbound
))
2350 CHECK_NUMBER (tem0
, 0);
2351 f
->height
= XINT (tem0
);
2353 if (!EQ (tem1
, Qunbound
))
2355 CHECK_NUMBER (tem1
, 0);
2356 f
->width
= XINT (tem1
);
2358 if (!NILP (tem2
) && !EQ (tem2
, Qunbound
))
2359 window_prompting
|= USSize
;
2361 window_prompting
|= PSize
;
2364 f
->output_data
.x
->vertical_scroll_bar_extra
2365 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
2367 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0
2368 ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f
)
2369 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.x
->font
)));
2370 f
->output_data
.x
->pixel_width
= CHAR_TO_PIXEL_WIDTH (f
, f
->width
);
2371 f
->output_data
.x
->pixel_height
= CHAR_TO_PIXEL_HEIGHT (f
, f
->height
);
2373 tem0
= x_get_arg (parms
, Qtop
, 0, 0, number
);
2374 tem1
= x_get_arg (parms
, Qleft
, 0, 0, number
);
2375 tem2
= x_get_arg (parms
, Quser_position
, 0, 0, number
);
2376 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
2378 if (EQ (tem0
, Qminus
))
2380 f
->output_data
.x
->top_pos
= 0;
2381 window_prompting
|= YNegative
;
2383 else if (CONSP (tem0
) && EQ (XCONS (tem0
)->car
, Qminus
)
2384 && CONSP (XCONS (tem0
)->cdr
)
2385 && INTEGERP (XCONS (XCONS (tem0
)->cdr
)->car
))
2387 f
->output_data
.x
->top_pos
= - XINT (XCONS (XCONS (tem0
)->cdr
)->car
);
2388 window_prompting
|= YNegative
;
2390 else if (CONSP (tem0
) && EQ (XCONS (tem0
)->car
, Qplus
)
2391 && CONSP (XCONS (tem0
)->cdr
)
2392 && INTEGERP (XCONS (XCONS (tem0
)->cdr
)->car
))
2394 f
->output_data
.x
->top_pos
= XINT (XCONS (XCONS (tem0
)->cdr
)->car
);
2396 else if (EQ (tem0
, Qunbound
))
2397 f
->output_data
.x
->top_pos
= 0;
2400 CHECK_NUMBER (tem0
, 0);
2401 f
->output_data
.x
->top_pos
= XINT (tem0
);
2402 if (f
->output_data
.x
->top_pos
< 0)
2403 window_prompting
|= YNegative
;
2406 if (EQ (tem1
, Qminus
))
2408 f
->output_data
.x
->left_pos
= 0;
2409 window_prompting
|= XNegative
;
2411 else if (CONSP (tem1
) && EQ (XCONS (tem1
)->car
, Qminus
)
2412 && CONSP (XCONS (tem1
)->cdr
)
2413 && INTEGERP (XCONS (XCONS (tem1
)->cdr
)->car
))
2415 f
->output_data
.x
->left_pos
= - XINT (XCONS (XCONS (tem1
)->cdr
)->car
);
2416 window_prompting
|= XNegative
;
2418 else if (CONSP (tem1
) && EQ (XCONS (tem1
)->car
, Qplus
)
2419 && CONSP (XCONS (tem1
)->cdr
)
2420 && INTEGERP (XCONS (XCONS (tem1
)->cdr
)->car
))
2422 f
->output_data
.x
->left_pos
= XINT (XCONS (XCONS (tem1
)->cdr
)->car
);
2424 else if (EQ (tem1
, Qunbound
))
2425 f
->output_data
.x
->left_pos
= 0;
2428 CHECK_NUMBER (tem1
, 0);
2429 f
->output_data
.x
->left_pos
= XINT (tem1
);
2430 if (f
->output_data
.x
->left_pos
< 0)
2431 window_prompting
|= XNegative
;
2434 if (!NILP (tem2
) && ! EQ (tem2
, Qunbound
))
2435 window_prompting
|= USPosition
;
2437 window_prompting
|= PPosition
;
2440 return window_prompting
;
2443 #if !defined (HAVE_X11R4) && !defined (HAVE_XSETWMPROTOCOLS)
2446 XSetWMProtocols (dpy
, w
, protocols
, count
)
2453 prop
= XInternAtom (dpy
, "WM_PROTOCOLS", False
);
2454 if (prop
== None
) return False
;
2455 XChangeProperty (dpy
, w
, prop
, XA_ATOM
, 32, PropModeReplace
,
2456 (unsigned char *) protocols
, count
);
2459 #endif /* not HAVE_X11R4 && not HAVE_XSETWMPROTOCOLS */
2461 #ifdef USE_X_TOOLKIT
2463 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
2464 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
2465 already be present because of the toolkit (Motif adds some of them,
2466 for example, but Xt doesn't). */
2469 hack_wm_protocols (f
, widget
)
2473 Display
*dpy
= XtDisplay (widget
);
2474 Window w
= XtWindow (widget
);
2475 int need_delete
= 1;
2481 Atom type
, *atoms
= 0;
2483 unsigned long nitems
= 0;
2484 unsigned long bytes_after
;
2486 if ((XGetWindowProperty (dpy
, w
,
2487 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2488 (long)0, (long)100, False
, XA_ATOM
,
2489 &type
, &format
, &nitems
, &bytes_after
,
2490 (unsigned char **) &atoms
)
2492 && format
== 32 && type
== XA_ATOM
)
2496 if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
)
2498 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
)
2500 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
)
2503 if (atoms
) XFree ((char *) atoms
);
2509 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2511 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
;
2513 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2515 XChangeProperty (dpy
, w
, FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2516 XA_ATOM
, 32, PropModeAppend
,
2517 (unsigned char *) props
, count
);
2523 #ifdef USE_X_TOOLKIT
2525 /* Create and set up the X widget for frame F. */
2528 x_window (f
, window_prompting
, minibuffer_only
)
2530 long window_prompting
;
2531 int minibuffer_only
;
2533 XClassHint class_hints
;
2534 XSetWindowAttributes attributes
;
2535 unsigned long attribute_mask
;
2537 Widget shell_widget
;
2539 Widget frame_widget
;
2545 /* Use the resource name as the top-level widget name
2546 for looking up resources. Make a non-Lisp copy
2547 for the window manager, so GC relocation won't bother it.
2549 Elsewhere we specify the window name for the window manager. */
2552 char *str
= (char *) XSTRING (Vx_resource_name
)->data
;
2553 f
->namebuf
= (char *) xmalloc (strlen (str
) + 1);
2554 strcpy (f
->namebuf
, str
);
2558 XtSetArg (al
[ac
], XtNallowShellResize
, 1); ac
++;
2559 XtSetArg (al
[ac
], XtNinput
, 1); ac
++;
2560 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2561 XtSetArg (al
[ac
], XtNborderWidth
, f
->output_data
.x
->border_width
); ac
++;
2562 shell_widget
= XtAppCreateShell (f
->namebuf
, EMACS_CLASS
,
2563 applicationShellWidgetClass
,
2564 FRAME_X_DISPLAY (f
), al
, ac
);
2566 f
->output_data
.x
->widget
= shell_widget
;
2567 /* maybe_set_screen_title_format (shell_widget); */
2569 pane_widget
= lw_create_widget ("main", "pane", widget_id_tick
++,
2570 (widget_value
*) NULL
,
2571 shell_widget
, False
,
2574 (lw_callback
) NULL
);
2576 f
->output_data
.x
->column_widget
= pane_widget
;
2578 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2579 the emacs screen when changing menubar. This reduces flickering. */
2582 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2583 XtSetArg (al
[ac
], XtNshowGrip
, 0); ac
++;
2584 XtSetArg (al
[ac
], XtNallowResize
, 1); ac
++;
2585 XtSetArg (al
[ac
], XtNresizeToPreferred
, 1); ac
++;
2586 XtSetArg (al
[ac
], XtNemacsFrame
, f
); ac
++;
2587 frame_widget
= XtCreateWidget (f
->namebuf
,
2589 pane_widget
, al
, ac
);
2591 f
->output_data
.x
->edit_widget
= frame_widget
;
2593 XtManageChild (frame_widget
);
2595 /* Do some needed geometry management. */
2598 char *tem
, shell_position
[32];
2601 int extra_borders
= 0;
2603 = (f
->output_data
.x
->menubar_widget
2604 ? (f
->output_data
.x
->menubar_widget
->core
.height
2605 + f
->output_data
.x
->menubar_widget
->core
.border_width
)
2607 extern char *lwlib_toolkit_type
;
2609 if (FRAME_EXTERNAL_MENU_BAR (f
))
2612 XtVaGetValues (pane_widget
, XtNinternalBorderWidth
, &ibw
, NULL
);
2613 menubar_size
+= ibw
;
2616 f
->output_data
.x
->menubar_height
= menubar_size
;
2618 /* Motif seems to need this amount added to the sizes
2619 specified for the shell widget. The Athena/Lucid widgets don't.
2620 Both conclusions reached experimentally. -- rms. */
2621 if (!strcmp (lwlib_toolkit_type
, "motif"))
2622 XtVaGetValues (f
->output_data
.x
->edit_widget
, XtNinternalBorderWidth
,
2623 &extra_borders
, NULL
);
2625 /* Convert our geometry parameters into a geometry string
2627 Note that we do not specify here whether the position
2628 is a user-specified or program-specified one.
2629 We pass that information later, in x_wm_set_size_hints. */
2631 int left
= f
->output_data
.x
->left_pos
;
2632 int xneg
= window_prompting
& XNegative
;
2633 int top
= f
->output_data
.x
->top_pos
;
2634 int yneg
= window_prompting
& YNegative
;
2640 if (window_prompting
& USPosition
)
2641 sprintf (shell_position
, "=%dx%d%c%d%c%d",
2642 PIXEL_WIDTH (f
) + extra_borders
,
2643 PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
,
2644 (xneg
? '-' : '+'), left
,
2645 (yneg
? '-' : '+'), top
);
2647 sprintf (shell_position
, "=%dx%d",
2648 PIXEL_WIDTH (f
) + extra_borders
,
2649 PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
);
2652 len
= strlen (shell_position
) + 1;
2653 tem
= (char *) xmalloc (len
);
2654 strncpy (tem
, shell_position
, len
);
2655 XtSetArg (al
[ac
], XtNgeometry
, tem
); ac
++;
2656 XtSetValues (shell_widget
, al
, ac
);
2659 XtManageChild (pane_widget
);
2660 XtRealizeWidget (shell_widget
);
2662 FRAME_X_WINDOW (f
) = XtWindow (frame_widget
);
2664 validate_x_resource_name ();
2666 class_hints
.res_name
= (char *) XSTRING (Vx_resource_name
)->data
;
2667 class_hints
.res_class
= EMACS_CLASS
;
2668 XSetClassHint (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
), &class_hints
);
2671 #ifndef X_I18N_INHIBITED
2676 xim
= XOpenIM (FRAME_X_DISPLAY (f
), NULL
, NULL
, NULL
);
2680 xic
= XCreateIC (xim
,
2681 XNInputStyle
, XIMPreeditNothing
| XIMStatusNothing
,
2682 XNClientWindow
, FRAME_X_WINDOW(f
),
2683 XNFocusWindow
, FRAME_X_WINDOW(f
),
2692 FRAME_XIM (f
) = xim
;
2693 FRAME_XIC (f
) = xic
;
2695 #else /* X_I18N_INHIBITED */
2698 #endif /* X_I18N_INHIBITED */
2699 #endif /* HAVE_X_I18N */
2701 f
->output_data
.x
->wm_hints
.input
= True
;
2702 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2703 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2704 &f
->output_data
.x
->wm_hints
);
2706 hack_wm_protocols (f
, shell_widget
);
2709 XtAddEventHandler (shell_widget
, 0, True
, _XEditResCheckMessages
, 0);
2712 /* Do a stupid property change to force the server to generate a
2713 propertyNotify event so that the event_stream server timestamp will
2714 be initialized to something relevant to the time we created the window.
2716 XChangeProperty (XtDisplay (frame_widget
), XtWindow (frame_widget
),
2717 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2718 XA_ATOM
, 32, PropModeAppend
,
2719 (unsigned char*) NULL
, 0);
2721 /* Make all the standard events reach the Emacs frame. */
2722 attributes
.event_mask
= STANDARD_EVENT_SET
;
2723 attribute_mask
= CWEventMask
;
2724 XChangeWindowAttributes (XtDisplay (shell_widget
), XtWindow (shell_widget
),
2725 attribute_mask
, &attributes
);
2727 XtMapWidget (frame_widget
);
2729 /* x_set_name normally ignores requests to set the name if the
2730 requested name is the same as the current name. This is the one
2731 place where that assumption isn't correct; f->name is set, but
2732 the X server hasn't been told. */
2735 int explicit = f
->explicit_name
;
2737 f
->explicit_name
= 0;
2740 x_set_name (f
, name
, explicit);
2743 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2744 f
->output_data
.x
->text_cursor
);
2748 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
2749 initialize_frame_menubar (f
);
2750 lw_set_main_areas (pane_widget
, f
->output_data
.x
->menubar_widget
, frame_widget
);
2752 if (FRAME_X_WINDOW (f
) == 0)
2753 error ("Unable to create window");
2756 #else /* not USE_X_TOOLKIT */
2758 /* Create and set up the X window for frame F. */
2764 XClassHint class_hints
;
2765 XSetWindowAttributes attributes
;
2766 unsigned long attribute_mask
;
2768 attributes
.background_pixel
= f
->output_data
.x
->background_pixel
;
2769 attributes
.border_pixel
= f
->output_data
.x
->border_pixel
;
2770 attributes
.bit_gravity
= StaticGravity
;
2771 attributes
.backing_store
= NotUseful
;
2772 attributes
.save_under
= True
;
2773 attributes
.event_mask
= STANDARD_EVENT_SET
;
2774 attribute_mask
= (CWBackPixel
| CWBorderPixel
| CWBitGravity
2776 | CWBackingStore
| CWSaveUnder
2782 = XCreateWindow (FRAME_X_DISPLAY (f
),
2783 f
->output_data
.x
->parent_desc
,
2784 f
->output_data
.x
->left_pos
,
2785 f
->output_data
.x
->top_pos
,
2786 PIXEL_WIDTH (f
), PIXEL_HEIGHT (f
),
2787 f
->output_data
.x
->border_width
,
2788 CopyFromParent
, /* depth */
2789 InputOutput
, /* class */
2790 FRAME_X_DISPLAY_INFO (f
)->visual
,
2791 attribute_mask
, &attributes
);
2793 #ifndef X_I18N_INHIBITED
2798 xim
= XOpenIM (FRAME_X_DISPLAY(f
), NULL
, NULL
, NULL
);
2802 xic
= XCreateIC (xim
,
2803 XNInputStyle
, XIMPreeditNothing
| XIMStatusNothing
,
2804 XNClientWindow
, FRAME_X_WINDOW(f
),
2805 XNFocusWindow
, FRAME_X_WINDOW(f
),
2815 FRAME_XIM (f
) = xim
;
2816 FRAME_XIC (f
) = xic
;
2818 #else /* X_I18N_INHIBITED */
2821 #endif /* X_I18N_INHIBITED */
2822 #endif /* HAVE_X_I18N */
2824 validate_x_resource_name ();
2826 class_hints
.res_name
= (char *) XSTRING (Vx_resource_name
)->data
;
2827 class_hints
.res_class
= EMACS_CLASS
;
2828 XSetClassHint (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &class_hints
);
2830 /* The menubar is part of the ordinary display;
2831 it does not count in addition to the height of the window. */
2832 f
->output_data
.x
->menubar_height
= 0;
2834 /* This indicates that we use the "Passive Input" input model.
2835 Unless we do this, we don't get the Focus{In,Out} events that we
2836 need to draw the cursor correctly. Accursed bureaucrats.
2837 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2839 f
->output_data
.x
->wm_hints
.input
= True
;
2840 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2841 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2842 &f
->output_data
.x
->wm_hints
);
2843 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
2845 /* Request "save yourself" and "delete window" commands from wm. */
2848 protocols
[0] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2849 protocols
[1] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2850 XSetWMProtocols (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), protocols
, 2);
2853 /* x_set_name normally ignores requests to set the name if the
2854 requested name is the same as the current name. This is the one
2855 place where that assumption isn't correct; f->name is set, but
2856 the X server hasn't been told. */
2859 int explicit = f
->explicit_name
;
2861 f
->explicit_name
= 0;
2864 x_set_name (f
, name
, explicit);
2867 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2868 f
->output_data
.x
->text_cursor
);
2872 if (FRAME_X_WINDOW (f
) == 0)
2873 error ("Unable to create window");
2876 #endif /* not USE_X_TOOLKIT */
2878 /* Handle the icon stuff for this window. Perhaps later we might
2879 want an x_set_icon_position which can be called interactively as
2887 Lisp_Object icon_x
, icon_y
;
2889 /* Set the position of the icon. Note that twm groups all
2890 icons in an icon window. */
2891 icon_x
= x_get_arg (parms
, Qicon_left
, 0, 0, number
);
2892 icon_y
= x_get_arg (parms
, Qicon_top
, 0, 0, number
);
2893 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2895 CHECK_NUMBER (icon_x
, 0);
2896 CHECK_NUMBER (icon_y
, 0);
2898 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2899 error ("Both left and top icon corners of icon must be specified");
2903 if (! EQ (icon_x
, Qunbound
))
2904 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
2906 /* Start up iconic or window? */
2907 x_wm_set_window_state
2908 (f
, (EQ (x_get_arg (parms
, Qvisibility
, 0, 0, symbol
), Qicon
)
2912 x_text_icon (f
, (char *) XSTRING ((!NILP (f
->icon_name
)
2919 /* Make the GC's needed for this window, setting the
2920 background, border and mouse colors; also create the
2921 mouse cursor and the gray border tile. */
2923 static char cursor_bits
[] =
2925 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2926 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2927 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2928 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2935 XGCValues gc_values
;
2941 /* Create the GC's of this frame.
2942 Note that many default values are used. */
2945 gc_values
.font
= f
->output_data
.x
->font
->fid
;
2946 gc_values
.foreground
= f
->output_data
.x
->foreground_pixel
;
2947 gc_values
.background
= f
->output_data
.x
->background_pixel
;
2948 gc_values
.line_width
= 0; /* Means 1 using fast algorithm. */
2949 f
->output_data
.x
->normal_gc
= XCreateGC (FRAME_X_DISPLAY (f
),
2951 GCLineWidth
| GCFont
2952 | GCForeground
| GCBackground
,
2955 /* Reverse video style. */
2956 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
2957 gc_values
.background
= f
->output_data
.x
->foreground_pixel
;
2958 f
->output_data
.x
->reverse_gc
= XCreateGC (FRAME_X_DISPLAY (f
),
2960 GCFont
| GCForeground
| GCBackground
2964 /* Cursor has cursor-color background, background-color foreground. */
2965 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
2966 gc_values
.background
= f
->output_data
.x
->cursor_pixel
;
2967 gc_values
.fill_style
= FillOpaqueStippled
;
2969 = XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
2970 FRAME_X_DISPLAY_INFO (f
)->root_window
,
2971 cursor_bits
, 16, 16);
2972 f
->output_data
.x
->cursor_gc
2973 = XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2974 (GCFont
| GCForeground
| GCBackground
2975 | GCFillStyle
| GCStipple
| GCLineWidth
),
2978 /* Create the gray border tile used when the pointer is not in
2979 the frame. Since this depends on the frame's pixel values,
2980 this must be done on a per-frame basis. */
2981 f
->output_data
.x
->border_tile
2982 = (XCreatePixmapFromBitmapData
2983 (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
2984 gray_bits
, gray_width
, gray_height
,
2985 f
->output_data
.x
->foreground_pixel
,
2986 f
->output_data
.x
->background_pixel
,
2987 DefaultDepth (FRAME_X_DISPLAY (f
),
2988 XScreenNumberOfScreen (FRAME_X_SCREEN (f
)))));
2993 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
2995 "Make a new X window, which is called a \"frame\" in Emacs terms.\n\
2996 Returns an Emacs frame object.\n\
2997 ALIST is an alist of frame parameters.\n\
2998 If the parameters specify that the frame should not have a minibuffer,\n\
2999 and do not specify a specific minibuffer window to use,\n\
3000 then `default-minibuffer-frame' must be a frame whose minibuffer can\n\
3001 be shared by the new frame.\n\
3003 This function is an internal primitive--use `make-frame' instead.")
3008 Lisp_Object frame
, tem
;
3010 int minibuffer_only
= 0;
3011 long window_prompting
= 0;
3013 int count
= specpdl_ptr
- specpdl
;
3014 struct gcpro gcpro1
;
3015 Lisp_Object display
;
3016 struct x_display_info
*dpyinfo
;
3022 /* Use this general default value to start with
3023 until we know if this frame has a specified name. */
3024 Vx_resource_name
= Vinvocation_name
;
3026 display
= x_get_arg (parms
, Qdisplay
, 0, 0, string
);
3027 if (EQ (display
, Qunbound
))
3029 dpyinfo
= check_x_display_info (display
);
3031 kb
= dpyinfo
->kboard
;
3033 kb
= &the_only_kboard
;
3036 name
= x_get_arg (parms
, Qname
, "name", "Name", string
);
3038 && ! EQ (name
, Qunbound
)
3040 error ("Invalid frame name--not a string or nil");
3043 Vx_resource_name
= name
;
3045 /* See if parent window is specified. */
3046 parent
= x_get_arg (parms
, Qparent_id
, NULL
, NULL
, number
);
3047 if (EQ (parent
, Qunbound
))
3049 if (! NILP (parent
))
3050 CHECK_NUMBER (parent
, 0);
3052 tem
= x_get_arg (parms
, Qminibuffer
, 0, 0, symbol
);
3053 if (EQ (tem
, Qnone
) || NILP (tem
))
3054 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
3055 else if (EQ (tem
, Qonly
))
3057 f
= make_minibuffer_frame ();
3058 minibuffer_only
= 1;
3060 else if (WINDOWP (tem
))
3061 f
= make_frame_without_minibuffer (tem
, kb
, display
);
3065 /* Note that X Windows does support scroll bars. */
3066 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
3068 XSETFRAME (frame
, f
);
3071 f
->output_method
= output_x_window
;
3072 f
->output_data
.x
= (struct x_output
*) xmalloc (sizeof (struct x_output
));
3073 bzero (f
->output_data
.x
, sizeof (struct x_output
));
3074 f
->output_data
.x
->icon_bitmap
= -1;
3077 = x_get_arg (parms
, Qicon_name
, "iconName", "Title", string
);
3078 if (! STRINGP (f
->icon_name
))
3079 f
->icon_name
= Qnil
;
3081 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
3083 FRAME_KBOARD (f
) = kb
;
3086 /* Specify the parent under which to make this X window. */
3090 f
->output_data
.x
->parent_desc
= parent
;
3091 f
->output_data
.x
->explicit_parent
= 1;
3095 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3096 f
->output_data
.x
->explicit_parent
= 0;
3099 /* Note that the frame has no physical cursor right now. */
3100 f
->phys_cursor_x
= -1;
3102 /* Set the name; the functions to which we pass f expect the name to
3104 if (EQ (name
, Qunbound
) || NILP (name
))
3106 f
->name
= build_string (dpyinfo
->x_id_name
);
3107 f
->explicit_name
= 0;
3112 f
->explicit_name
= 1;
3113 /* use the frame's title when getting resources for this frame. */
3114 specbind (Qx_resource_name
, name
);
3117 /* Extract the window parameters from the supplied values
3118 that are needed to determine window geometry. */
3122 font
= x_get_arg (parms
, Qfont
, "font", "Font", string
);
3124 /* First, try whatever font the caller has specified. */
3126 font
= x_new_font (f
, XSTRING (font
)->data
);
3127 /* Try out a font which we hope has bold and italic variations. */
3128 if (!STRINGP (font
))
3129 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3130 if (! STRINGP (font
))
3131 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3132 if (! STRINGP (font
))
3133 /* This was formerly the first thing tried, but it finds too many fonts
3134 and takes too long. */
3135 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
3136 /* If those didn't work, look for something which will at least work. */
3137 if (! STRINGP (font
))
3138 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
3140 if (! STRINGP (font
))
3141 font
= build_string ("fixed");
3143 x_default_parameter (f
, parms
, Qfont
, font
,
3144 "font", "Font", string
);
3147 #ifdef USE_X_TOOLKIT
3148 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
3149 whereby it fails to get any font. */
3150 xlwmenu_default_font
= f
->output_data
.x
->font
;
3153 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
3154 "borderwidth", "BorderWidth", number
);
3155 /* This defaults to 2 in order to match xterm. We recognize either
3156 internalBorderWidth or internalBorder (which is what xterm calls
3158 if (NILP (Fassq (Qinternal_border_width
, parms
)))
3162 value
= x_get_arg (parms
, Qinternal_border_width
,
3163 "internalBorder", "BorderWidth", number
);
3164 if (! EQ (value
, Qunbound
))
3165 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
3168 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (2),
3169 "internalBorderWidth", "BorderWidth", number
);
3170 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qt
,
3171 "verticalScrollBars", "ScrollBars", boolean
);
3173 /* Also do the stuff which must be set before the window exists. */
3174 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
3175 "foreground", "Foreground", string
);
3176 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
3177 "background", "Background", string
);
3178 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
3179 "pointerColor", "Foreground", string
);
3180 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
3181 "cursorColor", "Foreground", string
);
3182 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
3183 "borderColor", "BorderColor", string
);
3185 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
3186 "menuBar", "MenuBar", number
);
3187 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
3188 "scrollBarWidth", "ScrollBarWidth", number
);
3189 x_default_parameter (f
, parms
, Qbuffer_predicate
, Qnil
,
3190 "bufferPredicate", "BufferPredicate", symbol
);
3191 x_default_parameter (f
, parms
, Qtitle
, Qnil
,
3192 "title", "Title", string
);
3194 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3195 window_prompting
= x_figure_window_size (f
, parms
);
3197 if (window_prompting
& XNegative
)
3199 if (window_prompting
& YNegative
)
3200 f
->output_data
.x
->win_gravity
= SouthEastGravity
;
3202 f
->output_data
.x
->win_gravity
= NorthEastGravity
;
3206 if (window_prompting
& YNegative
)
3207 f
->output_data
.x
->win_gravity
= SouthWestGravity
;
3209 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
3212 f
->output_data
.x
->size_hint_flags
= window_prompting
;
3214 #ifdef USE_X_TOOLKIT
3215 x_window (f
, window_prompting
, minibuffer_only
);
3221 init_frame_faces (f
);
3223 /* We need to do this after creating the X window, so that the
3224 icon-creation functions can say whose icon they're describing. */
3225 x_default_parameter (f
, parms
, Qicon_type
, Qnil
,
3226 "bitmapIcon", "BitmapIcon", symbol
);
3228 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
3229 "autoRaise", "AutoRaiseLower", boolean
);
3230 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
3231 "autoLower", "AutoRaiseLower", boolean
);
3232 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
3233 "cursorType", "CursorType", symbol
);
3235 /* Dimensions, especially f->height, must be done via change_frame_size.
3236 Change will not be effected unless different from the current
3240 f
->height
= f
->width
= 0;
3241 change_frame_size (f
, height
, width
, 1, 0);
3243 /* Tell the server what size and position, etc, we want,
3244 and how badly we want them. */
3246 x_wm_set_size_hint (f
, window_prompting
, 0);
3249 tem
= x_get_arg (parms
, Qunsplittable
, 0, 0, boolean
);
3250 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
3254 /* It is now ok to make the frame official
3255 even if we get an error below.
3256 And the frame needs to be on Vframe_list
3257 or making it visible won't work. */
3258 Vframe_list
= Fcons (frame
, Vframe_list
);
3260 /* Now that the frame is official, it counts as a reference to
3262 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
3264 /* Make the window appear on the frame and enable display,
3265 unless the caller says not to. However, with explicit parent,
3266 Emacs cannot control visibility, so don't try. */
3267 if (! f
->output_data
.x
->explicit_parent
)
3269 Lisp_Object visibility
;
3271 visibility
= x_get_arg (parms
, Qvisibility
, 0, 0, symbol
);
3272 if (EQ (visibility
, Qunbound
))
3275 if (EQ (visibility
, Qicon
))
3276 x_iconify_frame (f
);
3277 else if (! NILP (visibility
))
3278 x_make_frame_visible (f
);
3280 /* Must have been Qnil. */
3284 return unbind_to (count
, frame
);
3287 /* FRAME is used only to get a handle on the X display. We don't pass the
3288 display info directly because we're called from frame.c, which doesn't
3289 know about that structure. */
3291 x_get_focus_frame (frame
)
3292 struct frame
*frame
;
3294 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (frame
);
3296 if (! dpyinfo
->x_focus_frame
)
3299 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
3303 DEFUN ("focus-frame", Ffocus_frame
, Sfocus_frame
, 1, 1, 0,
3304 "This function is obsolete, and does nothing.")
3311 DEFUN ("unfocus-frame", Funfocus_frame
, Sunfocus_frame
, 0, 0, 0,
3312 "This function is obsolete, and does nothing.")
3318 DEFUN ("x-list-fonts", Fx_list_fonts
, Sx_list_fonts
, 1, 3, 0,
3319 "Return a list of the names of available fonts matching PATTERN.\n\
3320 If optional arguments FACE and FRAME are specified, return only fonts\n\
3321 the same size as FACE on FRAME.\n\
3323 PATTERN is a string, perhaps with wildcard characters;\n\
3324 the * character matches any substring, and\n\
3325 the ? character matches any single character.\n\
3326 PATTERN is case-insensitive.\n\
3327 FACE is a face name--a symbol.\n\
3329 The return value is a list of strings, suitable as arguments to\n\
3332 Fonts Emacs can't use (i.e. proportional fonts) may or may not be excluded\n\
3333 even if they match PATTERN and FACE.")
3334 (pattern
, face
, frame
)
3335 Lisp_Object pattern
, face
, frame
;
3339 #ifndef BROKEN_XLISTFONTSWITHINFO
3342 XFontStruct
*size_ref
;
3347 CHECK_STRING (pattern
, 0);
3349 CHECK_SYMBOL (face
, 1);
3351 f
= check_x_frame (frame
);
3353 /* Determine the width standard for comparison with the fonts we find. */
3361 /* Don't die if we get called with a terminal frame. */
3362 if (! FRAME_X_P (f
))
3363 error ("Non-X frame used in `x-list-fonts'");
3365 face_id
= face_name_id_number (f
, face
);
3367 if (face_id
< 0 || face_id
>= FRAME_N_PARAM_FACES (f
)
3368 || FRAME_PARAM_FACES (f
) [face_id
] == 0)
3369 size_ref
= f
->output_data
.x
->font
;
3372 size_ref
= FRAME_PARAM_FACES (f
) [face_id
]->font
;
3373 if (size_ref
== (XFontStruct
*) (~0))
3374 size_ref
= f
->output_data
.x
->font
;
3378 /* See if we cached the result for this particular query. */
3379 list
= Fassoc (pattern
,
3380 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
);
3382 /* We have info in the cache for this PATTERN. */
3385 Lisp_Object tem
, newlist
;
3387 /* We have info about this pattern. */
3388 list
= XCONS (list
)->cdr
;
3395 /* Filter the cached info and return just the fonts that match FACE. */
3397 for (tem
= list
; CONSP (tem
); tem
= XCONS (tem
)->cdr
)
3399 XFontStruct
*thisinfo
;
3401 x_catch_errors (FRAME_X_DISPLAY (f
));
3403 thisinfo
= XLoadQueryFont (FRAME_X_DISPLAY (f
),
3404 XSTRING (XCONS (tem
)->car
)->data
);
3406 x_check_errors (FRAME_X_DISPLAY (f
), "XLoadQueryFont failure: %s");
3407 x_uncatch_errors (FRAME_X_DISPLAY (f
));
3409 if (thisinfo
&& same_size_fonts (thisinfo
, size_ref
))
3410 newlist
= Fcons (XCONS (tem
)->car
, newlist
);
3413 XFreeFont (FRAME_X_DISPLAY (f
), thisinfo
);
3423 x_catch_errors (FRAME_X_DISPLAY (f
));
3425 /* Solaris 2.3 has a bug in XListFontsWithInfo. */
3426 #ifndef BROKEN_XLISTFONTSWITHINFO
3428 names
= XListFontsWithInfo (FRAME_X_DISPLAY (f
),
3429 XSTRING (pattern
)->data
,
3430 2000, /* maxnames */
3431 &num_fonts
, /* count_return */
3432 &info
); /* info_return */
3435 names
= XListFonts (FRAME_X_DISPLAY (f
),
3436 XSTRING (pattern
)->data
,
3437 2000, /* maxnames */
3438 &num_fonts
); /* count_return */
3440 x_check_errors (FRAME_X_DISPLAY (f
), "XListFonts failure: %s");
3441 x_uncatch_errors (FRAME_X_DISPLAY (f
));
3450 Lisp_Object full_list
;
3452 /* Make a list of all the fonts we got back.
3453 Store that in the font cache for the display. */
3455 for (i
= 0; i
< num_fonts
; i
++)
3456 full_list
= Fcons (build_string (names
[i
]), full_list
);
3457 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
3458 = Fcons (Fcons (pattern
, full_list
),
3459 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
);
3461 /* Make a list of the fonts that have the right width. */
3463 for (i
= 0; i
< num_fonts
; i
++)
3471 #ifdef BROKEN_XLISTFONTSWITHINFO
3472 XFontStruct
*thisinfo
;
3476 x_catch_errors (FRAME_X_DISPLAY (f
));
3477 thisinfo
= XLoadQueryFont (FRAME_X_DISPLAY (f
), names
[i
]);
3478 x_check_errors (FRAME_X_DISPLAY (f
),
3479 "XLoadQueryFont failure: %s");
3480 x_uncatch_errors (FRAME_X_DISPLAY (f
));
3484 keeper
= thisinfo
&& same_size_fonts (thisinfo
, size_ref
);
3486 if (thisinfo
&& ! keeper
)
3487 XFreeFont (FRAME_X_DISPLAY (f
), thisinfo
);
3489 XFreeFontInfo (NULL
, thisinfo
, 1);
3492 keeper
= same_size_fonts (&info
[i
], size_ref
);
3496 list
= Fcons (build_string (names
[i
]), list
);
3498 list
= Fnreverse (list
);
3501 #ifndef BROKEN_XLISTFONTSWITHINFO
3503 XFreeFontInfo (names
, info
, num_fonts
);
3506 XFreeFontNames (names
);
3514 DEFUN ("x-color-defined-p", Fx_color_defined_p
, Sx_color_defined_p
, 1, 2, 0,
3515 "Return non-nil if color COLOR is supported on frame FRAME.\n\
3516 If FRAME is omitted or nil, use the selected frame.")
3518 Lisp_Object color
, frame
;
3521 FRAME_PTR f
= check_x_frame (frame
);
3523 CHECK_STRING (color
, 1);
3525 if (defined_color (f
, XSTRING (color
)->data
, &foo
, 0))
3531 DEFUN ("x-color-values", Fx_color_values
, Sx_color_values
, 1, 2, 0,
3532 "Return a description of the color named COLOR on frame FRAME.\n\
3533 The value is a list of integer RGB values--(RED GREEN BLUE).\n\
3534 These values appear to range from 0 to 65280 or 65535, depending\n\
3535 on the system; white is (65280 65280 65280) or (65535 65535 65535).\n\
3536 If FRAME is omitted or nil, use the selected frame.")
3538 Lisp_Object color
, frame
;
3541 FRAME_PTR f
= check_x_frame (frame
);
3543 CHECK_STRING (color
, 1);
3545 if (defined_color (f
, XSTRING (color
)->data
, &foo
, 0))
3549 rgb
[0] = make_number (foo
.red
);
3550 rgb
[1] = make_number (foo
.green
);
3551 rgb
[2] = make_number (foo
.blue
);
3552 return Flist (3, rgb
);
3558 DEFUN ("x-display-color-p", Fx_display_color_p
, Sx_display_color_p
, 0, 1, 0,
3559 "Return t if the X display supports color.\n\
3560 The optional argument DISPLAY specifies which display to ask about.\n\
3561 DISPLAY should be either a frame or a display name (a string).\n\
3562 If omitted or nil, that stands for the selected frame's display.")
3564 Lisp_Object display
;
3566 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3568 if (dpyinfo
->n_planes
<= 2)
3571 switch (dpyinfo
->visual
->class)
3584 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
3586 "Return t if the X display supports shades of gray.\n\
3587 Note that color displays do support shades of gray.\n\
3588 The optional argument DISPLAY specifies which display to ask about.\n\
3589 DISPLAY should be either a frame or a display name (a string).\n\
3590 If omitted or nil, that stands for the selected frame's display.")
3592 Lisp_Object display
;
3594 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3596 if (dpyinfo
->n_planes
<= 1)
3599 switch (dpyinfo
->visual
->class)
3614 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
3616 "Returns the width in pixels of the X display DISPLAY.\n\
3617 The optional argument DISPLAY specifies which display to ask about.\n\
3618 DISPLAY should be either a frame or a display name (a string).\n\
3619 If omitted or nil, that stands for the selected frame's display.")
3621 Lisp_Object display
;
3623 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3625 return make_number (dpyinfo
->width
);
3628 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
3629 Sx_display_pixel_height
, 0, 1, 0,
3630 "Returns the height in pixels of the X display DISPLAY.\n\
3631 The optional argument DISPLAY specifies which display to ask about.\n\
3632 DISPLAY should be either a frame or a display name (a string).\n\
3633 If omitted or nil, that stands for the selected frame's display.")
3635 Lisp_Object display
;
3637 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3639 return make_number (dpyinfo
->height
);
3642 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
3644 "Returns the number of bitplanes of the X display DISPLAY.\n\
3645 The optional argument DISPLAY specifies which display to ask about.\n\
3646 DISPLAY should be either a frame or a display name (a string).\n\
3647 If omitted or nil, that stands for the selected frame's display.")
3649 Lisp_Object display
;
3651 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3653 return make_number (dpyinfo
->n_planes
);
3656 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
3658 "Returns the number of color cells of the X display DISPLAY.\n\
3659 The optional argument DISPLAY specifies which display to ask about.\n\
3660 DISPLAY should be either a frame or a display name (a string).\n\
3661 If omitted or nil, that stands for the selected frame's display.")
3663 Lisp_Object display
;
3665 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3667 return make_number (DisplayCells (dpyinfo
->display
,
3668 XScreenNumberOfScreen (dpyinfo
->screen
)));
3671 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
3672 Sx_server_max_request_size
,
3674 "Returns the maximum request size of the X server of display DISPLAY.\n\
3675 The optional argument DISPLAY specifies which display to ask about.\n\
3676 DISPLAY should be either a frame or a display name (a string).\n\
3677 If omitted or nil, that stands for the selected frame's display.")
3679 Lisp_Object display
;
3681 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3683 return make_number (MAXREQUEST (dpyinfo
->display
));
3686 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
3687 "Returns the vendor ID string of the X server of display DISPLAY.\n\
3688 The optional argument DISPLAY specifies which display to ask about.\n\
3689 DISPLAY should be either a frame or a display name (a string).\n\
3690 If omitted or nil, that stands for the selected frame's display.")
3692 Lisp_Object display
;
3694 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3695 char *vendor
= ServerVendor (dpyinfo
->display
);
3697 if (! vendor
) vendor
= "";
3698 return build_string (vendor
);
3701 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
3702 "Returns the version numbers of the X server of display DISPLAY.\n\
3703 The value is a list of three integers: the major and minor\n\
3704 version numbers of the X Protocol in use, and the vendor-specific release\n\
3705 number. See also the function `x-server-vendor'.\n\n\
3706 The optional argument DISPLAY specifies which display to ask about.\n\
3707 DISPLAY should be either a frame or a display name (a string).\n\
3708 If omitted or nil, that stands for the selected frame's display.")
3710 Lisp_Object display
;
3712 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3713 Display
*dpy
= dpyinfo
->display
;
3715 return Fcons (make_number (ProtocolVersion (dpy
)),
3716 Fcons (make_number (ProtocolRevision (dpy
)),
3717 Fcons (make_number (VendorRelease (dpy
)), Qnil
)));
3720 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
3721 "Returns the number of screens on the X server of display DISPLAY.\n\
3722 The optional argument DISPLAY specifies which display to ask about.\n\
3723 DISPLAY should be either a frame or a display name (a string).\n\
3724 If omitted or nil, that stands for the selected frame's display.")
3726 Lisp_Object display
;
3728 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3730 return make_number (ScreenCount (dpyinfo
->display
));
3733 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
3734 "Returns the height in millimeters of the X display DISPLAY.\n\
3735 The optional argument DISPLAY specifies which display to ask about.\n\
3736 DISPLAY should be either a frame or a display name (a string).\n\
3737 If omitted or nil, that stands for the selected frame's display.")
3739 Lisp_Object display
;
3741 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3743 return make_number (HeightMMOfScreen (dpyinfo
->screen
));
3746 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
3747 "Returns the width in millimeters of the X display DISPLAY.\n\
3748 The optional argument DISPLAY specifies which display to ask about.\n\
3749 DISPLAY should be either a frame or a display name (a string).\n\
3750 If omitted or nil, that stands for the selected frame's display.")
3752 Lisp_Object display
;
3754 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3756 return make_number (WidthMMOfScreen (dpyinfo
->screen
));
3759 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
3760 Sx_display_backing_store
, 0, 1, 0,
3761 "Returns an indication of whether X display DISPLAY does backing store.\n\
3762 The value may be `always', `when-mapped', or `not-useful'.\n\
3763 The optional argument DISPLAY specifies which display to ask about.\n\
3764 DISPLAY should be either a frame or a display name (a string).\n\
3765 If omitted or nil, that stands for the selected frame's display.")
3767 Lisp_Object display
;
3769 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3771 switch (DoesBackingStore (dpyinfo
->screen
))
3774 return intern ("always");
3777 return intern ("when-mapped");
3780 return intern ("not-useful");
3783 error ("Strange value for BackingStore parameter of screen");
3787 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
3788 Sx_display_visual_class
, 0, 1, 0,
3789 "Returns the visual class of the X display DISPLAY.\n\
3790 The value is one of the symbols `static-gray', `gray-scale',\n\
3791 `static-color', `pseudo-color', `true-color', or `direct-color'.\n\n\
3792 The optional argument DISPLAY specifies which display to ask about.\n\
3793 DISPLAY should be either a frame or a display name (a string).\n\
3794 If omitted or nil, that stands for the selected frame's display.")
3796 Lisp_Object display
;
3798 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3800 switch (dpyinfo
->visual
->class)
3802 case StaticGray
: return (intern ("static-gray"));
3803 case GrayScale
: return (intern ("gray-scale"));
3804 case StaticColor
: return (intern ("static-color"));
3805 case PseudoColor
: return (intern ("pseudo-color"));
3806 case TrueColor
: return (intern ("true-color"));
3807 case DirectColor
: return (intern ("direct-color"));
3809 error ("Display has an unknown visual class");
3813 DEFUN ("x-display-save-under", Fx_display_save_under
,
3814 Sx_display_save_under
, 0, 1, 0,
3815 "Returns t if the X display DISPLAY supports the save-under feature.\n\
3816 The optional argument DISPLAY specifies which display to ask about.\n\
3817 DISPLAY should be either a frame or a display name (a string).\n\
3818 If omitted or nil, that stands for the selected frame's display.")
3820 Lisp_Object display
;
3822 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3824 if (DoesSaveUnders (dpyinfo
->screen
) == True
)
3832 register struct frame
*f
;
3834 return PIXEL_WIDTH (f
);
3839 register struct frame
*f
;
3841 return PIXEL_HEIGHT (f
);
3846 register struct frame
*f
;
3848 return FONT_WIDTH (f
->output_data
.x
->font
);
3853 register struct frame
*f
;
3855 return f
->output_data
.x
->line_height
;
3859 x_screen_planes (frame
)
3862 return FRAME_X_DISPLAY_INFO (XFRAME (frame
))->n_planes
;
3865 #if 0 /* These no longer seem like the right way to do things. */
3867 /* Draw a rectangle on the frame with left top corner including
3868 the character specified by LEFT_CHAR and TOP_CHAR. The rectangle is
3869 CHARS by LINES wide and long and is the color of the cursor. */
3872 x_rectangle (f
, gc
, left_char
, top_char
, chars
, lines
)
3873 register struct frame
*f
;
3875 register int top_char
, left_char
, chars
, lines
;
3879 int left
= (left_char
* FONT_WIDTH (f
->output_data
.x
->font
)
3880 + f
->output_data
.x
->internal_border_width
);
3881 int top
= (top_char
* f
->output_data
.x
->line_height
3882 + f
->output_data
.x
->internal_border_width
);
3885 width
= FONT_WIDTH (f
->output_data
.x
->font
) / 2;
3887 width
= FONT_WIDTH (f
->output_data
.x
->font
) * chars
;
3889 height
= f
->output_data
.x
->line_height
/ 2;
3891 height
= f
->output_data
.x
->line_height
* lines
;
3893 XDrawRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3894 gc
, left
, top
, width
, height
);
3897 DEFUN ("x-draw-rectangle", Fx_draw_rectangle
, Sx_draw_rectangle
, 5, 5, 0,
3898 "Draw a rectangle on FRAME between coordinates specified by\n\
3899 numbers X0, Y0, X1, Y1 in the cursor pixel.")
3900 (frame
, X0
, Y0
, X1
, Y1
)
3901 register Lisp_Object frame
, X0
, X1
, Y0
, Y1
;
3903 register int x0
, y0
, x1
, y1
, top
, left
, n_chars
, n_lines
;
3905 CHECK_LIVE_FRAME (frame
, 0);
3906 CHECK_NUMBER (X0
, 0);
3907 CHECK_NUMBER (Y0
, 1);
3908 CHECK_NUMBER (X1
, 2);
3909 CHECK_NUMBER (Y1
, 3);
3919 n_lines
= y1
- y0
+ 1;
3924 n_lines
= y0
- y1
+ 1;
3930 n_chars
= x1
- x0
+ 1;
3935 n_chars
= x0
- x1
+ 1;
3939 x_rectangle (XFRAME (frame
), XFRAME (frame
)->output_data
.x
->cursor_gc
,
3940 left
, top
, n_chars
, n_lines
);
3946 DEFUN ("x-erase-rectangle", Fx_erase_rectangle
, Sx_erase_rectangle
, 5, 5, 0,
3947 "Draw a rectangle drawn on FRAME between coordinates\n\
3948 X0, Y0, X1, Y1 in the regular background-pixel.")
3949 (frame
, X0
, Y0
, X1
, Y1
)
3950 register Lisp_Object frame
, X0
, Y0
, X1
, Y1
;
3952 register int x0
, y0
, x1
, y1
, top
, left
, n_chars
, n_lines
;
3954 CHECK_LIVE_FRAME (frame
, 0);
3955 CHECK_NUMBER (X0
, 0);
3956 CHECK_NUMBER (Y0
, 1);
3957 CHECK_NUMBER (X1
, 2);
3958 CHECK_NUMBER (Y1
, 3);
3968 n_lines
= y1
- y0
+ 1;
3973 n_lines
= y0
- y1
+ 1;
3979 n_chars
= x1
- x0
+ 1;
3984 n_chars
= x0
- x1
+ 1;
3988 x_rectangle (XFRAME (frame
), XFRAME (frame
)->output_data
.x
->reverse_gc
,
3989 left
, top
, n_chars
, n_lines
);
3995 /* Draw lines around the text region beginning at the character position
3996 TOP_X, TOP_Y and ending at BOTTOM_X and BOTTOM_Y. GC specifies the
3997 pixel and line characteristics. */
3999 #define line_len(line) (FRAME_CURRENT_GLYPHS (f)->used[(line)])
4002 outline_region (f
, gc
, top_x
, top_y
, bottom_x
, bottom_y
)
4003 register struct frame
*f
;
4005 int top_x
, top_y
, bottom_x
, bottom_y
;
4007 register int ibw
= f
->output_data
.x
->internal_border_width
;
4008 register int font_w
= FONT_WIDTH (f
->output_data
.x
->font
);
4009 register int font_h
= f
->output_data
.x
->line_height
;
4011 int x
= line_len (y
);
4012 XPoint
*pixel_points
4013 = (XPoint
*) alloca (((bottom_y
- top_y
+ 2) * 4) * sizeof (XPoint
));
4014 register XPoint
*this_point
= pixel_points
;
4016 /* Do the horizontal top line/lines */
4019 this_point
->x
= ibw
;
4020 this_point
->y
= ibw
+ (font_h
* top_y
);
4023 this_point
->x
= ibw
+ (font_w
/ 2); /* Half-size for newline chars. */
4025 this_point
->x
= ibw
+ (font_w
* x
);
4026 this_point
->y
= (this_point
- 1)->y
;
4030 this_point
->x
= ibw
;
4031 this_point
->y
= ibw
+ (font_h
* (top_y
+ 1));
4033 this_point
->x
= ibw
+ (font_w
* top_x
);
4034 this_point
->y
= (this_point
- 1)->y
;
4036 this_point
->x
= (this_point
- 1)->x
;
4037 this_point
->y
= ibw
+ (font_h
* top_y
);
4039 this_point
->x
= ibw
+ (font_w
* x
);
4040 this_point
->y
= (this_point
- 1)->y
;
4043 /* Now do the right side. */
4044 while (y
< bottom_y
)
4045 { /* Right vertical edge */
4047 this_point
->x
= (this_point
- 1)->x
;
4048 this_point
->y
= ibw
+ (font_h
* (y
+ 1));
4051 y
++; /* Horizontal connection to next line */
4054 this_point
->x
= ibw
+ (font_w
/ 2);
4056 this_point
->x
= ibw
+ (font_w
* x
);
4058 this_point
->y
= (this_point
- 1)->y
;
4061 /* Now do the bottom and connect to the top left point. */
4062 this_point
->x
= ibw
+ (font_w
* (bottom_x
+ 1));
4065 this_point
->x
= (this_point
- 1)->x
;
4066 this_point
->y
= ibw
+ (font_h
* (bottom_y
+ 1));
4068 this_point
->x
= ibw
;
4069 this_point
->y
= (this_point
- 1)->y
;
4071 this_point
->x
= pixel_points
->x
;
4072 this_point
->y
= pixel_points
->y
;
4074 XDrawLines (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4076 (this_point
- pixel_points
+ 1), CoordModeOrigin
);
4079 DEFUN ("x-contour-region", Fx_contour_region
, Sx_contour_region
, 1, 1, 0,
4080 "Highlight the region between point and the character under the mouse\n\
4083 register Lisp_Object event
;
4085 register int x0
, y0
, x1
, y1
;
4086 register struct frame
*f
= selected_frame
;
4087 register int p1
, p2
;
4089 CHECK_CONS (event
, 0);
4092 x0
= XINT (Fcar (Fcar (event
)));
4093 y0
= XINT (Fcar (Fcdr (Fcar (event
))));
4095 /* If the mouse is past the end of the line, don't that area. */
4096 /* ReWrite this... */
4101 if (y1
> y0
) /* point below mouse */
4102 outline_region (f
, f
->output_data
.x
->cursor_gc
,
4104 else if (y1
< y0
) /* point above mouse */
4105 outline_region (f
, f
->output_data
.x
->cursor_gc
,
4107 else /* same line: draw horizontal rectangle */
4110 x_rectangle (f
, f
->output_data
.x
->cursor_gc
,
4111 x0
, y0
, (x1
- x0
+ 1), 1);
4113 x_rectangle (f
, f
->output_data
.x
->cursor_gc
,
4114 x1
, y1
, (x0
- x1
+ 1), 1);
4117 XFlush (FRAME_X_DISPLAY (f
));
4123 DEFUN ("x-uncontour-region", Fx_uncontour_region
, Sx_uncontour_region
, 1, 1, 0,
4124 "Erase any highlighting of the region between point and the character\n\
4125 at X, Y on the selected frame.")
4127 register Lisp_Object event
;
4129 register int x0
, y0
, x1
, y1
;
4130 register struct frame
*f
= selected_frame
;
4133 x0
= XINT (Fcar (Fcar (event
)));
4134 y0
= XINT (Fcar (Fcdr (Fcar (event
))));
4138 if (y1
> y0
) /* point below mouse */
4139 outline_region (f
, f
->output_data
.x
->reverse_gc
,
4141 else if (y1
< y0
) /* point above mouse */
4142 outline_region (f
, f
->output_data
.x
->reverse_gc
,
4144 else /* same line: draw horizontal rectangle */
4147 x_rectangle (f
, f
->output_data
.x
->reverse_gc
,
4148 x0
, y0
, (x1
- x0
+ 1), 1);
4150 x_rectangle (f
, f
->output_data
.x
->reverse_gc
,
4151 x1
, y1
, (x0
- x1
+ 1), 1);
4159 int contour_begin_x
, contour_begin_y
;
4160 int contour_end_x
, contour_end_y
;
4161 int contour_npoints
;
4163 /* Clip the top part of the contour lines down (and including) line Y_POS.
4164 If X_POS is in the middle (rather than at the end) of the line, drop
4165 down a line at that character. */
4168 clip_contour_top (y_pos
, x_pos
)
4170 register XPoint
*begin
= contour_lines
[y_pos
].top_left
;
4171 register XPoint
*end
;
4172 register int npoints
;
4173 register struct display_line
*line
= selected_frame
->phys_lines
[y_pos
+ 1];
4175 if (x_pos
>= line
->len
- 1) /* Draw one, straight horizontal line. */
4177 end
= contour_lines
[y_pos
].top_right
;
4178 npoints
= (end
- begin
+ 1);
4179 XDrawLines (x_current_display
, contour_window
,
4180 contour_erase_gc
, begin_erase
, npoints
, CoordModeOrigin
);
4182 bcopy (end
, begin
+ 1, contour_last_point
- end
+ 1);
4183 contour_last_point
-= (npoints
- 2);
4184 XDrawLines (x_current_display
, contour_window
,
4185 contour_erase_gc
, begin
, 2, CoordModeOrigin
);
4186 XFlush (x_current_display
);
4188 /* Now, update contour_lines structure. */
4193 register XPoint
*p
= begin
+ 1;
4194 end
= contour_lines
[y_pos
].bottom_right
;
4195 npoints
= (end
- begin
+ 1);
4196 XDrawLines (x_current_display
, contour_window
,
4197 contour_erase_gc
, begin_erase
, npoints
, CoordModeOrigin
);
4200 p
->x
= ibw
+ (font_w
* (x_pos
+ 1));
4202 p
->y
= begin
->y
+ font_h
;
4204 bcopy (end
, begin
+ 3, contour_last_point
- end
+ 1);
4205 contour_last_point
-= (npoints
- 5);
4206 XDrawLines (x_current_display
, contour_window
,
4207 contour_erase_gc
, begin
, 4, CoordModeOrigin
);
4208 XFlush (x_current_display
);
4210 /* Now, update contour_lines structure. */
4214 /* Erase the top horizontal lines of the contour, and then extend
4215 the contour upwards. */
4218 extend_contour_top (line
)
4223 clip_contour_bottom (x_pos
, y_pos
)
4229 extend_contour_bottom (x_pos
, y_pos
)
4233 DEFUN ("x-select-region", Fx_select_region
, Sx_select_region
, 1, 1, "e",
4238 register struct frame
*f
= selected_frame
;
4239 register int point_x
= f
->cursor_x
;
4240 register int point_y
= f
->cursor_y
;
4241 register int mouse_below_point
;
4242 register Lisp_Object obj
;
4243 register int x_contour_x
, x_contour_y
;
4245 x_contour_x
= x_mouse_x
;
4246 x_contour_y
= x_mouse_y
;
4247 if (x_contour_y
> point_y
|| (x_contour_y
== point_y
4248 && x_contour_x
> point_x
))
4250 mouse_below_point
= 1;
4251 outline_region (f
, f
->output_data
.x
->cursor_gc
, point_x
, point_y
,
4252 x_contour_x
, x_contour_y
);
4256 mouse_below_point
= 0;
4257 outline_region (f
, f
->output_data
.x
->cursor_gc
, x_contour_x
, x_contour_y
,
4263 obj
= read_char (-1, 0, 0, Qnil
, 0);
4267 if (mouse_below_point
)
4269 if (x_mouse_y
<= point_y
) /* Flipped. */
4271 mouse_below_point
= 0;
4273 outline_region (f
, f
->output_data
.x
->reverse_gc
, point_x
, point_y
,
4274 x_contour_x
, x_contour_y
);
4275 outline_region (f
, f
->output_data
.x
->cursor_gc
, x_mouse_x
, x_mouse_y
,
4278 else if (x_mouse_y
< x_contour_y
) /* Bottom clipped. */
4280 clip_contour_bottom (x_mouse_y
);
4282 else if (x_mouse_y
> x_contour_y
) /* Bottom extended. */
4284 extend_bottom_contour (x_mouse_y
);
4287 x_contour_x
= x_mouse_x
;
4288 x_contour_y
= x_mouse_y
;
4290 else /* mouse above or same line as point */
4292 if (x_mouse_y
>= point_y
) /* Flipped. */
4294 mouse_below_point
= 1;
4296 outline_region (f
, f
->output_data
.x
->reverse_gc
,
4297 x_contour_x
, x_contour_y
, point_x
, point_y
);
4298 outline_region (f
, f
->output_data
.x
->cursor_gc
, point_x
, point_y
,
4299 x_mouse_x
, x_mouse_y
);
4301 else if (x_mouse_y
> x_contour_y
) /* Top clipped. */
4303 clip_contour_top (x_mouse_y
);
4305 else if (x_mouse_y
< x_contour_y
) /* Top extended. */
4307 extend_contour_top (x_mouse_y
);
4312 unread_command_event
= obj
;
4313 if (mouse_below_point
)
4315 contour_begin_x
= point_x
;
4316 contour_begin_y
= point_y
;
4317 contour_end_x
= x_contour_x
;
4318 contour_end_y
= x_contour_y
;
4322 contour_begin_x
= x_contour_x
;
4323 contour_begin_y
= x_contour_y
;
4324 contour_end_x
= point_x
;
4325 contour_end_y
= point_y
;
4330 DEFUN ("x-horizontal-line", Fx_horizontal_line
, Sx_horizontal_line
, 1, 1, "e",
4335 register Lisp_Object obj
;
4336 struct frame
*f
= selected_frame
;
4337 register struct window
*w
= XWINDOW (selected_window
);
4338 register GC line_gc
= f
->output_data
.x
->cursor_gc
;
4339 register GC erase_gc
= f
->output_data
.x
->reverse_gc
;
4341 char dash_list
[] = {6, 4, 6, 4};
4343 XGCValues gc_values
;
4345 register int previous_y
;
4346 register int line
= (x_mouse_y
+ 1) * f
->output_data
.x
->line_height
4347 + f
->output_data
.x
->internal_border_width
;
4348 register int left
= f
->output_data
.x
->internal_border_width
4350 * FONT_WIDTH (f
->output_data
.x
->font
));
4351 register int right
= left
+ (w
->width
4352 * FONT_WIDTH (f
->output_data
.x
->font
))
4353 - f
->output_data
.x
->internal_border_width
;
4357 gc_values
.foreground
= f
->output_data
.x
->cursor_pixel
;
4358 gc_values
.background
= f
->output_data
.x
->background_pixel
;
4359 gc_values
.line_width
= 1;
4360 gc_values
.line_style
= LineOnOffDash
;
4361 gc_values
.cap_style
= CapRound
;
4362 gc_values
.join_style
= JoinRound
;
4364 line_gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4365 GCLineStyle
| GCJoinStyle
| GCCapStyle
4366 | GCLineWidth
| GCForeground
| GCBackground
,
4368 XSetDashes (FRAME_X_DISPLAY (f
), line_gc
, 0, dash_list
, dashes
);
4369 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
4370 gc_values
.background
= f
->output_data
.x
->foreground_pixel
;
4371 erase_gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4372 GCLineStyle
| GCJoinStyle
| GCCapStyle
4373 | GCLineWidth
| GCForeground
| GCBackground
,
4375 XSetDashes (FRAME_X_DISPLAY (f
), erase_gc
, 0, dash_list
, dashes
);
4382 if (x_mouse_y
>= XINT (w
->top
)
4383 && x_mouse_y
< XINT (w
->top
) + XINT (w
->height
) - 1)
4385 previous_y
= x_mouse_y
;
4386 line
= (x_mouse_y
+ 1) * f
->output_data
.x
->line_height
4387 + f
->output_data
.x
->internal_border_width
;
4388 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4389 line_gc
, left
, line
, right
, line
);
4391 XFlush (FRAME_X_DISPLAY (f
));
4396 obj
= read_char (-1, 0, 0, Qnil
, 0);
4398 || (! EQ (Fcar (Fcdr (Fcdr (obj
))),
4399 Qvertical_scroll_bar
))
4403 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4404 erase_gc
, left
, line
, right
, line
);
4405 unread_command_event
= obj
;
4407 XFreeGC (FRAME_X_DISPLAY (f
), line_gc
);
4408 XFreeGC (FRAME_X_DISPLAY (f
), erase_gc
);
4414 while (x_mouse_y
== previous_y
);
4417 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4418 erase_gc
, left
, line
, right
, line
);
4425 /* These keep track of the rectangle following the pointer. */
4426 int mouse_track_top
, mouse_track_left
, mouse_track_width
;
4428 /* Offset in buffer of character under the pointer, or 0. */
4429 int mouse_buffer_offset
;
4431 DEFUN ("x-track-pointer", Fx_track_pointer
, Sx_track_pointer
, 0, 0, 0,
4432 "Track the pointer.")
4435 static Cursor current_pointer_shape
;
4436 FRAME_PTR f
= x_mouse_frame
;
4439 if (EQ (Vmouse_frame_part
, Qtext_part
)
4440 && (current_pointer_shape
!= f
->output_data
.x
->nontext_cursor
))
4445 current_pointer_shape
= f
->output_data
.x
->nontext_cursor
;
4446 XDefineCursor (FRAME_X_DISPLAY (f
),
4448 current_pointer_shape
);
4450 buf
= XBUFFER (XWINDOW (Vmouse_window
)->buffer
);
4451 c
= *(BUF_CHAR_ADDRESS (buf
, mouse_buffer_offset
));
4453 else if (EQ (Vmouse_frame_part
, Qmodeline_part
)
4454 && (current_pointer_shape
!= f
->output_data
.x
->modeline_cursor
))
4456 current_pointer_shape
= f
->output_data
.x
->modeline_cursor
;
4457 XDefineCursor (FRAME_X_DISPLAY (f
),
4459 current_pointer_shape
);
4462 XFlush (FRAME_X_DISPLAY (f
));
4468 DEFUN ("x-track-pointer", Fx_track_pointer
, Sx_track_pointer
, 1, 1, "e",
4469 "Draw rectangle around character under mouse pointer, if there is one.")
4473 struct window
*w
= XWINDOW (Vmouse_window
);
4474 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4475 struct buffer
*b
= XBUFFER (w
->buffer
);
4478 if (! EQ (Vmouse_window
, selected_window
))
4481 if (EQ (event
, Qnil
))
4485 x_read_mouse_position (selected_frame
, &x
, &y
);
4489 mouse_track_width
= 0;
4490 mouse_track_left
= mouse_track_top
= -1;
4494 if ((x_mouse_x
!= mouse_track_left
4495 && (x_mouse_x
< mouse_track_left
4496 || x_mouse_x
> (mouse_track_left
+ mouse_track_width
)))
4497 || x_mouse_y
!= mouse_track_top
)
4499 int hp
= 0; /* Horizontal position */
4500 int len
= FRAME_CURRENT_GLYPHS (f
)->used
[x_mouse_y
];
4501 int p
= FRAME_CURRENT_GLYPHS (f
)->bufp
[x_mouse_y
];
4502 int tab_width
= XINT (b
->tab_width
);
4503 int ctl_arrow_p
= !NILP (b
->ctl_arrow
);
4505 int mode_line_vpos
= XFASTINT (w
->height
) + XFASTINT (w
->top
) - 1;
4506 int in_mode_line
= 0;
4508 if (! FRAME_CURRENT_GLYPHS (f
)->enable
[x_mouse_y
])
4511 /* Erase previous rectangle. */
4512 if (mouse_track_width
)
4514 x_rectangle (f
, f
->output_data
.x
->reverse_gc
,
4515 mouse_track_left
, mouse_track_top
,
4516 mouse_track_width
, 1);
4518 if ((mouse_track_left
== f
->phys_cursor_x
4519 || mouse_track_left
== f
->phys_cursor_x
- 1)
4520 && mouse_track_top
== f
->phys_cursor_y
)
4522 x_display_cursor (f
, 1);
4526 mouse_track_left
= x_mouse_x
;
4527 mouse_track_top
= x_mouse_y
;
4528 mouse_track_width
= 0;
4530 if (mouse_track_left
> len
) /* Past the end of line. */
4533 if (mouse_track_top
== mode_line_vpos
)
4539 if (tab_width
<= 0 || tab_width
> 20) tab_width
= 8;
4543 if (len
== f
->width
&& hp
== len
- 1 && c
!= '\n')
4549 mouse_track_width
= tab_width
- (hp
% tab_width
);
4551 hp
+= mouse_track_width
;
4554 mouse_track_left
= hp
- mouse_track_width
;
4560 mouse_track_width
= -1;
4564 if (ctl_arrow_p
&& (c
< 040 || c
== 0177))
4569 mouse_track_width
= 2;
4574 mouse_track_left
= hp
- mouse_track_width
;
4580 mouse_track_width
= 1;
4587 while (hp
<= x_mouse_x
);
4590 if (mouse_track_width
) /* Over text; use text pointer shape. */
4592 XDefineCursor (FRAME_X_DISPLAY (f
),
4594 f
->output_data
.x
->text_cursor
);
4595 x_rectangle (f
, f
->output_data
.x
->cursor_gc
,
4596 mouse_track_left
, mouse_track_top
,
4597 mouse_track_width
, 1);
4599 else if (in_mode_line
)
4600 XDefineCursor (FRAME_X_DISPLAY (f
),
4602 f
->output_data
.x
->modeline_cursor
);
4604 XDefineCursor (FRAME_X_DISPLAY (f
),
4606 f
->output_data
.x
->nontext_cursor
);
4609 XFlush (FRAME_X_DISPLAY (f
));
4612 obj
= read_char (-1, 0, 0, Qnil
, 0);
4615 while (CONSP (obj
) /* Mouse event */
4616 && EQ (Fcar (Fcdr (Fcdr (obj
))), Qnil
) /* Not scroll bar */
4617 && EQ (Vmouse_depressed
, Qnil
) /* Only motion events */
4618 && EQ (Vmouse_window
, selected_window
) /* In this window */
4621 unread_command_event
= obj
;
4623 if (mouse_track_width
)
4625 x_rectangle (f
, f
->output_data
.x
->reverse_gc
,
4626 mouse_track_left
, mouse_track_top
,
4627 mouse_track_width
, 1);
4628 mouse_track_width
= 0;
4629 if ((mouse_track_left
== f
->phys_cursor_x
4630 || mouse_track_left
- 1 == f
->phys_cursor_x
)
4631 && mouse_track_top
== f
->phys_cursor_y
)
4633 x_display_cursor (f
, 1);
4636 XDefineCursor (FRAME_X_DISPLAY (f
),
4638 f
->output_data
.x
->nontext_cursor
);
4639 XFlush (FRAME_X_DISPLAY (f
));
4649 /* Draw a pixmap specified by IMAGE_DATA of dimensions WIDTH and HEIGHT
4650 on the frame F at position X, Y. */
4652 x_draw_pixmap (f
, x
, y
, image_data
, width
, height
)
4654 int x
, y
, width
, height
;
4659 image
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
4660 FRAME_X_WINDOW (f
), image_data
,
4662 XCopyPlane (FRAME_X_DISPLAY (f
), image
, FRAME_X_WINDOW (f
),
4663 f
->output_data
.x
->normal_gc
, 0, 0, width
, height
, x
, y
);
4667 #if 0 /* I'm told these functions are superfluous
4668 given the ability to bind function keys. */
4671 DEFUN ("x-rebind-key", Fx_rebind_key
, Sx_rebind_key
, 3, 3, 0,
4672 "Rebind X keysym KEYSYM, with MODIFIERS, to generate NEWSTRING.\n\
4673 KEYSYM is a string which conforms to the X keysym definitions found\n\
4674 in X11/keysymdef.h, sans the initial XK_. MODIFIERS is nil or a\n\
4675 list of strings specifying modifier keys such as Control_L, which must\n\
4676 also be depressed for NEWSTRING to appear.")
4677 (x_keysym
, modifiers
, newstring
)
4678 register Lisp_Object x_keysym
;
4679 register Lisp_Object modifiers
;
4680 register Lisp_Object newstring
;
4683 register KeySym keysym
;
4684 KeySym modifier_list
[16];
4687 CHECK_STRING (x_keysym
, 1);
4688 CHECK_STRING (newstring
, 3);
4690 keysym
= XStringToKeysym ((char *) XSTRING (x_keysym
)->data
);
4691 if (keysym
== NoSymbol
)
4692 error ("Keysym does not exist");
4694 if (NILP (modifiers
))
4695 XRebindKeysym (x_current_display
, keysym
, modifier_list
, 0,
4696 XSTRING (newstring
)->data
, XSTRING (newstring
)->size
);
4699 register Lisp_Object rest
, mod
;
4702 for (rest
= modifiers
; !NILP (rest
); rest
= Fcdr (rest
))
4705 error ("Can't have more than 16 modifiers");
4708 CHECK_STRING (mod
, 3);
4709 modifier_list
[i
] = XStringToKeysym ((char *) XSTRING (mod
)->data
);
4711 if (modifier_list
[i
] == NoSymbol
4712 || !(IsModifierKey (modifier_list
[i
])
4713 || ((unsigned)(modifier_list
[i
]) == XK_Mode_switch
)
4714 || ((unsigned)(modifier_list
[i
]) == XK_Num_Lock
)))
4716 if (modifier_list
[i
] == NoSymbol
4717 || !IsModifierKey (modifier_list
[i
]))
4719 error ("Element is not a modifier keysym");
4723 XRebindKeysym (x_current_display
, keysym
, modifier_list
, i
,
4724 XSTRING (newstring
)->data
, XSTRING (newstring
)->size
);
4730 DEFUN ("x-rebind-keys", Fx_rebind_keys
, Sx_rebind_keys
, 2, 2, 0,
4731 "Rebind KEYCODE to list of strings STRINGS.\n\
4732 STRINGS should be a list of 16 elements, one for each shift combination.\n\
4733 nil as element means don't change.\n\
4734 See the documentation of `x-rebind-key' for more information.")
4736 register Lisp_Object keycode
;
4737 register Lisp_Object strings
;
4739 register Lisp_Object item
;
4740 register unsigned char *rawstring
;
4741 KeySym rawkey
, modifier
[1];
4743 register unsigned i
;
4746 CHECK_NUMBER (keycode
, 1);
4747 CHECK_CONS (strings
, 2);
4748 rawkey
= (KeySym
) ((unsigned) (XINT (keycode
))) & 255;
4749 for (i
= 0; i
<= 15; strings
= Fcdr (strings
), i
++)
4751 item
= Fcar (strings
);
4754 CHECK_STRING (item
, 2);
4755 strsize
= XSTRING (item
)->size
;
4756 rawstring
= (unsigned char *) xmalloc (strsize
);
4757 bcopy (XSTRING (item
)->data
, rawstring
, strsize
);
4758 modifier
[1] = 1 << i
;
4759 XRebindKeysym (x_current_display
, rawkey
, modifier
, 1,
4760 rawstring
, strsize
);
4765 #endif /* HAVE_X11 */
4768 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4770 XScreenNumberOfScreen (scr
)
4771 register Screen
*scr
;
4773 register Display
*dpy
;
4774 register Screen
*dpyscr
;
4778 dpyscr
= dpy
->screens
;
4780 for (i
= 0; i
< dpy
->nscreens
; i
++, dpyscr
++)
4786 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4789 select_visual (dpy
, screen
, depth
)
4792 unsigned int *depth
;
4795 XVisualInfo
*vinfo
, vinfo_template
;
4798 v
= DefaultVisualOfScreen (screen
);
4801 vinfo_template
.visualid
= XVisualIDFromVisual (v
);
4803 vinfo_template
.visualid
= v
->visualid
;
4806 vinfo_template
.screen
= XScreenNumberOfScreen (screen
);
4808 vinfo
= XGetVisualInfo (dpy
,
4809 VisualIDMask
| VisualScreenMask
, &vinfo_template
,
4812 fatal ("Can't get proper X visual info");
4814 if ((1 << vinfo
->depth
) == vinfo
->colormap_size
)
4815 *depth
= vinfo
->depth
;
4819 int n
= vinfo
->colormap_size
- 1;
4828 XFree ((char *) vinfo
);
4832 /* Return the X display structure for the display named NAME.
4833 Open a new connection if necessary. */
4835 struct x_display_info
*
4836 x_display_info_for_name (name
)
4840 struct x_display_info
*dpyinfo
;
4842 CHECK_STRING (name
, 0);
4844 if (! EQ (Vwindow_system
, intern ("x")))
4845 error ("Not using X Windows");
4847 for (dpyinfo
= x_display_list
, names
= x_display_name_list
;
4849 dpyinfo
= dpyinfo
->next
, names
= XCONS (names
)->cdr
)
4852 tem
= Fstring_equal (XCONS (XCONS (names
)->car
)->car
, name
);
4857 /* Use this general default value to start with. */
4858 Vx_resource_name
= Vinvocation_name
;
4860 validate_x_resource_name ();
4862 dpyinfo
= x_term_init (name
, (unsigned char *)0,
4863 (char *) XSTRING (Vx_resource_name
)->data
);
4866 error ("Cannot connect to X server %s", XSTRING (name
)->data
);
4869 XSETFASTINT (Vwindow_system_version
, 11);
4874 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
4875 1, 3, 0, "Open a connection to an X server.\n\
4876 DISPLAY is the name of the display to connect to.\n\
4877 Optional second arg XRM-STRING is a string of resources in xrdb format.\n\
4878 If the optional third arg MUST-SUCCEED is non-nil,\n\
4879 terminate Emacs if we can't open the connection.")
4880 (display
, xrm_string
, must_succeed
)
4881 Lisp_Object display
, xrm_string
, must_succeed
;
4883 unsigned int n_planes
;
4884 unsigned char *xrm_option
;
4885 struct x_display_info
*dpyinfo
;
4887 CHECK_STRING (display
, 0);
4888 if (! NILP (xrm_string
))
4889 CHECK_STRING (xrm_string
, 1);
4891 if (! EQ (Vwindow_system
, intern ("x")))
4892 error ("Not using X Windows");
4894 if (! NILP (xrm_string
))
4895 xrm_option
= (unsigned char *) XSTRING (xrm_string
)->data
;
4897 xrm_option
= (unsigned char *) 0;
4899 /* Use this general default value to start with. */
4900 Vx_resource_name
= Vinvocation_name
;
4902 validate_x_resource_name ();
4904 /* This is what opens the connection and sets x_current_display.
4905 This also initializes many symbols, such as those used for input. */
4906 dpyinfo
= x_term_init (display
, xrm_option
,
4907 (char *) XSTRING (Vx_resource_name
)->data
);
4911 if (!NILP (must_succeed
))
4912 fatal ("Cannot connect to X server %s.\n\
4913 Check the DISPLAY environment variable or use `-d'.\n\
4914 Also use the `xhost' program to verify that it is set to permit\n\
4915 connections from your machine.\n",
4916 XSTRING (display
)->data
);
4918 error ("Cannot connect to X server %s", XSTRING (display
)->data
);
4923 XSETFASTINT (Vwindow_system_version
, 11);
4927 DEFUN ("x-close-connection", Fx_close_connection
,
4928 Sx_close_connection
, 1, 1, 0,
4929 "Close the connection to DISPLAY's X server.\n\
4930 For DISPLAY, specify either a frame or a display name (a string).\n\
4931 If DISPLAY is nil, that stands for the selected frame's display.")
4933 Lisp_Object display
;
4935 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4936 struct x_display_info
*tail
;
4939 if (dpyinfo
->reference_count
> 0)
4940 error ("Display still has frames on it");
4943 /* Free the fonts in the font table. */
4944 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
4946 if (dpyinfo
->font_table
[i
].name
)
4947 free (dpyinfo
->font_table
[i
].name
);
4948 /* Don't free the full_name string;
4949 it is always shared with something else. */
4950 XFreeFont (dpyinfo
->display
, dpyinfo
->font_table
[i
].font
);
4952 x_destroy_all_bitmaps (dpyinfo
);
4953 XSetCloseDownMode (dpyinfo
->display
, DestroyAll
);
4955 #ifdef USE_X_TOOLKIT
4956 XtCloseDisplay (dpyinfo
->display
);
4958 XCloseDisplay (dpyinfo
->display
);
4961 x_delete_display (dpyinfo
);
4967 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
4968 "Return the list of display names that Emacs has connections to.")
4971 Lisp_Object tail
, result
;
4974 for (tail
= x_display_name_list
; ! NILP (tail
); tail
= XCONS (tail
)->cdr
)
4975 result
= Fcons (XCONS (XCONS (tail
)->car
)->car
, result
);
4980 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
4981 "If ON is non-nil, report X errors as soon as the erring request is made.\n\
4982 If ON is nil, allow buffering of requests.\n\
4983 Turning on synchronization prohibits the Xlib routines from buffering\n\
4984 requests and seriously degrades performance, but makes debugging much\n\
4986 The optional second argument DISPLAY specifies which display to act on.\n\
4987 DISPLAY should be either a frame or a display name (a string).\n\
4988 If DISPLAY is omitted or nil, that stands for the selected frame's display.")
4990 Lisp_Object display
, on
;
4992 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4994 XSynchronize (dpyinfo
->display
, !EQ (on
, Qnil
));
4999 /* Wait for responses to all X commands issued so far for frame F. */
5006 XSync (FRAME_X_DISPLAY (f
), False
);
5012 /* This is zero if not using X windows. */
5015 /* The section below is built by the lisp expression at the top of the file,
5016 just above where these variables are declared. */
5017 /*&&& init symbols here &&&*/
5018 Qauto_raise
= intern ("auto-raise");
5019 staticpro (&Qauto_raise
);
5020 Qauto_lower
= intern ("auto-lower");
5021 staticpro (&Qauto_lower
);
5022 Qbackground_color
= intern ("background-color");
5023 staticpro (&Qbackground_color
);
5024 Qbar
= intern ("bar");
5026 Qborder_color
= intern ("border-color");
5027 staticpro (&Qborder_color
);
5028 Qborder_width
= intern ("border-width");
5029 staticpro (&Qborder_width
);
5030 Qbox
= intern ("box");
5032 Qcursor_color
= intern ("cursor-color");
5033 staticpro (&Qcursor_color
);
5034 Qcursor_type
= intern ("cursor-type");
5035 staticpro (&Qcursor_type
);
5036 Qfont
= intern ("font");
5038 Qforeground_color
= intern ("foreground-color");
5039 staticpro (&Qforeground_color
);
5040 Qgeometry
= intern ("geometry");
5041 staticpro (&Qgeometry
);
5042 Qicon_left
= intern ("icon-left");
5043 staticpro (&Qicon_left
);
5044 Qicon_top
= intern ("icon-top");
5045 staticpro (&Qicon_top
);
5046 Qicon_type
= intern ("icon-type");
5047 staticpro (&Qicon_type
);
5048 Qicon_name
= intern ("icon-name");
5049 staticpro (&Qicon_name
);
5050 Qinternal_border_width
= intern ("internal-border-width");
5051 staticpro (&Qinternal_border_width
);
5052 Qleft
= intern ("left");
5054 Qmouse_color
= intern ("mouse-color");
5055 staticpro (&Qmouse_color
);
5056 Qnone
= intern ("none");
5058 Qparent_id
= intern ("parent-id");
5059 staticpro (&Qparent_id
);
5060 Qscroll_bar_width
= intern ("scroll-bar-width");
5061 staticpro (&Qscroll_bar_width
);
5062 Qsuppress_icon
= intern ("suppress-icon");
5063 staticpro (&Qsuppress_icon
);
5064 Qtop
= intern ("top");
5066 Qundefined_color
= intern ("undefined-color");
5067 staticpro (&Qundefined_color
);
5068 Qvertical_scroll_bars
= intern ("vertical-scroll-bars");
5069 staticpro (&Qvertical_scroll_bars
);
5070 Qvisibility
= intern ("visibility");
5071 staticpro (&Qvisibility
);
5072 Qwindow_id
= intern ("window-id");
5073 staticpro (&Qwindow_id
);
5074 Qx_frame_parameter
= intern ("x-frame-parameter");
5075 staticpro (&Qx_frame_parameter
);
5076 Qx_resource_name
= intern ("x-resource-name");
5077 staticpro (&Qx_resource_name
);
5078 Quser_position
= intern ("user-position");
5079 staticpro (&Quser_position
);
5080 Quser_size
= intern ("user-size");
5081 staticpro (&Quser_size
);
5082 Qdisplay
= intern ("display");
5083 staticpro (&Qdisplay
);
5084 /* This is the end of symbol initialization. */
5086 Fput (Qundefined_color
, Qerror_conditions
,
5087 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
5088 Fput (Qundefined_color
, Qerror_message
,
5089 build_string ("Undefined color"));
5091 init_x_parm_symbols ();
5093 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path
,
5094 "List of directories to search for bitmap files for X.");
5095 Vx_bitmap_file_path
= decode_env_path ((char *) 0, PATH_BITMAPS
);
5097 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
5098 "The shape of the pointer when over text.\n\
5099 Changing the value does not affect existing frames\n\
5100 unless you set the mouse color.");
5101 Vx_pointer_shape
= Qnil
;
5103 DEFVAR_LISP ("x-resource-name", &Vx_resource_name
,
5104 "The name Emacs uses to look up X resources; for internal use only.\n\
5105 `x-get-resource' uses this as the first component of the instance name\n\
5106 when requesting resource values.\n\
5107 Emacs initially sets `x-resource-name' to the name under which Emacs\n\
5108 was invoked, or to the value specified with the `-name' or `-rn'\n\
5109 switches, if present.");
5110 Vx_resource_name
= Qnil
;
5112 #if 0 /* This doesn't really do anything. */
5113 DEFVAR_INT ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape
,
5114 "The shape of the pointer when not over text.\n\
5115 This variable takes effect when you create a new frame\n\
5116 or when you set the mouse color.");
5118 Vx_nontext_pointer_shape
= Qnil
;
5120 #if 0 /* This doesn't really do anything. */
5121 DEFVAR_INT ("x-mode-pointer-shape", &Vx_mode_pointer_shape
,
5122 "The shape of the pointer when over the mode line.\n\
5123 This variable takes effect when you create a new frame\n\
5124 or when you set the mouse color.");
5126 Vx_mode_pointer_shape
= Qnil
;
5128 DEFVAR_INT ("x-sensitive-text-pointer-shape",
5129 &Vx_sensitive_text_pointer_shape
,
5130 "The shape of the pointer when over mouse-sensitive text.\n\
5131 This variable takes effect when you create a new frame\n\
5132 or when you set the mouse color.");
5133 Vx_sensitive_text_pointer_shape
= Qnil
;
5135 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
5136 "A string indicating the foreground color of the cursor box.");
5137 Vx_cursor_fore_pixel
= Qnil
;
5139 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
5140 "Non-nil if no X window manager is in use.\n\
5141 Emacs doesn't try to figure this out; this is always nil\n\
5142 unless you set it to something else.");
5143 /* We don't have any way to find this out, so set it to nil
5144 and maybe the user would like to set it to t. */
5145 Vx_no_window_manager
= Qnil
;
5147 #ifdef USE_X_TOOLKIT
5148 Fprovide (intern ("x-toolkit"));
5151 Fprovide (intern ("motif"));
5154 defsubr (&Sx_get_resource
);
5156 defsubr (&Sx_draw_rectangle
);
5157 defsubr (&Sx_erase_rectangle
);
5158 defsubr (&Sx_contour_region
);
5159 defsubr (&Sx_uncontour_region
);
5161 defsubr (&Sx_list_fonts
);
5162 defsubr (&Sx_display_color_p
);
5163 defsubr (&Sx_display_grayscale_p
);
5164 defsubr (&Sx_color_defined_p
);
5165 defsubr (&Sx_color_values
);
5166 defsubr (&Sx_server_max_request_size
);
5167 defsubr (&Sx_server_vendor
);
5168 defsubr (&Sx_server_version
);
5169 defsubr (&Sx_display_pixel_width
);
5170 defsubr (&Sx_display_pixel_height
);
5171 defsubr (&Sx_display_mm_width
);
5172 defsubr (&Sx_display_mm_height
);
5173 defsubr (&Sx_display_screens
);
5174 defsubr (&Sx_display_planes
);
5175 defsubr (&Sx_display_color_cells
);
5176 defsubr (&Sx_display_visual_class
);
5177 defsubr (&Sx_display_backing_store
);
5178 defsubr (&Sx_display_save_under
);
5180 defsubr (&Sx_rebind_key
);
5181 defsubr (&Sx_rebind_keys
);
5182 defsubr (&Sx_track_pointer
);
5183 defsubr (&Sx_grab_pointer
);
5184 defsubr (&Sx_ungrab_pointer
);
5186 defsubr (&Sx_parse_geometry
);
5187 defsubr (&Sx_create_frame
);
5188 defsubr (&Sfocus_frame
);
5189 defsubr (&Sunfocus_frame
);
5191 defsubr (&Sx_horizontal_line
);
5193 defsubr (&Sx_open_connection
);
5194 defsubr (&Sx_close_connection
);
5195 defsubr (&Sx_display_list
);
5196 defsubr (&Sx_synchronize
);
5199 #endif /* HAVE_X_WINDOWS */