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