1 /* Functions for the X window system.
2 Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20 /* Completely rewritten by Richard Stallman. */
22 /* Rewritten for X11 by Joseph Arceneaux */
27 /* This makes the fields of a Display accessible, in Xlib header files. */
28 #define XLIB_ILLEGAL_ACCESS
35 #include "dispextern.h"
37 #include "blockinput.h"
44 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */
45 #include "bitmaps/gray.xbm"
47 #include <X11/bitmaps/gray>
50 #include "[.bitmaps]gray.xbm"
54 #include <X11/Shell.h>
57 #include <X11/Xaw/Paned.h>
58 #include <X11/Xaw/Label.h>
59 #endif /* USE_MOTIF */
62 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
71 #include "../lwlib/lwlib.h"
73 /* Do the EDITRES protocol if running X11R5 */
74 #if (XtSpecificationRelease >= 5)
76 extern void _XEditResCheckMessages ();
77 #endif /* R5 + Athena */
79 /* Unique id counter for widgets created by the Lucid Widget
81 extern LWLIB_ID widget_id_tick
;
83 /* This is part of a kludge--see lwlib/xlwmenu.c. */
84 XFontStruct
*xlwmenu_default_font
;
86 extern void free_frame_menubar ();
87 #endif /* USE_X_TOOLKIT */
89 #define min(a,b) ((a) < (b) ? (a) : (b))
90 #define max(a,b) ((a) > (b) ? (a) : (b))
93 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
95 #define MAXREQUEST(dpy) ((dpy)->max_request_size)
98 /* The name we're using in resource queries. */
99 Lisp_Object Vx_resource_name
;
101 /* The background and shape of the mouse pointer, and shape when not
102 over text or in the modeline. */
103 Lisp_Object Vx_pointer_shape
, Vx_nontext_pointer_shape
, Vx_mode_pointer_shape
;
104 /* The shape when over mouse-sensitive text. */
105 Lisp_Object Vx_sensitive_text_pointer_shape
;
107 /* Color of chars displayed in cursor box. */
108 Lisp_Object Vx_cursor_fore_pixel
;
110 /* Nonzero if using X. */
113 /* Non nil if no window manager is in use. */
114 Lisp_Object Vx_no_window_manager
;
116 /* Search path for bitmap files. */
117 Lisp_Object Vx_bitmap_file_path
;
119 /* Evaluate this expression to rebuild the section of syms_of_xfns
120 that initializes and staticpros the symbols declared below. Note
121 that Emacs 18 has a bug that keeps C-x C-e from being able to
122 evaluate this expression.
125 ;; Accumulate a list of the symbols we want to initialize from the
126 ;; declarations at the top of the file.
127 (goto-char (point-min))
128 (search-forward "/\*&&& symbols declared here &&&*\/\n")
130 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
132 (cons (buffer-substring (match-beginning 1) (match-end 1))
135 (setq symbol-list (nreverse symbol-list))
136 ;; Delete the section of syms_of_... where we initialize the symbols.
137 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
138 (let ((start (point)))
139 (while (looking-at "^ Q")
141 (kill-region start (point)))
142 ;; Write a new symbol initialization section.
144 (insert (format " %s = intern (\"" (car symbol-list)))
145 (let ((start (point)))
146 (insert (substring (car symbol-list) 1))
147 (subst-char-in-region start (point) ?_ ?-))
148 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
149 (setq symbol-list (cdr symbol-list)))))
153 /*&&& symbols declared here &&&*/
154 Lisp_Object Qauto_raise
;
155 Lisp_Object Qauto_lower
;
156 Lisp_Object Qbackground_color
;
158 Lisp_Object Qborder_color
;
159 Lisp_Object Qborder_width
;
161 Lisp_Object Qcursor_color
;
162 Lisp_Object Qcursor_type
;
164 Lisp_Object Qforeground_color
;
165 Lisp_Object Qgeometry
;
166 Lisp_Object Qicon_left
;
167 Lisp_Object Qicon_top
;
168 Lisp_Object Qicon_type
;
169 Lisp_Object Qicon_name
;
170 Lisp_Object Qinternal_border_width
;
172 Lisp_Object Qmouse_color
;
174 Lisp_Object Qparent_id
;
175 Lisp_Object Qscroll_bar_width
;
176 Lisp_Object Qsuppress_icon
;
178 Lisp_Object Qundefined_color
;
179 Lisp_Object Qvertical_scroll_bars
;
180 Lisp_Object Qvisibility
;
181 Lisp_Object Qwindow_id
;
182 Lisp_Object Qx_frame_parameter
;
183 Lisp_Object Qx_resource_name
;
184 Lisp_Object Quser_position
;
185 Lisp_Object Quser_size
;
186 Lisp_Object Qdisplay
;
188 /* The below are defined in frame.c. */
189 extern Lisp_Object Qheight
, Qminibuffer
, Qname
, Qonly
, Qwidth
;
190 extern Lisp_Object Qunsplittable
, Qmenu_bar_lines
;
192 extern Lisp_Object Vwindow_system_version
;
195 /* Error if we are not connected to X. */
200 error ("X windows are not in use or not initialized");
203 /* Nonzero if using X for display. */
211 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
212 and checking validity for X. */
215 check_x_frame (frame
)
224 CHECK_LIVE_FRAME (frame
, 0);
228 error ("non-X frame used");
232 /* Let the user specify an X display with a frame.
233 nil stands for the selected frame--or, if that is not an X frame,
234 the first X display on the list. */
236 static struct x_display_info
*
237 check_x_display_info (frame
)
242 if (FRAME_X_P (selected_frame
))
243 return FRAME_X_DISPLAY_INFO (selected_frame
);
244 else if (x_display_list
!= 0)
245 return x_display_list
;
247 error ("X windows are not in use or not initialized");
249 else if (STRINGP (frame
))
250 return x_display_info_for_name (frame
);
255 CHECK_LIVE_FRAME (frame
, 0);
258 error ("non-X frame used");
259 return FRAME_X_DISPLAY_INFO (f
);
263 /* Return the Emacs frame-object corresponding to an X window.
264 It could be the frame's main window or an icon window. */
266 /* This function can be called during GC, so use GC_xxx type test macros. */
269 x_window_to_frame (dpyinfo
, wdesc
)
270 struct x_display_info
*dpyinfo
;
273 Lisp_Object tail
, frame
;
276 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
278 frame
= XCONS (tail
)->car
;
279 if (!GC_FRAMEP (frame
))
282 if (f
->output_data
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
285 if ((f
->output_data
.x
->edit_widget
286 && XtWindow (f
->output_data
.x
->edit_widget
) == wdesc
)
287 || f
->output_data
.x
->icon_desc
== wdesc
)
289 #else /* not USE_X_TOOLKIT */
290 if (FRAME_X_WINDOW (f
) == wdesc
291 || f
->output_data
.x
->icon_desc
== wdesc
)
293 #endif /* not USE_X_TOOLKIT */
299 /* Like x_window_to_frame but also compares the window with the widget's
303 x_any_window_to_frame (dpyinfo
, wdesc
)
304 struct x_display_info
*dpyinfo
;
307 Lisp_Object tail
, frame
;
311 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
313 frame
= XCONS (tail
)->car
;
314 if (!GC_FRAMEP (frame
))
317 if (f
->output_data
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
319 x
= f
->output_data
.x
;
320 /* This frame matches if the window is any of its widgets. */
321 if (wdesc
== XtWindow (x
->widget
)
322 || wdesc
== XtWindow (x
->column_widget
)
323 || wdesc
== XtWindow (x
->edit_widget
))
325 /* Match if the window is this frame's menubar. */
326 if (lw_window_is_in_menubar (wdesc
, x
->menubar_widget
))
332 /* Likewise, but exclude the menu bar widget. */
335 x_non_menubar_window_to_frame (dpyinfo
, wdesc
)
336 struct x_display_info
*dpyinfo
;
339 Lisp_Object tail
, frame
;
343 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
345 frame
= XCONS (tail
)->car
;
346 if (!GC_FRAMEP (frame
))
349 if (f
->output_data
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
351 x
= f
->output_data
.x
;
352 /* This frame matches if the window is any of its widgets. */
353 if (wdesc
== XtWindow (x
->widget
)
354 || wdesc
== XtWindow (x
->column_widget
)
355 || wdesc
== XtWindow (x
->edit_widget
))
361 /* Likewise, but consider only the menu bar widget. */
364 x_menubar_window_to_frame (dpyinfo
, wdesc
)
365 struct x_display_info
*dpyinfo
;
368 Lisp_Object tail
, frame
;
372 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
374 frame
= XCONS (tail
)->car
;
375 if (!GC_FRAMEP (frame
))
378 if (f
->output_data
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
380 x
= f
->output_data
.x
;
381 /* Match if the window is this frame's menubar. */
382 if (lw_window_is_in_menubar (wdesc
, x
->menubar_widget
))
388 /* Return the frame whose principal (outermost) window is WDESC.
389 If WDESC is some other (smaller) window, we return 0. */
392 x_top_window_to_frame (dpyinfo
, wdesc
)
393 struct x_display_info
*dpyinfo
;
396 Lisp_Object tail
, frame
;
400 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
402 frame
= XCONS (tail
)->car
;
403 if (!GC_FRAMEP (frame
))
406 if (f
->output_data
.nothing
== 1 || FRAME_X_DISPLAY_INFO (f
) != dpyinfo
)
408 x
= f
->output_data
.x
;
409 /* This frame matches if the window is its topmost widget. */
410 if (wdesc
== XtWindow (x
->widget
))
412 #if 0 /* I don't know why it did this,
413 but it seems logically wrong,
414 and it causes trouble for MapNotify events. */
415 /* Match if the window is this frame's menubar. */
416 if (x
->menubar_widget
417 && wdesc
== XtWindow (x
->menubar_widget
))
423 #endif /* USE_X_TOOLKIT */
427 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
428 id, which is just an int that this section returns. Bitmaps are
429 reference counted so they can be shared among frames.
431 Bitmap indices are guaranteed to be > 0, so a negative number can
432 be used to indicate no bitmap.
434 If you use x_create_bitmap_from_data, then you must keep track of
435 the bitmaps yourself. That is, creating a bitmap from the same
436 data more than once will not be caught. */
439 /* Functions to access the contents of a bitmap, given an id. */
442 x_bitmap_height (f
, id
)
446 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].height
;
450 x_bitmap_width (f
, id
)
454 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].width
;
458 x_bitmap_pixmap (f
, id
)
462 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].pixmap
;
466 /* Allocate a new bitmap record. Returns index of new record. */
469 x_allocate_bitmap_record (f
)
472 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
475 if (dpyinfo
->bitmaps
== NULL
)
477 dpyinfo
->bitmaps_size
= 10;
479 = (struct x_bitmap_record
*) xmalloc (dpyinfo
->bitmaps_size
* sizeof (struct x_bitmap_record
));
480 dpyinfo
->bitmaps_last
= 1;
484 if (dpyinfo
->bitmaps_last
< dpyinfo
->bitmaps_size
)
485 return ++dpyinfo
->bitmaps_last
;
487 for (i
= 0; i
< dpyinfo
->bitmaps_size
; ++i
)
488 if (dpyinfo
->bitmaps
[i
].refcount
== 0)
491 dpyinfo
->bitmaps_size
*= 2;
493 = (struct x_bitmap_record
*) xrealloc (dpyinfo
->bitmaps
,
494 dpyinfo
->bitmaps_size
* sizeof (struct x_bitmap_record
));
495 return ++dpyinfo
->bitmaps_last
;
498 /* Add one reference to the reference count of the bitmap with id ID. */
501 x_reference_bitmap (f
, id
)
505 ++FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].refcount
;
508 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
511 x_create_bitmap_from_data (f
, bits
, width
, height
)
514 unsigned int width
, height
;
516 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
520 bitmap
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
521 bits
, width
, height
);
526 id
= x_allocate_bitmap_record (f
);
527 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
528 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
529 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
530 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
531 dpyinfo
->bitmaps
[id
- 1].height
= height
;
532 dpyinfo
->bitmaps
[id
- 1].width
= width
;
537 /* Create bitmap from file FILE for frame F. */
540 x_create_bitmap_from_file (f
, file
)
544 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
545 unsigned int width
, height
;
547 int xhot
, yhot
, result
, id
;
552 /* Look for an existing bitmap with the same name. */
553 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
555 if (dpyinfo
->bitmaps
[id
].refcount
556 && dpyinfo
->bitmaps
[id
].file
557 && !strcmp (dpyinfo
->bitmaps
[id
].file
, (char *) XSTRING (file
)->data
))
559 ++dpyinfo
->bitmaps
[id
].refcount
;
564 /* Search bitmap-file-path for the file, if appropriate. */
565 fd
= openp (Vx_bitmap_file_path
, file
, "", &found
, 0);
570 filename
= (char *) XSTRING (found
)->data
;
572 result
= XReadBitmapFile (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
573 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
574 if (result
!= BitmapSuccess
)
577 id
= x_allocate_bitmap_record (f
);
578 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
579 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
580 dpyinfo
->bitmaps
[id
- 1].file
= (char *) xmalloc (XSTRING (file
)->size
+ 1);
581 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
582 dpyinfo
->bitmaps
[id
- 1].height
= height
;
583 dpyinfo
->bitmaps
[id
- 1].width
= width
;
584 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, XSTRING (file
)->data
);
589 /* Remove reference to bitmap with id number ID. */
592 x_destroy_bitmap (f
, id
)
596 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
600 --dpyinfo
->bitmaps
[id
- 1].refcount
;
601 if (dpyinfo
->bitmaps
[id
- 1].refcount
== 0)
604 XFreePixmap (FRAME_X_DISPLAY (f
), dpyinfo
->bitmaps
[id
- 1].pixmap
);
605 if (dpyinfo
->bitmaps
[id
- 1].file
)
607 free (dpyinfo
->bitmaps
[id
- 1].file
);
608 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
615 /* Free all the bitmaps for the display specified by DPYINFO. */
618 x_destroy_all_bitmaps (dpyinfo
)
619 struct x_display_info
*dpyinfo
;
622 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++)
623 if (dpyinfo
->bitmaps
[i
].refcount
> 0)
625 XFreePixmap (dpyinfo
->display
, dpyinfo
->bitmaps
[i
].pixmap
);
626 if (dpyinfo
->bitmaps
[i
].file
)
627 free (dpyinfo
->bitmaps
[i
].file
);
629 dpyinfo
->bitmaps_last
= 0;
632 /* Connect the frame-parameter names for X frames
633 to the ways of passing the parameter values to the window system.
635 The name of a parameter, as a Lisp symbol,
636 has an `x-frame-parameter' property which is an integer in Lisp
637 but can be interpreted as an `enum x_frame_parm' in C. */
641 X_PARM_FOREGROUND_COLOR
,
642 X_PARM_BACKGROUND_COLOR
,
649 X_PARM_INTERNAL_BORDER_WIDTH
,
653 X_PARM_VERT_SCROLL_BAR
,
655 X_PARM_MENU_BAR_LINES
659 struct x_frame_parm_table
662 void (*setter
)( /* struct frame *frame, Lisp_Object val, oldval */ );
665 void x_set_foreground_color ();
666 void x_set_background_color ();
667 void x_set_mouse_color ();
668 void x_set_cursor_color ();
669 void x_set_border_color ();
670 void x_set_cursor_type ();
671 void x_set_icon_type ();
672 void x_set_icon_name ();
674 void x_set_border_width ();
675 void x_set_internal_border_width ();
676 void x_explicitly_set_name ();
677 void x_set_autoraise ();
678 void x_set_autolower ();
679 void x_set_vertical_scroll_bars ();
680 void x_set_visibility ();
681 void x_set_menu_bar_lines ();
682 void x_set_scroll_bar_width ();
683 void x_set_unsplittable ();
685 static struct x_frame_parm_table x_frame_parms
[] =
687 "foreground-color", x_set_foreground_color
,
688 "background-color", x_set_background_color
,
689 "mouse-color", x_set_mouse_color
,
690 "cursor-color", x_set_cursor_color
,
691 "border-color", x_set_border_color
,
692 "cursor-type", x_set_cursor_type
,
693 "icon-type", x_set_icon_type
,
694 "icon-name", x_set_icon_name
,
696 "border-width", x_set_border_width
,
697 "internal-border-width", x_set_internal_border_width
,
698 "name", x_explicitly_set_name
,
699 "auto-raise", x_set_autoraise
,
700 "auto-lower", x_set_autolower
,
701 "vertical-scroll-bars", x_set_vertical_scroll_bars
,
702 "visibility", x_set_visibility
,
703 "menu-bar-lines", x_set_menu_bar_lines
,
704 "scroll-bar-width", x_set_scroll_bar_width
,
705 "unsplittable", x_set_unsplittable
,
708 /* Attach the `x-frame-parameter' properties to
709 the Lisp symbol names of parameters relevant to X. */
711 init_x_parm_symbols ()
715 for (i
= 0; i
< sizeof (x_frame_parms
) / sizeof (x_frame_parms
[0]); i
++)
716 Fput (intern (x_frame_parms
[i
].name
), Qx_frame_parameter
,
720 /* Change the parameters of FRAME as specified by ALIST.
721 If a parameter is not specially recognized, do nothing;
722 otherwise call the `x_set_...' function for that parameter. */
725 x_set_frame_parameters (f
, alist
)
731 /* If both of these parameters are present, it's more efficient to
732 set them both at once. So we wait until we've looked at the
733 entire list before we set them. */
734 Lisp_Object width
, height
;
737 Lisp_Object left
, top
;
739 /* Same with these. */
740 Lisp_Object icon_left
, icon_top
;
742 /* Record in these vectors all the parms specified. */
746 int left_no_change
= 0, top_no_change
= 0;
747 int icon_left_no_change
= 0, icon_top_no_change
= 0;
750 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
753 parms
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
754 values
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
756 /* Extract parm names and values into those vectors. */
759 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
761 Lisp_Object elt
, prop
, val
;
764 parms
[i
] = Fcar (elt
);
765 values
[i
] = Fcdr (elt
);
769 width
= height
= top
= left
= Qunbound
;
770 icon_left
= icon_top
= Qunbound
;
772 /* Now process them in reverse of specified order. */
773 for (i
--; i
>= 0; i
--)
775 Lisp_Object prop
, val
;
780 if (EQ (prop
, Qwidth
))
782 else if (EQ (prop
, Qheight
))
784 else if (EQ (prop
, Qtop
))
786 else if (EQ (prop
, Qleft
))
788 else if (EQ (prop
, Qicon_top
))
790 else if (EQ (prop
, Qicon_left
))
794 register Lisp_Object param_index
, old_value
;
796 param_index
= Fget (prop
, Qx_frame_parameter
);
797 old_value
= get_frame_param (f
, prop
);
798 store_frame_param (f
, prop
, val
);
799 if (NATNUMP (param_index
)
800 && (XFASTINT (param_index
)
801 < sizeof (x_frame_parms
)/sizeof (x_frame_parms
[0])))
802 (*x_frame_parms
[XINT (param_index
)].setter
)(f
, val
, old_value
);
806 /* Don't die if just one of these was set. */
807 if (EQ (left
, Qunbound
))
810 if (f
->output_data
.x
->left_pos
< 0)
811 left
= Fcons (Qplus
, Fcons (make_number (f
->output_data
.x
->left_pos
), Qnil
));
813 XSETINT (left
, f
->output_data
.x
->left_pos
);
815 if (EQ (top
, Qunbound
))
818 if (f
->output_data
.x
->top_pos
< 0)
819 top
= Fcons (Qplus
, Fcons (make_number (f
->output_data
.x
->top_pos
), Qnil
));
821 XSETINT (top
, f
->output_data
.x
->top_pos
);
824 /* If one of the icon positions was not set, preserve or default it. */
825 if (EQ (icon_left
, Qunbound
) || ! INTEGERP (icon_left
))
827 icon_left_no_change
= 1;
828 icon_left
= Fcdr (Fassq (Qicon_left
, f
->param_alist
));
829 if (NILP (icon_left
))
830 XSETINT (icon_left
, 0);
832 if (EQ (icon_top
, Qunbound
) || ! INTEGERP (icon_top
))
834 icon_top_no_change
= 1;
835 icon_top
= Fcdr (Fassq (Qicon_top
, f
->param_alist
));
837 XSETINT (icon_top
, 0);
840 /* Don't die if just one of these was set. */
841 if (EQ (width
, Qunbound
))
842 XSETINT (width
, FRAME_WIDTH (f
));
843 if (EQ (height
, Qunbound
))
844 XSETINT (height
, FRAME_HEIGHT (f
));
846 /* Don't set these parameters unless they've been explicitly
847 specified. The window might be mapped or resized while we're in
848 this function, and we don't want to override that unless the lisp
849 code has asked for it.
851 Don't set these parameters unless they actually differ from the
852 window's current parameters; the window may not actually exist
857 check_frame_size (f
, &height
, &width
);
859 XSETFRAME (frame
, f
);
861 if ((NUMBERP (width
) && XINT (width
) != FRAME_WIDTH (f
))
862 || (NUMBERP (height
) && XINT (height
) != FRAME_HEIGHT (f
)))
863 Fset_frame_size (frame
, width
, height
);
865 if ((!NILP (left
) || !NILP (top
))
866 && ! (left_no_change
&& top_no_change
)
867 && ! (NUMBERP (left
) && XINT (left
) == f
->output_data
.x
->left_pos
868 && NUMBERP (top
) && XINT (top
) == f
->output_data
.x
->top_pos
))
873 /* Record the signs. */
874 f
->output_data
.x
->size_hint_flags
&= ~ (XNegative
| YNegative
);
875 if (EQ (left
, Qminus
))
876 f
->output_data
.x
->size_hint_flags
|= XNegative
;
877 else if (INTEGERP (left
))
879 leftpos
= XINT (left
);
881 f
->output_data
.x
->size_hint_flags
|= XNegative
;
883 else if (CONSP (left
) && EQ (XCONS (left
)->car
, Qminus
)
884 && CONSP (XCONS (left
)->cdr
)
885 && INTEGERP (XCONS (XCONS (left
)->cdr
)->car
))
887 leftpos
= - XINT (XCONS (XCONS (left
)->cdr
)->car
);
888 f
->output_data
.x
->size_hint_flags
|= XNegative
;
890 else if (CONSP (left
) && EQ (XCONS (left
)->car
, Qplus
)
891 && CONSP (XCONS (left
)->cdr
)
892 && INTEGERP (XCONS (XCONS (left
)->cdr
)->car
))
894 leftpos
= XINT (XCONS (XCONS (left
)->cdr
)->car
);
897 if (EQ (top
, Qminus
))
898 f
->output_data
.x
->size_hint_flags
|= YNegative
;
899 else if (INTEGERP (top
))
903 f
->output_data
.x
->size_hint_flags
|= YNegative
;
905 else if (CONSP (top
) && EQ (XCONS (top
)->car
, Qminus
)
906 && CONSP (XCONS (top
)->cdr
)
907 && INTEGERP (XCONS (XCONS (top
)->cdr
)->car
))
909 toppos
= - XINT (XCONS (XCONS (top
)->cdr
)->car
);
910 f
->output_data
.x
->size_hint_flags
|= YNegative
;
912 else if (CONSP (top
) && EQ (XCONS (top
)->car
, Qplus
)
913 && CONSP (XCONS (top
)->cdr
)
914 && INTEGERP (XCONS (XCONS (top
)->cdr
)->car
))
916 toppos
= XINT (XCONS (XCONS (top
)->cdr
)->car
);
920 /* Store the numeric value of the position. */
921 f
->output_data
.x
->top_pos
= toppos
;
922 f
->output_data
.x
->left_pos
= leftpos
;
924 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
926 /* Actually set that position, and convert to absolute. */
927 x_set_offset (f
, leftpos
, toppos
, -1);
930 if ((!NILP (icon_left
) || !NILP (icon_top
))
931 && ! (icon_left_no_change
&& icon_top_no_change
))
932 x_wm_set_icon_position (f
, XINT (icon_left
), XINT (icon_top
));
936 /* Store the screen positions of frame F into XPTR and YPTR.
937 These are the positions of the containing window manager window,
938 not Emacs's own window. */
941 x_real_positions (f
, xptr
, yptr
)
948 /* This is pretty gross, but seems to be the easiest way out of
949 the problem that arises when restarting window-managers. */
952 Window outer
= XtWindow (f
->output_data
.x
->widget
);
954 Window outer
= f
->output_data
.x
->window_desc
;
956 Window tmp_root_window
;
957 Window
*tmp_children
;
962 x_catch_errors (FRAME_X_DISPLAY (f
));
964 XQueryTree (FRAME_X_DISPLAY (f
), outer
, &tmp_root_window
,
965 &f
->output_data
.x
->parent_desc
,
966 &tmp_children
, &tmp_nchildren
);
967 xfree (tmp_children
);
971 /* Find the position of the outside upper-left corner of
972 the inner window, with respect to the outer window. */
973 if (f
->output_data
.x
->parent_desc
!= FRAME_X_DISPLAY_INFO (f
)->root_window
)
975 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
977 /* From-window, to-window. */
979 XtWindow (f
->output_data
.x
->widget
),
981 f
->output_data
.x
->window_desc
,
983 f
->output_data
.x
->parent_desc
,
985 /* From-position, to-position. */
986 0, 0, &win_x
, &win_y
,
991 #if 0 /* The values seem to be right without this and wrong with. */
992 win_x
+= f
->output_data
.x
->border_width
;
993 win_y
+= f
->output_data
.x
->border_width
;
997 /* It is possible for the window returned by the XQueryNotify
998 to become invalid by the time we call XTranslateCoordinates.
999 That can happen when you restart some window managers.
1000 If so, we get an error in XTranslateCoordinates.
1001 Detect that and try the whole thing over. */
1002 if (! x_had_errors_p (FRAME_X_DISPLAY (f
)))
1005 x_uncatch_errors (FRAME_X_DISPLAY (f
));
1008 x_uncatch_errors (FRAME_X_DISPLAY (f
));
1010 *xptr
= f
->output_data
.x
->left_pos
- win_x
;
1011 *yptr
= f
->output_data
.x
->top_pos
- win_y
;
1014 /* Insert a description of internally-recorded parameters of frame X
1015 into the parameter alist *ALISTPTR that is to be given to the user.
1016 Only parameters that are specific to the X window system
1017 and whose values are not correctly recorded in the frame's
1018 param_alist need to be considered here. */
1020 x_report_frame_params (f
, alistptr
)
1022 Lisp_Object
*alistptr
;
1027 /* Represent negative positions (off the top or left screen edge)
1028 in a way that Fmodify_frame_parameters will understand correctly. */
1029 XSETINT (tem
, f
->output_data
.x
->left_pos
);
1030 if (f
->output_data
.x
->left_pos
>= 0)
1031 store_in_alist (alistptr
, Qleft
, tem
);
1033 store_in_alist (alistptr
, Qleft
, Fcons (Qplus
, Fcons (tem
, Qnil
)));
1035 XSETINT (tem
, f
->output_data
.x
->top_pos
);
1036 if (f
->output_data
.x
->top_pos
>= 0)
1037 store_in_alist (alistptr
, Qtop
, tem
);
1039 store_in_alist (alistptr
, Qtop
, Fcons (Qplus
, Fcons (tem
, Qnil
)));
1041 store_in_alist (alistptr
, Qborder_width
,
1042 make_number (f
->output_data
.x
->border_width
));
1043 store_in_alist (alistptr
, Qinternal_border_width
,
1044 make_number (f
->output_data
.x
->internal_border_width
));
1045 sprintf (buf
, "%ld", (long) FRAME_X_WINDOW (f
));
1046 store_in_alist (alistptr
, Qwindow_id
,
1047 build_string (buf
));
1048 store_in_alist (alistptr
, Qicon_name
, f
->icon_name
);
1049 FRAME_SAMPLE_VISIBILITY (f
);
1050 store_in_alist (alistptr
, Qvisibility
,
1051 (FRAME_VISIBLE_P (f
) ? Qt
1052 : FRAME_ICONIFIED_P (f
) ? Qicon
: Qnil
));
1053 store_in_alist (alistptr
, Qdisplay
,
1054 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->car
);
1058 /* Decide if color named COLOR is valid for the display associated with
1059 the selected frame; if so, return the rgb values in COLOR_DEF.
1060 If ALLOC is nonzero, allocate a new colormap cell. */
1063 defined_color (f
, color
, color_def
, alloc
)
1069 register int status
;
1070 Colormap screen_colormap
;
1071 Display
*display
= FRAME_X_DISPLAY (f
);
1074 screen_colormap
= DefaultColormap (display
, XDefaultScreen (display
));
1076 status
= XParseColor (display
, screen_colormap
, color
, color_def
);
1077 if (status
&& alloc
)
1079 status
= XAllocColor (display
, screen_colormap
, color_def
);
1082 /* If we got to this point, the colormap is full, so we're
1083 going to try and get the next closest color.
1084 The algorithm used is a least-squares matching, which is
1085 what X uses for closest color matching with StaticColor visuals. */
1090 long nearest_delta
, trial_delta
;
1093 no_cells
= XDisplayCells (display
, XDefaultScreen (display
));
1094 cells
= (XColor
*) alloca (sizeof (XColor
) * no_cells
);
1096 for (x
= 0; x
< no_cells
; x
++)
1099 XQueryColors (display
, screen_colormap
, cells
, no_cells
);
1101 /* I'm assuming CSE so I'm not going to condense this. */
1102 nearest_delta
= ((((color_def
->red
>> 8) - (cells
[0].red
>> 8))
1103 * ((color_def
->red
>> 8) - (cells
[0].red
>> 8)))
1105 (((color_def
->green
>> 8) - (cells
[0].green
>> 8))
1106 * ((color_def
->green
>> 8) - (cells
[0].green
>> 8)))
1108 (((color_def
->blue
>> 8) - (cells
[0].blue
>> 8))
1109 * ((color_def
->blue
>> 8) - (cells
[0].blue
>> 8))));
1110 for (x
= 1; x
< no_cells
; x
++)
1112 trial_delta
= ((((color_def
->red
>> 8) - (cells
[x
].red
>> 8))
1113 * ((color_def
->red
>> 8) - (cells
[x
].red
>> 8)))
1115 (((color_def
->green
>> 8) - (cells
[x
].green
>> 8))
1116 * ((color_def
->green
>> 8) - (cells
[x
].green
>> 8)))
1118 (((color_def
->blue
>> 8) - (cells
[x
].blue
>> 8))
1119 * ((color_def
->blue
>> 8) - (cells
[x
].blue
>> 8))));
1120 if (trial_delta
< nearest_delta
)
1123 nearest_delta
= trial_delta
;
1126 color_def
->red
= cells
[nearest
].red
;
1127 color_def
->green
= cells
[nearest
].green
;
1128 color_def
->blue
= cells
[nearest
].blue
;
1129 status
= XAllocColor (display
, screen_colormap
, color_def
);
1140 /* Given a string ARG naming a color, compute a pixel value from it
1141 suitable for screen F.
1142 If F is not a color screen, return DEF (default) regardless of what
1146 x_decode_color (f
, arg
, def
)
1153 CHECK_STRING (arg
, 0);
1155 if (strcmp (XSTRING (arg
)->data
, "black") == 0)
1156 return BLACK_PIX_DEFAULT (f
);
1157 else if (strcmp (XSTRING (arg
)->data
, "white") == 0)
1158 return WHITE_PIX_DEFAULT (f
);
1160 if (FRAME_X_DISPLAY_INFO (f
)->n_planes
== 1)
1163 /* defined_color is responsible for coping with failures
1164 by looking for a near-miss. */
1165 if (defined_color (f
, XSTRING (arg
)->data
, &cdef
, 1))
1168 /* defined_color failed; return an ultimate default. */
1172 /* Functions called only from `x_set_frame_param'
1173 to set individual parameters.
1175 If FRAME_X_WINDOW (f) is 0,
1176 the frame is being created and its X-window does not exist yet.
1177 In that case, just record the parameter's new value
1178 in the standard place; do not attempt to change the window. */
1181 x_set_foreground_color (f
, arg
, oldval
)
1183 Lisp_Object arg
, oldval
;
1185 f
->output_data
.x
->foreground_pixel
1186 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1187 if (FRAME_X_WINDOW (f
) != 0)
1190 XSetForeground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->normal_gc
,
1191 f
->output_data
.x
->foreground_pixel
);
1192 XSetBackground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->reverse_gc
,
1193 f
->output_data
.x
->foreground_pixel
);
1195 recompute_basic_faces (f
);
1196 if (FRAME_VISIBLE_P (f
))
1202 x_set_background_color (f
, arg
, oldval
)
1204 Lisp_Object arg
, oldval
;
1209 f
->output_data
.x
->background_pixel
1210 = x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
1212 if (FRAME_X_WINDOW (f
) != 0)
1215 /* The main frame area. */
1216 XSetBackground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->normal_gc
,
1217 f
->output_data
.x
->background_pixel
);
1218 XSetForeground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->reverse_gc
,
1219 f
->output_data
.x
->background_pixel
);
1220 XSetForeground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->cursor_gc
,
1221 f
->output_data
.x
->background_pixel
);
1222 XSetWindowBackground (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1223 f
->output_data
.x
->background_pixel
);
1226 for (bar
= FRAME_SCROLL_BARS (f
); !NILP (bar
);
1227 bar
= XSCROLL_BAR (bar
)->next
)
1228 XSetWindowBackground (FRAME_X_DISPLAY (f
),
1229 SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
)),
1230 f
->output_data
.x
->background_pixel
);
1234 recompute_basic_faces (f
);
1236 if (FRAME_VISIBLE_P (f
))
1242 x_set_mouse_color (f
, arg
, oldval
)
1244 Lisp_Object arg
, oldval
;
1246 Cursor cursor
, nontext_cursor
, mode_cursor
, cross_cursor
;
1249 if (!EQ (Qnil
, arg
))
1250 f
->output_data
.x
->mouse_pixel
1251 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1252 mask_color
= f
->output_data
.x
->background_pixel
;
1253 /* No invisible pointers. */
1254 if (mask_color
== f
->output_data
.x
->mouse_pixel
1255 && mask_color
== f
->output_data
.x
->background_pixel
)
1256 f
->output_data
.x
->mouse_pixel
= f
->output_data
.x
->foreground_pixel
;
1260 /* It's not okay to crash if the user selects a screwy cursor. */
1261 x_catch_errors (FRAME_X_DISPLAY (f
));
1263 if (!EQ (Qnil
, Vx_pointer_shape
))
1265 CHECK_NUMBER (Vx_pointer_shape
, 0);
1266 cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XINT (Vx_pointer_shape
));
1269 cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_xterm
);
1270 x_check_errors (FRAME_X_DISPLAY (f
), "bad text pointer cursor: %s");
1272 if (!EQ (Qnil
, Vx_nontext_pointer_shape
))
1274 CHECK_NUMBER (Vx_nontext_pointer_shape
, 0);
1275 nontext_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
),
1276 XINT (Vx_nontext_pointer_shape
));
1279 nontext_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_left_ptr
);
1280 x_check_errors (FRAME_X_DISPLAY (f
), "bad nontext pointer cursor: %s");
1282 if (!EQ (Qnil
, Vx_mode_pointer_shape
))
1284 CHECK_NUMBER (Vx_mode_pointer_shape
, 0);
1285 mode_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
),
1286 XINT (Vx_mode_pointer_shape
));
1289 mode_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_xterm
);
1290 x_check_errors (FRAME_X_DISPLAY (f
), "bad modeline pointer cursor: %s");
1292 if (!EQ (Qnil
, Vx_sensitive_text_pointer_shape
))
1294 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
, 0);
1296 = XCreateFontCursor (FRAME_X_DISPLAY (f
),
1297 XINT (Vx_sensitive_text_pointer_shape
));
1300 cross_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f
), XC_crosshair
);
1302 /* Check and report errors with the above calls. */
1303 x_check_errors (FRAME_X_DISPLAY (f
), "can't set cursor shape: %s");
1304 x_uncatch_errors (FRAME_X_DISPLAY (f
));
1307 XColor fore_color
, back_color
;
1309 fore_color
.pixel
= f
->output_data
.x
->mouse_pixel
;
1310 back_color
.pixel
= mask_color
;
1311 XQueryColor (FRAME_X_DISPLAY (f
),
1312 DefaultColormap (FRAME_X_DISPLAY (f
),
1313 DefaultScreen (FRAME_X_DISPLAY (f
))),
1315 XQueryColor (FRAME_X_DISPLAY (f
),
1316 DefaultColormap (FRAME_X_DISPLAY (f
),
1317 DefaultScreen (FRAME_X_DISPLAY (f
))),
1319 XRecolorCursor (FRAME_X_DISPLAY (f
), cursor
,
1320 &fore_color
, &back_color
);
1321 XRecolorCursor (FRAME_X_DISPLAY (f
), nontext_cursor
,
1322 &fore_color
, &back_color
);
1323 XRecolorCursor (FRAME_X_DISPLAY (f
), mode_cursor
,
1324 &fore_color
, &back_color
);
1325 XRecolorCursor (FRAME_X_DISPLAY (f
), cross_cursor
,
1326 &fore_color
, &back_color
);
1329 if (FRAME_X_WINDOW (f
) != 0)
1331 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
1334 if (cursor
!= f
->output_data
.x
->text_cursor
&& f
->output_data
.x
->text_cursor
!= 0)
1335 XFreeCursor (FRAME_X_DISPLAY (f
), f
->output_data
.x
->text_cursor
);
1336 f
->output_data
.x
->text_cursor
= cursor
;
1338 if (nontext_cursor
!= f
->output_data
.x
->nontext_cursor
1339 && f
->output_data
.x
->nontext_cursor
!= 0)
1340 XFreeCursor (FRAME_X_DISPLAY (f
), f
->output_data
.x
->nontext_cursor
);
1341 f
->output_data
.x
->nontext_cursor
= nontext_cursor
;
1343 if (mode_cursor
!= f
->output_data
.x
->modeline_cursor
1344 && f
->output_data
.x
->modeline_cursor
!= 0)
1345 XFreeCursor (FRAME_X_DISPLAY (f
), f
->output_data
.x
->modeline_cursor
);
1346 f
->output_data
.x
->modeline_cursor
= mode_cursor
;
1347 if (cross_cursor
!= f
->output_data
.x
->cross_cursor
1348 && f
->output_data
.x
->cross_cursor
!= 0)
1349 XFreeCursor (FRAME_X_DISPLAY (f
), f
->output_data
.x
->cross_cursor
);
1350 f
->output_data
.x
->cross_cursor
= cross_cursor
;
1352 XFlush (FRAME_X_DISPLAY (f
));
1357 x_set_cursor_color (f
, arg
, oldval
)
1359 Lisp_Object arg
, oldval
;
1361 unsigned long fore_pixel
;
1363 if (!EQ (Vx_cursor_fore_pixel
, Qnil
))
1364 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
1365 WHITE_PIX_DEFAULT (f
));
1367 fore_pixel
= f
->output_data
.x
->background_pixel
;
1368 f
->output_data
.x
->cursor_pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1370 /* Make sure that the cursor color differs from the background color. */
1371 if (f
->output_data
.x
->cursor_pixel
== f
->output_data
.x
->background_pixel
)
1373 f
->output_data
.x
->cursor_pixel
= f
->output_data
.x
->mouse_pixel
;
1374 if (f
->output_data
.x
->cursor_pixel
== fore_pixel
)
1375 fore_pixel
= f
->output_data
.x
->background_pixel
;
1377 f
->output_data
.x
->cursor_foreground_pixel
= fore_pixel
;
1379 if (FRAME_X_WINDOW (f
) != 0)
1382 XSetBackground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->cursor_gc
,
1383 f
->output_data
.x
->cursor_pixel
);
1384 XSetForeground (FRAME_X_DISPLAY (f
), f
->output_data
.x
->cursor_gc
,
1388 if (FRAME_VISIBLE_P (f
))
1390 x_display_cursor (f
, 0);
1391 x_display_cursor (f
, 1);
1396 /* Set the border-color of frame F to value described by ARG.
1397 ARG can be a string naming a color.
1398 The border-color is used for the border that is drawn by the X server.
1399 Note that this does not fully take effect if done before
1400 F has an x-window; it must be redone when the window is created.
1402 Note: this is done in two routines because of the way X10 works.
1404 Note: under X11, this is normally the province of the window manager,
1405 and so emacs' border colors may be overridden. */
1408 x_set_border_color (f
, arg
, oldval
)
1410 Lisp_Object arg
, oldval
;
1415 CHECK_STRING (arg
, 0);
1416 str
= XSTRING (arg
)->data
;
1418 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1420 x_set_border_pixel (f
, pix
);
1423 /* Set the border-color of frame F to pixel value PIX.
1424 Note that this does not fully take effect if done before
1425 F has an x-window. */
1427 x_set_border_pixel (f
, pix
)
1431 f
->output_data
.x
->border_pixel
= pix
;
1433 if (FRAME_X_WINDOW (f
) != 0 && f
->output_data
.x
->border_width
> 0)
1439 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1440 (unsigned long)pix
);
1443 if (FRAME_VISIBLE_P (f
))
1449 x_set_cursor_type (f
, arg
, oldval
)
1451 Lisp_Object arg
, oldval
;
1455 FRAME_DESIRED_CURSOR (f
) = bar_cursor
;
1456 f
->output_data
.x
->cursor_width
= 2;
1458 else if (CONSP (arg
) && EQ (XCONS (arg
)->car
, Qbar
)
1459 && INTEGERP (XCONS (arg
)->cdr
))
1461 FRAME_DESIRED_CURSOR (f
) = bar_cursor
;
1462 f
->output_data
.x
->cursor_width
= XINT (XCONS (arg
)->cdr
);
1465 /* Treat anything unknown as "box cursor".
1466 It was bad to signal an error; people have trouble fixing
1467 .Xdefaults with Emacs, when it has something bad in it. */
1468 FRAME_DESIRED_CURSOR (f
) = filled_box_cursor
;
1470 /* Make sure the cursor gets redrawn. This is overkill, but how
1471 often do people change cursor types? */
1472 update_mode_lines
++;
1476 x_set_icon_type (f
, arg
, oldval
)
1478 Lisp_Object arg
, oldval
;
1485 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1488 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1493 result
= x_text_icon (f
,
1494 (char *) XSTRING ((!NILP (f
->icon_name
)
1498 result
= x_bitmap_icon (f
, arg
);
1503 error ("No icon window available");
1506 XFlush (FRAME_X_DISPLAY (f
));
1510 /* Return non-nil if frame F wants a bitmap icon. */
1518 tem
= assq_no_quit (Qicon_type
, f
->param_alist
);
1520 return XCONS (tem
)->cdr
;
1526 x_set_icon_name (f
, arg
, oldval
)
1528 Lisp_Object arg
, oldval
;
1535 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1538 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
1543 if (f
->output_data
.x
->icon_bitmap
!= 0)
1548 result
= x_text_icon (f
,
1549 (char *) XSTRING ((!NILP (f
->icon_name
)
1556 error ("No icon window available");
1559 XFlush (FRAME_X_DISPLAY (f
));
1563 extern Lisp_Object
x_new_font ();
1566 x_set_font (f
, arg
, oldval
)
1568 Lisp_Object arg
, oldval
;
1572 CHECK_STRING (arg
, 1);
1575 result
= x_new_font (f
, XSTRING (arg
)->data
);
1578 if (EQ (result
, Qnil
))
1579 error ("Font \"%s\" is not defined", XSTRING (arg
)->data
);
1580 else if (EQ (result
, Qt
))
1581 error ("the characters of the given font have varying widths");
1582 else if (STRINGP (result
))
1584 recompute_basic_faces (f
);
1585 store_frame_param (f
, Qfont
, result
);
1592 x_set_border_width (f
, arg
, oldval
)
1594 Lisp_Object arg
, oldval
;
1596 CHECK_NUMBER (arg
, 0);
1598 if (XINT (arg
) == f
->output_data
.x
->border_width
)
1601 if (FRAME_X_WINDOW (f
) != 0)
1602 error ("Cannot change the border width of a window");
1604 f
->output_data
.x
->border_width
= XINT (arg
);
1608 x_set_internal_border_width (f
, arg
, oldval
)
1610 Lisp_Object arg
, oldval
;
1613 int old
= f
->output_data
.x
->internal_border_width
;
1615 CHECK_NUMBER (arg
, 0);
1616 f
->output_data
.x
->internal_border_width
= XINT (arg
);
1617 if (f
->output_data
.x
->internal_border_width
< 0)
1618 f
->output_data
.x
->internal_border_width
= 0;
1620 if (f
->output_data
.x
->internal_border_width
== old
)
1623 if (FRAME_X_WINDOW (f
) != 0)
1626 x_set_window_size (f
, 0, f
->width
, f
->height
);
1628 x_set_resize_hint (f
);
1630 XFlush (FRAME_X_DISPLAY (f
));
1632 SET_FRAME_GARBAGED (f
);
1637 x_set_visibility (f
, value
, oldval
)
1639 Lisp_Object value
, oldval
;
1642 XSETFRAME (frame
, f
);
1645 Fmake_frame_invisible (frame
, Qt
);
1646 else if (EQ (value
, Qicon
))
1647 Ficonify_frame (frame
);
1649 Fmake_frame_visible (frame
);
1653 x_set_menu_bar_lines_1 (window
, n
)
1657 struct window
*w
= XWINDOW (window
);
1659 XSETFASTINT (w
->top
, XFASTINT (w
->top
) + n
);
1660 XSETFASTINT (w
->height
, XFASTINT (w
->height
) - n
);
1662 /* Handle just the top child in a vertical split. */
1663 if (!NILP (w
->vchild
))
1664 x_set_menu_bar_lines_1 (w
->vchild
, n
);
1666 /* Adjust all children in a horizontal split. */
1667 for (window
= w
->hchild
; !NILP (window
); window
= w
->next
)
1669 w
= XWINDOW (window
);
1670 x_set_menu_bar_lines_1 (window
, n
);
1675 x_set_menu_bar_lines (f
, value
, oldval
)
1677 Lisp_Object value
, oldval
;
1680 int olines
= FRAME_MENU_BAR_LINES (f
);
1682 /* Right now, menu bars don't work properly in minibuf-only frames;
1683 most of the commands try to apply themselves to the minibuffer
1684 frame itslef, and get an error because you can't switch buffers
1685 in or split the minibuffer window. */
1686 if (FRAME_MINIBUF_ONLY_P (f
))
1689 if (INTEGERP (value
))
1690 nlines
= XINT (value
);
1694 #ifdef USE_X_TOOLKIT
1695 FRAME_MENU_BAR_LINES (f
) = 0;
1698 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
1699 if (f
->output_data
.x
->menubar_widget
== 0)
1700 /* Make sure next redisplay shows the menu bar. */
1701 XWINDOW (FRAME_SELECTED_WINDOW (f
))->update_mode_line
= Qt
;
1705 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
1706 free_frame_menubar (f
);
1707 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
1708 f
->output_data
.x
->menubar_widget
= 0;
1710 #else /* not USE_X_TOOLKIT */
1711 FRAME_MENU_BAR_LINES (f
) = nlines
;
1712 x_set_menu_bar_lines_1 (f
->root_window
, nlines
- olines
);
1713 #endif /* not USE_X_TOOLKIT */
1716 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1719 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1720 name; if NAME is a string, set F's name to NAME and set
1721 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1723 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1724 suggesting a new name, which lisp code should override; if
1725 F->explicit_name is set, ignore the new name; otherwise, set it. */
1728 x_set_name (f
, name
, explicit)
1733 /* Make sure that requests from lisp code override requests from
1734 Emacs redisplay code. */
1737 /* If we're switching from explicit to implicit, we had better
1738 update the mode lines and thereby update the title. */
1739 if (f
->explicit_name
&& NILP (name
))
1740 update_mode_lines
= 1;
1742 f
->explicit_name
= ! NILP (name
);
1744 else if (f
->explicit_name
)
1747 /* If NAME is nil, set the name to the x_id_name. */
1750 /* Check for no change needed in this very common case
1751 before we do any consing. */
1752 if (!strcmp (FRAME_X_DISPLAY_INFO (f
)->x_id_name
,
1753 XSTRING (f
->name
)->data
))
1755 name
= build_string (FRAME_X_DISPLAY_INFO (f
)->x_id_name
);
1758 CHECK_STRING (name
, 0);
1760 /* Don't change the name if it's already NAME. */
1761 if (! NILP (Fstring_equal (name
, f
->name
)))
1764 if (FRAME_X_WINDOW (f
))
1769 XTextProperty text
, icon
;
1770 Lisp_Object icon_name
;
1772 text
.value
= XSTRING (name
)->data
;
1773 text
.encoding
= XA_STRING
;
1775 text
.nitems
= XSTRING (name
)->size
;
1777 icon_name
= (!NILP (f
->icon_name
) ? f
->icon_name
: name
);
1779 icon
.value
= XSTRING (icon_name
)->data
;
1780 icon
.encoding
= XA_STRING
;
1782 icon
.nitems
= XSTRING (icon_name
)->size
;
1783 #ifdef USE_X_TOOLKIT
1784 XSetWMName (FRAME_X_DISPLAY (f
),
1785 XtWindow (f
->output_data
.x
->widget
), &text
);
1786 XSetWMIconName (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
),
1788 #else /* not USE_X_TOOLKIT */
1789 XSetWMName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &text
);
1790 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &icon
);
1791 #endif /* not USE_X_TOOLKIT */
1793 #else /* not HAVE_X11R4 */
1794 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1795 XSTRING (name
)->data
);
1796 XStoreName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1797 XSTRING (name
)->data
);
1798 #endif /* not HAVE_X11R4 */
1805 /* This function should be called when the user's lisp code has
1806 specified a name for the frame; the name will override any set by the
1809 x_explicitly_set_name (f
, arg
, oldval
)
1811 Lisp_Object arg
, oldval
;
1813 x_set_name (f
, arg
, 1);
1816 /* This function should be called by Emacs redisplay code to set the
1817 name; names set this way will never override names set by the user's
1820 x_implicitly_set_name (f
, arg
, oldval
)
1822 Lisp_Object arg
, oldval
;
1824 x_set_name (f
, arg
, 0);
1828 x_set_autoraise (f
, arg
, oldval
)
1830 Lisp_Object arg
, oldval
;
1832 f
->auto_raise
= !EQ (Qnil
, arg
);
1836 x_set_autolower (f
, arg
, oldval
)
1838 Lisp_Object arg
, oldval
;
1840 f
->auto_lower
= !EQ (Qnil
, arg
);
1844 x_set_unsplittable (f
, arg
, oldval
)
1846 Lisp_Object arg
, oldval
;
1848 f
->no_split
= !NILP (arg
);
1852 x_set_vertical_scroll_bars (f
, arg
, oldval
)
1854 Lisp_Object arg
, oldval
;
1856 if (NILP (arg
) != ! FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
1858 FRAME_HAS_VERTICAL_SCROLL_BARS (f
) = ! NILP (arg
);
1860 /* We set this parameter before creating the X window for the
1861 frame, so we can get the geometry right from the start.
1862 However, if the window hasn't been created yet, we shouldn't
1863 call x_set_window_size. */
1864 if (FRAME_X_WINDOW (f
))
1865 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
1870 x_set_scroll_bar_width (f
, arg
, oldval
)
1872 Lisp_Object arg
, oldval
;
1876 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = 0;
1877 FRAME_SCROLL_BAR_COLS (f
) = 2;
1879 else if (INTEGERP (arg
) && XINT (arg
) > 0
1880 && XFASTINT (arg
) != FRAME_SCROLL_BAR_PIXEL_WIDTH (f
))
1882 int wid
= FONT_WIDTH (f
->output_data
.x
->font
);
1883 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = XFASTINT (arg
);
1884 FRAME_SCROLL_BAR_COLS (f
) = (XFASTINT (arg
) + wid
-1) / wid
;
1885 if (FRAME_X_WINDOW (f
))
1886 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
1890 /* Subroutines of creating an X frame. */
1892 /* Make sure that Vx_resource_name is set to a reasonable value.
1893 Fix it up, or set it to `emacs' if it is too hopeless. */
1896 validate_x_resource_name ()
1899 /* Number of valid characters in the resource name. */
1901 /* Number of invalid characters in the resource name. */
1906 if (STRINGP (Vx_resource_name
))
1908 unsigned char *p
= XSTRING (Vx_resource_name
)->data
;
1911 len
= XSTRING (Vx_resource_name
)->size
;
1913 /* Only letters, digits, - and _ are valid in resource names.
1914 Count the valid characters and count the invalid ones. */
1915 for (i
= 0; i
< len
; i
++)
1918 if (! ((c
>= 'a' && c
<= 'z')
1919 || (c
>= 'A' && c
<= 'Z')
1920 || (c
>= '0' && c
<= '9')
1921 || c
== '-' || c
== '_'))
1928 /* Not a string => completely invalid. */
1929 bad_count
= 5, good_count
= 0;
1931 /* If name is valid already, return. */
1935 /* If name is entirely invalid, or nearly so, use `emacs'. */
1937 || (good_count
== 1 && bad_count
> 0))
1939 Vx_resource_name
= build_string ("emacs");
1943 /* Name is partly valid. Copy it and replace the invalid characters
1944 with underscores. */
1946 Vx_resource_name
= new = Fcopy_sequence (Vx_resource_name
);
1948 for (i
= 0; i
< len
; i
++)
1950 int c
= XSTRING (new)->data
[i
];
1951 if (! ((c
>= 'a' && c
<= 'z')
1952 || (c
>= 'A' && c
<= 'Z')
1953 || (c
>= '0' && c
<= '9')
1954 || c
== '-' || c
== '_'))
1955 XSTRING (new)->data
[i
] = '_';
1960 extern char *x_get_string_resource ();
1962 DEFUN ("x-get-resource", Fx_get_resource
, Sx_get_resource
, 2, 4, 0,
1963 "Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.\n\
1964 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the\n\
1965 class, where INSTANCE is the name under which Emacs was invoked, or\n\
1966 the name specified by the `-name' or `-rn' command-line arguments.\n\
1968 The optional arguments COMPONENT and SUBCLASS add to the key and the\n\
1969 class, respectively. You must specify both of them or neither.\n\
1970 If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'\n\
1971 and the class is `Emacs.CLASS.SUBCLASS'.")
1972 (attribute
, class, component
, subclass
)
1973 Lisp_Object attribute
, class, component
, subclass
;
1975 register char *value
;
1981 CHECK_STRING (attribute
, 0);
1982 CHECK_STRING (class, 0);
1984 if (!NILP (component
))
1985 CHECK_STRING (component
, 1);
1986 if (!NILP (subclass
))
1987 CHECK_STRING (subclass
, 2);
1988 if (NILP (component
) != NILP (subclass
))
1989 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
1991 validate_x_resource_name ();
1993 /* Allocate space for the components, the dots which separate them,
1994 and the final '\0'. Make them big enough for the worst case. */
1995 name_key
= (char *) alloca (XSTRING (Vx_resource_name
)->size
1996 + (STRINGP (component
)
1997 ? XSTRING (component
)->size
: 0)
1998 + XSTRING (attribute
)->size
2001 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
2002 + XSTRING (class)->size
2003 + (STRINGP (subclass
)
2004 ? XSTRING (subclass
)->size
: 0)
2007 /* Start with emacs.FRAMENAME for the name (the specific one)
2008 and with `Emacs' for the class key (the general one). */
2009 strcpy (name_key
, XSTRING (Vx_resource_name
)->data
);
2010 strcpy (class_key
, EMACS_CLASS
);
2012 strcat (class_key
, ".");
2013 strcat (class_key
, XSTRING (class)->data
);
2015 if (!NILP (component
))
2017 strcat (class_key
, ".");
2018 strcat (class_key
, XSTRING (subclass
)->data
);
2020 strcat (name_key
, ".");
2021 strcat (name_key
, XSTRING (component
)->data
);
2024 strcat (name_key
, ".");
2025 strcat (name_key
, XSTRING (attribute
)->data
);
2027 value
= x_get_string_resource (check_x_display_info (Qnil
)->xrdb
,
2028 name_key
, class_key
);
2030 if (value
!= (char *) 0)
2031 return build_string (value
);
2036 /* Used when C code wants a resource value. */
2039 x_get_resource_string (attribute
, class)
2040 char *attribute
, *class;
2042 register char *value
;
2046 /* Allocate space for the components, the dots which separate them,
2047 and the final '\0'. */
2048 name_key
= (char *) alloca (XSTRING (Vinvocation_name
)->size
2049 + strlen (attribute
) + 2);
2050 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
2051 + strlen (class) + 2);
2053 sprintf (name_key
, "%s.%s",
2054 XSTRING (Vinvocation_name
)->data
,
2056 sprintf (class_key
, "%s.%s", EMACS_CLASS
, class);
2058 return x_get_string_resource (FRAME_X_DISPLAY_INFO (selected_frame
)->xrdb
,
2059 name_key
, class_key
);
2062 /* Types we might convert a resource string into. */
2065 number
, boolean
, string
, symbol
2068 /* Return the value of parameter PARAM.
2070 First search ALIST, then Vdefault_frame_alist, then the X defaults
2071 database, using ATTRIBUTE as the attribute name and CLASS as its class.
2073 Convert the resource to the type specified by desired_type.
2075 If no default is specified, return Qunbound. If you call
2076 x_get_arg, make sure you deal with Qunbound in a reasonable way,
2077 and don't let it get stored in any Lisp-visible variables! */
2080 x_get_arg (alist
, param
, attribute
, class, type
)
2081 Lisp_Object alist
, param
;
2084 enum resource_types type
;
2086 register Lisp_Object tem
;
2088 tem
= Fassq (param
, alist
);
2090 tem
= Fassq (param
, Vdefault_frame_alist
);
2096 tem
= Fx_get_resource (build_string (attribute
),
2097 build_string (class),
2106 return make_number (atoi (XSTRING (tem
)->data
));
2109 tem
= Fdowncase (tem
);
2110 if (!strcmp (XSTRING (tem
)->data
, "on")
2111 || !strcmp (XSTRING (tem
)->data
, "true"))
2120 /* As a special case, we map the values `true' and `on'
2121 to Qt, and `false' and `off' to Qnil. */
2124 lower
= Fdowncase (tem
);
2125 if (!strcmp (XSTRING (lower
)->data
, "on")
2126 || !strcmp (XSTRING (lower
)->data
, "true"))
2128 else if (!strcmp (XSTRING (lower
)->data
, "off")
2129 || !strcmp (XSTRING (lower
)->data
, "false"))
2132 return Fintern (tem
, Qnil
);
2145 /* Record in frame F the specified or default value according to ALIST
2146 of the parameter named PARAM (a Lisp symbol).
2147 If no value is specified for PARAM, look for an X default for XPROP
2148 on the frame named NAME.
2149 If that is not found either, use the value DEFLT. */
2152 x_default_parameter (f
, alist
, prop
, deflt
, xprop
, xclass
, type
)
2159 enum resource_types type
;
2163 tem
= x_get_arg (alist
, prop
, xprop
, xclass
, type
);
2164 if (EQ (tem
, Qunbound
))
2166 x_set_frame_parameters (f
, Fcons (Fcons (prop
, tem
), Qnil
));
2170 DEFUN ("x-parse-geometry", Fx_parse_geometry
, Sx_parse_geometry
, 1, 1, 0,
2171 "Parse an X-style geometry string STRING.\n\
2172 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).\n\
2173 The properties returned may include `top', `left', `height', and `width'.\n\
2174 The value of `left' or `top' may be an integer,\n\
2175 or a list (+ N) meaning N pixels relative to top/left corner,\n\
2176 or a list (- N) meaning -N pixels relative to bottom/right corner.")
2181 unsigned int width
, height
;
2184 CHECK_STRING (string
, 0);
2186 geometry
= XParseGeometry ((char *) XSTRING (string
)->data
,
2187 &x
, &y
, &width
, &height
);
2190 if (!!(geometry
& XValue
) != !!(geometry
& YValue
))
2191 error ("Must specify both x and y position, or neither");
2195 if (geometry
& XValue
)
2197 Lisp_Object element
;
2199 if (x
>= 0 && (geometry
& XNegative
))
2200 element
= Fcons (Qleft
, Fcons (Qminus
, Fcons (make_number (-x
), Qnil
)));
2201 else if (x
< 0 && ! (geometry
& XNegative
))
2202 element
= Fcons (Qleft
, Fcons (Qplus
, Fcons (make_number (x
), Qnil
)));
2204 element
= Fcons (Qleft
, make_number (x
));
2205 result
= Fcons (element
, result
);
2208 if (geometry
& YValue
)
2210 Lisp_Object element
;
2212 if (y
>= 0 && (geometry
& YNegative
))
2213 element
= Fcons (Qtop
, Fcons (Qminus
, Fcons (make_number (-y
), Qnil
)));
2214 else if (y
< 0 && ! (geometry
& YNegative
))
2215 element
= Fcons (Qtop
, Fcons (Qplus
, Fcons (make_number (y
), Qnil
)));
2217 element
= Fcons (Qtop
, make_number (y
));
2218 result
= Fcons (element
, result
);
2221 if (geometry
& WidthValue
)
2222 result
= Fcons (Fcons (Qwidth
, make_number (width
)), result
);
2223 if (geometry
& HeightValue
)
2224 result
= Fcons (Fcons (Qheight
, make_number (height
)), result
);
2229 /* Calculate the desired size and position of this window,
2230 and return the flags saying which aspects were specified.
2232 This function does not make the coordinates positive. */
2234 #define DEFAULT_ROWS 40
2235 #define DEFAULT_COLS 80
2238 x_figure_window_size (f
, parms
)
2242 register Lisp_Object tem0
, tem1
, tem2
;
2243 int height
, width
, left
, top
;
2244 register int geometry
;
2245 long window_prompting
= 0;
2247 /* Default values if we fall through.
2248 Actually, if that happens we should get
2249 window manager prompting. */
2250 f
->width
= DEFAULT_COLS
;
2251 f
->height
= DEFAULT_ROWS
;
2252 /* Window managers expect that if program-specified
2253 positions are not (0,0), they're intentional, not defaults. */
2254 f
->output_data
.x
->top_pos
= 0;
2255 f
->output_data
.x
->left_pos
= 0;
2257 tem0
= x_get_arg (parms
, Qheight
, 0, 0, number
);
2258 tem1
= x_get_arg (parms
, Qwidth
, 0, 0, number
);
2259 tem2
= x_get_arg (parms
, Quser_size
, 0, 0, number
);
2260 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
2262 if (!EQ (tem0
, Qunbound
))
2264 CHECK_NUMBER (tem0
, 0);
2265 f
->height
= XINT (tem0
);
2267 if (!EQ (tem1
, Qunbound
))
2269 CHECK_NUMBER (tem1
, 0);
2270 f
->width
= XINT (tem1
);
2272 if (!NILP (tem2
) && !EQ (tem2
, Qunbound
))
2273 window_prompting
|= USSize
;
2275 window_prompting
|= PSize
;
2278 f
->output_data
.x
->vertical_scroll_bar_extra
2279 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
2281 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0
2282 ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f
)
2283 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.x
->font
)));
2284 f
->output_data
.x
->pixel_width
= CHAR_TO_PIXEL_WIDTH (f
, f
->width
);
2285 f
->output_data
.x
->pixel_height
= CHAR_TO_PIXEL_HEIGHT (f
, f
->height
);
2287 tem0
= x_get_arg (parms
, Qtop
, 0, 0, number
);
2288 tem1
= x_get_arg (parms
, Qleft
, 0, 0, number
);
2289 tem2
= x_get_arg (parms
, Quser_position
, 0, 0, number
);
2290 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
2292 if (EQ (tem0
, Qminus
))
2294 f
->output_data
.x
->top_pos
= 0;
2295 window_prompting
|= YNegative
;
2297 else if (CONSP (tem0
) && EQ (XCONS (tem0
)->car
, Qminus
)
2298 && CONSP (XCONS (tem0
)->cdr
)
2299 && INTEGERP (XCONS (XCONS (tem0
)->cdr
)->car
))
2301 f
->output_data
.x
->top_pos
= - XINT (XCONS (XCONS (tem0
)->cdr
)->car
);
2302 window_prompting
|= YNegative
;
2304 else if (CONSP (tem0
) && EQ (XCONS (tem0
)->car
, Qplus
)
2305 && CONSP (XCONS (tem0
)->cdr
)
2306 && INTEGERP (XCONS (XCONS (tem0
)->cdr
)->car
))
2308 f
->output_data
.x
->top_pos
= XINT (XCONS (XCONS (tem0
)->cdr
)->car
);
2310 else if (EQ (tem0
, Qunbound
))
2311 f
->output_data
.x
->top_pos
= 0;
2314 CHECK_NUMBER (tem0
, 0);
2315 f
->output_data
.x
->top_pos
= XINT (tem0
);
2316 if (f
->output_data
.x
->top_pos
< 0)
2317 window_prompting
|= YNegative
;
2320 if (EQ (tem1
, Qminus
))
2322 f
->output_data
.x
->left_pos
= 0;
2323 window_prompting
|= XNegative
;
2325 else if (CONSP (tem1
) && EQ (XCONS (tem1
)->car
, Qminus
)
2326 && CONSP (XCONS (tem1
)->cdr
)
2327 && INTEGERP (XCONS (XCONS (tem1
)->cdr
)->car
))
2329 f
->output_data
.x
->left_pos
= - XINT (XCONS (XCONS (tem1
)->cdr
)->car
);
2330 window_prompting
|= XNegative
;
2332 else if (CONSP (tem1
) && EQ (XCONS (tem1
)->car
, Qplus
)
2333 && CONSP (XCONS (tem1
)->cdr
)
2334 && INTEGERP (XCONS (XCONS (tem1
)->cdr
)->car
))
2336 f
->output_data
.x
->left_pos
= XINT (XCONS (XCONS (tem1
)->cdr
)->car
);
2338 else if (EQ (tem1
, Qunbound
))
2339 f
->output_data
.x
->left_pos
= 0;
2342 CHECK_NUMBER (tem1
, 0);
2343 f
->output_data
.x
->left_pos
= XINT (tem1
);
2344 if (f
->output_data
.x
->left_pos
< 0)
2345 window_prompting
|= XNegative
;
2348 if (!NILP (tem2
) && ! EQ (tem2
, Qunbound
))
2349 window_prompting
|= USPosition
;
2351 window_prompting
|= PPosition
;
2354 return window_prompting
;
2357 #if !defined (HAVE_X11R4) && !defined (HAVE_XSETWMPROTOCOLS)
2360 XSetWMProtocols (dpy
, w
, protocols
, count
)
2367 prop
= XInternAtom (dpy
, "WM_PROTOCOLS", False
);
2368 if (prop
== None
) return False
;
2369 XChangeProperty (dpy
, w
, prop
, XA_ATOM
, 32, PropModeReplace
,
2370 (unsigned char *) protocols
, count
);
2373 #endif /* not HAVE_X11R4 && not HAVE_XSETWMPROTOCOLS */
2375 #ifdef USE_X_TOOLKIT
2377 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
2378 WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them. (They may
2379 already be present because of the toolkit (Motif adds some of them,
2380 for example, but Xt doesn't). */
2383 hack_wm_protocols (f
, widget
)
2387 Display
*dpy
= XtDisplay (widget
);
2388 Window w
= XtWindow (widget
);
2389 int need_delete
= 1;
2395 Atom type
, *atoms
= 0;
2397 unsigned long nitems
= 0;
2398 unsigned long bytes_after
;
2400 if ((XGetWindowProperty (dpy
, w
,
2401 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2402 (long)0, (long)100, False
, XA_ATOM
,
2403 &type
, &format
, &nitems
, &bytes_after
,
2404 (unsigned char **) &atoms
)
2406 && format
== 32 && type
== XA_ATOM
)
2410 if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
)
2412 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
)
2414 else if (atoms
[nitems
] == FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
)
2417 if (atoms
) XFree ((char *) atoms
);
2423 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2425 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_take_focus
;
2427 props
[count
++] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2429 XChangeProperty (dpy
, w
, FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2430 XA_ATOM
, 32, PropModeAppend
,
2431 (unsigned char *) props
, count
);
2437 #ifdef USE_X_TOOLKIT
2439 /* Create and set up the X widget for frame F. */
2442 x_window (f
, window_prompting
, minibuffer_only
)
2444 long window_prompting
;
2445 int minibuffer_only
;
2447 XClassHint class_hints
;
2448 XSetWindowAttributes attributes
;
2449 unsigned long attribute_mask
;
2451 Widget shell_widget
;
2453 Widget frame_widget
;
2459 /* Use the resource name as the top-level widget name
2460 for looking up resources. Make a non-Lisp copy
2461 for the window manager, so GC relocation won't bother it.
2463 Elsewhere we specify the window name for the window manager. */
2466 char *str
= (char *) XSTRING (Vx_resource_name
)->data
;
2467 f
->namebuf
= (char *) xmalloc (strlen (str
) + 1);
2468 strcpy (f
->namebuf
, str
);
2472 XtSetArg (al
[ac
], XtNallowShellResize
, 1); ac
++;
2473 XtSetArg (al
[ac
], XtNinput
, 1); ac
++;
2474 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2475 XtSetArg (al
[ac
], XtNborderWidth
, f
->output_data
.x
->border_width
); ac
++;
2476 shell_widget
= XtAppCreateShell (f
->namebuf
, EMACS_CLASS
,
2477 applicationShellWidgetClass
,
2478 FRAME_X_DISPLAY (f
), al
, ac
);
2480 f
->output_data
.x
->widget
= shell_widget
;
2481 /* maybe_set_screen_title_format (shell_widget); */
2483 pane_widget
= lw_create_widget ("main", "pane", widget_id_tick
++,
2484 (widget_value
*) NULL
,
2485 shell_widget
, False
,
2488 (lw_callback
) NULL
);
2490 f
->output_data
.x
->column_widget
= pane_widget
;
2492 /* mappedWhenManaged to false tells to the paned window to not map/unmap
2493 the emacs screen when changing menubar. This reduces flickering. */
2496 XtSetArg (al
[ac
], XtNmappedWhenManaged
, 0); ac
++;
2497 XtSetArg (al
[ac
], XtNshowGrip
, 0); ac
++;
2498 XtSetArg (al
[ac
], XtNallowResize
, 1); ac
++;
2499 XtSetArg (al
[ac
], XtNresizeToPreferred
, 1); ac
++;
2500 XtSetArg (al
[ac
], XtNemacsFrame
, f
); ac
++;
2501 frame_widget
= XtCreateWidget (f
->namebuf
,
2503 pane_widget
, al
, ac
);
2505 f
->output_data
.x
->edit_widget
= frame_widget
;
2507 XtManageChild (frame_widget
);
2509 /* Do some needed geometry management. */
2512 char *tem
, shell_position
[32];
2515 int extra_borders
= 0;
2517 = (f
->output_data
.x
->menubar_widget
2518 ? (f
->output_data
.x
->menubar_widget
->core
.height
2519 + f
->output_data
.x
->menubar_widget
->core
.border_width
)
2521 extern char *lwlib_toolkit_type
;
2523 if (FRAME_EXTERNAL_MENU_BAR (f
))
2526 XtVaGetValues (pane_widget
, XtNinternalBorderWidth
, &ibw
, NULL
);
2527 menubar_size
+= ibw
;
2530 f
->output_data
.x
->menubar_height
= menubar_size
;
2532 /* Motif seems to need this amount added to the sizes
2533 specified for the shell widget. The Athena/Lucid widgets don't.
2534 Both conclusions reached experimentally. -- rms. */
2535 if (!strcmp (lwlib_toolkit_type
, "motif"))
2536 XtVaGetValues (f
->output_data
.x
->edit_widget
, XtNinternalBorderWidth
,
2537 &extra_borders
, NULL
);
2539 /* Convert our geometry parameters into a geometry string
2541 Note that we do not specify here whether the position
2542 is a user-specified or program-specified one.
2543 We pass that information later, in x_wm_set_size_hints. */
2545 int left
= f
->output_data
.x
->left_pos
;
2546 int xneg
= window_prompting
& XNegative
;
2547 int top
= f
->output_data
.x
->top_pos
;
2548 int yneg
= window_prompting
& YNegative
;
2554 if (window_prompting
& USPosition
)
2555 sprintf (shell_position
, "=%dx%d%c%d%c%d",
2556 PIXEL_WIDTH (f
) + extra_borders
,
2557 PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
,
2558 (xneg
? '-' : '+'), left
,
2559 (yneg
? '-' : '+'), top
);
2561 sprintf (shell_position
, "=%dx%d",
2562 PIXEL_WIDTH (f
) + extra_borders
,
2563 PIXEL_HEIGHT (f
) + menubar_size
+ extra_borders
);
2566 len
= strlen (shell_position
) + 1;
2567 tem
= (char *) xmalloc (len
);
2568 strncpy (tem
, shell_position
, len
);
2569 XtSetArg (al
[ac
], XtNgeometry
, tem
); ac
++;
2570 XtSetValues (shell_widget
, al
, ac
);
2573 XtManageChild (pane_widget
);
2574 XtRealizeWidget (shell_widget
);
2576 FRAME_X_WINDOW (f
) = XtWindow (frame_widget
);
2578 validate_x_resource_name ();
2580 class_hints
.res_name
= (char *) XSTRING (Vx_resource_name
)->data
;
2581 class_hints
.res_class
= EMACS_CLASS
;
2582 XSetClassHint (FRAME_X_DISPLAY (f
), XtWindow (shell_widget
), &class_hints
);
2584 f
->output_data
.x
->wm_hints
.input
= True
;
2585 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2586 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2587 &f
->output_data
.x
->wm_hints
);
2589 hack_wm_protocols (f
, shell_widget
);
2592 XtAddEventHandler (shell_widget
, 0, True
, _XEditResCheckMessages
, 0);
2595 /* Do a stupid property change to force the server to generate a
2596 propertyNotify event so that the event_stream server timestamp will
2597 be initialized to something relevant to the time we created the window.
2599 XChangeProperty (XtDisplay (frame_widget
), XtWindow (frame_widget
),
2600 FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_protocols
,
2601 XA_ATOM
, 32, PropModeAppend
,
2602 (unsigned char*) NULL
, 0);
2604 /* Make all the standard events reach the Emacs frame. */
2605 attributes
.event_mask
= STANDARD_EVENT_SET
;
2606 attribute_mask
= CWEventMask
;
2607 XChangeWindowAttributes (XtDisplay (shell_widget
), XtWindow (shell_widget
),
2608 attribute_mask
, &attributes
);
2610 XtMapWidget (frame_widget
);
2612 /* x_set_name normally ignores requests to set the name if the
2613 requested name is the same as the current name. This is the one
2614 place where that assumption isn't correct; f->name is set, but
2615 the X server hasn't been told. */
2618 int explicit = f
->explicit_name
;
2620 f
->explicit_name
= 0;
2623 x_set_name (f
, name
, explicit);
2626 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2627 f
->output_data
.x
->text_cursor
);
2631 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
2632 initialize_frame_menubar (f
);
2633 lw_set_main_areas (pane_widget
, f
->output_data
.x
->menubar_widget
, frame_widget
);
2635 if (FRAME_X_WINDOW (f
) == 0)
2636 error ("Unable to create window");
2639 #else /* not USE_X_TOOLKIT */
2641 /* Create and set up the X window for frame F. */
2647 XClassHint class_hints
;
2648 XSetWindowAttributes attributes
;
2649 unsigned long attribute_mask
;
2651 attributes
.background_pixel
= f
->output_data
.x
->background_pixel
;
2652 attributes
.border_pixel
= f
->output_data
.x
->border_pixel
;
2653 attributes
.bit_gravity
= StaticGravity
;
2654 attributes
.backing_store
= NotUseful
;
2655 attributes
.save_under
= True
;
2656 attributes
.event_mask
= STANDARD_EVENT_SET
;
2657 attribute_mask
= (CWBackPixel
| CWBorderPixel
| CWBitGravity
2659 | CWBackingStore
| CWSaveUnder
2665 = XCreateWindow (FRAME_X_DISPLAY (f
),
2666 f
->output_data
.x
->parent_desc
,
2667 f
->output_data
.x
->left_pos
,
2668 f
->output_data
.x
->top_pos
,
2669 PIXEL_WIDTH (f
), PIXEL_HEIGHT (f
),
2670 f
->output_data
.x
->border_width
,
2671 CopyFromParent
, /* depth */
2672 InputOutput
, /* class */
2673 FRAME_X_DISPLAY_INFO (f
)->visual
,
2674 attribute_mask
, &attributes
);
2676 validate_x_resource_name ();
2678 class_hints
.res_name
= (char *) XSTRING (Vx_resource_name
)->data
;
2679 class_hints
.res_class
= EMACS_CLASS
;
2680 XSetClassHint (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &class_hints
);
2682 /* The menubar is part of the ordinary display;
2683 it does not count in addition to the height of the window. */
2684 f
->output_data
.x
->menubar_height
= 0;
2686 /* This indicates that we use the "Passive Input" input model.
2687 Unless we do this, we don't get the Focus{In,Out} events that we
2688 need to draw the cursor correctly. Accursed bureaucrats.
2689 XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */
2691 f
->output_data
.x
->wm_hints
.input
= True
;
2692 f
->output_data
.x
->wm_hints
.flags
|= InputHint
;
2693 XSetWMHints (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2694 &f
->output_data
.x
->wm_hints
);
2696 /* Request "save yourself" and "delete window" commands from wm. */
2699 protocols
[0] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_delete_window
;
2700 protocols
[1] = FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_save_yourself
;
2701 XSetWMProtocols (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), protocols
, 2);
2704 /* x_set_name normally ignores requests to set the name if the
2705 requested name is the same as the current name. This is the one
2706 place where that assumption isn't correct; f->name is set, but
2707 the X server hasn't been told. */
2710 int explicit = f
->explicit_name
;
2712 f
->explicit_name
= 0;
2715 x_set_name (f
, name
, explicit);
2718 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2719 f
->output_data
.x
->text_cursor
);
2723 if (FRAME_X_WINDOW (f
) == 0)
2724 error ("Unable to create window");
2727 #endif /* not USE_X_TOOLKIT */
2729 /* Handle the icon stuff for this window. Perhaps later we might
2730 want an x_set_icon_position which can be called interactively as
2738 Lisp_Object icon_x
, icon_y
;
2740 /* Set the position of the icon. Note that twm groups all
2741 icons in an icon window. */
2742 icon_x
= x_get_arg (parms
, Qicon_left
, 0, 0, number
);
2743 icon_y
= x_get_arg (parms
, Qicon_top
, 0, 0, number
);
2744 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
2746 CHECK_NUMBER (icon_x
, 0);
2747 CHECK_NUMBER (icon_y
, 0);
2749 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
2750 error ("Both left and top icon corners of icon must be specified");
2754 if (! EQ (icon_x
, Qunbound
))
2755 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
2757 /* Start up iconic or window? */
2758 x_wm_set_window_state
2759 (f
, (EQ (x_get_arg (parms
, Qvisibility
, 0, 0, symbol
), Qicon
)
2763 x_text_icon (f
, (char *) XSTRING ((!NILP (f
->icon_name
)
2770 /* Make the GC's needed for this window, setting the
2771 background, border and mouse colors; also create the
2772 mouse cursor and the gray border tile. */
2774 static char cursor_bits
[] =
2776 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2777 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2778 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2779 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2786 XGCValues gc_values
;
2792 /* Create the GC's of this frame.
2793 Note that many default values are used. */
2796 gc_values
.font
= f
->output_data
.x
->font
->fid
;
2797 gc_values
.foreground
= f
->output_data
.x
->foreground_pixel
;
2798 gc_values
.background
= f
->output_data
.x
->background_pixel
;
2799 gc_values
.line_width
= 0; /* Means 1 using fast algorithm. */
2800 f
->output_data
.x
->normal_gc
= XCreateGC (FRAME_X_DISPLAY (f
),
2802 GCLineWidth
| GCFont
2803 | GCForeground
| GCBackground
,
2806 /* Reverse video style. */
2807 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
2808 gc_values
.background
= f
->output_data
.x
->foreground_pixel
;
2809 f
->output_data
.x
->reverse_gc
= XCreateGC (FRAME_X_DISPLAY (f
),
2811 GCFont
| GCForeground
| GCBackground
2815 /* Cursor has cursor-color background, background-color foreground. */
2816 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
2817 gc_values
.background
= f
->output_data
.x
->cursor_pixel
;
2818 gc_values
.fill_style
= FillOpaqueStippled
;
2820 = XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
2821 FRAME_X_DISPLAY_INFO (f
)->root_window
,
2822 cursor_bits
, 16, 16);
2823 f
->output_data
.x
->cursor_gc
2824 = XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2825 (GCFont
| GCForeground
| GCBackground
2826 | GCFillStyle
| GCStipple
| GCLineWidth
),
2829 /* Create the gray border tile used when the pointer is not in
2830 the frame. Since this depends on the frame's pixel values,
2831 this must be done on a per-frame basis. */
2832 f
->output_data
.x
->border_tile
2833 = (XCreatePixmapFromBitmapData
2834 (FRAME_X_DISPLAY (f
), FRAME_X_DISPLAY_INFO (f
)->root_window
,
2835 gray_bits
, gray_width
, gray_height
,
2836 f
->output_data
.x
->foreground_pixel
,
2837 f
->output_data
.x
->background_pixel
,
2838 DefaultDepth (FRAME_X_DISPLAY (f
),
2839 XScreenNumberOfScreen (FRAME_X_SCREEN (f
)))));
2844 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
2846 "Make a new X window, which is called a \"frame\" in Emacs terms.\n\
2847 Returns an Emacs frame object.\n\
2848 ALIST is an alist of frame parameters.\n\
2849 If the parameters specify that the frame should not have a minibuffer,\n\
2850 and do not specify a specific minibuffer window to use,\n\
2851 then `default-minibuffer-frame' must be a frame whose minibuffer can\n\
2852 be shared by the new frame.\n\
2854 This function is an internal primitive--use `make-frame' instead.")
2859 Lisp_Object frame
, tem
;
2861 int minibuffer_only
= 0;
2862 long window_prompting
= 0;
2864 int count
= specpdl_ptr
- specpdl
;
2865 struct gcpro gcpro1
;
2866 Lisp_Object display
;
2867 struct x_display_info
*dpyinfo
;
2873 /* Use this general default value to start with
2874 until we know if this frame has a specified name. */
2875 Vx_resource_name
= Vinvocation_name
;
2877 display
= x_get_arg (parms
, Qdisplay
, 0, 0, string
);
2878 if (EQ (display
, Qunbound
))
2880 dpyinfo
= check_x_display_info (display
);
2882 kb
= dpyinfo
->kboard
;
2884 kb
= &the_only_kboard
;
2887 name
= x_get_arg (parms
, Qname
, "title", "Title", string
);
2889 && ! EQ (name
, Qunbound
)
2891 error ("Invalid frame name--not a string or nil");
2894 Vx_resource_name
= name
;
2896 /* See if parent window is specified. */
2897 parent
= x_get_arg (parms
, Qparent_id
, NULL
, NULL
, number
);
2898 if (EQ (parent
, Qunbound
))
2900 if (! NILP (parent
))
2901 CHECK_NUMBER (parent
, 0);
2903 tem
= x_get_arg (parms
, Qminibuffer
, 0, 0, symbol
);
2904 if (EQ (tem
, Qnone
) || NILP (tem
))
2905 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
2906 else if (EQ (tem
, Qonly
))
2908 f
= make_minibuffer_frame ();
2909 minibuffer_only
= 1;
2911 else if (WINDOWP (tem
))
2912 f
= make_frame_without_minibuffer (tem
, kb
, display
);
2916 /* Note that X Windows does support scroll bars. */
2917 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
2919 XSETFRAME (frame
, f
);
2922 f
->output_method
= output_x_window
;
2923 f
->output_data
.x
= (struct x_output
*) xmalloc (sizeof (struct x_output
));
2924 bzero (f
->output_data
.x
, sizeof (struct x_output
));
2925 f
->output_data
.x
->icon_bitmap
= -1;
2928 = x_get_arg (parms
, Qicon_name
, "iconName", "Title", string
);
2929 if (! STRINGP (f
->icon_name
))
2930 f
->icon_name
= Qnil
;
2932 FRAME_X_DISPLAY_INFO (f
) = dpyinfo
;
2934 FRAME_KBOARD (f
) = kb
;
2937 /* Specify the parent under which to make this X window. */
2941 f
->output_data
.x
->parent_desc
= parent
;
2942 f
->output_data
.x
->explicit_parent
= 1;
2946 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
2947 f
->output_data
.x
->explicit_parent
= 0;
2950 /* Note that the frame has no physical cursor right now. */
2951 f
->phys_cursor_x
= -1;
2953 /* Set the name; the functions to which we pass f expect the name to
2955 if (EQ (name
, Qunbound
) || NILP (name
))
2957 f
->name
= build_string (dpyinfo
->x_id_name
);
2958 f
->explicit_name
= 0;
2963 f
->explicit_name
= 1;
2964 /* use the frame's title when getting resources for this frame. */
2965 specbind (Qx_resource_name
, name
);
2968 /* Extract the window parameters from the supplied values
2969 that are needed to determine window geometry. */
2973 font
= x_get_arg (parms
, Qfont
, "font", "Font", string
);
2975 /* First, try whatever font the caller has specified. */
2977 font
= x_new_font (f
, XSTRING (font
)->data
);
2978 /* Try out a font which we hope has bold and italic variations. */
2979 if (!STRINGP (font
))
2980 font
= x_new_font (f
, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
2981 if (! STRINGP (font
))
2982 font
= x_new_font (f
, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
2983 if (! STRINGP (font
))
2984 /* This was formerly the first thing tried, but it finds too many fonts
2985 and takes too long. */
2986 font
= x_new_font (f
, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
2987 /* If those didn't work, look for something which will at least work. */
2988 if (! STRINGP (font
))
2989 font
= x_new_font (f
, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
2991 if (! STRINGP (font
))
2992 font
= build_string ("fixed");
2994 x_default_parameter (f
, parms
, Qfont
, font
,
2995 "font", "Font", string
);
2998 #ifdef USE_X_TOOLKIT
2999 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
3000 whereby it fails to get any font. */
3001 xlwmenu_default_font
= f
->output_data
.x
->font
;
3004 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
3005 "borderwidth", "BorderWidth", number
);
3006 /* This defaults to 2 in order to match xterm. We recognize either
3007 internalBorderWidth or internalBorder (which is what xterm calls
3009 if (NILP (Fassq (Qinternal_border_width
, parms
)))
3013 value
= x_get_arg (parms
, Qinternal_border_width
,
3014 "internalBorder", "BorderWidth", number
);
3015 if (! EQ (value
, Qunbound
))
3016 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
3019 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (2),
3020 "internalBorderWidth", "BorderWidth", number
);
3021 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qt
,
3022 "verticalScrollBars", "ScrollBars", boolean
);
3024 /* Also do the stuff which must be set before the window exists. */
3025 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
3026 "foreground", "Foreground", string
);
3027 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
3028 "background", "Background", string
);
3029 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
3030 "pointerColor", "Foreground", string
);
3031 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
3032 "cursorColor", "Foreground", string
);
3033 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
3034 "borderColor", "BorderColor", string
);
3036 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
3037 "menuBar", "MenuBar", number
);
3038 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
3039 "scrollBarWidth", "ScrollBarWidth", number
);
3041 f
->output_data
.x
->parent_desc
= FRAME_X_DISPLAY_INFO (f
)->root_window
;
3042 window_prompting
= x_figure_window_size (f
, parms
);
3044 if (window_prompting
& XNegative
)
3046 if (window_prompting
& YNegative
)
3047 f
->output_data
.x
->win_gravity
= SouthEastGravity
;
3049 f
->output_data
.x
->win_gravity
= NorthEastGravity
;
3053 if (window_prompting
& YNegative
)
3054 f
->output_data
.x
->win_gravity
= SouthWestGravity
;
3056 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
3059 f
->output_data
.x
->size_hint_flags
= window_prompting
;
3061 #ifdef USE_X_TOOLKIT
3062 x_window (f
, window_prompting
, minibuffer_only
);
3068 init_frame_faces (f
);
3070 /* We need to do this after creating the X window, so that the
3071 icon-creation functions can say whose icon they're describing. */
3072 x_default_parameter (f
, parms
, Qicon_type
, Qnil
,
3073 "bitmapIcon", "BitmapIcon", symbol
);
3075 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
3076 "autoRaise", "AutoRaiseLower", boolean
);
3077 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
3078 "autoLower", "AutoRaiseLower", boolean
);
3079 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
3080 "cursorType", "CursorType", symbol
);
3082 /* Dimensions, especially f->height, must be done via change_frame_size.
3083 Change will not be effected unless different from the current
3087 f
->height
= f
->width
= 0;
3088 change_frame_size (f
, height
, width
, 1, 0);
3090 /* Tell the server what size and position, etc, we want,
3091 and how badly we want them. */
3093 x_wm_set_size_hint (f
, window_prompting
, 0);
3096 tem
= x_get_arg (parms
, Qunsplittable
, 0, 0, boolean
);
3097 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
3101 /* It is now ok to make the frame official
3102 even if we get an error below.
3103 And the frame needs to be on Vframe_list
3104 or making it visible won't work. */
3105 Vframe_list
= Fcons (frame
, Vframe_list
);
3107 /* Now that the frame is official, it counts as a reference to
3109 FRAME_X_DISPLAY_INFO (f
)->reference_count
++;
3111 /* Make the window appear on the frame and enable display,
3112 unless the caller says not to. However, with explicit parent,
3113 Emacs cannot control visibility, so don't try. */
3114 if (! f
->output_data
.x
->explicit_parent
)
3116 Lisp_Object visibility
;
3118 visibility
= x_get_arg (parms
, Qvisibility
, 0, 0, symbol
);
3119 if (EQ (visibility
, Qunbound
))
3122 if (EQ (visibility
, Qicon
))
3123 x_iconify_frame (f
);
3124 else if (! NILP (visibility
))
3125 x_make_frame_visible (f
);
3127 /* Must have been Qnil. */
3131 return unbind_to (count
, frame
);
3134 /* FRAME is used only to get a handle on the X display. We don't pass the
3135 display info directly because we're called from frame.c, which doesn't
3136 know about that structure. */
3138 x_get_focus_frame (frame
)
3139 struct frame
*frame
;
3141 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (frame
);
3143 if (! dpyinfo
->x_focus_frame
)
3146 XSETFRAME (xfocus
, dpyinfo
->x_focus_frame
);
3150 DEFUN ("focus-frame", Ffocus_frame
, Sfocus_frame
, 1, 1, 0,
3151 "This function is obsolete, and does nothing.")
3158 DEFUN ("unfocus-frame", Funfocus_frame
, Sunfocus_frame
, 0, 0, 0,
3159 "This function is obsolete, and does nothing.")
3165 DEFUN ("x-list-fonts", Fx_list_fonts
, Sx_list_fonts
, 1, 3, 0,
3166 "Return a list of the names of available fonts matching PATTERN.\n\
3167 If optional arguments FACE and FRAME are specified, return only fonts\n\
3168 the same size as FACE on FRAME.\n\
3170 PATTERN is a string, perhaps with wildcard characters;\n\
3171 the * character matches any substring, and\n\
3172 the ? character matches any single character.\n\
3173 PATTERN is case-insensitive.\n\
3174 FACE is a face name--a symbol.\n\
3176 The return value is a list of strings, suitable as arguments to\n\
3179 Fonts Emacs can't use (i.e. proportional fonts) may or may not be excluded\n\
3180 even if they match PATTERN and FACE.")
3181 (pattern
, face
, frame
)
3182 Lisp_Object pattern
, face
, frame
;
3186 #ifndef BROKEN_XLISTFONTSWITHINFO
3189 XFontStruct
*size_ref
;
3194 CHECK_STRING (pattern
, 0);
3196 CHECK_SYMBOL (face
, 1);
3198 f
= check_x_frame (frame
);
3200 /* Determine the width standard for comparison with the fonts we find. */
3208 /* Don't die if we get called with a terminal frame. */
3209 if (! FRAME_X_P (f
))
3210 error ("non-X frame used in `x-list-fonts'");
3212 face_id
= face_name_id_number (f
, face
);
3214 if (face_id
< 0 || face_id
>= FRAME_N_PARAM_FACES (f
)
3215 || FRAME_PARAM_FACES (f
) [face_id
] == 0)
3216 size_ref
= f
->output_data
.x
->font
;
3219 size_ref
= FRAME_PARAM_FACES (f
) [face_id
]->font
;
3220 if (size_ref
== (XFontStruct
*) (~0))
3221 size_ref
= f
->output_data
.x
->font
;
3225 /* See if we cached the result for this particular query. */
3226 list
= Fassoc (pattern
,
3227 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
);
3229 /* We have info in the cache for this PATTERN. */
3232 Lisp_Object tem
, newlist
;
3234 /* We have info about this pattern. */
3235 list
= XCONS (list
)->cdr
;
3242 /* Filter the cached info and return just the fonts that match FACE. */
3244 for (tem
= list
; CONSP (tem
); tem
= XCONS (tem
)->cdr
)
3246 XFontStruct
*thisinfo
;
3248 thisinfo
= XLoadQueryFont (FRAME_X_DISPLAY (f
),
3249 XSTRING (XCONS (tem
)->car
)->data
);
3251 if (thisinfo
&& same_size_fonts (thisinfo
, size_ref
))
3252 newlist
= Fcons (XCONS (tem
)->car
, newlist
);
3255 XFreeFont (FRAME_X_DISPLAY (f
), thisinfo
);
3265 /* Solaris 2.3 has a bug in XListFontsWithInfo. */
3266 #ifndef BROKEN_XLISTFONTSWITHINFO
3268 names
= XListFontsWithInfo (FRAME_X_DISPLAY (f
),
3269 XSTRING (pattern
)->data
,
3270 2000, /* maxnames */
3271 &num_fonts
, /* count_return */
3272 &info
); /* info_return */
3275 names
= XListFonts (FRAME_X_DISPLAY (f
),
3276 XSTRING (pattern
)->data
,
3277 2000, /* maxnames */
3278 &num_fonts
); /* count_return */
3287 Lisp_Object full_list
;
3289 /* Make a list of all the fonts we got back.
3290 Store that in the font cache for the display. */
3292 for (i
= 0; i
< num_fonts
; i
++)
3293 full_list
= Fcons (build_string (names
[i
]), full_list
);
3294 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
3295 = Fcons (Fcons (pattern
, full_list
),
3296 XCONS (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)->cdr
);
3298 /* Make a list of the fonts that have the right width. */
3300 for (i
= 0; i
< num_fonts
; i
++)
3308 #ifdef BROKEN_XLISTFONTSWITHINFO
3309 XFontStruct
*thisinfo
;
3312 thisinfo
= XLoadQueryFont (FRAME_X_DISPLAY (f
), names
[i
]);
3315 keeper
= thisinfo
&& same_size_fonts (thisinfo
, size_ref
);
3317 keeper
= same_size_fonts (&info
[i
], size_ref
);
3321 list
= Fcons (build_string (names
[i
]), list
);
3323 list
= Fnreverse (list
);
3326 #ifndef BROKEN_XLISTFONTSWITHINFO
3328 XFreeFontInfo (names
, info
, num_fonts
);
3331 XFreeFontNames (names
);
3339 DEFUN ("x-color-defined-p", Fx_color_defined_p
, Sx_color_defined_p
, 1, 2, 0,
3340 "Return non-nil if color COLOR is supported on frame FRAME.\n\
3341 If FRAME is omitted or nil, use the selected frame.")
3343 Lisp_Object color
, frame
;
3346 FRAME_PTR f
= check_x_frame (frame
);
3348 CHECK_STRING (color
, 1);
3350 if (defined_color (f
, XSTRING (color
)->data
, &foo
, 0))
3356 DEFUN ("x-color-values", Fx_color_values
, Sx_color_values
, 1, 2, 0,
3357 "Return a description of the color named COLOR on frame FRAME.\n\
3358 The value is a list of integer RGB values--(RED GREEN BLUE).\n\
3359 These values appear to range from 0 to 65280 or 65535, depending\n\
3360 on the system; white is (65280 65280 65280) or (65535 65535 65535).\n\
3361 If FRAME is omitted or nil, use the selected frame.")
3363 Lisp_Object color
, frame
;
3366 FRAME_PTR f
= check_x_frame (frame
);
3368 CHECK_STRING (color
, 1);
3370 if (defined_color (f
, XSTRING (color
)->data
, &foo
, 0))
3374 rgb
[0] = make_number (foo
.red
);
3375 rgb
[1] = make_number (foo
.green
);
3376 rgb
[2] = make_number (foo
.blue
);
3377 return Flist (3, rgb
);
3383 DEFUN ("x-display-color-p", Fx_display_color_p
, Sx_display_color_p
, 0, 1, 0,
3384 "Return t if the X display supports color.\n\
3385 The optional argument DISPLAY specifies which display to ask about.\n\
3386 DISPLAY should be either a frame or a display name (a string).\n\
3387 If omitted or nil, that stands for the selected frame's display.")
3389 Lisp_Object display
;
3391 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3393 if (dpyinfo
->n_planes
<= 2)
3396 switch (dpyinfo
->visual
->class)
3409 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
3411 "Return t if the X display supports shades of gray.\n\
3412 Note that color displays do support shades of gray.\n\
3413 The optional argument DISPLAY specifies which display to ask about.\n\
3414 DISPLAY should be either a frame or a display name (a string).\n\
3415 If omitted or nil, that stands for the selected frame's display.")
3417 Lisp_Object display
;
3419 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3421 if (dpyinfo
->n_planes
<= 1)
3424 switch (dpyinfo
->visual
->class)
3439 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
3441 "Returns the width in pixels of the X display DISPLAY.\n\
3442 The optional argument DISPLAY specifies which display to ask about.\n\
3443 DISPLAY should be either a frame or a display name (a string).\n\
3444 If omitted or nil, that stands for the selected frame's display.")
3446 Lisp_Object display
;
3448 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3450 return make_number (dpyinfo
->width
);
3453 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
3454 Sx_display_pixel_height
, 0, 1, 0,
3455 "Returns the height in pixels of the X display DISPLAY.\n\
3456 The optional argument DISPLAY specifies which display to ask about.\n\
3457 DISPLAY should be either a frame or a display name (a string).\n\
3458 If omitted or nil, that stands for the selected frame's display.")
3460 Lisp_Object display
;
3462 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3464 return make_number (dpyinfo
->height
);
3467 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
3469 "Returns the number of bitplanes of the X display DISPLAY.\n\
3470 The optional argument DISPLAY specifies which display to ask about.\n\
3471 DISPLAY should be either a frame or a display name (a string).\n\
3472 If omitted or nil, that stands for the selected frame's display.")
3474 Lisp_Object display
;
3476 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3478 return make_number (dpyinfo
->n_planes
);
3481 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
3483 "Returns the number of color cells of the X display DISPLAY.\n\
3484 The optional argument DISPLAY specifies which display to ask about.\n\
3485 DISPLAY should be either a frame or a display name (a string).\n\
3486 If omitted or nil, that stands for the selected frame's display.")
3488 Lisp_Object display
;
3490 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3492 return make_number (DisplayCells (dpyinfo
->display
,
3493 XScreenNumberOfScreen (dpyinfo
->screen
)));
3496 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
3497 Sx_server_max_request_size
,
3499 "Returns the maximum request size of the X server of display DISPLAY.\n\
3500 The optional argument DISPLAY specifies which display to ask about.\n\
3501 DISPLAY should be either a frame or a display name (a string).\n\
3502 If omitted or nil, that stands for the selected frame's display.")
3504 Lisp_Object display
;
3506 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3508 return make_number (MAXREQUEST (dpyinfo
->display
));
3511 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
3512 "Returns the vendor ID string of the X server of display DISPLAY.\n\
3513 The optional argument DISPLAY specifies which display to ask about.\n\
3514 DISPLAY should be either a frame or a display name (a string).\n\
3515 If omitted or nil, that stands for the selected frame's display.")
3517 Lisp_Object display
;
3519 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3520 char *vendor
= ServerVendor (dpyinfo
->display
);
3522 if (! vendor
) vendor
= "";
3523 return build_string (vendor
);
3526 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
3527 "Returns the version numbers of the X server of display DISPLAY.\n\
3528 The value is a list of three integers: the major and minor\n\
3529 version numbers of the X Protocol in use, and the vendor-specific release\n\
3530 number. See also the function `x-server-vendor'.\n\n\
3531 The optional argument DISPLAY specifies which display to ask about.\n\
3532 DISPLAY should be either a frame or a display name (a string).\n\
3533 If omitted or nil, that stands for the selected frame's display.")
3535 Lisp_Object display
;
3537 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3538 Display
*dpy
= dpyinfo
->display
;
3540 return Fcons (make_number (ProtocolVersion (dpy
)),
3541 Fcons (make_number (ProtocolRevision (dpy
)),
3542 Fcons (make_number (VendorRelease (dpy
)), Qnil
)));
3545 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
3546 "Returns the number of screens on the X server of display DISPLAY.\n\
3547 The optional argument DISPLAY specifies which display to ask about.\n\
3548 DISPLAY should be either a frame or a display name (a string).\n\
3549 If omitted or nil, that stands for the selected frame's display.")
3551 Lisp_Object display
;
3553 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3555 return make_number (ScreenCount (dpyinfo
->display
));
3558 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
3559 "Returns the height in millimeters of the X display DISPLAY.\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 return make_number (HeightMMOfScreen (dpyinfo
->screen
));
3571 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
3572 "Returns the width in millimeters of the X display DISPLAY.\n\
3573 The optional argument DISPLAY specifies which display to ask about.\n\
3574 DISPLAY should be either a frame or a display name (a string).\n\
3575 If omitted or nil, that stands for the selected frame's display.")
3577 Lisp_Object display
;
3579 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3581 return make_number (WidthMMOfScreen (dpyinfo
->screen
));
3584 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
3585 Sx_display_backing_store
, 0, 1, 0,
3586 "Returns an indication of whether X display DISPLAY does backing store.\n\
3587 The value may be `always', `when-mapped', or `not-useful'.\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 switch (DoesBackingStore (dpyinfo
->screen
))
3599 return intern ("always");
3602 return intern ("when-mapped");
3605 return intern ("not-useful");
3608 error ("Strange value for BackingStore parameter of screen");
3612 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
3613 Sx_display_visual_class
, 0, 1, 0,
3614 "Returns the visual class of the X display DISPLAY.\n\
3615 The value is one of the symbols `static-gray', `gray-scale',\n\
3616 `static-color', `pseudo-color', `true-color', or `direct-color'.\n\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 switch (dpyinfo
->visual
->class)
3627 case StaticGray
: return (intern ("static-gray"));
3628 case GrayScale
: return (intern ("gray-scale"));
3629 case StaticColor
: return (intern ("static-color"));
3630 case PseudoColor
: return (intern ("pseudo-color"));
3631 case TrueColor
: return (intern ("true-color"));
3632 case DirectColor
: return (intern ("direct-color"));
3634 error ("Display has an unknown visual class");
3638 DEFUN ("x-display-save-under", Fx_display_save_under
,
3639 Sx_display_save_under
, 0, 1, 0,
3640 "Returns t if the X display DISPLAY supports the save-under feature.\n\
3641 The optional argument DISPLAY specifies which display to ask about.\n\
3642 DISPLAY should be either a frame or a display name (a string).\n\
3643 If omitted or nil, that stands for the selected frame's display.")
3645 Lisp_Object display
;
3647 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
3649 if (DoesSaveUnders (dpyinfo
->screen
) == True
)
3657 register struct frame
*f
;
3659 return PIXEL_WIDTH (f
);
3664 register struct frame
*f
;
3666 return PIXEL_HEIGHT (f
);
3671 register struct frame
*f
;
3673 return FONT_WIDTH (f
->output_data
.x
->font
);
3678 register struct frame
*f
;
3680 return f
->output_data
.x
->line_height
;
3684 x_screen_planes (frame
)
3687 return FRAME_X_DISPLAY_INFO (XFRAME (frame
))->n_planes
;
3690 #if 0 /* These no longer seem like the right way to do things. */
3692 /* Draw a rectangle on the frame with left top corner including
3693 the character specified by LEFT_CHAR and TOP_CHAR. The rectangle is
3694 CHARS by LINES wide and long and is the color of the cursor. */
3697 x_rectangle (f
, gc
, left_char
, top_char
, chars
, lines
)
3698 register struct frame
*f
;
3700 register int top_char
, left_char
, chars
, lines
;
3704 int left
= (left_char
* FONT_WIDTH (f
->output_data
.x
->font
)
3705 + f
->output_data
.x
->internal_border_width
);
3706 int top
= (top_char
* f
->output_data
.x
->line_height
3707 + f
->output_data
.x
->internal_border_width
);
3710 width
= FONT_WIDTH (f
->output_data
.x
->font
) / 2;
3712 width
= FONT_WIDTH (f
->output_data
.x
->font
) * chars
;
3714 height
= f
->output_data
.x
->line_height
/ 2;
3716 height
= f
->output_data
.x
->line_height
* lines
;
3718 XDrawRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3719 gc
, left
, top
, width
, height
);
3722 DEFUN ("x-draw-rectangle", Fx_draw_rectangle
, Sx_draw_rectangle
, 5, 5, 0,
3723 "Draw a rectangle on FRAME between coordinates specified by\n\
3724 numbers X0, Y0, X1, Y1 in the cursor pixel.")
3725 (frame
, X0
, Y0
, X1
, Y1
)
3726 register Lisp_Object frame
, X0
, X1
, Y0
, Y1
;
3728 register int x0
, y0
, x1
, y1
, top
, left
, n_chars
, n_lines
;
3730 CHECK_LIVE_FRAME (frame
, 0);
3731 CHECK_NUMBER (X0
, 0);
3732 CHECK_NUMBER (Y0
, 1);
3733 CHECK_NUMBER (X1
, 2);
3734 CHECK_NUMBER (Y1
, 3);
3744 n_lines
= y1
- y0
+ 1;
3749 n_lines
= y0
- y1
+ 1;
3755 n_chars
= x1
- x0
+ 1;
3760 n_chars
= x0
- x1
+ 1;
3764 x_rectangle (XFRAME (frame
), XFRAME (frame
)->output_data
.x
->cursor_gc
,
3765 left
, top
, n_chars
, n_lines
);
3771 DEFUN ("x-erase-rectangle", Fx_erase_rectangle
, Sx_erase_rectangle
, 5, 5, 0,
3772 "Draw a rectangle drawn on FRAME between coordinates\n\
3773 X0, Y0, X1, Y1 in the regular background-pixel.")
3774 (frame
, X0
, Y0
, X1
, Y1
)
3775 register Lisp_Object frame
, X0
, Y0
, X1
, Y1
;
3777 register int x0
, y0
, x1
, y1
, top
, left
, n_chars
, n_lines
;
3779 CHECK_LIVE_FRAME (frame
, 0);
3780 CHECK_NUMBER (X0
, 0);
3781 CHECK_NUMBER (Y0
, 1);
3782 CHECK_NUMBER (X1
, 2);
3783 CHECK_NUMBER (Y1
, 3);
3793 n_lines
= y1
- y0
+ 1;
3798 n_lines
= y0
- y1
+ 1;
3804 n_chars
= x1
- x0
+ 1;
3809 n_chars
= x0
- x1
+ 1;
3813 x_rectangle (XFRAME (frame
), XFRAME (frame
)->output_data
.x
->reverse_gc
,
3814 left
, top
, n_chars
, n_lines
);
3820 /* Draw lines around the text region beginning at the character position
3821 TOP_X, TOP_Y and ending at BOTTOM_X and BOTTOM_Y. GC specifies the
3822 pixel and line characteristics. */
3824 #define line_len(line) (FRAME_CURRENT_GLYPHS (f)->used[(line)])
3827 outline_region (f
, gc
, top_x
, top_y
, bottom_x
, bottom_y
)
3828 register struct frame
*f
;
3830 int top_x
, top_y
, bottom_x
, bottom_y
;
3832 register int ibw
= f
->output_data
.x
->internal_border_width
;
3833 register int font_w
= FONT_WIDTH (f
->output_data
.x
->font
);
3834 register int font_h
= f
->output_data
.x
->line_height
;
3836 int x
= line_len (y
);
3837 XPoint
*pixel_points
3838 = (XPoint
*) alloca (((bottom_y
- top_y
+ 2) * 4) * sizeof (XPoint
));
3839 register XPoint
*this_point
= pixel_points
;
3841 /* Do the horizontal top line/lines */
3844 this_point
->x
= ibw
;
3845 this_point
->y
= ibw
+ (font_h
* top_y
);
3848 this_point
->x
= ibw
+ (font_w
/ 2); /* Half-size for newline chars. */
3850 this_point
->x
= ibw
+ (font_w
* x
);
3851 this_point
->y
= (this_point
- 1)->y
;
3855 this_point
->x
= ibw
;
3856 this_point
->y
= ibw
+ (font_h
* (top_y
+ 1));
3858 this_point
->x
= ibw
+ (font_w
* top_x
);
3859 this_point
->y
= (this_point
- 1)->y
;
3861 this_point
->x
= (this_point
- 1)->x
;
3862 this_point
->y
= ibw
+ (font_h
* top_y
);
3864 this_point
->x
= ibw
+ (font_w
* x
);
3865 this_point
->y
= (this_point
- 1)->y
;
3868 /* Now do the right side. */
3869 while (y
< bottom_y
)
3870 { /* Right vertical edge */
3872 this_point
->x
= (this_point
- 1)->x
;
3873 this_point
->y
= ibw
+ (font_h
* (y
+ 1));
3876 y
++; /* Horizontal connection to next line */
3879 this_point
->x
= ibw
+ (font_w
/ 2);
3881 this_point
->x
= ibw
+ (font_w
* x
);
3883 this_point
->y
= (this_point
- 1)->y
;
3886 /* Now do the bottom and connect to the top left point. */
3887 this_point
->x
= ibw
+ (font_w
* (bottom_x
+ 1));
3890 this_point
->x
= (this_point
- 1)->x
;
3891 this_point
->y
= ibw
+ (font_h
* (bottom_y
+ 1));
3893 this_point
->x
= ibw
;
3894 this_point
->y
= (this_point
- 1)->y
;
3896 this_point
->x
= pixel_points
->x
;
3897 this_point
->y
= pixel_points
->y
;
3899 XDrawLines (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3901 (this_point
- pixel_points
+ 1), CoordModeOrigin
);
3904 DEFUN ("x-contour-region", Fx_contour_region
, Sx_contour_region
, 1, 1, 0,
3905 "Highlight the region between point and the character under the mouse\n\
3908 register Lisp_Object event
;
3910 register int x0
, y0
, x1
, y1
;
3911 register struct frame
*f
= selected_frame
;
3912 register int p1
, p2
;
3914 CHECK_CONS (event
, 0);
3917 x0
= XINT (Fcar (Fcar (event
)));
3918 y0
= XINT (Fcar (Fcdr (Fcar (event
))));
3920 /* If the mouse is past the end of the line, don't that area. */
3921 /* ReWrite this... */
3926 if (y1
> y0
) /* point below mouse */
3927 outline_region (f
, f
->output_data
.x
->cursor_gc
,
3929 else if (y1
< y0
) /* point above mouse */
3930 outline_region (f
, f
->output_data
.x
->cursor_gc
,
3932 else /* same line: draw horizontal rectangle */
3935 x_rectangle (f
, f
->output_data
.x
->cursor_gc
,
3936 x0
, y0
, (x1
- x0
+ 1), 1);
3938 x_rectangle (f
, f
->output_data
.x
->cursor_gc
,
3939 x1
, y1
, (x0
- x1
+ 1), 1);
3942 XFlush (FRAME_X_DISPLAY (f
));
3948 DEFUN ("x-uncontour-region", Fx_uncontour_region
, Sx_uncontour_region
, 1, 1, 0,
3949 "Erase any highlighting of the region between point and the character\n\
3950 at X, Y on the selected frame.")
3952 register Lisp_Object event
;
3954 register int x0
, y0
, x1
, y1
;
3955 register struct frame
*f
= selected_frame
;
3958 x0
= XINT (Fcar (Fcar (event
)));
3959 y0
= XINT (Fcar (Fcdr (Fcar (event
))));
3963 if (y1
> y0
) /* point below mouse */
3964 outline_region (f
, f
->output_data
.x
->reverse_gc
,
3966 else if (y1
< y0
) /* point above mouse */
3967 outline_region (f
, f
->output_data
.x
->reverse_gc
,
3969 else /* same line: draw horizontal rectangle */
3972 x_rectangle (f
, f
->output_data
.x
->reverse_gc
,
3973 x0
, y0
, (x1
- x0
+ 1), 1);
3975 x_rectangle (f
, f
->output_data
.x
->reverse_gc
,
3976 x1
, y1
, (x0
- x1
+ 1), 1);
3984 int contour_begin_x
, contour_begin_y
;
3985 int contour_end_x
, contour_end_y
;
3986 int contour_npoints
;
3988 /* Clip the top part of the contour lines down (and including) line Y_POS.
3989 If X_POS is in the middle (rather than at the end) of the line, drop
3990 down a line at that character. */
3993 clip_contour_top (y_pos
, x_pos
)
3995 register XPoint
*begin
= contour_lines
[y_pos
].top_left
;
3996 register XPoint
*end
;
3997 register int npoints
;
3998 register struct display_line
*line
= selected_frame
->phys_lines
[y_pos
+ 1];
4000 if (x_pos
>= line
->len
- 1) /* Draw one, straight horizontal line. */
4002 end
= contour_lines
[y_pos
].top_right
;
4003 npoints
= (end
- begin
+ 1);
4004 XDrawLines (x_current_display
, contour_window
,
4005 contour_erase_gc
, begin_erase
, npoints
, CoordModeOrigin
);
4007 bcopy (end
, begin
+ 1, contour_last_point
- end
+ 1);
4008 contour_last_point
-= (npoints
- 2);
4009 XDrawLines (x_current_display
, contour_window
,
4010 contour_erase_gc
, begin
, 2, CoordModeOrigin
);
4011 XFlush (x_current_display
);
4013 /* Now, update contour_lines structure. */
4018 register XPoint
*p
= begin
+ 1;
4019 end
= contour_lines
[y_pos
].bottom_right
;
4020 npoints
= (end
- begin
+ 1);
4021 XDrawLines (x_current_display
, contour_window
,
4022 contour_erase_gc
, begin_erase
, npoints
, CoordModeOrigin
);
4025 p
->x
= ibw
+ (font_w
* (x_pos
+ 1));
4027 p
->y
= begin
->y
+ font_h
;
4029 bcopy (end
, begin
+ 3, contour_last_point
- end
+ 1);
4030 contour_last_point
-= (npoints
- 5);
4031 XDrawLines (x_current_display
, contour_window
,
4032 contour_erase_gc
, begin
, 4, CoordModeOrigin
);
4033 XFlush (x_current_display
);
4035 /* Now, update contour_lines structure. */
4039 /* Erase the top horizontal lines of the contour, and then extend
4040 the contour upwards. */
4043 extend_contour_top (line
)
4048 clip_contour_bottom (x_pos
, y_pos
)
4054 extend_contour_bottom (x_pos
, y_pos
)
4058 DEFUN ("x-select-region", Fx_select_region
, Sx_select_region
, 1, 1, "e",
4063 register struct frame
*f
= selected_frame
;
4064 register int point_x
= f
->cursor_x
;
4065 register int point_y
= f
->cursor_y
;
4066 register int mouse_below_point
;
4067 register Lisp_Object obj
;
4068 register int x_contour_x
, x_contour_y
;
4070 x_contour_x
= x_mouse_x
;
4071 x_contour_y
= x_mouse_y
;
4072 if (x_contour_y
> point_y
|| (x_contour_y
== point_y
4073 && x_contour_x
> point_x
))
4075 mouse_below_point
= 1;
4076 outline_region (f
, f
->output_data
.x
->cursor_gc
, point_x
, point_y
,
4077 x_contour_x
, x_contour_y
);
4081 mouse_below_point
= 0;
4082 outline_region (f
, f
->output_data
.x
->cursor_gc
, x_contour_x
, x_contour_y
,
4088 obj
= read_char (-1, 0, 0, Qnil
, 0);
4092 if (mouse_below_point
)
4094 if (x_mouse_y
<= point_y
) /* Flipped. */
4096 mouse_below_point
= 0;
4098 outline_region (f
, f
->output_data
.x
->reverse_gc
, point_x
, point_y
,
4099 x_contour_x
, x_contour_y
);
4100 outline_region (f
, f
->output_data
.x
->cursor_gc
, x_mouse_x
, x_mouse_y
,
4103 else if (x_mouse_y
< x_contour_y
) /* Bottom clipped. */
4105 clip_contour_bottom (x_mouse_y
);
4107 else if (x_mouse_y
> x_contour_y
) /* Bottom extended. */
4109 extend_bottom_contour (x_mouse_y
);
4112 x_contour_x
= x_mouse_x
;
4113 x_contour_y
= x_mouse_y
;
4115 else /* mouse above or same line as point */
4117 if (x_mouse_y
>= point_y
) /* Flipped. */
4119 mouse_below_point
= 1;
4121 outline_region (f
, f
->output_data
.x
->reverse_gc
,
4122 x_contour_x
, x_contour_y
, point_x
, point_y
);
4123 outline_region (f
, f
->output_data
.x
->cursor_gc
, point_x
, point_y
,
4124 x_mouse_x
, x_mouse_y
);
4126 else if (x_mouse_y
> x_contour_y
) /* Top clipped. */
4128 clip_contour_top (x_mouse_y
);
4130 else if (x_mouse_y
< x_contour_y
) /* Top extended. */
4132 extend_contour_top (x_mouse_y
);
4137 unread_command_event
= obj
;
4138 if (mouse_below_point
)
4140 contour_begin_x
= point_x
;
4141 contour_begin_y
= point_y
;
4142 contour_end_x
= x_contour_x
;
4143 contour_end_y
= x_contour_y
;
4147 contour_begin_x
= x_contour_x
;
4148 contour_begin_y
= x_contour_y
;
4149 contour_end_x
= point_x
;
4150 contour_end_y
= point_y
;
4155 DEFUN ("x-horizontal-line", Fx_horizontal_line
, Sx_horizontal_line
, 1, 1, "e",
4160 register Lisp_Object obj
;
4161 struct frame
*f
= selected_frame
;
4162 register struct window
*w
= XWINDOW (selected_window
);
4163 register GC line_gc
= f
->output_data
.x
->cursor_gc
;
4164 register GC erase_gc
= f
->output_data
.x
->reverse_gc
;
4166 char dash_list
[] = {6, 4, 6, 4};
4168 XGCValues gc_values
;
4170 register int previous_y
;
4171 register int line
= (x_mouse_y
+ 1) * f
->output_data
.x
->line_height
4172 + f
->output_data
.x
->internal_border_width
;
4173 register int left
= f
->output_data
.x
->internal_border_width
4175 * FONT_WIDTH (f
->output_data
.x
->font
));
4176 register int right
= left
+ (w
->width
4177 * FONT_WIDTH (f
->output_data
.x
->font
))
4178 - f
->output_data
.x
->internal_border_width
;
4182 gc_values
.foreground
= f
->output_data
.x
->cursor_pixel
;
4183 gc_values
.background
= f
->output_data
.x
->background_pixel
;
4184 gc_values
.line_width
= 1;
4185 gc_values
.line_style
= LineOnOffDash
;
4186 gc_values
.cap_style
= CapRound
;
4187 gc_values
.join_style
= JoinRound
;
4189 line_gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4190 GCLineStyle
| GCJoinStyle
| GCCapStyle
4191 | GCLineWidth
| GCForeground
| GCBackground
,
4193 XSetDashes (FRAME_X_DISPLAY (f
), line_gc
, 0, dash_list
, dashes
);
4194 gc_values
.foreground
= f
->output_data
.x
->background_pixel
;
4195 gc_values
.background
= f
->output_data
.x
->foreground_pixel
;
4196 erase_gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4197 GCLineStyle
| GCJoinStyle
| GCCapStyle
4198 | GCLineWidth
| GCForeground
| GCBackground
,
4200 XSetDashes (FRAME_X_DISPLAY (f
), erase_gc
, 0, dash_list
, dashes
);
4207 if (x_mouse_y
>= XINT (w
->top
)
4208 && x_mouse_y
< XINT (w
->top
) + XINT (w
->height
) - 1)
4210 previous_y
= x_mouse_y
;
4211 line
= (x_mouse_y
+ 1) * f
->output_data
.x
->line_height
4212 + f
->output_data
.x
->internal_border_width
;
4213 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4214 line_gc
, left
, line
, right
, line
);
4216 XFlush (FRAME_X_DISPLAY (f
));
4221 obj
= read_char (-1, 0, 0, Qnil
, 0);
4223 || (! EQ (Fcar (Fcdr (Fcdr (obj
))),
4224 Qvertical_scroll_bar
))
4228 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4229 erase_gc
, left
, line
, right
, line
);
4230 unread_command_event
= obj
;
4232 XFreeGC (FRAME_X_DISPLAY (f
), line_gc
);
4233 XFreeGC (FRAME_X_DISPLAY (f
), erase_gc
);
4239 while (x_mouse_y
== previous_y
);
4242 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4243 erase_gc
, left
, line
, right
, line
);
4250 /* These keep track of the rectangle following the pointer. */
4251 int mouse_track_top
, mouse_track_left
, mouse_track_width
;
4253 /* Offset in buffer of character under the pointer, or 0. */
4254 int mouse_buffer_offset
;
4256 DEFUN ("x-track-pointer", Fx_track_pointer
, Sx_track_pointer
, 0, 0, 0,
4257 "Track the pointer.")
4260 static Cursor current_pointer_shape
;
4261 FRAME_PTR f
= x_mouse_frame
;
4264 if (EQ (Vmouse_frame_part
, Qtext_part
)
4265 && (current_pointer_shape
!= f
->output_data
.x
->nontext_cursor
))
4270 current_pointer_shape
= f
->output_data
.x
->nontext_cursor
;
4271 XDefineCursor (FRAME_X_DISPLAY (f
),
4273 current_pointer_shape
);
4275 buf
= XBUFFER (XWINDOW (Vmouse_window
)->buffer
);
4276 c
= *(BUF_CHAR_ADDRESS (buf
, mouse_buffer_offset
));
4278 else if (EQ (Vmouse_frame_part
, Qmodeline_part
)
4279 && (current_pointer_shape
!= f
->output_data
.x
->modeline_cursor
))
4281 current_pointer_shape
= f
->output_data
.x
->modeline_cursor
;
4282 XDefineCursor (FRAME_X_DISPLAY (f
),
4284 current_pointer_shape
);
4287 XFlush (FRAME_X_DISPLAY (f
));
4293 DEFUN ("x-track-pointer", Fx_track_pointer
, Sx_track_pointer
, 1, 1, "e",
4294 "Draw rectangle around character under mouse pointer, if there is one.")
4298 struct window
*w
= XWINDOW (Vmouse_window
);
4299 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4300 struct buffer
*b
= XBUFFER (w
->buffer
);
4303 if (! EQ (Vmouse_window
, selected_window
))
4306 if (EQ (event
, Qnil
))
4310 x_read_mouse_position (selected_frame
, &x
, &y
);
4314 mouse_track_width
= 0;
4315 mouse_track_left
= mouse_track_top
= -1;
4319 if ((x_mouse_x
!= mouse_track_left
4320 && (x_mouse_x
< mouse_track_left
4321 || x_mouse_x
> (mouse_track_left
+ mouse_track_width
)))
4322 || x_mouse_y
!= mouse_track_top
)
4324 int hp
= 0; /* Horizontal position */
4325 int len
= FRAME_CURRENT_GLYPHS (f
)->used
[x_mouse_y
];
4326 int p
= FRAME_CURRENT_GLYPHS (f
)->bufp
[x_mouse_y
];
4327 int tab_width
= XINT (b
->tab_width
);
4328 int ctl_arrow_p
= !NILP (b
->ctl_arrow
);
4330 int mode_line_vpos
= XFASTINT (w
->height
) + XFASTINT (w
->top
) - 1;
4331 int in_mode_line
= 0;
4333 if (! FRAME_CURRENT_GLYPHS (f
)->enable
[x_mouse_y
])
4336 /* Erase previous rectangle. */
4337 if (mouse_track_width
)
4339 x_rectangle (f
, f
->output_data
.x
->reverse_gc
,
4340 mouse_track_left
, mouse_track_top
,
4341 mouse_track_width
, 1);
4343 if ((mouse_track_left
== f
->phys_cursor_x
4344 || mouse_track_left
== f
->phys_cursor_x
- 1)
4345 && mouse_track_top
== f
->phys_cursor_y
)
4347 x_display_cursor (f
, 1);
4351 mouse_track_left
= x_mouse_x
;
4352 mouse_track_top
= x_mouse_y
;
4353 mouse_track_width
= 0;
4355 if (mouse_track_left
> len
) /* Past the end of line. */
4358 if (mouse_track_top
== mode_line_vpos
)
4364 if (tab_width
<= 0 || tab_width
> 20) tab_width
= 8;
4368 if (len
== f
->width
&& hp
== len
- 1 && c
!= '\n')
4374 mouse_track_width
= tab_width
- (hp
% tab_width
);
4376 hp
+= mouse_track_width
;
4379 mouse_track_left
= hp
- mouse_track_width
;
4385 mouse_track_width
= -1;
4389 if (ctl_arrow_p
&& (c
< 040 || c
== 0177))
4394 mouse_track_width
= 2;
4399 mouse_track_left
= hp
- mouse_track_width
;
4405 mouse_track_width
= 1;
4412 while (hp
<= x_mouse_x
);
4415 if (mouse_track_width
) /* Over text; use text pointer shape. */
4417 XDefineCursor (FRAME_X_DISPLAY (f
),
4419 f
->output_data
.x
->text_cursor
);
4420 x_rectangle (f
, f
->output_data
.x
->cursor_gc
,
4421 mouse_track_left
, mouse_track_top
,
4422 mouse_track_width
, 1);
4424 else if (in_mode_line
)
4425 XDefineCursor (FRAME_X_DISPLAY (f
),
4427 f
->output_data
.x
->modeline_cursor
);
4429 XDefineCursor (FRAME_X_DISPLAY (f
),
4431 f
->output_data
.x
->nontext_cursor
);
4434 XFlush (FRAME_X_DISPLAY (f
));
4437 obj
= read_char (-1, 0, 0, Qnil
, 0);
4440 while (CONSP (obj
) /* Mouse event */
4441 && EQ (Fcar (Fcdr (Fcdr (obj
))), Qnil
) /* Not scroll bar */
4442 && EQ (Vmouse_depressed
, Qnil
) /* Only motion events */
4443 && EQ (Vmouse_window
, selected_window
) /* In this window */
4446 unread_command_event
= obj
;
4448 if (mouse_track_width
)
4450 x_rectangle (f
, f
->output_data
.x
->reverse_gc
,
4451 mouse_track_left
, mouse_track_top
,
4452 mouse_track_width
, 1);
4453 mouse_track_width
= 0;
4454 if ((mouse_track_left
== f
->phys_cursor_x
4455 || mouse_track_left
- 1 == f
->phys_cursor_x
)
4456 && mouse_track_top
== f
->phys_cursor_y
)
4458 x_display_cursor (f
, 1);
4461 XDefineCursor (FRAME_X_DISPLAY (f
),
4463 f
->output_data
.x
->nontext_cursor
);
4464 XFlush (FRAME_X_DISPLAY (f
));
4474 /* Draw a pixmap specified by IMAGE_DATA of dimensions WIDTH and HEIGHT
4475 on the frame F at position X, Y. */
4477 x_draw_pixmap (f
, x
, y
, image_data
, width
, height
)
4479 int x
, y
, width
, height
;
4484 image
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
),
4485 FRAME_X_WINDOW (f
), image_data
,
4487 XCopyPlane (FRAME_X_DISPLAY (f
), image
, FRAME_X_WINDOW (f
),
4488 f
->output_data
.x
->normal_gc
, 0, 0, width
, height
, x
, y
);
4492 #if 0 /* I'm told these functions are superfluous
4493 given the ability to bind function keys. */
4496 DEFUN ("x-rebind-key", Fx_rebind_key
, Sx_rebind_key
, 3, 3, 0,
4497 "Rebind X keysym KEYSYM, with MODIFIERS, to generate NEWSTRING.\n\
4498 KEYSYM is a string which conforms to the X keysym definitions found\n\
4499 in X11/keysymdef.h, sans the initial XK_. MODIFIERS is nil or a\n\
4500 list of strings specifying modifier keys such as Control_L, which must\n\
4501 also be depressed for NEWSTRING to appear.")
4502 (x_keysym
, modifiers
, newstring
)
4503 register Lisp_Object x_keysym
;
4504 register Lisp_Object modifiers
;
4505 register Lisp_Object newstring
;
4508 register KeySym keysym
;
4509 KeySym modifier_list
[16];
4512 CHECK_STRING (x_keysym
, 1);
4513 CHECK_STRING (newstring
, 3);
4515 keysym
= XStringToKeysym ((char *) XSTRING (x_keysym
)->data
);
4516 if (keysym
== NoSymbol
)
4517 error ("Keysym does not exist");
4519 if (NILP (modifiers
))
4520 XRebindKeysym (x_current_display
, keysym
, modifier_list
, 0,
4521 XSTRING (newstring
)->data
, XSTRING (newstring
)->size
);
4524 register Lisp_Object rest
, mod
;
4527 for (rest
= modifiers
; !NILP (rest
); rest
= Fcdr (rest
))
4530 error ("Can't have more than 16 modifiers");
4533 CHECK_STRING (mod
, 3);
4534 modifier_list
[i
] = XStringToKeysym ((char *) XSTRING (mod
)->data
);
4536 if (modifier_list
[i
] == NoSymbol
4537 || !(IsModifierKey (modifier_list
[i
])
4538 || ((unsigned)(modifier_list
[i
]) == XK_Mode_switch
)
4539 || ((unsigned)(modifier_list
[i
]) == XK_Num_Lock
)))
4541 if (modifier_list
[i
] == NoSymbol
4542 || !IsModifierKey (modifier_list
[i
]))
4544 error ("Element is not a modifier keysym");
4548 XRebindKeysym (x_current_display
, keysym
, modifier_list
, i
,
4549 XSTRING (newstring
)->data
, XSTRING (newstring
)->size
);
4555 DEFUN ("x-rebind-keys", Fx_rebind_keys
, Sx_rebind_keys
, 2, 2, 0,
4556 "Rebind KEYCODE to list of strings STRINGS.\n\
4557 STRINGS should be a list of 16 elements, one for each shift combination.\n\
4558 nil as element means don't change.\n\
4559 See the documentation of `x-rebind-key' for more information.")
4561 register Lisp_Object keycode
;
4562 register Lisp_Object strings
;
4564 register Lisp_Object item
;
4565 register unsigned char *rawstring
;
4566 KeySym rawkey
, modifier
[1];
4568 register unsigned i
;
4571 CHECK_NUMBER (keycode
, 1);
4572 CHECK_CONS (strings
, 2);
4573 rawkey
= (KeySym
) ((unsigned) (XINT (keycode
))) & 255;
4574 for (i
= 0; i
<= 15; strings
= Fcdr (strings
), i
++)
4576 item
= Fcar (strings
);
4579 CHECK_STRING (item
, 2);
4580 strsize
= XSTRING (item
)->size
;
4581 rawstring
= (unsigned char *) xmalloc (strsize
);
4582 bcopy (XSTRING (item
)->data
, rawstring
, strsize
);
4583 modifier
[1] = 1 << i
;
4584 XRebindKeysym (x_current_display
, rawkey
, modifier
, 1,
4585 rawstring
, strsize
);
4590 #endif /* HAVE_X11 */
4593 #ifndef HAVE_XSCREENNUMBEROFSCREEN
4595 XScreenNumberOfScreen (scr
)
4596 register Screen
*scr
;
4598 register Display
*dpy
;
4599 register Screen
*dpyscr
;
4603 dpyscr
= dpy
->screens
;
4605 for (i
= 0; i
< dpy
->nscreens
; i
++, dpyscr
++)
4611 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4614 select_visual (dpy
, screen
, depth
)
4617 unsigned int *depth
;
4620 XVisualInfo
*vinfo
, vinfo_template
;
4623 v
= DefaultVisualOfScreen (screen
);
4626 vinfo_template
.visualid
= XVisualIDFromVisual (v
);
4628 vinfo_template
.visualid
= v
->visualid
;
4631 vinfo_template
.screen
= XScreenNumberOfScreen (screen
);
4633 vinfo
= XGetVisualInfo (dpy
,
4634 VisualIDMask
| VisualScreenMask
, &vinfo_template
,
4637 fatal ("Can't get proper X visual info");
4639 if ((1 << vinfo
->depth
) == vinfo
->colormap_size
)
4640 *depth
= vinfo
->depth
;
4644 int n
= vinfo
->colormap_size
- 1;
4653 XFree ((char *) vinfo
);
4657 /* Return the X display structure for the display named NAME.
4658 Open a new connection if necessary. */
4660 struct x_display_info
*
4661 x_display_info_for_name (name
)
4665 struct x_display_info
*dpyinfo
;
4667 CHECK_STRING (name
, 0);
4669 if (! EQ (Vwindow_system
, intern ("x")))
4670 error ("Not using X Windows");
4672 for (dpyinfo
= x_display_list
, names
= x_display_name_list
;
4674 dpyinfo
= dpyinfo
->next
, names
= XCONS (names
)->cdr
)
4677 tem
= Fstring_equal (XCONS (XCONS (names
)->car
)->car
, name
);
4682 /* Use this general default value to start with. */
4683 Vx_resource_name
= Vinvocation_name
;
4685 validate_x_resource_name ();
4687 dpyinfo
= x_term_init (name
, (unsigned char *)0,
4688 (char *) XSTRING (Vx_resource_name
)->data
);
4691 error ("Cannot connect to X server %s", XSTRING (name
)->data
);
4694 XSETFASTINT (Vwindow_system_version
, 11);
4699 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
4700 1, 3, 0, "Open a connection to an X server.\n\
4701 DISPLAY is the name of the display to connect to.\n\
4702 Optional second arg XRM-STRING is a string of resources in xrdb format.\n\
4703 If the optional third arg MUST-SUCCEED is non-nil,\n\
4704 terminate Emacs if we can't open the connection.")
4705 (display
, xrm_string
, must_succeed
)
4706 Lisp_Object display
, xrm_string
, must_succeed
;
4708 unsigned int n_planes
;
4709 unsigned char *xrm_option
;
4710 struct x_display_info
*dpyinfo
;
4712 CHECK_STRING (display
, 0);
4713 if (! NILP (xrm_string
))
4714 CHECK_STRING (xrm_string
, 1);
4716 if (! EQ (Vwindow_system
, intern ("x")))
4717 error ("Not using X Windows");
4719 if (! NILP (xrm_string
))
4720 xrm_option
= (unsigned char *) XSTRING (xrm_string
)->data
;
4722 xrm_option
= (unsigned char *) 0;
4724 /* Use this general default value to start with. */
4725 Vx_resource_name
= Vinvocation_name
;
4727 validate_x_resource_name ();
4729 /* This is what opens the connection and sets x_current_display.
4730 This also initializes many symbols, such as those used for input. */
4731 dpyinfo
= x_term_init (display
, xrm_option
,
4732 (char *) XSTRING (Vx_resource_name
)->data
);
4736 if (!NILP (must_succeed
))
4737 fatal ("Cannot connect to X server %s.\n\
4738 Check the DISPLAY environment variable or use `-d'.\n\
4739 Also use the `xhost' program to verify that it is set to permit\n\
4740 connections from your machine.\n",
4741 XSTRING (display
)->data
);
4743 error ("Cannot connect to X server %s", XSTRING (display
)->data
);
4748 XSETFASTINT (Vwindow_system_version
, 11);
4752 DEFUN ("x-close-connection", Fx_close_connection
,
4753 Sx_close_connection
, 1, 1, 0,
4754 "Close the connection to DISPLAY's X server.\n\
4755 For DISPLAY, specify either a frame or a display name (a string).\n\
4756 If DISPLAY is nil, that stands for the selected frame's display.")
4758 Lisp_Object display
;
4760 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4761 struct x_display_info
*tail
;
4764 if (dpyinfo
->reference_count
> 0)
4765 error ("Display still has frames on it");
4768 /* Free the fonts in the font table. */
4769 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
4771 if (dpyinfo
->font_table
[i
].name
)
4772 free (dpyinfo
->font_table
[i
].name
);
4773 /* Don't free the full_name string;
4774 it is always shared with something else. */
4775 XFreeFont (dpyinfo
->display
, dpyinfo
->font_table
[i
].font
);
4777 x_destroy_all_bitmaps (dpyinfo
);
4778 XSetCloseDownMode (dpyinfo
->display
, DestroyAll
);
4780 #ifdef USE_X_TOOLKIT
4781 XtCloseDisplay (dpyinfo
->display
);
4783 XCloseDisplay (dpyinfo
->display
);
4786 x_delete_display (dpyinfo
);
4792 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
4793 "Return the list of display names that Emacs has connections to.")
4796 Lisp_Object tail
, result
;
4799 for (tail
= x_display_name_list
; ! NILP (tail
); tail
= XCONS (tail
)->cdr
)
4800 result
= Fcons (XCONS (XCONS (tail
)->car
)->car
, result
);
4805 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
4806 "If ON is non-nil, report X errors as soon as the erring request is made.\n\
4807 If ON is nil, allow buffering of requests.\n\
4808 Turning on synchronization prohibits the Xlib routines from buffering\n\
4809 requests and seriously degrades performance, but makes debugging much\n\
4811 The optional second argument DISPLAY specifies which display to act on.\n\
4812 DISPLAY should be either a frame or a display name (a string).\n\
4813 If DISPLAY is omitted or nil, that stands for the selected frame's display.")
4815 Lisp_Object display
, on
;
4817 struct x_display_info
*dpyinfo
= check_x_display_info (display
);
4819 XSynchronize (dpyinfo
->display
, !EQ (on
, Qnil
));
4824 /* Wait for responses to all X commands issued so far for frame F. */
4831 XSync (FRAME_X_DISPLAY (f
), False
);
4837 /* This is zero if not using X windows. */
4840 /* The section below is built by the lisp expression at the top of the file,
4841 just above where these variables are declared. */
4842 /*&&& init symbols here &&&*/
4843 Qauto_raise
= intern ("auto-raise");
4844 staticpro (&Qauto_raise
);
4845 Qauto_lower
= intern ("auto-lower");
4846 staticpro (&Qauto_lower
);
4847 Qbackground_color
= intern ("background-color");
4848 staticpro (&Qbackground_color
);
4849 Qbar
= intern ("bar");
4851 Qborder_color
= intern ("border-color");
4852 staticpro (&Qborder_color
);
4853 Qborder_width
= intern ("border-width");
4854 staticpro (&Qborder_width
);
4855 Qbox
= intern ("box");
4857 Qcursor_color
= intern ("cursor-color");
4858 staticpro (&Qcursor_color
);
4859 Qcursor_type
= intern ("cursor-type");
4860 staticpro (&Qcursor_type
);
4861 Qfont
= intern ("font");
4863 Qforeground_color
= intern ("foreground-color");
4864 staticpro (&Qforeground_color
);
4865 Qgeometry
= intern ("geometry");
4866 staticpro (&Qgeometry
);
4867 Qicon_left
= intern ("icon-left");
4868 staticpro (&Qicon_left
);
4869 Qicon_top
= intern ("icon-top");
4870 staticpro (&Qicon_top
);
4871 Qicon_type
= intern ("icon-type");
4872 staticpro (&Qicon_type
);
4873 Qicon_name
= intern ("icon-name");
4874 staticpro (&Qicon_name
);
4875 Qinternal_border_width
= intern ("internal-border-width");
4876 staticpro (&Qinternal_border_width
);
4877 Qleft
= intern ("left");
4879 Qmouse_color
= intern ("mouse-color");
4880 staticpro (&Qmouse_color
);
4881 Qnone
= intern ("none");
4883 Qparent_id
= intern ("parent-id");
4884 staticpro (&Qparent_id
);
4885 Qscroll_bar_width
= intern ("scroll-bar-width");
4886 staticpro (&Qscroll_bar_width
);
4887 Qsuppress_icon
= intern ("suppress-icon");
4888 staticpro (&Qsuppress_icon
);
4889 Qtop
= intern ("top");
4891 Qundefined_color
= intern ("undefined-color");
4892 staticpro (&Qundefined_color
);
4893 Qvertical_scroll_bars
= intern ("vertical-scroll-bars");
4894 staticpro (&Qvertical_scroll_bars
);
4895 Qvisibility
= intern ("visibility");
4896 staticpro (&Qvisibility
);
4897 Qwindow_id
= intern ("window-id");
4898 staticpro (&Qwindow_id
);
4899 Qx_frame_parameter
= intern ("x-frame-parameter");
4900 staticpro (&Qx_frame_parameter
);
4901 Qx_resource_name
= intern ("x-resource-name");
4902 staticpro (&Qx_resource_name
);
4903 Quser_position
= intern ("user-position");
4904 staticpro (&Quser_position
);
4905 Quser_size
= intern ("user-size");
4906 staticpro (&Quser_size
);
4907 Qdisplay
= intern ("display");
4908 staticpro (&Qdisplay
);
4909 /* This is the end of symbol initialization. */
4911 Fput (Qundefined_color
, Qerror_conditions
,
4912 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
4913 Fput (Qundefined_color
, Qerror_message
,
4914 build_string ("Undefined color"));
4916 init_x_parm_symbols ();
4918 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path
,
4919 "List of directories to search for bitmap files for X.");
4920 Vx_bitmap_file_path
= decode_env_path ((char *) 0, PATH_BITMAPS
);
4922 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
4923 "The shape of the pointer when over text.\n\
4924 Changing the value does not affect existing frames\n\
4925 unless you set the mouse color.");
4926 Vx_pointer_shape
= Qnil
;
4928 DEFVAR_LISP ("x-resource-name", &Vx_resource_name
,
4929 "The name Emacs uses to look up X resources; for internal use only.\n\
4930 `x-get-resource' uses this as the first component of the instance name\n\
4931 when requesting resource values.\n\
4932 Emacs initially sets `x-resource-name' to the name under which Emacs\n\
4933 was invoked, or to the value specified with the `-name' or `-rn'\n\
4934 switches, if present.");
4935 Vx_resource_name
= Qnil
;
4937 #if 0 /* This doesn't really do anything. */
4938 DEFVAR_INT ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape
,
4939 "The shape of the pointer when not over text.\n\
4940 This variable takes effect when you create a new frame\n\
4941 or when you set the mouse color.");
4943 Vx_nontext_pointer_shape
= Qnil
;
4945 #if 0 /* This doesn't really do anything. */
4946 DEFVAR_INT ("x-mode-pointer-shape", &Vx_mode_pointer_shape
,
4947 "The shape of the pointer when over the mode line.\n\
4948 This variable takes effect when you create a new frame\n\
4949 or when you set the mouse color.");
4951 Vx_mode_pointer_shape
= Qnil
;
4953 DEFVAR_INT ("x-sensitive-text-pointer-shape",
4954 &Vx_sensitive_text_pointer_shape
,
4955 "The shape of the pointer when over mouse-sensitive text.\n\
4956 This variable takes effect when you create a new frame\n\
4957 or when you set the mouse color.");
4958 Vx_sensitive_text_pointer_shape
= Qnil
;
4960 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
4961 "A string indicating the foreground color of the cursor box.");
4962 Vx_cursor_fore_pixel
= Qnil
;
4964 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
4965 "Non-nil if no X window manager is in use.\n\
4966 Emacs doesn't try to figure this out; this is always nil\n\
4967 unless you set it to something else.");
4968 /* We don't have any way to find this out, so set it to nil
4969 and maybe the user would like to set it to t. */
4970 Vx_no_window_manager
= Qnil
;
4972 #ifdef USE_X_TOOLKIT
4973 Fprovide (intern ("x-toolkit"));
4976 Fprovide (intern ("motif"));
4979 defsubr (&Sx_get_resource
);
4981 defsubr (&Sx_draw_rectangle
);
4982 defsubr (&Sx_erase_rectangle
);
4983 defsubr (&Sx_contour_region
);
4984 defsubr (&Sx_uncontour_region
);
4986 defsubr (&Sx_list_fonts
);
4987 defsubr (&Sx_display_color_p
);
4988 defsubr (&Sx_display_grayscale_p
);
4989 defsubr (&Sx_color_defined_p
);
4990 defsubr (&Sx_color_values
);
4991 defsubr (&Sx_server_max_request_size
);
4992 defsubr (&Sx_server_vendor
);
4993 defsubr (&Sx_server_version
);
4994 defsubr (&Sx_display_pixel_width
);
4995 defsubr (&Sx_display_pixel_height
);
4996 defsubr (&Sx_display_mm_width
);
4997 defsubr (&Sx_display_mm_height
);
4998 defsubr (&Sx_display_screens
);
4999 defsubr (&Sx_display_planes
);
5000 defsubr (&Sx_display_color_cells
);
5001 defsubr (&Sx_display_visual_class
);
5002 defsubr (&Sx_display_backing_store
);
5003 defsubr (&Sx_display_save_under
);
5005 defsubr (&Sx_rebind_key
);
5006 defsubr (&Sx_rebind_keys
);
5007 defsubr (&Sx_track_pointer
);
5008 defsubr (&Sx_grab_pointer
);
5009 defsubr (&Sx_ungrab_pointer
);
5011 defsubr (&Sx_parse_geometry
);
5012 defsubr (&Sx_create_frame
);
5013 defsubr (&Sfocus_frame
);
5014 defsubr (&Sunfocus_frame
);
5016 defsubr (&Sx_horizontal_line
);
5018 defsubr (&Sx_open_connection
);
5019 defsubr (&Sx_close_connection
);
5020 defsubr (&Sx_display_list
);
5021 defsubr (&Sx_synchronize
);
5024 #endif /* HAVE_X_WINDOWS */