(Fx_create_frame): Set xlwmenu_default_font.
[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 {
8d45a19e 2269 Dimension ibw;
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
82c90203
RS
2670 /* Prevent lwlib/xlwmenu.c from crashing because of a bug
2671 whereby it fails to get any font. */
2672 xlwmenu_default_font = f->display.x->font;
2673
cf177271
JB
2674 x_default_parameter (f, parms, Qborder_width, make_number (2),
2675 "borderwidth", "BorderWidth", number);
ddf768c3
JB
2676 /* This defaults to 2 in order to match xterm. We recognize either
2677 internalBorderWidth or internalBorder (which is what xterm calls
2678 it). */
2679 if (NILP (Fassq (Qinternal_border_width, parms)))
2680 {
2681 Lisp_Object value;
2682
2683 value = x_get_arg (parms, Qinternal_border_width,
2684 "internalBorder", "BorderWidth", number);
2685 if (! EQ (value, Qunbound))
2686 parms = Fcons (Fcons (Qinternal_border_width, value),
2687 parms);
2688 }
cf177271
JB
2689 x_default_parameter (f, parms, Qinternal_border_width, make_number (2),
2690 "internalBorderWidth", "BorderWidth", number);
a3c87d4e
JB
2691 x_default_parameter (f, parms, Qvertical_scroll_bars, Qt,
2692 "verticalScrollBars", "ScrollBars", boolean);
01f1ba30 2693
b9dc4443 2694 /* Also do the stuff which must be set before the window exists. */
cf177271
JB
2695 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
2696 "foreground", "Foreground", string);
2697 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
2698 "background", "Background", string);
2699 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
2700 "pointerColor", "Foreground", string);
2701 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
2702 "cursorColor", "Foreground", string);
2703 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
2704 "borderColor", "BorderColor", string);
01f1ba30 2705
c7bcb20d 2706 x_default_parameter (f, parms, Qmenu_bar_lines, make_number (1),
e1d962d7 2707 "menuBar", "MenuBar", number);
dff9a538 2708 x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
4701395c 2709 "scrollBarWidth", "ScrollBarWidth", number);
90eb1019 2710
b9dc4443 2711 f->display.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
f676886a 2712 window_prompting = x_figure_window_size (f, parms);
01f1ba30 2713
f83f10ba 2714 if (window_prompting & XNegative)
2365c027 2715 {
f83f10ba
RS
2716 if (window_prompting & YNegative)
2717 f->display.x->win_gravity = SouthEastGravity;
2718 else
2719 f->display.x->win_gravity = NorthEastGravity;
2720 }
2721 else
2722 {
2723 if (window_prompting & YNegative)
2724 f->display.x->win_gravity = SouthWestGravity;
2725 else
2726 f->display.x->win_gravity = NorthWestGravity;
2365c027
RS
2727 }
2728
38d22040
RS
2729 f->display.x->size_hint_flags = window_prompting;
2730
a7f7d550
FP
2731#ifdef USE_X_TOOLKIT
2732 x_window (f, window_prompting, minibuffer_only);
2733#else
f676886a 2734 x_window (f);
a7f7d550 2735#endif
f676886a
JB
2736 x_icon (f, parms);
2737 x_make_gc (f);
ea96210c 2738 init_frame_faces (f);
01f1ba30 2739
f9942c9e
JB
2740 /* We need to do this after creating the X window, so that the
2741 icon-creation functions can say whose icon they're describing. */
cf177271 2742 x_default_parameter (f, parms, Qicon_type, Qnil,
6998a3b4 2743 "bitmapIcon", "BitmapIcon", symbol);
f9942c9e 2744
cf177271
JB
2745 x_default_parameter (f, parms, Qauto_raise, Qnil,
2746 "autoRaise", "AutoRaiseLower", boolean);
2747 x_default_parameter (f, parms, Qauto_lower, Qnil,
2748 "autoLower", "AutoRaiseLower", boolean);
dbc4e1c1
JB
2749 x_default_parameter (f, parms, Qcursor_type, Qbox,
2750 "cursorType", "CursorType", symbol);
f9942c9e 2751
f676886a 2752 /* Dimensions, especially f->height, must be done via change_frame_size.
01f1ba30 2753 Change will not be effected unless different from the current
b9dc4443 2754 f->height. */
f676886a
JB
2755 width = f->width;
2756 height = f->height;
2757 f->height = f->width = 0;
f9942c9e 2758 change_frame_size (f, height, width, 1, 0);
d043f1a4 2759
a7f7d550
FP
2760/* With the toolkit, the geometry management is done in x_window. */
2761#ifndef USE_X_TOOLKIT
01f1ba30 2762 BLOCK_INPUT;
7989f084 2763 x_wm_set_size_hint (f, window_prompting, 0);
01f1ba30 2764 UNBLOCK_INPUT;
a7f7d550 2765#endif /* USE_X_TOOLKIT */
01f1ba30 2766
cf177271 2767 tem = x_get_arg (parms, Qunsplittable, 0, 0, boolean);
f676886a 2768 f->no_split = minibuffer_only || EQ (tem, Qt);
01f1ba30 2769
f8ea8499
PR
2770 UNGCPRO;
2771
59d61058
RS
2772 /* It is now ok to make the frame official
2773 even if we get an error below.
2774 And the frame needs to be on Vframe_list
2775 or making it visible won't work. */
2776 Vframe_list = Fcons (frame, Vframe_list);
2777
08a90d6a
RS
2778 /* Now that the frame is official, it counts as a reference to
2779 its display. */
2780 FRAME_X_DISPLAY_INFO (f)->reference_count++;
2781
d043f1a4
RS
2782 /* Make the window appear on the frame and enable display,
2783 unless the caller says not to. */
49795535 2784 {
98381190 2785 Lisp_Object visibility;
49795535 2786
98381190 2787 visibility = x_get_arg (parms, Qvisibility, 0, 0, symbol);
49795535
JB
2788 if (EQ (visibility, Qunbound))
2789 visibility = Qt;
2790
2791 if (EQ (visibility, Qicon))
2792 x_iconify_frame (f);
2793 else if (! NILP (visibility))
2794 x_make_frame_visible (f);
2795 else
2796 /* Must have been Qnil. */
2797 ;
2798 }
01f1ba30 2799
9ef48a9d 2800 return unbind_to (count, frame);
01f1ba30
JB
2801}
2802
87498171
KH
2803Lisp_Object
2804x_get_focus_frame ()
2805{
2806 Lisp_Object xfocus;
2807 if (! x_focus_frame)
2808 return Qnil;
2809
191ed777 2810 XSETFRAME (xfocus, x_focus_frame);
87498171
KH
2811 return xfocus;
2812}
2813
f676886a
JB
2814DEFUN ("focus-frame", Ffocus_frame, Sfocus_frame, 1, 1, 0,
2815 "Set the focus on FRAME.")
2816 (frame)
2817 Lisp_Object frame;
01f1ba30 2818{
f676886a 2819 CHECK_LIVE_FRAME (frame, 0);
01f1ba30 2820
f9942c9e 2821 if (FRAME_X_P (XFRAME (frame)))
01f1ba30
JB
2822 {
2823 BLOCK_INPUT;
f676886a 2824 x_focus_on_frame (XFRAME (frame));
01f1ba30 2825 UNBLOCK_INPUT;
f676886a 2826 return frame;
01f1ba30
JB
2827 }
2828
2829 return Qnil;
2830}
2831
f676886a
JB
2832DEFUN ("unfocus-frame", Funfocus_frame, Sunfocus_frame, 0, 0, 0,
2833 "If a frame has been focused, release it.")
01f1ba30
JB
2834 ()
2835{
f676886a 2836 if (x_focus_frame)
01f1ba30
JB
2837 {
2838 BLOCK_INPUT;
f676886a 2839 x_unfocus_frame (x_focus_frame);
01f1ba30
JB
2840 UNBLOCK_INPUT;
2841 }
2842
2843 return Qnil;
2844}
2845\f
f0614854
JB
2846DEFUN ("x-list-fonts", Fx_list_fonts, Sx_list_fonts, 1, 3, 0,
2847 "Return a list of the names of available fonts matching PATTERN.\n\
2848If optional arguments FACE and FRAME are specified, return only fonts\n\
2849the same size as FACE on FRAME.\n\
2850\n\
2851PATTERN is a string, perhaps with wildcard characters;\n\
2852 the * character matches any substring, and\n\
2853 the ? character matches any single character.\n\
2854 PATTERN is case-insensitive.\n\
08a90d6a 2855FACE is a face name--a symbol.\n\
f0614854
JB
2856\n\
2857The return value is a list of strings, suitable as arguments to\n\
2858set-face-font.\n\
2859\n\
410d4321
RS
2860Fonts Emacs can't use (i.e. proportional fonts) may or may not be excluded\n\
2861even if they match PATTERN and FACE.")
f0614854
JB
2862 (pattern, face, frame)
2863 Lisp_Object pattern, face, frame;
2864{
2865 int num_fonts;
2866 char **names;
2867 XFontStruct *info;
2868 XFontStruct *size_ref;
2869 Lisp_Object list;
f1c16f36 2870 FRAME_PTR f;
f0614854 2871
7fc9de26 2872 check_x ();
f0614854
JB
2873 CHECK_STRING (pattern, 0);
2874 if (!NILP (face))
2875 CHECK_SYMBOL (face, 1);
f0614854 2876
b9dc4443 2877 f = check_x_frame (frame);
f1c16f36
RS
2878
2879 /* Determine the width standard for comparison with the fonts we find. */
2880
f0614854
JB
2881 if (NILP (face))
2882 size_ref = 0;
2883 else
2884 {
90eb1019
RS
2885 int face_id;
2886
2887 /* Don't die if we get called with a terminal frame. */
2888 if (! FRAME_X_P (f))
2889 error ("non-X frame used in `x-list-fonts'");
2890
2891 face_id = face_name_id_number (f, face);
f0614854 2892
a081bd37
JB
2893 if (face_id < 0 || face_id >= FRAME_N_PARAM_FACES (f)
2894 || FRAME_PARAM_FACES (f) [face_id] == 0)
ea96210c 2895 size_ref = f->display.x->font;
6998a3b4
RS
2896 else
2897 {
a081bd37 2898 size_ref = FRAME_PARAM_FACES (f) [face_id]->font;
6998a3b4
RS
2899 if (size_ref == (XFontStruct *) (~0))
2900 size_ref = f->display.x->font;
2901 }
f0614854
JB
2902 }
2903
f1c16f36 2904 /* See if we cached the result for this particular query. */
08a90d6a
RS
2905 list = Fassoc (pattern,
2906 XCONS (FRAME_X_DISPLAY_INFO (f)->name_list_element)->cdr);
f1c16f36
RS
2907
2908 /* We have info in the cache for this PATTERN. */
2909 if (!NILP (list))
2910 {
2911 Lisp_Object tem, newlist;
2912
2913 /* We have info about this pattern. */
2914 list = XCONS (list)->cdr;
2915
2916 if (size_ref == 0)
2917 return list;
2918
2919 BLOCK_INPUT;
2920
2921 /* Filter the cached info and return just the fonts that match FACE. */
2922 newlist = Qnil;
2923 for (tem = list; CONSP (tem); tem = XCONS (tem)->cdr)
2924 {
2925 XFontStruct *thisinfo;
2926
b9dc4443 2927 thisinfo = XLoadQueryFont (FRAME_X_DISPLAY (f),
f1c16f36
RS
2928 XSTRING (XCONS (tem)->car)->data);
2929
2930 if (thisinfo && same_size_fonts (thisinfo, size_ref))
2931 newlist = Fcons (XCONS (tem)->car, newlist);
2932
b9dc4443 2933 XFreeFont (FRAME_X_DISPLAY (f), thisinfo);
f1c16f36
RS
2934 }
2935
2936 UNBLOCK_INPUT;
2937
2938 return newlist;
2939 }
2940
f0614854 2941 BLOCK_INPUT;
f58534a3
RS
2942
2943 /* Solaris 2.3 has a bug in XListFontsWithInfo. */
2944#ifdef BROKEN_XLISTFONTSWITHINFO
b9dc4443 2945 names = XListFonts (FRAME_X_DISPLAY (f),
f58534a3
RS
2946 XSTRING (pattern)->data,
2947 2000, /* maxnames */
2948 &num_fonts); /* count_return */
2949#else
b9dc4443 2950 names = XListFontsWithInfo (FRAME_X_DISPLAY (f),
f0614854 2951 XSTRING (pattern)->data,
ea96210c 2952 2000, /* maxnames */
f0614854
JB
2953 &num_fonts, /* count_return */
2954 &info); /* info_return */
f58534a3 2955#endif
f0614854
JB
2956 UNBLOCK_INPUT;
2957
a9107360 2958 list = Qnil;
f0614854 2959
a9107360
RS
2960 if (names)
2961 {
a9107360 2962 int i;
f1c16f36
RS
2963 Lisp_Object full_list;
2964
2965 /* Make a list of all the fonts we got back.
2966 Store that in the font cache for the display. */
2967 full_list = Qnil;
2968 for (i = 0; i < num_fonts; i++)
2969 full_list = Fcons (build_string (names[i]), full_list);
08a90d6a 2970 XCONS (FRAME_X_DISPLAY_INFO (f)->name_list_element)->cdr
f1c16f36 2971 = Fcons (Fcons (pattern, full_list),
08a90d6a 2972 XCONS (FRAME_X_DISPLAY_INFO (f)->name_list_element)->cdr);
a9107360 2973
f1c16f36
RS
2974 /* Make a list of the fonts that have the right width. */
2975 list = Qnil;
a9107360 2976 for (i = 0; i < num_fonts; i++)
f58534a3 2977 {
74712156
KH
2978 XFontStruct *thisinfo;
2979
f58534a3
RS
2980#ifdef BROKEN_XLISTFONTSWITHINFO
2981 BLOCK_INPUT;
b9dc4443 2982 thisinfo = XLoadQueryFont (FRAME_X_DISPLAY (f), names[i]);
f58534a3
RS
2983 UNBLOCK_INPUT;
2984#else
74712156 2985 thisinfo = &info[i];
f58534a3 2986#endif
74712156
KH
2987 if (thisinfo && (! size_ref
2988 || same_size_fonts (thisinfo, size_ref)))
f1c16f36 2989 list = Fcons (build_string (names[i]), list);
f58534a3 2990 }
f1c16f36 2991 list = Fnreverse (list);
a9107360 2992
f58534a3
RS
2993 BLOCK_INPUT;
2994#ifdef BROKEN_XLISTFONTSWITHINFO
2995 XFreeFontNames (names);
2996#else
a9107360 2997 XFreeFontInfo (names, info, num_fonts);
f58534a3
RS
2998#endif
2999 UNBLOCK_INPUT;
a9107360 3000 }
f0614854
JB
3001
3002 return list;
3003}
3004
3005\f
b9dc4443 3006DEFUN ("x-color-defined-p", Fx_color_defined_p, Sx_color_defined_p, 1, 2, 0,
08a90d6a
RS
3007 "Return non-nil color COLOR is supported on frame FRAME.\n\
3008If FRAME is omitted or nil, use the selected frame.")
b9dc4443
RS
3009 (color, frame)
3010 Lisp_Object color, frame;
e12d55b2 3011{
b9dc4443
RS
3012 XColor foo;
3013 FRAME_PTR f = check_x_frame (frame);
e12d55b2 3014
b9dc4443
RS
3015 CHECK_STRING (color, 1);
3016
3017 if (defined_color (f, XSTRING (color)->data, &foo, 0))
e12d55b2
RS
3018 return Qt;
3019 else
3020 return Qnil;
3021}
3022
b9dc4443
RS
3023DEFUN ("x-color-values", Fx_color_values, Sx_color_values, 1, 2, 0,
3024 "Return a description of the color named COLOR on frame FRAME.\n\
e12d55b2 3025The value is a list of integer RGB values--(RED GREEN BLUE).\n\
08a90d6a
RS
3026These values appear to range from 0 to 65280; white is (65280 65280 65280).\n\
3027If FRAME is omitted or nil, use the selected frame.")
b9dc4443
RS
3028 (color, frame)
3029 Lisp_Object color, frame;
01f1ba30 3030{
b9dc4443
RS
3031 XColor foo;
3032 FRAME_PTR f = check_x_frame (frame);
3033
3034 CHECK_STRING (color, 1);
01f1ba30 3035
b9dc4443 3036 if (defined_color (f, XSTRING (color)->data, &foo, 0))
57c82a63
RS
3037 {
3038 Lisp_Object rgb[3];
3039
3040 rgb[0] = make_number (foo.red);
3041 rgb[1] = make_number (foo.green);
3042 rgb[2] = make_number (foo.blue);
3043 return Flist (3, rgb);
3044 }
01f1ba30
JB
3045 else
3046 return Qnil;
3047}
3048
b9dc4443 3049DEFUN ("x-display-color-p", Fx_display_color_p, Sx_display_color_p, 0, 1, 0,
08a90d6a
RS
3050 "Return t if the X display supports color.\n\
3051The optional argument DISPLAY specifies which display to ask about.\n\
3052DISPLAY should be either a frame or a display name (a string).\n\
3053If omitted or nil, that stands for the selected frame's display.")
3054 (display)
3055 Lisp_Object display;
01f1ba30 3056{
08a90d6a 3057 struct x_display_info *dpyinfo = check_x_display_info (display);
11ae94fe 3058
b9dc4443 3059 if (dpyinfo->n_planes <= 2)
01f1ba30
JB
3060 return Qnil;
3061
b9dc4443 3062 switch (dpyinfo->visual->class)
01f1ba30
JB
3063 {
3064 case StaticColor:
3065 case PseudoColor:
3066 case TrueColor:
3067 case DirectColor:
3068 return Qt;
3069
3070 default:
3071 return Qnil;
3072 }
3073}
3074
d0c9d219 3075DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
b9dc4443 3076 0, 1, 0,
08a90d6a
RS
3077 "Return t if the X display supports shades of gray.\n\
3078The optional argument DISPLAY specifies which display to ask about.\n\
3079DISPLAY should be either a frame or a display name (a string).\n\
3080If omitted or nil, that stands for the selected frame's display.")
3081 (display)
3082 Lisp_Object display;
d0c9d219 3083{
08a90d6a 3084 struct x_display_info *dpyinfo = check_x_display_info (display);
d0c9d219 3085
b9dc4443
RS
3086 if (dpyinfo->n_planes <= 2)
3087 return Qnil;
3088
3089 return (dpyinfo->n_planes > 1
3090 && (dpyinfo->visual->class == StaticGray
3091 || dpyinfo->visual->class == GrayScale));
d0c9d219
RS
3092}
3093
41beb8fc
RS
3094DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
3095 0, 1, 0,
08a90d6a
RS
3096 "Returns the width in pixels of the X display DISPLAY.\n\
3097The optional argument DISPLAY specifies which display to ask about.\n\
3098DISPLAY should be either a frame or a display name (a string).\n\
3099If omitted or nil, that stands for the selected frame's display.")
3100 (display)
3101 Lisp_Object display;
41beb8fc 3102{
08a90d6a 3103 struct x_display_info *dpyinfo = check_x_display_info (display);
b9dc4443
RS
3104
3105 return make_number (dpyinfo->width);
41beb8fc
RS
3106}
3107
3108DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
3109 Sx_display_pixel_height, 0, 1, 0,
08a90d6a
RS
3110 "Returns the height in pixels of the X display DISPLAY.\n\
3111The optional argument DISPLAY specifies which display to ask about.\n\
3112DISPLAY should be either a frame or a display name (a string).\n\
3113If omitted or nil, that stands for the selected frame's display.")
3114 (display)
3115 Lisp_Object display;
41beb8fc 3116{
08a90d6a 3117 struct x_display_info *dpyinfo = check_x_display_info (display);
b9dc4443
RS
3118
3119 return make_number (dpyinfo->height);
41beb8fc
RS
3120}
3121
3122DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
3123 0, 1, 0,
08a90d6a
RS
3124 "Returns the number of bitplanes of the X display DISPLAY.\n\
3125The optional argument DISPLAY specifies which display to ask about.\n\
3126DISPLAY should be either a frame or a display name (a string).\n\
3127If omitted or nil, that stands for the selected frame's display.")
3128 (display)
3129 Lisp_Object display;
41beb8fc 3130{
08a90d6a 3131 struct x_display_info *dpyinfo = check_x_display_info (display);
b9dc4443
RS
3132
3133 return make_number (dpyinfo->n_planes);
41beb8fc
RS
3134}
3135
3136DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
3137 0, 1, 0,
08a90d6a
RS
3138 "Returns the number of color cells of the X display DISPLAY.\n\
3139The optional argument DISPLAY specifies which display to ask about.\n\
3140DISPLAY should be either a frame or a display name (a string).\n\
3141If omitted or nil, that stands for the selected frame's display.")
3142 (display)
3143 Lisp_Object display;
41beb8fc 3144{
08a90d6a 3145 struct x_display_info *dpyinfo = check_x_display_info (display);
b9dc4443
RS
3146
3147 return make_number (DisplayCells (dpyinfo->display,
3148 XScreenNumberOfScreen (dpyinfo->screen)));
41beb8fc
RS
3149}
3150
9d317b2c
RS
3151DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
3152 Sx_server_max_request_size,
3153 0, 1, 0,
08a90d6a
RS
3154 "Returns the maximum request size of the X server of display DISPLAY.\n\
3155The optional argument DISPLAY specifies which display to ask about.\n\
3156DISPLAY should be either a frame or a display name (a string).\n\
3157If omitted or nil, that stands for the selected frame's display.")
3158 (display)
3159 Lisp_Object display;
9d317b2c 3160{
08a90d6a 3161 struct x_display_info *dpyinfo = check_x_display_info (display);
b9dc4443
RS
3162
3163 return make_number (MAXREQUEST (dpyinfo->display));
9d317b2c
RS
3164}
3165
41beb8fc 3166DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
08a90d6a
RS
3167 "Returns the vendor ID string of the X server of display DISPLAY.\n\
3168The optional argument DISPLAY specifies which display to ask about.\n\
3169DISPLAY should be either a frame or a display name (a string).\n\
3170If omitted or nil, that stands for the selected frame's display.")
3171 (display)
3172 Lisp_Object display;
41beb8fc 3173{
08a90d6a 3174 struct x_display_info *dpyinfo = check_x_display_info (display);
b9dc4443
RS
3175 char *vendor = ServerVendor (dpyinfo->display);
3176
41beb8fc
RS
3177 if (! vendor) vendor = "";
3178 return build_string (vendor);
3179}
3180
3181DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
08a90d6a 3182 "Returns the version numbers of the X server of display DISPLAY.\n\
41beb8fc
RS
3183The value is a list of three integers: the major and minor\n\
3184version numbers of the X Protocol in use, and the vendor-specific release\n\
08a90d6a
RS
3185number. See also the function `x-server-vendor'.\n\n\
3186The optional argument DISPLAY specifies which display to ask about.\n\
3187DISPLAY should be either a frame or a display name (a string).\n\
3188If omitted or nil, that stands for the selected frame's display.")
3189 (display)
3190 Lisp_Object display;
41beb8fc 3191{
08a90d6a 3192 struct x_display_info *dpyinfo = check_x_display_info (display);
b9dc4443 3193 Display *dpy = dpyinfo->display;
11ae94fe 3194
41beb8fc
RS
3195 return Fcons (make_number (ProtocolVersion (dpy)),
3196 Fcons (make_number (ProtocolRevision (dpy)),
3197 Fcons (make_number (VendorRelease (dpy)), Qnil)));
3198}
3199
3200DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
08a90d6a
RS
3201 "Returns the number of screens on the X server of display DISPLAY.\n\
3202The optional argument DISPLAY specifies which display to ask about.\n\
3203DISPLAY should be either a frame or a display name (a string).\n\
3204If omitted or nil, that stands for the selected frame's display.")
3205 (display)
3206 Lisp_Object display;
41beb8fc 3207{
08a90d6a 3208 struct x_display_info *dpyinfo = check_x_display_info (display);
b9dc4443
RS
3209
3210 return make_number (ScreenCount (dpyinfo->display));
41beb8fc
RS
3211}
3212
3213DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
08a90d6a
RS
3214 "Returns the height in millimeters of the X display DISPLAY.\n\
3215The optional argument DISPLAY specifies which display to ask about.\n\
3216DISPLAY should be either a frame or a display name (a string).\n\
3217If omitted or nil, that stands for the selected frame's display.")
3218 (display)
3219 Lisp_Object display;
41beb8fc 3220{
08a90d6a 3221 struct x_display_info *dpyinfo = check_x_display_info (display);
b9dc4443
RS
3222
3223 return make_number (HeightMMOfScreen (dpyinfo->screen));
41beb8fc
RS
3224}
3225
3226DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
08a90d6a
RS
3227 "Returns the width in millimeters of the X display DISPLAY.\n\
3228The optional argument DISPLAY specifies which display to ask about.\n\
3229DISPLAY should be either a frame or a display name (a string).\n\
3230If omitted or nil, that stands for the selected frame's display.")
3231 (display)
3232 Lisp_Object display;
41beb8fc 3233{
08a90d6a 3234 struct x_display_info *dpyinfo = check_x_display_info (display);
b9dc4443
RS
3235
3236 return make_number (WidthMMOfScreen (dpyinfo->screen));
41beb8fc
RS
3237}
3238
3239DEFUN ("x-display-backing-store", Fx_display_backing_store,
3240 Sx_display_backing_store, 0, 1, 0,
08a90d6a
RS
3241 "Returns an indication of whether X display DISPLAY does backing store.\n\
3242The value may be `always', `when-mapped', or `not-useful'.\n\
3243The optional argument DISPLAY specifies which display to ask about.\n\
3244DISPLAY should be either a frame or a display name (a string).\n\
3245If omitted or nil, that stands for the selected frame's display.")
3246 (display)
3247 Lisp_Object display;
41beb8fc 3248{
08a90d6a 3249 struct x_display_info *dpyinfo = check_x_display_info (display);
11ae94fe 3250
b9dc4443 3251 switch (DoesBackingStore (dpyinfo->screen))
41beb8fc
RS
3252 {
3253 case Always:
3254 return intern ("always");
3255
3256 case WhenMapped:
3257 return intern ("when-mapped");
3258
3259 case NotUseful:
3260 return intern ("not-useful");
3261
3262 default:
3263 error ("Strange value for BackingStore parameter of screen");
3264 }
3265}
3266
3267DEFUN ("x-display-visual-class", Fx_display_visual_class,
3268 Sx_display_visual_class, 0, 1, 0,
08a90d6a 3269 "Returns the visual class of the X display DISPLAY.\n\
41beb8fc 3270The value is one of the symbols `static-gray', `gray-scale',\n\
08a90d6a
RS
3271`static-color', `pseudo-color', `true-color', or `direct-color'.\n\n\
3272The optional argument DISPLAY specifies which display to ask about.\n\
3273DISPLAY should be either a frame or a display name (a string).\n\
3274If omitted or nil, that stands for the selected frame's display.")
3275 (display)
3276 Lisp_Object display;
41beb8fc 3277{
08a90d6a 3278 struct x_display_info *dpyinfo = check_x_display_info (display);
11ae94fe 3279
b9dc4443 3280 switch (dpyinfo->visual->class)
41beb8fc
RS
3281 {
3282 case StaticGray: return (intern ("static-gray"));
3283 case GrayScale: return (intern ("gray-scale"));
3284 case StaticColor: return (intern ("static-color"));
3285 case PseudoColor: return (intern ("pseudo-color"));
3286 case TrueColor: return (intern ("true-color"));
3287 case DirectColor: return (intern ("direct-color"));
3288 default:
3289 error ("Display has an unknown visual class");
3290 }
3291}
3292
3293DEFUN ("x-display-save-under", Fx_display_save_under,
3294 Sx_display_save_under, 0, 1, 0,
08a90d6a
RS
3295 "Returns t if the X display DISPLAY supports the save-under feature.\n\
3296The optional argument DISPLAY specifies which display to ask about.\n\
3297DISPLAY should be either a frame or a display name (a string).\n\
3298If omitted or nil, that stands for the selected frame's display.")
3299 (display)
3300 Lisp_Object display;
41beb8fc 3301{
08a90d6a 3302 struct x_display_info *dpyinfo = check_x_display_info (display);
11ae94fe 3303
b9dc4443 3304 if (DoesSaveUnders (dpyinfo->screen) == True)
41beb8fc
RS
3305 return Qt;
3306 else
3307 return Qnil;
3308}
3309\f
b9dc4443 3310int
55caf99c
RS
3311x_pixel_width (f)
3312 register struct frame *f;
01f1ba30 3313{
55caf99c 3314 return PIXEL_WIDTH (f);
01f1ba30
JB
3315}
3316
b9dc4443 3317int
55caf99c
RS
3318x_pixel_height (f)
3319 register struct frame *f;
01f1ba30 3320{
55caf99c
RS
3321 return PIXEL_HEIGHT (f);
3322}
3323
b9dc4443 3324int
55caf99c
RS
3325x_char_width (f)
3326 register struct frame *f;
3327{
3328 return FONT_WIDTH (f->display.x->font);
3329}
3330
b9dc4443 3331int
55caf99c
RS
3332x_char_height (f)
3333 register struct frame *f;
3334{
5d45642b 3335 return f->display.x->line_height;
01f1ba30 3336}
b9dc4443
RS
3337
3338int
3339x_screen_planes (frame)
3340 Lisp_Object frame;
3341{
3342 return FRAME_X_DISPLAY_INFO (XFRAME (frame))->n_planes;
3343}
01f1ba30 3344\f
85ffea93
RS
3345#if 0 /* These no longer seem like the right way to do things. */
3346
f676886a 3347/* Draw a rectangle on the frame with left top corner including
01f1ba30 3348 the character specified by LEFT_CHAR and TOP_CHAR. The rectangle is
b9dc4443 3349 CHARS by LINES wide and long and is the color of the cursor. */
01f1ba30
JB
3350
3351void
f676886a
JB
3352x_rectangle (f, gc, left_char, top_char, chars, lines)
3353 register struct frame *f;
01f1ba30
JB
3354 GC gc;
3355 register int top_char, left_char, chars, lines;
3356{
3357 int width;
3358 int height;
f676886a
JB
3359 int left = (left_char * FONT_WIDTH (f->display.x->font)
3360 + f->display.x->internal_border_width);
5d45642b 3361 int top = (top_char * f->display.x->line_height
f676886a 3362 + f->display.x->internal_border_width);
01f1ba30
JB
3363
3364 if (chars < 0)
f676886a 3365 width = FONT_WIDTH (f->display.x->font) / 2;
01f1ba30 3366 else
f676886a 3367 width = FONT_WIDTH (f->display.x->font) * chars;
01f1ba30 3368 if (lines < 0)
5d45642b 3369 height = f->display.x->line_height / 2;
01f1ba30 3370 else
5d45642b 3371 height = f->display.x->line_height * lines;
01f1ba30 3372
b9dc4443 3373 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
01f1ba30
JB
3374 gc, left, top, width, height);
3375}
3376
3377DEFUN ("x-draw-rectangle", Fx_draw_rectangle, Sx_draw_rectangle, 5, 5, 0,
f676886a 3378 "Draw a rectangle on FRAME between coordinates specified by\n\
01f1ba30 3379numbers X0, Y0, X1, Y1 in the cursor pixel.")
f676886a
JB
3380 (frame, X0, Y0, X1, Y1)
3381 register Lisp_Object frame, X0, X1, Y0, Y1;
01f1ba30
JB
3382{
3383 register int x0, y0, x1, y1, top, left, n_chars, n_lines;
3384
f676886a 3385 CHECK_LIVE_FRAME (frame, 0);
01f1ba30
JB
3386 CHECK_NUMBER (X0, 0);
3387 CHECK_NUMBER (Y0, 1);
3388 CHECK_NUMBER (X1, 2);
3389 CHECK_NUMBER (Y1, 3);
3390
3391 x0 = XINT (X0);
3392 x1 = XINT (X1);
3393 y0 = XINT (Y0);
3394 y1 = XINT (Y1);
3395
3396 if (y1 > y0)
3397 {
3398 top = y0;
3399 n_lines = y1 - y0 + 1;
3400 }
3401 else
3402 {
3403 top = y1;
3404 n_lines = y0 - y1 + 1;
3405 }
3406
3407 if (x1 > x0)
3408 {
3409 left = x0;
3410 n_chars = x1 - x0 + 1;
3411 }
3412 else
3413 {
3414 left = x1;
3415 n_chars = x0 - x1 + 1;
3416 }
3417
3418 BLOCK_INPUT;
f676886a 3419 x_rectangle (XFRAME (frame), XFRAME (frame)->display.x->cursor_gc,
01f1ba30
JB
3420 left, top, n_chars, n_lines);
3421 UNBLOCK_INPUT;
3422
3423 return Qt;
3424}
3425
3426DEFUN ("x-erase-rectangle", Fx_erase_rectangle, Sx_erase_rectangle, 5, 5, 0,
f676886a 3427 "Draw a rectangle drawn on FRAME between coordinates\n\
01f1ba30 3428X0, Y0, X1, Y1 in the regular background-pixel.")
f676886a
JB
3429 (frame, X0, Y0, X1, Y1)
3430 register Lisp_Object frame, X0, Y0, X1, Y1;
01f1ba30
JB
3431{
3432 register int x0, y0, x1, y1, top, left, n_chars, n_lines;
3433
b9dc4443 3434 CHECK_LIVE_FRAME (frame, 0);
01f1ba30
JB
3435 CHECK_NUMBER (X0, 0);
3436 CHECK_NUMBER (Y0, 1);
3437 CHECK_NUMBER (X1, 2);
3438 CHECK_NUMBER (Y1, 3);
3439
3440 x0 = XINT (X0);
3441 x1 = XINT (X1);
3442 y0 = XINT (Y0);
3443 y1 = XINT (Y1);
3444
3445 if (y1 > y0)
3446 {
3447 top = y0;
3448 n_lines = y1 - y0 + 1;
3449 }
3450 else
3451 {
3452 top = y1;
3453 n_lines = y0 - y1 + 1;
3454 }
3455
3456 if (x1 > x0)
3457 {
3458 left = x0;
3459 n_chars = x1 - x0 + 1;
3460 }
3461 else
3462 {
3463 left = x1;
3464 n_chars = x0 - x1 + 1;
3465 }
3466
3467 BLOCK_INPUT;
f676886a 3468 x_rectangle (XFRAME (frame), XFRAME (frame)->display.x->reverse_gc,
01f1ba30
JB
3469 left, top, n_chars, n_lines);
3470 UNBLOCK_INPUT;
3471
3472 return Qt;
3473}
3474
3475/* Draw lines around the text region beginning at the character position
3476 TOP_X, TOP_Y and ending at BOTTOM_X and BOTTOM_Y. GC specifies the
b9dc4443 3477 pixel and line characteristics. */
01f1ba30 3478
f676886a 3479#define line_len(line) (FRAME_CURRENT_GLYPHS (f)->used[(line)])
01f1ba30
JB
3480
3481static void
f676886a
JB
3482outline_region (f, gc, top_x, top_y, bottom_x, bottom_y)
3483 register struct frame *f;
01f1ba30
JB
3484 GC gc;
3485 int top_x, top_y, bottom_x, bottom_y;
3486{
f676886a
JB
3487 register int ibw = f->display.x->internal_border_width;
3488 register int font_w = FONT_WIDTH (f->display.x->font);
5d45642b 3489 register int font_h = f->display.x->line_height;
01f1ba30
JB
3490 int y = top_y;
3491 int x = line_len (y);
9ef48a9d
RS
3492 XPoint *pixel_points
3493 = (XPoint *) alloca (((bottom_y - top_y + 2) * 4) * sizeof (XPoint));
01f1ba30
JB
3494 register XPoint *this_point = pixel_points;
3495
3496 /* Do the horizontal top line/lines */
3497 if (top_x == 0)
3498 {
3499 this_point->x = ibw;
3500 this_point->y = ibw + (font_h * top_y);
3501 this_point++;
3502 if (x == 0)
b9dc4443 3503 this_point->x = ibw + (font_w / 2); /* Half-size for newline chars. */
01f1ba30
JB
3504 else
3505 this_point->x = ibw + (font_w * x);
3506 this_point->y = (this_point - 1)->y;
3507 }
3508 else
3509 {
3510 this_point->x = ibw;
3511 this_point->y = ibw + (font_h * (top_y + 1));
3512 this_point++;
3513 this_point->x = ibw + (font_w * top_x);
3514 this_point->y = (this_point - 1)->y;
3515 this_point++;
3516 this_point->x = (this_point - 1)->x;
3517 this_point->y = ibw + (font_h * top_y);
3518 this_point++;
3519 this_point->x = ibw + (font_w * x);
3520 this_point->y = (this_point - 1)->y;
3521 }
3522
b9dc4443 3523 /* Now do the right side. */
01f1ba30
JB
3524 while (y < bottom_y)
3525 { /* Right vertical edge */
3526 this_point++;
3527 this_point->x = (this_point - 1)->x;
3528 this_point->y = ibw + (font_h * (y + 1));
3529 this_point++;
3530
3531 y++; /* Horizontal connection to next line */
3532 x = line_len (y);
3533 if (x == 0)
3534 this_point->x = ibw + (font_w / 2);
3535 else
3536 this_point->x = ibw + (font_w * x);
3537
3538 this_point->y = (this_point - 1)->y;
3539 }
3540
b9dc4443 3541 /* Now do the bottom and connect to the top left point. */
01f1ba30
JB
3542 this_point->x = ibw + (font_w * (bottom_x + 1));
3543
3544 this_point++;
3545 this_point->x = (this_point - 1)->x;
3546 this_point->y = ibw + (font_h * (bottom_y + 1));
3547 this_point++;
3548 this_point->x = ibw;
3549 this_point->y = (this_point - 1)->y;
3550 this_point++;
3551 this_point->x = pixel_points->x;
3552 this_point->y = pixel_points->y;
3553
b9dc4443 3554 XDrawLines (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
01f1ba30
JB
3555 gc, pixel_points,
3556 (this_point - pixel_points + 1), CoordModeOrigin);
3557}
3558
3559DEFUN ("x-contour-region", Fx_contour_region, Sx_contour_region, 1, 1, 0,
3560 "Highlight the region between point and the character under the mouse\n\
f676886a 3561selected frame.")
01f1ba30
JB
3562 (event)
3563 register Lisp_Object event;
3564{
3565 register int x0, y0, x1, y1;
f676886a 3566 register struct frame *f = selected_frame;
01f1ba30
JB
3567 register int p1, p2;
3568
3569 CHECK_CONS (event, 0);
3570
3571 BLOCK_INPUT;
3572 x0 = XINT (Fcar (Fcar (event)));
3573 y0 = XINT (Fcar (Fcdr (Fcar (event))));
3574
b9dc4443
RS
3575 /* If the mouse is past the end of the line, don't that area. */
3576 /* ReWrite this... */
01f1ba30 3577
f676886a
JB
3578 x1 = f->cursor_x;
3579 y1 = f->cursor_y;
01f1ba30
JB
3580
3581 if (y1 > y0) /* point below mouse */
f676886a 3582 outline_region (f, f->display.x->cursor_gc,
01f1ba30
JB
3583 x0, y0, x1, y1);
3584 else if (y1 < y0) /* point above mouse */
f676886a 3585 outline_region (f, f->display.x->cursor_gc,
01f1ba30
JB
3586 x1, y1, x0, y0);
3587 else /* same line: draw horizontal rectangle */
3588 {
3589 if (x1 > x0)
f676886a 3590 x_rectangle (f, f->display.x->cursor_gc,
01f1ba30
JB
3591 x0, y0, (x1 - x0 + 1), 1);
3592 else if (x1 < x0)
f676886a 3593 x_rectangle (f, f->display.x->cursor_gc,
01f1ba30
JB
3594 x1, y1, (x0 - x1 + 1), 1);
3595 }
3596
b9dc4443 3597 XFlush (FRAME_X_DISPLAY (f));
01f1ba30
JB
3598 UNBLOCK_INPUT;
3599
3600 return Qnil;
3601}
3602
3603DEFUN ("x-uncontour-region", Fx_uncontour_region, Sx_uncontour_region, 1, 1, 0,
3604 "Erase any highlighting of the region between point and the character\n\
f676886a 3605at X, Y on the selected frame.")
01f1ba30
JB
3606 (event)
3607 register Lisp_Object event;
3608{
3609 register int x0, y0, x1, y1;
f676886a 3610 register struct frame *f = selected_frame;
01f1ba30
JB
3611
3612 BLOCK_INPUT;
3613 x0 = XINT (Fcar (Fcar (event)));
3614 y0 = XINT (Fcar (Fcdr (Fcar (event))));
f676886a
JB
3615 x1 = f->cursor_x;
3616 y1 = f->cursor_y;
01f1ba30
JB
3617
3618 if (y1 > y0) /* point below mouse */
f676886a 3619 outline_region (f, f->display.x->reverse_gc,
01f1ba30
JB
3620 x0, y0, x1, y1);
3621 else if (y1 < y0) /* point above mouse */
f676886a 3622 outline_region (f, f->display.x->reverse_gc,
01f1ba30
JB
3623 x1, y1, x0, y0);
3624 else /* same line: draw horizontal rectangle */
3625 {
3626 if (x1 > x0)
f676886a 3627 x_rectangle (f, f->display.x->reverse_gc,
01f1ba30
JB
3628 x0, y0, (x1 - x0 + 1), 1);
3629 else if (x1 < x0)
f676886a 3630 x_rectangle (f, f->display.x->reverse_gc,
01f1ba30
JB
3631 x1, y1, (x0 - x1 + 1), 1);
3632 }
3633 UNBLOCK_INPUT;
3634
3635 return Qnil;
3636}
3637
01f1ba30
JB
3638#if 0
3639int contour_begin_x, contour_begin_y;
3640int contour_end_x, contour_end_y;
3641int contour_npoints;
3642
3643/* Clip the top part of the contour lines down (and including) line Y_POS.
3644 If X_POS is in the middle (rather than at the end) of the line, drop
b9dc4443 3645 down a line at that character. */
01f1ba30
JB
3646
3647static void
3648clip_contour_top (y_pos, x_pos)
3649{
3650 register XPoint *begin = contour_lines[y_pos].top_left;
3651 register XPoint *end;
3652 register int npoints;
f676886a 3653 register struct display_line *line = selected_frame->phys_lines[y_pos + 1];
01f1ba30 3654
b9dc4443 3655 if (x_pos >= line->len - 1) /* Draw one, straight horizontal line. */
01f1ba30
JB
3656 {
3657 end = contour_lines[y_pos].top_right;
3658 npoints = (end - begin + 1);
3659 XDrawLines (x_current_display, contour_window,
3660 contour_erase_gc, begin_erase, npoints, CoordModeOrigin);
3661
3662 bcopy (end, begin + 1, contour_last_point - end + 1);
3663 contour_last_point -= (npoints - 2);
3664 XDrawLines (x_current_display, contour_window,
3665 contour_erase_gc, begin, 2, CoordModeOrigin);
3666 XFlush (x_current_display);
3667
b9dc4443 3668 /* Now, update contour_lines structure. */
01f1ba30
JB
3669 }
3670 /* ______. */
3671 else /* |________*/
3672 {
3673 register XPoint *p = begin + 1;
3674 end = contour_lines[y_pos].bottom_right;
3675 npoints = (end - begin + 1);
3676 XDrawLines (x_current_display, contour_window,
3677 contour_erase_gc, begin_erase, npoints, CoordModeOrigin);
3678
3679 p->y = begin->y;
3680 p->x = ibw + (font_w * (x_pos + 1));
3681 p++;
3682 p->y = begin->y + font_h;
3683 p->x = (p - 1)->x;
3684 bcopy (end, begin + 3, contour_last_point - end + 1);
3685 contour_last_point -= (npoints - 5);
3686 XDrawLines (x_current_display, contour_window,
3687 contour_erase_gc, begin, 4, CoordModeOrigin);
3688 XFlush (x_current_display);
3689
b9dc4443 3690 /* Now, update contour_lines structure. */
01f1ba30
JB
3691 }
3692}
3693
eb8c3be9 3694/* Erase the top horizontal lines of the contour, and then extend
b9dc4443 3695 the contour upwards. */
01f1ba30
JB
3696
3697static void
3698extend_contour_top (line)
3699{
3700}
3701
3702static void
3703clip_contour_bottom (x_pos, y_pos)
3704 int x_pos, y_pos;
3705{
3706}
3707
3708static void
3709extend_contour_bottom (x_pos, y_pos)
3710{
3711}
3712
3713DEFUN ("x-select-region", Fx_select_region, Sx_select_region, 1, 1, "e",
3714 "")
3715 (event)
3716 Lisp_Object event;
3717{
f676886a
JB
3718 register struct frame *f = selected_frame;
3719 register int point_x = f->cursor_x;
3720 register int point_y = f->cursor_y;
01f1ba30
JB
3721 register int mouse_below_point;
3722 register Lisp_Object obj;
3723 register int x_contour_x, x_contour_y;
3724
3725 x_contour_x = x_mouse_x;
3726 x_contour_y = x_mouse_y;
3727 if (x_contour_y > point_y || (x_contour_y == point_y
3728 && x_contour_x > point_x))
3729 {
3730 mouse_below_point = 1;
f676886a 3731 outline_region (f, f->display.x->cursor_gc, point_x, point_y,
01f1ba30
JB
3732 x_contour_x, x_contour_y);
3733 }
3734 else
3735 {
3736 mouse_below_point = 0;
f676886a 3737 outline_region (f, f->display.x->cursor_gc, x_contour_x, x_contour_y,
01f1ba30
JB
3738 point_x, point_y);
3739 }
3740
3741 while (1)
3742 {
95be70ed 3743 obj = read_char (-1, 0, 0, Qnil, 0);
6a5e54e2 3744 if (!CONSP (obj))
01f1ba30
JB
3745 break;
3746
3747 if (mouse_below_point)
3748 {
b9dc4443 3749 if (x_mouse_y <= point_y) /* Flipped. */
01f1ba30
JB
3750 {
3751 mouse_below_point = 0;
3752
f676886a 3753 outline_region (f, f->display.x->reverse_gc, point_x, point_y,
01f1ba30 3754 x_contour_x, x_contour_y);
f676886a 3755 outline_region (f, f->display.x->cursor_gc, x_mouse_x, x_mouse_y,
01f1ba30
JB
3756 point_x, point_y);
3757 }
b9dc4443 3758 else if (x_mouse_y < x_contour_y) /* Bottom clipped. */
01f1ba30
JB
3759 {
3760 clip_contour_bottom (x_mouse_y);
3761 }
b9dc4443 3762 else if (x_mouse_y > x_contour_y) /* Bottom extended. */
01f1ba30
JB
3763 {
3764 extend_bottom_contour (x_mouse_y);
3765 }
3766
3767 x_contour_x = x_mouse_x;
3768 x_contour_y = x_mouse_y;
3769 }
3770 else /* mouse above or same line as point */
3771 {
b9dc4443 3772 if (x_mouse_y >= point_y) /* Flipped. */
01f1ba30
JB
3773 {
3774 mouse_below_point = 1;
3775
f676886a 3776 outline_region (f, f->display.x->reverse_gc,
01f1ba30 3777 x_contour_x, x_contour_y, point_x, point_y);
f676886a 3778 outline_region (f, f->display.x->cursor_gc, point_x, point_y,
01f1ba30
JB
3779 x_mouse_x, x_mouse_y);
3780 }
b9dc4443 3781 else if (x_mouse_y > x_contour_y) /* Top clipped. */
01f1ba30
JB
3782 {
3783 clip_contour_top (x_mouse_y);
3784 }
b9dc4443 3785 else if (x_mouse_y < x_contour_y) /* Top extended. */
01f1ba30
JB
3786 {
3787 extend_contour_top (x_mouse_y);
3788 }
3789 }
3790 }
3791
b4f5687c 3792 unread_command_event = obj;
01f1ba30
JB
3793 if (mouse_below_point)
3794 {
3795 contour_begin_x = point_x;
3796 contour_begin_y = point_y;
3797 contour_end_x = x_contour_x;
3798 contour_end_y = x_contour_y;
3799 }
3800 else
3801 {
3802 contour_begin_x = x_contour_x;
3803 contour_begin_y = x_contour_y;
3804 contour_end_x = point_x;
3805 contour_end_y = point_y;
3806 }
3807}
3808#endif
3809
3810DEFUN ("x-horizontal-line", Fx_horizontal_line, Sx_horizontal_line, 1, 1, "e",
3811 "")
3812 (event)
3813 Lisp_Object event;
3814{
3815 register Lisp_Object obj;
f676886a 3816 struct frame *f = selected_frame;
01f1ba30 3817 register struct window *w = XWINDOW (selected_window);
f676886a
JB
3818 register GC line_gc = f->display.x->cursor_gc;
3819 register GC erase_gc = f->display.x->reverse_gc;
01f1ba30
JB
3820#if 0
3821 char dash_list[] = {6, 4, 6, 4};
3822 int dashes = 4;
3823 XGCValues gc_values;
3824#endif
3825 register int previous_y;
5d45642b 3826 register int line = (x_mouse_y + 1) * f->display.x->line_height
f676886a
JB
3827 + f->display.x->internal_border_width;
3828 register int left = f->display.x->internal_border_width
01f1ba30 3829 + (w->left
f676886a 3830 * FONT_WIDTH (f->display.x->font));
01f1ba30 3831 register int right = left + (w->width
f676886a
JB
3832 * FONT_WIDTH (f->display.x->font))
3833 - f->display.x->internal_border_width;
01f1ba30
JB
3834
3835#if 0
3836 BLOCK_INPUT;
f676886a
JB
3837 gc_values.foreground = f->display.x->cursor_pixel;
3838 gc_values.background = f->display.x->background_pixel;
01f1ba30
JB
3839 gc_values.line_width = 1;
3840 gc_values.line_style = LineOnOffDash;
3841 gc_values.cap_style = CapRound;
3842 gc_values.join_style = JoinRound;
3843
b9dc4443 3844 line_gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
01f1ba30
JB
3845 GCLineStyle | GCJoinStyle | GCCapStyle
3846 | GCLineWidth | GCForeground | GCBackground,
3847 &gc_values);
b9dc4443 3848 XSetDashes (FRAME_X_DISPLAY (f), line_gc, 0, dash_list, dashes);
f676886a
JB
3849 gc_values.foreground = f->display.x->background_pixel;
3850 gc_values.background = f->display.x->foreground_pixel;
b9dc4443 3851 erase_gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
01f1ba30
JB
3852 GCLineStyle | GCJoinStyle | GCCapStyle
3853 | GCLineWidth | GCForeground | GCBackground,
3854 &gc_values);
b9dc4443 3855 XSetDashes (FRAME_X_DISPLAY (f), erase_gc, 0, dash_list, dashes);
01f1ba30
JB
3856#endif
3857
3858 while (1)
3859 {
3860 BLOCK_INPUT;
3861 if (x_mouse_y >= XINT (w->top)
3862 && x_mouse_y < XINT (w->top) + XINT (w->height) - 1)
3863 {
3864 previous_y = x_mouse_y;
5d45642b 3865 line = (x_mouse_y + 1) * f->display.x->line_height
f676886a 3866 + f->display.x->internal_border_width;
b9dc4443 3867 XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
01f1ba30
JB
3868 line_gc, left, line, right, line);
3869 }
b9dc4443 3870 XFlush (FRAME_X_DISPLAY (f));
01f1ba30
JB
3871 UNBLOCK_INPUT;
3872
3873 do
3874 {
95be70ed 3875 obj = read_char (-1, 0, 0, Qnil, 0);
6a5e54e2 3876 if (!CONSP (obj)
01f1ba30 3877 || (! EQ (Fcar (Fcdr (Fcdr (obj))),
6a5e54e2 3878 Qvertical_scroll_bar))
01f1ba30
JB
3879 || x_mouse_grabbed)
3880 {
3881 BLOCK_INPUT;
b9dc4443 3882 XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
01f1ba30
JB
3883 erase_gc, left, line, right, line);
3884 UNBLOCK_INPUT;
b4f5687c 3885 unread_command_event = obj;
01f1ba30 3886#if 0
b9dc4443
RS
3887 XFreeGC (FRAME_X_DISPLAY (f), line_gc);
3888 XFreeGC (FRAME_X_DISPLAY (f), erase_gc);
01f1ba30
JB
3889#endif
3890 return Qnil;
3891 }
3892 }
3893 while (x_mouse_y == previous_y);
3894
3895 BLOCK_INPUT;
b9dc4443 3896 XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
01f1ba30
JB
3897 erase_gc, left, line, right, line);
3898 UNBLOCK_INPUT;
3899 }
3900}
06ef7355 3901#endif
01f1ba30 3902\f
01f1ba30 3903#if 0
b9dc4443 3904/* These keep track of the rectangle following the pointer. */
01f1ba30
JB
3905int mouse_track_top, mouse_track_left, mouse_track_width;
3906
b9dc4443
RS
3907/* Offset in buffer of character under the pointer, or 0. */
3908int mouse_buffer_offset;
3909
01f1ba30
JB
3910DEFUN ("x-track-pointer", Fx_track_pointer, Sx_track_pointer, 0, 0, 0,
3911 "Track the pointer.")
3912 ()
3913{
3914 static Cursor current_pointer_shape;
f676886a 3915 FRAME_PTR f = x_mouse_frame;
01f1ba30
JB
3916
3917 BLOCK_INPUT;
f676886a
JB
3918 if (EQ (Vmouse_frame_part, Qtext_part)
3919 && (current_pointer_shape != f->display.x->nontext_cursor))
01f1ba30
JB
3920 {
3921 unsigned char c;
3922 struct buffer *buf;
3923
f676886a 3924 current_pointer_shape = f->display.x->nontext_cursor;
b9dc4443 3925 XDefineCursor (FRAME_X_DISPLAY (f),
fe24a618 3926 FRAME_X_WINDOW (f),
01f1ba30
JB
3927 current_pointer_shape);
3928
3929 buf = XBUFFER (XWINDOW (Vmouse_window)->buffer);
3930 c = *(BUF_CHAR_ADDRESS (buf, mouse_buffer_offset));
3931 }
f676886a
JB
3932 else if (EQ (Vmouse_frame_part, Qmodeline_part)
3933 && (current_pointer_shape != f->display.x->modeline_cursor))
01f1ba30 3934 {
f676886a 3935 current_pointer_shape = f->display.x->modeline_cursor;
b9dc4443 3936 XDefineCursor (FRAME_X_DISPLAY (f),
fe24a618 3937 FRAME_X_WINDOW (f),
01f1ba30
JB
3938 current_pointer_shape);
3939 }
3940
b9dc4443 3941 XFlush (FRAME_X_DISPLAY (f));
01f1ba30
JB
3942 UNBLOCK_INPUT;
3943}
3944#endif
3945
3946#if 0
3947DEFUN ("x-track-pointer", Fx_track_pointer, Sx_track_pointer, 1, 1, "e",
3948 "Draw rectangle around character under mouse pointer, if there is one.")
3949 (event)
3950 Lisp_Object event;
3951{
3952 struct window *w = XWINDOW (Vmouse_window);
f676886a 3953 struct frame *f = XFRAME (WINDOW_FRAME (w));
01f1ba30
JB
3954 struct buffer *b = XBUFFER (w->buffer);
3955 Lisp_Object obj;
3956
3957 if (! EQ (Vmouse_window, selected_window))
3958 return Qnil;
3959
3960 if (EQ (event, Qnil))
3961 {
3962 int x, y;
3963
f676886a 3964 x_read_mouse_position (selected_frame, &x, &y);
01f1ba30
JB
3965 }
3966
3967 BLOCK_INPUT;
3968 mouse_track_width = 0;
3969 mouse_track_left = mouse_track_top = -1;
3970
3971 do
3972 {
3973 if ((x_mouse_x != mouse_track_left
3974 && (x_mouse_x < mouse_track_left
3975 || x_mouse_x > (mouse_track_left + mouse_track_width)))
3976 || x_mouse_y != mouse_track_top)
3977 {
3978 int hp = 0; /* Horizontal position */
f676886a
JB
3979 int len = FRAME_CURRENT_GLYPHS (f)->used[x_mouse_y];
3980 int p = FRAME_CURRENT_GLYPHS (f)->bufp[x_mouse_y];
01f1ba30 3981 int tab_width = XINT (b->tab_width);
265a9e55 3982 int ctl_arrow_p = !NILP (b->ctl_arrow);
01f1ba30
JB
3983 unsigned char c;
3984 int mode_line_vpos = XFASTINT (w->height) + XFASTINT (w->top) - 1;
3985 int in_mode_line = 0;
3986
f676886a 3987 if (! FRAME_CURRENT_GLYPHS (f)->enable[x_mouse_y])
01f1ba30
JB
3988 break;
3989
b9dc4443 3990 /* Erase previous rectangle. */
01f1ba30
JB
3991 if (mouse_track_width)
3992 {
f676886a 3993 x_rectangle (f, f->display.x->reverse_gc,
01f1ba30
JB
3994 mouse_track_left, mouse_track_top,
3995 mouse_track_width, 1);
3996
f676886a
JB
3997 if ((mouse_track_left == f->phys_cursor_x
3998 || mouse_track_left == f->phys_cursor_x - 1)
3999 && mouse_track_top == f->phys_cursor_y)
01f1ba30 4000 {
f676886a 4001 x_display_cursor (f, 1);
01f1ba30
JB
4002 }
4003 }
4004
4005 mouse_track_left = x_mouse_x;
4006 mouse_track_top = x_mouse_y;
4007 mouse_track_width = 0;
4008
b9dc4443 4009 if (mouse_track_left > len) /* Past the end of line. */
01f1ba30
JB
4010 goto draw_or_not;
4011
4012 if (mouse_track_top == mode_line_vpos)
4013 {
4014 in_mode_line = 1;
4015 goto draw_or_not;
4016 }
4017
4018 if (tab_width <= 0 || tab_width > 20) tab_width = 8;
4019 do
4020 {
4021 c = FETCH_CHAR (p);
f676886a 4022 if (len == f->width && hp == len - 1 && c != '\n')
01f1ba30
JB
4023 goto draw_or_not;
4024
4025 switch (c)
4026 {
4027 case '\t':
4028 mouse_track_width = tab_width - (hp % tab_width);
4029 p++;
4030 hp += mouse_track_width;
4031 if (hp > x_mouse_x)
4032 {
4033 mouse_track_left = hp - mouse_track_width;
4034 goto draw_or_not;
4035 }
4036 continue;
4037
4038 case '\n':
4039 mouse_track_width = -1;
4040 goto draw_or_not;
4041
4042 default:
4043 if (ctl_arrow_p && (c < 040 || c == 0177))
4044 {
4045 if (p > ZV)
4046 goto draw_or_not;
4047
4048 mouse_track_width = 2;
4049 p++;
4050 hp +=2;
4051 if (hp > x_mouse_x)
4052 {
4053 mouse_track_left = hp - mouse_track_width;
4054 goto draw_or_not;
4055 }
4056 }
4057 else
4058 {
4059 mouse_track_width = 1;
4060 p++;
4061 hp++;
4062 }
4063 continue;
4064 }
4065 }
4066 while (hp <= x_mouse_x);
4067
4068 draw_or_not:
b9dc4443 4069 if (mouse_track_width) /* Over text; use text pointer shape. */
01f1ba30 4070 {
b9dc4443 4071 XDefineCursor (FRAME_X_DISPLAY (f),
fe24a618 4072 FRAME_X_WINDOW (f),
f676886a
JB
4073 f->display.x->text_cursor);
4074 x_rectangle (f, f->display.x->cursor_gc,
01f1ba30
JB
4075 mouse_track_left, mouse_track_top,
4076 mouse_track_width, 1);
4077 }
4078 else if (in_mode_line)
b9dc4443 4079 XDefineCursor (FRAME_X_DISPLAY (f),
fe24a618 4080 FRAME_X_WINDOW (f),
f676886a 4081 f->display.x->modeline_cursor);
01f1ba30 4082 else
b9dc4443 4083 XDefineCursor (FRAME_X_DISPLAY (f),
fe24a618 4084 FRAME_X_WINDOW (f),
f676886a 4085 f->display.x->nontext_cursor);
01f1ba30
JB
4086 }
4087
b9dc4443 4088 XFlush (FRAME_X_DISPLAY (f));
01f1ba30
JB
4089 UNBLOCK_INPUT;
4090
95be70ed 4091 obj = read_char (-1, 0, 0, Qnil, 0);
01f1ba30
JB
4092 BLOCK_INPUT;
4093 }
6a5e54e2 4094 while (CONSP (obj) /* Mouse event */
a3c87d4e 4095 && EQ (Fcar (Fcdr (Fcdr (obj))), Qnil) /* Not scroll bar */
01f1ba30
JB
4096 && EQ (Vmouse_depressed, Qnil) /* Only motion events */
4097 && EQ (Vmouse_window, selected_window) /* In this window */
f676886a 4098 && x_mouse_frame);
01f1ba30 4099
b4f5687c 4100 unread_command_event = obj;
01f1ba30
JB
4101
4102 if (mouse_track_width)
4103 {
f676886a 4104 x_rectangle (f, f->display.x->reverse_gc,
01f1ba30
JB
4105 mouse_track_left, mouse_track_top,
4106 mouse_track_width, 1);
4107 mouse_track_width = 0;
f676886a
JB
4108 if ((mouse_track_left == f->phys_cursor_x
4109 || mouse_track_left - 1 == f->phys_cursor_x)
4110 && mouse_track_top == f->phys_cursor_y)
01f1ba30 4111 {
f676886a 4112 x_display_cursor (f, 1);
01f1ba30
JB
4113 }
4114 }
b9dc4443 4115 XDefineCursor (FRAME_X_DISPLAY (f),
fe24a618 4116 FRAME_X_WINDOW (f),
f676886a 4117 f->display.x->nontext_cursor);
b9dc4443 4118 XFlush (FRAME_X_DISPLAY (f));
01f1ba30
JB
4119 UNBLOCK_INPUT;
4120
4121 return Qnil;
4122}
4123#endif
4124\f
4125#if 0
4126#include "glyphs.h"
4127
4128/* Draw a pixmap specified by IMAGE_DATA of dimensions WIDTH and HEIGHT
b9dc4443 4129 on the frame F at position X, Y. */
01f1ba30 4130
f676886a
JB
4131x_draw_pixmap (f, x, y, image_data, width, height)
4132 struct frame *f;
01f1ba30
JB
4133 int x, y, width, height;
4134 char *image_data;
4135{
4136 Pixmap image;
4137
b9dc4443 4138 image = XCreateBitmapFromData (FRAME_X_DISPLAY (f),
fe24a618 4139 FRAME_X_WINDOW (f), image_data,
01f1ba30 4140 width, height);
b9dc4443 4141 XCopyPlane (FRAME_X_DISPLAY (f), image, FRAME_X_WINDOW (f),
f676886a 4142 f->display.x->normal_gc, 0, 0, width, height, x, y);
01f1ba30
JB
4143}
4144#endif
4145\f
01567351
RS
4146#if 0 /* I'm told these functions are superfluous
4147 given the ability to bind function keys. */
4148
01f1ba30
JB
4149#ifdef HAVE_X11
4150DEFUN ("x-rebind-key", Fx_rebind_key, Sx_rebind_key, 3, 3, 0,
4151"Rebind X keysym KEYSYM, with MODIFIERS, to generate NEWSTRING.\n\
4152KEYSYM is a string which conforms to the X keysym definitions found\n\
4153in X11/keysymdef.h, sans the initial XK_. MODIFIERS is nil or a\n\
4154list of strings specifying modifier keys such as Control_L, which must\n\
4155also be depressed for NEWSTRING to appear.")
4156 (x_keysym, modifiers, newstring)
4157 register Lisp_Object x_keysym;
4158 register Lisp_Object modifiers;
4159 register Lisp_Object newstring;
4160{
4161 char *rawstring;
c047688c
JA
4162 register KeySym keysym;
4163 KeySym modifier_list[16];
01f1ba30 4164
11ae94fe 4165 check_x ();
01f1ba30
JB
4166 CHECK_STRING (x_keysym, 1);
4167 CHECK_STRING (newstring, 3);
4168
4169 keysym = XStringToKeysym ((char *) XSTRING (x_keysym)->data);
4170 if (keysym == NoSymbol)
4171 error ("Keysym does not exist");
4172
265a9e55 4173 if (NILP (modifiers))
01f1ba30
JB
4174 XRebindKeysym (x_current_display, keysym, modifier_list, 0,
4175 XSTRING (newstring)->data, XSTRING (newstring)->size);
4176 else
4177 {
4178 register Lisp_Object rest, mod;
4179 register int i = 0;
4180
265a9e55 4181 for (rest = modifiers; !NILP (rest); rest = Fcdr (rest))
01f1ba30
JB
4182 {
4183 if (i == 16)
4184 error ("Can't have more than 16 modifiers");
4185
4186 mod = Fcar (rest);
4187 CHECK_STRING (mod, 3);
4188 modifier_list[i] = XStringToKeysym ((char *) XSTRING (mod)->data);
fb351039
JB
4189#ifndef HAVE_X11R5
4190 if (modifier_list[i] == NoSymbol
4191 || !(IsModifierKey (modifier_list[i])
4192 || ((unsigned)(modifier_list[i]) == XK_Mode_switch)
4193 || ((unsigned)(modifier_list[i]) == XK_Num_Lock)))
4194#else
01f1ba30
JB
4195 if (modifier_list[i] == NoSymbol
4196 || !IsModifierKey (modifier_list[i]))
fb351039 4197#endif
01f1ba30
JB
4198 error ("Element is not a modifier keysym");
4199 i++;
4200 }
4201
4202 XRebindKeysym (x_current_display, keysym, modifier_list, i,
4203 XSTRING (newstring)->data, XSTRING (newstring)->size);
4204 }
4205
4206 return Qnil;
4207}
4208
4209DEFUN ("x-rebind-keys", Fx_rebind_keys, Sx_rebind_keys, 2, 2, 0,
4210 "Rebind KEYCODE to list of strings STRINGS.\n\
4211STRINGS should be a list of 16 elements, one for each shift combination.\n\
4212nil as element means don't change.\n\
4213See the documentation of `x-rebind-key' for more information.")
4214 (keycode, strings)
4215 register Lisp_Object keycode;
4216 register Lisp_Object strings;
4217{
4218 register Lisp_Object item;
4219 register unsigned char *rawstring;
4220 KeySym rawkey, modifier[1];
4221 int strsize;
4222 register unsigned i;
4223
11ae94fe 4224 check_x ();
01f1ba30
JB
4225 CHECK_NUMBER (keycode, 1);
4226 CHECK_CONS (strings, 2);
4227 rawkey = (KeySym) ((unsigned) (XINT (keycode))) & 255;
4228 for (i = 0; i <= 15; strings = Fcdr (strings), i++)
4229 {
4230 item = Fcar (strings);
265a9e55 4231 if (!NILP (item))
01f1ba30
JB
4232 {
4233 CHECK_STRING (item, 2);
4234 strsize = XSTRING (item)->size;
4235 rawstring = (unsigned char *) xmalloc (strsize);
4236 bcopy (XSTRING (item)->data, rawstring, strsize);
4237 modifier[1] = 1 << i;
4238 XRebindKeysym (x_current_display, rawkey, modifier, 1,
4239 rawstring, strsize);
4240 }
4241 }
4242 return Qnil;
4243}
9d04a87a 4244#endif /* HAVE_X11 */
01567351 4245#endif /* 0 */
01f1ba30 4246\f
404daac1
RS
4247#ifndef HAVE_XSCREENNUMBEROFSCREEN
4248int
4249XScreenNumberOfScreen (scr)
4250 register Screen *scr;
4251{
3df34fdb
BF
4252 register Display *dpy;
4253 register Screen *dpyscr;
404daac1
RS
4254 register int i;
4255
3df34fdb
BF
4256 dpy = scr->display;
4257 dpyscr = dpy->screens;
4258
404daac1
RS
4259 for (i = 0; i < dpy->nscreens; i++, dpyscr++)
4260 if (scr == dpyscr)
4261 return i;
4262
4263 return -1;
4264}
4265#endif /* not HAVE_XSCREENNUMBEROFSCREEN */
4266
01f1ba30 4267Visual *
b9dc4443
RS
4268select_visual (dpy, screen, depth)
4269 Display *dpy;
01f1ba30
JB
4270 Screen *screen;
4271 unsigned int *depth;
4272{
4273 Visual *v;
4274 XVisualInfo *vinfo, vinfo_template;
4275 int n_visuals;
4276
4277 v = DefaultVisualOfScreen (screen);
fe24a618
JB
4278
4279#ifdef HAVE_X11R4
4280 vinfo_template.visualid = XVisualIDFromVisual (v);
4281#else
6afb1d07 4282 vinfo_template.visualid = v->visualid;
fe24a618
JB
4283#endif
4284
f0614854
JB
4285 vinfo_template.screen = XScreenNumberOfScreen (screen);
4286
b9dc4443 4287 vinfo = XGetVisualInfo (dpy,
f0614854 4288 VisualIDMask | VisualScreenMask, &vinfo_template,
01f1ba30
JB
4289 &n_visuals);
4290 if (n_visuals != 1)
4291 fatal ("Can't get proper X visual info");
4292
4293 if ((1 << vinfo->depth) == vinfo->colormap_size)
4294 *depth = vinfo->depth;
4295 else
4296 {
4297 int i = 0;
4298 int n = vinfo->colormap_size - 1;
4299 while (n)
4300 {
4301 n = n >> 1;
4302 i++;
4303 }
4304 *depth = i;
4305 }
4306
4307 XFree ((char *) vinfo);
4308 return v;
4309}
01f1ba30 4310
b9dc4443
RS
4311/* Return the X display structure for the display named NAME.
4312 Open a new connection if necessary. */
4313
4314struct x_display_info *
4315x_display_info_for_name (name)
4316 Lisp_Object name;
4317{
08a90d6a 4318 Lisp_Object names;
b9dc4443
RS
4319 struct x_display_info *dpyinfo;
4320
4321 CHECK_STRING (name, 0);
4322
08a90d6a
RS
4323 for (dpyinfo = x_display_list, names = x_display_name_list;
4324 dpyinfo;
4325 dpyinfo = dpyinfo->next, names = XCONS (names)->cdr)
b9dc4443
RS
4326 {
4327 Lisp_Object tem;
08a90d6a
RS
4328 tem = Fstring_equal (XCONS (XCONS (names)->car)->car, name);
4329 if (!NILP (tem))
b9dc4443
RS
4330 return dpyinfo;
4331 }
4332
4333 validate_x_resource_name ();
4334
4335 dpyinfo = x_term_init (name, (unsigned char *)0,
4336 XSTRING (Vx_resource_name)->data);
4337
08a90d6a
RS
4338 if (dpyinfo == 0)
4339 error ("X server %s not responding", XSTRING (name)->data);
4340
b9dc4443
RS
4341 x_in_use = 1;
4342 XSETFASTINT (Vwindow_system_version, 11);
4343
4344 return dpyinfo;
4345}
4346
01f1ba30 4347DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
08a90d6a 4348 1, 3, 0, "Open a connection to an X server.\n\
d387c960 4349DISPLAY is the name of the display to connect to.\n\
08a90d6a
RS
4350Optional second arg XRM-STRING is a string of resources in xrdb format.\n\
4351If the optional third arg MUST-SUCCEED is non-nil,\n\
4352terminate Emacs if we can't open the connection.")
4353 (display, xrm_string, must_succeed)
4354 Lisp_Object display, xrm_string, must_succeed;
01f1ba30
JB
4355{
4356 unsigned int n_planes;
01f1ba30 4357 unsigned char *xrm_option;
b9dc4443 4358 struct x_display_info *dpyinfo;
01f1ba30
JB
4359
4360 CHECK_STRING (display, 0);
d387c960
JB
4361 if (! NILP (xrm_string))
4362 CHECK_STRING (xrm_string, 1);
01f1ba30 4363
d387c960
JB
4364 if (! NILP (xrm_string))
4365 xrm_option = (unsigned char *) XSTRING (xrm_string)->data;
01f1ba30
JB
4366 else
4367 xrm_option = (unsigned char *) 0;
d387c960
JB
4368
4369 validate_x_resource_name ();
4370
e1b1bee8 4371 /* This is what opens the connection and sets x_current_display.
b9dc4443
RS
4372 This also initializes many symbols, such as those used for input. */
4373 dpyinfo = x_term_init (display, xrm_option,
4374 XSTRING (Vx_resource_name)->data);
f1c16f36 4375
08a90d6a
RS
4376 if (dpyinfo == 0)
4377 {
4378 if (!NILP (must_succeed))
4379 fatal ("X server %s not responding.\n\
4380Check the DISPLAY environment variable or use \"-d\"\n",
4381 XSTRING (display)->data);
4382 else
4383 error ("X server %s not responding", XSTRING (display)->data);
4384 }
4385
b9dc4443 4386 x_in_use = 1;
01f1ba30 4387
b9dc4443 4388 XSETFASTINT (Vwindow_system_version, 11);
01f1ba30
JB
4389 return Qnil;
4390}
4391
08a90d6a
RS
4392DEFUN ("x-close-connection", Fx_close_connection,
4393 Sx_close_connection, 1, 1, 0,
4394 "Close the connection to DISPLAY's X server.\n\
4395For DISPLAY, specify either a frame or a display name (a string).\n\
4396If DISPLAY is nil, that stands for the selected frame's display.")
4397 (display)
4398 Lisp_Object display;
01f1ba30 4399{
08a90d6a
RS
4400 struct x_display_info *dpyinfo = check_x_display_info (display);
4401 struct x_display_info *tail;
4402 int i;
3457bc6e 4403
08a90d6a
RS
4404 if (dpyinfo->reference_count > 0)
4405 error ("Display still has frames on it");
01f1ba30 4406
08a90d6a
RS
4407 BLOCK_INPUT;
4408 /* Free the fonts in the font table. */
4409 for (i = 0; i < dpyinfo->n_fonts; i++)
01f1ba30 4410 {
08a90d6a
RS
4411 if (dpyinfo->font_table[i].name)
4412 free (dpyinfo->font_table[i].name);
4413 /* Don't free the full_name string;
4414 it is always shared with something else. */
4415 XFreeFont (dpyinfo->display, dpyinfo->font_table[i].font);
01f1ba30 4416 }
08a90d6a
RS
4417 x_destroy_all_bitmaps (dpyinfo);
4418 XSetCloseDownMode (dpyinfo->display, DestroyAll);
82c90203
RS
4419
4420#ifdef USE_X_TOOLKIT
4421 XtCloseDisplay (dpyinfo->display);
4422#else
08a90d6a 4423 XCloseDisplay (dpyinfo->display);
82c90203 4424#endif
08a90d6a
RS
4425
4426 x_delete_display (dpyinfo);
4427 UNBLOCK_INPUT;
3457bc6e 4428
01f1ba30
JB
4429 return Qnil;
4430}
4431
08a90d6a
RS
4432DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
4433 "Return the list of display names that Emacs has connections to.")
4434 ()
4435{
4436 Lisp_Object tail, result;
4437
4438 result = Qnil;
4439 for (tail = x_display_name_list; ! NILP (tail); tail = XCONS (tail)->cdr)
4440 result = Fcons (XCONS (XCONS (tail)->car)->car, result);
4441
4442 return result;
4443}
4444
4445DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
4446 "If ON is non-nil, report X errors as soon as the erring request is made.\n\
01f1ba30
JB
4447If ON is nil, allow buffering of requests.\n\
4448Turning on synchronization prohibits the Xlib routines from buffering\n\
4449requests and seriously degrades performance, but makes debugging much\n\
08a90d6a
RS
4450easier.
4451The optional second argument DISPLAY specifies which display to act on.\n\
4452DISPLAY should be either a frame or a display name (a string).\n\
4453If DISPLAY is omitted or nil, that stands for the selected frame's display.")
4454 (on, display)
4455 Lisp_Object display, on;
01f1ba30 4456{
08a90d6a 4457 struct x_display_info *dpyinfo = check_x_display_info (display);
11ae94fe 4458
b9dc4443 4459 XSynchronize (dpyinfo->display, !EQ (on, Qnil));
01f1ba30
JB
4460
4461 return Qnil;
4462}
4463
b9dc4443 4464/* Wait for responses to all X commands issued so far for frame F. */
6b7b1820
RS
4465
4466void
b9dc4443
RS
4467x_sync (f)
4468 FRAME_PTR f;
6b7b1820 4469{
4e87f4d2 4470 BLOCK_INPUT;
b9dc4443 4471 XSync (FRAME_X_DISPLAY (f), False);
4e87f4d2 4472 UNBLOCK_INPUT;
6b7b1820 4473}
01f1ba30
JB
4474\f
4475syms_of_xfns ()
4476{
01f1ba30 4477 /* This is zero if not using X windows. */
b9dc4443 4478 x_in_use = 0;
f1c16f36 4479
f9942c9e
JB
4480 /* The section below is built by the lisp expression at the top of the file,
4481 just above where these variables are declared. */
4482 /*&&& init symbols here &&&*/
4483 Qauto_raise = intern ("auto-raise");
4484 staticpro (&Qauto_raise);
4485 Qauto_lower = intern ("auto-lower");
4486 staticpro (&Qauto_lower);
4487 Qbackground_color = intern ("background-color");
4488 staticpro (&Qbackground_color);
dbc4e1c1
JB
4489 Qbar = intern ("bar");
4490 staticpro (&Qbar);
f9942c9e
JB
4491 Qborder_color = intern ("border-color");
4492 staticpro (&Qborder_color);
4493 Qborder_width = intern ("border-width");
4494 staticpro (&Qborder_width);
dbc4e1c1
JB
4495 Qbox = intern ("box");
4496 staticpro (&Qbox);
f9942c9e
JB
4497 Qcursor_color = intern ("cursor-color");
4498 staticpro (&Qcursor_color);
dbc4e1c1
JB
4499 Qcursor_type = intern ("cursor-type");
4500 staticpro (&Qcursor_type);
f9942c9e
JB
4501 Qfont = intern ("font");
4502 staticpro (&Qfont);
4503 Qforeground_color = intern ("foreground-color");
4504 staticpro (&Qforeground_color);
4505 Qgeometry = intern ("geometry");
4506 staticpro (&Qgeometry);
f9942c9e
JB
4507 Qicon_left = intern ("icon-left");
4508 staticpro (&Qicon_left);
4509 Qicon_top = intern ("icon-top");
4510 staticpro (&Qicon_top);
4511 Qicon_type = intern ("icon-type");
4512 staticpro (&Qicon_type);
f9942c9e
JB
4513 Qinternal_border_width = intern ("internal-border-width");
4514 staticpro (&Qinternal_border_width);
4515 Qleft = intern ("left");
4516 staticpro (&Qleft);
4517 Qmouse_color = intern ("mouse-color");
4518 staticpro (&Qmouse_color);
baaed68e
JB
4519 Qnone = intern ("none");
4520 staticpro (&Qnone);
f9942c9e
JB
4521 Qparent_id = intern ("parent-id");
4522 staticpro (&Qparent_id);
4701395c
KH
4523 Qscroll_bar_width = intern ("scroll-bar-width");
4524 staticpro (&Qscroll_bar_width);
8af1d7ca
JB
4525 Qsuppress_icon = intern ("suppress-icon");
4526 staticpro (&Qsuppress_icon);
f9942c9e
JB
4527 Qtop = intern ("top");
4528 staticpro (&Qtop);
01f1ba30 4529 Qundefined_color = intern ("undefined-color");
f9942c9e 4530 staticpro (&Qundefined_color);
a3c87d4e
JB
4531 Qvertical_scroll_bars = intern ("vertical-scroll-bars");
4532 staticpro (&Qvertical_scroll_bars);
49795535
JB
4533 Qvisibility = intern ("visibility");
4534 staticpro (&Qvisibility);
f9942c9e
JB
4535 Qwindow_id = intern ("window-id");
4536 staticpro (&Qwindow_id);
4537 Qx_frame_parameter = intern ("x-frame-parameter");
4538 staticpro (&Qx_frame_parameter);
9ef48a9d
RS
4539 Qx_resource_name = intern ("x-resource-name");
4540 staticpro (&Qx_resource_name);
4fe1de12
RS
4541 Quser_position = intern ("user-position");
4542 staticpro (&Quser_position);
4543 Quser_size = intern ("user-size");
4544 staticpro (&Quser_size);
b9dc4443
RS
4545 Qdisplay = intern ("display");
4546 staticpro (&Qdisplay);
f9942c9e
JB
4547 /* This is the end of symbol initialization. */
4548
01f1ba30
JB
4549 Fput (Qundefined_color, Qerror_conditions,
4550 Fcons (Qundefined_color, Fcons (Qerror, Qnil)));
4551 Fput (Qundefined_color, Qerror_message,
4552 build_string ("Undefined color"));
4553
f9942c9e
JB
4554 init_x_parm_symbols ();
4555
f1c7b5a6
RS
4556 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path,
4557 "List of directories to search for bitmap files for X.");
4558 Vx_bitmap_file_path = Fcons (build_string (PATH_BITMAPS), Qnil);
4559
16ae08a9 4560 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
d387c960 4561 "The shape of the pointer when over text.\n\
af01ef26
RS
4562Changing the value does not affect existing frames\n\
4563unless you set the mouse color.");
01f1ba30
JB
4564 Vx_pointer_shape = Qnil;
4565
d387c960
JB
4566 DEFVAR_LISP ("x-resource-name", &Vx_resource_name,
4567 "The name Emacs uses to look up X resources; for internal use only.\n\
4568`x-get-resource' uses this as the first component of the instance name\n\
4569when requesting resource values.\n\
4570Emacs initially sets `x-resource-name' to the name under which Emacs\n\
4571was invoked, or to the value specified with the `-name' or `-rn'\n\
4572switches, if present.");
4573 Vx_resource_name = Qnil;
ac63d3d6 4574
ca0ecbf5 4575#if 0 /* This doesn't really do anything. */
01f1ba30 4576 DEFVAR_INT ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape,
ca0ecbf5
RS
4577 "The shape of the pointer when not over text.\n\
4578This variable takes effect when you create a new frame\n\
4579or when you set the mouse color.");
af01ef26 4580#endif
01f1ba30
JB
4581 Vx_nontext_pointer_shape = Qnil;
4582
ca0ecbf5 4583#if 0 /* This doesn't really do anything. */
01f1ba30 4584 DEFVAR_INT ("x-mode-pointer-shape", &Vx_mode_pointer_shape,
ca0ecbf5
RS
4585 "The shape of the pointer when over the mode line.\n\
4586This variable takes effect when you create a new frame\n\
4587or when you set the mouse color.");
af01ef26 4588#endif
01f1ba30
JB
4589 Vx_mode_pointer_shape = Qnil;
4590
ca0ecbf5
RS
4591 DEFVAR_INT ("x-sensitive-text-pointer-shape",
4592 &Vx_sensitive_text_pointer_shape,
4593 "The shape of the pointer when over mouse-sensitive text.\n\
4594This variable takes effect when you create a new frame\n\
4595or when you set the mouse color.");
4596 Vx_sensitive_text_pointer_shape = Qnil;
95f80c78 4597
01f1ba30
JB
4598 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel,
4599 "A string indicating the foreground color of the cursor box.");
4600 Vx_cursor_fore_pixel = Qnil;
4601
01f1ba30 4602 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
1d3dac41
RS
4603 "Non-nil if no X window manager is in use.");
4604
1d3dac41 4605#ifdef USE_X_TOOLKIT
f1d238ef 4606 Fprovide (intern ("x-toolkit"));
1d3dac41 4607#endif
01f1ba30 4608
01f1ba30 4609 defsubr (&Sx_get_resource);
85ffea93 4610#if 0
01f1ba30
JB
4611 defsubr (&Sx_draw_rectangle);
4612 defsubr (&Sx_erase_rectangle);
4613 defsubr (&Sx_contour_region);
4614 defsubr (&Sx_uncontour_region);
85ffea93 4615#endif
f0614854 4616 defsubr (&Sx_list_fonts);
d0c9d219
RS
4617 defsubr (&Sx_display_color_p);
4618 defsubr (&Sx_display_grayscale_p);
8af1d7ca 4619 defsubr (&Sx_color_defined_p);
e12d55b2 4620 defsubr (&Sx_color_values);
9d317b2c 4621 defsubr (&Sx_server_max_request_size);
41beb8fc
RS
4622 defsubr (&Sx_server_vendor);
4623 defsubr (&Sx_server_version);
4624 defsubr (&Sx_display_pixel_width);
4625 defsubr (&Sx_display_pixel_height);
4626 defsubr (&Sx_display_mm_width);
4627 defsubr (&Sx_display_mm_height);
4628 defsubr (&Sx_display_screens);
4629 defsubr (&Sx_display_planes);
4630 defsubr (&Sx_display_color_cells);
4631 defsubr (&Sx_display_visual_class);
4632 defsubr (&Sx_display_backing_store);
4633 defsubr (&Sx_display_save_under);
01567351 4634#if 0
9d04a87a
RS
4635 defsubr (&Sx_rebind_key);
4636 defsubr (&Sx_rebind_keys);
01f1ba30 4637 defsubr (&Sx_track_pointer);
01f1ba30
JB
4638 defsubr (&Sx_grab_pointer);
4639 defsubr (&Sx_ungrab_pointer);
01f1ba30 4640#endif
8af1d7ca 4641 defsubr (&Sx_parse_geometry);
f676886a
JB
4642 defsubr (&Sx_create_frame);
4643 defsubr (&Sfocus_frame);
4644 defsubr (&Sunfocus_frame);
06ef7355 4645#if 0
01f1ba30 4646 defsubr (&Sx_horizontal_line);
06ef7355 4647#endif
01f1ba30 4648 defsubr (&Sx_open_connection);
08a90d6a
RS
4649 defsubr (&Sx_close_connection);
4650 defsubr (&Sx_display_list);
01f1ba30 4651 defsubr (&Sx_synchronize);
01f1ba30
JB
4652}
4653
4654#endif /* HAVE_X_WINDOWS */