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