(sys_signal): Use 0, not NULL, to set sa_flags.
[bpt/emacs.git] / src / xfns.c
CommitLineData
01f1ba30 1/* Functions for the X window system.
cf177271 2 Copyright (C) 1989, 1992, 1993 Free Software Foundation.
01f1ba30
JB
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
1113d9db 8the Free Software Foundation; either version 2, or (at your option)
01f1ba30
JB
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20/* Completely rewritten by Richard Stallman. */
21
22/* Rewritten for X11 by Joseph Arceneaux */
23
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"
f676886a 31#include "frame.h"
01f1ba30
JB
32#include "window.h"
33#include "buffer.h"
34#include "dispextern.h"
1f98fa48 35#include "keyboard.h"
9ac0d9e0 36#include "blockinput.h"
01f1ba30
JB
37
38#ifdef HAVE_X_WINDOWS
39extern void abort ();
40
0a93081c 41#ifndef VMS
dbc4e1c1 42#include <X11/bitmaps/gray>
0a93081c
JB
43#else
44#include "[.bitmaps]gray.xbm"
45#endif
dbc4e1c1 46
01f1ba30
JB
47#define min(a,b) ((a) < (b) ? (a) : (b))
48#define max(a,b) ((a) > (b) ? (a) : (b))
49
50#ifdef HAVE_X11
51/* X Resource data base */
52static XrmDatabase xrdb;
53
54/* The class of this X application. */
55#define EMACS_CLASS "Emacs"
56
ac63d3d6
JB
57/* The name we're using for this X application. */
58Lisp_Object Vxrdb_name;
59
01f1ba30 60/* Title name and application name for X stuff. */
60fb3ee1 61extern char *x_id_name;
01f1ba30
JB
62
63/* The background and shape of the mouse pointer, and shape when not
64 over text or in the modeline. */
65Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
66
67/* Color of chars displayed in cursor box. */
68Lisp_Object Vx_cursor_fore_pixel;
69
41beb8fc
RS
70/* The screen being used. */
71static Screen *x_screen;
72
01f1ba30
JB
73/* The X Visual we are using for X windows (the default) */
74Visual *screen_visual;
75
01f1ba30
JB
76/* Height of this X screen in pixels. */
77int x_screen_height;
78
01f1ba30
JB
79/* Width of this X screen in pixels. */
80int x_screen_width;
81
01f1ba30
JB
82/* Number of planes for this screen. */
83int x_screen_planes;
84
01f1ba30
JB
85/* Non nil if no window manager is in use. */
86Lisp_Object Vx_no_window_manager;
87
01f1ba30
JB
88/* `t' if a mouse button is depressed. */
89
90Lisp_Object Vmouse_depressed;
91
f370ccb7 92extern unsigned int x_mouse_x, x_mouse_y, x_mouse_grabbed;
f370ccb7 93
01f1ba30 94/* Atom for indicating window state to the window manager. */
99e72068 95extern Atom Xatom_wm_change_state;
01f1ba30 96
3c254570
JA
97/* Communication with window managers. */
98extern Atom Xatom_wm_protocols;
99
100/* Kinds of protocol things we may receive. */
101extern Atom Xatom_wm_take_focus;
102extern Atom Xatom_wm_save_yourself;
103extern Atom Xatom_wm_delete_window;
104
105/* Other WM communication */
c047688c
JA
106extern Atom Xatom_wm_configure_denied; /* When our config request is denied */
107extern Atom Xatom_wm_window_moved; /* When the WM moves us. */
3c254570 108
01f1ba30
JB
109#else /* X10 */
110
179956b9 111/* Default size of an Emacs window. */
01f1ba30
JB
112static char *default_window = "=80x24+0+0";
113
114#define MAXICID 80
115char iconidentity[MAXICID];
116#define ICONTAG "emacs@"
117char minibuffer_iconidentity[MAXICID];
118#define MINIBUFFER_ICONTAG "minibuffer@"
119
120#endif /* X10 */
121
122/* The last 23 bits of the timestamp of the last mouse button event. */
123Time mouse_timestamp;
124
f9942c9e
JB
125/* Evaluate this expression to rebuild the section of syms_of_xfns
126 that initializes and staticpros the symbols declared below. Note
127 that Emacs 18 has a bug that keeps C-x C-e from being able to
128 evaluate this expression.
129
130(progn
131 ;; Accumulate a list of the symbols we want to initialize from the
132 ;; declarations at the top of the file.
133 (goto-char (point-min))
134 (search-forward "/\*&&& symbols declared here &&&*\/\n")
135 (let (symbol-list)
136 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
137 (setq symbol-list
138 (cons (buffer-substring (match-beginning 1) (match-end 1))
139 symbol-list))
140 (forward-line 1))
141 (setq symbol-list (nreverse symbol-list))
142 ;; Delete the section of syms_of_... where we initialize the symbols.
143 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
144 (let ((start (point)))
145 (while (looking-at "^ Q")
146 (forward-line 2))
147 (kill-region start (point)))
148 ;; Write a new symbol initialization section.
149 (while symbol-list
150 (insert (format " %s = intern (\"" (car symbol-list)))
151 (let ((start (point)))
152 (insert (substring (car symbol-list) 1))
153 (subst-char-in-region start (point) ?_ ?-))
154 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
155 (setq symbol-list (cdr symbol-list)))))
156
157 */
158
159/*&&& symbols declared here &&&*/
160Lisp_Object Qauto_raise;
161Lisp_Object Qauto_lower;
162Lisp_Object Qbackground_color;
dbc4e1c1 163Lisp_Object Qbar;
f9942c9e
JB
164Lisp_Object Qborder_color;
165Lisp_Object Qborder_width;
dbc4e1c1 166Lisp_Object Qbox;
f9942c9e 167Lisp_Object Qcursor_color;
dbc4e1c1 168Lisp_Object Qcursor_type;
f9942c9e
JB
169Lisp_Object Qfont;
170Lisp_Object Qforeground_color;
171Lisp_Object Qgeometry;
49795535 172Lisp_Object Qicon;
f9942c9e
JB
173Lisp_Object Qicon_left;
174Lisp_Object Qicon_top;
175Lisp_Object Qicon_type;
f9942c9e
JB
176Lisp_Object Qinternal_border_width;
177Lisp_Object Qleft;
178Lisp_Object Qmouse_color;
baaed68e 179Lisp_Object Qnone;
f9942c9e 180Lisp_Object Qparent_id;
8af1d7ca 181Lisp_Object Qsuppress_icon;
f9942c9e 182Lisp_Object Qtop;
01f1ba30 183Lisp_Object Qundefined_color;
a3c87d4e 184Lisp_Object Qvertical_scroll_bars;
49795535 185Lisp_Object Qvisibility;
f9942c9e 186Lisp_Object Qwindow_id;
f676886a 187Lisp_Object Qx_frame_parameter;
01f1ba30 188
f9942c9e 189/* The below are defined in frame.c. */
baaed68e 190extern Lisp_Object Qheight, Qminibuffer, Qname, Qonly, Qwidth;
d043f1a4 191extern Lisp_Object Qunsplittable, Qmenu_bar_lines, Qicon;
f9942c9e 192
01f1ba30
JB
193extern Lisp_Object Vwindow_system_version;
194
195/* Mouse map for clicks in windows. */
196extern Lisp_Object Vglobal_mouse_map;
197
01f1ba30 198\f
11ae94fe
RS
199/* Error if we are not connected to X. */
200static void
201check_x ()
202{
203 if (x_current_display == 0)
204 error ("X windows are not in use or not initialized");
205}
206
f676886a
JB
207/* Return the Emacs frame-object corresponding to an X window.
208 It could be the frame's main window or an icon window. */
01f1ba30 209
bcb2db92
RS
210/* This function can be called during GC, so use XGCTYPE. */
211
f676886a
JB
212struct frame *
213x_window_to_frame (wdesc)
01f1ba30
JB
214 int wdesc;
215{
f676886a
JB
216 Lisp_Object tail, frame;
217 struct frame *f;
01f1ba30 218
bcb2db92
RS
219 for (tail = Vframe_list; XGCTYPE (tail) == Lisp_Cons;
220 tail = XCONS (tail)->cdr)
01f1ba30 221 {
f676886a 222 frame = XCONS (tail)->car;
bcb2db92 223 if (XGCTYPE (frame) != Lisp_Frame)
01f1ba30 224 continue;
f676886a 225 f = XFRAME (frame);
fe24a618 226 if (FRAME_X_WINDOW (f) == wdesc
f676886a
JB
227 || f->display.x->icon_desc == wdesc)
228 return f;
01f1ba30
JB
229 }
230 return 0;
231}
232
01f1ba30 233\f
f676886a 234/* Connect the frame-parameter names for X frames
01f1ba30
JB
235 to the ways of passing the parameter values to the window system.
236
237 The name of a parameter, as a Lisp symbol,
f676886a
JB
238 has an `x-frame-parameter' property which is an integer in Lisp
239 but can be interpreted as an `enum x_frame_parm' in C. */
01f1ba30 240
f676886a 241enum x_frame_parm
01f1ba30
JB
242{
243 X_PARM_FOREGROUND_COLOR,
244 X_PARM_BACKGROUND_COLOR,
245 X_PARM_MOUSE_COLOR,
246 X_PARM_CURSOR_COLOR,
247 X_PARM_BORDER_COLOR,
248 X_PARM_ICON_TYPE,
249 X_PARM_FONT,
250 X_PARM_BORDER_WIDTH,
251 X_PARM_INTERNAL_BORDER_WIDTH,
252 X_PARM_NAME,
253 X_PARM_AUTORAISE,
254 X_PARM_AUTOLOWER,
a3c87d4e 255 X_PARM_VERT_SCROLL_BAR,
d043f1a4
RS
256 X_PARM_VISIBILITY,
257 X_PARM_MENU_BAR_LINES
01f1ba30
JB
258};
259
260
f676886a 261struct x_frame_parm_table
01f1ba30
JB
262{
263 char *name;
f676886a 264 void (*setter)( /* struct frame *frame, Lisp_Object val, oldval */ );
01f1ba30
JB
265};
266
267void x_set_foreground_color ();
268void x_set_background_color ();
269void x_set_mouse_color ();
270void x_set_cursor_color ();
271void x_set_border_color ();
dbc4e1c1 272void x_set_cursor_type ();
01f1ba30
JB
273void x_set_icon_type ();
274void x_set_font ();
275void x_set_border_width ();
276void x_set_internal_border_width ();
f945b920 277void x_explicitly_set_name ();
01f1ba30
JB
278void x_set_autoraise ();
279void x_set_autolower ();
a3c87d4e 280void x_set_vertical_scroll_bars ();
d043f1a4
RS
281void x_set_visibility ();
282void x_set_menu_bar_lines ();
01f1ba30 283
f676886a 284static struct x_frame_parm_table x_frame_parms[] =
01f1ba30
JB
285{
286 "foreground-color", x_set_foreground_color,
287 "background-color", x_set_background_color,
288 "mouse-color", x_set_mouse_color,
289 "cursor-color", x_set_cursor_color,
290 "border-color", x_set_border_color,
dbc4e1c1 291 "cursor-type", x_set_cursor_type,
01f1ba30
JB
292 "icon-type", x_set_icon_type,
293 "font", x_set_font,
294 "border-width", x_set_border_width,
295 "internal-border-width", x_set_internal_border_width,
f945b920 296 "name", x_explicitly_set_name,
baaed68e
JB
297 "auto-raise", x_set_autoraise,
298 "auto-lower", x_set_autolower,
a3c87d4e 299 "vertical-scroll-bars", x_set_vertical_scroll_bars,
d043f1a4
RS
300 "visibility", x_set_visibility,
301 "menu-bar-lines", x_set_menu_bar_lines,
01f1ba30
JB
302};
303
f676886a 304/* Attach the `x-frame-parameter' properties to
01f1ba30
JB
305 the Lisp symbol names of parameters relevant to X. */
306
307init_x_parm_symbols ()
308{
309 int i;
310
d043f1a4 311 for (i = 0; i < sizeof (x_frame_parms) / sizeof (x_frame_parms[0]); i++)
f676886a 312 Fput (intern (x_frame_parms[i].name), Qx_frame_parameter,
01f1ba30
JB
313 make_number (i));
314}
315\f
f9942c9e
JB
316/* Change the parameters of FRAME as specified by ALIST.
317 If a parameter is not specially recognized, do nothing;
318 otherwise call the `x_set_...' function for that parameter. */
d043f1a4 319
f9942c9e
JB
320void
321x_set_frame_parameters (f, alist)
322 FRAME_PTR f;
323 Lisp_Object alist;
324{
325 Lisp_Object tail;
326
327 /* If both of these parameters are present, it's more efficient to
328 set them both at once. So we wait until we've looked at the
329 entire list before we set them. */
330 Lisp_Object width, height;
331
332 /* Same here. */
333 Lisp_Object left, top;
f9942c9e 334
312b93ee 335 width = height = top = left = Qnil;
f9942c9e
JB
336
337 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
338 {
339 Lisp_Object elt, prop, val;
340
341 elt = Fcar (tail);
342 prop = Fcar (elt);
343 val = Fcdr (elt);
344
312b93ee
JB
345 /* Ignore all but the first set presented. You're supposed to
346 be able to append two parameter lists and have the first
347 shadow the second. */
348 if (EQ (prop, Qwidth) && NILP (width))
f9942c9e 349 width = val;
312b93ee 350 else if (EQ (prop, Qheight) && NILP (height))
f9942c9e 351 height = val;
312b93ee 352 else if (EQ (prop, Qtop) && NILP (top))
f9942c9e 353 top = val;
312b93ee 354 else if (EQ (prop, Qleft) && NILP (left))
f9942c9e
JB
355 left = val;
356 else
357 {
ea96210c
JB
358 register Lisp_Object param_index = Fget (prop, Qx_frame_parameter);
359 register Lisp_Object old_value = get_frame_param (f, prop);
360
f9942c9e 361 store_frame_param (f, prop, val);
ea96210c
JB
362 if (XTYPE (param_index) == Lisp_Int
363 && XINT (param_index) >= 0
364 && (XINT (param_index)
365 < sizeof (x_frame_parms)/sizeof (x_frame_parms[0])))
366 (*x_frame_parms[XINT (param_index)].setter)(f, val, old_value);
f9942c9e
JB
367 }
368 }
369
370 /* Don't call these unless they've changed; the window may not actually
371 exist yet. */
372 {
373 Lisp_Object frame;
374
312b93ee
JB
375 if (NILP (width)) XSET (width, Lisp_Int, FRAME_WIDTH (f));
376 if (NILP (height)) XSET (height, Lisp_Int, FRAME_HEIGHT (f));
377
378 if (NILP (top)) XSET (top, Lisp_Int, f->display.x->top_pos);
379 if (NILP (left)) XSET (left, Lisp_Int, f->display.x->left_pos);
380
f9942c9e
JB
381 XSET (frame, Lisp_Frame, f);
382 if (XINT (width) != FRAME_WIDTH (f)
383 || XINT (height) != FRAME_HEIGHT (f))
384 Fset_frame_size (frame, width, height);
385 if (XINT (left) != f->display.x->left_pos
386 || XINT (top) != f->display.x->top_pos)
387 Fset_frame_position (frame, left, top);
388 }
389}
01f1ba30 390
f676886a 391/* Insert a description of internally-recorded parameters of frame X
01f1ba30
JB
392 into the parameter alist *ALISTPTR that is to be given to the user.
393 Only parameters that are specific to the X window system
f676886a 394 and whose values are not correctly recorded in the frame's
01f1ba30
JB
395 param_alist need to be considered here. */
396
f676886a
JB
397x_report_frame_params (f, alistptr)
398 struct frame *f;
01f1ba30
JB
399 Lisp_Object *alistptr;
400{
401 char buf[16];
402
f9942c9e
JB
403 store_in_alist (alistptr, Qleft, make_number (f->display.x->left_pos));
404 store_in_alist (alistptr, Qtop, make_number (f->display.x->top_pos));
405 store_in_alist (alistptr, Qborder_width,
f676886a 406 make_number (f->display.x->border_width));
f9942c9e 407 store_in_alist (alistptr, Qinternal_border_width,
f676886a 408 make_number (f->display.x->internal_border_width));
fe24a618 409 sprintf (buf, "%d", FRAME_X_WINDOW (f));
f9942c9e 410 store_in_alist (alistptr, Qwindow_id,
01f1ba30 411 build_string (buf));
d043f1a4
RS
412 store_in_alist (alistptr, Qvisibility,
413 (FRAME_VISIBLE_P (f) ? Qt
414 : FRAME_ICONIFIED_P (f) ? Qicon : Qnil));
01f1ba30
JB
415}
416\f
417/* Decide if color named COLOR is valid for the display
f676886a 418 associated with the selected frame. */
01f1ba30
JB
419int
420defined_color (color, color_def)
421 char *color;
422 Color *color_def;
423{
424 register int foo;
425 Colormap screen_colormap;
426
427 BLOCK_INPUT;
428#ifdef HAVE_X11
429 screen_colormap
430 = DefaultColormap (x_current_display, XDefaultScreen (x_current_display));
431
432 foo = XParseColor (x_current_display, screen_colormap,
433 color, color_def)
434 && XAllocColor (x_current_display, screen_colormap, color_def);
435#else
436 foo = XParseColor (color, color_def) && XGetHardwareColor (color_def);
437#endif /* not HAVE_X11 */
438 UNBLOCK_INPUT;
439
440 if (foo)
441 return 1;
442 else
443 return 0;
444}
445
446/* Given a string ARG naming a color, compute a pixel value from it
f676886a
JB
447 suitable for screen F.
448 If F is not a color screen, return DEF (default) regardless of what
01f1ba30
JB
449 ARG says. */
450
451int
452x_decode_color (arg, def)
453 Lisp_Object arg;
454 int def;
455{
456 Color cdef;
457
458 CHECK_STRING (arg, 0);
459
460 if (strcmp (XSTRING (arg)->data, "black") == 0)
461 return BLACK_PIX_DEFAULT;
462 else if (strcmp (XSTRING (arg)->data, "white") == 0)
463 return WHITE_PIX_DEFAULT;
464
465#ifdef HAVE_X11
a6605e5c 466 if (x_screen_planes == 1)
01f1ba30
JB
467 return def;
468#else
265a9e55 469 if (DISPLAY_CELLS == 1)
01f1ba30
JB
470 return def;
471#endif
472
473 if (defined_color (XSTRING (arg)->data, &cdef))
474 return cdef.pixel;
475 else
476 Fsignal (Qundefined_color, Fcons (arg, Qnil));
477}
478\f
f676886a 479/* Functions called only from `x_set_frame_param'
01f1ba30
JB
480 to set individual parameters.
481
fe24a618 482 If FRAME_X_WINDOW (f) is 0,
f676886a 483 the frame is being created and its X-window does not exist yet.
01f1ba30
JB
484 In that case, just record the parameter's new value
485 in the standard place; do not attempt to change the window. */
486
487void
f676886a
JB
488x_set_foreground_color (f, arg, oldval)
489 struct frame *f;
01f1ba30
JB
490 Lisp_Object arg, oldval;
491{
f676886a 492 f->display.x->foreground_pixel = x_decode_color (arg, BLACK_PIX_DEFAULT);
fe24a618 493 if (FRAME_X_WINDOW (f) != 0)
01f1ba30
JB
494 {
495#ifdef HAVE_X11
496 BLOCK_INPUT;
f676886a
JB
497 XSetForeground (x_current_display, f->display.x->normal_gc,
498 f->display.x->foreground_pixel);
499 XSetBackground (x_current_display, f->display.x->reverse_gc,
500 f->display.x->foreground_pixel);
01f1ba30
JB
501 UNBLOCK_INPUT;
502#endif /* HAVE_X11 */
ea96210c 503 recompute_basic_faces (f);
179956b9 504 if (FRAME_VISIBLE_P (f))
f676886a 505 redraw_frame (f);
01f1ba30
JB
506 }
507}
508
509void
f676886a
JB
510x_set_background_color (f, arg, oldval)
511 struct frame *f;
01f1ba30
JB
512 Lisp_Object arg, oldval;
513{
514 Pixmap temp;
515 int mask;
516
f676886a 517 f->display.x->background_pixel = x_decode_color (arg, WHITE_PIX_DEFAULT);
01f1ba30 518
fe24a618 519 if (FRAME_X_WINDOW (f) != 0)
01f1ba30
JB
520 {
521 BLOCK_INPUT;
522#ifdef HAVE_X11
f676886a
JB
523 /* The main frame area. */
524 XSetBackground (x_current_display, f->display.x->normal_gc,
525 f->display.x->background_pixel);
526 XSetForeground (x_current_display, f->display.x->reverse_gc,
527 f->display.x->background_pixel);
fe24a618 528 XSetWindowBackground (x_current_display, FRAME_X_WINDOW (f),
f676886a 529 f->display.x->background_pixel);
01f1ba30 530
01f1ba30 531#else
f676886a 532 temp = XMakeTile (f->display.x->background_pixel);
fe24a618 533 XChangeBackground (FRAME_X_WINDOW (f), temp);
01f1ba30
JB
534 XFreePixmap (temp);
535#endif /* not HAVE_X11 */
536 UNBLOCK_INPUT;
537
ea96210c
JB
538 recompute_basic_faces (f);
539
179956b9 540 if (FRAME_VISIBLE_P (f))
f676886a 541 redraw_frame (f);
01f1ba30
JB
542 }
543}
544
545void
f676886a
JB
546x_set_mouse_color (f, arg, oldval)
547 struct frame *f;
01f1ba30
JB
548 Lisp_Object arg, oldval;
549{
550 Cursor cursor, nontext_cursor, mode_cursor;
551 int mask_color;
552
553 if (!EQ (Qnil, arg))
f676886a
JB
554 f->display.x->mouse_pixel = x_decode_color (arg, BLACK_PIX_DEFAULT);
555 mask_color = f->display.x->background_pixel;
01f1ba30 556 /* No invisible pointers. */
f676886a
JB
557 if (mask_color == f->display.x->mouse_pixel
558 && mask_color == f->display.x->background_pixel)
559 f->display.x->mouse_pixel = f->display.x->foreground_pixel;
01f1ba30
JB
560
561 BLOCK_INPUT;
562#ifdef HAVE_X11
fe24a618
JB
563
564 /* It's not okay to crash if the user selects a screwey cursor. */
565 x_catch_errors ();
566
01f1ba30
JB
567 if (!EQ (Qnil, Vx_pointer_shape))
568 {
569 CHECK_NUMBER (Vx_pointer_shape, 0);
570 cursor = XCreateFontCursor (x_current_display, XINT (Vx_pointer_shape));
571 }
572 else
573 cursor = XCreateFontCursor (x_current_display, XC_xterm);
a6605e5c 574 x_check_errors ("bad text pointer cursor: %s");
01f1ba30
JB
575
576 if (!EQ (Qnil, Vx_nontext_pointer_shape))
577 {
578 CHECK_NUMBER (Vx_nontext_pointer_shape, 0);
579 nontext_cursor = XCreateFontCursor (x_current_display,
580 XINT (Vx_nontext_pointer_shape));
581 }
582 else
583 nontext_cursor = XCreateFontCursor (x_current_display, XC_left_ptr);
a6605e5c 584 x_check_errors ("bad nontext pointer cursor: %s");
01f1ba30
JB
585
586 if (!EQ (Qnil, Vx_mode_pointer_shape))
587 {
588 CHECK_NUMBER (Vx_mode_pointer_shape, 0);
589 mode_cursor = XCreateFontCursor (x_current_display,
590 XINT (Vx_mode_pointer_shape));
591 }
592 else
593 mode_cursor = XCreateFontCursor (x_current_display, XC_xterm);
594
fe24a618
JB
595 /* Check and report errors with the above calls. */
596 x_check_errors ("can't set cursor shape: %s");
597 x_uncatch_errors ();
598
01f1ba30
JB
599 {
600 XColor fore_color, back_color;
601
f676886a 602 fore_color.pixel = f->display.x->mouse_pixel;
01f1ba30
JB
603 back_color.pixel = mask_color;
604 XQueryColor (x_current_display,
605 DefaultColormap (x_current_display,
606 DefaultScreen (x_current_display)),
607 &fore_color);
608 XQueryColor (x_current_display,
609 DefaultColormap (x_current_display,
610 DefaultScreen (x_current_display)),
611 &back_color);
612 XRecolorCursor (x_current_display, cursor,
613 &fore_color, &back_color);
614 XRecolorCursor (x_current_display, nontext_cursor,
615 &fore_color, &back_color);
616 XRecolorCursor (x_current_display, mode_cursor,
617 &fore_color, &back_color);
618 }
619#else /* X10 */
620 cursor = XCreateCursor (16, 16, MouseCursor, MouseMask,
621 0, 0,
f676886a
JB
622 f->display.x->mouse_pixel,
623 f->display.x->background_pixel,
01f1ba30
JB
624 GXcopy);
625#endif /* X10 */
626
fe24a618 627 if (FRAME_X_WINDOW (f) != 0)
01f1ba30 628 {
fe24a618 629 XDefineCursor (XDISPLAY FRAME_X_WINDOW (f), cursor);
01f1ba30
JB
630 }
631
f676886a
JB
632 if (cursor != f->display.x->text_cursor && f->display.x->text_cursor != 0)
633 XFreeCursor (XDISPLAY f->display.x->text_cursor);
634 f->display.x->text_cursor = cursor;
01f1ba30 635#ifdef HAVE_X11
f676886a
JB
636 if (nontext_cursor != f->display.x->nontext_cursor
637 && f->display.x->nontext_cursor != 0)
638 XFreeCursor (XDISPLAY f->display.x->nontext_cursor);
639 f->display.x->nontext_cursor = nontext_cursor;
640
641 if (mode_cursor != f->display.x->modeline_cursor
642 && f->display.x->modeline_cursor != 0)
643 XFreeCursor (XDISPLAY f->display.x->modeline_cursor);
644 f->display.x->modeline_cursor = mode_cursor;
01f1ba30
JB
645#endif /* HAVE_X11 */
646
647 XFlushQueue ();
648 UNBLOCK_INPUT;
649}
650
651void
f676886a
JB
652x_set_cursor_color (f, arg, oldval)
653 struct frame *f;
01f1ba30
JB
654 Lisp_Object arg, oldval;
655{
656 unsigned long fore_pixel;
657
658 if (!EQ (Vx_cursor_fore_pixel, Qnil))
659 fore_pixel = x_decode_color (Vx_cursor_fore_pixel, WHITE_PIX_DEFAULT);
660 else
f676886a
JB
661 fore_pixel = f->display.x->background_pixel;
662 f->display.x->cursor_pixel = x_decode_color (arg, BLACK_PIX_DEFAULT);
f9942c9e
JB
663
664 /* Make sure that the cursor color differs from the background color. */
f676886a 665 if (f->display.x->cursor_pixel == f->display.x->background_pixel)
01f1ba30 666 {
f676886a
JB
667 f->display.x->cursor_pixel == f->display.x->mouse_pixel;
668 if (f->display.x->cursor_pixel == fore_pixel)
669 fore_pixel = f->display.x->background_pixel;
01f1ba30 670 }
c49cbce2 671 f->display.x->cursor_foreground_pixel = fore_pixel;
01f1ba30 672
fe24a618 673 if (FRAME_X_WINDOW (f) != 0)
01f1ba30
JB
674 {
675#ifdef HAVE_X11
676 BLOCK_INPUT;
f676886a
JB
677 XSetBackground (x_current_display, f->display.x->cursor_gc,
678 f->display.x->cursor_pixel);
679 XSetForeground (x_current_display, f->display.x->cursor_gc,
01f1ba30
JB
680 fore_pixel);
681 UNBLOCK_INPUT;
682#endif /* HAVE_X11 */
683
179956b9 684 if (FRAME_VISIBLE_P (f))
01f1ba30 685 {
f676886a
JB
686 x_display_cursor (f, 0);
687 x_display_cursor (f, 1);
01f1ba30
JB
688 }
689 }
690}
691
f676886a 692/* Set the border-color of frame F to value described by ARG.
01f1ba30
JB
693 ARG can be a string naming a color.
694 The border-color is used for the border that is drawn by the X server.
695 Note that this does not fully take effect if done before
f676886a 696 F has an x-window; it must be redone when the window is created.
01f1ba30
JB
697
698 Note: this is done in two routines because of the way X10 works.
699
700 Note: under X11, this is normally the province of the window manager,
701 and so emacs' border colors may be overridden. */
702
703void
f676886a
JB
704x_set_border_color (f, arg, oldval)
705 struct frame *f;
01f1ba30
JB
706 Lisp_Object arg, oldval;
707{
708 unsigned char *str;
709 int pix;
710
711 CHECK_STRING (arg, 0);
712 str = XSTRING (arg)->data;
713
714#ifndef HAVE_X11
715 if (!strcmp (str, "grey") || !strcmp (str, "Grey")
716 || !strcmp (str, "gray") || !strcmp (str, "Gray"))
717 pix = -1;
718 else
719#endif /* X10 */
720
721 pix = x_decode_color (arg, BLACK_PIX_DEFAULT);
722
f676886a 723 x_set_border_pixel (f, pix);
01f1ba30
JB
724}
725
f676886a 726/* Set the border-color of frame F to pixel value PIX.
01f1ba30 727 Note that this does not fully take effect if done before
f676886a 728 F has an x-window. */
01f1ba30 729
f676886a
JB
730x_set_border_pixel (f, pix)
731 struct frame *f;
01f1ba30
JB
732 int pix;
733{
f676886a 734 f->display.x->border_pixel = pix;
01f1ba30 735
fe24a618 736 if (FRAME_X_WINDOW (f) != 0 && f->display.x->border_width > 0)
01f1ba30
JB
737 {
738 Pixmap temp;
739 int mask;
740
741 BLOCK_INPUT;
742#ifdef HAVE_X11
fe24a618 743 XSetWindowBorder (x_current_display, FRAME_X_WINDOW (f),
01f1ba30 744 pix);
01f1ba30
JB
745#else
746 if (pix < 0)
dbc4e1c1
JB
747 temp = XMakePixmap ((Bitmap) XStoreBitmap (gray_width, gray_height,
748 gray_bits),
01f1ba30
JB
749 BLACK_PIX_DEFAULT, WHITE_PIX_DEFAULT);
750 else
751 temp = XMakeTile (pix);
fe24a618 752 XChangeBorder (FRAME_X_WINDOW (f), temp);
01f1ba30
JB
753 XFreePixmap (XDISPLAY temp);
754#endif /* not HAVE_X11 */
755 UNBLOCK_INPUT;
756
179956b9 757 if (FRAME_VISIBLE_P (f))
f676886a 758 redraw_frame (f);
01f1ba30
JB
759 }
760}
761
dbc4e1c1
JB
762void
763x_set_cursor_type (f, arg, oldval)
764 FRAME_PTR f;
765 Lisp_Object arg, oldval;
766{
767 if (EQ (arg, Qbar))
768 FRAME_DESIRED_CURSOR (f) = bar_cursor;
15ab234b
RS
769 else
770#if 0
771 if (EQ (arg, Qbox))
772#endif
773 FRAME_DESIRED_CURSOR (f) = filled_box_cursor;
774 /* Error messages commented out because people have trouble fixing
775 .Xdefaults with Emacs, when it has something bad in it. */
776#if 0
dbc4e1c1
JB
777 else
778 error
779 ("the `cursor-type' frame parameter should be either `bar' or `box'");
15ab234b 780#endif
dbc4e1c1
JB
781
782 /* Make sure the cursor gets redrawn. This is overkill, but how
783 often do people change cursor types? */
784 update_mode_lines++;
785}
786
01f1ba30 787void
f676886a
JB
788x_set_icon_type (f, arg, oldval)
789 struct frame *f;
01f1ba30
JB
790 Lisp_Object arg, oldval;
791{
792 Lisp_Object tem;
793 int result;
794
795 if (EQ (oldval, Qnil) == EQ (arg, Qnil))
796 return;
797
798 BLOCK_INPUT;
265a9e55 799 if (NILP (arg))
f676886a 800 result = x_text_icon (f, 0);
01f1ba30 801 else
f111a131 802 result = x_bitmap_icon (f);
01f1ba30
JB
803
804 if (result)
805 {
01f1ba30 806 UNBLOCK_INPUT;
f9942c9e 807 error ("No icon window available.");
01f1ba30
JB
808 }
809
810 /* If the window was unmapped (and its icon was mapped),
811 the new icon is not mapped, so map the window in its stead. */
179956b9 812 if (FRAME_VISIBLE_P (f))
fe24a618 813 XMapWindow (XDISPLAY FRAME_X_WINDOW (f));
01f1ba30
JB
814
815 XFlushQueue ();
816 UNBLOCK_INPUT;
817}
818
ea96210c
JB
819extern Lisp_Object x_new_font ();
820
01f1ba30 821void
f676886a
JB
822x_set_font (f, arg, oldval)
823 struct frame *f;
01f1ba30
JB
824 Lisp_Object arg, oldval;
825{
ea96210c 826 Lisp_Object result;
01f1ba30
JB
827
828 CHECK_STRING (arg, 1);
01f1ba30
JB
829
830 BLOCK_INPUT;
ea96210c 831 result = x_new_font (f, XSTRING (arg)->data);
01f1ba30
JB
832 UNBLOCK_INPUT;
833
ea96210c
JB
834 if (EQ (result, Qnil))
835 error ("Font \"%s\" is not defined", XSTRING (arg)->data);
836 else if (EQ (result, Qt))
c7e1d890 837 error ("the characters of the given font have varying widths");
ea96210c
JB
838 else if (STRINGP (result))
839 {
840 recompute_basic_faces (f);
841 store_frame_param (f, Qfont, result);
842 }
843 else
844 abort ();
01f1ba30
JB
845}
846
847void
f676886a
JB
848x_set_border_width (f, arg, oldval)
849 struct frame *f;
01f1ba30
JB
850 Lisp_Object arg, oldval;
851{
852 CHECK_NUMBER (arg, 0);
853
f676886a 854 if (XINT (arg) == f->display.x->border_width)
01f1ba30
JB
855 return;
856
fe24a618 857 if (FRAME_X_WINDOW (f) != 0)
01f1ba30
JB
858 error ("Cannot change the border width of a window");
859
f676886a 860 f->display.x->border_width = XINT (arg);
01f1ba30
JB
861}
862
863void
f676886a
JB
864x_set_internal_border_width (f, arg, oldval)
865 struct frame *f;
01f1ba30
JB
866 Lisp_Object arg, oldval;
867{
868 int mask;
f676886a 869 int old = f->display.x->internal_border_width;
01f1ba30
JB
870
871 CHECK_NUMBER (arg, 0);
f676886a
JB
872 f->display.x->internal_border_width = XINT (arg);
873 if (f->display.x->internal_border_width < 0)
874 f->display.x->internal_border_width = 0;
01f1ba30 875
f676886a 876 if (f->display.x->internal_border_width == old)
01f1ba30
JB
877 return;
878
fe24a618 879 if (FRAME_X_WINDOW (f) != 0)
01f1ba30
JB
880 {
881 BLOCK_INPUT;
f676886a 882 x_set_window_size (f, f->width, f->height);
01f1ba30 883#if 0
f676886a 884 x_set_resize_hint (f);
01f1ba30
JB
885#endif
886 XFlushQueue ();
887 UNBLOCK_INPUT;
f676886a 888 SET_FRAME_GARBAGED (f);
01f1ba30
JB
889 }
890}
891
d043f1a4
RS
892void
893x_set_visibility (f, value, oldval)
894 struct frame *f;
895 Lisp_Object value, oldval;
896{
897 Lisp_Object frame;
898 XSET (frame, Lisp_Frame, f);
899
900 if (NILP (value))
901 Fmake_frame_invisible (frame);
49795535 902 else if (EQ (value, Qicon))
d043f1a4 903 Ficonify_frame (frame);
49795535
JB
904 else
905 Fmake_frame_visible (frame);
d043f1a4
RS
906}
907
908static void
909x_set_menu_bar_lines_1 (window, n)
910 Lisp_Object window;
911 int n;
912{
913 for (; !NILP (window); window = XWINDOW (window)->next)
914 {
915 struct window *w = XWINDOW (window);
916
11ae94fe 917 XFASTINT (w->top) += n;
d043f1a4
RS
918
919 if (!NILP (w->vchild))
11ae94fe 920 x_set_menu_bar_lines_1 (w->vchild, n);
d043f1a4
RS
921
922 if (!NILP (w->hchild))
11ae94fe 923 x_set_menu_bar_lines_1 (w->hchild, n);
d043f1a4
RS
924 }
925}
926
927void
928x_set_menu_bar_lines (f, value, oldval)
929 struct frame *f;
930 Lisp_Object value, oldval;
931{
932 int nlines;
933 int olines = FRAME_MENU_BAR_LINES (f);
934
f64ba6ea
JB
935 /* Right now, menu bars don't work properly in minibuf-only frames;
936 most of the commands try to apply themselves to the minibuffer
937 frame itslef, and get an error because you can't switch buffers
938 in or split the minibuffer window. */
519066d2 939 if (FRAME_MINIBUF_ONLY_P (f))
f64ba6ea
JB
940 return;
941
d043f1a4
RS
942 if (XTYPE (value) == Lisp_Int)
943 nlines = XINT (value);
944 else
945 nlines = 0;
946
947 FRAME_MENU_BAR_LINES (f) = nlines;
948 x_set_menu_bar_lines_1 (f->root_window, nlines - olines);
949 x_set_window_size (f, FRAME_WIDTH (f),
950 FRAME_HEIGHT (f) + nlines - olines);
951}
952
f945b920
JB
953/* Change the name of frame F to ARG. If ARG is nil, set F's name to
954 x_id_name.
955
956 If EXPLICIT is non-zero, that indicates that lisp code is setting the
957 name; if ARG is a string, set F's name to ARG and set
958 F->explicit_name; if ARG is Qnil, then clear F->explicit_name.
959
960 If EXPLICIT is zero, that indicates that Emacs redisplay code is
961 suggesting a new name, which lisp code should override; if
962 F->explicit_name is set, ignore the new name; otherwise, set it. */
963
964void
965x_set_name (f, name, explicit)
966 struct frame *f;
967 Lisp_Object name;
968 int explicit;
969{
970 /* Make sure that requests from lisp code override requests from
971 Emacs redisplay code. */
972 if (explicit)
973 {
974 /* If we're switching from explicit to implicit, we had better
975 update the mode lines and thereby update the title. */
976 if (f->explicit_name && NILP (name))
cf177271 977 update_mode_lines = 1;
f945b920
JB
978
979 f->explicit_name = ! NILP (name);
980 }
981 else if (f->explicit_name)
982 return;
983
984 /* If NAME is nil, set the name to the x_id_name. */
985 if (NILP (name))
986 name = build_string (x_id_name);
62265f1c 987 else
f945b920 988 CHECK_STRING (name, 0);
01f1ba30 989
f945b920
JB
990 /* Don't change the name if it's already NAME. */
991 if (! NILP (Fstring_equal (name, f->name)))
daa37602
JB
992 return;
993
fe24a618 994 if (FRAME_X_WINDOW (f))
01f1ba30 995 {
01f1ba30 996 BLOCK_INPUT;
fe24a618
JB
997
998#ifdef HAVE_X11R4
999 {
1000 XTextProperty text;
1001 text.value = XSTRING (name)->data;
1002 text.encoding = XA_STRING;
1003 text.format = 8;
1004 text.nitems = XSTRING (name)->size;
1005 XSetWMName (x_current_display, FRAME_X_WINDOW (f), &text);
1006 XSetWMIconName (x_current_display, FRAME_X_WINDOW (f), &text);
1007 }
1008#else
1009 XSetIconName (XDISPLAY FRAME_X_WINDOW (f),
1010 XSTRING (name)->data);
1011 XStoreName (XDISPLAY FRAME_X_WINDOW (f),
1012 XSTRING (name)->data);
1013#endif
1014
01f1ba30
JB
1015 UNBLOCK_INPUT;
1016 }
daa37602 1017
f945b920
JB
1018 f->name = name;
1019}
1020
1021/* This function should be called when the user's lisp code has
1022 specified a name for the frame; the name will override any set by the
1023 redisplay code. */
1024void
1025x_explicitly_set_name (f, arg, oldval)
1026 FRAME_PTR f;
1027 Lisp_Object arg, oldval;
1028{
1029 x_set_name (f, arg, 1);
1030}
1031
1032/* This function should be called by Emacs redisplay code to set the
1033 name; names set this way will never override names set by the user's
1034 lisp code. */
25250031 1035void
f945b920
JB
1036x_implicitly_set_name (f, arg, oldval)
1037 FRAME_PTR f;
1038 Lisp_Object arg, oldval;
1039{
1040 x_set_name (f, arg, 0);
01f1ba30
JB
1041}
1042
1043void
f676886a
JB
1044x_set_autoraise (f, arg, oldval)
1045 struct frame *f;
01f1ba30
JB
1046 Lisp_Object arg, oldval;
1047{
f676886a 1048 f->auto_raise = !EQ (Qnil, arg);
01f1ba30
JB
1049}
1050
1051void
f676886a
JB
1052x_set_autolower (f, arg, oldval)
1053 struct frame *f;
01f1ba30
JB
1054 Lisp_Object arg, oldval;
1055{
f676886a 1056 f->auto_lower = !EQ (Qnil, arg);
01f1ba30 1057}
179956b9
JB
1058
1059void
a3c87d4e 1060x_set_vertical_scroll_bars (f, arg, oldval)
179956b9
JB
1061 struct frame *f;
1062 Lisp_Object arg, oldval;
1063{
a3c87d4e 1064 if (NILP (arg) != ! FRAME_HAS_VERTICAL_SCROLL_BARS (f))
179956b9 1065 {
a3c87d4e 1066 FRAME_HAS_VERTICAL_SCROLL_BARS (f) = ! NILP (arg);
179956b9 1067
cf177271
JB
1068 /* We set this parameter before creating the X window for the
1069 frame, so we can get the geometry right from the start.
1070 However, if the window hasn't been created yet, we shouldn't
1071 call x_set_window_size. */
1072 if (FRAME_X_WINDOW (f))
1073 x_set_window_size (f, FRAME_WIDTH (f), FRAME_HEIGHT (f));
179956b9
JB
1074 }
1075}
01f1ba30 1076\f
f676886a 1077/* Subroutines of creating an X frame. */
01f1ba30
JB
1078
1079#ifdef HAVE_X11
1080extern char *x_get_string_resource ();
1081extern XrmDatabase x_load_resources ();
1082
cf177271
JB
1083DEFUN ("x-get-resource", Fx_get_resource, Sx_get_resource, 2, 4, 0,
1084 "Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.\n\
1085This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the\n\
1086class, where INSTANCE is the name under which Emacs was invoked.\n\
01f1ba30 1087\n\
8fabe6f4
RS
1088The optional arguments COMPONENT and SUBCLASS add to the key and the\n\
1089class, respectively. You must specify both of them or neither.\n\
1090If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'\n\
cf177271
JB
1091and the class is `Emacs.CLASS.SUBCLASS'.")
1092 (attribute, class, component, subclass)
1093 Lisp_Object attribute, class, component, subclass;
01f1ba30
JB
1094{
1095 register char *value;
1096 char *name_key;
1097 char *class_key;
1098
11ae94fe
RS
1099 check_x ();
1100
01f1ba30 1101 CHECK_STRING (attribute, 0);
cf177271
JB
1102 CHECK_STRING (class, 0);
1103
8fabe6f4
RS
1104 if (!NILP (component))
1105 CHECK_STRING (component, 1);
1106 if (!NILP (subclass))
1107 CHECK_STRING (subclass, 2);
1108 if (NILP (component) != NILP (subclass))
1109 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
1110
1111 if (NILP (component))
01f1ba30 1112 {
cf177271
JB
1113 /* Allocate space for the components, the dots which separate them,
1114 and the final '\0'. */
ac63d3d6 1115 name_key = (char *) alloca (XSTRING (Vxrdb_name)->size
cf177271
JB
1116 + XSTRING (attribute)->size
1117 + 2);
1118 class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
1119 + XSTRING (class)->size
1120 + 2);
60fb3ee1 1121
01f1ba30 1122 sprintf (name_key, "%s.%s",
ac63d3d6 1123 XSTRING (Vxrdb_name)->data,
01f1ba30 1124 XSTRING (attribute)->data);
cf177271
JB
1125 sprintf (class_key, "%s.%s",
1126 EMACS_CLASS,
1127 XSTRING (class)->data);
01f1ba30
JB
1128 }
1129 else
1130 {
ac63d3d6 1131 name_key = (char *) alloca (XSTRING (Vxrdb_name)->size
cf177271
JB
1132 + XSTRING (component)->size
1133 + XSTRING (attribute)->size
1134 + 3);
60fb3ee1 1135
cf177271
JB
1136 class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
1137 + XSTRING (class)->size
1138 + XSTRING (subclass)->size
1139 + 3);
01f1ba30
JB
1140
1141 sprintf (name_key, "%s.%s.%s",
ac63d3d6 1142 XSTRING (Vxrdb_name)->data,
8fabe6f4 1143 XSTRING (component)->data,
01f1ba30 1144 XSTRING (attribute)->data);
ac63d3d6 1145 sprintf (class_key, "%s.%s.%s",
cf177271
JB
1146 EMACS_CLASS,
1147 XSTRING (class)->data,
1148 XSTRING (subclass)->data);
01f1ba30
JB
1149 }
1150
1151 value = x_get_string_resource (xrdb, name_key, class_key);
1152
1153 if (value != (char *) 0)
1154 return build_string (value);
1155 else
1156 return Qnil;
1157}
1158
3402e1a4
RS
1159/* Used when C code wants a resource value. */
1160
1161char *
1162x_get_resource_string (attribute, class)
1163 char *attribute, *class;
1164{
1165 register char *value;
1166 char *name_key;
1167 char *class_key;
1168
1169 /* Allocate space for the components, the dots which separate them,
1170 and the final '\0'. */
1171 name_key = (char *) alloca (XSTRING (Vinvocation_name)->size
1172 + strlen (attribute) + 2);
1173 class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
1174 + strlen (class) + 2);
1175
1176 sprintf (name_key, "%s.%s",
1177 XSTRING (Vinvocation_name)->data,
1178 attribute);
1179 sprintf (class_key, "%s.%s", EMACS_CLASS, class);
1180
1181 return x_get_string_resource (xrdb, name_key, class_key);
1182}
1183
01f1ba30
JB
1184#else /* X10 */
1185
60fb3ee1 1186DEFUN ("x-get-default", Fx_get_default, Sx_get_default, 1, 1, 0,
f9942c9e 1187 "Get X default ATTRIBUTE from the system, or nil if no default.\n\
01f1ba30
JB
1188Value is a string (when not nil) and ATTRIBUTE is also a string.\n\
1189The defaults are specified in the file `~/.Xdefaults'.")
60fb3ee1
JB
1190 (arg)
1191 Lisp_Object arg;
01f1ba30
JB
1192{
1193 register unsigned char *value;
1194
1195 CHECK_STRING (arg, 1);
1196
1197 value = (unsigned char *) XGetDefault (XDISPLAY
59653951 1198 XSTRING (Vinvocation_name)->data,
01f1ba30
JB
1199 XSTRING (arg)->data);
1200 if (value == 0)
1201 /* Try reversing last two args, in case this is the buggy version of X. */
1202 value = (unsigned char *) XGetDefault (XDISPLAY
1203 XSTRING (arg)->data,
59653951 1204 XSTRING (Vinvocation_name)->data);
01f1ba30
JB
1205 if (value != 0)
1206 return build_string (value);
1207 else
1208 return (Qnil);
1209}
1210
cf177271
JB
1211#define Fx_get_resource(attribute, class, component, subclass) \
1212 Fx_get_default(attribute)
01f1ba30
JB
1213
1214#endif /* X10 */
1215
60fb3ee1
JB
1216/* Types we might convert a resource string into. */
1217enum resource_types
1218 {
f945b920 1219 number, boolean, string, symbol,
60fb3ee1
JB
1220 };
1221
01f1ba30 1222/* Return the value of parameter PARAM.
60fb3ee1 1223
f676886a 1224 First search ALIST, then Vdefault_frame_alist, then the X defaults
cf177271 1225 database, using ATTRIBUTE as the attribute name and CLASS as its class.
60fb3ee1
JB
1226
1227 Convert the resource to the type specified by desired_type.
1228
f9942c9e
JB
1229 If no default is specified, return Qunbound. If you call
1230 x_get_arg, make sure you deal with Qunbound in a reasonable way,
1231 and don't let it get stored in any lisp-visible variables! */
01f1ba30
JB
1232
1233static Lisp_Object
cf177271 1234x_get_arg (alist, param, attribute, class, type)
3c254570 1235 Lisp_Object alist, param;
60fb3ee1 1236 char *attribute;
cf177271 1237 char *class;
60fb3ee1 1238 enum resource_types type;
01f1ba30
JB
1239{
1240 register Lisp_Object tem;
1241
1242 tem = Fassq (param, alist);
1243 if (EQ (tem, Qnil))
f676886a 1244 tem = Fassq (param, Vdefault_frame_alist);
f9942c9e 1245 if (EQ (tem, Qnil))
01f1ba30 1246 {
60fb3ee1 1247
f9942c9e 1248 if (attribute)
60fb3ee1 1249 {
cf177271
JB
1250 tem = Fx_get_resource (build_string (attribute),
1251 build_string (class),
1252 Qnil, Qnil);
f9942c9e
JB
1253
1254 if (NILP (tem))
1255 return Qunbound;
1256
1257 switch (type)
1258 {
1259 case number:
1260 return make_number (atoi (XSTRING (tem)->data));
1261
1262 case boolean:
1263 tem = Fdowncase (tem);
1264 if (!strcmp (XSTRING (tem)->data, "on")
1265 || !strcmp (XSTRING (tem)->data, "true"))
1266 return Qt;
1267 else
1268 return Qnil;
1269
1270 case string:
1271 return tem;
1272
f945b920 1273 case symbol:
49795535
JB
1274 /* As a special case, we map the values `true' and `on'
1275 to Qt, and `false' and `off' to Qnil. */
1276 {
1277 Lisp_Object lower = Fdowncase (tem);
1278 if (!strcmp (XSTRING (tem)->data, "on")
1279 || !strcmp (XSTRING (tem)->data, "true"))
1280 return Qt;
8bc59570 1281 else if (!strcmp (XSTRING (tem)->data, "off")
49795535
JB
1282 || !strcmp (XSTRING (tem)->data, "false"))
1283 return Qnil;
1284 else
89032215 1285 return Fintern (tem, Qnil);
49795535 1286 }
f945b920 1287
f9942c9e
JB
1288 default:
1289 abort ();
1290 }
60fb3ee1 1291 }
f9942c9e
JB
1292 else
1293 return Qunbound;
01f1ba30
JB
1294 }
1295 return Fcdr (tem);
1296}
1297
f676886a 1298/* Record in frame F the specified or default value according to ALIST
01f1ba30
JB
1299 of the parameter named PARAM (a Lisp symbol).
1300 If no value is specified for PARAM, look for an X default for XPROP
f676886a 1301 on the frame named NAME.
01f1ba30
JB
1302 If that is not found either, use the value DEFLT. */
1303
1304static Lisp_Object
cf177271 1305x_default_parameter (f, alist, prop, deflt, xprop, xclass, type)
f676886a 1306 struct frame *f;
01f1ba30 1307 Lisp_Object alist;
f9942c9e 1308 Lisp_Object prop;
01f1ba30
JB
1309 Lisp_Object deflt;
1310 char *xprop;
cf177271 1311 char *xclass;
60fb3ee1 1312 enum resource_types type;
01f1ba30 1313{
01f1ba30
JB
1314 Lisp_Object tem;
1315
cf177271 1316 tem = x_get_arg (alist, prop, xprop, xclass, type);
f9942c9e 1317 if (EQ (tem, Qunbound))
01f1ba30 1318 tem = deflt;
f9942c9e 1319 x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));
01f1ba30
JB
1320 return tem;
1321}
1322\f
8af1d7ca 1323DEFUN ("x-parse-geometry", Fx_parse_geometry, Sx_parse_geometry, 1, 1, 0,
01f1ba30
JB
1324 "Parse an X-style geometry string STRING.\n\
1325Returns an alist of the form ((top . TOP), (left . LEFT) ... ).")
1326 (string)
a6605e5c 1327 Lisp_Object string;
01f1ba30
JB
1328{
1329 int geometry, x, y;
1330 unsigned int width, height;
1331 Lisp_Object values[4];
1332
1333 CHECK_STRING (string, 0);
1334
1335 geometry = XParseGeometry ((char *) XSTRING (string)->data,
1336 &x, &y, &width, &height);
1337
1338 switch (geometry & 0xf) /* Mask out {X,Y}Negative */
1339 {
1340 case (XValue | YValue):
1341 /* What's one pixel among friends?
1342 Perhaps fix this some day by returning symbol `extreme-top'... */
1343 if (x == 0 && (geometry & XNegative))
1344 x = -1;
1345 if (y == 0 && (geometry & YNegative))
1346 y = -1;
f9942c9e
JB
1347 values[0] = Fcons (Qleft, make_number (x));
1348 values[1] = Fcons (Qtop, make_number (y));
01f1ba30
JB
1349 return Flist (2, values);
1350 break;
1351
1352 case (WidthValue | HeightValue):
f9942c9e
JB
1353 values[0] = Fcons (Qwidth, make_number (width));
1354 values[1] = Fcons (Qheight, make_number (height));
01f1ba30
JB
1355 return Flist (2, values);
1356 break;
1357
1358 case (XValue | YValue | WidthValue | HeightValue):
1359 if (x == 0 && (geometry & XNegative))
1360 x = -1;
1361 if (y == 0 && (geometry & YNegative))
1362 y = -1;
f9942c9e
JB
1363 values[0] = Fcons (Qwidth, make_number (width));
1364 values[1] = Fcons (Qheight, make_number (height));
1365 values[2] = Fcons (Qleft, make_number (x));
1366 values[3] = Fcons (Qtop, make_number (y));
01f1ba30
JB
1367 return Flist (4, values);
1368 break;
1369
1370 case 0:
1371 return Qnil;
1372
1373 default:
1374 error ("Must specify x and y value, and/or width and height");
1375 }
1376}
1377
1378#ifdef HAVE_X11
1379/* Calculate the desired size and position of this window,
1380 or set rubber-band prompting if none. */
1381
1382#define DEFAULT_ROWS 40
1383#define DEFAULT_COLS 80
1384
f9942c9e 1385static int
f676886a
JB
1386x_figure_window_size (f, parms)
1387 struct frame *f;
01f1ba30
JB
1388 Lisp_Object parms;
1389{
1390 register Lisp_Object tem0, tem1;
1391 int height, width, left, top;
1392 register int geometry;
1393 long window_prompting = 0;
1394
1395 /* Default values if we fall through.
1396 Actually, if that happens we should get
1397 window manager prompting. */
f676886a
JB
1398 f->width = DEFAULT_COLS;
1399 f->height = DEFAULT_ROWS;
bd0b85c3
RS
1400 /* Window managers expect that if program-specified
1401 positions are not (0,0), they're intentional, not defaults. */
1402 f->display.x->top_pos = 0;
1403 f->display.x->left_pos = 0;
01f1ba30 1404
cf177271
JB
1405 tem0 = x_get_arg (parms, Qheight, 0, 0, number);
1406 tem1 = x_get_arg (parms, Qwidth, 0, 0, number);
f9942c9e 1407 if (! EQ (tem0, Qunbound) && ! EQ (tem1, Qunbound))
01f1ba30
JB
1408 {
1409 CHECK_NUMBER (tem0, 0);
1410 CHECK_NUMBER (tem1, 0);
f676886a
JB
1411 f->height = XINT (tem0);
1412 f->width = XINT (tem1);
01f1ba30
JB
1413 window_prompting |= USSize;
1414 }
f9942c9e 1415 else if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
01f1ba30
JB
1416 error ("Must specify *both* height and width");
1417
a3c87d4e
JB
1418 f->display.x->vertical_scroll_bar_extra =
1419 (FRAME_HAS_VERTICAL_SCROLL_BARS (f)
1420 ? VERTICAL_SCROLL_BAR_PIXEL_WIDTH (f)
cf177271 1421 : 0);
179956b9
JB
1422 f->display.x->pixel_width = CHAR_TO_PIXEL_WIDTH (f, f->width);
1423 f->display.x->pixel_height = CHAR_TO_PIXEL_HEIGHT (f, f->height);
01f1ba30 1424
cf177271
JB
1425 tem0 = x_get_arg (parms, Qtop, 0, 0, number);
1426 tem1 = x_get_arg (parms, Qleft, 0, 0, number);
f9942c9e 1427 if (! EQ (tem0, Qunbound) && ! EQ (tem1, Qunbound))
01f1ba30
JB
1428 {
1429 CHECK_NUMBER (tem0, 0);
1430 CHECK_NUMBER (tem1, 0);
f676886a
JB
1431 f->display.x->top_pos = XINT (tem0);
1432 f->display.x->left_pos = XINT (tem1);
1433 x_calc_absolute_position (f);
01f1ba30
JB
1434 window_prompting |= USPosition;
1435 }
f9942c9e 1436 else if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
01f1ba30
JB
1437 error ("Must specify *both* top and left corners");
1438
1439 switch (window_prompting)
1440 {
1441 case USSize | USPosition:
1442 return window_prompting;
1443 break;
1444
1445 case USSize: /* Got the size, need the position. */
1446 window_prompting |= PPosition;
1447 return window_prompting;
1448 break;
1449
1450 case USPosition: /* Got the position, need the size. */
1451 window_prompting |= PSize;
1452 return window_prompting;
1453 break;
1454
1455 case 0: /* Got nothing, take both from geometry. */
1456 window_prompting |= PPosition | PSize;
1457 return window_prompting;
1458 break;
1459
1460 default:
1461 /* Somehow a bit got set in window_prompting that we didn't
1462 put there. */
1463 abort ();
1464 }
1465}
1466
1467static void
f676886a
JB
1468x_window (f)
1469 struct frame *f;
01f1ba30
JB
1470{
1471 XSetWindowAttributes attributes;
1472 unsigned long attribute_mask;
1473 XClassHint class_hints;
1474
f676886a
JB
1475 attributes.background_pixel = f->display.x->background_pixel;
1476 attributes.border_pixel = f->display.x->border_pixel;
01f1ba30
JB
1477 attributes.bit_gravity = StaticGravity;
1478 attributes.backing_store = NotUseful;
1479 attributes.save_under = True;
1480 attributes.event_mask = STANDARD_EVENT_SET;
1481 attribute_mask = (CWBackPixel | CWBorderPixel | CWBitGravity
1482#if 0
1483 | CWBackingStore | CWSaveUnder
1484#endif
1485 | CWEventMask);
1486
1487 BLOCK_INPUT;
fe24a618 1488 FRAME_X_WINDOW (f)
01f1ba30 1489 = XCreateWindow (x_current_display, ROOT_WINDOW,
f676886a
JB
1490 f->display.x->left_pos,
1491 f->display.x->top_pos,
1492 PIXEL_WIDTH (f), PIXEL_HEIGHT (f),
1493 f->display.x->border_width,
01f1ba30
JB
1494 CopyFromParent, /* depth */
1495 InputOutput, /* class */
1496 screen_visual, /* set in Fx_open_connection */
1497 attribute_mask, &attributes);
1498
f676886a 1499 class_hints.res_name = (char *) XSTRING (f->name)->data;
01f1ba30 1500 class_hints.res_class = EMACS_CLASS;
fe24a618 1501 XSetClassHint (x_current_display, FRAME_X_WINDOW (f), &class_hints);
01f1ba30 1502
179956b9
JB
1503 /* This indicates that we use the "Passive Input" input model.
1504 Unless we do this, we don't get the Focus{In,Out} events that we
1505 need to draw the cursor correctly. Accursed bureaucrats.
1506 XWhipsAndChains (x_current_display, IronMaiden, &TheRack); */
1507
1508 f->display.x->wm_hints.input = True;
1509 f->display.x->wm_hints.flags |= InputHint;
1510 XSetWMHints (x_current_display, FRAME_X_WINDOW (f), &f->display.x->wm_hints);
1511
e373f201
JB
1512 /* x_set_name normally ignores requests to set the name if the
1513 requested name is the same as the current name. This is the one
1514 place where that assumption isn't correct; f->name is set, but
1515 the X server hasn't been told. */
1516 {
1517 Lisp_Object name = f->name;
cf177271 1518 int explicit = f->explicit_name;
e373f201
JB
1519
1520 f->name = Qnil;
cf177271
JB
1521 f->explicit_name = 0;
1522 x_set_name (f, name, explicit);
e373f201
JB
1523 }
1524
fe24a618 1525 XDefineCursor (XDISPLAY FRAME_X_WINDOW (f),
f676886a 1526 f->display.x->text_cursor);
01f1ba30
JB
1527 UNBLOCK_INPUT;
1528
fe24a618 1529 if (FRAME_X_WINDOW (f) == 0)
01f1ba30
JB
1530 error ("Unable to create window.");
1531}
1532
1533/* Handle the icon stuff for this window. Perhaps later we might
1534 want an x_set_icon_position which can be called interactively as
1535 well. */
1536
1537static void
f676886a
JB
1538x_icon (f, parms)
1539 struct frame *f;
01f1ba30
JB
1540 Lisp_Object parms;
1541{
f9942c9e 1542 Lisp_Object icon_x, icon_y;
01f1ba30
JB
1543
1544 /* Set the position of the icon. Note that twm groups all
1545 icons in an icon window. */
cf177271
JB
1546 icon_x = x_get_arg (parms, Qicon_left, 0, 0, number);
1547 icon_y = x_get_arg (parms, Qicon_top, 0, 0, number);
f9942c9e 1548 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
01f1ba30 1549 {
f9942c9e
JB
1550 CHECK_NUMBER (icon_x, 0);
1551 CHECK_NUMBER (icon_y, 0);
01f1ba30 1552 }
f9942c9e 1553 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
01f1ba30 1554 error ("Both left and top icon corners of icon must be specified");
01f1ba30 1555
f9942c9e
JB
1556 BLOCK_INPUT;
1557
fe24a618
JB
1558 if (! EQ (icon_x, Qunbound))
1559 x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
f9942c9e 1560
01f1ba30 1561 /* Start up iconic or window? */
49795535
JB
1562 x_wm_set_window_state
1563 (f, (EQ (x_get_arg (parms, Qvisibility, 0, 0, symbol), Qicon)
1564 ? IconicState
1565 : NormalState));
01f1ba30 1566
01f1ba30
JB
1567 UNBLOCK_INPUT;
1568}
1569
1570/* Make the GC's needed for this window, setting the
1571 background, border and mouse colors; also create the
1572 mouse cursor and the gray border tile. */
1573
f945b920
JB
1574static char cursor_bits[] =
1575 {
1576 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1577 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1578 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1579 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1580 };
1581
01f1ba30 1582static void
f676886a
JB
1583x_make_gc (f)
1584 struct frame *f;
01f1ba30
JB
1585{
1586 XGCValues gc_values;
1587 GC temp_gc;
1588 XImage tileimage;
01f1ba30 1589
6afb1d07
JB
1590 BLOCK_INPUT;
1591
f676886a 1592 /* Create the GC's of this frame.
01f1ba30
JB
1593 Note that many default values are used. */
1594
1595 /* Normal video */
f676886a
JB
1596 gc_values.font = f->display.x->font->fid;
1597 gc_values.foreground = f->display.x->foreground_pixel;
1598 gc_values.background = f->display.x->background_pixel;
01f1ba30 1599 gc_values.line_width = 0; /* Means 1 using fast algorithm. */
f676886a 1600 f->display.x->normal_gc = XCreateGC (x_current_display,
fe24a618 1601 FRAME_X_WINDOW (f),
01f1ba30
JB
1602 GCLineWidth | GCFont
1603 | GCForeground | GCBackground,
1604 &gc_values);
1605
1606 /* Reverse video style. */
f676886a
JB
1607 gc_values.foreground = f->display.x->background_pixel;
1608 gc_values.background = f->display.x->foreground_pixel;
1609 f->display.x->reverse_gc = XCreateGC (x_current_display,
fe24a618 1610 FRAME_X_WINDOW (f),
01f1ba30
JB
1611 GCFont | GCForeground | GCBackground
1612 | GCLineWidth,
1613 &gc_values);
1614
1615 /* Cursor has cursor-color background, background-color foreground. */
f676886a
JB
1616 gc_values.foreground = f->display.x->background_pixel;
1617 gc_values.background = f->display.x->cursor_pixel;
01f1ba30
JB
1618 gc_values.fill_style = FillOpaqueStippled;
1619 gc_values.stipple
1620 = XCreateBitmapFromData (x_current_display, ROOT_WINDOW,
1621 cursor_bits, 16, 16);
f676886a 1622 f->display.x->cursor_gc
fe24a618 1623 = XCreateGC (x_current_display, FRAME_X_WINDOW (f),
01f1ba30
JB
1624 (GCFont | GCForeground | GCBackground
1625 | GCFillStyle | GCStipple | GCLineWidth),
1626 &gc_values);
1627
1628 /* Create the gray border tile used when the pointer is not in
f676886a
JB
1629 the frame. Since this depends on the frame's pixel values,
1630 this must be done on a per-frame basis. */
d043f1a4
RS
1631 f->display.x->border_tile
1632 = (XCreatePixmapFromBitmapData
1633 (x_current_display, ROOT_WINDOW,
1634 gray_bits, gray_width, gray_height,
1635 f->display.x->foreground_pixel,
1636 f->display.x->background_pixel,
1637 DefaultDepth (x_current_display, XDefaultScreen (x_current_display))));
6afb1d07
JB
1638
1639 UNBLOCK_INPUT;
01f1ba30
JB
1640}
1641#endif /* HAVE_X11 */
1642
f676886a 1643DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
01f1ba30 1644 1, 1, 0,
f676886a
JB
1645 "Make a new X window, which is called a \"frame\" in Emacs terms.\n\
1646Return an Emacs frame object representing the X window.\n\
1647ALIST is an alist of frame parameters.\n\
1648If the parameters specify that the frame should not have a minibuffer,\n\
e22d6b02 1649and do not specify a specific minibuffer window to use,\n\
f676886a
JB
1650then `default-minibuffer-frame' must be a frame whose minibuffer can\n\
1651be shared by the new frame.")
01f1ba30
JB
1652 (parms)
1653 Lisp_Object parms;
1654{
1655#ifdef HAVE_X11
f676886a
JB
1656 struct frame *f;
1657 Lisp_Object frame, tem;
01f1ba30
JB
1658 Lisp_Object name;
1659 int minibuffer_only = 0;
1660 long window_prompting = 0;
1661 int width, height;
1662
11ae94fe 1663 check_x ();
01f1ba30 1664
cf177271
JB
1665 name = x_get_arg (parms, Qname, "title", "Title", string);
1666 if (XTYPE (name) != Lisp_String
1667 && ! EQ (name, Qunbound)
1668 && ! NILP (name))
f676886a 1669 error ("x-create-frame: name parameter must be a string");
01f1ba30 1670
cf177271 1671 tem = x_get_arg (parms, Qminibuffer, 0, 0, symbol);
f9942c9e 1672 if (EQ (tem, Qnone) || NILP (tem))
f676886a 1673 f = make_frame_without_minibuffer (Qnil);
f9942c9e 1674 else if (EQ (tem, Qonly))
01f1ba30 1675 {
f676886a 1676 f = make_minibuffer_frame ();
01f1ba30
JB
1677 minibuffer_only = 1;
1678 }
f9942c9e 1679 else if (XTYPE (tem) == Lisp_Window)
f676886a 1680 f = make_frame_without_minibuffer (tem);
f9942c9e
JB
1681 else
1682 f = make_frame (1);
01f1ba30 1683
a3c87d4e
JB
1684 /* Note that X Windows does support scroll bars. */
1685 FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
179956b9 1686
cf177271
JB
1687 /* Set the name; the functions to which we pass f expect the name to
1688 be set. */
1689 if (EQ (name, Qunbound) || NILP (name))
1690 {
1691 f->name = build_string (x_id_name);
1692 f->explicit_name = 0;
1693 }
1694 else
1695 {
1696 f->name = name;
1697 f->explicit_name = 1;
1698 }
01f1ba30 1699
f676886a
JB
1700 XSET (frame, Lisp_Frame, f);
1701 f->output_method = output_x_window;
1702 f->display.x = (struct x_display *) xmalloc (sizeof (struct x_display));
1703 bzero (f->display.x, sizeof (struct x_display));
01f1ba30 1704
f676886a
JB
1705 /* Note that the frame has no physical cursor right now. */
1706 f->phys_cursor_x = -1;
265a9e55 1707
01f1ba30
JB
1708 /* Extract the window parameters from the supplied values
1709 that are needed to determine window geometry. */
ee8f40cc
JB
1710 x_default_parameter (f, parms, Qfont,
1711 build_string
1712 /* If we use an XLFD name for this font, the lisp code
1713 knows how to find variants which are bold, italic,
1714 etcetera. */
1715 ("-*-fixed-*-*-*-*-*-120-*-*-c-*-iso8859-1"),
cf177271
JB
1716 "font", "Font", string);
1717 x_default_parameter (f, parms, Qborder_width, make_number (2),
1718 "borderwidth", "BorderWidth", number);
1719 /* This defaults to 2 in order to match xterm. */
1720 x_default_parameter (f, parms, Qinternal_border_width, make_number (2),
1721 "internalBorderWidth", "BorderWidth", number);
a3c87d4e
JB
1722 x_default_parameter (f, parms, Qvertical_scroll_bars, Qt,
1723 "verticalScrollBars", "ScrollBars", boolean);
01f1ba30
JB
1724
1725 /* Also do the stuff which must be set before the window exists. */
cf177271
JB
1726 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
1727 "foreground", "Foreground", string);
1728 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
1729 "background", "Background", string);
1730 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
1731 "pointerColor", "Foreground", string);
1732 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
1733 "cursorColor", "Foreground", string);
1734 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
1735 "borderColor", "BorderColor", string);
01f1ba30 1736
f676886a
JB
1737 f->display.x->parent_desc = ROOT_WINDOW;
1738 window_prompting = x_figure_window_size (f, parms);
01f1ba30 1739
f676886a
JB
1740 x_window (f);
1741 x_icon (f, parms);
1742 x_make_gc (f);
ea96210c 1743 init_frame_faces (f);
01f1ba30 1744
f9942c9e
JB
1745 /* We need to do this after creating the X window, so that the
1746 icon-creation functions can say whose icon they're describing. */
cf177271
JB
1747 x_default_parameter (f, parms, Qicon_type, Qnil,
1748 "iconType", "IconType", symbol);
f9942c9e 1749
cf177271
JB
1750 x_default_parameter (f, parms, Qauto_raise, Qnil,
1751 "autoRaise", "AutoRaiseLower", boolean);
1752 x_default_parameter (f, parms, Qauto_lower, Qnil,
1753 "autoLower", "AutoRaiseLower", boolean);
dbc4e1c1
JB
1754 x_default_parameter (f, parms, Qcursor_type, Qbox,
1755 "cursorType", "CursorType", symbol);
f9942c9e 1756
f676886a 1757 /* Dimensions, especially f->height, must be done via change_frame_size.
01f1ba30 1758 Change will not be effected unless different from the current
f676886a
JB
1759 f->height. */
1760 width = f->width;
1761 height = f->height;
1762 f->height = f->width = 0;
f9942c9e 1763 change_frame_size (f, height, width, 1, 0);
d043f1a4
RS
1764
1765 x_default_parameter (f, parms, Qmenu_bar_lines, make_number (0),
1766 "menuBarLines", "MenuBarLines", number);
1767
01f1ba30 1768 BLOCK_INPUT;
f676886a 1769 x_wm_set_size_hint (f, window_prompting);
01f1ba30
JB
1770 UNBLOCK_INPUT;
1771
cf177271 1772 tem = x_get_arg (parms, Qunsplittable, 0, 0, boolean);
f676886a 1773 f->no_split = minibuffer_only || EQ (tem, Qt);
01f1ba30 1774
d043f1a4
RS
1775 /* Make the window appear on the frame and enable display,
1776 unless the caller says not to. */
49795535
JB
1777 {
1778 Lisp_Object visibility = x_get_arg (parms, Qvisibility, 0, 0, symbol);
1779
1780 if (EQ (visibility, Qunbound))
1781 visibility = Qt;
1782
1783 if (EQ (visibility, Qicon))
1784 x_iconify_frame (f);
1785 else if (! NILP (visibility))
1786 x_make_frame_visible (f);
1787 else
1788 /* Must have been Qnil. */
1789 ;
1790 }
01f1ba30 1791
f676886a 1792 return frame;
01f1ba30 1793#else /* X10 */
f676886a
JB
1794 struct frame *f;
1795 Lisp_Object frame, tem;
01f1ba30
JB
1796 Lisp_Object name;
1797 int pixelwidth, pixelheight;
1798 Cursor cursor;
1799 int height, width;
1800 Window parent;
1801 Pixmap temp;
1802 int minibuffer_only = 0;
1803 Lisp_Object vscroll, hscroll;
1804
1805 if (x_current_display == 0)
1806 error ("X windows are not in use or not initialized");
1807
f9942c9e 1808 name = Fassq (Qname, parms);
01f1ba30 1809
cf177271 1810 tem = x_get_arg (parms, Qminibuffer, 0, 0, symbol);
f9942c9e 1811 if (EQ (tem, Qnone))
f676886a 1812 f = make_frame_without_minibuffer (Qnil);
f9942c9e 1813 else if (EQ (tem, Qonly))
01f1ba30 1814 {
f676886a 1815 f = make_minibuffer_frame ();
01f1ba30
JB
1816 minibuffer_only = 1;
1817 }
f9942c9e 1818 else if (EQ (tem, Qnil) || EQ (tem, Qunbound))
f676886a 1819 f = make_frame (1);
f9942c9e
JB
1820 else
1821 f = make_frame_without_minibuffer (tem);
01f1ba30
JB
1822
1823 parent = ROOT_WINDOW;
1824
f676886a
JB
1825 XSET (frame, Lisp_Frame, f);
1826 f->output_method = output_x_window;
1827 f->display.x = (struct x_display *) xmalloc (sizeof (struct x_display));
1828 bzero (f->display.x, sizeof (struct x_display));
01f1ba30
JB
1829
1830 /* Some temprorary default values for height and width. */
1831 width = 80;
1832 height = 40;
f676886a
JB
1833 f->display.x->left_pos = -1;
1834 f->display.x->top_pos = -1;
01f1ba30 1835
f676886a 1836 /* Give the frame a default name (which may be overridden with PARMS). */
01f1ba30
JB
1837
1838 strncpy (iconidentity, ICONTAG, MAXICID);
1839 if (gethostname (&iconidentity[sizeof (ICONTAG) - 1],
1840 (MAXICID - 1) - sizeof (ICONTAG)))
1841 iconidentity[sizeof (ICONTAG) - 2] = '\0';
f676886a 1842 f->name = build_string (iconidentity);
01f1ba30
JB
1843
1844 /* Extract some window parameters from the supplied values.
1845 These are the parameters that affect window geometry. */
1846
cf177271 1847 tem = x_get_arg (parms, Qfont, "BodyFont", 0, string);
f9942c9e 1848 if (EQ (tem, Qunbound))
01f1ba30 1849 tem = build_string ("9x15");
f9942c9e
JB
1850 x_set_font (f, tem, Qnil);
1851 x_default_parameter (f, parms, Qborder_color,
cf177271 1852 build_string ("black"), "Border", 0, string);
f9942c9e 1853 x_default_parameter (f, parms, Qbackground_color,
cf177271 1854 build_string ("white"), "Background", 0, string);
f9942c9e 1855 x_default_parameter (f, parms, Qforeground_color,
cf177271 1856 build_string ("black"), "Foreground", 0, string);
f9942c9e 1857 x_default_parameter (f, parms, Qmouse_color,
cf177271 1858 build_string ("black"), "Mouse", 0, string);
f9942c9e 1859 x_default_parameter (f, parms, Qcursor_color,
cf177271 1860 build_string ("black"), "Cursor", 0, string);
f9942c9e 1861 x_default_parameter (f, parms, Qborder_width,
cf177271 1862 make_number (2), "BorderWidth", 0, number);
f9942c9e 1863 x_default_parameter (f, parms, Qinternal_border_width,
cf177271 1864 make_number (4), "InternalBorderWidth", 0, number);
f9942c9e 1865 x_default_parameter (f, parms, Qauto_raise,
cf177271 1866 Qnil, "AutoRaise", 0, boolean);
01f1ba30 1867
cf177271
JB
1868 hscroll = EQ (x_get_arg (parms, Qhorizontal_scroll_bar, 0, 0, boolean), Qt);
1869 vscroll = EQ (x_get_arg (parms, Qvertical_scroll_bar, 0, 0, boolean), Qt);
01f1ba30 1870
f676886a
JB
1871 if (f->display.x->internal_border_width < 0)
1872 f->display.x->internal_border_width = 0;
01f1ba30 1873
cf177271 1874 tem = x_get_arg (parms, Qwindow_id, 0, 0, number);
f9942c9e 1875 if (!EQ (tem, Qunbound))
01f1ba30
JB
1876 {
1877 WINDOWINFO_TYPE wininfo;
1878 int nchildren;
1879 Window *children, root;
1880
f9942c9e 1881 CHECK_NUMBER (tem, 0);
fe24a618 1882 FRAME_X_WINDOW (f) = (Window) XINT (tem);
01f1ba30
JB
1883
1884 BLOCK_INPUT;
fe24a618
JB
1885 XGetWindowInfo (FRAME_X_WINDOW (f), &wininfo);
1886 XQueryTree (FRAME_X_WINDOW (f), &parent, &nchildren, &children);
9ac0d9e0 1887 xfree (children);
01f1ba30
JB
1888 UNBLOCK_INPUT;
1889
cf177271
JB
1890 height = PIXEL_TO_CHAR_HEIGHT (f, wininfo.height);
1891 width = PIXEL_TO_CHAR_WIDTH (f, wininfo.width);
f676886a
JB
1892 f->display.x->left_pos = wininfo.x;
1893 f->display.x->top_pos = wininfo.y;
179956b9 1894 FRAME_SET_VISIBILITY (f, wininfo.mapped != 0);
f676886a
JB
1895 f->display.x->border_width = wininfo.bdrwidth;
1896 f->display.x->parent_desc = parent;
01f1ba30
JB
1897 }
1898 else
1899 {
cf177271 1900 tem = x_get_arg (parms, Qparent_id, 0, 0, number);
f9942c9e 1901 if (!EQ (tem, Qunbound))
01f1ba30 1902 {
f9942c9e
JB
1903 CHECK_NUMBER (tem, 0);
1904 parent = (Window) XINT (tem);
01f1ba30 1905 }
f676886a 1906 f->display.x->parent_desc = parent;
cf177271 1907 tem = x_get_arg (parms, Qheight, 0, 0, number);
f9942c9e 1908 if (EQ (tem, Qunbound))
01f1ba30 1909 {
cf177271 1910 tem = x_get_arg (parms, Qwidth, 0, 0, number);
f9942c9e 1911 if (EQ (tem, Qunbound))
01f1ba30 1912 {
cf177271 1913 tem = x_get_arg (parms, Qtop, 0, 0, number);
f9942c9e 1914 if (EQ (tem, Qunbound))
cf177271 1915 tem = x_get_arg (parms, Qleft, 0, 0, number);
01f1ba30
JB
1916 }
1917 }
f9942c9e 1918 /* Now TEM is Qunbound if no edge or size was specified.
01f1ba30 1919 In that case, we must do rubber-banding. */
f9942c9e 1920 if (EQ (tem, Qunbound))
01f1ba30 1921 {
cf177271 1922 tem = x_get_arg (parms, Qgeometry, 0, 0, number);
f676886a
JB
1923 x_rubber_band (f,
1924 &f->display.x->left_pos, &f->display.x->top_pos,
01f1ba30
JB
1925 &width, &height,
1926 (XTYPE (tem) == Lisp_String
1927 ? (char *) XSTRING (tem)->data : ""),
f676886a 1928 XSTRING (f->name)->data,
265a9e55 1929 !NILP (hscroll), !NILP (vscroll));
01f1ba30
JB
1930 }
1931 else
1932 {
1933 /* Here if at least one edge or size was specified.
1934 Demand that they all were specified, and use them. */
cf177271 1935 tem = x_get_arg (parms, Qheight, 0, 0, number);
f9942c9e 1936 if (EQ (tem, Qunbound))
01f1ba30
JB
1937 error ("Height not specified");
1938 CHECK_NUMBER (tem, 0);
1939 height = XINT (tem);
1940
cf177271 1941 tem = x_get_arg (parms, Qwidth, 0, 0, number);
f9942c9e 1942 if (EQ (tem, Qunbound))
01f1ba30
JB
1943 error ("Width not specified");
1944 CHECK_NUMBER (tem, 0);
1945 width = XINT (tem);
1946
cf177271 1947 tem = x_get_arg (parms, Qtop, 0, 0, number);
f9942c9e 1948 if (EQ (tem, Qunbound))
01f1ba30
JB
1949 error ("Top position not specified");
1950 CHECK_NUMBER (tem, 0);
f676886a 1951 f->display.x->left_pos = XINT (tem);
01f1ba30 1952
cf177271 1953 tem = x_get_arg (parms, Qleft, 0, 0, number);
f9942c9e 1954 if (EQ (tem, Qunbound))
01f1ba30
JB
1955 error ("Left position not specified");
1956 CHECK_NUMBER (tem, 0);
f676886a 1957 f->display.x->top_pos = XINT (tem);
01f1ba30
JB
1958 }
1959
cf177271
JB
1960 pixelwidth = CHAR_TO_PIXEL_WIDTH (f, width);
1961 pixelheight = CHAR_TO_PIXEL_HEIGHT (f, height);
01f1ba30
JB
1962
1963 BLOCK_INPUT;
fe24a618 1964 FRAME_X_WINDOW (f)
01f1ba30 1965 = XCreateWindow (parent,
f676886a
JB
1966 f->display.x->left_pos, /* Absolute horizontal offset */
1967 f->display.x->top_pos, /* Absolute Vertical offset */
01f1ba30 1968 pixelwidth, pixelheight,
f676886a 1969 f->display.x->border_width,
01f1ba30
JB
1970 BLACK_PIX_DEFAULT, WHITE_PIX_DEFAULT);
1971 UNBLOCK_INPUT;
fe24a618 1972 if (FRAME_X_WINDOW (f) == 0)
01f1ba30
JB
1973 error ("Unable to create window.");
1974 }
1975
1976 /* Install the now determined height and width
1977 in the windows and in phys_lines and desired_lines. */
f9942c9e 1978 change_frame_size (f, height, width, 1, 0);
fe24a618 1979 XSelectInput (FRAME_X_WINDOW (f), KeyPressed | ExposeWindow
01f1ba30
JB
1980 | ButtonPressed | ButtonReleased | ExposeRegion | ExposeCopy
1981 | EnterWindow | LeaveWindow | UnmapWindow );
f676886a 1982 x_set_resize_hint (f);
01f1ba30
JB
1983
1984 /* Tell the server the window's default name. */
fe24a618 1985 XStoreName (XDISPLAY FRAME_X_WINDOW (f), XSTRING (f->name)->data);
1113d9db 1986
01f1ba30
JB
1987 /* Now override the defaults with all the rest of the specified
1988 parms. */
cf177271 1989 tem = x_get_arg (parms, Qunsplittable, 0, 0, boolean);
f676886a 1990 f->no_split = minibuffer_only || EQ (tem, Qt);
01f1ba30 1991
8af1d7ca
JB
1992 /* Do not create an icon window if the caller says not to */
1993 if (!EQ (x_get_arg (parms, Qsuppress_icon, 0, 0, boolean), Qt)
1994 || f->display.x->parent_desc != ROOT_WINDOW)
1995 {
1996 x_text_icon (f, iconidentity);
1997 x_default_parameter (f, parms, Qicon_type, Qnil,
1998 "BitmapIcon", 0, symbol);
1999 }
01f1ba30
JB
2000
2001 /* Tell the X server the previously set values of the
2002 background, border and mouse colors; also create the mouse cursor. */
2003 BLOCK_INPUT;
f676886a 2004 temp = XMakeTile (f->display.x->background_pixel);
fe24a618 2005 XChangeBackground (FRAME_X_WINDOW (f), temp);
01f1ba30
JB
2006 XFreePixmap (temp);
2007 UNBLOCK_INPUT;
f676886a 2008 x_set_border_pixel (f, f->display.x->border_pixel);
01f1ba30 2009
f676886a 2010 x_set_mouse_color (f, Qnil, Qnil);
01f1ba30
JB
2011
2012 /* Now override the defaults with all the rest of the specified parms. */
2013
f676886a 2014 Fmodify_frame_parameters (frame, parms);
01f1ba30 2015
f676886a 2016 /* Make the window appear on the frame and enable display. */
49795535
JB
2017 {
2018 Lisp_Object visibility = x_get_arg (parms, Qvisibility, 0, 0, symbol);
2019
2020 if (EQ (visibility, Qunbound))
2021 visibility = Qt;
2022
2023 if (! EQ (visibility, Qicon)
2024 && ! NILP (visibility))
2025 x_make_window_visible (f);
2026 }
01f1ba30 2027
cf177271 2028 SET_FRAME_GARBAGED (f);
01f1ba30 2029
f676886a 2030 return frame;
01f1ba30
JB
2031#endif /* X10 */
2032}
2033
f676886a
JB
2034DEFUN ("focus-frame", Ffocus_frame, Sfocus_frame, 1, 1, 0,
2035 "Set the focus on FRAME.")
2036 (frame)
2037 Lisp_Object frame;
01f1ba30 2038{
f676886a 2039 CHECK_LIVE_FRAME (frame, 0);
01f1ba30 2040
f9942c9e 2041 if (FRAME_X_P (XFRAME (frame)))
01f1ba30
JB
2042 {
2043 BLOCK_INPUT;
f676886a 2044 x_focus_on_frame (XFRAME (frame));
01f1ba30 2045 UNBLOCK_INPUT;
f676886a 2046 return frame;
01f1ba30
JB
2047 }
2048
2049 return Qnil;
2050}
2051
f676886a
JB
2052DEFUN ("unfocus-frame", Funfocus_frame, Sunfocus_frame, 0, 0, 0,
2053 "If a frame has been focused, release it.")
01f1ba30
JB
2054 ()
2055{
f676886a 2056 if (x_focus_frame)
01f1ba30
JB
2057 {
2058 BLOCK_INPUT;
f676886a 2059 x_unfocus_frame (x_focus_frame);
01f1ba30
JB
2060 UNBLOCK_INPUT;
2061 }
2062
2063 return Qnil;
2064}
2065\f
2066#ifndef HAVE_X11
2067/* Computes an X-window size and position either from geometry GEO
2068 or with the mouse.
2069
f676886a 2070 F is a frame. It specifies an X window which is used to
01f1ba30
JB
2071 determine which display to compute for. Its font, borders
2072 and colors control how the rectangle will be displayed.
2073
2074 X and Y are where to store the positions chosen.
2075 WIDTH and HEIGHT are where to store the sizes chosen.
2076
2077 GEO is the geometry that may specify some of the info.
2078 STR is a prompt to display.
2079 HSCROLL and VSCROLL say whether we have horiz and vert scroll bars. */
2080
2081int
f676886a
JB
2082x_rubber_band (f, x, y, width, height, geo, str, hscroll, vscroll)
2083 struct frame *f;
01f1ba30
JB
2084 int *x, *y, *width, *height;
2085 char *geo;
2086 char *str;
2087 int hscroll, vscroll;
2088{
2089 OpaqueFrame frame;
2090 Window tempwindow;
2091 WindowInfo wininfo;
2092 int border_color;
2093 int background_color;
2094 Lisp_Object tem;
2095 int mask;
2096
2097 BLOCK_INPUT;
2098
f676886a
JB
2099 background_color = f->display.x->background_pixel;
2100 border_color = f->display.x->border_pixel;
01f1ba30 2101
f676886a 2102 frame.bdrwidth = f->display.x->border_width;
01f1ba30
JB
2103 frame.border = XMakeTile (border_color);
2104 frame.background = XMakeTile (background_color);
2105 tempwindow = XCreateTerm (str, "emacs", geo, default_window, &frame, 10, 5,
f676886a 2106 (2 * f->display.x->internal_border_width
01f1ba30 2107 + (vscroll ? VSCROLL_WIDTH : 0)),
f676886a 2108 (2 * f->display.x->internal_border_width
01f1ba30 2109 + (hscroll ? HSCROLL_HEIGHT : 0)),
f676886a
JB
2110 width, height, f->display.x->font,
2111 FONT_WIDTH (f->display.x->font),
2112 FONT_HEIGHT (f->display.x->font));
01f1ba30
JB
2113 XFreePixmap (frame.border);
2114 XFreePixmap (frame.background);
2115
2116 if (tempwindow != 0)
2117 {
2118 XQueryWindow (tempwindow, &wininfo);
2119 XDestroyWindow (tempwindow);
2120 *x = wininfo.x;
2121 *y = wininfo.y;
2122 }
2123
2124 /* Coordinates we got are relative to the root window.
2125 Convert them to coordinates relative to desired parent window
2126 by scanning from there up to the root. */
f676886a 2127 tempwindow = f->display.x->parent_desc;
01f1ba30
JB
2128 while (tempwindow != ROOT_WINDOW)
2129 {
2130 int nchildren;
2131 Window *children;
2132 XQueryWindow (tempwindow, &wininfo);
2133 *x -= wininfo.x;
2134 *y -= wininfo.y;
2135 XQueryTree (tempwindow, &tempwindow, &nchildren, &children);
9ac0d9e0 2136 xfree (children);
01f1ba30
JB
2137 }
2138
2139 UNBLOCK_INPUT;
2140 return tempwindow != 0;
2141}
2142#endif /* not HAVE_X11 */
2143\f
f0614854
JB
2144DEFUN ("x-list-fonts", Fx_list_fonts, Sx_list_fonts, 1, 3, 0,
2145 "Return a list of the names of available fonts matching PATTERN.\n\
2146If optional arguments FACE and FRAME are specified, return only fonts\n\
2147the same size as FACE on FRAME.\n\
2148\n\
2149PATTERN is a string, perhaps with wildcard characters;\n\
2150 the * character matches any substring, and\n\
2151 the ? character matches any single character.\n\
2152 PATTERN is case-insensitive.\n\
2153FACE is a face name - a symbol.\n\
2154\n\
2155The return value is a list of strings, suitable as arguments to\n\
2156set-face-font.\n\
2157\n\
2158The list does not include fonts Emacs can't use (i.e. proportional\n\
2159fonts), even if they match PATTERN and FACE.")
2160 (pattern, face, frame)
2161 Lisp_Object pattern, face, frame;
2162{
2163 int num_fonts;
2164 char **names;
2165 XFontStruct *info;
2166 XFontStruct *size_ref;
2167 Lisp_Object list;
2168
2169 CHECK_STRING (pattern, 0);
2170 if (!NILP (face))
2171 CHECK_SYMBOL (face, 1);
2172 if (!NILP (frame))
2173 CHECK_SYMBOL (frame, 2);
2174
2175 if (NILP (face))
2176 size_ref = 0;
2177 else
2178 {
2179 FRAME_PTR f = NILP (frame) ? selected_frame : XFRAME (frame);
2180 int face_id = face_name_id_number (f, face);
2181
2182 if (face_id < 0 || face_id > FRAME_N_FACES (f))
2183 face_id = 0;
2184 size_ref = FRAME_FACES (f) [face_id]->font;
2185 if (size_ref == (XFontStruct *) (~0))
ea96210c 2186 size_ref = f->display.x->font;
f0614854
JB
2187 }
2188
2189 BLOCK_INPUT;
2190 names = XListFontsWithInfo (x_current_display,
2191 XSTRING (pattern)->data,
ea96210c 2192 2000, /* maxnames */
f0614854
JB
2193 &num_fonts, /* count_return */
2194 &info); /* info_return */
2195 UNBLOCK_INPUT;
2196
2197 {
2198 Lisp_Object *tail;
2199 int i;
2200
2201 list = Qnil;
2202 tail = &list;
2203 for (i = 0; i < num_fonts; i++)
ea96210c
JB
2204 if (! size_ref
2205 || same_size_fonts (&info[i], size_ref))
f0614854
JB
2206 {
2207 *tail = Fcons (build_string (names[i]), Qnil);
2208 tail = &XCONS (*tail)->cdr;
2209 }
2210
2211 XFreeFontInfo (names, info, num_fonts);
2212 }
2213
2214 return list;
2215}
2216
2217\f
8af1d7ca 2218DEFUN ("x-color-defined-p", Fx_color_defined_p, Sx_color_defined_p, 1, 1, 0,
01f1ba30
JB
2219 "Return t if the current X display supports the color named COLOR.")
2220 (color)
2221 Lisp_Object color;
2222{
2223 Color foo;
2224
11ae94fe 2225 check_x ();
01f1ba30
JB
2226 CHECK_STRING (color, 0);
2227
2228 if (defined_color (XSTRING (color)->data, &foo))
2229 return Qt;
2230 else
2231 return Qnil;
2232}
2233
bcc426b4
RS
2234DEFUN ("x-display-color-p", Fx_display_color_p, Sx_display_color_p, 0, 0, 0,
2235 "Return t if the X screen currently in use supports color.")
01f1ba30
JB
2236 ()
2237{
11ae94fe
RS
2238 check_x ();
2239
a6605e5c 2240 if (x_screen_planes <= 2)
01f1ba30
JB
2241 return Qnil;
2242
2243 switch (screen_visual->class)
2244 {
2245 case StaticColor:
2246 case PseudoColor:
2247 case TrueColor:
2248 case DirectColor:
2249 return Qt;
2250
2251 default:
2252 return Qnil;
2253 }
2254}
2255
41beb8fc
RS
2256DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
2257 0, 1, 0,
2258 "Returns the width in pixels of the display FRAME is on.")
2259 (frame)
2260 Lisp_Object frame;
2261{
2262 Display *dpy = x_current_display;
11ae94fe 2263 check_x ();
41beb8fc
RS
2264 return make_number (DisplayWidth (dpy, DefaultScreen (dpy)));
2265}
2266
2267DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
2268 Sx_display_pixel_height, 0, 1, 0,
2269 "Returns the height in pixels of the display FRAME is on.")
2270 (frame)
2271 Lisp_Object frame;
2272{
2273 Display *dpy = x_current_display;
11ae94fe 2274 check_x ();
41beb8fc
RS
2275 return make_number (DisplayHeight (dpy, DefaultScreen (dpy)));
2276}
2277
2278DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
2279 0, 1, 0,
2280 "Returns the number of bitplanes of the display FRAME is on.")
2281 (frame)
2282 Lisp_Object frame;
2283{
2284 Display *dpy = x_current_display;
11ae94fe 2285 check_x ();
41beb8fc
RS
2286 return make_number (DisplayPlanes (dpy, DefaultScreen (dpy)));
2287}
2288
2289DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
2290 0, 1, 0,
2291 "Returns the number of color cells of the display FRAME is on.")
2292 (frame)
2293 Lisp_Object frame;
2294{
2295 Display *dpy = x_current_display;
11ae94fe 2296 check_x ();
41beb8fc
RS
2297 return make_number (DisplayCells (dpy, DefaultScreen (dpy)));
2298}
2299
2300DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
2301 "Returns the vendor ID string of the X server FRAME is on.")
2302 (frame)
2303 Lisp_Object frame;
2304{
2305 Display *dpy = x_current_display;
2306 char *vendor;
11ae94fe 2307 check_x ();
41beb8fc
RS
2308 vendor = ServerVendor (dpy);
2309 if (! vendor) vendor = "";
2310 return build_string (vendor);
2311}
2312
2313DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
2314 "Returns the version numbers of the X server in use.\n\
2315The value is a list of three integers: the major and minor\n\
2316version numbers of the X Protocol in use, and the vendor-specific release\n\
2317number. See also the variable `x-server-vendor'.")
2318 (frame)
2319 Lisp_Object frame;
2320{
2321 Display *dpy = x_current_display;
11ae94fe
RS
2322
2323 check_x ();
41beb8fc
RS
2324 return Fcons (make_number (ProtocolVersion (dpy)),
2325 Fcons (make_number (ProtocolRevision (dpy)),
2326 Fcons (make_number (VendorRelease (dpy)), Qnil)));
2327}
2328
2329DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
2330 "Returns the number of screens on the X server FRAME is on.")
2331 (frame)
2332 Lisp_Object frame;
2333{
11ae94fe 2334 check_x ();
41beb8fc
RS
2335 return make_number (ScreenCount (x_current_display));
2336}
2337
2338DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
2339 "Returns the height in millimeters of the X screen FRAME is on.")
2340 (frame)
2341 Lisp_Object frame;
2342{
11ae94fe 2343 check_x ();
41beb8fc
RS
2344 return make_number (HeightMMOfScreen (x_screen));
2345}
2346
2347DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
2348 "Returns the width in millimeters of the X screen FRAME is on.")
2349 (frame)
2350 Lisp_Object frame;
2351{
11ae94fe 2352 check_x ();
41beb8fc
RS
2353 return make_number (WidthMMOfScreen (x_screen));
2354}
2355
2356DEFUN ("x-display-backing-store", Fx_display_backing_store,
2357 Sx_display_backing_store, 0, 1, 0,
2358 "Returns an indication of whether the X screen FRAME is on does backing store.\n\
2359The value may be `always', `when-mapped', or `not-useful'.")
2360 (frame)
2361 Lisp_Object frame;
2362{
11ae94fe
RS
2363 check_x ();
2364
41beb8fc
RS
2365 switch (DoesBackingStore (x_screen))
2366 {
2367 case Always:
2368 return intern ("always");
2369
2370 case WhenMapped:
2371 return intern ("when-mapped");
2372
2373 case NotUseful:
2374 return intern ("not-useful");
2375
2376 default:
2377 error ("Strange value for BackingStore parameter of screen");
2378 }
2379}
2380
2381DEFUN ("x-display-visual-class", Fx_display_visual_class,
2382 Sx_display_visual_class, 0, 1, 0,
2383 "Returns the visual class of the display `screen' is on.\n\
2384The value is one of the symbols `static-gray', `gray-scale',\n\
2385`static-color', `pseudo-color', `true-color', or `direct-color'.")
2386 (screen)
2387 Lisp_Object screen;
2388{
11ae94fe
RS
2389 check_x ();
2390
41beb8fc
RS
2391 switch (screen_visual->class)
2392 {
2393 case StaticGray: return (intern ("static-gray"));
2394 case GrayScale: return (intern ("gray-scale"));
2395 case StaticColor: return (intern ("static-color"));
2396 case PseudoColor: return (intern ("pseudo-color"));
2397 case TrueColor: return (intern ("true-color"));
2398 case DirectColor: return (intern ("direct-color"));
2399 default:
2400 error ("Display has an unknown visual class");
2401 }
2402}
2403
2404DEFUN ("x-display-save-under", Fx_display_save_under,
2405 Sx_display_save_under, 0, 1, 0,
2406 "Returns t if the X screen FRAME is on supports the save-under feature.")
2407 (frame)
2408 Lisp_Object frame;
2409{
11ae94fe
RS
2410 check_x ();
2411
41beb8fc
RS
2412 if (DoesSaveUnders (x_screen) == True)
2413 return Qt;
2414 else
2415 return Qnil;
2416}
2417\f
55caf99c
RS
2418x_pixel_width (f)
2419 register struct frame *f;
01f1ba30 2420{
55caf99c 2421 return PIXEL_WIDTH (f);
01f1ba30
JB
2422}
2423
55caf99c
RS
2424x_pixel_height (f)
2425 register struct frame *f;
01f1ba30 2426{
55caf99c
RS
2427 return PIXEL_HEIGHT (f);
2428}
2429
2430x_char_width (f)
2431 register struct frame *f;
2432{
2433 return FONT_WIDTH (f->display.x->font);
2434}
2435
2436x_char_height (f)
2437 register struct frame *f;
2438{
2439 return FONT_HEIGHT (f->display.x->font);
01f1ba30
JB
2440}
2441\f
85ffea93
RS
2442#if 0 /* These no longer seem like the right way to do things. */
2443
f676886a 2444/* Draw a rectangle on the frame with left top corner including
01f1ba30
JB
2445 the character specified by LEFT_CHAR and TOP_CHAR. The rectangle is
2446 CHARS by LINES wide and long and is the color of the cursor. */
2447
2448void
f676886a
JB
2449x_rectangle (f, gc, left_char, top_char, chars, lines)
2450 register struct frame *f;
01f1ba30
JB
2451 GC gc;
2452 register int top_char, left_char, chars, lines;
2453{
2454 int width;
2455 int height;
f676886a
JB
2456 int left = (left_char * FONT_WIDTH (f->display.x->font)
2457 + f->display.x->internal_border_width);
2458 int top = (top_char * FONT_HEIGHT (f->display.x->font)
2459 + f->display.x->internal_border_width);
01f1ba30
JB
2460
2461 if (chars < 0)
f676886a 2462 width = FONT_WIDTH (f->display.x->font) / 2;
01f1ba30 2463 else
f676886a 2464 width = FONT_WIDTH (f->display.x->font) * chars;
01f1ba30 2465 if (lines < 0)
f676886a 2466 height = FONT_HEIGHT (f->display.x->font) / 2;
01f1ba30 2467 else
f676886a 2468 height = FONT_HEIGHT (f->display.x->font) * lines;
01f1ba30 2469
fe24a618 2470 XDrawRectangle (x_current_display, FRAME_X_WINDOW (f),
01f1ba30
JB
2471 gc, left, top, width, height);
2472}
2473
2474DEFUN ("x-draw-rectangle", Fx_draw_rectangle, Sx_draw_rectangle, 5, 5, 0,
f676886a 2475 "Draw a rectangle on FRAME between coordinates specified by\n\
01f1ba30 2476numbers X0, Y0, X1, Y1 in the cursor pixel.")
f676886a
JB
2477 (frame, X0, Y0, X1, Y1)
2478 register Lisp_Object frame, X0, X1, Y0, Y1;
01f1ba30
JB
2479{
2480 register int x0, y0, x1, y1, top, left, n_chars, n_lines;
2481
f676886a 2482 CHECK_LIVE_FRAME (frame, 0);
01f1ba30
JB
2483 CHECK_NUMBER (X0, 0);
2484 CHECK_NUMBER (Y0, 1);
2485 CHECK_NUMBER (X1, 2);
2486 CHECK_NUMBER (Y1, 3);
2487
2488 x0 = XINT (X0);
2489 x1 = XINT (X1);
2490 y0 = XINT (Y0);
2491 y1 = XINT (Y1);
2492
2493 if (y1 > y0)
2494 {
2495 top = y0;
2496 n_lines = y1 - y0 + 1;
2497 }
2498 else
2499 {
2500 top = y1;
2501 n_lines = y0 - y1 + 1;
2502 }
2503
2504 if (x1 > x0)
2505 {
2506 left = x0;
2507 n_chars = x1 - x0 + 1;
2508 }
2509 else
2510 {
2511 left = x1;
2512 n_chars = x0 - x1 + 1;
2513 }
2514
2515 BLOCK_INPUT;
f676886a 2516 x_rectangle (XFRAME (frame), XFRAME (frame)->display.x->cursor_gc,
01f1ba30
JB
2517 left, top, n_chars, n_lines);
2518 UNBLOCK_INPUT;
2519
2520 return Qt;
2521}
2522
2523DEFUN ("x-erase-rectangle", Fx_erase_rectangle, Sx_erase_rectangle, 5, 5, 0,
f676886a 2524 "Draw a rectangle drawn on FRAME between coordinates\n\
01f1ba30 2525X0, Y0, X1, Y1 in the regular background-pixel.")
f676886a
JB
2526 (frame, X0, Y0, X1, Y1)
2527 register Lisp_Object frame, X0, Y0, X1, Y1;
01f1ba30
JB
2528{
2529 register int x0, y0, x1, y1, top, left, n_chars, n_lines;
2530
f676886a 2531 CHECK_FRAME (frame, 0);
01f1ba30
JB
2532 CHECK_NUMBER (X0, 0);
2533 CHECK_NUMBER (Y0, 1);
2534 CHECK_NUMBER (X1, 2);
2535 CHECK_NUMBER (Y1, 3);
2536
2537 x0 = XINT (X0);
2538 x1 = XINT (X1);
2539 y0 = XINT (Y0);
2540 y1 = XINT (Y1);
2541
2542 if (y1 > y0)
2543 {
2544 top = y0;
2545 n_lines = y1 - y0 + 1;
2546 }
2547 else
2548 {
2549 top = y1;
2550 n_lines = y0 - y1 + 1;
2551 }
2552
2553 if (x1 > x0)
2554 {
2555 left = x0;
2556 n_chars = x1 - x0 + 1;
2557 }
2558 else
2559 {
2560 left = x1;
2561 n_chars = x0 - x1 + 1;
2562 }
2563
2564 BLOCK_INPUT;
f676886a 2565 x_rectangle (XFRAME (frame), XFRAME (frame)->display.x->reverse_gc,
01f1ba30
JB
2566 left, top, n_chars, n_lines);
2567 UNBLOCK_INPUT;
2568
2569 return Qt;
2570}
2571
2572/* Draw lines around the text region beginning at the character position
2573 TOP_X, TOP_Y and ending at BOTTOM_X and BOTTOM_Y. GC specifies the
2574 pixel and line characteristics. */
2575
f676886a 2576#define line_len(line) (FRAME_CURRENT_GLYPHS (f)->used[(line)])
01f1ba30
JB
2577
2578static void
f676886a
JB
2579outline_region (f, gc, top_x, top_y, bottom_x, bottom_y)
2580 register struct frame *f;
01f1ba30
JB
2581 GC gc;
2582 int top_x, top_y, bottom_x, bottom_y;
2583{
f676886a
JB
2584 register int ibw = f->display.x->internal_border_width;
2585 register int font_w = FONT_WIDTH (f->display.x->font);
2586 register int font_h = FONT_HEIGHT (f->display.x->font);
01f1ba30
JB
2587 int y = top_y;
2588 int x = line_len (y);
2589 XPoint *pixel_points = (XPoint *)
2590 alloca (((bottom_y - top_y + 2) * 4) * sizeof (XPoint));
2591 register XPoint *this_point = pixel_points;
2592
2593 /* Do the horizontal top line/lines */
2594 if (top_x == 0)
2595 {
2596 this_point->x = ibw;
2597 this_point->y = ibw + (font_h * top_y);
2598 this_point++;
2599 if (x == 0)
2600 this_point->x = ibw + (font_w / 2); /* Half-size for newline chars. */
2601 else
2602 this_point->x = ibw + (font_w * x);
2603 this_point->y = (this_point - 1)->y;
2604 }
2605 else
2606 {
2607 this_point->x = ibw;
2608 this_point->y = ibw + (font_h * (top_y + 1));
2609 this_point++;
2610 this_point->x = ibw + (font_w * top_x);
2611 this_point->y = (this_point - 1)->y;
2612 this_point++;
2613 this_point->x = (this_point - 1)->x;
2614 this_point->y = ibw + (font_h * top_y);
2615 this_point++;
2616 this_point->x = ibw + (font_w * x);
2617 this_point->y = (this_point - 1)->y;
2618 }
2619
2620 /* Now do the right side. */
2621 while (y < bottom_y)
2622 { /* Right vertical edge */
2623 this_point++;
2624 this_point->x = (this_point - 1)->x;
2625 this_point->y = ibw + (font_h * (y + 1));
2626 this_point++;
2627
2628 y++; /* Horizontal connection to next line */
2629 x = line_len (y);
2630 if (x == 0)
2631 this_point->x = ibw + (font_w / 2);
2632 else
2633 this_point->x = ibw + (font_w * x);
2634
2635 this_point->y = (this_point - 1)->y;
2636 }
2637
2638 /* Now do the bottom and connect to the top left point. */
2639 this_point->x = ibw + (font_w * (bottom_x + 1));
2640
2641 this_point++;
2642 this_point->x = (this_point - 1)->x;
2643 this_point->y = ibw + (font_h * (bottom_y + 1));
2644 this_point++;
2645 this_point->x = ibw;
2646 this_point->y = (this_point - 1)->y;
2647 this_point++;
2648 this_point->x = pixel_points->x;
2649 this_point->y = pixel_points->y;
2650
fe24a618 2651 XDrawLines (x_current_display, FRAME_X_WINDOW (f),
01f1ba30
JB
2652 gc, pixel_points,
2653 (this_point - pixel_points + 1), CoordModeOrigin);
2654}
2655
2656DEFUN ("x-contour-region", Fx_contour_region, Sx_contour_region, 1, 1, 0,
2657 "Highlight the region between point and the character under the mouse\n\
f676886a 2658selected frame.")
01f1ba30
JB
2659 (event)
2660 register Lisp_Object event;
2661{
2662 register int x0, y0, x1, y1;
f676886a 2663 register struct frame *f = selected_frame;
01f1ba30
JB
2664 register int p1, p2;
2665
2666 CHECK_CONS (event, 0);
2667
2668 BLOCK_INPUT;
2669 x0 = XINT (Fcar (Fcar (event)));
2670 y0 = XINT (Fcar (Fcdr (Fcar (event))));
2671
2672 /* If the mouse is past the end of the line, don't that area. */
2673 /* ReWrite this... */
2674
f676886a
JB
2675 x1 = f->cursor_x;
2676 y1 = f->cursor_y;
01f1ba30
JB
2677
2678 if (y1 > y0) /* point below mouse */
f676886a 2679 outline_region (f, f->display.x->cursor_gc,
01f1ba30
JB
2680 x0, y0, x1, y1);
2681 else if (y1 < y0) /* point above mouse */
f676886a 2682 outline_region (f, f->display.x->cursor_gc,
01f1ba30
JB
2683 x1, y1, x0, y0);
2684 else /* same line: draw horizontal rectangle */
2685 {
2686 if (x1 > x0)
f676886a 2687 x_rectangle (f, f->display.x->cursor_gc,
01f1ba30
JB
2688 x0, y0, (x1 - x0 + 1), 1);
2689 else if (x1 < x0)
f676886a 2690 x_rectangle (f, f->display.x->cursor_gc,
01f1ba30
JB
2691 x1, y1, (x0 - x1 + 1), 1);
2692 }
2693
2694 XFlush (x_current_display);
2695 UNBLOCK_INPUT;
2696
2697 return Qnil;
2698}
2699
2700DEFUN ("x-uncontour-region", Fx_uncontour_region, Sx_uncontour_region, 1, 1, 0,
2701 "Erase any highlighting of the region between point and the character\n\
f676886a 2702at X, Y on the selected frame.")
01f1ba30
JB
2703 (event)
2704 register Lisp_Object event;
2705{
2706 register int x0, y0, x1, y1;
f676886a 2707 register struct frame *f = selected_frame;
01f1ba30
JB
2708
2709 BLOCK_INPUT;
2710 x0 = XINT (Fcar (Fcar (event)));
2711 y0 = XINT (Fcar (Fcdr (Fcar (event))));
f676886a
JB
2712 x1 = f->cursor_x;
2713 y1 = f->cursor_y;
01f1ba30
JB
2714
2715 if (y1 > y0) /* point below mouse */
f676886a 2716 outline_region (f, f->display.x->reverse_gc,
01f1ba30
JB
2717 x0, y0, x1, y1);
2718 else if (y1 < y0) /* point above mouse */
f676886a 2719 outline_region (f, f->display.x->reverse_gc,
01f1ba30
JB
2720 x1, y1, x0, y0);
2721 else /* same line: draw horizontal rectangle */
2722 {
2723 if (x1 > x0)
f676886a 2724 x_rectangle (f, f->display.x->reverse_gc,
01f1ba30
JB
2725 x0, y0, (x1 - x0 + 1), 1);
2726 else if (x1 < x0)
f676886a 2727 x_rectangle (f, f->display.x->reverse_gc,
01f1ba30
JB
2728 x1, y1, (x0 - x1 + 1), 1);
2729 }
2730 UNBLOCK_INPUT;
2731
2732 return Qnil;
2733}
2734
01f1ba30
JB
2735#if 0
2736int contour_begin_x, contour_begin_y;
2737int contour_end_x, contour_end_y;
2738int contour_npoints;
2739
2740/* Clip the top part of the contour lines down (and including) line Y_POS.
2741 If X_POS is in the middle (rather than at the end) of the line, drop
2742 down a line at that character. */
2743
2744static void
2745clip_contour_top (y_pos, x_pos)
2746{
2747 register XPoint *begin = contour_lines[y_pos].top_left;
2748 register XPoint *end;
2749 register int npoints;
f676886a 2750 register struct display_line *line = selected_frame->phys_lines[y_pos + 1];
01f1ba30
JB
2751
2752 if (x_pos >= line->len - 1) /* Draw one, straight horizontal line. */
2753 {
2754 end = contour_lines[y_pos].top_right;
2755 npoints = (end - begin + 1);
2756 XDrawLines (x_current_display, contour_window,
2757 contour_erase_gc, begin_erase, npoints, CoordModeOrigin);
2758
2759 bcopy (end, begin + 1, contour_last_point - end + 1);
2760 contour_last_point -= (npoints - 2);
2761 XDrawLines (x_current_display, contour_window,
2762 contour_erase_gc, begin, 2, CoordModeOrigin);
2763 XFlush (x_current_display);
2764
2765 /* Now, update contour_lines structure. */
2766 }
2767 /* ______. */
2768 else /* |________*/
2769 {
2770 register XPoint *p = begin + 1;
2771 end = contour_lines[y_pos].bottom_right;
2772 npoints = (end - begin + 1);
2773 XDrawLines (x_current_display, contour_window,
2774 contour_erase_gc, begin_erase, npoints, CoordModeOrigin);
2775
2776 p->y = begin->y;
2777 p->x = ibw + (font_w * (x_pos + 1));
2778 p++;
2779 p->y = begin->y + font_h;
2780 p->x = (p - 1)->x;
2781 bcopy (end, begin + 3, contour_last_point - end + 1);
2782 contour_last_point -= (npoints - 5);
2783 XDrawLines (x_current_display, contour_window,
2784 contour_erase_gc, begin, 4, CoordModeOrigin);
2785 XFlush (x_current_display);
2786
2787 /* Now, update contour_lines structure. */
2788 }
2789}
2790
2791/* Erase the top horzontal lines of the contour, and then extend
2792 the contour upwards. */
2793
2794static void
2795extend_contour_top (line)
2796{
2797}
2798
2799static void
2800clip_contour_bottom (x_pos, y_pos)
2801 int x_pos, y_pos;
2802{
2803}
2804
2805static void
2806extend_contour_bottom (x_pos, y_pos)
2807{
2808}
2809
2810DEFUN ("x-select-region", Fx_select_region, Sx_select_region, 1, 1, "e",
2811 "")
2812 (event)
2813 Lisp_Object event;
2814{
f676886a
JB
2815 register struct frame *f = selected_frame;
2816 register int point_x = f->cursor_x;
2817 register int point_y = f->cursor_y;
01f1ba30
JB
2818 register int mouse_below_point;
2819 register Lisp_Object obj;
2820 register int x_contour_x, x_contour_y;
2821
2822 x_contour_x = x_mouse_x;
2823 x_contour_y = x_mouse_y;
2824 if (x_contour_y > point_y || (x_contour_y == point_y
2825 && x_contour_x > point_x))
2826 {
2827 mouse_below_point = 1;
f676886a 2828 outline_region (f, f->display.x->cursor_gc, point_x, point_y,
01f1ba30
JB
2829 x_contour_x, x_contour_y);
2830 }
2831 else
2832 {
2833 mouse_below_point = 0;
f676886a 2834 outline_region (f, f->display.x->cursor_gc, x_contour_x, x_contour_y,
01f1ba30
JB
2835 point_x, point_y);
2836 }
2837
2838 while (1)
2839 {
95be70ed 2840 obj = read_char (-1, 0, 0, Qnil, 0);
01f1ba30
JB
2841 if (XTYPE (obj) != Lisp_Cons)
2842 break;
2843
2844 if (mouse_below_point)
2845 {
2846 if (x_mouse_y <= point_y) /* Flipped. */
2847 {
2848 mouse_below_point = 0;
2849
f676886a 2850 outline_region (f, f->display.x->reverse_gc, point_x, point_y,
01f1ba30 2851 x_contour_x, x_contour_y);
f676886a 2852 outline_region (f, f->display.x->cursor_gc, x_mouse_x, x_mouse_y,
01f1ba30
JB
2853 point_x, point_y);
2854 }
2855 else if (x_mouse_y < x_contour_y) /* Bottom clipped. */
2856 {
2857 clip_contour_bottom (x_mouse_y);
2858 }
2859 else if (x_mouse_y > x_contour_y) /* Bottom extended. */
2860 {
2861 extend_bottom_contour (x_mouse_y);
2862 }
2863
2864 x_contour_x = x_mouse_x;
2865 x_contour_y = x_mouse_y;
2866 }
2867 else /* mouse above or same line as point */
2868 {
2869 if (x_mouse_y >= point_y) /* Flipped. */
2870 {
2871 mouse_below_point = 1;
2872
f676886a 2873 outline_region (f, f->display.x->reverse_gc,
01f1ba30 2874 x_contour_x, x_contour_y, point_x, point_y);
f676886a 2875 outline_region (f, f->display.x->cursor_gc, point_x, point_y,
01f1ba30
JB
2876 x_mouse_x, x_mouse_y);
2877 }
2878 else if (x_mouse_y > x_contour_y) /* Top clipped. */
2879 {
2880 clip_contour_top (x_mouse_y);
2881 }
2882 else if (x_mouse_y < x_contour_y) /* Top extended. */
2883 {
2884 extend_contour_top (x_mouse_y);
2885 }
2886 }
2887 }
2888
b4f5687c 2889 unread_command_event = obj;
01f1ba30
JB
2890 if (mouse_below_point)
2891 {
2892 contour_begin_x = point_x;
2893 contour_begin_y = point_y;
2894 contour_end_x = x_contour_x;
2895 contour_end_y = x_contour_y;
2896 }
2897 else
2898 {
2899 contour_begin_x = x_contour_x;
2900 contour_begin_y = x_contour_y;
2901 contour_end_x = point_x;
2902 contour_end_y = point_y;
2903 }
2904}
2905#endif
2906
2907DEFUN ("x-horizontal-line", Fx_horizontal_line, Sx_horizontal_line, 1, 1, "e",
2908 "")
2909 (event)
2910 Lisp_Object event;
2911{
2912 register Lisp_Object obj;
f676886a 2913 struct frame *f = selected_frame;
01f1ba30 2914 register struct window *w = XWINDOW (selected_window);
f676886a
JB
2915 register GC line_gc = f->display.x->cursor_gc;
2916 register GC erase_gc = f->display.x->reverse_gc;
01f1ba30
JB
2917#if 0
2918 char dash_list[] = {6, 4, 6, 4};
2919 int dashes = 4;
2920 XGCValues gc_values;
2921#endif
2922 register int previous_y;
f676886a
JB
2923 register int line = (x_mouse_y + 1) * FONT_HEIGHT (f->display.x->font)
2924 + f->display.x->internal_border_width;
2925 register int left = f->display.x->internal_border_width
01f1ba30 2926 + (w->left
f676886a 2927 * FONT_WIDTH (f->display.x->font));
01f1ba30 2928 register int right = left + (w->width
f676886a
JB
2929 * FONT_WIDTH (f->display.x->font))
2930 - f->display.x->internal_border_width;
01f1ba30
JB
2931
2932#if 0
2933 BLOCK_INPUT;
f676886a
JB
2934 gc_values.foreground = f->display.x->cursor_pixel;
2935 gc_values.background = f->display.x->background_pixel;
01f1ba30
JB
2936 gc_values.line_width = 1;
2937 gc_values.line_style = LineOnOffDash;
2938 gc_values.cap_style = CapRound;
2939 gc_values.join_style = JoinRound;
2940
fe24a618 2941 line_gc = XCreateGC (x_current_display, FRAME_X_WINDOW (f),
01f1ba30
JB
2942 GCLineStyle | GCJoinStyle | GCCapStyle
2943 | GCLineWidth | GCForeground | GCBackground,
2944 &gc_values);
2945 XSetDashes (x_current_display, line_gc, 0, dash_list, dashes);
f676886a
JB
2946 gc_values.foreground = f->display.x->background_pixel;
2947 gc_values.background = f->display.x->foreground_pixel;
fe24a618 2948 erase_gc = XCreateGC (x_current_display, FRAME_X_WINDOW (f),
01f1ba30
JB
2949 GCLineStyle | GCJoinStyle | GCCapStyle
2950 | GCLineWidth | GCForeground | GCBackground,
2951 &gc_values);
2952 XSetDashes (x_current_display, erase_gc, 0, dash_list, dashes);
2953#endif
2954
2955 while (1)
2956 {
2957 BLOCK_INPUT;
2958 if (x_mouse_y >= XINT (w->top)
2959 && x_mouse_y < XINT (w->top) + XINT (w->height) - 1)
2960 {
2961 previous_y = x_mouse_y;
f676886a
JB
2962 line = (x_mouse_y + 1) * FONT_HEIGHT (f->display.x->font)
2963 + f->display.x->internal_border_width;
fe24a618 2964 XDrawLine (x_current_display, FRAME_X_WINDOW (f),
01f1ba30
JB
2965 line_gc, left, line, right, line);
2966 }
2967 XFlushQueue ();
2968 UNBLOCK_INPUT;
2969
2970 do
2971 {
95be70ed 2972 obj = read_char (-1, 0, 0, Qnil, 0);
01f1ba30
JB
2973 if ((XTYPE (obj) != Lisp_Cons)
2974 || (! EQ (Fcar (Fcdr (Fcdr (obj))),
f9942c9e 2975 Qvertical_scroll_bar))
01f1ba30
JB
2976 || x_mouse_grabbed)
2977 {
2978 BLOCK_INPUT;
fe24a618 2979 XDrawLine (x_current_display, FRAME_X_WINDOW (f),
01f1ba30
JB
2980 erase_gc, left, line, right, line);
2981 UNBLOCK_INPUT;
b4f5687c 2982 unread_command_event = obj;
01f1ba30
JB
2983#if 0
2984 XFreeGC (x_current_display, line_gc);
2985 XFreeGC (x_current_display, erase_gc);
2986#endif
2987 return Qnil;
2988 }
2989 }
2990 while (x_mouse_y == previous_y);
2991
2992 BLOCK_INPUT;
fe24a618 2993 XDrawLine (x_current_display, FRAME_X_WINDOW (f),
01f1ba30
JB
2994 erase_gc, left, line, right, line);
2995 UNBLOCK_INPUT;
2996 }
2997}
06ef7355 2998#endif
01f1ba30 2999\f
01f1ba30
JB
3000/* Offset in buffer of character under the pointer, or 0. */
3001int mouse_buffer_offset;
3002
3003#if 0
3004/* These keep track of the rectangle following the pointer. */
3005int mouse_track_top, mouse_track_left, mouse_track_width;
3006
3007DEFUN ("x-track-pointer", Fx_track_pointer, Sx_track_pointer, 0, 0, 0,
3008 "Track the pointer.")
3009 ()
3010{
3011 static Cursor current_pointer_shape;
f676886a 3012 FRAME_PTR f = x_mouse_frame;
01f1ba30
JB
3013
3014 BLOCK_INPUT;
f676886a
JB
3015 if (EQ (Vmouse_frame_part, Qtext_part)
3016 && (current_pointer_shape != f->display.x->nontext_cursor))
01f1ba30
JB
3017 {
3018 unsigned char c;
3019 struct buffer *buf;
3020
f676886a 3021 current_pointer_shape = f->display.x->nontext_cursor;
01f1ba30 3022 XDefineCursor (x_current_display,
fe24a618 3023 FRAME_X_WINDOW (f),
01f1ba30
JB
3024 current_pointer_shape);
3025
3026 buf = XBUFFER (XWINDOW (Vmouse_window)->buffer);
3027 c = *(BUF_CHAR_ADDRESS (buf, mouse_buffer_offset));
3028 }
f676886a
JB
3029 else if (EQ (Vmouse_frame_part, Qmodeline_part)
3030 && (current_pointer_shape != f->display.x->modeline_cursor))
01f1ba30 3031 {
f676886a 3032 current_pointer_shape = f->display.x->modeline_cursor;
01f1ba30 3033 XDefineCursor (x_current_display,
fe24a618 3034 FRAME_X_WINDOW (f),
01f1ba30
JB
3035 current_pointer_shape);
3036 }
3037
3038 XFlushQueue ();
3039 UNBLOCK_INPUT;
3040}
3041#endif
3042
3043#if 0
3044DEFUN ("x-track-pointer", Fx_track_pointer, Sx_track_pointer, 1, 1, "e",
3045 "Draw rectangle around character under mouse pointer, if there is one.")
3046 (event)
3047 Lisp_Object event;
3048{
3049 struct window *w = XWINDOW (Vmouse_window);
f676886a 3050 struct frame *f = XFRAME (WINDOW_FRAME (w));
01f1ba30
JB
3051 struct buffer *b = XBUFFER (w->buffer);
3052 Lisp_Object obj;
3053
3054 if (! EQ (Vmouse_window, selected_window))
3055 return Qnil;
3056
3057 if (EQ (event, Qnil))
3058 {
3059 int x, y;
3060
f676886a 3061 x_read_mouse_position (selected_frame, &x, &y);
01f1ba30
JB
3062 }
3063
3064 BLOCK_INPUT;
3065 mouse_track_width = 0;
3066 mouse_track_left = mouse_track_top = -1;
3067
3068 do
3069 {
3070 if ((x_mouse_x != mouse_track_left
3071 && (x_mouse_x < mouse_track_left
3072 || x_mouse_x > (mouse_track_left + mouse_track_width)))
3073 || x_mouse_y != mouse_track_top)
3074 {
3075 int hp = 0; /* Horizontal position */
f676886a
JB
3076 int len = FRAME_CURRENT_GLYPHS (f)->used[x_mouse_y];
3077 int p = FRAME_CURRENT_GLYPHS (f)->bufp[x_mouse_y];
01f1ba30 3078 int tab_width = XINT (b->tab_width);
265a9e55 3079 int ctl_arrow_p = !NILP (b->ctl_arrow);
01f1ba30
JB
3080 unsigned char c;
3081 int mode_line_vpos = XFASTINT (w->height) + XFASTINT (w->top) - 1;
3082 int in_mode_line = 0;
3083
f676886a 3084 if (! FRAME_CURRENT_GLYPHS (f)->enable[x_mouse_y])
01f1ba30
JB
3085 break;
3086
3087 /* Erase previous rectangle. */
3088 if (mouse_track_width)
3089 {
f676886a 3090 x_rectangle (f, f->display.x->reverse_gc,
01f1ba30
JB
3091 mouse_track_left, mouse_track_top,
3092 mouse_track_width, 1);
3093
f676886a
JB
3094 if ((mouse_track_left == f->phys_cursor_x
3095 || mouse_track_left == f->phys_cursor_x - 1)
3096 && mouse_track_top == f->phys_cursor_y)
01f1ba30 3097 {
f676886a 3098 x_display_cursor (f, 1);
01f1ba30
JB
3099 }
3100 }
3101
3102 mouse_track_left = x_mouse_x;
3103 mouse_track_top = x_mouse_y;
3104 mouse_track_width = 0;
3105
3106 if (mouse_track_left > len) /* Past the end of line. */
3107 goto draw_or_not;
3108
3109 if (mouse_track_top == mode_line_vpos)
3110 {
3111 in_mode_line = 1;
3112 goto draw_or_not;
3113 }
3114
3115 if (tab_width <= 0 || tab_width > 20) tab_width = 8;
3116 do
3117 {
3118 c = FETCH_CHAR (p);
f676886a 3119 if (len == f->width && hp == len - 1 && c != '\n')
01f1ba30
JB
3120 goto draw_or_not;
3121
3122 switch (c)
3123 {
3124 case '\t':
3125 mouse_track_width = tab_width - (hp % tab_width);
3126 p++;
3127 hp += mouse_track_width;
3128 if (hp > x_mouse_x)
3129 {
3130 mouse_track_left = hp - mouse_track_width;
3131 goto draw_or_not;
3132 }
3133 continue;
3134
3135 case '\n':
3136 mouse_track_width = -1;
3137 goto draw_or_not;
3138
3139 default:
3140 if (ctl_arrow_p && (c < 040 || c == 0177))
3141 {
3142 if (p > ZV)
3143 goto draw_or_not;
3144
3145 mouse_track_width = 2;
3146 p++;
3147 hp +=2;
3148 if (hp > x_mouse_x)
3149 {
3150 mouse_track_left = hp - mouse_track_width;
3151 goto draw_or_not;
3152 }
3153 }
3154 else
3155 {
3156 mouse_track_width = 1;
3157 p++;
3158 hp++;
3159 }
3160 continue;
3161 }
3162 }
3163 while (hp <= x_mouse_x);
3164
3165 draw_or_not:
3166 if (mouse_track_width) /* Over text; use text pointer shape. */
3167 {
3168 XDefineCursor (x_current_display,
fe24a618 3169 FRAME_X_WINDOW (f),
f676886a
JB
3170 f->display.x->text_cursor);
3171 x_rectangle (f, f->display.x->cursor_gc,
01f1ba30
JB
3172 mouse_track_left, mouse_track_top,
3173 mouse_track_width, 1);
3174 }
3175 else if (in_mode_line)
3176 XDefineCursor (x_current_display,
fe24a618 3177 FRAME_X_WINDOW (f),
f676886a 3178 f->display.x->modeline_cursor);
01f1ba30
JB
3179 else
3180 XDefineCursor (x_current_display,
fe24a618 3181 FRAME_X_WINDOW (f),
f676886a 3182 f->display.x->nontext_cursor);
01f1ba30
JB
3183 }
3184
3185 XFlush (x_current_display);
3186 UNBLOCK_INPUT;
3187
95be70ed 3188 obj = read_char (-1, 0, 0, Qnil, 0);
01f1ba30
JB
3189 BLOCK_INPUT;
3190 }
3191 while (XTYPE (obj) == Lisp_Cons /* Mouse event */
a3c87d4e 3192 && EQ (Fcar (Fcdr (Fcdr (obj))), Qnil) /* Not scroll bar */
01f1ba30
JB
3193 && EQ (Vmouse_depressed, Qnil) /* Only motion events */
3194 && EQ (Vmouse_window, selected_window) /* In this window */
f676886a 3195 && x_mouse_frame);
01f1ba30 3196
b4f5687c 3197 unread_command_event = obj;
01f1ba30
JB
3198
3199 if (mouse_track_width)
3200 {
f676886a 3201 x_rectangle (f, f->display.x->reverse_gc,
01f1ba30
JB
3202 mouse_track_left, mouse_track_top,
3203 mouse_track_width, 1);
3204 mouse_track_width = 0;
f676886a
JB
3205 if ((mouse_track_left == f->phys_cursor_x
3206 || mouse_track_left - 1 == f->phys_cursor_x)
3207 && mouse_track_top == f->phys_cursor_y)
01f1ba30 3208 {
f676886a 3209 x_display_cursor (f, 1);
01f1ba30
JB
3210 }
3211 }
3212 XDefineCursor (x_current_display,
fe24a618 3213 FRAME_X_WINDOW (f),
f676886a 3214 f->display.x->nontext_cursor);
01f1ba30
JB
3215 XFlush (x_current_display);
3216 UNBLOCK_INPUT;
3217
3218 return Qnil;
3219}
3220#endif
3221\f
3222#if 0
3223#include "glyphs.h"
3224
3225/* Draw a pixmap specified by IMAGE_DATA of dimensions WIDTH and HEIGHT
f676886a 3226 on the frame F at position X, Y. */
01f1ba30 3227
f676886a
JB
3228x_draw_pixmap (f, x, y, image_data, width, height)
3229 struct frame *f;
01f1ba30
JB
3230 int x, y, width, height;
3231 char *image_data;
3232{
3233 Pixmap image;
3234
3235 image = XCreateBitmapFromData (x_current_display,
fe24a618 3236 FRAME_X_WINDOW (f), image_data,
01f1ba30 3237 width, height);
fe24a618 3238 XCopyPlane (x_current_display, image, FRAME_X_WINDOW (f),
f676886a 3239 f->display.x->normal_gc, 0, 0, width, height, x, y);
01f1ba30
JB
3240}
3241#endif
3242\f
01f1ba30
JB
3243#ifndef HAVE_X11
3244DEFUN ("x-store-cut-buffer", Fx_store_cut_buffer, Sx_store_cut_buffer,
3245 1, 1, "sStore text in cut buffer: ",
3246 "Store contents of STRING into the cut buffer of the X window system.")
3247 (string)
3248 register Lisp_Object string;
3249{
3250 int mask;
3251
3252 CHECK_STRING (string, 1);
f9942c9e 3253 if (! FRAME_X_P (selected_frame))
f676886a 3254 error ("Selected frame does not understand X protocol.");
01f1ba30
JB
3255
3256 BLOCK_INPUT;
3257 XStoreBytes ((char *) XSTRING (string)->data, XSTRING (string)->size);
3258 UNBLOCK_INPUT;
3259
3260 return Qnil;
3261}
3262
3263DEFUN ("x-get-cut-buffer", Fx_get_cut_buffer, Sx_get_cut_buffer, 0, 0, 0,
3264 "Return contents of cut buffer of the X window system, as a string.")
3265 ()
3266{
3267 int len;
3268 register Lisp_Object string;
3269 int mask;
3270 register char *d;
3271
3272 BLOCK_INPUT;
3273 d = XFetchBytes (&len);
3274 string = make_string (d, len);
3275 XFree (d);
3276 UNBLOCK_INPUT;
3277 return string;
3278}
3279#endif /* X10 */
3280\f
3281#ifdef HAVE_X11
3282DEFUN ("x-rebind-key", Fx_rebind_key, Sx_rebind_key, 3, 3, 0,
3283"Rebind X keysym KEYSYM, with MODIFIERS, to generate NEWSTRING.\n\
3284KEYSYM is a string which conforms to the X keysym definitions found\n\
3285in X11/keysymdef.h, sans the initial XK_. MODIFIERS is nil or a\n\
3286list of strings specifying modifier keys such as Control_L, which must\n\
3287also be depressed for NEWSTRING to appear.")
3288 (x_keysym, modifiers, newstring)
3289 register Lisp_Object x_keysym;
3290 register Lisp_Object modifiers;
3291 register Lisp_Object newstring;
3292{
3293 char *rawstring;
c047688c
JA
3294 register KeySym keysym;
3295 KeySym modifier_list[16];
01f1ba30 3296
11ae94fe 3297 check_x ();
01f1ba30
JB
3298 CHECK_STRING (x_keysym, 1);
3299 CHECK_STRING (newstring, 3);
3300
3301 keysym = XStringToKeysym ((char *) XSTRING (x_keysym)->data);
3302 if (keysym == NoSymbol)
3303 error ("Keysym does not exist");
3304
265a9e55 3305 if (NILP (modifiers))
01f1ba30
JB
3306 XRebindKeysym (x_current_display, keysym, modifier_list, 0,
3307 XSTRING (newstring)->data, XSTRING (newstring)->size);
3308 else
3309 {
3310 register Lisp_Object rest, mod;
3311 register int i = 0;
3312
265a9e55 3313 for (rest = modifiers; !NILP (rest); rest = Fcdr (rest))
01f1ba30
JB
3314 {
3315 if (i == 16)
3316 error ("Can't have more than 16 modifiers");
3317
3318 mod = Fcar (rest);
3319 CHECK_STRING (mod, 3);
3320 modifier_list[i] = XStringToKeysym ((char *) XSTRING (mod)->data);
3321 if (modifier_list[i] == NoSymbol
3322 || !IsModifierKey (modifier_list[i]))
3323 error ("Element is not a modifier keysym");
3324 i++;
3325 }
3326
3327 XRebindKeysym (x_current_display, keysym, modifier_list, i,
3328 XSTRING (newstring)->data, XSTRING (newstring)->size);
3329 }
3330
3331 return Qnil;
3332}
3333
3334DEFUN ("x-rebind-keys", Fx_rebind_keys, Sx_rebind_keys, 2, 2, 0,
3335 "Rebind KEYCODE to list of strings STRINGS.\n\
3336STRINGS should be a list of 16 elements, one for each shift combination.\n\
3337nil as element means don't change.\n\
3338See the documentation of `x-rebind-key' for more information.")
3339 (keycode, strings)
3340 register Lisp_Object keycode;
3341 register Lisp_Object strings;
3342{
3343 register Lisp_Object item;
3344 register unsigned char *rawstring;
3345 KeySym rawkey, modifier[1];
3346 int strsize;
3347 register unsigned i;
3348
11ae94fe 3349 check_x ();
01f1ba30
JB
3350 CHECK_NUMBER (keycode, 1);
3351 CHECK_CONS (strings, 2);
3352 rawkey = (KeySym) ((unsigned) (XINT (keycode))) & 255;
3353 for (i = 0; i <= 15; strings = Fcdr (strings), i++)
3354 {
3355 item = Fcar (strings);
265a9e55 3356 if (!NILP (item))
01f1ba30
JB
3357 {
3358 CHECK_STRING (item, 2);
3359 strsize = XSTRING (item)->size;
3360 rawstring = (unsigned char *) xmalloc (strsize);
3361 bcopy (XSTRING (item)->data, rawstring, strsize);
3362 modifier[1] = 1 << i;
3363 XRebindKeysym (x_current_display, rawkey, modifier, 1,
3364 rawstring, strsize);
3365 }
3366 }
3367 return Qnil;
3368}
9d04a87a 3369#endif /* HAVE_X11 */
01f1ba30
JB
3370\f
3371#ifdef HAVE_X11
3372Visual *
3373select_visual (screen, depth)
3374 Screen *screen;
3375 unsigned int *depth;
3376{
3377 Visual *v;
3378 XVisualInfo *vinfo, vinfo_template;
3379 int n_visuals;
3380
3381 v = DefaultVisualOfScreen (screen);
fe24a618
JB
3382
3383#ifdef HAVE_X11R4
3384 vinfo_template.visualid = XVisualIDFromVisual (v);
3385#else
6afb1d07 3386 vinfo_template.visualid = v->visualid;
fe24a618
JB
3387#endif
3388
f0614854
JB
3389 vinfo_template.screen = XScreenNumberOfScreen (screen);
3390
3391 vinfo = XGetVisualInfo (x_current_display,
3392 VisualIDMask | VisualScreenMask, &vinfo_template,
01f1ba30
JB
3393 &n_visuals);
3394 if (n_visuals != 1)
3395 fatal ("Can't get proper X visual info");
3396
3397 if ((1 << vinfo->depth) == vinfo->colormap_size)
3398 *depth = vinfo->depth;
3399 else
3400 {
3401 int i = 0;
3402 int n = vinfo->colormap_size - 1;
3403 while (n)
3404 {
3405 n = n >> 1;
3406 i++;
3407 }
3408 *depth = i;
3409 }
3410
3411 XFree ((char *) vinfo);
3412 return v;
3413}
3414#endif /* HAVE_X11 */
3415
3416DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
3417 1, 2, 0, "Open a connection to an X server.\n\
3418DISPLAY is the name of the display to connect to. Optional second\n\
3419arg XRM_STRING is a string of resources in xrdb format.")
3420 (display, xrm_string)
3421 Lisp_Object display, xrm_string;
3422{
3423 unsigned int n_planes;
01f1ba30
JB
3424 unsigned char *xrm_option;
3425
3426 CHECK_STRING (display, 0);
3427 if (x_current_display != 0)
3428 error ("X server connection is already initialized");
3429
3430 /* This is what opens the connection and sets x_current_display.
3431 This also initializes many symbols, such as those used for input. */
3432 x_term_init (XSTRING (display)->data);
3433
01f1ba30
JB
3434#ifdef HAVE_X11
3435 XFASTINT (Vwindow_system_version) = 11;
3436
3437 if (!EQ (xrm_string, Qnil))
3438 {
3439 CHECK_STRING (xrm_string, 1);
6c703f4a 3440 xrm_option = (unsigned char *) XSTRING (xrm_string)->data;
01f1ba30
JB
3441 }
3442 else
3443 xrm_option = (unsigned char *) 0;
3444 xrdb = x_load_resources (x_current_display, xrm_option, EMACS_CLASS);
eb5d618c
JB
3445#ifdef HAVE_X11R5
3446 XrmSetDatabase (x_current_display, xrdb);
3447#else
01f1ba30 3448 x_current_display->db = xrdb;
eb5d618c 3449#endif
01f1ba30 3450
ac63d3d6
JB
3451 /* Make a version of Vinvocation_name suitable for use in xrdb
3452 queries - i.e. containing no dots or asterisks. */
3453 Vxrdb_name = Fcopy_sequence (Vinvocation_name);
3454 {
3455 int i;
3456 int len = XSTRING (Vxrdb_name)->size;
3457 char *data = XSTRING (Vxrdb_name)->data;
3458
3459 for (i = 0; i < len; i++)
3460 if (data[i] == '.' || data[i] == '*')
3461 data[i] = '-';
3462 }
3463
01f1ba30
JB
3464 x_screen = DefaultScreenOfDisplay (x_current_display);
3465
01f1ba30 3466 screen_visual = select_visual (x_screen, &n_planes);
a6605e5c 3467 x_screen_planes = n_planes;
41beb8fc
RS
3468 x_screen_height = HeightOfScreen (x_screen);
3469 x_screen_width = WidthOfScreen (x_screen);
01f1ba30
JB
3470
3471 /* X Atoms used by emacs. */
99e72068 3472 Xatoms_of_xselect ();
01f1ba30 3473 BLOCK_INPUT;
3c254570
JA
3474 Xatom_wm_protocols = XInternAtom (x_current_display, "WM_PROTOCOLS",
3475 False);
3476 Xatom_wm_take_focus = XInternAtom (x_current_display, "WM_TAKE_FOCUS",
3477 False);
3478 Xatom_wm_save_yourself = XInternAtom (x_current_display, "WM_SAVE_YOURSELF",
3479 False);
3480 Xatom_wm_delete_window = XInternAtom (x_current_display, "WM_DELETE_WINDOW",
3481 False);
3482 Xatom_wm_change_state = XInternAtom (x_current_display, "WM_CHANGE_STATE",
3483 False);
3484 Xatom_wm_configure_denied = XInternAtom (x_current_display,
3485 "WM_CONFIGURE_DENIED", False);
3486 Xatom_wm_window_moved = XInternAtom (x_current_display, "WM_MOVED",
3487 False);
01f1ba30
JB
3488 UNBLOCK_INPUT;
3489#else /* not HAVE_X11 */
3490 XFASTINT (Vwindow_system_version) = 10;
3491#endif /* not HAVE_X11 */
3492 return Qnil;
3493}
3494
3495DEFUN ("x-close-current-connection", Fx_close_current_connection,
3496 Sx_close_current_connection,
3497 0, 0, 0, "Close the connection to the current X server.")
3498 ()
3499{
3500#ifdef HAVE_X11
3501 /* This is ONLY used when killing emacs; For switching displays
3502 we'll have to take care of setting CloseDownMode elsewhere. */
3503
3504 if (x_current_display)
3505 {
3506 BLOCK_INPUT;
3507 XSetCloseDownMode (x_current_display, DestroyAll);
3508 XCloseDisplay (x_current_display);
3509 }
3510 else
3511 fatal ("No current X display connection to close\n");
3512#endif
3513 return Qnil;
3514}
3515
3516DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize,
3517 1, 1, 0, "If ON is non-nil, report X errors as soon as the erring request is made.\n\
3518If ON is nil, allow buffering of requests.\n\
3519Turning on synchronization prohibits the Xlib routines from buffering\n\
3520requests and seriously degrades performance, but makes debugging much\n\
3521easier.")
3522 (on)
3523 Lisp_Object on;
3524{
11ae94fe
RS
3525 check_x ();
3526
01f1ba30
JB
3527 XSynchronize (x_current_display, !EQ (on, Qnil));
3528
3529 return Qnil;
3530}
3531
3532\f
3533syms_of_xfns ()
3534{
01f1ba30
JB
3535 /* This is zero if not using X windows. */
3536 x_current_display = 0;
3537
f9942c9e
JB
3538 /* The section below is built by the lisp expression at the top of the file,
3539 just above where these variables are declared. */
3540 /*&&& init symbols here &&&*/
3541 Qauto_raise = intern ("auto-raise");
3542 staticpro (&Qauto_raise);
3543 Qauto_lower = intern ("auto-lower");
3544 staticpro (&Qauto_lower);
3545 Qbackground_color = intern ("background-color");
3546 staticpro (&Qbackground_color);
dbc4e1c1
JB
3547 Qbar = intern ("bar");
3548 staticpro (&Qbar);
f9942c9e
JB
3549 Qborder_color = intern ("border-color");
3550 staticpro (&Qborder_color);
3551 Qborder_width = intern ("border-width");
3552 staticpro (&Qborder_width);
dbc4e1c1
JB
3553 Qbox = intern ("box");
3554 staticpro (&Qbox);
f9942c9e
JB
3555 Qcursor_color = intern ("cursor-color");
3556 staticpro (&Qcursor_color);
dbc4e1c1
JB
3557 Qcursor_type = intern ("cursor-type");
3558 staticpro (&Qcursor_type);
f9942c9e
JB
3559 Qfont = intern ("font");
3560 staticpro (&Qfont);
3561 Qforeground_color = intern ("foreground-color");
3562 staticpro (&Qforeground_color);
3563 Qgeometry = intern ("geometry");
3564 staticpro (&Qgeometry);
49795535
JB
3565 Qicon = intern ("icon");
3566 staticpro (&Qicon);
f9942c9e
JB
3567 Qicon_left = intern ("icon-left");
3568 staticpro (&Qicon_left);
3569 Qicon_top = intern ("icon-top");
3570 staticpro (&Qicon_top);
3571 Qicon_type = intern ("icon-type");
3572 staticpro (&Qicon_type);
f9942c9e
JB
3573 Qinternal_border_width = intern ("internal-border-width");
3574 staticpro (&Qinternal_border_width);
3575 Qleft = intern ("left");
3576 staticpro (&Qleft);
3577 Qmouse_color = intern ("mouse-color");
3578 staticpro (&Qmouse_color);
baaed68e
JB
3579 Qnone = intern ("none");
3580 staticpro (&Qnone);
f9942c9e
JB
3581 Qparent_id = intern ("parent-id");
3582 staticpro (&Qparent_id);
8af1d7ca
JB
3583 Qsuppress_icon = intern ("suppress-icon");
3584 staticpro (&Qsuppress_icon);
f9942c9e
JB
3585 Qtop = intern ("top");
3586 staticpro (&Qtop);
01f1ba30 3587 Qundefined_color = intern ("undefined-color");
f9942c9e 3588 staticpro (&Qundefined_color);
a3c87d4e
JB
3589 Qvertical_scroll_bars = intern ("vertical-scroll-bars");
3590 staticpro (&Qvertical_scroll_bars);
49795535
JB
3591 Qvisibility = intern ("visibility");
3592 staticpro (&Qvisibility);
f9942c9e
JB
3593 Qwindow_id = intern ("window-id");
3594 staticpro (&Qwindow_id);
3595 Qx_frame_parameter = intern ("x-frame-parameter");
3596 staticpro (&Qx_frame_parameter);
3597 /* This is the end of symbol initialization. */
3598
01f1ba30
JB
3599 Fput (Qundefined_color, Qerror_conditions,
3600 Fcons (Qundefined_color, Fcons (Qerror, Qnil)));
3601 Fput (Qundefined_color, Qerror_message,
3602 build_string ("Undefined color"));
3603
f9942c9e
JB
3604 init_x_parm_symbols ();
3605
01f1ba30
JB
3606 DEFVAR_INT ("mouse-buffer-offset", &mouse_buffer_offset,
3607 "The buffer offset of the character under the pointer.");
a6605e5c 3608 mouse_buffer_offset = 0;
01f1ba30 3609
01f1ba30 3610 DEFVAR_INT ("x-pointer-shape", &Vx_pointer_shape,
af01ef26
RS
3611 "The shape of the pointer when over text.\n\
3612Changing the value does not affect existing frames\n\
3613unless you set the mouse color.");
01f1ba30
JB
3614 Vx_pointer_shape = Qnil;
3615
ac63d3d6
JB
3616 staticpro (&Vxrdb_name);
3617
af01ef26 3618#if 0
01f1ba30
JB
3619 DEFVAR_INT ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape,
3620 "The shape of the pointer when not over text.");
af01ef26 3621#endif
01f1ba30
JB
3622 Vx_nontext_pointer_shape = Qnil;
3623
af01ef26 3624#if 0
01f1ba30 3625 DEFVAR_INT ("x-mode-pointer-shape", &Vx_mode_pointer_shape,
06ef7355 3626 "The shape of the pointer when over the mode line.");
af01ef26 3627#endif
01f1ba30
JB
3628 Vx_mode_pointer_shape = Qnil;
3629
01f1ba30
JB
3630 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel,
3631 "A string indicating the foreground color of the cursor box.");
3632 Vx_cursor_fore_pixel = Qnil;
3633
3634 DEFVAR_LISP ("mouse-grabbed", &Vmouse_depressed,
3635 "Non-nil if a mouse button is currently depressed.");
3636 Vmouse_depressed = Qnil;
3637
01f1ba30
JB
3638 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
3639 "t if no X window manager is in use.");
3640
3641#ifdef HAVE_X11
3642 defsubr (&Sx_get_resource);
85ffea93 3643#if 0
01f1ba30
JB
3644 defsubr (&Sx_draw_rectangle);
3645 defsubr (&Sx_erase_rectangle);
3646 defsubr (&Sx_contour_region);
3647 defsubr (&Sx_uncontour_region);
85ffea93 3648#endif
bcc426b4 3649 defsubr (&Sx_display_color_p);
f0614854 3650 defsubr (&Sx_list_fonts);
8af1d7ca 3651 defsubr (&Sx_color_defined_p);
41beb8fc
RS
3652 defsubr (&Sx_server_vendor);
3653 defsubr (&Sx_server_version);
3654 defsubr (&Sx_display_pixel_width);
3655 defsubr (&Sx_display_pixel_height);
3656 defsubr (&Sx_display_mm_width);
3657 defsubr (&Sx_display_mm_height);
3658 defsubr (&Sx_display_screens);
3659 defsubr (&Sx_display_planes);
3660 defsubr (&Sx_display_color_cells);
3661 defsubr (&Sx_display_visual_class);
3662 defsubr (&Sx_display_backing_store);
3663 defsubr (&Sx_display_save_under);
9d04a87a
RS
3664 defsubr (&Sx_rebind_key);
3665 defsubr (&Sx_rebind_keys);
01f1ba30
JB
3666#if 0
3667 defsubr (&Sx_track_pointer);
01f1ba30
JB
3668 defsubr (&Sx_grab_pointer);
3669 defsubr (&Sx_ungrab_pointer);
809ca691 3670#endif
01f1ba30
JB
3671#else
3672 defsubr (&Sx_get_default);
3673 defsubr (&Sx_store_cut_buffer);
3674 defsubr (&Sx_get_cut_buffer);
01f1ba30 3675#endif
8af1d7ca 3676 defsubr (&Sx_parse_geometry);
f676886a
JB
3677 defsubr (&Sx_create_frame);
3678 defsubr (&Sfocus_frame);
3679 defsubr (&Sunfocus_frame);
06ef7355 3680#if 0
01f1ba30 3681 defsubr (&Sx_horizontal_line);
06ef7355 3682#endif
01f1ba30
JB
3683 defsubr (&Sx_open_connection);
3684 defsubr (&Sx_close_current_connection);
3685 defsubr (&Sx_synchronize);
01f1ba30
JB
3686}
3687
3688#endif /* HAVE_X_WINDOWS */