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