(undigestify-rmail-message): Update summary buffer.
[emacs.git] / src / xfns.c
blob898f86c3119f781efdab95375bb69523d20bc9a0
1 /* Functions for the X window system.
2 Copyright (C) 1989, 1992, 1993 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)
9 any later version.
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 */
24 #if 0
25 #include <stdio.h>
26 #endif
27 #include <signal.h>
28 #include <config.h>
29 #include "lisp.h"
30 #include "xterm.h"
31 #include "frame.h"
32 #include "window.h"
33 #include "buffer.h"
34 #include "dispextern.h"
35 #include "keyboard.h"
36 #include "blockinput.h"
38 #ifdef HAVE_X_WINDOWS
39 extern void abort ();
41 #ifndef VMS
42 #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */
43 #include "bitmaps/gray.xbm"
44 #else
45 #include <X11/bitmaps/gray>
46 #endif
47 #else
48 #include "[.bitmaps]gray.xbm"
49 #endif
51 #ifdef USE_X_TOOLKIT
52 #include <X11/Shell.h>
54 #include <X11/Xaw/Paned.h>
55 #include <X11/Xaw/Label.h>
57 #ifdef USG
58 #undef USG /* ####KLUDGE for Solaris 2.2 and up */
59 #include <X11/Xos.h>
60 #define USG
61 #else
62 #include <X11/Xos.h>
63 #endif
65 #include "widget.h"
67 #include "../lwlib/lwlib.h"
69 /* The one and only application context associated with the connection
70 to the one and only X display that Emacs uses. */
71 XtAppContext Xt_app_con;
73 /* The one and only application shell. Emacs screens are popup shells of this
74 application. */
75 Widget Xt_app_shell;
77 extern void free_frame_menubar ();
78 extern void free_frame_menubar ();
79 #endif /* USE_X_TOOLKIT */
81 #define min(a,b) ((a) < (b) ? (a) : (b))
82 #define max(a,b) ((a) > (b) ? (a) : (b))
84 #ifdef HAVE_X11
85 /* X Resource data base */
86 static XrmDatabase xrdb;
88 /* The class of this X application. */
89 #define EMACS_CLASS "Emacs"
91 #ifdef HAVE_X11R4
92 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
93 #else
94 #define MAXREQUEST(dpy) ((dpy)->max_request_size)
95 #endif
97 /* The name we're using in resource queries. */
98 Lisp_Object Vx_resource_name;
100 /* Title name and application name for X stuff. */
101 extern char *x_id_name;
103 /* The background and shape of the mouse pointer, and shape when not
104 over text or in the modeline. */
105 Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
106 Lisp_Object Vx_cross_pointer_shape;
108 /* Color of chars displayed in cursor box. */
109 Lisp_Object Vx_cursor_fore_pixel;
111 /* The screen being used. */
112 static Screen *x_screen;
114 /* The X Visual we are using for X windows (the default) */
115 Visual *screen_visual;
117 /* Height of this X screen in pixels. */
118 int x_screen_height;
120 /* Width of this X screen in pixels. */
121 int x_screen_width;
123 /* Number of planes for this screen. */
124 int x_screen_planes;
126 /* Non nil if no window manager is in use. */
127 Lisp_Object Vx_no_window_manager;
129 /* `t' if a mouse button is depressed. */
131 Lisp_Object Vmouse_depressed;
133 extern unsigned int x_mouse_x, x_mouse_y, x_mouse_grabbed;
135 /* Atom for indicating window state to the window manager. */
136 extern Atom Xatom_wm_change_state;
138 /* Communication with window managers. */
139 extern Atom Xatom_wm_protocols;
141 /* Kinds of protocol things we may receive. */
142 extern Atom Xatom_wm_take_focus;
143 extern Atom Xatom_wm_save_yourself;
144 extern Atom Xatom_wm_delete_window;
146 /* Other WM communication */
147 extern Atom Xatom_wm_configure_denied; /* When our config request is denied */
148 extern Atom Xatom_wm_window_moved; /* When the WM moves us. */
150 /* EditRes protocol */
151 extern Atom Xatom_editres_name;
153 #else /* X10 */
155 /* Default size of an Emacs window. */
156 static char *default_window = "=80x24+0+0";
158 #define MAXICID 80
159 char iconidentity[MAXICID];
160 #define ICONTAG "emacs@"
161 char minibuffer_iconidentity[MAXICID];
162 #define MINIBUFFER_ICONTAG "minibuffer@"
164 #endif /* X10 */
166 /* The last 23 bits of the timestamp of the last mouse button event. */
167 Time mouse_timestamp;
169 /* Evaluate this expression to rebuild the section of syms_of_xfns
170 that initializes and staticpros the symbols declared below. Note
171 that Emacs 18 has a bug that keeps C-x C-e from being able to
172 evaluate this expression.
174 (progn
175 ;; Accumulate a list of the symbols we want to initialize from the
176 ;; declarations at the top of the file.
177 (goto-char (point-min))
178 (search-forward "/\*&&& symbols declared here &&&*\/\n")
179 (let (symbol-list)
180 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
181 (setq symbol-list
182 (cons (buffer-substring (match-beginning 1) (match-end 1))
183 symbol-list))
184 (forward-line 1))
185 (setq symbol-list (nreverse symbol-list))
186 ;; Delete the section of syms_of_... where we initialize the symbols.
187 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
188 (let ((start (point)))
189 (while (looking-at "^ Q")
190 (forward-line 2))
191 (kill-region start (point)))
192 ;; Write a new symbol initialization section.
193 (while symbol-list
194 (insert (format " %s = intern (\"" (car symbol-list)))
195 (let ((start (point)))
196 (insert (substring (car symbol-list) 1))
197 (subst-char-in-region start (point) ?_ ?-))
198 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
199 (setq symbol-list (cdr symbol-list)))))
203 /*&&& symbols declared here &&&*/
204 Lisp_Object Qauto_raise;
205 Lisp_Object Qauto_lower;
206 Lisp_Object Qbackground_color;
207 Lisp_Object Qbar;
208 Lisp_Object Qborder_color;
209 Lisp_Object Qborder_width;
210 Lisp_Object Qbox;
211 Lisp_Object Qcursor_color;
212 Lisp_Object Qcursor_type;
213 Lisp_Object Qfont;
214 Lisp_Object Qforeground_color;
215 Lisp_Object Qgeometry;
216 /* Lisp_Object Qicon; */
217 Lisp_Object Qicon_left;
218 Lisp_Object Qicon_top;
219 Lisp_Object Qicon_type;
220 Lisp_Object Qinternal_border_width;
221 Lisp_Object Qleft;
222 Lisp_Object Qmouse_color;
223 Lisp_Object Qnone;
224 Lisp_Object Qparent_id;
225 Lisp_Object Qsuppress_icon;
226 Lisp_Object Qtop;
227 Lisp_Object Qundefined_color;
228 Lisp_Object Qvertical_scroll_bars;
229 Lisp_Object Qvisibility;
230 Lisp_Object Qwindow_id;
231 Lisp_Object Qx_frame_parameter;
232 Lisp_Object Qx_resource_name;
234 /* The below are defined in frame.c. */
235 extern Lisp_Object Qheight, Qminibuffer, Qname, Qonly, Qwidth;
236 extern Lisp_Object Qunsplittable, Qmenu_bar_lines;
238 extern Lisp_Object Vwindow_system_version;
241 /* Error if we are not connected to X. */
242 void
243 check_x ()
245 if (x_current_display == 0)
246 error ("X windows are not in use or not initialized");
249 /* Return the Emacs frame-object corresponding to an X window.
250 It could be the frame's main window or an icon window. */
252 /* This function can be called during GC, so use XGCTYPE. */
254 struct frame *
255 x_window_to_frame (wdesc)
256 int wdesc;
258 Lisp_Object tail, frame;
259 struct frame *f;
261 for (tail = Vframe_list; XGCTYPE (tail) == Lisp_Cons;
262 tail = XCONS (tail)->cdr)
264 frame = XCONS (tail)->car;
265 if (XGCTYPE (frame) != Lisp_Frame)
266 continue;
267 f = XFRAME (frame);
268 #ifdef USE_X_TOOLKIT
269 if (f->display.nothing == 1)
270 return 0;
271 if ((f->display.x->edit_widget
272 && XtWindow (f->display.x->edit_widget) == wdesc)
273 || f->display.x->icon_desc == wdesc)
274 return f;
275 #else /* not USE_X_TOOLKIT */
276 if (FRAME_X_WINDOW (f) == wdesc
277 || f->display.x->icon_desc == wdesc)
278 return f;
279 #endif /* not USE_X_TOOLKIT */
281 return 0;
284 #ifdef USE_X_TOOLKIT
285 /* Like x_window_to_frame but also compares the window with the widget's
286 windows. */
288 struct frame *
289 x_any_window_to_frame (wdesc)
290 int wdesc;
292 Lisp_Object tail, frame;
293 struct frame *f;
294 struct x_display *x;
296 for (tail = Vframe_list; XGCTYPE (tail) == Lisp_Cons;
297 tail = XCONS (tail)->cdr)
299 frame = XCONS (tail)->car;
300 if (XGCTYPE (frame) != Lisp_Frame)
301 continue;
302 f = XFRAME (frame);
303 if (f->display.nothing == 1)
304 return 0;
305 x = f->display.x;
306 /* This frame matches if the window is any of its widgets. */
307 if (wdesc == XtWindow (x->widget)
308 || wdesc == XtWindow (x->column_widget)
309 || wdesc == XtWindow (x->edit_widget))
310 return f;
311 /* Match if the window is this frame's menubar. */
312 if (x->menubar_widget
313 && wdesc == XtWindow (x->menubar_widget))
314 return f;
316 return 0;
318 #endif /* USE_X_TOOLKIT */
321 /* Connect the frame-parameter names for X frames
322 to the ways of passing the parameter values to the window system.
324 The name of a parameter, as a Lisp symbol,
325 has an `x-frame-parameter' property which is an integer in Lisp
326 but can be interpreted as an `enum x_frame_parm' in C. */
328 enum x_frame_parm
330 X_PARM_FOREGROUND_COLOR,
331 X_PARM_BACKGROUND_COLOR,
332 X_PARM_MOUSE_COLOR,
333 X_PARM_CURSOR_COLOR,
334 X_PARM_BORDER_COLOR,
335 X_PARM_ICON_TYPE,
336 X_PARM_FONT,
337 X_PARM_BORDER_WIDTH,
338 X_PARM_INTERNAL_BORDER_WIDTH,
339 X_PARM_NAME,
340 X_PARM_AUTORAISE,
341 X_PARM_AUTOLOWER,
342 X_PARM_VERT_SCROLL_BAR,
343 X_PARM_VISIBILITY,
344 X_PARM_MENU_BAR_LINES
348 struct x_frame_parm_table
350 char *name;
351 void (*setter)( /* struct frame *frame, Lisp_Object val, oldval */ );
354 void x_set_foreground_color ();
355 void x_set_background_color ();
356 void x_set_mouse_color ();
357 void x_set_cursor_color ();
358 void x_set_border_color ();
359 void x_set_cursor_type ();
360 void x_set_icon_type ();
361 void x_set_font ();
362 void x_set_border_width ();
363 void x_set_internal_border_width ();
364 void x_explicitly_set_name ();
365 void x_set_autoraise ();
366 void x_set_autolower ();
367 void x_set_vertical_scroll_bars ();
368 void x_set_visibility ();
369 void x_set_menu_bar_lines ();
371 static struct x_frame_parm_table x_frame_parms[] =
373 "foreground-color", x_set_foreground_color,
374 "background-color", x_set_background_color,
375 "mouse-color", x_set_mouse_color,
376 "cursor-color", x_set_cursor_color,
377 "border-color", x_set_border_color,
378 "cursor-type", x_set_cursor_type,
379 "icon-type", x_set_icon_type,
380 "font", x_set_font,
381 "border-width", x_set_border_width,
382 "internal-border-width", x_set_internal_border_width,
383 "name", x_explicitly_set_name,
384 "auto-raise", x_set_autoraise,
385 "auto-lower", x_set_autolower,
386 "vertical-scroll-bars", x_set_vertical_scroll_bars,
387 "visibility", x_set_visibility,
388 "menu-bar-lines", x_set_menu_bar_lines,
391 /* Attach the `x-frame-parameter' properties to
392 the Lisp symbol names of parameters relevant to X. */
394 init_x_parm_symbols ()
396 int i;
398 for (i = 0; i < sizeof (x_frame_parms) / sizeof (x_frame_parms[0]); i++)
399 Fput (intern (x_frame_parms[i].name), Qx_frame_parameter,
400 make_number (i));
403 /* Change the parameters of FRAME as specified by ALIST.
404 If a parameter is not specially recognized, do nothing;
405 otherwise call the `x_set_...' function for that parameter. */
407 void
408 x_set_frame_parameters (f, alist)
409 FRAME_PTR f;
410 Lisp_Object alist;
412 Lisp_Object tail;
414 /* If both of these parameters are present, it's more efficient to
415 set them both at once. So we wait until we've looked at the
416 entire list before we set them. */
417 Lisp_Object width, height;
419 /* Same here. */
420 Lisp_Object left, top;
422 /* Record in these vectors all the parms specified. */
423 Lisp_Object *parms;
424 Lisp_Object *values;
425 int i;
427 i = 0;
428 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
429 i++;
431 parms = (Lisp_Object *) alloca (i * sizeof (Lisp_Object));
432 values = (Lisp_Object *) alloca (i * sizeof (Lisp_Object));
434 /* Extract parm names and values into those vectors. */
436 i = 0;
437 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
439 Lisp_Object elt, prop, val;
441 elt = Fcar (tail);
442 parms[i] = Fcar (elt);
443 values[i] = Fcdr (elt);
444 i++;
447 width = height = top = left = Qunbound;
449 /* Now process them in reverse of specified order. */
450 for (i--; i >= 0; i--)
452 Lisp_Object prop, val;
454 prop = parms[i];
455 val = values[i];
457 if (EQ (prop, Qwidth))
458 width = val;
459 else if (EQ (prop, Qheight))
460 height = val;
461 else if (EQ (prop, Qtop))
462 top = val;
463 else if (EQ (prop, Qleft))
464 left = val;
465 else
467 register Lisp_Object param_index, old_value;
469 param_index = Fget (prop, Qx_frame_parameter);
470 old_value = get_frame_param (f, prop);
471 store_frame_param (f, prop, val);
472 if (XTYPE (param_index) == Lisp_Int
473 && XINT (param_index) >= 0
474 && (XINT (param_index)
475 < sizeof (x_frame_parms)/sizeof (x_frame_parms[0])))
476 (*x_frame_parms[XINT (param_index)].setter)(f, val, old_value);
480 /* Don't die if just one of these was set. */
481 if (EQ (left, Qunbound))
482 XSET (left, Lisp_Int, f->display.x->left_pos);
483 if (EQ (top, Qunbound))
484 XSET (top, Lisp_Int, f->display.x->top_pos);
486 /* Don't die if just one of these was set. */
487 if (EQ (width, Qunbound))
488 XSET (width, Lisp_Int, FRAME_WIDTH (f));
489 if (EQ (height, Qunbound))
490 XSET (height, Lisp_Int, FRAME_HEIGHT (f));
492 /* Don't set these parameters these unless they've been explicitly
493 specified. The window might be mapped or resized while we're in
494 this function, and we don't want to override that unless the lisp
495 code has asked for it.
497 Don't set these parameters unless they actually differ from the
498 window's current parameters; the window may not actually exist
499 yet. */
501 Lisp_Object frame;
503 check_frame_size (f, &height, &width);
505 XSET (frame, Lisp_Frame, f);
507 if ((NUMBERP (width) && XINT (width) != FRAME_WIDTH (f))
508 || (NUMBERP (height) && XINT (height) != FRAME_HEIGHT (f)))
509 Fset_frame_size (frame, width, height);
510 if ((NUMBERP (left) && XINT (left) != f->display.x->left_pos)
511 || (NUMBERP (top) && XINT (top) != f->display.x->top_pos))
512 Fset_frame_position (frame, left, top);
516 /* Insert a description of internally-recorded parameters of frame X
517 into the parameter alist *ALISTPTR that is to be given to the user.
518 Only parameters that are specific to the X window system
519 and whose values are not correctly recorded in the frame's
520 param_alist need to be considered here. */
522 x_report_frame_params (f, alistptr)
523 struct frame *f;
524 Lisp_Object *alistptr;
526 char buf[16];
528 store_in_alist (alistptr, Qleft, make_number (f->display.x->left_pos));
529 store_in_alist (alistptr, Qtop, make_number (f->display.x->top_pos));
530 store_in_alist (alistptr, Qborder_width,
531 make_number (f->display.x->border_width));
532 store_in_alist (alistptr, Qinternal_border_width,
533 make_number (f->display.x->internal_border_width));
534 sprintf (buf, "%d", FRAME_X_WINDOW (f));
535 store_in_alist (alistptr, Qwindow_id,
536 build_string (buf));
537 FRAME_SAMPLE_VISIBILITY (f);
538 store_in_alist (alistptr, Qvisibility,
539 (FRAME_VISIBLE_P (f) ? Qt
540 : FRAME_ICONIFIED_P (f) ? Qicon : Qnil));
543 /* Decide if color named COLOR is valid for the display
544 associated with the selected frame. */
546 defined_color (color, color_def)
547 char *color;
548 Color *color_def;
550 register int foo;
551 Colormap screen_colormap;
553 BLOCK_INPUT;
554 #ifdef HAVE_X11
555 screen_colormap
556 = DefaultColormap (x_current_display, XDefaultScreen (x_current_display));
558 foo = XParseColor (x_current_display, screen_colormap,
559 color, color_def)
560 && XAllocColor (x_current_display, screen_colormap, color_def);
561 #else
562 foo = XParseColor (color, color_def) && XGetHardwareColor (color_def);
563 #endif /* not HAVE_X11 */
564 UNBLOCK_INPUT;
566 if (foo)
567 return 1;
568 else
569 return 0;
572 /* Given a string ARG naming a color, compute a pixel value from it
573 suitable for screen F.
574 If F is not a color screen, return DEF (default) regardless of what
575 ARG says. */
578 x_decode_color (arg, def)
579 Lisp_Object arg;
580 int def;
582 Color cdef;
584 CHECK_STRING (arg, 0);
586 if (strcmp (XSTRING (arg)->data, "black") == 0)
587 return BLACK_PIX_DEFAULT;
588 else if (strcmp (XSTRING (arg)->data, "white") == 0)
589 return WHITE_PIX_DEFAULT;
591 #ifdef HAVE_X11
592 if (x_screen_planes == 1)
593 return def;
594 #else
595 if (DISPLAY_CELLS == 1)
596 return def;
597 #endif
599 if (defined_color (XSTRING (arg)->data, &cdef))
600 return cdef.pixel;
601 else
602 Fsignal (Qundefined_color, Fcons (arg, Qnil));
605 /* Functions called only from `x_set_frame_param'
606 to set individual parameters.
608 If FRAME_X_WINDOW (f) is 0,
609 the frame is being created and its X-window does not exist yet.
610 In that case, just record the parameter's new value
611 in the standard place; do not attempt to change the window. */
613 void
614 x_set_foreground_color (f, arg, oldval)
615 struct frame *f;
616 Lisp_Object arg, oldval;
618 f->display.x->foreground_pixel = x_decode_color (arg, BLACK_PIX_DEFAULT);
619 if (FRAME_X_WINDOW (f) != 0)
621 #ifdef HAVE_X11
622 BLOCK_INPUT;
623 XSetForeground (x_current_display, f->display.x->normal_gc,
624 f->display.x->foreground_pixel);
625 XSetBackground (x_current_display, f->display.x->reverse_gc,
626 f->display.x->foreground_pixel);
627 UNBLOCK_INPUT;
628 #endif /* HAVE_X11 */
629 recompute_basic_faces (f);
630 if (FRAME_VISIBLE_P (f))
631 redraw_frame (f);
635 void
636 x_set_background_color (f, arg, oldval)
637 struct frame *f;
638 Lisp_Object arg, oldval;
640 Pixmap temp;
641 int mask;
643 f->display.x->background_pixel = x_decode_color (arg, WHITE_PIX_DEFAULT);
645 if (FRAME_X_WINDOW (f) != 0)
647 BLOCK_INPUT;
648 #ifdef HAVE_X11
649 /* The main frame area. */
650 XSetBackground (x_current_display, f->display.x->normal_gc,
651 f->display.x->background_pixel);
652 XSetForeground (x_current_display, f->display.x->reverse_gc,
653 f->display.x->background_pixel);
654 XSetForeground (x_current_display, f->display.x->cursor_gc,
655 f->display.x->background_pixel);
656 XSetWindowBackground (x_current_display, FRAME_X_WINDOW (f),
657 f->display.x->background_pixel);
659 #else
660 temp = XMakeTile (f->display.x->background_pixel);
661 XChangeBackground (FRAME_X_WINDOW (f), temp);
662 XFreePixmap (temp);
663 #endif /* not HAVE_X11 */
664 UNBLOCK_INPUT;
666 recompute_basic_faces (f);
668 if (FRAME_VISIBLE_P (f))
669 redraw_frame (f);
673 void
674 x_set_mouse_color (f, arg, oldval)
675 struct frame *f;
676 Lisp_Object arg, oldval;
678 Cursor cursor, nontext_cursor, mode_cursor, cross_cursor;
679 int mask_color;
681 if (!EQ (Qnil, arg))
682 f->display.x->mouse_pixel = x_decode_color (arg, BLACK_PIX_DEFAULT);
683 mask_color = f->display.x->background_pixel;
684 /* No invisible pointers. */
685 if (mask_color == f->display.x->mouse_pixel
686 && mask_color == f->display.x->background_pixel)
687 f->display.x->mouse_pixel = f->display.x->foreground_pixel;
689 BLOCK_INPUT;
690 #ifdef HAVE_X11
692 /* It's not okay to crash if the user selects a screwy cursor. */
693 x_catch_errors ();
695 if (!EQ (Qnil, Vx_pointer_shape))
697 CHECK_NUMBER (Vx_pointer_shape, 0);
698 cursor = XCreateFontCursor (x_current_display, XINT (Vx_pointer_shape));
700 else
701 cursor = XCreateFontCursor (x_current_display, XC_xterm);
702 x_check_errors ("bad text pointer cursor: %s");
704 if (!EQ (Qnil, Vx_nontext_pointer_shape))
706 CHECK_NUMBER (Vx_nontext_pointer_shape, 0);
707 nontext_cursor = XCreateFontCursor (x_current_display,
708 XINT (Vx_nontext_pointer_shape));
710 else
711 nontext_cursor = XCreateFontCursor (x_current_display, XC_left_ptr);
712 x_check_errors ("bad nontext pointer cursor: %s");
714 if (!EQ (Qnil, Vx_mode_pointer_shape))
716 CHECK_NUMBER (Vx_mode_pointer_shape, 0);
717 mode_cursor = XCreateFontCursor (x_current_display,
718 XINT (Vx_mode_pointer_shape));
720 else
721 mode_cursor = XCreateFontCursor (x_current_display, XC_xterm);
722 x_check_errors ("bad modeline pointer cursor: %s");
724 if (!EQ (Qnil, Vx_cross_pointer_shape))
726 CHECK_NUMBER (Vx_cross_pointer_shape, 0);
727 cross_cursor = XCreateFontCursor (x_current_display,
728 XINT (Vx_cross_pointer_shape));
730 else
731 cross_cursor = XCreateFontCursor (x_current_display, XC_crosshair);
733 /* Check and report errors with the above calls. */
734 x_check_errors ("can't set cursor shape: %s");
735 x_uncatch_errors ();
738 XColor fore_color, back_color;
740 fore_color.pixel = f->display.x->mouse_pixel;
741 back_color.pixel = mask_color;
742 XQueryColor (x_current_display,
743 DefaultColormap (x_current_display,
744 DefaultScreen (x_current_display)),
745 &fore_color);
746 XQueryColor (x_current_display,
747 DefaultColormap (x_current_display,
748 DefaultScreen (x_current_display)),
749 &back_color);
750 XRecolorCursor (x_current_display, cursor,
751 &fore_color, &back_color);
752 XRecolorCursor (x_current_display, nontext_cursor,
753 &fore_color, &back_color);
754 XRecolorCursor (x_current_display, mode_cursor,
755 &fore_color, &back_color);
756 XRecolorCursor (x_current_display, cross_cursor,
757 &fore_color, &back_color);
759 #else /* X10 */
760 cursor = XCreateCursor (16, 16, MouseCursor, MouseMask,
761 0, 0,
762 f->display.x->mouse_pixel,
763 f->display.x->background_pixel,
764 GXcopy);
765 #endif /* X10 */
767 if (FRAME_X_WINDOW (f) != 0)
769 XDefineCursor (XDISPLAY FRAME_X_WINDOW (f), cursor);
772 if (cursor != f->display.x->text_cursor && f->display.x->text_cursor != 0)
773 XFreeCursor (XDISPLAY f->display.x->text_cursor);
774 f->display.x->text_cursor = cursor;
775 #ifdef HAVE_X11
776 if (nontext_cursor != f->display.x->nontext_cursor
777 && f->display.x->nontext_cursor != 0)
778 XFreeCursor (XDISPLAY f->display.x->nontext_cursor);
779 f->display.x->nontext_cursor = nontext_cursor;
781 if (mode_cursor != f->display.x->modeline_cursor
782 && f->display.x->modeline_cursor != 0)
783 XFreeCursor (XDISPLAY f->display.x->modeline_cursor);
784 f->display.x->modeline_cursor = mode_cursor;
785 if (cross_cursor != f->display.x->cross_cursor
786 && f->display.x->cross_cursor != 0)
787 XFreeCursor (XDISPLAY f->display.x->cross_cursor);
788 f->display.x->cross_cursor = cross_cursor;
789 #endif /* HAVE_X11 */
791 XFlushQueue ();
792 UNBLOCK_INPUT;
795 void
796 x_set_cursor_color (f, arg, oldval)
797 struct frame *f;
798 Lisp_Object arg, oldval;
800 unsigned long fore_pixel;
802 if (!EQ (Vx_cursor_fore_pixel, Qnil))
803 fore_pixel = x_decode_color (Vx_cursor_fore_pixel, WHITE_PIX_DEFAULT);
804 else
805 fore_pixel = f->display.x->background_pixel;
806 f->display.x->cursor_pixel = x_decode_color (arg, BLACK_PIX_DEFAULT);
808 /* Make sure that the cursor color differs from the background color. */
809 if (f->display.x->cursor_pixel == f->display.x->background_pixel)
811 f->display.x->cursor_pixel == f->display.x->mouse_pixel;
812 if (f->display.x->cursor_pixel == fore_pixel)
813 fore_pixel = f->display.x->background_pixel;
815 f->display.x->cursor_foreground_pixel = fore_pixel;
817 if (FRAME_X_WINDOW (f) != 0)
819 #ifdef HAVE_X11
820 BLOCK_INPUT;
821 XSetBackground (x_current_display, f->display.x->cursor_gc,
822 f->display.x->cursor_pixel);
823 XSetForeground (x_current_display, f->display.x->cursor_gc,
824 fore_pixel);
825 UNBLOCK_INPUT;
826 #endif /* HAVE_X11 */
828 if (FRAME_VISIBLE_P (f))
830 x_display_cursor (f, 0);
831 x_display_cursor (f, 1);
836 /* Set the border-color of frame F to value described by ARG.
837 ARG can be a string naming a color.
838 The border-color is used for the border that is drawn by the X server.
839 Note that this does not fully take effect if done before
840 F has an x-window; it must be redone when the window is created.
842 Note: this is done in two routines because of the way X10 works.
844 Note: under X11, this is normally the province of the window manager,
845 and so emacs' border colors may be overridden. */
847 void
848 x_set_border_color (f, arg, oldval)
849 struct frame *f;
850 Lisp_Object arg, oldval;
852 unsigned char *str;
853 int pix;
855 CHECK_STRING (arg, 0);
856 str = XSTRING (arg)->data;
858 #ifndef HAVE_X11
859 if (!strcmp (str, "grey") || !strcmp (str, "Grey")
860 || !strcmp (str, "gray") || !strcmp (str, "Gray"))
861 pix = -1;
862 else
863 #endif /* X10 */
865 pix = x_decode_color (arg, BLACK_PIX_DEFAULT);
867 x_set_border_pixel (f, pix);
870 /* Set the border-color of frame F to pixel value PIX.
871 Note that this does not fully take effect if done before
872 F has an x-window. */
874 x_set_border_pixel (f, pix)
875 struct frame *f;
876 int pix;
878 f->display.x->border_pixel = pix;
880 if (FRAME_X_WINDOW (f) != 0 && f->display.x->border_width > 0)
882 Pixmap temp;
883 int mask;
885 BLOCK_INPUT;
886 #ifdef HAVE_X11
887 XSetWindowBorder (x_current_display, FRAME_X_WINDOW (f),
888 pix);
889 #else
890 if (pix < 0)
891 temp = XMakePixmap ((Bitmap) XStoreBitmap (gray_width, gray_height,
892 gray_bits),
893 BLACK_PIX_DEFAULT, WHITE_PIX_DEFAULT);
894 else
895 temp = XMakeTile (pix);
896 XChangeBorder (FRAME_X_WINDOW (f), temp);
897 XFreePixmap (XDISPLAY temp);
898 #endif /* not HAVE_X11 */
899 UNBLOCK_INPUT;
901 if (FRAME_VISIBLE_P (f))
902 redraw_frame (f);
906 void
907 x_set_cursor_type (f, arg, oldval)
908 FRAME_PTR f;
909 Lisp_Object arg, oldval;
911 if (EQ (arg, Qbar))
912 FRAME_DESIRED_CURSOR (f) = bar_cursor;
913 else
914 #if 0
915 if (EQ (arg, Qbox))
916 #endif
917 FRAME_DESIRED_CURSOR (f) = filled_box_cursor;
918 /* Error messages commented out because people have trouble fixing
919 .Xdefaults with Emacs, when it has something bad in it. */
920 #if 0
921 else
922 error
923 ("the `cursor-type' frame parameter should be either `bar' or `box'");
924 #endif
926 /* Make sure the cursor gets redrawn. This is overkill, but how
927 often do people change cursor types? */
928 update_mode_lines++;
931 void
932 x_set_icon_type (f, arg, oldval)
933 struct frame *f;
934 Lisp_Object arg, oldval;
936 Lisp_Object tem;
937 int result;
939 if (EQ (oldval, Qnil) == EQ (arg, Qnil))
940 return;
942 BLOCK_INPUT;
943 if (NILP (arg))
944 result = x_text_icon (f, 0);
945 else
946 result = x_bitmap_icon (f);
948 if (result)
950 UNBLOCK_INPUT;
951 error ("No icon window available.");
954 /* If the window was unmapped (and its icon was mapped),
955 the new icon is not mapped, so map the window in its stead. */
956 if (FRAME_VISIBLE_P (f))
957 #ifdef USE_X_TOOLKIT
958 XtPopup (f->display.x->widget, XtGrabNone);
959 #endif
960 XMapWindow (XDISPLAY FRAME_X_WINDOW (f));
962 XFlushQueue ();
963 UNBLOCK_INPUT;
966 extern Lisp_Object x_new_font ();
968 void
969 x_set_font (f, arg, oldval)
970 struct frame *f;
971 Lisp_Object arg, oldval;
973 Lisp_Object result;
975 CHECK_STRING (arg, 1);
977 BLOCK_INPUT;
978 result = x_new_font (f, XSTRING (arg)->data);
979 UNBLOCK_INPUT;
981 if (EQ (result, Qnil))
982 error ("Font \"%s\" is not defined", XSTRING (arg)->data);
983 else if (EQ (result, Qt))
984 error ("the characters of the given font have varying widths");
985 else if (STRINGP (result))
987 recompute_basic_faces (f);
988 store_frame_param (f, Qfont, result);
990 else
991 abort ();
994 void
995 x_set_border_width (f, arg, oldval)
996 struct frame *f;
997 Lisp_Object arg, oldval;
999 CHECK_NUMBER (arg, 0);
1001 if (XINT (arg) == f->display.x->border_width)
1002 return;
1004 if (FRAME_X_WINDOW (f) != 0)
1005 error ("Cannot change the border width of a window");
1007 f->display.x->border_width = XINT (arg);
1010 void
1011 x_set_internal_border_width (f, arg, oldval)
1012 struct frame *f;
1013 Lisp_Object arg, oldval;
1015 int mask;
1016 int old = f->display.x->internal_border_width;
1018 CHECK_NUMBER (arg, 0);
1019 f->display.x->internal_border_width = XINT (arg);
1020 if (f->display.x->internal_border_width < 0)
1021 f->display.x->internal_border_width = 0;
1023 if (f->display.x->internal_border_width == old)
1024 return;
1026 if (FRAME_X_WINDOW (f) != 0)
1028 BLOCK_INPUT;
1029 x_set_window_size (f, 0, f->width, f->height);
1030 #if 0
1031 x_set_resize_hint (f);
1032 #endif
1033 XFlushQueue ();
1034 UNBLOCK_INPUT;
1035 SET_FRAME_GARBAGED (f);
1039 void
1040 x_set_visibility (f, value, oldval)
1041 struct frame *f;
1042 Lisp_Object value, oldval;
1044 Lisp_Object frame;
1045 XSET (frame, Lisp_Frame, f);
1047 if (NILP (value))
1048 Fmake_frame_invisible (frame, Qt);
1049 else if (EQ (value, Qicon))
1050 Ficonify_frame (frame);
1051 else
1052 Fmake_frame_visible (frame);
1055 static void
1056 x_set_menu_bar_lines_1 (window, n)
1057 Lisp_Object window;
1058 int n;
1060 struct window *w = XWINDOW (window);
1062 XFASTINT (w->top) += n;
1063 XFASTINT (w->height) -= n;
1065 /* Handle just the top child in a vertical split. */
1066 if (!NILP (w->vchild))
1067 x_set_menu_bar_lines_1 (w->vchild, n);
1069 /* Adjust all children in a horizontal split. */
1070 for (window = w->hchild; !NILP (window); window = w->next)
1072 w = XWINDOW (window);
1073 x_set_menu_bar_lines_1 (window, n);
1077 void
1078 x_set_menu_bar_lines (f, value, oldval)
1079 struct frame *f;
1080 Lisp_Object value, oldval;
1082 int nlines;
1083 int olines = FRAME_MENU_BAR_LINES (f);
1085 /* Right now, menu bars don't work properly in minibuf-only frames;
1086 most of the commands try to apply themselves to the minibuffer
1087 frame itslef, and get an error because you can't switch buffers
1088 in or split the minibuffer window. */
1089 if (FRAME_MINIBUF_ONLY_P (f))
1090 return;
1092 if (XTYPE (value) == Lisp_Int)
1093 nlines = XINT (value);
1094 else
1095 nlines = 0;
1097 #ifdef USE_X_TOOLKIT
1098 FRAME_MENU_BAR_LINES (f) = 0;
1099 if (nlines)
1100 FRAME_EXTERNAL_MENU_BAR (f) = 1;
1101 else
1103 if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
1104 free_frame_menubar (f);
1105 FRAME_EXTERNAL_MENU_BAR (f) = 0;
1106 f->display.x->menubar_widget = 0;
1108 #else /* not USE_X_TOOLKIT */
1109 FRAME_MENU_BAR_LINES (f) = nlines;
1110 x_set_menu_bar_lines_1 (f->root_window, nlines - olines);
1111 #endif /* not USE_X_TOOLKIT */
1114 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1115 x_id_name.
1117 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1118 name; if NAME is a string, set F's name to NAME and set
1119 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1121 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1122 suggesting a new name, which lisp code should override; if
1123 F->explicit_name is set, ignore the new name; otherwise, set it. */
1125 void
1126 x_set_name (f, name, explicit)
1127 struct frame *f;
1128 Lisp_Object name;
1129 int explicit;
1131 /* Make sure that requests from lisp code override requests from
1132 Emacs redisplay code. */
1133 if (explicit)
1135 /* If we're switching from explicit to implicit, we had better
1136 update the mode lines and thereby update the title. */
1137 if (f->explicit_name && NILP (name))
1138 update_mode_lines = 1;
1140 f->explicit_name = ! NILP (name);
1142 else if (f->explicit_name)
1143 return;
1145 /* If NAME is nil, set the name to the x_id_name. */
1146 if (NILP (name))
1147 name = build_string (x_id_name);
1148 else
1149 CHECK_STRING (name, 0);
1151 /* Don't change the name if it's already NAME. */
1152 if (! NILP (Fstring_equal (name, f->name)))
1153 return;
1155 if (FRAME_X_WINDOW (f))
1157 BLOCK_INPUT;
1158 #ifdef HAVE_X11R4
1160 XTextProperty text;
1161 text.value = XSTRING (name)->data;
1162 text.encoding = XA_STRING;
1163 text.format = 8;
1164 text.nitems = XSTRING (name)->size;
1165 #ifdef USE_X_TOOLKIT
1166 XSetWMName (x_current_display, XtWindow (f->display.x->widget), &text);
1167 XSetWMIconName (x_current_display, XtWindow (f->display.x->widget),
1168 &text);
1169 #else /* not USE_X_TOOLKIT */
1170 XSetWMName (x_current_display, FRAME_X_WINDOW (f), &text);
1171 XSetWMIconName (x_current_display, FRAME_X_WINDOW (f), &text);
1172 #endif /* not USE_X_TOOLKIT */
1174 #else /* not HAVE_X11R4 */
1175 XSetIconName (XDISPLAY FRAME_X_WINDOW (f),
1176 XSTRING (name)->data);
1177 XStoreName (XDISPLAY FRAME_X_WINDOW (f),
1178 XSTRING (name)->data);
1179 #endif /* not HAVE_X11R4 */
1180 UNBLOCK_INPUT;
1183 f->name = name;
1186 /* This function should be called when the user's lisp code has
1187 specified a name for the frame; the name will override any set by the
1188 redisplay code. */
1189 void
1190 x_explicitly_set_name (f, arg, oldval)
1191 FRAME_PTR f;
1192 Lisp_Object arg, oldval;
1194 x_set_name (f, arg, 1);
1197 /* This function should be called by Emacs redisplay code to set the
1198 name; names set this way will never override names set by the user's
1199 lisp code. */
1200 void
1201 x_implicitly_set_name (f, arg, oldval)
1202 FRAME_PTR f;
1203 Lisp_Object arg, oldval;
1205 x_set_name (f, arg, 0);
1208 void
1209 x_set_autoraise (f, arg, oldval)
1210 struct frame *f;
1211 Lisp_Object arg, oldval;
1213 f->auto_raise = !EQ (Qnil, arg);
1216 void
1217 x_set_autolower (f, arg, oldval)
1218 struct frame *f;
1219 Lisp_Object arg, oldval;
1221 f->auto_lower = !EQ (Qnil, arg);
1224 void
1225 x_set_vertical_scroll_bars (f, arg, oldval)
1226 struct frame *f;
1227 Lisp_Object arg, oldval;
1229 if (NILP (arg) != ! FRAME_HAS_VERTICAL_SCROLL_BARS (f))
1231 FRAME_HAS_VERTICAL_SCROLL_BARS (f) = ! NILP (arg);
1233 /* We set this parameter before creating the X window for the
1234 frame, so we can get the geometry right from the start.
1235 However, if the window hasn't been created yet, we shouldn't
1236 call x_set_window_size. */
1237 if (FRAME_X_WINDOW (f))
1238 x_set_window_size (f, 0, FRAME_WIDTH (f), FRAME_HEIGHT (f));
1242 /* Subroutines of creating an X frame. */
1244 #ifdef HAVE_X11
1246 /* Make sure that Vx_resource_name is set to a reasonable value. */
1247 static void
1248 validate_x_resource_name ()
1250 if (! STRINGP (Vx_resource_name))
1251 Vx_resource_name = make_string ("emacs", 5);
1255 extern char *x_get_string_resource ();
1256 extern XrmDatabase x_load_resources ();
1258 DEFUN ("x-get-resource", Fx_get_resource, Sx_get_resource, 2, 4, 0,
1259 "Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.\n\
1260 This uses `NAME.ATTRIBUTE' as the key and `Emacs.CLASS' as the\n\
1261 class, where INSTANCE is the name under which Emacs was invoked, or\n\
1262 the name specified by the `-name' or `-rn' command-line arguments.\n\
1264 The optional arguments COMPONENT and SUBCLASS add to the key and the\n\
1265 class, respectively. You must specify both of them or neither.\n\
1266 If you specify them, the key is `NAME.COMPONENT.ATTRIBUTE'\n\
1267 and the class is `Emacs.CLASS.SUBCLASS'.")
1268 (attribute, class, component, subclass)
1269 Lisp_Object attribute, class, component, subclass;
1271 register char *value;
1272 char *name_key;
1273 char *class_key;
1274 Lisp_Object resname;
1276 check_x ();
1278 CHECK_STRING (attribute, 0);
1279 CHECK_STRING (class, 0);
1281 if (!NILP (component))
1282 CHECK_STRING (component, 1);
1283 if (!NILP (subclass))
1284 CHECK_STRING (subclass, 2);
1285 if (NILP (component) != NILP (subclass))
1286 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
1288 validate_x_resource_name ();
1289 resname = Vx_resource_name;
1291 if (NILP (component))
1293 /* Allocate space for the components, the dots which separate them,
1294 and the final '\0'. */
1295 name_key = (char *) alloca (XSTRING (resname)->size
1296 + XSTRING (attribute)->size
1297 + 2);
1298 class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
1299 + XSTRING (class)->size
1300 + 2);
1302 sprintf (name_key, "%s.%s",
1303 XSTRING (resname)->data,
1304 XSTRING (attribute)->data);
1305 sprintf (class_key, "%s.%s",
1306 EMACS_CLASS,
1307 XSTRING (class)->data);
1309 else
1311 name_key = (char *) alloca (XSTRING (resname)->size
1312 + XSTRING (component)->size
1313 + XSTRING (attribute)->size
1314 + 3);
1316 class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
1317 + XSTRING (class)->size
1318 + XSTRING (subclass)->size
1319 + 3);
1321 sprintf (name_key, "%s.%s.%s",
1322 XSTRING (resname)->data,
1323 XSTRING (component)->data,
1324 XSTRING (attribute)->data);
1325 sprintf (class_key, "%s.%s.%s",
1326 EMACS_CLASS,
1327 XSTRING (class)->data,
1328 XSTRING (subclass)->data);
1331 value = x_get_string_resource (xrdb, name_key, class_key);
1333 if (value != (char *) 0)
1334 return build_string (value);
1335 else
1336 return Qnil;
1339 /* Used when C code wants a resource value. */
1341 char *
1342 x_get_resource_string (attribute, class)
1343 char *attribute, *class;
1345 register char *value;
1346 char *name_key;
1347 char *class_key;
1349 /* Allocate space for the components, the dots which separate them,
1350 and the final '\0'. */
1351 name_key = (char *) alloca (XSTRING (Vinvocation_name)->size
1352 + strlen (attribute) + 2);
1353 class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
1354 + strlen (class) + 2);
1356 sprintf (name_key, "%s.%s",
1357 XSTRING (Vinvocation_name)->data,
1358 attribute);
1359 sprintf (class_key, "%s.%s", EMACS_CLASS, class);
1361 return x_get_string_resource (xrdb, name_key, class_key);
1364 #else /* X10 */
1366 DEFUN ("x-get-default", Fx_get_default, Sx_get_default, 1, 1, 0,
1367 "Get X default ATTRIBUTE from the system, or nil if no default.\n\
1368 Value is a string (when not nil) and ATTRIBUTE is also a string.\n\
1369 The defaults are specified in the file `~/.Xdefaults'.")
1370 (arg)
1371 Lisp_Object arg;
1373 register unsigned char *value;
1375 CHECK_STRING (arg, 1);
1377 value = (unsigned char *) XGetDefault (XDISPLAY
1378 XSTRING (Vinvocation_name)->data,
1379 XSTRING (arg)->data);
1380 if (value == 0)
1381 /* Try reversing last two args, in case this is the buggy version of X. */
1382 value = (unsigned char *) XGetDefault (XDISPLAY
1383 XSTRING (arg)->data,
1384 XSTRING (Vinvocation_name)->data);
1385 if (value != 0)
1386 return build_string (value);
1387 else
1388 return (Qnil);
1391 #define Fx_get_resource(attribute, class, component, subclass) \
1392 Fx_get_default (attribute)
1394 #endif /* X10 */
1396 /* Types we might convert a resource string into. */
1397 enum resource_types
1399 number, boolean, string, symbol
1402 /* Return the value of parameter PARAM.
1404 First search ALIST, then Vdefault_frame_alist, then the X defaults
1405 database, using ATTRIBUTE as the attribute name and CLASS as its class.
1407 Convert the resource to the type specified by desired_type.
1409 If no default is specified, return Qunbound. If you call
1410 x_get_arg, make sure you deal with Qunbound in a reasonable way,
1411 and don't let it get stored in any lisp-visible variables! */
1413 static Lisp_Object
1414 x_get_arg (alist, param, attribute, class, type)
1415 Lisp_Object alist, param;
1416 char *attribute;
1417 char *class;
1418 enum resource_types type;
1420 register Lisp_Object tem;
1422 tem = Fassq (param, alist);
1423 if (EQ (tem, Qnil))
1424 tem = Fassq (param, Vdefault_frame_alist);
1425 if (EQ (tem, Qnil))
1428 if (attribute)
1430 tem = Fx_get_resource (build_string (attribute),
1431 build_string (class),
1432 Qnil, Qnil);
1434 if (NILP (tem))
1435 return Qunbound;
1437 switch (type)
1439 case number:
1440 return make_number (atoi (XSTRING (tem)->data));
1442 case boolean:
1443 tem = Fdowncase (tem);
1444 if (!strcmp (XSTRING (tem)->data, "on")
1445 || !strcmp (XSTRING (tem)->data, "true"))
1446 return Qt;
1447 else
1448 return Qnil;
1450 case string:
1451 return tem;
1453 case symbol:
1454 /* As a special case, we map the values `true' and `on'
1455 to Qt, and `false' and `off' to Qnil. */
1457 Lisp_Object lower;
1458 lower = Fdowncase (tem);
1459 if (!strcmp (XSTRING (lower)->data, "on")
1460 || !strcmp (XSTRING (lower)->data, "true"))
1461 return Qt;
1462 else if (!strcmp (XSTRING (lower)->data, "off")
1463 || !strcmp (XSTRING (lower)->data, "false"))
1464 return Qnil;
1465 else
1466 return Fintern (tem, Qnil);
1469 default:
1470 abort ();
1473 else
1474 return Qunbound;
1476 return Fcdr (tem);
1479 /* Record in frame F the specified or default value according to ALIST
1480 of the parameter named PARAM (a Lisp symbol).
1481 If no value is specified for PARAM, look for an X default for XPROP
1482 on the frame named NAME.
1483 If that is not found either, use the value DEFLT. */
1485 static Lisp_Object
1486 x_default_parameter (f, alist, prop, deflt, xprop, xclass, type)
1487 struct frame *f;
1488 Lisp_Object alist;
1489 Lisp_Object prop;
1490 Lisp_Object deflt;
1491 char *xprop;
1492 char *xclass;
1493 enum resource_types type;
1495 Lisp_Object tem;
1497 tem = x_get_arg (alist, prop, xprop, xclass, type);
1498 if (EQ (tem, Qunbound))
1499 tem = deflt;
1500 x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));
1501 return tem;
1504 DEFUN ("x-parse-geometry", Fx_parse_geometry, Sx_parse_geometry, 1, 1, 0,
1505 "Parse an X-style geometry string STRING.\n\
1506 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).")
1507 (string)
1508 Lisp_Object string;
1510 int geometry, x, y;
1511 unsigned int width, height;
1512 Lisp_Object values[4];
1514 CHECK_STRING (string, 0);
1516 geometry = XParseGeometry ((char *) XSTRING (string)->data,
1517 &x, &y, &width, &height);
1519 switch (geometry & 0xf) /* Mask out {X,Y}Negative */
1521 case (XValue | YValue):
1522 /* What's one pixel among friends?
1523 Perhaps fix this some day by returning symbol `extreme-top'... */
1524 if (x == 0 && (geometry & XNegative))
1525 x = -1;
1526 if (y == 0 && (geometry & YNegative))
1527 y = -1;
1528 values[0] = Fcons (Qleft, make_number (x));
1529 values[1] = Fcons (Qtop, make_number (y));
1530 return Flist (2, values);
1531 break;
1533 case (WidthValue | HeightValue):
1534 values[0] = Fcons (Qwidth, make_number (width));
1535 values[1] = Fcons (Qheight, make_number (height));
1536 return Flist (2, values);
1537 break;
1539 case (XValue | YValue | WidthValue | HeightValue):
1540 if (x == 0 && (geometry & XNegative))
1541 x = -1;
1542 if (y == 0 && (geometry & YNegative))
1543 y = -1;
1544 values[0] = Fcons (Qwidth, make_number (width));
1545 values[1] = Fcons (Qheight, make_number (height));
1546 values[2] = Fcons (Qleft, make_number (x));
1547 values[3] = Fcons (Qtop, make_number (y));
1548 return Flist (4, values);
1549 break;
1551 case 0:
1552 return Qnil;
1554 default:
1555 error ("Must specify x and y value, and/or width and height");
1559 #ifdef HAVE_X11
1560 /* Calculate the desired size and position of this window,
1561 and return the attributes saying which aspects were specified.
1563 This function does not make the coordinates positive. */
1565 #define DEFAULT_ROWS 40
1566 #define DEFAULT_COLS 80
1568 static int
1569 x_figure_window_size (f, parms)
1570 struct frame *f;
1571 Lisp_Object parms;
1573 register Lisp_Object tem0, tem1;
1574 int height, width, left, top;
1575 register int geometry;
1576 long window_prompting = 0;
1578 /* Default values if we fall through.
1579 Actually, if that happens we should get
1580 window manager prompting. */
1581 f->width = DEFAULT_COLS;
1582 f->height = DEFAULT_ROWS;
1583 /* Window managers expect that if program-specified
1584 positions are not (0,0), they're intentional, not defaults. */
1585 f->display.x->top_pos = 0;
1586 f->display.x->left_pos = 0;
1588 tem0 = x_get_arg (parms, Qheight, 0, 0, number);
1589 tem1 = x_get_arg (parms, Qwidth, 0, 0, number);
1590 if (! EQ (tem0, Qunbound) && ! EQ (tem1, Qunbound))
1592 CHECK_NUMBER (tem0, 0);
1593 CHECK_NUMBER (tem1, 0);
1594 f->height = XINT (tem0);
1595 f->width = XINT (tem1);
1596 window_prompting |= USSize;
1598 else if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
1599 error ("Must specify *both* height and width");
1601 f->display.x->vertical_scroll_bar_extra
1602 = (FRAME_HAS_VERTICAL_SCROLL_BARS (f)
1603 ? VERTICAL_SCROLL_BAR_PIXEL_WIDTH (f)
1604 : 0);
1605 f->display.x->pixel_width = CHAR_TO_PIXEL_WIDTH (f, f->width);
1606 f->display.x->pixel_height = CHAR_TO_PIXEL_HEIGHT (f, f->height);
1608 tem0 = x_get_arg (parms, Qtop, 0, 0, number);
1609 tem1 = x_get_arg (parms, Qleft, 0, 0, number);
1610 if (! EQ (tem0, Qunbound) && ! EQ (tem1, Qunbound))
1612 CHECK_NUMBER (tem0, 0);
1613 CHECK_NUMBER (tem1, 0);
1614 f->display.x->top_pos = XINT (tem0);
1615 f->display.x->left_pos = XINT (tem1);
1616 if (f->display.x->top_pos < 0)
1617 window_prompting |= YNegative;
1618 if (f->display.x->left_pos < 0)
1619 window_prompting |= YNegative;
1620 window_prompting |= USPosition;
1622 else if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
1623 error ("Must specify *both* top and left corners");
1625 #if 0 /* PPosition and PSize mean "specified explicitly,
1626 by the program rather than by the user". So it is wrong to
1627 set them if nothing was specified. */
1628 switch (window_prompting)
1630 case USSize | USPosition:
1631 return window_prompting;
1632 break;
1634 case USSize: /* Got the size, need the position. */
1635 window_prompting |= PPosition;
1636 return window_prompting;
1637 break;
1639 case USPosition: /* Got the position, need the size. */
1640 window_prompting |= PSize;
1641 return window_prompting;
1642 break;
1644 case 0: /* Got nothing, take both from geometry. */
1645 window_prompting |= PPosition | PSize;
1646 return window_prompting;
1647 break;
1649 default:
1650 /* Somehow a bit got set in window_prompting that we didn't
1651 put there. */
1652 abort ();
1654 #endif
1655 return window_prompting;
1658 #if !defined (HAVE_X11R4) && !defined (HAVE_XSETWMPROTOCOLS)
1660 Status
1661 XSetWMProtocols (dpy, w, protocols, count)
1662 Display *dpy;
1663 Window w;
1664 Atom *protocols;
1665 int count;
1667 Atom prop;
1668 prop = XInternAtom (dpy, "WM_PROTOCOLS", False);
1669 if (prop == None) return False;
1670 XChangeProperty (dpy, w, prop, XA_ATOM, 32, PropModeReplace,
1671 (unsigned char *) protocols, count);
1672 return True;
1674 #endif /* not HAVE_X11R4 && not HAVE_XSETWMPROTOCOLS */
1676 #ifdef USE_X_TOOLKIT
1678 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS
1679 and WM_DELETE_WINDOW, then add them. (They may already be present
1680 because of the toolkit (Motif adds them, for example, but Xt doesn't). */
1682 static void
1683 hack_wm_protocols (widget)
1684 Widget widget;
1686 Display *dpy = XtDisplay (widget);
1687 Window w = XtWindow (widget);
1688 int need_delete = 1;
1689 int need_focus = 1;
1691 BLOCK_INPUT;
1693 Atom type, *atoms = 0;
1694 int format = 0;
1695 unsigned long nitems = 0;
1696 unsigned long bytes_after;
1698 if (Success == XGetWindowProperty (dpy, w, Xatom_wm_protocols,
1699 0, 100, False, XA_ATOM,
1700 &type, &format, &nitems, &bytes_after,
1701 (unsigned char **) &atoms)
1702 && format == 32 && type == XA_ATOM)
1703 while (nitems > 0)
1705 nitems--;
1706 if (atoms [nitems] == Xatom_wm_delete_window) need_delete = 0;
1707 else if (atoms [nitems] == Xatom_wm_take_focus) need_focus = 0;
1709 if (atoms) XFree ((char *) atoms);
1712 Atom props [10];
1713 int count = 0;
1714 if (need_delete) props [count++] = Xatom_wm_delete_window;
1715 if (need_focus) props [count++] = Xatom_wm_take_focus;
1716 if (count)
1717 XChangeProperty (dpy, w, Xatom_wm_protocols, XA_ATOM, 32, PropModeAppend,
1718 (unsigned char *) props, count);
1720 UNBLOCK_INPUT;
1722 #endif
1724 #ifdef USE_X_TOOLKIT
1726 /* Create and set up the X widget for frame F. */
1728 static void
1729 x_window (f, window_prompting, minibuffer_only)
1730 struct frame *f;
1731 long window_prompting;
1732 int minibuffer_only;
1734 XClassHint class_hints;
1735 XSetWindowAttributes attributes;
1736 unsigned long attribute_mask;
1738 Widget shell_widget;
1739 Widget pane_widget;
1740 Widget screen_widget;
1741 char* name;
1742 Arg al [25];
1743 int ac;
1745 BLOCK_INPUT;
1747 if (STRINGP (f->name))
1748 name = (char*) XSTRING (f->name)->data;
1749 else
1750 name = "emacs";
1752 ac = 0;
1753 XtSetArg (al[ac], XtNallowShellResize, 1); ac++;
1754 XtSetArg (al[ac], XtNinput, 1); ac++;
1755 shell_widget = XtCreatePopupShell ("shell",
1756 topLevelShellWidgetClass,
1757 Xt_app_shell, al, ac);
1759 f->display.x->widget = shell_widget;
1760 /* maybe_set_screen_title_format (shell_widget); */
1763 ac = 0;
1764 XtSetArg (al[ac], XtNborderWidth, 0); ac++;
1765 pane_widget = XtCreateWidget ("pane",
1766 panedWidgetClass,
1767 shell_widget, al, ac);
1769 f->display.x->column_widget = pane_widget;
1771 if (!minibuffer_only && FRAME_MENU_BAR_LINES (f) > 0)
1772 initialize_frame_menubar (f);
1774 /* mappedWhenManaged to false tells to the paned window to not map/unmap
1775 * the emacs screen when changing menubar. This reduces flickering a lot.
1778 ac = 0;
1779 XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
1780 XtSetArg (al[ac], XtNshowGrip, 0); ac++;
1781 XtSetArg (al[ac], XtNallowResize, 1); ac++;
1782 XtSetArg (al[ac], XtNresizeToPreferred, 1); ac++;
1783 XtSetArg (al[ac], XtNemacsFrame, f); ac++;
1784 screen_widget = XtCreateWidget (name,
1785 emacsFrameClass,
1786 pane_widget, al, ac);
1788 f->display.x->edit_widget = screen_widget;
1790 if (f->display.x->menubar_widget)
1791 XtManageChild (f->display.x->menubar_widget);
1792 XtManageChild (screen_widget);
1794 /* Do some needed geometry management. */
1796 int len;
1797 char *tem, shell_position[32];
1798 Arg al[2];
1799 int ac = 0;
1800 int menubar_size
1801 = (f->display.x->menubar_widget
1802 ? (f->display.x->menubar_widget->core.height
1803 + f->display.x->menubar_widget->core.border_width)
1804 : 0);
1806 if (window_prompting & USPosition)
1808 int left = f->display.x->left_pos;
1809 int xneg = left < 0;
1810 int top = f->display.x->top_pos;
1811 int yneg = top < 0;
1812 if (left < 0)
1813 left = -left;
1814 if (top < 0)
1815 top = -top;
1816 sprintf (shell_position, "=%dx%d%c%d%c%d", PIXEL_WIDTH (f),
1817 PIXEL_HEIGHT (f) + menubar_size,
1818 (xneg ? '-' : '+'), left,
1819 (yneg ? '-' : '+'), top);
1821 else
1822 sprintf (shell_position, "=%dx%d", PIXEL_WIDTH (f),
1823 PIXEL_HEIGHT (f) + menubar_size);
1824 len = strlen (shell_position) + 1;
1825 tem = (char *) xmalloc (len);
1826 strncpy (tem, shell_position, len);
1827 XtSetArg (al[ac], XtNgeometry, tem); ac++;
1828 XtSetValues (shell_widget, al, ac);
1831 x_calc_absolute_position (f);
1833 XtManageChild (pane_widget);
1834 XtRealizeWidget (shell_widget);
1836 FRAME_X_WINDOW (f) = XtWindow (screen_widget);
1838 validate_x_resource_name ();
1839 class_hints.res_name = (char *) XSTRING (Vx_resource_name)->data;
1840 class_hints.res_class = EMACS_CLASS;
1841 XSetClassHint (x_current_display, XtWindow (shell_widget), &class_hints);
1843 hack_wm_protocols (shell_widget);
1845 /* Do a stupid property change to force the server to generate a
1846 propertyNotify event so that the event_stream server timestamp will
1847 be initialized to something relevant to the time we created the window.
1849 XChangeProperty (XtDisplay (screen_widget), XtWindow (screen_widget),
1850 Xatom_wm_protocols, XA_ATOM, 32, PropModeAppend,
1851 (unsigned char*) NULL, 0);
1853 /* Make all the standard events reach the Emacs frame. */
1854 attributes.event_mask = STANDARD_EVENT_SET;
1855 attribute_mask = CWEventMask;
1856 XChangeWindowAttributes (XtDisplay (shell_widget), XtWindow (shell_widget),
1857 attribute_mask, &attributes);
1859 XtMapWidget (screen_widget);
1861 /* x_set_name normally ignores requests to set the name if the
1862 requested name is the same as the current name. This is the one
1863 place where that assumption isn't correct; f->name is set, but
1864 the X server hasn't been told. */
1866 Lisp_Object name;
1867 int explicit = f->explicit_name;
1869 f->explicit_name = 0;
1870 name = f->name;
1871 f->name = Qnil;
1872 x_set_name (f, name, explicit);
1875 XDefineCursor (XDISPLAY FRAME_X_WINDOW (f),
1876 f->display.x->text_cursor);
1878 UNBLOCK_INPUT;
1880 if (FRAME_X_WINDOW (f) == 0)
1881 error ("Unable to create window");
1884 #else /* not USE_X_TOOLKIT */
1886 /* Create and set up the X window for frame F. */
1888 x_window (f)
1889 struct frame *f;
1892 XClassHint class_hints;
1893 XSetWindowAttributes attributes;
1894 unsigned long attribute_mask;
1896 attributes.background_pixel = f->display.x->background_pixel;
1897 attributes.border_pixel = f->display.x->border_pixel;
1898 attributes.bit_gravity = StaticGravity;
1899 attributes.backing_store = NotUseful;
1900 attributes.save_under = True;
1901 attributes.event_mask = STANDARD_EVENT_SET;
1902 attribute_mask = (CWBackPixel | CWBorderPixel | CWBitGravity
1903 #if 0
1904 | CWBackingStore | CWSaveUnder
1905 #endif
1906 | CWEventMask);
1908 BLOCK_INPUT;
1909 FRAME_X_WINDOW (f)
1910 = XCreateWindow (x_current_display, ROOT_WINDOW,
1911 f->display.x->left_pos,
1912 f->display.x->top_pos,
1913 PIXEL_WIDTH (f), PIXEL_HEIGHT (f),
1914 f->display.x->border_width,
1915 CopyFromParent, /* depth */
1916 InputOutput, /* class */
1917 screen_visual, /* set in Fx_open_connection */
1918 attribute_mask, &attributes);
1920 validate_x_resource_name ();
1921 class_hints.res_name = (char *) XSTRING (Vx_resource_name)->data;
1922 class_hints.res_class = EMACS_CLASS;
1923 XSetClassHint (x_current_display, FRAME_X_WINDOW (f), &class_hints);
1925 /* This indicates that we use the "Passive Input" input model.
1926 Unless we do this, we don't get the Focus{In,Out} events that we
1927 need to draw the cursor correctly. Accursed bureaucrats.
1928 XWhipsAndChains (x_current_display, IronMaiden, &TheRack); */
1930 f->display.x->wm_hints.input = True;
1931 f->display.x->wm_hints.flags |= InputHint;
1932 XSetWMHints (x_current_display, FRAME_X_WINDOW (f), &f->display.x->wm_hints);
1933 XSetWMProtocols (x_current_display, FRAME_X_WINDOW (f),
1934 &Xatom_wm_delete_window, 1);
1937 /* x_set_name normally ignores requests to set the name if the
1938 requested name is the same as the current name. This is the one
1939 place where that assumption isn't correct; f->name is set, but
1940 the X server hasn't been told. */
1942 Lisp_Object name;
1943 int explicit = f->explicit_name;
1945 f->explicit_name = 0;
1946 name = f->name;
1947 f->name = Qnil;
1948 x_set_name (f, name, explicit);
1951 XDefineCursor (XDISPLAY FRAME_X_WINDOW (f),
1952 f->display.x->text_cursor);
1954 UNBLOCK_INPUT;
1956 if (FRAME_X_WINDOW (f) == 0)
1957 error ("Unable to create window");
1960 #endif /* not USE_X_TOOLKIT */
1962 /* Handle the icon stuff for this window. Perhaps later we might
1963 want an x_set_icon_position which can be called interactively as
1964 well. */
1966 static void
1967 x_icon (f, parms)
1968 struct frame *f;
1969 Lisp_Object parms;
1971 Lisp_Object icon_x, icon_y;
1973 /* Set the position of the icon. Note that twm groups all
1974 icons in an icon window. */
1975 icon_x = x_get_arg (parms, Qicon_left, 0, 0, number);
1976 icon_y = x_get_arg (parms, Qicon_top, 0, 0, number);
1977 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
1979 CHECK_NUMBER (icon_x, 0);
1980 CHECK_NUMBER (icon_y, 0);
1982 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
1983 error ("Both left and top icon corners of icon must be specified");
1985 BLOCK_INPUT;
1987 if (! EQ (icon_x, Qunbound))
1988 x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
1990 /* Start up iconic or window? */
1991 x_wm_set_window_state
1992 (f, (EQ (x_get_arg (parms, Qvisibility, 0, 0, symbol), Qicon)
1993 ? IconicState
1994 : NormalState));
1996 UNBLOCK_INPUT;
1999 /* Make the GC's needed for this window, setting the
2000 background, border and mouse colors; also create the
2001 mouse cursor and the gray border tile. */
2003 static char cursor_bits[] =
2005 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2006 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2007 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2008 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2011 static void
2012 x_make_gc (f)
2013 struct frame *f;
2015 XGCValues gc_values;
2016 GC temp_gc;
2017 XImage tileimage;
2019 BLOCK_INPUT;
2021 /* Create the GC's of this frame.
2022 Note that many default values are used. */
2024 /* Normal video */
2025 gc_values.font = f->display.x->font->fid;
2026 gc_values.foreground = f->display.x->foreground_pixel;
2027 gc_values.background = f->display.x->background_pixel;
2028 gc_values.line_width = 0; /* Means 1 using fast algorithm. */
2029 f->display.x->normal_gc = XCreateGC (x_current_display,
2030 FRAME_X_WINDOW (f),
2031 GCLineWidth | GCFont
2032 | GCForeground | GCBackground,
2033 &gc_values);
2035 /* Reverse video style. */
2036 gc_values.foreground = f->display.x->background_pixel;
2037 gc_values.background = f->display.x->foreground_pixel;
2038 f->display.x->reverse_gc = XCreateGC (x_current_display,
2039 FRAME_X_WINDOW (f),
2040 GCFont | GCForeground | GCBackground
2041 | GCLineWidth,
2042 &gc_values);
2044 /* Cursor has cursor-color background, background-color foreground. */
2045 gc_values.foreground = f->display.x->background_pixel;
2046 gc_values.background = f->display.x->cursor_pixel;
2047 gc_values.fill_style = FillOpaqueStippled;
2048 gc_values.stipple
2049 = XCreateBitmapFromData (x_current_display, ROOT_WINDOW,
2050 cursor_bits, 16, 16);
2051 f->display.x->cursor_gc
2052 = XCreateGC (x_current_display, FRAME_X_WINDOW (f),
2053 (GCFont | GCForeground | GCBackground
2054 | GCFillStyle | GCStipple | GCLineWidth),
2055 &gc_values);
2057 /* Create the gray border tile used when the pointer is not in
2058 the frame. Since this depends on the frame's pixel values,
2059 this must be done on a per-frame basis. */
2060 f->display.x->border_tile
2061 = (XCreatePixmapFromBitmapData
2062 (x_current_display, ROOT_WINDOW,
2063 gray_bits, gray_width, gray_height,
2064 f->display.x->foreground_pixel,
2065 f->display.x->background_pixel,
2066 DefaultDepth (x_current_display, XDefaultScreen (x_current_display))));
2068 UNBLOCK_INPUT;
2070 #endif /* HAVE_X11 */
2072 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
2073 1, 1, 0,
2074 "Make a new X window, which is called a \"frame\" in Emacs terms.\n\
2075 Return an Emacs frame object representing the X window.\n\
2076 ALIST is an alist of frame parameters.\n\
2077 If the parameters specify that the frame should not have a minibuffer,\n\
2078 and do not specify a specific minibuffer window to use,\n\
2079 then `default-minibuffer-frame' must be a frame whose minibuffer can\n\
2080 be shared by the new frame.")
2081 (parms)
2082 Lisp_Object parms;
2084 #ifdef HAVE_X11
2085 struct frame *f;
2086 Lisp_Object frame, tem;
2087 Lisp_Object name;
2088 int minibuffer_only = 0;
2089 long window_prompting = 0;
2090 int width, height;
2091 int count = specpdl_ptr - specpdl;
2093 check_x ();
2095 name = x_get_arg (parms, Qname, "title", "Title", string);
2096 if (XTYPE (name) != Lisp_String
2097 && ! EQ (name, Qunbound)
2098 && ! NILP (name))
2099 error ("x-create-frame: name parameter must be a string");
2101 tem = x_get_arg (parms, Qminibuffer, 0, 0, symbol);
2102 if (EQ (tem, Qnone) || NILP (tem))
2103 f = make_frame_without_minibuffer (Qnil);
2104 else if (EQ (tem, Qonly))
2106 f = make_minibuffer_frame ();
2107 minibuffer_only = 1;
2109 else if (XTYPE (tem) == Lisp_Window)
2110 f = make_frame_without_minibuffer (tem);
2111 else
2112 f = make_frame (1);
2114 /* Note that X Windows does support scroll bars. */
2115 FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
2117 /* Set the name; the functions to which we pass f expect the name to
2118 be set. */
2119 if (EQ (name, Qunbound) || NILP (name))
2121 f->name = build_string (x_id_name);
2122 f->explicit_name = 0;
2124 else
2126 f->name = name;
2127 f->explicit_name = 1;
2128 /* use the frame's title when getting resources for this frame. */
2129 specbind (Qx_resource_name, name);
2132 XSET (frame, Lisp_Frame, f);
2133 f->output_method = output_x_window;
2134 f->display.x = (struct x_display *) xmalloc (sizeof (struct x_display));
2135 bzero (f->display.x, sizeof (struct x_display));
2137 /* Note that the frame has no physical cursor right now. */
2138 f->phys_cursor_x = -1;
2140 /* Extract the window parameters from the supplied values
2141 that are needed to determine window geometry. */
2143 Lisp_Object font;
2145 font = x_get_arg (parms, Qfont, "font", "Font", string);
2146 BLOCK_INPUT;
2147 /* First, try whatever font the caller has specified. */
2148 if (STRINGP (font))
2149 font = x_new_font (f, XSTRING (font)->data);
2150 /* Try out a font which we hope has bold and italic variations. */
2151 if (!STRINGP (font))
2152 font = x_new_font (f, "-misc-fixed-medium-r-normal-*-*-120-*-*-c-*-iso8859-1");
2153 if (! STRINGP (font))
2154 font = x_new_font (f, "-*-*-medium-r-normal-*-*-120-*-*-c-*-iso8859-1");
2155 if (! STRINGP (font))
2156 /* This was formerly the first thing tried, but it finds too many fonts
2157 and takes too long. */
2158 font = x_new_font (f, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
2159 /* If those didn't work, look for something which will at least work. */
2160 if (! STRINGP (font))
2161 font = x_new_font (f, "-*-fixed-*-*-*-*-*-120-*-*-c-*-iso8859-1");
2162 UNBLOCK_INPUT;
2163 if (! STRINGP (font))
2164 font = build_string ("fixed");
2166 x_default_parameter (f, parms, Qfont, font,
2167 "font", "Font", string);
2170 x_default_parameter (f, parms, Qborder_width, make_number (2),
2171 "borderwidth", "BorderWidth", number);
2172 /* This defaults to 2 in order to match xterm. We recognize either
2173 internalBorderWidth or internalBorder (which is what xterm calls
2174 it). */
2175 if (NILP (Fassq (Qinternal_border_width, parms)))
2177 Lisp_Object value;
2179 value = x_get_arg (parms, Qinternal_border_width,
2180 "internalBorder", "BorderWidth", number);
2181 if (! EQ (value, Qunbound))
2182 parms = Fcons (Fcons (Qinternal_border_width, value),
2183 parms);
2185 x_default_parameter (f, parms, Qinternal_border_width, make_number (2),
2186 "internalBorderWidth", "BorderWidth", number);
2187 x_default_parameter (f, parms, Qvertical_scroll_bars, Qt,
2188 "verticalScrollBars", "ScrollBars", boolean);
2190 /* Also do the stuff which must be set before the window exists. */
2191 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
2192 "foreground", "Foreground", string);
2193 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
2194 "background", "Background", string);
2195 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
2196 "pointerColor", "Foreground", string);
2197 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
2198 "cursorColor", "Foreground", string);
2199 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
2200 "borderColor", "BorderColor", string);
2202 x_default_parameter (f, parms, Qmenu_bar_lines, make_number (0),
2203 "menuBarLines", "MenuBarLines", number);
2205 f->display.x->parent_desc = ROOT_WINDOW;
2206 window_prompting = x_figure_window_size (f, parms);
2208 switch (((f->display.x->left_pos < 0) << 1) + (f->display.x->top_pos < 0))
2210 case 0:
2211 f->display.x->win_gravity = NorthWestGravity;
2212 break;
2213 case 1:
2214 f->display.x->win_gravity = SouthWestGravity;
2215 break;
2216 case 2:
2217 f->display.x->win_gravity = NorthEastGravity;
2218 break;
2219 case 3:
2220 f->display.x->win_gravity = SouthEastGravity;
2221 break;
2224 #ifdef USE_X_TOOLKIT
2225 x_window (f, window_prompting, minibuffer_only);
2226 #else
2227 x_window (f);
2228 #endif
2229 x_icon (f, parms);
2230 x_make_gc (f);
2231 init_frame_faces (f);
2233 /* We need to do this after creating the X window, so that the
2234 icon-creation functions can say whose icon they're describing. */
2235 x_default_parameter (f, parms, Qicon_type, Qnil,
2236 "bitmapIcon", "BitmapIcon", symbol);
2238 x_default_parameter (f, parms, Qauto_raise, Qnil,
2239 "autoRaise", "AutoRaiseLower", boolean);
2240 x_default_parameter (f, parms, Qauto_lower, Qnil,
2241 "autoLower", "AutoRaiseLower", boolean);
2242 x_default_parameter (f, parms, Qcursor_type, Qbox,
2243 "cursorType", "CursorType", symbol);
2245 /* Dimensions, especially f->height, must be done via change_frame_size.
2246 Change will not be effected unless different from the current
2247 f->height. */
2248 width = f->width;
2249 height = f->height;
2250 f->height = f->width = 0;
2251 change_frame_size (f, height, width, 1, 0);
2253 /* With the toolkit, the geometry management is done in x_window. */
2254 #ifndef USE_X_TOOLKIT
2255 BLOCK_INPUT;
2256 x_wm_set_size_hint (f, window_prompting, 1);
2257 UNBLOCK_INPUT;
2258 #endif /* USE_X_TOOLKIT */
2260 tem = x_get_arg (parms, Qunsplittable, 0, 0, boolean);
2261 f->no_split = minibuffer_only || EQ (tem, Qt);
2263 /* It is now ok to make the frame official
2264 even if we get an error below.
2265 And the frame needs to be on Vframe_list
2266 or making it visible won't work. */
2267 Vframe_list = Fcons (frame, Vframe_list);
2269 /* Make the window appear on the frame and enable display,
2270 unless the caller says not to. */
2272 Lisp_Object visibility;
2274 visibility = x_get_arg (parms, Qvisibility, 0, 0, symbol);
2275 if (EQ (visibility, Qunbound))
2276 visibility = Qt;
2278 if (EQ (visibility, Qicon))
2279 x_iconify_frame (f);
2280 else if (! NILP (visibility))
2281 x_make_frame_visible (f);
2282 else
2283 /* Must have been Qnil. */
2287 return unbind_to (count, frame);
2288 #else /* X10 */
2289 struct frame *f;
2290 Lisp_Object frame, tem;
2291 Lisp_Object name;
2292 int pixelwidth, pixelheight;
2293 Cursor cursor;
2294 int height, width;
2295 Window parent;
2296 Pixmap temp;
2297 int minibuffer_only = 0;
2298 Lisp_Object vscroll, hscroll;
2300 if (x_current_display == 0)
2301 error ("X windows are not in use or not initialized");
2303 name = Fassq (Qname, parms);
2305 tem = x_get_arg (parms, Qminibuffer, 0, 0, symbol);
2306 if (EQ (tem, Qnone))
2307 f = make_frame_without_minibuffer (Qnil);
2308 else if (EQ (tem, Qonly))
2310 f = make_minibuffer_frame ();
2311 minibuffer_only = 1;
2313 else if (EQ (tem, Qnil) || EQ (tem, Qunbound))
2314 f = make_frame (1);
2315 else
2316 f = make_frame_without_minibuffer (tem);
2318 parent = ROOT_WINDOW;
2320 XSET (frame, Lisp_Frame, f);
2321 f->output_method = output_x_window;
2322 f->display.x = (struct x_display *) xmalloc (sizeof (struct x_display));
2323 bzero (f->display.x, sizeof (struct x_display));
2325 /* Some temporary default values for height and width. */
2326 width = 80;
2327 height = 40;
2328 f->display.x->left_pos = -1;
2329 f->display.x->top_pos = -1;
2331 /* Give the frame a default name (which may be overridden with PARMS). */
2333 strncpy (iconidentity, ICONTAG, MAXICID);
2334 if (gethostname (&iconidentity[sizeof (ICONTAG) - 1],
2335 (MAXICID - 1) - sizeof (ICONTAG)))
2336 iconidentity[sizeof (ICONTAG) - 2] = '\0';
2337 f->name = build_string (iconidentity);
2339 /* Extract some window parameters from the supplied values.
2340 These are the parameters that affect window geometry. */
2342 tem = x_get_arg (parms, Qfont, "BodyFont", 0, string);
2343 if (EQ (tem, Qunbound))
2344 tem = build_string ("9x15");
2345 x_set_font (f, tem, Qnil);
2346 x_default_parameter (f, parms, Qborder_color,
2347 build_string ("black"), "Border", 0, string);
2348 x_default_parameter (f, parms, Qbackground_color,
2349 build_string ("white"), "Background", 0, string);
2350 x_default_parameter (f, parms, Qforeground_color,
2351 build_string ("black"), "Foreground", 0, string);
2352 x_default_parameter (f, parms, Qmouse_color,
2353 build_string ("black"), "Mouse", 0, string);
2354 x_default_parameter (f, parms, Qcursor_color,
2355 build_string ("black"), "Cursor", 0, string);
2356 x_default_parameter (f, parms, Qborder_width,
2357 make_number (2), "BorderWidth", 0, number);
2358 x_default_parameter (f, parms, Qinternal_border_width,
2359 make_number (4), "InternalBorderWidth", 0, number);
2360 x_default_parameter (f, parms, Qauto_raise,
2361 Qnil, "AutoRaise", 0, boolean);
2363 hscroll = EQ (x_get_arg (parms, Qhorizontal_scroll_bar, 0, 0, boolean), Qt);
2364 vscroll = EQ (x_get_arg (parms, Qvertical_scroll_bar, 0, 0, boolean), Qt);
2366 if (f->display.x->internal_border_width < 0)
2367 f->display.x->internal_border_width = 0;
2369 tem = x_get_arg (parms, Qwindow_id, 0, 0, number);
2370 if (!EQ (tem, Qunbound))
2372 WINDOWINFO_TYPE wininfo;
2373 int nchildren;
2374 Window *children, root;
2376 CHECK_NUMBER (tem, 0);
2377 FRAME_X_WINDOW (f) = (Window) XINT (tem);
2379 BLOCK_INPUT;
2380 XGetWindowInfo (FRAME_X_WINDOW (f), &wininfo);
2381 XQueryTree (FRAME_X_WINDOW (f), &parent, &nchildren, &children);
2382 xfree (children);
2383 UNBLOCK_INPUT;
2385 height = PIXEL_TO_CHAR_HEIGHT (f, wininfo.height);
2386 width = PIXEL_TO_CHAR_WIDTH (f, wininfo.width);
2387 f->display.x->left_pos = wininfo.x;
2388 f->display.x->top_pos = wininfo.y;
2389 FRAME_SET_VISIBILITY (f, wininfo.mapped != 0);
2390 f->display.x->border_width = wininfo.bdrwidth;
2391 f->display.x->parent_desc = parent;
2393 else
2395 tem = x_get_arg (parms, Qparent_id, 0, 0, number);
2396 if (!EQ (tem, Qunbound))
2398 CHECK_NUMBER (tem, 0);
2399 parent = (Window) XINT (tem);
2401 f->display.x->parent_desc = parent;
2402 tem = x_get_arg (parms, Qheight, 0, 0, number);
2403 if (EQ (tem, Qunbound))
2405 tem = x_get_arg (parms, Qwidth, 0, 0, number);
2406 if (EQ (tem, Qunbound))
2408 tem = x_get_arg (parms, Qtop, 0, 0, number);
2409 if (EQ (tem, Qunbound))
2410 tem = x_get_arg (parms, Qleft, 0, 0, number);
2413 /* Now TEM is Qunbound if no edge or size was specified.
2414 In that case, we must do rubber-banding. */
2415 if (EQ (tem, Qunbound))
2417 tem = x_get_arg (parms, Qgeometry, 0, 0, number);
2418 x_rubber_band (f,
2419 &f->display.x->left_pos, &f->display.x->top_pos,
2420 &width, &height,
2421 (XTYPE (tem) == Lisp_String
2422 ? (char *) XSTRING (tem)->data : ""),
2423 XSTRING (f->name)->data,
2424 !NILP (hscroll), !NILP (vscroll));
2426 else
2428 /* Here if at least one edge or size was specified.
2429 Demand that they all were specified, and use them. */
2430 tem = x_get_arg (parms, Qheight, 0, 0, number);
2431 if (EQ (tem, Qunbound))
2432 error ("Height not specified");
2433 CHECK_NUMBER (tem, 0);
2434 height = XINT (tem);
2436 tem = x_get_arg (parms, Qwidth, 0, 0, number);
2437 if (EQ (tem, Qunbound))
2438 error ("Width not specified");
2439 CHECK_NUMBER (tem, 0);
2440 width = XINT (tem);
2442 tem = x_get_arg (parms, Qtop, 0, 0, number);
2443 if (EQ (tem, Qunbound))
2444 error ("Top position not specified");
2445 CHECK_NUMBER (tem, 0);
2446 f->display.x->left_pos = XINT (tem);
2448 tem = x_get_arg (parms, Qleft, 0, 0, number);
2449 if (EQ (tem, Qunbound))
2450 error ("Left position not specified");
2451 CHECK_NUMBER (tem, 0);
2452 f->display.x->top_pos = XINT (tem);
2455 pixelwidth = CHAR_TO_PIXEL_WIDTH (f, width);
2456 pixelheight = CHAR_TO_PIXEL_HEIGHT (f, height);
2458 BLOCK_INPUT;
2459 FRAME_X_WINDOW (f)
2460 = XCreateWindow (parent,
2461 f->display.x->left_pos, /* Absolute horizontal offset */
2462 f->display.x->top_pos, /* Absolute Vertical offset */
2463 pixelwidth, pixelheight,
2464 f->display.x->border_width,
2465 BLACK_PIX_DEFAULT, WHITE_PIX_DEFAULT);
2466 UNBLOCK_INPUT;
2467 if (FRAME_X_WINDOW (f) == 0)
2468 error ("Unable to create window.");
2471 /* Install the now determined height and width
2472 in the windows and in phys_lines and desired_lines. */
2473 change_frame_size (f, height, width, 1, 0);
2474 XSelectInput (FRAME_X_WINDOW (f), KeyPressed | ExposeWindow
2475 | ButtonPressed | ButtonReleased | ExposeRegion | ExposeCopy
2476 | EnterWindow | LeaveWindow | UnmapWindow );
2477 x_set_resize_hint (f);
2479 /* Tell the server the window's default name. */
2480 XStoreName (XDISPLAY FRAME_X_WINDOW (f), XSTRING (f->name)->data);
2482 /* Now override the defaults with all the rest of the specified
2483 parms. */
2484 tem = x_get_arg (parms, Qunsplittable, 0, 0, boolean);
2485 f->no_split = minibuffer_only || EQ (tem, Qt);
2487 /* Do not create an icon window if the caller says not to */
2488 if (!EQ (x_get_arg (parms, Qsuppress_icon, 0, 0, boolean), Qt)
2489 || f->display.x->parent_desc != ROOT_WINDOW)
2491 x_text_icon (f, iconidentity);
2492 x_default_parameter (f, parms, Qicon_type, Qnil,
2493 "BitmapIcon", 0, symbol);
2496 /* Tell the X server the previously set values of the
2497 background, border and mouse colors; also create the mouse cursor. */
2498 BLOCK_INPUT;
2499 temp = XMakeTile (f->display.x->background_pixel);
2500 XChangeBackground (FRAME_X_WINDOW (f), temp);
2501 XFreePixmap (temp);
2502 UNBLOCK_INPUT;
2503 x_set_border_pixel (f, f->display.x->border_pixel);
2505 x_set_mouse_color (f, Qnil, Qnil);
2507 /* Now override the defaults with all the rest of the specified parms. */
2509 Fmodify_frame_parameters (frame, parms);
2511 /* Make the window appear on the frame and enable display. */
2513 Lisp_Object visibility;
2515 visibility = x_get_arg (parms, Qvisibility, 0, 0, symbol);
2516 if (EQ (visibility, Qunbound))
2517 visibility = Qt;
2519 if (! EQ (visibility, Qicon)
2520 && ! NILP (visibility))
2521 x_make_window_visible (f);
2524 SET_FRAME_GARBAGED (f);
2526 Vframe_list = Fcons (frame, Vframe_list);
2527 return frame;
2528 #endif /* X10 */
2531 Lisp_Object
2532 x_get_focus_frame ()
2534 Lisp_Object xfocus;
2535 if (! x_focus_frame)
2536 return Qnil;
2538 XSET (xfocus, Lisp_Frame, x_focus_frame);
2539 return xfocus;
2542 DEFUN ("focus-frame", Ffocus_frame, Sfocus_frame, 1, 1, 0,
2543 "Set the focus on FRAME.")
2544 (frame)
2545 Lisp_Object frame;
2547 CHECK_LIVE_FRAME (frame, 0);
2549 if (FRAME_X_P (XFRAME (frame)))
2551 BLOCK_INPUT;
2552 x_focus_on_frame (XFRAME (frame));
2553 UNBLOCK_INPUT;
2554 return frame;
2557 return Qnil;
2560 DEFUN ("unfocus-frame", Funfocus_frame, Sunfocus_frame, 0, 0, 0,
2561 "If a frame has been focused, release it.")
2564 if (x_focus_frame)
2566 BLOCK_INPUT;
2567 x_unfocus_frame (x_focus_frame);
2568 UNBLOCK_INPUT;
2571 return Qnil;
2574 #ifndef HAVE_X11
2575 /* Computes an X-window size and position either from geometry GEO
2576 or with the mouse.
2578 F is a frame. It specifies an X window which is used to
2579 determine which display to compute for. Its font, borders
2580 and colors control how the rectangle will be displayed.
2582 X and Y are where to store the positions chosen.
2583 WIDTH and HEIGHT are where to store the sizes chosen.
2585 GEO is the geometry that may specify some of the info.
2586 STR is a prompt to display.
2587 HSCROLL and VSCROLL say whether we have horiz and vert scroll bars. */
2590 x_rubber_band (f, x, y, width, height, geo, str, hscroll, vscroll)
2591 struct frame *f;
2592 int *x, *y, *width, *height;
2593 char *geo;
2594 char *str;
2595 int hscroll, vscroll;
2597 OpaqueFrame frame;
2598 Window tempwindow;
2599 WindowInfo wininfo;
2600 int border_color;
2601 int background_color;
2602 Lisp_Object tem;
2603 int mask;
2605 BLOCK_INPUT;
2607 background_color = f->display.x->background_pixel;
2608 border_color = f->display.x->border_pixel;
2610 frame.bdrwidth = f->display.x->border_width;
2611 frame.border = XMakeTile (border_color);
2612 frame.background = XMakeTile (background_color);
2613 tempwindow = XCreateTerm (str, "emacs", geo, default_window, &frame, 10, 5,
2614 (2 * f->display.x->internal_border_width
2615 + (vscroll ? VSCROLL_WIDTH : 0)),
2616 (2 * f->display.x->internal_border_width
2617 + (hscroll ? HSCROLL_HEIGHT : 0)),
2618 width, height, f->display.x->font,
2619 FONT_WIDTH (f->display.x->font),
2620 f->display.x->line_height);
2621 XFreePixmap (frame.border);
2622 XFreePixmap (frame.background);
2624 if (tempwindow != 0)
2626 XQueryWindow (tempwindow, &wininfo);
2627 XDestroyWindow (tempwindow);
2628 *x = wininfo.x;
2629 *y = wininfo.y;
2632 /* Coordinates we got are relative to the root window.
2633 Convert them to coordinates relative to desired parent window
2634 by scanning from there up to the root. */
2635 tempwindow = f->display.x->parent_desc;
2636 while (tempwindow != ROOT_WINDOW)
2638 int nchildren;
2639 Window *children;
2640 XQueryWindow (tempwindow, &wininfo);
2641 *x -= wininfo.x;
2642 *y -= wininfo.y;
2643 XQueryTree (tempwindow, &tempwindow, &nchildren, &children);
2644 xfree (children);
2647 UNBLOCK_INPUT;
2648 return tempwindow != 0;
2650 #endif /* not HAVE_X11 */
2652 DEFUN ("x-list-fonts", Fx_list_fonts, Sx_list_fonts, 1, 3, 0,
2653 "Return a list of the names of available fonts matching PATTERN.\n\
2654 If optional arguments FACE and FRAME are specified, return only fonts\n\
2655 the same size as FACE on FRAME.\n\
2657 PATTERN is a string, perhaps with wildcard characters;\n\
2658 the * character matches any substring, and\n\
2659 the ? character matches any single character.\n\
2660 PATTERN is case-insensitive.\n\
2661 FACE is a face name - a symbol.\n\
2663 The return value is a list of strings, suitable as arguments to\n\
2664 set-face-font.\n\
2666 Fonts Emacs can't use (i.e. proportional fonts) may or may not be excluded\n\
2667 even if they match PATTERN and FACE.")
2668 (pattern, face, frame)
2669 Lisp_Object pattern, face, frame;
2671 int num_fonts;
2672 char **names;
2673 XFontStruct *info;
2674 XFontStruct *size_ref;
2675 Lisp_Object list;
2677 check_x ();
2678 CHECK_STRING (pattern, 0);
2679 if (!NILP (face))
2680 CHECK_SYMBOL (face, 1);
2681 if (!NILP (frame))
2682 CHECK_LIVE_FRAME (frame, 2);
2684 if (NILP (face))
2685 size_ref = 0;
2686 else
2688 FRAME_PTR f = NILP (frame) ? selected_frame : XFRAME (frame);
2689 int face_id;
2691 /* Don't die if we get called with a terminal frame. */
2692 if (! FRAME_X_P (f))
2693 error ("non-X frame used in `x-list-fonts'");
2695 face_id = face_name_id_number (f, face);
2697 if (face_id < 0 || face_id >= FRAME_N_PARAM_FACES (f)
2698 || FRAME_PARAM_FACES (f) [face_id] == 0)
2699 size_ref = f->display.x->font;
2700 else
2702 size_ref = FRAME_PARAM_FACES (f) [face_id]->font;
2703 if (size_ref == (XFontStruct *) (~0))
2704 size_ref = f->display.x->font;
2708 BLOCK_INPUT;
2710 /* Solaris 2.3 has a bug in XListFontsWithInfo. */
2711 #ifdef BROKEN_XLISTFONTSWITHINFO
2712 names = XListFonts (x_current_display,
2713 XSTRING (pattern)->data,
2714 2000, /* maxnames */
2715 &num_fonts); /* count_return */
2716 #else
2717 names = XListFontsWithInfo (x_current_display,
2718 XSTRING (pattern)->data,
2719 2000, /* maxnames */
2720 &num_fonts, /* count_return */
2721 &info); /* info_return */
2722 #endif
2723 UNBLOCK_INPUT;
2725 list = Qnil;
2727 if (names)
2729 Lisp_Object *tail;
2730 int i;
2732 tail = &list;
2733 for (i = 0; i < num_fonts; i++)
2735 XFontStruct *thisinfo;
2737 #ifdef BROKEN_XLISTFONTSWITHINFO
2738 BLOCK_INPUT;
2739 thisinfo = XLoadQueryFont (x_current_display, names[i]);
2740 UNBLOCK_INPUT;
2741 #else
2742 thisinfo = &info[i];
2743 #endif
2744 if (thisinfo && (! size_ref
2745 || same_size_fonts (thisinfo, size_ref)))
2747 *tail = Fcons (build_string (names[i]), Qnil);
2748 tail = &XCONS (*tail)->cdr;
2752 BLOCK_INPUT;
2753 #ifdef BROKEN_XLISTFONTSWITHINFO
2754 XFreeFontNames (names);
2755 #else
2756 XFreeFontInfo (names, info, num_fonts);
2757 #endif
2758 UNBLOCK_INPUT;
2761 return list;
2765 DEFUN ("x-color-defined-p", Fx_color_defined_p, Sx_color_defined_p, 1, 1, 0,
2766 "Return t if the current X display supports the color named COLOR.")
2767 (color)
2768 Lisp_Object color;
2770 Color foo;
2772 check_x ();
2773 CHECK_STRING (color, 0);
2775 if (defined_color (XSTRING (color)->data, &foo))
2776 return Qt;
2777 else
2778 return Qnil;
2781 DEFUN ("x-display-color-p", Fx_display_color_p, Sx_display_color_p, 0, 0, 0,
2782 "Return t if the X screen currently in use supports color.")
2785 check_x ();
2787 if (x_screen_planes <= 2)
2788 return Qnil;
2790 switch (screen_visual->class)
2792 case StaticColor:
2793 case PseudoColor:
2794 case TrueColor:
2795 case DirectColor:
2796 return Qt;
2798 default:
2799 return Qnil;
2803 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
2804 0, 1, 0,
2805 "Returns the width in pixels of the display FRAME is on.")
2806 (frame)
2807 Lisp_Object frame;
2809 Display *dpy = x_current_display;
2810 check_x ();
2811 return make_number (DisplayWidth (dpy, DefaultScreen (dpy)));
2814 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
2815 Sx_display_pixel_height, 0, 1, 0,
2816 "Returns the height in pixels of the display FRAME is on.")
2817 (frame)
2818 Lisp_Object frame;
2820 Display *dpy = x_current_display;
2821 check_x ();
2822 return make_number (DisplayHeight (dpy, DefaultScreen (dpy)));
2825 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
2826 0, 1, 0,
2827 "Returns the number of bitplanes of the display FRAME is on.")
2828 (frame)
2829 Lisp_Object frame;
2831 Display *dpy = x_current_display;
2832 check_x ();
2833 return make_number (DisplayPlanes (dpy, DefaultScreen (dpy)));
2836 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
2837 0, 1, 0,
2838 "Returns the number of color cells of the display FRAME is on.")
2839 (frame)
2840 Lisp_Object frame;
2842 Display *dpy = x_current_display;
2843 check_x ();
2844 return make_number (DisplayCells (dpy, DefaultScreen (dpy)));
2847 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
2848 Sx_server_max_request_size,
2849 0, 1, 0,
2850 "Returns the maximum request size of the X server FRAME is using.")
2851 (frame)
2852 Lisp_Object frame;
2854 Display *dpy = x_current_display;
2855 check_x ();
2856 return make_number (MAXREQUEST (dpy));
2859 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
2860 "Returns the vendor ID string of the X server FRAME is on.")
2861 (frame)
2862 Lisp_Object frame;
2864 Display *dpy = x_current_display;
2865 char *vendor;
2866 check_x ();
2867 vendor = ServerVendor (dpy);
2868 if (! vendor) vendor = "";
2869 return build_string (vendor);
2872 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
2873 "Returns the version numbers of the X server in use.\n\
2874 The value is a list of three integers: the major and minor\n\
2875 version numbers of the X Protocol in use, and the vendor-specific release\n\
2876 number. See also the variable `x-server-vendor'.")
2877 (frame)
2878 Lisp_Object frame;
2880 Display *dpy = x_current_display;
2882 check_x ();
2883 return Fcons (make_number (ProtocolVersion (dpy)),
2884 Fcons (make_number (ProtocolRevision (dpy)),
2885 Fcons (make_number (VendorRelease (dpy)), Qnil)));
2888 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
2889 "Returns the number of screens on the X server FRAME is on.")
2890 (frame)
2891 Lisp_Object frame;
2893 check_x ();
2894 return make_number (ScreenCount (x_current_display));
2897 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
2898 "Returns the height in millimeters of the X screen FRAME is on.")
2899 (frame)
2900 Lisp_Object frame;
2902 check_x ();
2903 return make_number (HeightMMOfScreen (x_screen));
2906 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
2907 "Returns the width in millimeters of the X screen FRAME is on.")
2908 (frame)
2909 Lisp_Object frame;
2911 check_x ();
2912 return make_number (WidthMMOfScreen (x_screen));
2915 DEFUN ("x-display-backing-store", Fx_display_backing_store,
2916 Sx_display_backing_store, 0, 1, 0,
2917 "Returns an indication of whether the X screen FRAME is on does backing store.\n\
2918 The value may be `always', `when-mapped', or `not-useful'.")
2919 (frame)
2920 Lisp_Object frame;
2922 check_x ();
2924 switch (DoesBackingStore (x_screen))
2926 case Always:
2927 return intern ("always");
2929 case WhenMapped:
2930 return intern ("when-mapped");
2932 case NotUseful:
2933 return intern ("not-useful");
2935 default:
2936 error ("Strange value for BackingStore parameter of screen");
2940 DEFUN ("x-display-visual-class", Fx_display_visual_class,
2941 Sx_display_visual_class, 0, 1, 0,
2942 "Returns the visual class of the display `screen' is on.\n\
2943 The value is one of the symbols `static-gray', `gray-scale',\n\
2944 `static-color', `pseudo-color', `true-color', or `direct-color'.")
2945 (screen)
2946 Lisp_Object screen;
2948 check_x ();
2950 switch (screen_visual->class)
2952 case StaticGray: return (intern ("static-gray"));
2953 case GrayScale: return (intern ("gray-scale"));
2954 case StaticColor: return (intern ("static-color"));
2955 case PseudoColor: return (intern ("pseudo-color"));
2956 case TrueColor: return (intern ("true-color"));
2957 case DirectColor: return (intern ("direct-color"));
2958 default:
2959 error ("Display has an unknown visual class");
2963 DEFUN ("x-display-save-under", Fx_display_save_under,
2964 Sx_display_save_under, 0, 1, 0,
2965 "Returns t if the X screen FRAME is on supports the save-under feature.")
2966 (frame)
2967 Lisp_Object frame;
2969 check_x ();
2971 if (DoesSaveUnders (x_screen) == True)
2972 return Qt;
2973 else
2974 return Qnil;
2977 x_pixel_width (f)
2978 register struct frame *f;
2980 return PIXEL_WIDTH (f);
2983 x_pixel_height (f)
2984 register struct frame *f;
2986 return PIXEL_HEIGHT (f);
2989 x_char_width (f)
2990 register struct frame *f;
2992 return FONT_WIDTH (f->display.x->font);
2995 x_char_height (f)
2996 register struct frame *f;
2998 return f->display.x->line_height;
3001 #if 0 /* These no longer seem like the right way to do things. */
3003 /* Draw a rectangle on the frame with left top corner including
3004 the character specified by LEFT_CHAR and TOP_CHAR. The rectangle is
3005 CHARS by LINES wide and long and is the color of the cursor. */
3007 void
3008 x_rectangle (f, gc, left_char, top_char, chars, lines)
3009 register struct frame *f;
3010 GC gc;
3011 register int top_char, left_char, chars, lines;
3013 int width;
3014 int height;
3015 int left = (left_char * FONT_WIDTH (f->display.x->font)
3016 + f->display.x->internal_border_width);
3017 int top = (top_char * f->display.x->line_height
3018 + f->display.x->internal_border_width);
3020 if (chars < 0)
3021 width = FONT_WIDTH (f->display.x->font) / 2;
3022 else
3023 width = FONT_WIDTH (f->display.x->font) * chars;
3024 if (lines < 0)
3025 height = f->display.x->line_height / 2;
3026 else
3027 height = f->display.x->line_height * lines;
3029 XDrawRectangle (x_current_display, FRAME_X_WINDOW (f),
3030 gc, left, top, width, height);
3033 DEFUN ("x-draw-rectangle", Fx_draw_rectangle, Sx_draw_rectangle, 5, 5, 0,
3034 "Draw a rectangle on FRAME between coordinates specified by\n\
3035 numbers X0, Y0, X1, Y1 in the cursor pixel.")
3036 (frame, X0, Y0, X1, Y1)
3037 register Lisp_Object frame, X0, X1, Y0, Y1;
3039 register int x0, y0, x1, y1, top, left, n_chars, n_lines;
3041 CHECK_LIVE_FRAME (frame, 0);
3042 CHECK_NUMBER (X0, 0);
3043 CHECK_NUMBER (Y0, 1);
3044 CHECK_NUMBER (X1, 2);
3045 CHECK_NUMBER (Y1, 3);
3047 x0 = XINT (X0);
3048 x1 = XINT (X1);
3049 y0 = XINT (Y0);
3050 y1 = XINT (Y1);
3052 if (y1 > y0)
3054 top = y0;
3055 n_lines = y1 - y0 + 1;
3057 else
3059 top = y1;
3060 n_lines = y0 - y1 + 1;
3063 if (x1 > x0)
3065 left = x0;
3066 n_chars = x1 - x0 + 1;
3068 else
3070 left = x1;
3071 n_chars = x0 - x1 + 1;
3074 BLOCK_INPUT;
3075 x_rectangle (XFRAME (frame), XFRAME (frame)->display.x->cursor_gc,
3076 left, top, n_chars, n_lines);
3077 UNBLOCK_INPUT;
3079 return Qt;
3082 DEFUN ("x-erase-rectangle", Fx_erase_rectangle, Sx_erase_rectangle, 5, 5, 0,
3083 "Draw a rectangle drawn on FRAME between coordinates\n\
3084 X0, Y0, X1, Y1 in the regular background-pixel.")
3085 (frame, X0, Y0, X1, Y1)
3086 register Lisp_Object frame, X0, Y0, X1, Y1;
3088 register int x0, y0, x1, y1, top, left, n_chars, n_lines;
3090 CHECK_FRAME (frame, 0);
3091 CHECK_NUMBER (X0, 0);
3092 CHECK_NUMBER (Y0, 1);
3093 CHECK_NUMBER (X1, 2);
3094 CHECK_NUMBER (Y1, 3);
3096 x0 = XINT (X0);
3097 x1 = XINT (X1);
3098 y0 = XINT (Y0);
3099 y1 = XINT (Y1);
3101 if (y1 > y0)
3103 top = y0;
3104 n_lines = y1 - y0 + 1;
3106 else
3108 top = y1;
3109 n_lines = y0 - y1 + 1;
3112 if (x1 > x0)
3114 left = x0;
3115 n_chars = x1 - x0 + 1;
3117 else
3119 left = x1;
3120 n_chars = x0 - x1 + 1;
3123 BLOCK_INPUT;
3124 x_rectangle (XFRAME (frame), XFRAME (frame)->display.x->reverse_gc,
3125 left, top, n_chars, n_lines);
3126 UNBLOCK_INPUT;
3128 return Qt;
3131 /* Draw lines around the text region beginning at the character position
3132 TOP_X, TOP_Y and ending at BOTTOM_X and BOTTOM_Y. GC specifies the
3133 pixel and line characteristics. */
3135 #define line_len(line) (FRAME_CURRENT_GLYPHS (f)->used[(line)])
3137 static void
3138 outline_region (f, gc, top_x, top_y, bottom_x, bottom_y)
3139 register struct frame *f;
3140 GC gc;
3141 int top_x, top_y, bottom_x, bottom_y;
3143 register int ibw = f->display.x->internal_border_width;
3144 register int font_w = FONT_WIDTH (f->display.x->font);
3145 register int font_h = f->display.x->line_height;
3146 int y = top_y;
3147 int x = line_len (y);
3148 XPoint *pixel_points
3149 = (XPoint *) alloca (((bottom_y - top_y + 2) * 4) * sizeof (XPoint));
3150 register XPoint *this_point = pixel_points;
3152 /* Do the horizontal top line/lines */
3153 if (top_x == 0)
3155 this_point->x = ibw;
3156 this_point->y = ibw + (font_h * top_y);
3157 this_point++;
3158 if (x == 0)
3159 this_point->x = ibw + (font_w / 2); /* Half-size for newline chars. */
3160 else
3161 this_point->x = ibw + (font_w * x);
3162 this_point->y = (this_point - 1)->y;
3164 else
3166 this_point->x = ibw;
3167 this_point->y = ibw + (font_h * (top_y + 1));
3168 this_point++;
3169 this_point->x = ibw + (font_w * top_x);
3170 this_point->y = (this_point - 1)->y;
3171 this_point++;
3172 this_point->x = (this_point - 1)->x;
3173 this_point->y = ibw + (font_h * top_y);
3174 this_point++;
3175 this_point->x = ibw + (font_w * x);
3176 this_point->y = (this_point - 1)->y;
3179 /* Now do the right side. */
3180 while (y < bottom_y)
3181 { /* Right vertical edge */
3182 this_point++;
3183 this_point->x = (this_point - 1)->x;
3184 this_point->y = ibw + (font_h * (y + 1));
3185 this_point++;
3187 y++; /* Horizontal connection to next line */
3188 x = line_len (y);
3189 if (x == 0)
3190 this_point->x = ibw + (font_w / 2);
3191 else
3192 this_point->x = ibw + (font_w * x);
3194 this_point->y = (this_point - 1)->y;
3197 /* Now do the bottom and connect to the top left point. */
3198 this_point->x = ibw + (font_w * (bottom_x + 1));
3200 this_point++;
3201 this_point->x = (this_point - 1)->x;
3202 this_point->y = ibw + (font_h * (bottom_y + 1));
3203 this_point++;
3204 this_point->x = ibw;
3205 this_point->y = (this_point - 1)->y;
3206 this_point++;
3207 this_point->x = pixel_points->x;
3208 this_point->y = pixel_points->y;
3210 XDrawLines (x_current_display, FRAME_X_WINDOW (f),
3211 gc, pixel_points,
3212 (this_point - pixel_points + 1), CoordModeOrigin);
3215 DEFUN ("x-contour-region", Fx_contour_region, Sx_contour_region, 1, 1, 0,
3216 "Highlight the region between point and the character under the mouse\n\
3217 selected frame.")
3218 (event)
3219 register Lisp_Object event;
3221 register int x0, y0, x1, y1;
3222 register struct frame *f = selected_frame;
3223 register int p1, p2;
3225 CHECK_CONS (event, 0);
3227 BLOCK_INPUT;
3228 x0 = XINT (Fcar (Fcar (event)));
3229 y0 = XINT (Fcar (Fcdr (Fcar (event))));
3231 /* If the mouse is past the end of the line, don't that area. */
3232 /* ReWrite this... */
3234 x1 = f->cursor_x;
3235 y1 = f->cursor_y;
3237 if (y1 > y0) /* point below mouse */
3238 outline_region (f, f->display.x->cursor_gc,
3239 x0, y0, x1, y1);
3240 else if (y1 < y0) /* point above mouse */
3241 outline_region (f, f->display.x->cursor_gc,
3242 x1, y1, x0, y0);
3243 else /* same line: draw horizontal rectangle */
3245 if (x1 > x0)
3246 x_rectangle (f, f->display.x->cursor_gc,
3247 x0, y0, (x1 - x0 + 1), 1);
3248 else if (x1 < x0)
3249 x_rectangle (f, f->display.x->cursor_gc,
3250 x1, y1, (x0 - x1 + 1), 1);
3253 XFlush (x_current_display);
3254 UNBLOCK_INPUT;
3256 return Qnil;
3259 DEFUN ("x-uncontour-region", Fx_uncontour_region, Sx_uncontour_region, 1, 1, 0,
3260 "Erase any highlighting of the region between point and the character\n\
3261 at X, Y on the selected frame.")
3262 (event)
3263 register Lisp_Object event;
3265 register int x0, y0, x1, y1;
3266 register struct frame *f = selected_frame;
3268 BLOCK_INPUT;
3269 x0 = XINT (Fcar (Fcar (event)));
3270 y0 = XINT (Fcar (Fcdr (Fcar (event))));
3271 x1 = f->cursor_x;
3272 y1 = f->cursor_y;
3274 if (y1 > y0) /* point below mouse */
3275 outline_region (f, f->display.x->reverse_gc,
3276 x0, y0, x1, y1);
3277 else if (y1 < y0) /* point above mouse */
3278 outline_region (f, f->display.x->reverse_gc,
3279 x1, y1, x0, y0);
3280 else /* same line: draw horizontal rectangle */
3282 if (x1 > x0)
3283 x_rectangle (f, f->display.x->reverse_gc,
3284 x0, y0, (x1 - x0 + 1), 1);
3285 else if (x1 < x0)
3286 x_rectangle (f, f->display.x->reverse_gc,
3287 x1, y1, (x0 - x1 + 1), 1);
3289 UNBLOCK_INPUT;
3291 return Qnil;
3294 #if 0
3295 int contour_begin_x, contour_begin_y;
3296 int contour_end_x, contour_end_y;
3297 int contour_npoints;
3299 /* Clip the top part of the contour lines down (and including) line Y_POS.
3300 If X_POS is in the middle (rather than at the end) of the line, drop
3301 down a line at that character. */
3303 static void
3304 clip_contour_top (y_pos, x_pos)
3306 register XPoint *begin = contour_lines[y_pos].top_left;
3307 register XPoint *end;
3308 register int npoints;
3309 register struct display_line *line = selected_frame->phys_lines[y_pos + 1];
3311 if (x_pos >= line->len - 1) /* Draw one, straight horizontal line. */
3313 end = contour_lines[y_pos].top_right;
3314 npoints = (end - begin + 1);
3315 XDrawLines (x_current_display, contour_window,
3316 contour_erase_gc, begin_erase, npoints, CoordModeOrigin);
3318 bcopy (end, begin + 1, contour_last_point - end + 1);
3319 contour_last_point -= (npoints - 2);
3320 XDrawLines (x_current_display, contour_window,
3321 contour_erase_gc, begin, 2, CoordModeOrigin);
3322 XFlush (x_current_display);
3324 /* Now, update contour_lines structure. */
3326 /* ______. */
3327 else /* |________*/
3329 register XPoint *p = begin + 1;
3330 end = contour_lines[y_pos].bottom_right;
3331 npoints = (end - begin + 1);
3332 XDrawLines (x_current_display, contour_window,
3333 contour_erase_gc, begin_erase, npoints, CoordModeOrigin);
3335 p->y = begin->y;
3336 p->x = ibw + (font_w * (x_pos + 1));
3337 p++;
3338 p->y = begin->y + font_h;
3339 p->x = (p - 1)->x;
3340 bcopy (end, begin + 3, contour_last_point - end + 1);
3341 contour_last_point -= (npoints - 5);
3342 XDrawLines (x_current_display, contour_window,
3343 contour_erase_gc, begin, 4, CoordModeOrigin);
3344 XFlush (x_current_display);
3346 /* Now, update contour_lines structure. */
3350 /* Erase the top horizontal lines of the contour, and then extend
3351 the contour upwards. */
3353 static void
3354 extend_contour_top (line)
3358 static void
3359 clip_contour_bottom (x_pos, y_pos)
3360 int x_pos, y_pos;
3364 static void
3365 extend_contour_bottom (x_pos, y_pos)
3369 DEFUN ("x-select-region", Fx_select_region, Sx_select_region, 1, 1, "e",
3371 (event)
3372 Lisp_Object event;
3374 register struct frame *f = selected_frame;
3375 register int point_x = f->cursor_x;
3376 register int point_y = f->cursor_y;
3377 register int mouse_below_point;
3378 register Lisp_Object obj;
3379 register int x_contour_x, x_contour_y;
3381 x_contour_x = x_mouse_x;
3382 x_contour_y = x_mouse_y;
3383 if (x_contour_y > point_y || (x_contour_y == point_y
3384 && x_contour_x > point_x))
3386 mouse_below_point = 1;
3387 outline_region (f, f->display.x->cursor_gc, point_x, point_y,
3388 x_contour_x, x_contour_y);
3390 else
3392 mouse_below_point = 0;
3393 outline_region (f, f->display.x->cursor_gc, x_contour_x, x_contour_y,
3394 point_x, point_y);
3397 while (1)
3399 obj = read_char (-1, 0, 0, Qnil, 0);
3400 if (XTYPE (obj) != Lisp_Cons)
3401 break;
3403 if (mouse_below_point)
3405 if (x_mouse_y <= point_y) /* Flipped. */
3407 mouse_below_point = 0;
3409 outline_region (f, f->display.x->reverse_gc, point_x, point_y,
3410 x_contour_x, x_contour_y);
3411 outline_region (f, f->display.x->cursor_gc, x_mouse_x, x_mouse_y,
3412 point_x, point_y);
3414 else if (x_mouse_y < x_contour_y) /* Bottom clipped. */
3416 clip_contour_bottom (x_mouse_y);
3418 else if (x_mouse_y > x_contour_y) /* Bottom extended. */
3420 extend_bottom_contour (x_mouse_y);
3423 x_contour_x = x_mouse_x;
3424 x_contour_y = x_mouse_y;
3426 else /* mouse above or same line as point */
3428 if (x_mouse_y >= point_y) /* Flipped. */
3430 mouse_below_point = 1;
3432 outline_region (f, f->display.x->reverse_gc,
3433 x_contour_x, x_contour_y, point_x, point_y);
3434 outline_region (f, f->display.x->cursor_gc, point_x, point_y,
3435 x_mouse_x, x_mouse_y);
3437 else if (x_mouse_y > x_contour_y) /* Top clipped. */
3439 clip_contour_top (x_mouse_y);
3441 else if (x_mouse_y < x_contour_y) /* Top extended. */
3443 extend_contour_top (x_mouse_y);
3448 unread_command_event = obj;
3449 if (mouse_below_point)
3451 contour_begin_x = point_x;
3452 contour_begin_y = point_y;
3453 contour_end_x = x_contour_x;
3454 contour_end_y = x_contour_y;
3456 else
3458 contour_begin_x = x_contour_x;
3459 contour_begin_y = x_contour_y;
3460 contour_end_x = point_x;
3461 contour_end_y = point_y;
3464 #endif
3466 DEFUN ("x-horizontal-line", Fx_horizontal_line, Sx_horizontal_line, 1, 1, "e",
3468 (event)
3469 Lisp_Object event;
3471 register Lisp_Object obj;
3472 struct frame *f = selected_frame;
3473 register struct window *w = XWINDOW (selected_window);
3474 register GC line_gc = f->display.x->cursor_gc;
3475 register GC erase_gc = f->display.x->reverse_gc;
3476 #if 0
3477 char dash_list[] = {6, 4, 6, 4};
3478 int dashes = 4;
3479 XGCValues gc_values;
3480 #endif
3481 register int previous_y;
3482 register int line = (x_mouse_y + 1) * f->display.x->line_height
3483 + f->display.x->internal_border_width;
3484 register int left = f->display.x->internal_border_width
3485 + (w->left
3486 * FONT_WIDTH (f->display.x->font));
3487 register int right = left + (w->width
3488 * FONT_WIDTH (f->display.x->font))
3489 - f->display.x->internal_border_width;
3491 #if 0
3492 BLOCK_INPUT;
3493 gc_values.foreground = f->display.x->cursor_pixel;
3494 gc_values.background = f->display.x->background_pixel;
3495 gc_values.line_width = 1;
3496 gc_values.line_style = LineOnOffDash;
3497 gc_values.cap_style = CapRound;
3498 gc_values.join_style = JoinRound;
3500 line_gc = XCreateGC (x_current_display, FRAME_X_WINDOW (f),
3501 GCLineStyle | GCJoinStyle | GCCapStyle
3502 | GCLineWidth | GCForeground | GCBackground,
3503 &gc_values);
3504 XSetDashes (x_current_display, line_gc, 0, dash_list, dashes);
3505 gc_values.foreground = f->display.x->background_pixel;
3506 gc_values.background = f->display.x->foreground_pixel;
3507 erase_gc = XCreateGC (x_current_display, FRAME_X_WINDOW (f),
3508 GCLineStyle | GCJoinStyle | GCCapStyle
3509 | GCLineWidth | GCForeground | GCBackground,
3510 &gc_values);
3511 XSetDashes (x_current_display, erase_gc, 0, dash_list, dashes);
3512 #endif
3514 while (1)
3516 BLOCK_INPUT;
3517 if (x_mouse_y >= XINT (w->top)
3518 && x_mouse_y < XINT (w->top) + XINT (w->height) - 1)
3520 previous_y = x_mouse_y;
3521 line = (x_mouse_y + 1) * f->display.x->line_height
3522 + f->display.x->internal_border_width;
3523 XDrawLine (x_current_display, FRAME_X_WINDOW (f),
3524 line_gc, left, line, right, line);
3526 XFlushQueue ();
3527 UNBLOCK_INPUT;
3531 obj = read_char (-1, 0, 0, Qnil, 0);
3532 if ((XTYPE (obj) != Lisp_Cons)
3533 || (! EQ (Fcar (Fcdr (Fcdr (obj))),
3534 Qvertical_scroll_bar))
3535 || x_mouse_grabbed)
3537 BLOCK_INPUT;
3538 XDrawLine (x_current_display, FRAME_X_WINDOW (f),
3539 erase_gc, left, line, right, line);
3540 UNBLOCK_INPUT;
3541 unread_command_event = obj;
3542 #if 0
3543 XFreeGC (x_current_display, line_gc);
3544 XFreeGC (x_current_display, erase_gc);
3545 #endif
3546 return Qnil;
3549 while (x_mouse_y == previous_y);
3551 BLOCK_INPUT;
3552 XDrawLine (x_current_display, FRAME_X_WINDOW (f),
3553 erase_gc, left, line, right, line);
3554 UNBLOCK_INPUT;
3557 #endif
3559 /* Offset in buffer of character under the pointer, or 0. */
3560 int mouse_buffer_offset;
3562 #if 0
3563 /* These keep track of the rectangle following the pointer. */
3564 int mouse_track_top, mouse_track_left, mouse_track_width;
3566 DEFUN ("x-track-pointer", Fx_track_pointer, Sx_track_pointer, 0, 0, 0,
3567 "Track the pointer.")
3570 static Cursor current_pointer_shape;
3571 FRAME_PTR f = x_mouse_frame;
3573 BLOCK_INPUT;
3574 if (EQ (Vmouse_frame_part, Qtext_part)
3575 && (current_pointer_shape != f->display.x->nontext_cursor))
3577 unsigned char c;
3578 struct buffer *buf;
3580 current_pointer_shape = f->display.x->nontext_cursor;
3581 XDefineCursor (x_current_display,
3582 FRAME_X_WINDOW (f),
3583 current_pointer_shape);
3585 buf = XBUFFER (XWINDOW (Vmouse_window)->buffer);
3586 c = *(BUF_CHAR_ADDRESS (buf, mouse_buffer_offset));
3588 else if (EQ (Vmouse_frame_part, Qmodeline_part)
3589 && (current_pointer_shape != f->display.x->modeline_cursor))
3591 current_pointer_shape = f->display.x->modeline_cursor;
3592 XDefineCursor (x_current_display,
3593 FRAME_X_WINDOW (f),
3594 current_pointer_shape);
3597 XFlushQueue ();
3598 UNBLOCK_INPUT;
3600 #endif
3602 #if 0
3603 DEFUN ("x-track-pointer", Fx_track_pointer, Sx_track_pointer, 1, 1, "e",
3604 "Draw rectangle around character under mouse pointer, if there is one.")
3605 (event)
3606 Lisp_Object event;
3608 struct window *w = XWINDOW (Vmouse_window);
3609 struct frame *f = XFRAME (WINDOW_FRAME (w));
3610 struct buffer *b = XBUFFER (w->buffer);
3611 Lisp_Object obj;
3613 if (! EQ (Vmouse_window, selected_window))
3614 return Qnil;
3616 if (EQ (event, Qnil))
3618 int x, y;
3620 x_read_mouse_position (selected_frame, &x, &y);
3623 BLOCK_INPUT;
3624 mouse_track_width = 0;
3625 mouse_track_left = mouse_track_top = -1;
3629 if ((x_mouse_x != mouse_track_left
3630 && (x_mouse_x < mouse_track_left
3631 || x_mouse_x > (mouse_track_left + mouse_track_width)))
3632 || x_mouse_y != mouse_track_top)
3634 int hp = 0; /* Horizontal position */
3635 int len = FRAME_CURRENT_GLYPHS (f)->used[x_mouse_y];
3636 int p = FRAME_CURRENT_GLYPHS (f)->bufp[x_mouse_y];
3637 int tab_width = XINT (b->tab_width);
3638 int ctl_arrow_p = !NILP (b->ctl_arrow);
3639 unsigned char c;
3640 int mode_line_vpos = XFASTINT (w->height) + XFASTINT (w->top) - 1;
3641 int in_mode_line = 0;
3643 if (! FRAME_CURRENT_GLYPHS (f)->enable[x_mouse_y])
3644 break;
3646 /* Erase previous rectangle. */
3647 if (mouse_track_width)
3649 x_rectangle (f, f->display.x->reverse_gc,
3650 mouse_track_left, mouse_track_top,
3651 mouse_track_width, 1);
3653 if ((mouse_track_left == f->phys_cursor_x
3654 || mouse_track_left == f->phys_cursor_x - 1)
3655 && mouse_track_top == f->phys_cursor_y)
3657 x_display_cursor (f, 1);
3661 mouse_track_left = x_mouse_x;
3662 mouse_track_top = x_mouse_y;
3663 mouse_track_width = 0;
3665 if (mouse_track_left > len) /* Past the end of line. */
3666 goto draw_or_not;
3668 if (mouse_track_top == mode_line_vpos)
3670 in_mode_line = 1;
3671 goto draw_or_not;
3674 if (tab_width <= 0 || tab_width > 20) tab_width = 8;
3677 c = FETCH_CHAR (p);
3678 if (len == f->width && hp == len - 1 && c != '\n')
3679 goto draw_or_not;
3681 switch (c)
3683 case '\t':
3684 mouse_track_width = tab_width - (hp % tab_width);
3685 p++;
3686 hp += mouse_track_width;
3687 if (hp > x_mouse_x)
3689 mouse_track_left = hp - mouse_track_width;
3690 goto draw_or_not;
3692 continue;
3694 case '\n':
3695 mouse_track_width = -1;
3696 goto draw_or_not;
3698 default:
3699 if (ctl_arrow_p && (c < 040 || c == 0177))
3701 if (p > ZV)
3702 goto draw_or_not;
3704 mouse_track_width = 2;
3705 p++;
3706 hp +=2;
3707 if (hp > x_mouse_x)
3709 mouse_track_left = hp - mouse_track_width;
3710 goto draw_or_not;
3713 else
3715 mouse_track_width = 1;
3716 p++;
3717 hp++;
3719 continue;
3722 while (hp <= x_mouse_x);
3724 draw_or_not:
3725 if (mouse_track_width) /* Over text; use text pointer shape. */
3727 XDefineCursor (x_current_display,
3728 FRAME_X_WINDOW (f),
3729 f->display.x->text_cursor);
3730 x_rectangle (f, f->display.x->cursor_gc,
3731 mouse_track_left, mouse_track_top,
3732 mouse_track_width, 1);
3734 else if (in_mode_line)
3735 XDefineCursor (x_current_display,
3736 FRAME_X_WINDOW (f),
3737 f->display.x->modeline_cursor);
3738 else
3739 XDefineCursor (x_current_display,
3740 FRAME_X_WINDOW (f),
3741 f->display.x->nontext_cursor);
3744 XFlush (x_current_display);
3745 UNBLOCK_INPUT;
3747 obj = read_char (-1, 0, 0, Qnil, 0);
3748 BLOCK_INPUT;
3750 while (XTYPE (obj) == Lisp_Cons /* Mouse event */
3751 && EQ (Fcar (Fcdr (Fcdr (obj))), Qnil) /* Not scroll bar */
3752 && EQ (Vmouse_depressed, Qnil) /* Only motion events */
3753 && EQ (Vmouse_window, selected_window) /* In this window */
3754 && x_mouse_frame);
3756 unread_command_event = obj;
3758 if (mouse_track_width)
3760 x_rectangle (f, f->display.x->reverse_gc,
3761 mouse_track_left, mouse_track_top,
3762 mouse_track_width, 1);
3763 mouse_track_width = 0;
3764 if ((mouse_track_left == f->phys_cursor_x
3765 || mouse_track_left - 1 == f->phys_cursor_x)
3766 && mouse_track_top == f->phys_cursor_y)
3768 x_display_cursor (f, 1);
3771 XDefineCursor (x_current_display,
3772 FRAME_X_WINDOW (f),
3773 f->display.x->nontext_cursor);
3774 XFlush (x_current_display);
3775 UNBLOCK_INPUT;
3777 return Qnil;
3779 #endif
3781 #if 0
3782 #include "glyphs.h"
3784 /* Draw a pixmap specified by IMAGE_DATA of dimensions WIDTH and HEIGHT
3785 on the frame F at position X, Y. */
3787 x_draw_pixmap (f, x, y, image_data, width, height)
3788 struct frame *f;
3789 int x, y, width, height;
3790 char *image_data;
3792 Pixmap image;
3794 image = XCreateBitmapFromData (x_current_display,
3795 FRAME_X_WINDOW (f), image_data,
3796 width, height);
3797 XCopyPlane (x_current_display, image, FRAME_X_WINDOW (f),
3798 f->display.x->normal_gc, 0, 0, width, height, x, y);
3800 #endif
3802 #ifndef HAVE_X11
3803 DEFUN ("x-store-cut-buffer", Fx_store_cut_buffer, Sx_store_cut_buffer,
3804 1, 1, "sStore text in cut buffer: ",
3805 "Store contents of STRING into the cut buffer of the X window system.")
3806 (string)
3807 register Lisp_Object string;
3809 int mask;
3811 CHECK_STRING (string, 1);
3812 if (! FRAME_X_P (selected_frame))
3813 error ("Selected frame does not understand X protocol.");
3815 BLOCK_INPUT;
3816 XStoreBytes ((char *) XSTRING (string)->data, XSTRING (string)->size);
3817 UNBLOCK_INPUT;
3819 return Qnil;
3822 DEFUN ("x-get-cut-buffer", Fx_get_cut_buffer, Sx_get_cut_buffer, 0, 0, 0,
3823 "Return contents of cut buffer of the X window system, as a string.")
3826 int len;
3827 register Lisp_Object string;
3828 int mask;
3829 register char *d;
3831 BLOCK_INPUT;
3832 d = XFetchBytes (&len);
3833 string = make_string (d, len);
3834 XFree (d);
3835 UNBLOCK_INPUT;
3836 return string;
3838 #endif /* X10 */
3840 #if 0 /* I'm told these functions are superfluous
3841 given the ability to bind function keys. */
3843 #ifdef HAVE_X11
3844 DEFUN ("x-rebind-key", Fx_rebind_key, Sx_rebind_key, 3, 3, 0,
3845 "Rebind X keysym KEYSYM, with MODIFIERS, to generate NEWSTRING.\n\
3846 KEYSYM is a string which conforms to the X keysym definitions found\n\
3847 in X11/keysymdef.h, sans the initial XK_. MODIFIERS is nil or a\n\
3848 list of strings specifying modifier keys such as Control_L, which must\n\
3849 also be depressed for NEWSTRING to appear.")
3850 (x_keysym, modifiers, newstring)
3851 register Lisp_Object x_keysym;
3852 register Lisp_Object modifiers;
3853 register Lisp_Object newstring;
3855 char *rawstring;
3856 register KeySym keysym;
3857 KeySym modifier_list[16];
3859 check_x ();
3860 CHECK_STRING (x_keysym, 1);
3861 CHECK_STRING (newstring, 3);
3863 keysym = XStringToKeysym ((char *) XSTRING (x_keysym)->data);
3864 if (keysym == NoSymbol)
3865 error ("Keysym does not exist");
3867 if (NILP (modifiers))
3868 XRebindKeysym (x_current_display, keysym, modifier_list, 0,
3869 XSTRING (newstring)->data, XSTRING (newstring)->size);
3870 else
3872 register Lisp_Object rest, mod;
3873 register int i = 0;
3875 for (rest = modifiers; !NILP (rest); rest = Fcdr (rest))
3877 if (i == 16)
3878 error ("Can't have more than 16 modifiers");
3880 mod = Fcar (rest);
3881 CHECK_STRING (mod, 3);
3882 modifier_list[i] = XStringToKeysym ((char *) XSTRING (mod)->data);
3883 #ifndef HAVE_X11R5
3884 if (modifier_list[i] == NoSymbol
3885 || !(IsModifierKey (modifier_list[i])
3886 || ((unsigned)(modifier_list[i]) == XK_Mode_switch)
3887 || ((unsigned)(modifier_list[i]) == XK_Num_Lock)))
3888 #else
3889 if (modifier_list[i] == NoSymbol
3890 || !IsModifierKey (modifier_list[i]))
3891 #endif
3892 error ("Element is not a modifier keysym");
3893 i++;
3896 XRebindKeysym (x_current_display, keysym, modifier_list, i,
3897 XSTRING (newstring)->data, XSTRING (newstring)->size);
3900 return Qnil;
3903 DEFUN ("x-rebind-keys", Fx_rebind_keys, Sx_rebind_keys, 2, 2, 0,
3904 "Rebind KEYCODE to list of strings STRINGS.\n\
3905 STRINGS should be a list of 16 elements, one for each shift combination.\n\
3906 nil as element means don't change.\n\
3907 See the documentation of `x-rebind-key' for more information.")
3908 (keycode, strings)
3909 register Lisp_Object keycode;
3910 register Lisp_Object strings;
3912 register Lisp_Object item;
3913 register unsigned char *rawstring;
3914 KeySym rawkey, modifier[1];
3915 int strsize;
3916 register unsigned i;
3918 check_x ();
3919 CHECK_NUMBER (keycode, 1);
3920 CHECK_CONS (strings, 2);
3921 rawkey = (KeySym) ((unsigned) (XINT (keycode))) & 255;
3922 for (i = 0; i <= 15; strings = Fcdr (strings), i++)
3924 item = Fcar (strings);
3925 if (!NILP (item))
3927 CHECK_STRING (item, 2);
3928 strsize = XSTRING (item)->size;
3929 rawstring = (unsigned char *) xmalloc (strsize);
3930 bcopy (XSTRING (item)->data, rawstring, strsize);
3931 modifier[1] = 1 << i;
3932 XRebindKeysym (x_current_display, rawkey, modifier, 1,
3933 rawstring, strsize);
3936 return Qnil;
3938 #endif /* HAVE_X11 */
3939 #endif /* 0 */
3941 #ifdef HAVE_X11
3943 #ifndef HAVE_XSCREENNUMBEROFSCREEN
3945 XScreenNumberOfScreen (scr)
3946 register Screen *scr;
3948 register Display *dpy;
3949 register Screen *dpyscr;
3950 register int i;
3952 dpy = scr->display;
3953 dpyscr = dpy->screens;
3955 for (i = 0; i < dpy->nscreens; i++, dpyscr++)
3956 if (scr == dpyscr)
3957 return i;
3959 return -1;
3961 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
3963 Visual *
3964 select_visual (screen, depth)
3965 Screen *screen;
3966 unsigned int *depth;
3968 Visual *v;
3969 XVisualInfo *vinfo, vinfo_template;
3970 int n_visuals;
3972 v = DefaultVisualOfScreen (screen);
3974 #ifdef HAVE_X11R4
3975 vinfo_template.visualid = XVisualIDFromVisual (v);
3976 #else
3977 vinfo_template.visualid = v->visualid;
3978 #endif
3980 vinfo_template.screen = XScreenNumberOfScreen (screen);
3982 vinfo = XGetVisualInfo (x_current_display,
3983 VisualIDMask | VisualScreenMask, &vinfo_template,
3984 &n_visuals);
3985 if (n_visuals != 1)
3986 fatal ("Can't get proper X visual info");
3988 if ((1 << vinfo->depth) == vinfo->colormap_size)
3989 *depth = vinfo->depth;
3990 else
3992 int i = 0;
3993 int n = vinfo->colormap_size - 1;
3994 while (n)
3996 n = n >> 1;
3997 i++;
3999 *depth = i;
4002 XFree ((char *) vinfo);
4003 return v;
4005 #endif /* HAVE_X11 */
4007 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
4008 1, 2, 0, "Open a connection to an X server.\n\
4009 DISPLAY is the name of the display to connect to.\n\
4010 Optional second arg XRM_STRING is a string of resources in xrdb format.")
4011 (display, xrm_string)
4012 Lisp_Object display, xrm_string;
4014 unsigned int n_planes;
4015 unsigned char *xrm_option;
4017 CHECK_STRING (display, 0);
4018 if (x_current_display != 0)
4019 error ("X server connection is already initialized");
4020 if (! NILP (xrm_string))
4021 CHECK_STRING (xrm_string, 1);
4023 /* This is what opens the connection and sets x_current_display.
4024 This also initializes many symbols, such as those used for input. */
4025 x_term_init (XSTRING (display)->data);
4027 #ifdef HAVE_X11
4028 XFASTINT (Vwindow_system_version) = 11;
4030 if (! NILP (xrm_string))
4031 xrm_option = (unsigned char *) XSTRING (xrm_string)->data;
4032 else
4033 xrm_option = (unsigned char *) 0;
4035 validate_x_resource_name ();
4037 BLOCK_INPUT;
4038 xrdb = x_load_resources (x_current_display, xrm_option,
4039 (char *) XSTRING (Vx_resource_name)->data,
4040 EMACS_CLASS);
4041 UNBLOCK_INPUT;
4042 #ifdef HAVE_XRMSETDATABASE
4043 XrmSetDatabase (x_current_display, xrdb);
4044 #else
4045 x_current_display->db = xrdb;
4046 #endif
4048 x_screen = DefaultScreenOfDisplay (x_current_display);
4050 screen_visual = select_visual (x_screen, &n_planes);
4051 x_screen_planes = n_planes;
4052 x_screen_height = HeightOfScreen (x_screen);
4053 x_screen_width = WidthOfScreen (x_screen);
4055 /* X Atoms used by emacs. */
4056 Xatoms_of_xselect ();
4057 BLOCK_INPUT;
4058 Xatom_wm_protocols = XInternAtom (x_current_display, "WM_PROTOCOLS",
4059 False);
4060 Xatom_wm_take_focus = XInternAtom (x_current_display, "WM_TAKE_FOCUS",
4061 False);
4062 Xatom_wm_save_yourself = XInternAtom (x_current_display, "WM_SAVE_YOURSELF",
4063 False);
4064 Xatom_wm_delete_window = XInternAtom (x_current_display, "WM_DELETE_WINDOW",
4065 False);
4066 Xatom_wm_change_state = XInternAtom (x_current_display, "WM_CHANGE_STATE",
4067 False);
4068 Xatom_wm_configure_denied = XInternAtom (x_current_display,
4069 "WM_CONFIGURE_DENIED", False);
4070 Xatom_wm_window_moved = XInternAtom (x_current_display, "WM_MOVED",
4071 False);
4072 Xatom_editres_name = XInternAtom (x_current_display, "Editres", False);
4073 UNBLOCK_INPUT;
4074 #else /* not HAVE_X11 */
4075 XFASTINT (Vwindow_system_version) = 10;
4076 #endif /* not HAVE_X11 */
4077 return Qnil;
4080 DEFUN ("x-close-current-connection", Fx_close_current_connection,
4081 Sx_close_current_connection,
4082 0, 0, 0, "Close the connection to the current X server.")
4085 /* Note: If we're going to call check_x here, then the fatal error
4086 can't happen. For the moment, this check is just for safety,
4087 so a user won't try out the function and get a crash. If it's
4088 really intended only to be called when killing emacs, then there's
4089 no reason for it to have a lisp interface at all. */
4090 check_x();
4091 #ifdef HAVE_X11
4092 /* This is ONLY used when killing emacs; For switching displays
4093 we'll have to take care of setting CloseDownMode elsewhere. */
4095 if (x_current_display)
4097 BLOCK_INPUT;
4098 XSetCloseDownMode (x_current_display, DestroyAll);
4099 XCloseDisplay (x_current_display);
4100 x_current_display = 0;
4102 else
4103 fatal ("No current X display connection to close\n");
4104 #endif
4105 return Qnil;
4108 DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize,
4109 1, 1, 0, "If ON is non-nil, report X errors as soon as the erring request is made.\n\
4110 If ON is nil, allow buffering of requests.\n\
4111 Turning on synchronization prohibits the Xlib routines from buffering\n\
4112 requests and seriously degrades performance, but makes debugging much\n\
4113 easier.")
4114 (on)
4115 Lisp_Object on;
4117 check_x ();
4119 XSynchronize (x_current_display, !EQ (on, Qnil));
4121 return Qnil;
4124 /* Wait for responses to all X commands issued so far for FRAME. */
4126 void
4127 x_sync (frame)
4128 Lisp_Object frame;
4130 BLOCK_INPUT;
4131 XSync (x_current_display, False);
4132 UNBLOCK_INPUT;
4135 syms_of_xfns ()
4137 /* This is zero if not using X windows. */
4138 x_current_display = 0;
4140 /* The section below is built by the lisp expression at the top of the file,
4141 just above where these variables are declared. */
4142 /*&&& init symbols here &&&*/
4143 Qauto_raise = intern ("auto-raise");
4144 staticpro (&Qauto_raise);
4145 Qauto_lower = intern ("auto-lower");
4146 staticpro (&Qauto_lower);
4147 Qbackground_color = intern ("background-color");
4148 staticpro (&Qbackground_color);
4149 Qbar = intern ("bar");
4150 staticpro (&Qbar);
4151 Qborder_color = intern ("border-color");
4152 staticpro (&Qborder_color);
4153 Qborder_width = intern ("border-width");
4154 staticpro (&Qborder_width);
4155 Qbox = intern ("box");
4156 staticpro (&Qbox);
4157 Qcursor_color = intern ("cursor-color");
4158 staticpro (&Qcursor_color);
4159 Qcursor_type = intern ("cursor-type");
4160 staticpro (&Qcursor_type);
4161 Qfont = intern ("font");
4162 staticpro (&Qfont);
4163 Qforeground_color = intern ("foreground-color");
4164 staticpro (&Qforeground_color);
4165 Qgeometry = intern ("geometry");
4166 staticpro (&Qgeometry);
4167 Qicon_left = intern ("icon-left");
4168 staticpro (&Qicon_left);
4169 Qicon_top = intern ("icon-top");
4170 staticpro (&Qicon_top);
4171 Qicon_type = intern ("icon-type");
4172 staticpro (&Qicon_type);
4173 Qinternal_border_width = intern ("internal-border-width");
4174 staticpro (&Qinternal_border_width);
4175 Qleft = intern ("left");
4176 staticpro (&Qleft);
4177 Qmouse_color = intern ("mouse-color");
4178 staticpro (&Qmouse_color);
4179 Qnone = intern ("none");
4180 staticpro (&Qnone);
4181 Qparent_id = intern ("parent-id");
4182 staticpro (&Qparent_id);
4183 Qsuppress_icon = intern ("suppress-icon");
4184 staticpro (&Qsuppress_icon);
4185 Qtop = intern ("top");
4186 staticpro (&Qtop);
4187 Qundefined_color = intern ("undefined-color");
4188 staticpro (&Qundefined_color);
4189 Qvertical_scroll_bars = intern ("vertical-scroll-bars");
4190 staticpro (&Qvertical_scroll_bars);
4191 Qvisibility = intern ("visibility");
4192 staticpro (&Qvisibility);
4193 Qwindow_id = intern ("window-id");
4194 staticpro (&Qwindow_id);
4195 Qx_frame_parameter = intern ("x-frame-parameter");
4196 staticpro (&Qx_frame_parameter);
4197 Qx_resource_name = intern ("x-resource-name");
4198 staticpro (&Qx_resource_name);
4199 /* This is the end of symbol initialization. */
4201 Fput (Qundefined_color, Qerror_conditions,
4202 Fcons (Qundefined_color, Fcons (Qerror, Qnil)));
4203 Fput (Qundefined_color, Qerror_message,
4204 build_string ("Undefined color"));
4206 init_x_parm_symbols ();
4208 DEFVAR_INT ("mouse-buffer-offset", &mouse_buffer_offset,
4209 "The buffer offset of the character under the pointer.");
4210 mouse_buffer_offset = 0;
4212 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
4213 "The shape of the pointer when over text.\n\
4214 Changing the value does not affect existing frames\n\
4215 unless you set the mouse color.");
4216 Vx_pointer_shape = Qnil;
4218 DEFVAR_LISP ("x-resource-name", &Vx_resource_name,
4219 "The name Emacs uses to look up X resources; for internal use only.\n\
4220 `x-get-resource' uses this as the first component of the instance name\n\
4221 when requesting resource values.\n\
4222 Emacs initially sets `x-resource-name' to the name under which Emacs\n\
4223 was invoked, or to the value specified with the `-name' or `-rn'\n\
4224 switches, if present.");
4225 Vx_resource_name = Qnil;
4227 #if 0
4228 DEFVAR_INT ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape,
4229 "The shape of the pointer when not over text.");
4230 #endif
4231 Vx_nontext_pointer_shape = Qnil;
4233 #if 0
4234 DEFVAR_INT ("x-mode-pointer-shape", &Vx_mode_pointer_shape,
4235 "The shape of the pointer when over the mode line.");
4236 #endif
4237 Vx_mode_pointer_shape = Qnil;
4239 Vx_cross_pointer_shape = Qnil;
4241 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel,
4242 "A string indicating the foreground color of the cursor box.");
4243 Vx_cursor_fore_pixel = Qnil;
4245 DEFVAR_LISP ("mouse-grabbed", &Vmouse_depressed,
4246 "Non-nil if a mouse button is currently depressed.");
4247 Vmouse_depressed = Qnil;
4249 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
4250 "t if no X window manager is in use.");
4252 #ifdef HAVE_X11
4253 defsubr (&Sx_get_resource);
4254 #if 0
4255 defsubr (&Sx_draw_rectangle);
4256 defsubr (&Sx_erase_rectangle);
4257 defsubr (&Sx_contour_region);
4258 defsubr (&Sx_uncontour_region);
4259 #endif
4260 defsubr (&Sx_display_color_p);
4261 defsubr (&Sx_list_fonts);
4262 defsubr (&Sx_color_defined_p);
4263 defsubr (&Sx_server_max_request_size);
4264 defsubr (&Sx_server_vendor);
4265 defsubr (&Sx_server_version);
4266 defsubr (&Sx_display_pixel_width);
4267 defsubr (&Sx_display_pixel_height);
4268 defsubr (&Sx_display_mm_width);
4269 defsubr (&Sx_display_mm_height);
4270 defsubr (&Sx_display_screens);
4271 defsubr (&Sx_display_planes);
4272 defsubr (&Sx_display_color_cells);
4273 defsubr (&Sx_display_visual_class);
4274 defsubr (&Sx_display_backing_store);
4275 defsubr (&Sx_display_save_under);
4276 #if 0
4277 defsubr (&Sx_rebind_key);
4278 defsubr (&Sx_rebind_keys);
4279 defsubr (&Sx_track_pointer);
4280 defsubr (&Sx_grab_pointer);
4281 defsubr (&Sx_ungrab_pointer);
4282 #endif
4283 #else
4284 defsubr (&Sx_get_default);
4285 defsubr (&Sx_store_cut_buffer);
4286 defsubr (&Sx_get_cut_buffer);
4287 #endif
4288 defsubr (&Sx_parse_geometry);
4289 defsubr (&Sx_create_frame);
4290 defsubr (&Sfocus_frame);
4291 defsubr (&Sunfocus_frame);
4292 #if 0
4293 defsubr (&Sx_horizontal_line);
4294 #endif
4295 defsubr (&Sx_open_connection);
4296 defsubr (&Sx_close_current_connection);
4297 defsubr (&Sx_synchronize);
4300 #endif /* HAVE_X_WINDOWS */