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