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