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