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