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