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