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