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