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