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