Use the `visiblity' parameter to determine the initial state of
[bpt/emacs.git] / src / xfns.c
1 /* Functions for the X window system.
2 Copyright (C) 1989, 1992, 1993 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 #if 0
25 #include <stdio.h>
26 #endif
27 #include <signal.h>
28 #include "config.h"
29 #include "lisp.h"
30 #include "xterm.h"
31 #include "frame.h"
32 #include "window.h"
33 #include "buffer.h"
34 #include "dispextern.h"
35 #include "keyboard.h"
36
37 #ifdef HAVE_X_WINDOWS
38 extern void abort ();
39
40 #include <X11/bitmaps/gray>
41
42 #define min(a,b) ((a) < (b) ? (a) : (b))
43 #define max(a,b) ((a) > (b) ? (a) : (b))
44
45 #ifdef HAVE_X11
46 /* X Resource data base */
47 static XrmDatabase xrdb;
48
49 /* The class of this X application. */
50 #define EMACS_CLASS "Emacs"
51
52 /* Title name and application name for X stuff. */
53 extern char *x_id_name;
54
55 /* The background and shape of the mouse pointer, and shape when not
56 over text or in the modeline. */
57 Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
58
59 /* Color of chars displayed in cursor box. */
60 Lisp_Object Vx_cursor_fore_pixel;
61
62 /* The screen being used. */
63 static Screen *x_screen;
64
65 /* The X Visual we are using for X windows (the default) */
66 Visual *screen_visual;
67
68 /* Height of this X screen in pixels. */
69 int x_screen_height;
70
71 /* Width of this X screen in pixels. */
72 int x_screen_width;
73
74 /* Number of planes for this screen. */
75 int x_screen_planes;
76
77 /* Non nil if no window manager is in use. */
78 Lisp_Object Vx_no_window_manager;
79
80 /* `t' if a mouse button is depressed. */
81
82 Lisp_Object Vmouse_depressed;
83
84 extern unsigned int x_mouse_x, x_mouse_y, x_mouse_grabbed;
85
86 /* Atom for indicating window state to the window manager. */
87 extern Atom Xatom_wm_change_state;
88
89 /* Communication with window managers. */
90 extern Atom Xatom_wm_protocols;
91
92 /* Kinds of protocol things we may receive. */
93 extern Atom Xatom_wm_take_focus;
94 extern Atom Xatom_wm_save_yourself;
95 extern Atom Xatom_wm_delete_window;
96
97 /* Other WM communication */
98 extern Atom Xatom_wm_configure_denied; /* When our config request is denied */
99 extern Atom Xatom_wm_window_moved; /* When the WM moves us. */
100
101 #else /* X10 */
102
103 /* Default size of an Emacs window. */
104 static char *default_window = "=80x24+0+0";
105
106 #define MAXICID 80
107 char iconidentity[MAXICID];
108 #define ICONTAG "emacs@"
109 char minibuffer_iconidentity[MAXICID];
110 #define MINIBUFFER_ICONTAG "minibuffer@"
111
112 #endif /* X10 */
113
114 /* The last 23 bits of the timestamp of the last mouse button event. */
115 Time mouse_timestamp;
116
117 /* Evaluate this expression to rebuild the section of syms_of_xfns
118 that initializes and staticpros the symbols declared below. Note
119 that Emacs 18 has a bug that keeps C-x C-e from being able to
120 evaluate this expression.
121
122 (progn
123 ;; Accumulate a list of the symbols we want to initialize from the
124 ;; declarations at the top of the file.
125 (goto-char (point-min))
126 (search-forward "/\*&&& symbols declared here &&&*\/\n")
127 (let (symbol-list)
128 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
129 (setq symbol-list
130 (cons (buffer-substring (match-beginning 1) (match-end 1))
131 symbol-list))
132 (forward-line 1))
133 (setq symbol-list (nreverse symbol-list))
134 ;; Delete the section of syms_of_... where we initialize the symbols.
135 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
136 (let ((start (point)))
137 (while (looking-at "^ Q")
138 (forward-line 2))
139 (kill-region start (point)))
140 ;; Write a new symbol initialization section.
141 (while symbol-list
142 (insert (format " %s = intern (\"" (car symbol-list)))
143 (let ((start (point)))
144 (insert (substring (car symbol-list) 1))
145 (subst-char-in-region start (point) ?_ ?-))
146 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
147 (setq symbol-list (cdr symbol-list)))))
148
149 */
150
151 /*&&& symbols declared here &&&*/
152 Lisp_Object Qauto_raise;
153 Lisp_Object Qauto_lower;
154 Lisp_Object Qbackground_color;
155 Lisp_Object Qbar;
156 Lisp_Object Qborder_color;
157 Lisp_Object Qborder_width;
158 Lisp_Object Qbox;
159 Lisp_Object Qcursor_color;
160 Lisp_Object Qcursor_type;
161 Lisp_Object Qfont;
162 Lisp_Object Qforeground_color;
163 Lisp_Object Qgeometry;
164 Lisp_Object Qicon;
165 Lisp_Object Qicon_left;
166 Lisp_Object Qicon_top;
167 Lisp_Object Qicon_type;
168 Lisp_Object Qinternal_border_width;
169 Lisp_Object Qleft;
170 Lisp_Object Qmouse_color;
171 Lisp_Object Qnone;
172 Lisp_Object Qparent_id;
173 Lisp_Object Qtop;
174 Lisp_Object Qundefined_color;
175 Lisp_Object Qvertical_scroll_bars;
176 Lisp_Object Qvisibility;
177 Lisp_Object Qwindow_id;
178 Lisp_Object Qx_frame_parameter;
179
180 /* The below are defined in frame.c. */
181 extern Lisp_Object Qheight, Qminibuffer, Qname, Qonly, Qwidth;
182 extern Lisp_Object Qunsplittable, Qmenu_bar_lines, Qicon;
183
184 extern Lisp_Object Vwindow_system_version;
185
186 /* Mouse map for clicks in windows. */
187 extern Lisp_Object Vglobal_mouse_map;
188
189 /* Points to table of defined typefaces. */
190 struct face *x_face_table[MAX_FACES_AND_GLYPHS];
191 \f
192 /* Return the Emacs frame-object corresponding to an X window.
193 It could be the frame's main window or an icon window. */
194
195 struct frame *
196 x_window_to_frame (wdesc)
197 int wdesc;
198 {
199 Lisp_Object tail, frame;
200 struct frame *f;
201
202 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
203 {
204 frame = XCONS (tail)->car;
205 if (XTYPE (frame) != Lisp_Frame)
206 continue;
207 f = XFRAME (frame);
208 if (FRAME_X_WINDOW (f) == wdesc
209 || f->display.x->icon_desc == wdesc)
210 return f;
211 }
212 return 0;
213 }
214
215 \f
216 /* Connect the frame-parameter names for X frames
217 to the ways of passing the parameter values to the window system.
218
219 The name of a parameter, as a Lisp symbol,
220 has an `x-frame-parameter' property which is an integer in Lisp
221 but can be interpreted as an `enum x_frame_parm' in C. */
222
223 enum x_frame_parm
224 {
225 X_PARM_FOREGROUND_COLOR,
226 X_PARM_BACKGROUND_COLOR,
227 X_PARM_MOUSE_COLOR,
228 X_PARM_CURSOR_COLOR,
229 X_PARM_BORDER_COLOR,
230 X_PARM_ICON_TYPE,
231 X_PARM_FONT,
232 X_PARM_BORDER_WIDTH,
233 X_PARM_INTERNAL_BORDER_WIDTH,
234 X_PARM_NAME,
235 X_PARM_AUTORAISE,
236 X_PARM_AUTOLOWER,
237 X_PARM_VERT_SCROLL_BAR,
238 X_PARM_VISIBILITY,
239 X_PARM_MENU_BAR_LINES
240 };
241
242
243 struct x_frame_parm_table
244 {
245 char *name;
246 void (*setter)( /* struct frame *frame, Lisp_Object val, oldval */ );
247 };
248
249 void x_set_foreground_color ();
250 void x_set_background_color ();
251 void x_set_mouse_color ();
252 void x_set_cursor_color ();
253 void x_set_border_color ();
254 void x_set_cursor_type ();
255 void x_set_icon_type ();
256 void x_set_font ();
257 void x_set_border_width ();
258 void x_set_internal_border_width ();
259 void x_explicitly_set_name ();
260 void x_set_autoraise ();
261 void x_set_autolower ();
262 void x_set_vertical_scroll_bars ();
263 void x_set_visibility ();
264 void x_set_menu_bar_lines ();
265
266 static struct x_frame_parm_table x_frame_parms[] =
267 {
268 "foreground-color", x_set_foreground_color,
269 "background-color", x_set_background_color,
270 "mouse-color", x_set_mouse_color,
271 "cursor-color", x_set_cursor_color,
272 "border-color", x_set_border_color,
273 "cursor-type", x_set_cursor_type,
274 "icon-type", x_set_icon_type,
275 "font", x_set_font,
276 "border-width", x_set_border_width,
277 "internal-border-width", x_set_internal_border_width,
278 "name", x_explicitly_set_name,
279 "auto-raise", x_set_autoraise,
280 "auto-lower", x_set_autolower,
281 "vertical-scroll-bars", x_set_vertical_scroll_bars,
282 "visibility", x_set_visibility,
283 "menu-bar-lines", x_set_menu_bar_lines,
284 };
285
286 /* Attach the `x-frame-parameter' properties to
287 the Lisp symbol names of parameters relevant to X. */
288
289 init_x_parm_symbols ()
290 {
291 int i;
292
293 for (i = 0; i < sizeof (x_frame_parms) / sizeof (x_frame_parms[0]); i++)
294 Fput (intern (x_frame_parms[i].name), Qx_frame_parameter,
295 make_number (i));
296 }
297 \f
298 /* Change the parameters of FRAME as specified by ALIST.
299 If a parameter is not specially recognized, do nothing;
300 otherwise call the `x_set_...' function for that parameter. */
301
302 void
303 x_set_frame_parameters (f, alist)
304 FRAME_PTR f;
305 Lisp_Object alist;
306 {
307 Lisp_Object tail;
308
309 /* If both of these parameters are present, it's more efficient to
310 set them both at once. So we wait until we've looked at the
311 entire list before we set them. */
312 Lisp_Object width, height;
313
314 /* Same here. */
315 Lisp_Object left, top;
316
317 XSET (width, Lisp_Int, FRAME_WIDTH (f));
318 XSET (height, Lisp_Int, FRAME_HEIGHT (f));
319
320 XSET (top, Lisp_Int, f->display.x->top_pos);
321 XSET (left, Lisp_Int, f->display.x->left_pos);
322
323 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
324 {
325 Lisp_Object elt, prop, val;
326
327 elt = Fcar (tail);
328 prop = Fcar (elt);
329 val = Fcdr (elt);
330
331 if (EQ (prop, Qwidth))
332 width = val;
333 else if (EQ (prop, Qheight))
334 height = val;
335 else if (EQ (prop, Qtop))
336 top = val;
337 else if (EQ (prop, Qleft))
338 left = val;
339 else
340 {
341 register Lisp_Object tem;
342 tem = Fget (prop, Qx_frame_parameter);
343 if (XTYPE (tem) == Lisp_Int
344 && XINT (tem) >= 0
345 && XINT (tem) < sizeof (x_frame_parms)/sizeof (x_frame_parms[0]))
346 (*x_frame_parms[XINT (tem)].setter)(f, val,
347 get_frame_param (f, prop));
348 store_frame_param (f, prop, val);
349 }
350 }
351
352 /* Don't call these unless they've changed; the window may not actually
353 exist yet. */
354 {
355 Lisp_Object frame;
356
357 XSET (frame, Lisp_Frame, f);
358 if (XINT (width) != FRAME_WIDTH (f)
359 || XINT (height) != FRAME_HEIGHT (f))
360 Fset_frame_size (frame, width, height);
361 if (XINT (left) != f->display.x->left_pos
362 || XINT (top) != f->display.x->top_pos)
363 Fset_frame_position (frame, left, top);
364 }
365 }
366
367 /* Insert a description of internally-recorded parameters of frame X
368 into the parameter alist *ALISTPTR that is to be given to the user.
369 Only parameters that are specific to the X window system
370 and whose values are not correctly recorded in the frame's
371 param_alist need to be considered here. */
372
373 x_report_frame_params (f, alistptr)
374 struct frame *f;
375 Lisp_Object *alistptr;
376 {
377 char buf[16];
378
379 store_in_alist (alistptr, Qleft, make_number (f->display.x->left_pos));
380 store_in_alist (alistptr, Qtop, make_number (f->display.x->top_pos));
381 store_in_alist (alistptr, Qborder_width,
382 make_number (f->display.x->border_width));
383 store_in_alist (alistptr, Qinternal_border_width,
384 make_number (f->display.x->internal_border_width));
385 sprintf (buf, "%d", FRAME_X_WINDOW (f));
386 store_in_alist (alistptr, Qwindow_id,
387 build_string (buf));
388 store_in_alist (alistptr, Qvisibility,
389 (FRAME_VISIBLE_P (f) ? Qt
390 : FRAME_ICONIFIED_P (f) ? Qicon : Qnil));
391 }
392 \f
393 /* Decide if color named COLOR is valid for the display
394 associated with the selected frame. */
395 int
396 defined_color (color, color_def)
397 char *color;
398 Color *color_def;
399 {
400 register int foo;
401 Colormap screen_colormap;
402
403 BLOCK_INPUT;
404 #ifdef HAVE_X11
405 screen_colormap
406 = DefaultColormap (x_current_display, XDefaultScreen (x_current_display));
407
408 foo = XParseColor (x_current_display, screen_colormap,
409 color, color_def)
410 && XAllocColor (x_current_display, screen_colormap, color_def);
411 #else
412 foo = XParseColor (color, color_def) && XGetHardwareColor (color_def);
413 #endif /* not HAVE_X11 */
414 UNBLOCK_INPUT;
415
416 if (foo)
417 return 1;
418 else
419 return 0;
420 }
421
422 /* Given a string ARG naming a color, compute a pixel value from it
423 suitable for screen F.
424 If F is not a color screen, return DEF (default) regardless of what
425 ARG says. */
426
427 int
428 x_decode_color (arg, def)
429 Lisp_Object arg;
430 int def;
431 {
432 Color cdef;
433
434 CHECK_STRING (arg, 0);
435
436 if (strcmp (XSTRING (arg)->data, "black") == 0)
437 return BLACK_PIX_DEFAULT;
438 else if (strcmp (XSTRING (arg)->data, "white") == 0)
439 return WHITE_PIX_DEFAULT;
440
441 #ifdef HAVE_X11
442 if (x_screen_planes == 1)
443 return def;
444 #else
445 if (DISPLAY_CELLS == 1)
446 return def;
447 #endif
448
449 if (defined_color (XSTRING (arg)->data, &cdef))
450 return cdef.pixel;
451 else
452 Fsignal (Qundefined_color, Fcons (arg, Qnil));
453 }
454 \f
455 /* Functions called only from `x_set_frame_param'
456 to set individual parameters.
457
458 If FRAME_X_WINDOW (f) is 0,
459 the frame is being created and its X-window does not exist yet.
460 In that case, just record the parameter's new value
461 in the standard place; do not attempt to change the window. */
462
463 void
464 x_set_foreground_color (f, arg, oldval)
465 struct frame *f;
466 Lisp_Object arg, oldval;
467 {
468 f->display.x->foreground_pixel = x_decode_color (arg, BLACK_PIX_DEFAULT);
469 if (FRAME_X_WINDOW (f) != 0)
470 {
471 #ifdef HAVE_X11
472 BLOCK_INPUT;
473 XSetForeground (x_current_display, f->display.x->normal_gc,
474 f->display.x->foreground_pixel);
475 XSetBackground (x_current_display, f->display.x->reverse_gc,
476 f->display.x->foreground_pixel);
477 UNBLOCK_INPUT;
478 #endif /* HAVE_X11 */
479 if (FRAME_VISIBLE_P (f))
480 redraw_frame (f);
481 }
482 }
483
484 void
485 x_set_background_color (f, arg, oldval)
486 struct frame *f;
487 Lisp_Object arg, oldval;
488 {
489 Pixmap temp;
490 int mask;
491
492 f->display.x->background_pixel = x_decode_color (arg, WHITE_PIX_DEFAULT);
493
494 if (FRAME_X_WINDOW (f) != 0)
495 {
496 BLOCK_INPUT;
497 #ifdef HAVE_X11
498 /* The main frame area. */
499 XSetBackground (x_current_display, f->display.x->normal_gc,
500 f->display.x->background_pixel);
501 XSetForeground (x_current_display, f->display.x->reverse_gc,
502 f->display.x->background_pixel);
503 XSetWindowBackground (x_current_display, FRAME_X_WINDOW (f),
504 f->display.x->background_pixel);
505
506 #else
507 temp = XMakeTile (f->display.x->background_pixel);
508 XChangeBackground (FRAME_X_WINDOW (f), temp);
509 XFreePixmap (temp);
510 #endif /* not HAVE_X11 */
511 UNBLOCK_INPUT;
512
513 if (FRAME_VISIBLE_P (f))
514 redraw_frame (f);
515 }
516 }
517
518 void
519 x_set_mouse_color (f, arg, oldval)
520 struct frame *f;
521 Lisp_Object arg, oldval;
522 {
523 Cursor cursor, nontext_cursor, mode_cursor;
524 int mask_color;
525
526 if (!EQ (Qnil, arg))
527 f->display.x->mouse_pixel = x_decode_color (arg, BLACK_PIX_DEFAULT);
528 mask_color = f->display.x->background_pixel;
529 /* No invisible pointers. */
530 if (mask_color == f->display.x->mouse_pixel
531 && mask_color == f->display.x->background_pixel)
532 f->display.x->mouse_pixel = f->display.x->foreground_pixel;
533
534 BLOCK_INPUT;
535 #ifdef HAVE_X11
536
537 /* It's not okay to crash if the user selects a screwey cursor. */
538 x_catch_errors ();
539
540 if (!EQ (Qnil, Vx_pointer_shape))
541 {
542 CHECK_NUMBER (Vx_pointer_shape, 0);
543 cursor = XCreateFontCursor (x_current_display, XINT (Vx_pointer_shape));
544 }
545 else
546 cursor = XCreateFontCursor (x_current_display, XC_xterm);
547 x_check_errors ("bad text pointer cursor: %s");
548
549 if (!EQ (Qnil, Vx_nontext_pointer_shape))
550 {
551 CHECK_NUMBER (Vx_nontext_pointer_shape, 0);
552 nontext_cursor = XCreateFontCursor (x_current_display,
553 XINT (Vx_nontext_pointer_shape));
554 }
555 else
556 nontext_cursor = XCreateFontCursor (x_current_display, XC_left_ptr);
557 x_check_errors ("bad nontext pointer cursor: %s");
558
559 if (!EQ (Qnil, Vx_mode_pointer_shape))
560 {
561 CHECK_NUMBER (Vx_mode_pointer_shape, 0);
562 mode_cursor = XCreateFontCursor (x_current_display,
563 XINT (Vx_mode_pointer_shape));
564 }
565 else
566 mode_cursor = XCreateFontCursor (x_current_display, XC_xterm);
567
568 /* Check and report errors with the above calls. */
569 x_check_errors ("can't set cursor shape: %s");
570 x_uncatch_errors ();
571
572 {
573 XColor fore_color, back_color;
574
575 fore_color.pixel = f->display.x->mouse_pixel;
576 back_color.pixel = mask_color;
577 XQueryColor (x_current_display,
578 DefaultColormap (x_current_display,
579 DefaultScreen (x_current_display)),
580 &fore_color);
581 XQueryColor (x_current_display,
582 DefaultColormap (x_current_display,
583 DefaultScreen (x_current_display)),
584 &back_color);
585 XRecolorCursor (x_current_display, cursor,
586 &fore_color, &back_color);
587 XRecolorCursor (x_current_display, nontext_cursor,
588 &fore_color, &back_color);
589 XRecolorCursor (x_current_display, mode_cursor,
590 &fore_color, &back_color);
591 }
592 #else /* X10 */
593 cursor = XCreateCursor (16, 16, MouseCursor, MouseMask,
594 0, 0,
595 f->display.x->mouse_pixel,
596 f->display.x->background_pixel,
597 GXcopy);
598 #endif /* X10 */
599
600 if (FRAME_X_WINDOW (f) != 0)
601 {
602 XDefineCursor (XDISPLAY FRAME_X_WINDOW (f), cursor);
603 }
604
605 if (cursor != f->display.x->text_cursor && f->display.x->text_cursor != 0)
606 XFreeCursor (XDISPLAY f->display.x->text_cursor);
607 f->display.x->text_cursor = cursor;
608 #ifdef HAVE_X11
609 if (nontext_cursor != f->display.x->nontext_cursor
610 && f->display.x->nontext_cursor != 0)
611 XFreeCursor (XDISPLAY f->display.x->nontext_cursor);
612 f->display.x->nontext_cursor = nontext_cursor;
613
614 if (mode_cursor != f->display.x->modeline_cursor
615 && f->display.x->modeline_cursor != 0)
616 XFreeCursor (XDISPLAY f->display.x->modeline_cursor);
617 f->display.x->modeline_cursor = mode_cursor;
618 #endif /* HAVE_X11 */
619
620 XFlushQueue ();
621 UNBLOCK_INPUT;
622 }
623
624 void
625 x_set_cursor_color (f, arg, oldval)
626 struct frame *f;
627 Lisp_Object arg, oldval;
628 {
629 unsigned long fore_pixel;
630
631 if (!EQ (Vx_cursor_fore_pixel, Qnil))
632 fore_pixel = x_decode_color (Vx_cursor_fore_pixel, WHITE_PIX_DEFAULT);
633 else
634 fore_pixel = f->display.x->background_pixel;
635 f->display.x->cursor_pixel = x_decode_color (arg, BLACK_PIX_DEFAULT);
636
637 /* Make sure that the cursor color differs from the background color. */
638 if (f->display.x->cursor_pixel == f->display.x->background_pixel)
639 {
640 f->display.x->cursor_pixel == f->display.x->mouse_pixel;
641 if (f->display.x->cursor_pixel == fore_pixel)
642 fore_pixel = f->display.x->background_pixel;
643 }
644
645 if (FRAME_X_WINDOW (f) != 0)
646 {
647 #ifdef HAVE_X11
648 BLOCK_INPUT;
649 XSetBackground (x_current_display, f->display.x->cursor_gc,
650 f->display.x->cursor_pixel);
651 XSetForeground (x_current_display, f->display.x->cursor_gc,
652 fore_pixel);
653 UNBLOCK_INPUT;
654 #endif /* HAVE_X11 */
655
656 if (FRAME_VISIBLE_P (f))
657 {
658 x_display_cursor (f, 0);
659 x_display_cursor (f, 1);
660 }
661 }
662 }
663
664 /* Set the border-color of frame F to value described by ARG.
665 ARG can be a string naming a color.
666 The border-color is used for the border that is drawn by the X server.
667 Note that this does not fully take effect if done before
668 F has an x-window; it must be redone when the window is created.
669
670 Note: this is done in two routines because of the way X10 works.
671
672 Note: under X11, this is normally the province of the window manager,
673 and so emacs' border colors may be overridden. */
674
675 void
676 x_set_border_color (f, arg, oldval)
677 struct frame *f;
678 Lisp_Object arg, oldval;
679 {
680 unsigned char *str;
681 int pix;
682
683 CHECK_STRING (arg, 0);
684 str = XSTRING (arg)->data;
685
686 #ifndef HAVE_X11
687 if (!strcmp (str, "grey") || !strcmp (str, "Grey")
688 || !strcmp (str, "gray") || !strcmp (str, "Gray"))
689 pix = -1;
690 else
691 #endif /* X10 */
692
693 pix = x_decode_color (arg, BLACK_PIX_DEFAULT);
694
695 x_set_border_pixel (f, pix);
696 }
697
698 /* Set the border-color of frame F to pixel value PIX.
699 Note that this does not fully take effect if done before
700 F has an x-window. */
701
702 x_set_border_pixel (f, pix)
703 struct frame *f;
704 int pix;
705 {
706 f->display.x->border_pixel = pix;
707
708 if (FRAME_X_WINDOW (f) != 0 && f->display.x->border_width > 0)
709 {
710 Pixmap temp;
711 int mask;
712
713 BLOCK_INPUT;
714 #ifdef HAVE_X11
715 XSetWindowBorder (x_current_display, FRAME_X_WINDOW (f),
716 pix);
717 #else
718 if (pix < 0)
719 temp = XMakePixmap ((Bitmap) XStoreBitmap (gray_width, gray_height,
720 gray_bits),
721 BLACK_PIX_DEFAULT, WHITE_PIX_DEFAULT);
722 else
723 temp = XMakeTile (pix);
724 XChangeBorder (FRAME_X_WINDOW (f), temp);
725 XFreePixmap (XDISPLAY temp);
726 #endif /* not HAVE_X11 */
727 UNBLOCK_INPUT;
728
729 if (FRAME_VISIBLE_P (f))
730 redraw_frame (f);
731 }
732 }
733
734 void
735 x_set_cursor_type (f, arg, oldval)
736 FRAME_PTR f;
737 Lisp_Object arg, oldval;
738 {
739 if (EQ (arg, Qbar))
740 FRAME_DESIRED_CURSOR (f) = bar_cursor;
741 else if (EQ (arg, Qbox))
742 FRAME_DESIRED_CURSOR (f) = filled_box_cursor;
743 else
744 error
745 ("the `cursor-type' frame parameter should be either `bar' or `box'");
746
747 /* Make sure the cursor gets redrawn. This is overkill, but how
748 often do people change cursor types? */
749 update_mode_lines++;
750 }
751
752 void
753 x_set_icon_type (f, arg, oldval)
754 struct frame *f;
755 Lisp_Object arg, oldval;
756 {
757 Lisp_Object tem;
758 int result;
759
760 if (EQ (oldval, Qnil) == EQ (arg, Qnil))
761 return;
762
763 BLOCK_INPUT;
764 if (NILP (arg))
765 result = x_text_icon (f, 0);
766 else
767 result = x_bitmap_icon (f);
768
769 if (result)
770 {
771 UNBLOCK_INPUT;
772 error ("No icon window available.");
773 }
774
775 /* If the window was unmapped (and its icon was mapped),
776 the new icon is not mapped, so map the window in its stead. */
777 if (FRAME_VISIBLE_P (f))
778 XMapWindow (XDISPLAY FRAME_X_WINDOW (f));
779
780 XFlushQueue ();
781 UNBLOCK_INPUT;
782 }
783
784 void
785 x_set_font (f, arg, oldval)
786 struct frame *f;
787 Lisp_Object arg, oldval;
788 {
789 unsigned char *name;
790 int result;
791
792 CHECK_STRING (arg, 1);
793 name = XSTRING (arg)->data;
794
795 BLOCK_INPUT;
796 result = x_new_font (f, name);
797 UNBLOCK_INPUT;
798
799 if (result)
800 error ("Font \"%s\" is not defined", name);
801 }
802
803 void
804 x_set_border_width (f, arg, oldval)
805 struct frame *f;
806 Lisp_Object arg, oldval;
807 {
808 CHECK_NUMBER (arg, 0);
809
810 if (XINT (arg) == f->display.x->border_width)
811 return;
812
813 if (FRAME_X_WINDOW (f) != 0)
814 error ("Cannot change the border width of a window");
815
816 f->display.x->border_width = XINT (arg);
817 }
818
819 void
820 x_set_internal_border_width (f, arg, oldval)
821 struct frame *f;
822 Lisp_Object arg, oldval;
823 {
824 int mask;
825 int old = f->display.x->internal_border_width;
826
827 CHECK_NUMBER (arg, 0);
828 f->display.x->internal_border_width = XINT (arg);
829 if (f->display.x->internal_border_width < 0)
830 f->display.x->internal_border_width = 0;
831
832 if (f->display.x->internal_border_width == old)
833 return;
834
835 if (FRAME_X_WINDOW (f) != 0)
836 {
837 BLOCK_INPUT;
838 x_set_window_size (f, f->width, f->height);
839 #if 0
840 x_set_resize_hint (f);
841 #endif
842 XFlushQueue ();
843 UNBLOCK_INPUT;
844 SET_FRAME_GARBAGED (f);
845 }
846 }
847
848 void
849 x_set_visibility (f, value, oldval)
850 struct frame *f;
851 Lisp_Object value, oldval;
852 {
853 Lisp_Object frame;
854 XSET (frame, Lisp_Frame, f);
855
856 if (NILP (value))
857 Fmake_frame_invisible (frame);
858 else if (EQ (value, Qicon))
859 Ficonify_frame (frame);
860 else
861 Fmake_frame_visible (frame);
862 }
863
864 static void
865 x_set_menu_bar_lines_1 (window, n)
866 Lisp_Object window;
867 int n;
868 {
869 for (; !NILP (window); window = XWINDOW (window)->next)
870 {
871 struct window *w = XWINDOW (window);
872
873 w->top += n;
874
875 if (!NILP (w->vchild))
876 x_set_menu_bar_lines_1 (w->vchild);
877
878 if (!NILP (w->hchild))
879 x_set_menu_bar_lines_1 (w->hchild);
880 }
881 }
882
883 void
884 x_set_menu_bar_lines (f, value, oldval)
885 struct frame *f;
886 Lisp_Object value, oldval;
887 {
888 int nlines;
889 int olines = FRAME_MENU_BAR_LINES (f);
890
891 if (XTYPE (value) == Lisp_Int)
892 nlines = XINT (value);
893 else
894 nlines = 0;
895
896 FRAME_MENU_BAR_LINES (f) = nlines;
897 x_set_menu_bar_lines_1 (f->root_window, nlines - olines);
898 x_set_window_size (f, FRAME_WIDTH (f),
899 FRAME_HEIGHT (f) + nlines - olines);
900 }
901
902 /* Change the name of frame F to ARG. If ARG is nil, set F's name to
903 x_id_name.
904
905 If EXPLICIT is non-zero, that indicates that lisp code is setting the
906 name; if ARG is a string, set F's name to ARG and set
907 F->explicit_name; if ARG is Qnil, then clear F->explicit_name.
908
909 If EXPLICIT is zero, that indicates that Emacs redisplay code is
910 suggesting a new name, which lisp code should override; if
911 F->explicit_name is set, ignore the new name; otherwise, set it. */
912
913 void
914 x_set_name (f, name, explicit)
915 struct frame *f;
916 Lisp_Object name;
917 int explicit;
918 {
919 /* Make sure that requests from lisp code override requests from
920 Emacs redisplay code. */
921 if (explicit)
922 {
923 /* If we're switching from explicit to implicit, we had better
924 update the mode lines and thereby update the title. */
925 if (f->explicit_name && NILP (name))
926 update_mode_lines = 1;
927
928 f->explicit_name = ! NILP (name);
929 }
930 else if (f->explicit_name)
931 return;
932
933 /* If NAME is nil, set the name to the x_id_name. */
934 if (NILP (name))
935 name = build_string (x_id_name);
936 else
937 CHECK_STRING (name, 0);
938
939 /* Don't change the name if it's already NAME. */
940 if (! NILP (Fstring_equal (name, f->name)))
941 return;
942
943 if (FRAME_X_WINDOW (f))
944 {
945 BLOCK_INPUT;
946
947 #ifdef HAVE_X11R4
948 {
949 XTextProperty text;
950 text.value = XSTRING (name)->data;
951 text.encoding = XA_STRING;
952 text.format = 8;
953 text.nitems = XSTRING (name)->size;
954 XSetWMName (x_current_display, FRAME_X_WINDOW (f), &text);
955 XSetWMIconName (x_current_display, FRAME_X_WINDOW (f), &text);
956 }
957 #else
958 XSetIconName (XDISPLAY FRAME_X_WINDOW (f),
959 XSTRING (name)->data);
960 XStoreName (XDISPLAY FRAME_X_WINDOW (f),
961 XSTRING (name)->data);
962 #endif
963
964 UNBLOCK_INPUT;
965 }
966
967 f->name = name;
968 }
969
970 /* This function should be called when the user's lisp code has
971 specified a name for the frame; the name will override any set by the
972 redisplay code. */
973 void
974 x_explicitly_set_name (f, arg, oldval)
975 FRAME_PTR f;
976 Lisp_Object arg, oldval;
977 {
978 x_set_name (f, arg, 1);
979 }
980
981 /* This function should be called by Emacs redisplay code to set the
982 name; names set this way will never override names set by the user's
983 lisp code. */
984 void
985 x_implicitly_set_name (f, arg, oldval)
986 FRAME_PTR f;
987 Lisp_Object arg, oldval;
988 {
989 x_set_name (f, arg, 0);
990 }
991
992 void
993 x_set_autoraise (f, arg, oldval)
994 struct frame *f;
995 Lisp_Object arg, oldval;
996 {
997 f->auto_raise = !EQ (Qnil, arg);
998 }
999
1000 void
1001 x_set_autolower (f, arg, oldval)
1002 struct frame *f;
1003 Lisp_Object arg, oldval;
1004 {
1005 f->auto_lower = !EQ (Qnil, arg);
1006 }
1007
1008 void
1009 x_set_vertical_scroll_bars (f, arg, oldval)
1010 struct frame *f;
1011 Lisp_Object arg, oldval;
1012 {
1013 if (NILP (arg) != ! FRAME_HAS_VERTICAL_SCROLL_BARS (f))
1014 {
1015 FRAME_HAS_VERTICAL_SCROLL_BARS (f) = ! NILP (arg);
1016
1017 /* We set this parameter before creating the X window for the
1018 frame, so we can get the geometry right from the start.
1019 However, if the window hasn't been created yet, we shouldn't
1020 call x_set_window_size. */
1021 if (FRAME_X_WINDOW (f))
1022 x_set_window_size (f, FRAME_WIDTH (f), FRAME_HEIGHT (f));
1023 }
1024 }
1025 \f
1026 #ifdef HAVE_X11
1027 int n_faces;
1028
1029 #if 0
1030 /* I believe this function is obsolete with respect to the new face display
1031 changes. */
1032 x_set_face (scr, font, background, foreground, stipple)
1033 struct frame *scr;
1034 XFontStruct *font;
1035 unsigned long background, foreground;
1036 Pixmap stipple;
1037 {
1038 XGCValues gc_values;
1039 GC temp_gc;
1040 unsigned long gc_mask;
1041 struct face *new_face;
1042 unsigned int width = 16;
1043 unsigned int height = 16;
1044
1045 if (n_faces == MAX_FACES_AND_GLYPHS)
1046 return 1;
1047
1048 /* Create the Graphics Context. */
1049 gc_values.font = font->fid;
1050 gc_values.foreground = foreground;
1051 gc_values.background = background;
1052 gc_values.line_width = 0;
1053 gc_mask = GCLineWidth | GCFont | GCForeground | GCBackground;
1054 if (stipple)
1055 {
1056 gc_values.stipple
1057 = XCreateBitmapFromData (x_current_display, ROOT_WINDOW,
1058 (char *) stipple, width, height);
1059 gc_mask |= GCStipple;
1060 }
1061
1062 temp_gc = XCreateGC (x_current_display, FRAME_X_WINDOW (scr),
1063 gc_mask, &gc_values);
1064 if (!temp_gc)
1065 return 1;
1066 new_face = (struct face *) xmalloc (sizeof (struct face));
1067 if (!new_face)
1068 {
1069 XFreeGC (x_current_display, temp_gc);
1070 return 1;
1071 }
1072
1073 new_face->font = font;
1074 new_face->foreground = foreground;
1075 new_face->background = background;
1076 new_face->face_gc = temp_gc;
1077 if (stipple)
1078 new_face->stipple = gc_values.stipple;
1079
1080 x_face_table[++n_faces] = new_face;
1081 return 1;
1082 }
1083 #endif
1084
1085 x_set_glyph (scr, glyph)
1086 {
1087 }
1088
1089 #if 0
1090 DEFUN ("x-set-face-font", Fx_set_face_font, Sx_set_face_font, 4, 2, 0,
1091 "Specify face table entry FACE-CODE to be the font named by FONT,\n\
1092 in colors FOREGROUND and BACKGROUND.")
1093 (face_code, font_name, foreground, background)
1094 Lisp_Object face_code;
1095 Lisp_Object font_name;
1096 Lisp_Object foreground;
1097 Lisp_Object background;
1098 {
1099 register struct face *fp; /* Current face info. */
1100 register int fn; /* Face number. */
1101 register FONT_TYPE *f; /* Font data structure. */
1102 unsigned char *newname;
1103 int fg, bg;
1104 GC temp_gc;
1105 XGCValues gc_values;
1106
1107 /* Need to do something about this. */
1108 Drawable drawable = FRAME_X_WINDOW (selected_frame);
1109
1110 CHECK_NUMBER (face_code, 1);
1111 CHECK_STRING (font_name, 2);
1112
1113 if (EQ (foreground, Qnil) || EQ (background, Qnil))
1114 {
1115 fg = selected_frame->display.x->foreground_pixel;
1116 bg = selected_frame->display.x->background_pixel;
1117 }
1118 else
1119 {
1120 CHECK_NUMBER (foreground, 0);
1121 CHECK_NUMBER (background, 1);
1122
1123 fg = x_decode_color (XINT (foreground), BLACK_PIX_DEFAULT);
1124 bg = x_decode_color (XINT (background), WHITE_PIX_DEFAULT);
1125 }
1126
1127 fn = XINT (face_code);
1128 if ((fn < 1) || (fn > 255))
1129 error ("Invalid face code, %d", fn);
1130
1131 newname = XSTRING (font_name)->data;
1132 BLOCK_INPUT;
1133 f = (*newname == 0 ? 0 : XGetFont (newname));
1134 UNBLOCK_INPUT;
1135 if (f == 0)
1136 error ("Font \"%s\" is not defined", newname);
1137
1138 fp = x_face_table[fn];
1139 if (fp == 0)
1140 {
1141 x_face_table[fn] = fp = (struct face *) xmalloc (sizeof (struct face));
1142 bzero (fp, sizeof (struct face));
1143 fp->face_type = x_pixmap;
1144 }
1145 else if (FACE_IS_FONT (fn))
1146 {
1147 BLOCK_INPUT;
1148 XFreeGC (FACE_FONT (fn));
1149 UNBLOCK_INPUT;
1150 }
1151 else if (FACE_IS_IMAGE (fn)) /* This should not happen... */
1152 {
1153 BLOCK_INPUT;
1154 XFreePixmap (x_current_display, FACE_IMAGE (fn));
1155 fp->face_type = x_font;
1156 UNBLOCK_INPUT;
1157 }
1158 else
1159 abort ();
1160
1161 fp->face_GLYPH.font_desc.font = f;
1162 gc_values.font = f->fid;
1163 gc_values.foreground = fg;
1164 gc_values.background = bg;
1165 fp->face_GLYPH.font_desc.face_gc = XCreateGC (x_current_display,
1166 drawable, GCFont | GCForeground
1167 | GCBackground, &gc_values);
1168 fp->face_GLYPH.font_desc.font_width = FONT_WIDTH (f);
1169 fp->face_GLYPH.font_desc.font_height = FONT_HEIGHT (f);
1170
1171 return face_code;
1172 }
1173 #endif
1174 #else /* X10 */
1175 DEFUN ("x-set-face", Fx_set_face, Sx_set_face, 4, 4, 0,
1176 "Specify face table entry FACE-CODE to be the font named by FONT,\n\
1177 in colors FOREGROUND and BACKGROUND.")
1178 (face_code, font_name, foreground, background)
1179 Lisp_Object face_code;
1180 Lisp_Object font_name;
1181 Lisp_Object foreground;
1182 Lisp_Object background;
1183 {
1184 register struct face *fp; /* Current face info. */
1185 register int fn; /* Face number. */
1186 register FONT_TYPE *f; /* Font data structure. */
1187 unsigned char *newname;
1188
1189 CHECK_NUMBER (face_code, 1);
1190 CHECK_STRING (font_name, 2);
1191
1192 fn = XINT (face_code);
1193 if ((fn < 1) || (fn > 255))
1194 error ("Invalid face code, %d", fn);
1195
1196 /* Ask the server to find the specified font. */
1197 newname = XSTRING (font_name)->data;
1198 BLOCK_INPUT;
1199 f = (*newname == 0 ? 0 : XGetFont (newname));
1200 UNBLOCK_INPUT;
1201 if (f == 0)
1202 error ("Font \"%s\" is not defined", newname);
1203
1204 /* Get the face structure for face_code in the face table.
1205 Make sure it exists. */
1206 fp = x_face_table[fn];
1207 if (fp == 0)
1208 {
1209 x_face_table[fn] = fp = (struct face *) xmalloc (sizeof (struct face));
1210 bzero (fp, sizeof (struct face));
1211 }
1212
1213 /* If this face code already exists, get rid of the old font. */
1214 if (fp->font != 0 && fp->font != f)
1215 {
1216 BLOCK_INPUT;
1217 XLoseFont (fp->font);
1218 UNBLOCK_INPUT;
1219 }
1220
1221 /* Store the specified information in FP. */
1222 fp->fg = x_decode_color (foreground, BLACK_PIX_DEFAULT);
1223 fp->bg = x_decode_color (background, WHITE_PIX_DEFAULT);
1224 fp->font = f;
1225
1226 return face_code;
1227 }
1228 #endif /* X10 */
1229
1230 #if 0
1231 /* This is excluded because there is no painless way
1232 to get or to remember the name of the font. */
1233
1234 DEFUN ("x-get-face", Fx_get_face, Sx_get_face, 1, 1, 0,
1235 "Get data defining face code FACE. FACE is an integer.\n\
1236 The value is a list (FONT FG-COLOR BG-COLOR).")
1237 (face)
1238 Lisp_Object face;
1239 {
1240 register struct face *fp; /* Current face info. */
1241 register int fn; /* Face number. */
1242
1243 CHECK_NUMBER (face, 1);
1244 fn = XINT (face);
1245 if ((fn < 1) || (fn > 255))
1246 error ("Invalid face code, %d", fn);
1247
1248 /* Make sure the face table exists and this face code is defined. */
1249 if (x_face_table == 0 || x_face_table[fn] == 0)
1250 return Qnil;
1251
1252 fp = x_face_table[fn];
1253
1254 return Fcons (build_string (fp->name),
1255 Fcons (make_number (fp->fg),
1256 Fcons (make_number (fp->bg), Qnil)));
1257 }
1258 #endif /* 0 */
1259 \f
1260 /* Subroutines of creating an X frame. */
1261
1262 #ifdef HAVE_X11
1263 extern char *x_get_string_resource ();
1264 extern XrmDatabase x_load_resources ();
1265
1266 DEFUN ("x-get-resource", Fx_get_resource, Sx_get_resource, 2, 4, 0,
1267 "Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.\n\
1268 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the\n\
1269 class, where INSTANCE is the name under which Emacs was invoked.\n\
1270 \n\
1271 The optional arguments COMPONENT and SUBCLASS add to the key and the\n\
1272 class, respectively. You must specify both of them or neither.\n\
1273 If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'\n\
1274 and the class is `Emacs.CLASS.SUBCLASS'.")
1275 (attribute, class, component, subclass)
1276 Lisp_Object attribute, class, component, subclass;
1277 {
1278 register char *value;
1279 char *name_key;
1280 char *class_key;
1281
1282 CHECK_STRING (attribute, 0);
1283 CHECK_STRING (class, 0);
1284
1285 if (!NILP (component))
1286 CHECK_STRING (component, 1);
1287 if (!NILP (subclass))
1288 CHECK_STRING (subclass, 2);
1289 if (NILP (component) != NILP (subclass))
1290 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
1291
1292 if (NILP (component))
1293 {
1294 /* Allocate space for the components, the dots which separate them,
1295 and the final '\0'. */
1296 name_key = (char *) alloca (XSTRING (Vinvocation_name)->size
1297 + XSTRING (attribute)->size
1298 + 2);
1299 class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
1300 + XSTRING (class)->size
1301 + 2);
1302
1303 sprintf (name_key, "%s.%s",
1304 XSTRING (Vinvocation_name)->data,
1305 XSTRING (attribute)->data);
1306 sprintf (class_key, "%s.%s",
1307 EMACS_CLASS,
1308 XSTRING (class)->data);
1309 }
1310 else
1311 {
1312 name_key = (char *) alloca (XSTRING (Vinvocation_name)->size
1313 + XSTRING (component)->size
1314 + XSTRING (attribute)->size
1315 + 3);
1316
1317 class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
1318 + XSTRING (class)->size
1319 + XSTRING (subclass)->size
1320 + 3);
1321
1322 sprintf (name_key, "%s.%s.%s",
1323 XSTRING (Vinvocation_name)->data,
1324 XSTRING (component)->data,
1325 XSTRING (attribute)->data);
1326 sprintf (class_key, "%s.%s",
1327 EMACS_CLASS,
1328 XSTRING (class)->data,
1329 XSTRING (subclass)->data);
1330 }
1331
1332 value = x_get_string_resource (xrdb, name_key, class_key);
1333
1334 if (value != (char *) 0)
1335 return build_string (value);
1336 else
1337 return Qnil;
1338 }
1339
1340 #else /* X10 */
1341
1342 DEFUN ("x-get-default", Fx_get_default, Sx_get_default, 1, 1, 0,
1343 "Get X default ATTRIBUTE from the system, or nil if no default.\n\
1344 Value is a string (when not nil) and ATTRIBUTE is also a string.\n\
1345 The defaults are specified in the file `~/.Xdefaults'.")
1346 (arg)
1347 Lisp_Object arg;
1348 {
1349 register unsigned char *value;
1350
1351 CHECK_STRING (arg, 1);
1352
1353 value = (unsigned char *) XGetDefault (XDISPLAY
1354 XSTRING (Vinvocation_name)->data,
1355 XSTRING (arg)->data);
1356 if (value == 0)
1357 /* Try reversing last two args, in case this is the buggy version of X. */
1358 value = (unsigned char *) XGetDefault (XDISPLAY
1359 XSTRING (arg)->data,
1360 XSTRING (Vinvocation_name)->data);
1361 if (value != 0)
1362 return build_string (value);
1363 else
1364 return (Qnil);
1365 }
1366
1367 #define Fx_get_resource(attribute, class, component, subclass) \
1368 Fx_get_default(attribute)
1369
1370 #endif /* X10 */
1371
1372 /* Types we might convert a resource string into. */
1373 enum resource_types
1374 {
1375 number, boolean, string, symbol,
1376 };
1377
1378 /* Return the value of parameter PARAM.
1379
1380 First search ALIST, then Vdefault_frame_alist, then the X defaults
1381 database, using ATTRIBUTE as the attribute name and CLASS as its class.
1382
1383 Convert the resource to the type specified by desired_type.
1384
1385 If no default is specified, return Qunbound. If you call
1386 x_get_arg, make sure you deal with Qunbound in a reasonable way,
1387 and don't let it get stored in any lisp-visible variables! */
1388
1389 static Lisp_Object
1390 x_get_arg (alist, param, attribute, class, type)
1391 Lisp_Object alist, param;
1392 char *attribute;
1393 char *class;
1394 enum resource_types type;
1395 {
1396 register Lisp_Object tem;
1397
1398 tem = Fassq (param, alist);
1399 if (EQ (tem, Qnil))
1400 tem = Fassq (param, Vdefault_frame_alist);
1401 if (EQ (tem, Qnil))
1402 {
1403
1404 if (attribute)
1405 {
1406 tem = Fx_get_resource (build_string (attribute),
1407 build_string (class),
1408 Qnil, Qnil);
1409
1410 if (NILP (tem))
1411 return Qunbound;
1412
1413 switch (type)
1414 {
1415 case number:
1416 return make_number (atoi (XSTRING (tem)->data));
1417
1418 case boolean:
1419 tem = Fdowncase (tem);
1420 if (!strcmp (XSTRING (tem)->data, "on")
1421 || !strcmp (XSTRING (tem)->data, "true"))
1422 return Qt;
1423 else
1424 return Qnil;
1425
1426 case string:
1427 return tem;
1428
1429 case symbol:
1430 /* As a special case, we map the values `true' and `on'
1431 to Qt, and `false' and `off' to Qnil. */
1432 {
1433 Lisp_Object lower = Fdowncase (tem);
1434 if (!strcmp (XSTRING (tem)->data, "on")
1435 || !strcmp (XSTRING (tem)->data, "true"))
1436 return Qt;
1437 else (!strcmp (XSTRING (tem)->data, "off")
1438 || !strcmp (XSTRING (tem)->data, "false"))
1439 return Qnil;
1440 else
1441 return intern (tem);
1442 }
1443
1444 default:
1445 abort ();
1446 }
1447 }
1448 else
1449 return Qunbound;
1450 }
1451 return Fcdr (tem);
1452 }
1453
1454 /* Record in frame F the specified or default value according to ALIST
1455 of the parameter named PARAM (a Lisp symbol).
1456 If no value is specified for PARAM, look for an X default for XPROP
1457 on the frame named NAME.
1458 If that is not found either, use the value DEFLT. */
1459
1460 static Lisp_Object
1461 x_default_parameter (f, alist, prop, deflt, xprop, xclass, type)
1462 struct frame *f;
1463 Lisp_Object alist;
1464 Lisp_Object prop;
1465 Lisp_Object deflt;
1466 char *xprop;
1467 char *xclass;
1468 enum resource_types type;
1469 {
1470 Lisp_Object tem;
1471
1472 tem = x_get_arg (alist, prop, xprop, xclass, type);
1473 if (EQ (tem, Qunbound))
1474 tem = deflt;
1475 x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));
1476 return tem;
1477 }
1478 \f
1479 DEFUN ("x-geometry", Fx_geometry, Sx_geometry, 1, 1, 0,
1480 "Parse an X-style geometry string STRING.\n\
1481 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).")
1482 (string)
1483 Lisp_Object string;
1484 {
1485 int geometry, x, y;
1486 unsigned int width, height;
1487 Lisp_Object values[4];
1488
1489 CHECK_STRING (string, 0);
1490
1491 geometry = XParseGeometry ((char *) XSTRING (string)->data,
1492 &x, &y, &width, &height);
1493
1494 switch (geometry & 0xf) /* Mask out {X,Y}Negative */
1495 {
1496 case (XValue | YValue):
1497 /* What's one pixel among friends?
1498 Perhaps fix this some day by returning symbol `extreme-top'... */
1499 if (x == 0 && (geometry & XNegative))
1500 x = -1;
1501 if (y == 0 && (geometry & YNegative))
1502 y = -1;
1503 values[0] = Fcons (Qleft, make_number (x));
1504 values[1] = Fcons (Qtop, make_number (y));
1505 return Flist (2, values);
1506 break;
1507
1508 case (WidthValue | HeightValue):
1509 values[0] = Fcons (Qwidth, make_number (width));
1510 values[1] = Fcons (Qheight, make_number (height));
1511 return Flist (2, values);
1512 break;
1513
1514 case (XValue | YValue | WidthValue | HeightValue):
1515 if (x == 0 && (geometry & XNegative))
1516 x = -1;
1517 if (y == 0 && (geometry & YNegative))
1518 y = -1;
1519 values[0] = Fcons (Qwidth, make_number (width));
1520 values[1] = Fcons (Qheight, make_number (height));
1521 values[2] = Fcons (Qleft, make_number (x));
1522 values[3] = Fcons (Qtop, make_number (y));
1523 return Flist (4, values);
1524 break;
1525
1526 case 0:
1527 return Qnil;
1528
1529 default:
1530 error ("Must specify x and y value, and/or width and height");
1531 }
1532 }
1533
1534 #ifdef HAVE_X11
1535 /* Calculate the desired size and position of this window,
1536 or set rubber-band prompting if none. */
1537
1538 #define DEFAULT_ROWS 40
1539 #define DEFAULT_COLS 80
1540
1541 static int
1542 x_figure_window_size (f, parms)
1543 struct frame *f;
1544 Lisp_Object parms;
1545 {
1546 register Lisp_Object tem0, tem1;
1547 int height, width, left, top;
1548 register int geometry;
1549 long window_prompting = 0;
1550
1551 /* Default values if we fall through.
1552 Actually, if that happens we should get
1553 window manager prompting. */
1554 f->width = DEFAULT_COLS;
1555 f->height = DEFAULT_ROWS;
1556 f->display.x->top_pos = 1;
1557 f->display.x->left_pos = 1;
1558
1559 tem0 = x_get_arg (parms, Qheight, 0, 0, number);
1560 tem1 = x_get_arg (parms, Qwidth, 0, 0, number);
1561 if (! EQ (tem0, Qunbound) && ! EQ (tem1, Qunbound))
1562 {
1563 CHECK_NUMBER (tem0, 0);
1564 CHECK_NUMBER (tem1, 0);
1565 f->height = XINT (tem0);
1566 f->width = XINT (tem1);
1567 window_prompting |= USSize;
1568 }
1569 else if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
1570 error ("Must specify *both* height and width");
1571
1572 f->display.x->vertical_scroll_bar_extra =
1573 (FRAME_HAS_VERTICAL_SCROLL_BARS (f)
1574 ? VERTICAL_SCROLL_BAR_PIXEL_WIDTH (f)
1575 : 0);
1576 f->display.x->pixel_width = CHAR_TO_PIXEL_WIDTH (f, f->width);
1577 f->display.x->pixel_height = CHAR_TO_PIXEL_HEIGHT (f, f->height);
1578
1579 tem0 = x_get_arg (parms, Qtop, 0, 0, number);
1580 tem1 = x_get_arg (parms, Qleft, 0, 0, number);
1581 if (! EQ (tem0, Qunbound) && ! EQ (tem1, Qunbound))
1582 {
1583 CHECK_NUMBER (tem0, 0);
1584 CHECK_NUMBER (tem1, 0);
1585 f->display.x->top_pos = XINT (tem0);
1586 f->display.x->left_pos = XINT (tem1);
1587 x_calc_absolute_position (f);
1588 window_prompting |= USPosition;
1589 }
1590 else if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
1591 error ("Must specify *both* top and left corners");
1592
1593 switch (window_prompting)
1594 {
1595 case USSize | USPosition:
1596 return window_prompting;
1597 break;
1598
1599 case USSize: /* Got the size, need the position. */
1600 window_prompting |= PPosition;
1601 return window_prompting;
1602 break;
1603
1604 case USPosition: /* Got the position, need the size. */
1605 window_prompting |= PSize;
1606 return window_prompting;
1607 break;
1608
1609 case 0: /* Got nothing, take both from geometry. */
1610 window_prompting |= PPosition | PSize;
1611 return window_prompting;
1612 break;
1613
1614 default:
1615 /* Somehow a bit got set in window_prompting that we didn't
1616 put there. */
1617 abort ();
1618 }
1619 }
1620
1621 static void
1622 x_window (f)
1623 struct frame *f;
1624 {
1625 XSetWindowAttributes attributes;
1626 unsigned long attribute_mask;
1627 XClassHint class_hints;
1628
1629 attributes.background_pixel = f->display.x->background_pixel;
1630 attributes.border_pixel = f->display.x->border_pixel;
1631 attributes.bit_gravity = StaticGravity;
1632 attributes.backing_store = NotUseful;
1633 attributes.save_under = True;
1634 attributes.event_mask = STANDARD_EVENT_SET;
1635 attribute_mask = (CWBackPixel | CWBorderPixel | CWBitGravity
1636 #if 0
1637 | CWBackingStore | CWSaveUnder
1638 #endif
1639 | CWEventMask);
1640
1641 BLOCK_INPUT;
1642 FRAME_X_WINDOW (f)
1643 = XCreateWindow (x_current_display, ROOT_WINDOW,
1644 f->display.x->left_pos,
1645 f->display.x->top_pos,
1646 PIXEL_WIDTH (f), PIXEL_HEIGHT (f),
1647 f->display.x->border_width,
1648 CopyFromParent, /* depth */
1649 InputOutput, /* class */
1650 screen_visual, /* set in Fx_open_connection */
1651 attribute_mask, &attributes);
1652
1653 class_hints.res_name = (char *) XSTRING (f->name)->data;
1654 class_hints.res_class = EMACS_CLASS;
1655 XSetClassHint (x_current_display, FRAME_X_WINDOW (f), &class_hints);
1656
1657 /* This indicates that we use the "Passive Input" input model.
1658 Unless we do this, we don't get the Focus{In,Out} events that we
1659 need to draw the cursor correctly. Accursed bureaucrats.
1660 XWhipsAndChains (x_current_display, IronMaiden, &TheRack); */
1661
1662 f->display.x->wm_hints.input = True;
1663 f->display.x->wm_hints.flags |= InputHint;
1664 XSetWMHints (x_current_display, FRAME_X_WINDOW (f), &f->display.x->wm_hints);
1665
1666 /* x_set_name normally ignores requests to set the name if the
1667 requested name is the same as the current name. This is the one
1668 place where that assumption isn't correct; f->name is set, but
1669 the X server hasn't been told. */
1670 {
1671 Lisp_Object name = f->name;
1672 int explicit = f->explicit_name;
1673
1674 f->name = Qnil;
1675 f->explicit_name = 0;
1676 x_set_name (f, name, explicit);
1677 }
1678
1679 XDefineCursor (XDISPLAY FRAME_X_WINDOW (f),
1680 f->display.x->text_cursor);
1681 UNBLOCK_INPUT;
1682
1683 if (FRAME_X_WINDOW (f) == 0)
1684 error ("Unable to create window.");
1685 }
1686
1687 /* Handle the icon stuff for this window. Perhaps later we might
1688 want an x_set_icon_position which can be called interactively as
1689 well. */
1690
1691 static void
1692 x_icon (f, parms)
1693 struct frame *f;
1694 Lisp_Object parms;
1695 {
1696 Lisp_Object icon_x, icon_y;
1697
1698 /* Set the position of the icon. Note that twm groups all
1699 icons in an icon window. */
1700 icon_x = x_get_arg (parms, Qicon_left, 0, 0, number);
1701 icon_y = x_get_arg (parms, Qicon_top, 0, 0, number);
1702 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
1703 {
1704 CHECK_NUMBER (icon_x, 0);
1705 CHECK_NUMBER (icon_y, 0);
1706 }
1707 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
1708 error ("Both left and top icon corners of icon must be specified");
1709
1710 BLOCK_INPUT;
1711
1712 if (! EQ (icon_x, Qunbound))
1713 x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
1714
1715 /* Start up iconic or window? */
1716 x_wm_set_window_state
1717 (f, (EQ (x_get_arg (parms, Qvisibility, 0, 0, symbol), Qicon)
1718 ? IconicState
1719 : NormalState));
1720
1721 UNBLOCK_INPUT;
1722 }
1723
1724 /* Make the GC's needed for this window, setting the
1725 background, border and mouse colors; also create the
1726 mouse cursor and the gray border tile. */
1727
1728 static char cursor_bits[] =
1729 {
1730 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1731 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1732 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1733 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1734 };
1735
1736 static void
1737 x_make_gc (f)
1738 struct frame *f;
1739 {
1740 XGCValues gc_values;
1741 GC temp_gc;
1742 XImage tileimage;
1743
1744 /* Create the GC's of this frame.
1745 Note that many default values are used. */
1746
1747 /* Normal video */
1748 gc_values.font = f->display.x->font->fid;
1749 gc_values.foreground = f->display.x->foreground_pixel;
1750 gc_values.background = f->display.x->background_pixel;
1751 gc_values.line_width = 0; /* Means 1 using fast algorithm. */
1752 f->display.x->normal_gc = XCreateGC (x_current_display,
1753 FRAME_X_WINDOW (f),
1754 GCLineWidth | GCFont
1755 | GCForeground | GCBackground,
1756 &gc_values);
1757
1758 /* Reverse video style. */
1759 gc_values.foreground = f->display.x->background_pixel;
1760 gc_values.background = f->display.x->foreground_pixel;
1761 f->display.x->reverse_gc = XCreateGC (x_current_display,
1762 FRAME_X_WINDOW (f),
1763 GCFont | GCForeground | GCBackground
1764 | GCLineWidth,
1765 &gc_values);
1766
1767 /* Cursor has cursor-color background, background-color foreground. */
1768 gc_values.foreground = f->display.x->background_pixel;
1769 gc_values.background = f->display.x->cursor_pixel;
1770 gc_values.fill_style = FillOpaqueStippled;
1771 gc_values.stipple
1772 = XCreateBitmapFromData (x_current_display, ROOT_WINDOW,
1773 cursor_bits, 16, 16);
1774 f->display.x->cursor_gc
1775 = XCreateGC (x_current_display, FRAME_X_WINDOW (f),
1776 (GCFont | GCForeground | GCBackground
1777 | GCFillStyle | GCStipple | GCLineWidth),
1778 &gc_values);
1779
1780 /* Create the gray border tile used when the pointer is not in
1781 the frame. Since this depends on the frame's pixel values,
1782 this must be done on a per-frame basis. */
1783 f->display.x->border_tile
1784 = (XCreatePixmapFromBitmapData
1785 (x_current_display, ROOT_WINDOW,
1786 gray_bits, gray_width, gray_height,
1787 f->display.x->foreground_pixel,
1788 f->display.x->background_pixel,
1789 DefaultDepth (x_current_display, XDefaultScreen (x_current_display))));
1790 }
1791 #endif /* HAVE_X11 */
1792
1793 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
1794 1, 1, 0,
1795 "Make a new X window, which is called a \"frame\" in Emacs terms.\n\
1796 Return an Emacs frame object representing the X window.\n\
1797 ALIST is an alist of frame parameters.\n\
1798 If the parameters specify that the frame should not have a minibuffer,\n\
1799 and do not specify a specific minibuffer window to use,\n\
1800 then `default-minibuffer-frame' must be a frame whose minibuffer can\n\
1801 be shared by the new frame.")
1802 (parms)
1803 Lisp_Object parms;
1804 {
1805 #ifdef HAVE_X11
1806 struct frame *f;
1807 Lisp_Object frame, tem;
1808 Lisp_Object name;
1809 int minibuffer_only = 0;
1810 long window_prompting = 0;
1811 int width, height;
1812
1813 if (x_current_display == 0)
1814 error ("X windows are not in use or not initialized");
1815
1816 name = x_get_arg (parms, Qname, "title", "Title", string);
1817 if (XTYPE (name) != Lisp_String
1818 && ! EQ (name, Qunbound)
1819 && ! NILP (name))
1820 error ("x-create-frame: name parameter must be a string");
1821
1822 tem = x_get_arg (parms, Qminibuffer, 0, 0, symbol);
1823 if (EQ (tem, Qnone) || NILP (tem))
1824 f = make_frame_without_minibuffer (Qnil);
1825 else if (EQ (tem, Qonly))
1826 {
1827 f = make_minibuffer_frame ();
1828 minibuffer_only = 1;
1829 }
1830 else if (XTYPE (tem) == Lisp_Window)
1831 f = make_frame_without_minibuffer (tem);
1832 else
1833 f = make_frame (1);
1834
1835 /* Note that X Windows does support scroll bars. */
1836 FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
1837
1838 /* Set the name; the functions to which we pass f expect the name to
1839 be set. */
1840 if (EQ (name, Qunbound) || NILP (name))
1841 {
1842 f->name = build_string (x_id_name);
1843 f->explicit_name = 0;
1844 }
1845 else
1846 {
1847 f->name = name;
1848 f->explicit_name = 1;
1849 }
1850
1851 XSET (frame, Lisp_Frame, f);
1852 f->output_method = output_x_window;
1853 f->display.x = (struct x_display *) xmalloc (sizeof (struct x_display));
1854 bzero (f->display.x, sizeof (struct x_display));
1855
1856 /* Note that the frame has no physical cursor right now. */
1857 f->phys_cursor_x = -1;
1858
1859 /* Extract the window parameters from the supplied values
1860 that are needed to determine window geometry. */
1861 x_default_parameter (f, parms, Qfont, build_string ("9x15"),
1862 "font", "Font", string);
1863 x_default_parameter (f, parms, Qborder_width, make_number (2),
1864 "borderwidth", "BorderWidth", number);
1865 /* This defaults to 2 in order to match xterm. */
1866 x_default_parameter (f, parms, Qinternal_border_width, make_number (2),
1867 "internalBorderWidth", "BorderWidth", number);
1868 x_default_parameter (f, parms, Qvertical_scroll_bars, Qt,
1869 "verticalScrollBars", "ScrollBars", boolean);
1870
1871 /* Also do the stuff which must be set before the window exists. */
1872 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
1873 "foreground", "Foreground", string);
1874 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
1875 "background", "Background", string);
1876 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
1877 "pointerColor", "Foreground", string);
1878 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
1879 "cursorColor", "Foreground", string);
1880 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
1881 "borderColor", "BorderColor", string);
1882
1883 f->display.x->parent_desc = ROOT_WINDOW;
1884 window_prompting = x_figure_window_size (f, parms);
1885
1886 x_window (f);
1887 x_icon (f, parms);
1888 x_make_gc (f);
1889
1890 /* We need to do this after creating the X window, so that the
1891 icon-creation functions can say whose icon they're describing. */
1892 x_default_parameter (f, parms, Qicon_type, Qnil,
1893 "iconType", "IconType", symbol);
1894
1895 x_default_parameter (f, parms, Qauto_raise, Qnil,
1896 "autoRaise", "AutoRaiseLower", boolean);
1897 x_default_parameter (f, parms, Qauto_lower, Qnil,
1898 "autoLower", "AutoRaiseLower", boolean);
1899 x_default_parameter (f, parms, Qcursor_type, Qbox,
1900 "cursorType", "CursorType", symbol);
1901
1902 /* Dimensions, especially f->height, must be done via change_frame_size.
1903 Change will not be effected unless different from the current
1904 f->height. */
1905 width = f->width;
1906 height = f->height;
1907 f->height = f->width = 0;
1908 change_frame_size (f, height, width, 1, 0);
1909
1910 x_default_parameter (f, parms, Qmenu_bar_lines, make_number (0),
1911 "menuBarLines", "MenuBarLines", number);
1912
1913 BLOCK_INPUT;
1914 x_wm_set_size_hint (f, window_prompting);
1915 UNBLOCK_INPUT;
1916
1917 tem = x_get_arg (parms, Qunsplittable, 0, 0, boolean);
1918 f->no_split = minibuffer_only || EQ (tem, Qt);
1919
1920 /* Make the window appear on the frame and enable display,
1921 unless the caller says not to. */
1922 {
1923 Lisp_Object visibility = x_get_arg (parms, Qvisibility, 0, 0, symbol);
1924
1925 if (EQ (visibility, Qunbound))
1926 visibility = Qt;
1927
1928 if (EQ (visibility, Qicon))
1929 x_iconify_frame (f);
1930 else if (! NILP (visibility))
1931 x_make_frame_visible (f);
1932 else
1933 /* Must have been Qnil. */
1934 ;
1935 }
1936
1937 return frame;
1938 #else /* X10 */
1939 struct frame *f;
1940 Lisp_Object frame, tem;
1941 Lisp_Object name;
1942 int pixelwidth, pixelheight;
1943 Cursor cursor;
1944 int height, width;
1945 Window parent;
1946 Pixmap temp;
1947 int minibuffer_only = 0;
1948 Lisp_Object vscroll, hscroll;
1949
1950 if (x_current_display == 0)
1951 error ("X windows are not in use or not initialized");
1952
1953 name = Fassq (Qname, parms);
1954
1955 tem = x_get_arg (parms, Qminibuffer, 0, 0, symbol);
1956 if (EQ (tem, Qnone))
1957 f = make_frame_without_minibuffer (Qnil);
1958 else if (EQ (tem, Qonly))
1959 {
1960 f = make_minibuffer_frame ();
1961 minibuffer_only = 1;
1962 }
1963 else if (EQ (tem, Qnil) || EQ (tem, Qunbound))
1964 f = make_frame (1);
1965 else
1966 f = make_frame_without_minibuffer (tem);
1967
1968 parent = ROOT_WINDOW;
1969
1970 XSET (frame, Lisp_Frame, f);
1971 f->output_method = output_x_window;
1972 f->display.x = (struct x_display *) xmalloc (sizeof (struct x_display));
1973 bzero (f->display.x, sizeof (struct x_display));
1974
1975 /* Some temprorary default values for height and width. */
1976 width = 80;
1977 height = 40;
1978 f->display.x->left_pos = -1;
1979 f->display.x->top_pos = -1;
1980
1981 /* Give the frame a default name (which may be overridden with PARMS). */
1982
1983 strncpy (iconidentity, ICONTAG, MAXICID);
1984 if (gethostname (&iconidentity[sizeof (ICONTAG) - 1],
1985 (MAXICID - 1) - sizeof (ICONTAG)))
1986 iconidentity[sizeof (ICONTAG) - 2] = '\0';
1987 f->name = build_string (iconidentity);
1988
1989 /* Extract some window parameters from the supplied values.
1990 These are the parameters that affect window geometry. */
1991
1992 tem = x_get_arg (parms, Qfont, "BodyFont", 0, string);
1993 if (EQ (tem, Qunbound))
1994 tem = build_string ("9x15");
1995 x_set_font (f, tem, Qnil);
1996 x_default_parameter (f, parms, Qborder_color,
1997 build_string ("black"), "Border", 0, string);
1998 x_default_parameter (f, parms, Qbackground_color,
1999 build_string ("white"), "Background", 0, string);
2000 x_default_parameter (f, parms, Qforeground_color,
2001 build_string ("black"), "Foreground", 0, string);
2002 x_default_parameter (f, parms, Qmouse_color,
2003 build_string ("black"), "Mouse", 0, string);
2004 x_default_parameter (f, parms, Qcursor_color,
2005 build_string ("black"), "Cursor", 0, string);
2006 x_default_parameter (f, parms, Qborder_width,
2007 make_number (2), "BorderWidth", 0, number);
2008 x_default_parameter (f, parms, Qinternal_border_width,
2009 make_number (4), "InternalBorderWidth", 0, number);
2010 x_default_parameter (f, parms, Qauto_raise,
2011 Qnil, "AutoRaise", 0, boolean);
2012
2013 hscroll = EQ (x_get_arg (parms, Qhorizontal_scroll_bar, 0, 0, boolean), Qt);
2014 vscroll = EQ (x_get_arg (parms, Qvertical_scroll_bar, 0, 0, boolean), Qt);
2015
2016 if (f->display.x->internal_border_width < 0)
2017 f->display.x->internal_border_width = 0;
2018
2019 tem = x_get_arg (parms, Qwindow_id, 0, 0, number);
2020 if (!EQ (tem, Qunbound))
2021 {
2022 WINDOWINFO_TYPE wininfo;
2023 int nchildren;
2024 Window *children, root;
2025
2026 CHECK_NUMBER (tem, 0);
2027 FRAME_X_WINDOW (f) = (Window) XINT (tem);
2028
2029 BLOCK_INPUT;
2030 XGetWindowInfo (FRAME_X_WINDOW (f), &wininfo);
2031 XQueryTree (FRAME_X_WINDOW (f), &parent, &nchildren, &children);
2032 free (children);
2033 UNBLOCK_INPUT;
2034
2035 height = PIXEL_TO_CHAR_HEIGHT (f, wininfo.height);
2036 width = PIXEL_TO_CHAR_WIDTH (f, wininfo.width);
2037 f->display.x->left_pos = wininfo.x;
2038 f->display.x->top_pos = wininfo.y;
2039 FRAME_SET_VISIBILITY (f, wininfo.mapped != 0);
2040 f->display.x->border_width = wininfo.bdrwidth;
2041 f->display.x->parent_desc = parent;
2042 }
2043 else
2044 {
2045 tem = x_get_arg (parms, Qparent_id, 0, 0, number);
2046 if (!EQ (tem, Qunbound))
2047 {
2048 CHECK_NUMBER (tem, 0);
2049 parent = (Window) XINT (tem);
2050 }
2051 f->display.x->parent_desc = parent;
2052 tem = x_get_arg (parms, Qheight, 0, 0, number);
2053 if (EQ (tem, Qunbound))
2054 {
2055 tem = x_get_arg (parms, Qwidth, 0, 0, number);
2056 if (EQ (tem, Qunbound))
2057 {
2058 tem = x_get_arg (parms, Qtop, 0, 0, number);
2059 if (EQ (tem, Qunbound))
2060 tem = x_get_arg (parms, Qleft, 0, 0, number);
2061 }
2062 }
2063 /* Now TEM is Qunbound if no edge or size was specified.
2064 In that case, we must do rubber-banding. */
2065 if (EQ (tem, Qunbound))
2066 {
2067 tem = x_get_arg (parms, Qgeometry, 0, 0, number);
2068 x_rubber_band (f,
2069 &f->display.x->left_pos, &f->display.x->top_pos,
2070 &width, &height,
2071 (XTYPE (tem) == Lisp_String
2072 ? (char *) XSTRING (tem)->data : ""),
2073 XSTRING (f->name)->data,
2074 !NILP (hscroll), !NILP (vscroll));
2075 }
2076 else
2077 {
2078 /* Here if at least one edge or size was specified.
2079 Demand that they all were specified, and use them. */
2080 tem = x_get_arg (parms, Qheight, 0, 0, number);
2081 if (EQ (tem, Qunbound))
2082 error ("Height not specified");
2083 CHECK_NUMBER (tem, 0);
2084 height = XINT (tem);
2085
2086 tem = x_get_arg (parms, Qwidth, 0, 0, number);
2087 if (EQ (tem, Qunbound))
2088 error ("Width not specified");
2089 CHECK_NUMBER (tem, 0);
2090 width = XINT (tem);
2091
2092 tem = x_get_arg (parms, Qtop, 0, 0, number);
2093 if (EQ (tem, Qunbound))
2094 error ("Top position not specified");
2095 CHECK_NUMBER (tem, 0);
2096 f->display.x->left_pos = XINT (tem);
2097
2098 tem = x_get_arg (parms, Qleft, 0, 0, number);
2099 if (EQ (tem, Qunbound))
2100 error ("Left position not specified");
2101 CHECK_NUMBER (tem, 0);
2102 f->display.x->top_pos = XINT (tem);
2103 }
2104
2105 pixelwidth = CHAR_TO_PIXEL_WIDTH (f, width);
2106 pixelheight = CHAR_TO_PIXEL_HEIGHT (f, height);
2107
2108 BLOCK_INPUT;
2109 FRAME_X_WINDOW (f)
2110 = XCreateWindow (parent,
2111 f->display.x->left_pos, /* Absolute horizontal offset */
2112 f->display.x->top_pos, /* Absolute Vertical offset */
2113 pixelwidth, pixelheight,
2114 f->display.x->border_width,
2115 BLACK_PIX_DEFAULT, WHITE_PIX_DEFAULT);
2116 UNBLOCK_INPUT;
2117 if (FRAME_X_WINDOW (f) == 0)
2118 error ("Unable to create window.");
2119 }
2120
2121 /* Install the now determined height and width
2122 in the windows and in phys_lines and desired_lines. */
2123 change_frame_size (f, height, width, 1, 0);
2124 XSelectInput (FRAME_X_WINDOW (f), KeyPressed | ExposeWindow
2125 | ButtonPressed | ButtonReleased | ExposeRegion | ExposeCopy
2126 | EnterWindow | LeaveWindow | UnmapWindow );
2127 x_set_resize_hint (f);
2128
2129 /* Tell the server the window's default name. */
2130 XStoreName (XDISPLAY FRAME_X_WINDOW (f), XSTRING (f->name)->data);
2131
2132 /* Now override the defaults with all the rest of the specified
2133 parms. */
2134 tem = x_get_arg (parms, Qunsplittable, 0, 0, boolean);
2135 f->no_split = minibuffer_only || EQ (tem, Qt);
2136
2137 /* Do not create an icon window if the caller says not to.
2138 I'm not sure that this code is right; how does X10 handle icons? */
2139 x_text_icon (f, iconidentity);
2140 x_default_parameter (f, parms, Qicon_type, Qnil,
2141 "BitmapIcon", 0, symbol);
2142
2143 /* Tell the X server the previously set values of the
2144 background, border and mouse colors; also create the mouse cursor. */
2145 BLOCK_INPUT;
2146 temp = XMakeTile (f->display.x->background_pixel);
2147 XChangeBackground (FRAME_X_WINDOW (f), temp);
2148 XFreePixmap (temp);
2149 UNBLOCK_INPUT;
2150 x_set_border_pixel (f, f->display.x->border_pixel);
2151
2152 x_set_mouse_color (f, Qnil, Qnil);
2153
2154 /* Now override the defaults with all the rest of the specified parms. */
2155
2156 Fmodify_frame_parameters (frame, parms);
2157
2158 /* Make the window appear on the frame and enable display. */
2159 {
2160 Lisp_Object visibility = x_get_arg (parms, Qvisibility, 0, 0, symbol);
2161
2162 if (EQ (visibility, Qunbound))
2163 visibility = Qt;
2164
2165 if (! EQ (visibility, Qicon)
2166 && ! NILP (visibility))
2167 x_make_window_visible (f);
2168 }
2169
2170 SET_FRAME_GARBAGED (f);
2171
2172 return frame;
2173 #endif /* X10 */
2174 }
2175
2176 DEFUN ("focus-frame", Ffocus_frame, Sfocus_frame, 1, 1, 0,
2177 "Set the focus on FRAME.")
2178 (frame)
2179 Lisp_Object frame;
2180 {
2181 CHECK_LIVE_FRAME (frame, 0);
2182
2183 if (FRAME_X_P (XFRAME (frame)))
2184 {
2185 BLOCK_INPUT;
2186 x_focus_on_frame (XFRAME (frame));
2187 UNBLOCK_INPUT;
2188 return frame;
2189 }
2190
2191 return Qnil;
2192 }
2193
2194 DEFUN ("unfocus-frame", Funfocus_frame, Sunfocus_frame, 0, 0, 0,
2195 "If a frame has been focused, release it.")
2196 ()
2197 {
2198 if (x_focus_frame)
2199 {
2200 BLOCK_INPUT;
2201 x_unfocus_frame (x_focus_frame);
2202 UNBLOCK_INPUT;
2203 }
2204
2205 return Qnil;
2206 }
2207 \f
2208 #ifndef HAVE_X11
2209 /* Computes an X-window size and position either from geometry GEO
2210 or with the mouse.
2211
2212 F is a frame. It specifies an X window which is used to
2213 determine which display to compute for. Its font, borders
2214 and colors control how the rectangle will be displayed.
2215
2216 X and Y are where to store the positions chosen.
2217 WIDTH and HEIGHT are where to store the sizes chosen.
2218
2219 GEO is the geometry that may specify some of the info.
2220 STR is a prompt to display.
2221 HSCROLL and VSCROLL say whether we have horiz and vert scroll bars. */
2222
2223 int
2224 x_rubber_band (f, x, y, width, height, geo, str, hscroll, vscroll)
2225 struct frame *f;
2226 int *x, *y, *width, *height;
2227 char *geo;
2228 char *str;
2229 int hscroll, vscroll;
2230 {
2231 OpaqueFrame frame;
2232 Window tempwindow;
2233 WindowInfo wininfo;
2234 int border_color;
2235 int background_color;
2236 Lisp_Object tem;
2237 int mask;
2238
2239 BLOCK_INPUT;
2240
2241 background_color = f->display.x->background_pixel;
2242 border_color = f->display.x->border_pixel;
2243
2244 frame.bdrwidth = f->display.x->border_width;
2245 frame.border = XMakeTile (border_color);
2246 frame.background = XMakeTile (background_color);
2247 tempwindow = XCreateTerm (str, "emacs", geo, default_window, &frame, 10, 5,
2248 (2 * f->display.x->internal_border_width
2249 + (vscroll ? VSCROLL_WIDTH : 0)),
2250 (2 * f->display.x->internal_border_width
2251 + (hscroll ? HSCROLL_HEIGHT : 0)),
2252 width, height, f->display.x->font,
2253 FONT_WIDTH (f->display.x->font),
2254 FONT_HEIGHT (f->display.x->font));
2255 XFreePixmap (frame.border);
2256 XFreePixmap (frame.background);
2257
2258 if (tempwindow != 0)
2259 {
2260 XQueryWindow (tempwindow, &wininfo);
2261 XDestroyWindow (tempwindow);
2262 *x = wininfo.x;
2263 *y = wininfo.y;
2264 }
2265
2266 /* Coordinates we got are relative to the root window.
2267 Convert them to coordinates relative to desired parent window
2268 by scanning from there up to the root. */
2269 tempwindow = f->display.x->parent_desc;
2270 while (tempwindow != ROOT_WINDOW)
2271 {
2272 int nchildren;
2273 Window *children;
2274 XQueryWindow (tempwindow, &wininfo);
2275 *x -= wininfo.x;
2276 *y -= wininfo.y;
2277 XQueryTree (tempwindow, &tempwindow, &nchildren, &children);
2278 free (children);
2279 }
2280
2281 UNBLOCK_INPUT;
2282 return tempwindow != 0;
2283 }
2284 #endif /* not HAVE_X11 */
2285 \f
2286 DEFUN ("x-defined-color", Fx_defined_color, Sx_defined_color, 1, 1, 0,
2287 "Return t if the current X display supports the color named COLOR.")
2288 (color)
2289 Lisp_Object color;
2290 {
2291 Color foo;
2292
2293 CHECK_STRING (color, 0);
2294
2295 if (defined_color (XSTRING (color)->data, &foo))
2296 return Qt;
2297 else
2298 return Qnil;
2299 }
2300
2301 DEFUN ("x-display-color-p", Fx_display_color_p, Sx_display_color_p, 0, 0, 0,
2302 "Return t if the X screen currently in use supports color.")
2303 ()
2304 {
2305 if (x_screen_planes <= 2)
2306 return Qnil;
2307
2308 switch (screen_visual->class)
2309 {
2310 case StaticColor:
2311 case PseudoColor:
2312 case TrueColor:
2313 case DirectColor:
2314 return Qt;
2315
2316 default:
2317 return Qnil;
2318 }
2319 }
2320
2321 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
2322 0, 1, 0,
2323 "Returns the width in pixels of the display FRAME is on.")
2324 (frame)
2325 Lisp_Object frame;
2326 {
2327 Display *dpy = x_current_display;
2328 return make_number (DisplayWidth (dpy, DefaultScreen (dpy)));
2329 }
2330
2331 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
2332 Sx_display_pixel_height, 0, 1, 0,
2333 "Returns the height in pixels of the display FRAME is on.")
2334 (frame)
2335 Lisp_Object frame;
2336 {
2337 Display *dpy = x_current_display;
2338 return make_number (DisplayHeight (dpy, DefaultScreen (dpy)));
2339 }
2340
2341 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
2342 0, 1, 0,
2343 "Returns the number of bitplanes of the display FRAME is on.")
2344 (frame)
2345 Lisp_Object frame;
2346 {
2347 Display *dpy = x_current_display;
2348 return make_number (DisplayPlanes (dpy, DefaultScreen (dpy)));
2349 }
2350
2351 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
2352 0, 1, 0,
2353 "Returns the number of color cells of the display FRAME is on.")
2354 (frame)
2355 Lisp_Object frame;
2356 {
2357 Display *dpy = x_current_display;
2358 return make_number (DisplayCells (dpy, DefaultScreen (dpy)));
2359 }
2360
2361 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
2362 "Returns the vendor ID string of the X server FRAME is on.")
2363 (frame)
2364 Lisp_Object frame;
2365 {
2366 Display *dpy = x_current_display;
2367 char *vendor;
2368 vendor = ServerVendor (dpy);
2369 if (! vendor) vendor = "";
2370 return build_string (vendor);
2371 }
2372
2373 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
2374 "Returns the version numbers of the X server in use.\n\
2375 The value is a list of three integers: the major and minor\n\
2376 version numbers of the X Protocol in use, and the vendor-specific release\n\
2377 number. See also the variable `x-server-vendor'.")
2378 (frame)
2379 Lisp_Object frame;
2380 {
2381 Display *dpy = x_current_display;
2382 return Fcons (make_number (ProtocolVersion (dpy)),
2383 Fcons (make_number (ProtocolRevision (dpy)),
2384 Fcons (make_number (VendorRelease (dpy)), Qnil)));
2385 }
2386
2387 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
2388 "Returns the number of screens on the X server FRAME is on.")
2389 (frame)
2390 Lisp_Object frame;
2391 {
2392 return make_number (ScreenCount (x_current_display));
2393 }
2394
2395 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
2396 "Returns the height in millimeters of the X screen FRAME is on.")
2397 (frame)
2398 Lisp_Object frame;
2399 {
2400 return make_number (HeightMMOfScreen (x_screen));
2401 }
2402
2403 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
2404 "Returns the width in millimeters of the X screen FRAME is on.")
2405 (frame)
2406 Lisp_Object frame;
2407 {
2408 return make_number (WidthMMOfScreen (x_screen));
2409 }
2410
2411 DEFUN ("x-display-backing-store", Fx_display_backing_store,
2412 Sx_display_backing_store, 0, 1, 0,
2413 "Returns an indication of whether the X screen FRAME is on does backing store.\n\
2414 The value may be `always', `when-mapped', or `not-useful'.")
2415 (frame)
2416 Lisp_Object frame;
2417 {
2418 switch (DoesBackingStore (x_screen))
2419 {
2420 case Always:
2421 return intern ("always");
2422
2423 case WhenMapped:
2424 return intern ("when-mapped");
2425
2426 case NotUseful:
2427 return intern ("not-useful");
2428
2429 default:
2430 error ("Strange value for BackingStore parameter of screen");
2431 }
2432 }
2433
2434 DEFUN ("x-display-visual-class", Fx_display_visual_class,
2435 Sx_display_visual_class, 0, 1, 0,
2436 "Returns the visual class of the display `screen' is on.\n\
2437 The value is one of the symbols `static-gray', `gray-scale',\n\
2438 `static-color', `pseudo-color', `true-color', or `direct-color'.")
2439 (screen)
2440 Lisp_Object screen;
2441 {
2442 switch (screen_visual->class)
2443 {
2444 case StaticGray: return (intern ("static-gray"));
2445 case GrayScale: return (intern ("gray-scale"));
2446 case StaticColor: return (intern ("static-color"));
2447 case PseudoColor: return (intern ("pseudo-color"));
2448 case TrueColor: return (intern ("true-color"));
2449 case DirectColor: return (intern ("direct-color"));
2450 default:
2451 error ("Display has an unknown visual class");
2452 }
2453 }
2454
2455 DEFUN ("x-display-save-under", Fx_display_save_under,
2456 Sx_display_save_under, 0, 1, 0,
2457 "Returns t if the X screen FRAME is on supports the save-under feature.")
2458 (frame)
2459 Lisp_Object frame;
2460 {
2461 if (DoesSaveUnders (x_screen) == True)
2462 return Qt;
2463 else
2464 return Qnil;
2465 }
2466 \f
2467 x_pixel_width (f)
2468 register struct frame *f;
2469 {
2470 return PIXEL_WIDTH (f);
2471 }
2472
2473 x_pixel_height (f)
2474 register struct frame *f;
2475 {
2476 return PIXEL_HEIGHT (f);
2477 }
2478
2479 x_char_width (f)
2480 register struct frame *f;
2481 {
2482 return FONT_WIDTH (f->display.x->font);
2483 }
2484
2485 x_char_height (f)
2486 register struct frame *f;
2487 {
2488 return FONT_HEIGHT (f->display.x->font);
2489 }
2490 \f
2491 #if 0 /* These no longer seem like the right way to do things. */
2492
2493 /* Draw a rectangle on the frame with left top corner including
2494 the character specified by LEFT_CHAR and TOP_CHAR. The rectangle is
2495 CHARS by LINES wide and long and is the color of the cursor. */
2496
2497 void
2498 x_rectangle (f, gc, left_char, top_char, chars, lines)
2499 register struct frame *f;
2500 GC gc;
2501 register int top_char, left_char, chars, lines;
2502 {
2503 int width;
2504 int height;
2505 int left = (left_char * FONT_WIDTH (f->display.x->font)
2506 + f->display.x->internal_border_width);
2507 int top = (top_char * FONT_HEIGHT (f->display.x->font)
2508 + f->display.x->internal_border_width);
2509
2510 if (chars < 0)
2511 width = FONT_WIDTH (f->display.x->font) / 2;
2512 else
2513 width = FONT_WIDTH (f->display.x->font) * chars;
2514 if (lines < 0)
2515 height = FONT_HEIGHT (f->display.x->font) / 2;
2516 else
2517 height = FONT_HEIGHT (f->display.x->font) * lines;
2518
2519 XDrawRectangle (x_current_display, FRAME_X_WINDOW (f),
2520 gc, left, top, width, height);
2521 }
2522
2523 DEFUN ("x-draw-rectangle", Fx_draw_rectangle, Sx_draw_rectangle, 5, 5, 0,
2524 "Draw a rectangle on FRAME between coordinates specified by\n\
2525 numbers X0, Y0, X1, Y1 in the cursor pixel.")
2526 (frame, X0, Y0, X1, Y1)
2527 register Lisp_Object frame, X0, X1, Y0, Y1;
2528 {
2529 register int x0, y0, x1, y1, top, left, n_chars, n_lines;
2530
2531 CHECK_LIVE_FRAME (frame, 0);
2532 CHECK_NUMBER (X0, 0);
2533 CHECK_NUMBER (Y0, 1);
2534 CHECK_NUMBER (X1, 2);
2535 CHECK_NUMBER (Y1, 3);
2536
2537 x0 = XINT (X0);
2538 x1 = XINT (X1);
2539 y0 = XINT (Y0);
2540 y1 = XINT (Y1);
2541
2542 if (y1 > y0)
2543 {
2544 top = y0;
2545 n_lines = y1 - y0 + 1;
2546 }
2547 else
2548 {
2549 top = y1;
2550 n_lines = y0 - y1 + 1;
2551 }
2552
2553 if (x1 > x0)
2554 {
2555 left = x0;
2556 n_chars = x1 - x0 + 1;
2557 }
2558 else
2559 {
2560 left = x1;
2561 n_chars = x0 - x1 + 1;
2562 }
2563
2564 BLOCK_INPUT;
2565 x_rectangle (XFRAME (frame), XFRAME (frame)->display.x->cursor_gc,
2566 left, top, n_chars, n_lines);
2567 UNBLOCK_INPUT;
2568
2569 return Qt;
2570 }
2571
2572 DEFUN ("x-erase-rectangle", Fx_erase_rectangle, Sx_erase_rectangle, 5, 5, 0,
2573 "Draw a rectangle drawn on FRAME between coordinates\n\
2574 X0, Y0, X1, Y1 in the regular background-pixel.")
2575 (frame, X0, Y0, X1, Y1)
2576 register Lisp_Object frame, X0, Y0, X1, Y1;
2577 {
2578 register int x0, y0, x1, y1, top, left, n_chars, n_lines;
2579
2580 CHECK_FRAME (frame, 0);
2581 CHECK_NUMBER (X0, 0);
2582 CHECK_NUMBER (Y0, 1);
2583 CHECK_NUMBER (X1, 2);
2584 CHECK_NUMBER (Y1, 3);
2585
2586 x0 = XINT (X0);
2587 x1 = XINT (X1);
2588 y0 = XINT (Y0);
2589 y1 = XINT (Y1);
2590
2591 if (y1 > y0)
2592 {
2593 top = y0;
2594 n_lines = y1 - y0 + 1;
2595 }
2596 else
2597 {
2598 top = y1;
2599 n_lines = y0 - y1 + 1;
2600 }
2601
2602 if (x1 > x0)
2603 {
2604 left = x0;
2605 n_chars = x1 - x0 + 1;
2606 }
2607 else
2608 {
2609 left = x1;
2610 n_chars = x0 - x1 + 1;
2611 }
2612
2613 BLOCK_INPUT;
2614 x_rectangle (XFRAME (frame), XFRAME (frame)->display.x->reverse_gc,
2615 left, top, n_chars, n_lines);
2616 UNBLOCK_INPUT;
2617
2618 return Qt;
2619 }
2620
2621 /* Draw lines around the text region beginning at the character position
2622 TOP_X, TOP_Y and ending at BOTTOM_X and BOTTOM_Y. GC specifies the
2623 pixel and line characteristics. */
2624
2625 #define line_len(line) (FRAME_CURRENT_GLYPHS (f)->used[(line)])
2626
2627 static void
2628 outline_region (f, gc, top_x, top_y, bottom_x, bottom_y)
2629 register struct frame *f;
2630 GC gc;
2631 int top_x, top_y, bottom_x, bottom_y;
2632 {
2633 register int ibw = f->display.x->internal_border_width;
2634 register int font_w = FONT_WIDTH (f->display.x->font);
2635 register int font_h = FONT_HEIGHT (f->display.x->font);
2636 int y = top_y;
2637 int x = line_len (y);
2638 XPoint *pixel_points = (XPoint *)
2639 alloca (((bottom_y - top_y + 2) * 4) * sizeof (XPoint));
2640 register XPoint *this_point = pixel_points;
2641
2642 /* Do the horizontal top line/lines */
2643 if (top_x == 0)
2644 {
2645 this_point->x = ibw;
2646 this_point->y = ibw + (font_h * top_y);
2647 this_point++;
2648 if (x == 0)
2649 this_point->x = ibw + (font_w / 2); /* Half-size for newline chars. */
2650 else
2651 this_point->x = ibw + (font_w * x);
2652 this_point->y = (this_point - 1)->y;
2653 }
2654 else
2655 {
2656 this_point->x = ibw;
2657 this_point->y = ibw + (font_h * (top_y + 1));
2658 this_point++;
2659 this_point->x = ibw + (font_w * top_x);
2660 this_point->y = (this_point - 1)->y;
2661 this_point++;
2662 this_point->x = (this_point - 1)->x;
2663 this_point->y = ibw + (font_h * top_y);
2664 this_point++;
2665 this_point->x = ibw + (font_w * x);
2666 this_point->y = (this_point - 1)->y;
2667 }
2668
2669 /* Now do the right side. */
2670 while (y < bottom_y)
2671 { /* Right vertical edge */
2672 this_point++;
2673 this_point->x = (this_point - 1)->x;
2674 this_point->y = ibw + (font_h * (y + 1));
2675 this_point++;
2676
2677 y++; /* Horizontal connection to next line */
2678 x = line_len (y);
2679 if (x == 0)
2680 this_point->x = ibw + (font_w / 2);
2681 else
2682 this_point->x = ibw + (font_w * x);
2683
2684 this_point->y = (this_point - 1)->y;
2685 }
2686
2687 /* Now do the bottom and connect to the top left point. */
2688 this_point->x = ibw + (font_w * (bottom_x + 1));
2689
2690 this_point++;
2691 this_point->x = (this_point - 1)->x;
2692 this_point->y = ibw + (font_h * (bottom_y + 1));
2693 this_point++;
2694 this_point->x = ibw;
2695 this_point->y = (this_point - 1)->y;
2696 this_point++;
2697 this_point->x = pixel_points->x;
2698 this_point->y = pixel_points->y;
2699
2700 XDrawLines (x_current_display, FRAME_X_WINDOW (f),
2701 gc, pixel_points,
2702 (this_point - pixel_points + 1), CoordModeOrigin);
2703 }
2704
2705 DEFUN ("x-contour-region", Fx_contour_region, Sx_contour_region, 1, 1, 0,
2706 "Highlight the region between point and the character under the mouse\n\
2707 selected frame.")
2708 (event)
2709 register Lisp_Object event;
2710 {
2711 register int x0, y0, x1, y1;
2712 register struct frame *f = selected_frame;
2713 register int p1, p2;
2714
2715 CHECK_CONS (event, 0);
2716
2717 BLOCK_INPUT;
2718 x0 = XINT (Fcar (Fcar (event)));
2719 y0 = XINT (Fcar (Fcdr (Fcar (event))));
2720
2721 /* If the mouse is past the end of the line, don't that area. */
2722 /* ReWrite this... */
2723
2724 x1 = f->cursor_x;
2725 y1 = f->cursor_y;
2726
2727 if (y1 > y0) /* point below mouse */
2728 outline_region (f, f->display.x->cursor_gc,
2729 x0, y0, x1, y1);
2730 else if (y1 < y0) /* point above mouse */
2731 outline_region (f, f->display.x->cursor_gc,
2732 x1, y1, x0, y0);
2733 else /* same line: draw horizontal rectangle */
2734 {
2735 if (x1 > x0)
2736 x_rectangle (f, f->display.x->cursor_gc,
2737 x0, y0, (x1 - x0 + 1), 1);
2738 else if (x1 < x0)
2739 x_rectangle (f, f->display.x->cursor_gc,
2740 x1, y1, (x0 - x1 + 1), 1);
2741 }
2742
2743 XFlush (x_current_display);
2744 UNBLOCK_INPUT;
2745
2746 return Qnil;
2747 }
2748
2749 DEFUN ("x-uncontour-region", Fx_uncontour_region, Sx_uncontour_region, 1, 1, 0,
2750 "Erase any highlighting of the region between point and the character\n\
2751 at X, Y on the selected frame.")
2752 (event)
2753 register Lisp_Object event;
2754 {
2755 register int x0, y0, x1, y1;
2756 register struct frame *f = selected_frame;
2757
2758 BLOCK_INPUT;
2759 x0 = XINT (Fcar (Fcar (event)));
2760 y0 = XINT (Fcar (Fcdr (Fcar (event))));
2761 x1 = f->cursor_x;
2762 y1 = f->cursor_y;
2763
2764 if (y1 > y0) /* point below mouse */
2765 outline_region (f, f->display.x->reverse_gc,
2766 x0, y0, x1, y1);
2767 else if (y1 < y0) /* point above mouse */
2768 outline_region (f, f->display.x->reverse_gc,
2769 x1, y1, x0, y0);
2770 else /* same line: draw horizontal rectangle */
2771 {
2772 if (x1 > x0)
2773 x_rectangle (f, f->display.x->reverse_gc,
2774 x0, y0, (x1 - x0 + 1), 1);
2775 else if (x1 < x0)
2776 x_rectangle (f, f->display.x->reverse_gc,
2777 x1, y1, (x0 - x1 + 1), 1);
2778 }
2779 UNBLOCK_INPUT;
2780
2781 return Qnil;
2782 }
2783
2784 #if 0
2785 int contour_begin_x, contour_begin_y;
2786 int contour_end_x, contour_end_y;
2787 int contour_npoints;
2788
2789 /* Clip the top part of the contour lines down (and including) line Y_POS.
2790 If X_POS is in the middle (rather than at the end) of the line, drop
2791 down a line at that character. */
2792
2793 static void
2794 clip_contour_top (y_pos, x_pos)
2795 {
2796 register XPoint *begin = contour_lines[y_pos].top_left;
2797 register XPoint *end;
2798 register int npoints;
2799 register struct display_line *line = selected_frame->phys_lines[y_pos + 1];
2800
2801 if (x_pos >= line->len - 1) /* Draw one, straight horizontal line. */
2802 {
2803 end = contour_lines[y_pos].top_right;
2804 npoints = (end - begin + 1);
2805 XDrawLines (x_current_display, contour_window,
2806 contour_erase_gc, begin_erase, npoints, CoordModeOrigin);
2807
2808 bcopy (end, begin + 1, contour_last_point - end + 1);
2809 contour_last_point -= (npoints - 2);
2810 XDrawLines (x_current_display, contour_window,
2811 contour_erase_gc, begin, 2, CoordModeOrigin);
2812 XFlush (x_current_display);
2813
2814 /* Now, update contour_lines structure. */
2815 }
2816 /* ______. */
2817 else /* |________*/
2818 {
2819 register XPoint *p = begin + 1;
2820 end = contour_lines[y_pos].bottom_right;
2821 npoints = (end - begin + 1);
2822 XDrawLines (x_current_display, contour_window,
2823 contour_erase_gc, begin_erase, npoints, CoordModeOrigin);
2824
2825 p->y = begin->y;
2826 p->x = ibw + (font_w * (x_pos + 1));
2827 p++;
2828 p->y = begin->y + font_h;
2829 p->x = (p - 1)->x;
2830 bcopy (end, begin + 3, contour_last_point - end + 1);
2831 contour_last_point -= (npoints - 5);
2832 XDrawLines (x_current_display, contour_window,
2833 contour_erase_gc, begin, 4, CoordModeOrigin);
2834 XFlush (x_current_display);
2835
2836 /* Now, update contour_lines structure. */
2837 }
2838 }
2839
2840 /* Erase the top horzontal lines of the contour, and then extend
2841 the contour upwards. */
2842
2843 static void
2844 extend_contour_top (line)
2845 {
2846 }
2847
2848 static void
2849 clip_contour_bottom (x_pos, y_pos)
2850 int x_pos, y_pos;
2851 {
2852 }
2853
2854 static void
2855 extend_contour_bottom (x_pos, y_pos)
2856 {
2857 }
2858
2859 DEFUN ("x-select-region", Fx_select_region, Sx_select_region, 1, 1, "e",
2860 "")
2861 (event)
2862 Lisp_Object event;
2863 {
2864 register struct frame *f = selected_frame;
2865 register int point_x = f->cursor_x;
2866 register int point_y = f->cursor_y;
2867 register int mouse_below_point;
2868 register Lisp_Object obj;
2869 register int x_contour_x, x_contour_y;
2870
2871 x_contour_x = x_mouse_x;
2872 x_contour_y = x_mouse_y;
2873 if (x_contour_y > point_y || (x_contour_y == point_y
2874 && x_contour_x > point_x))
2875 {
2876 mouse_below_point = 1;
2877 outline_region (f, f->display.x->cursor_gc, point_x, point_y,
2878 x_contour_x, x_contour_y);
2879 }
2880 else
2881 {
2882 mouse_below_point = 0;
2883 outline_region (f, f->display.x->cursor_gc, x_contour_x, x_contour_y,
2884 point_x, point_y);
2885 }
2886
2887 while (1)
2888 {
2889 obj = read_char (-1, 0, 0, Qnil, 0);
2890 if (XTYPE (obj) != Lisp_Cons)
2891 break;
2892
2893 if (mouse_below_point)
2894 {
2895 if (x_mouse_y <= point_y) /* Flipped. */
2896 {
2897 mouse_below_point = 0;
2898
2899 outline_region (f, f->display.x->reverse_gc, point_x, point_y,
2900 x_contour_x, x_contour_y);
2901 outline_region (f, f->display.x->cursor_gc, x_mouse_x, x_mouse_y,
2902 point_x, point_y);
2903 }
2904 else if (x_mouse_y < x_contour_y) /* Bottom clipped. */
2905 {
2906 clip_contour_bottom (x_mouse_y);
2907 }
2908 else if (x_mouse_y > x_contour_y) /* Bottom extended. */
2909 {
2910 extend_bottom_contour (x_mouse_y);
2911 }
2912
2913 x_contour_x = x_mouse_x;
2914 x_contour_y = x_mouse_y;
2915 }
2916 else /* mouse above or same line as point */
2917 {
2918 if (x_mouse_y >= point_y) /* Flipped. */
2919 {
2920 mouse_below_point = 1;
2921
2922 outline_region (f, f->display.x->reverse_gc,
2923 x_contour_x, x_contour_y, point_x, point_y);
2924 outline_region (f, f->display.x->cursor_gc, point_x, point_y,
2925 x_mouse_x, x_mouse_y);
2926 }
2927 else if (x_mouse_y > x_contour_y) /* Top clipped. */
2928 {
2929 clip_contour_top (x_mouse_y);
2930 }
2931 else if (x_mouse_y < x_contour_y) /* Top extended. */
2932 {
2933 extend_contour_top (x_mouse_y);
2934 }
2935 }
2936 }
2937
2938 unread_command_event = obj;
2939 if (mouse_below_point)
2940 {
2941 contour_begin_x = point_x;
2942 contour_begin_y = point_y;
2943 contour_end_x = x_contour_x;
2944 contour_end_y = x_contour_y;
2945 }
2946 else
2947 {
2948 contour_begin_x = x_contour_x;
2949 contour_begin_y = x_contour_y;
2950 contour_end_x = point_x;
2951 contour_end_y = point_y;
2952 }
2953 }
2954 #endif
2955
2956 DEFUN ("x-horizontal-line", Fx_horizontal_line, Sx_horizontal_line, 1, 1, "e",
2957 "")
2958 (event)
2959 Lisp_Object event;
2960 {
2961 register Lisp_Object obj;
2962 struct frame *f = selected_frame;
2963 register struct window *w = XWINDOW (selected_window);
2964 register GC line_gc = f->display.x->cursor_gc;
2965 register GC erase_gc = f->display.x->reverse_gc;
2966 #if 0
2967 char dash_list[] = {6, 4, 6, 4};
2968 int dashes = 4;
2969 XGCValues gc_values;
2970 #endif
2971 register int previous_y;
2972 register int line = (x_mouse_y + 1) * FONT_HEIGHT (f->display.x->font)
2973 + f->display.x->internal_border_width;
2974 register int left = f->display.x->internal_border_width
2975 + (w->left
2976 * FONT_WIDTH (f->display.x->font));
2977 register int right = left + (w->width
2978 * FONT_WIDTH (f->display.x->font))
2979 - f->display.x->internal_border_width;
2980
2981 #if 0
2982 BLOCK_INPUT;
2983 gc_values.foreground = f->display.x->cursor_pixel;
2984 gc_values.background = f->display.x->background_pixel;
2985 gc_values.line_width = 1;
2986 gc_values.line_style = LineOnOffDash;
2987 gc_values.cap_style = CapRound;
2988 gc_values.join_style = JoinRound;
2989
2990 line_gc = XCreateGC (x_current_display, FRAME_X_WINDOW (f),
2991 GCLineStyle | GCJoinStyle | GCCapStyle
2992 | GCLineWidth | GCForeground | GCBackground,
2993 &gc_values);
2994 XSetDashes (x_current_display, line_gc, 0, dash_list, dashes);
2995 gc_values.foreground = f->display.x->background_pixel;
2996 gc_values.background = f->display.x->foreground_pixel;
2997 erase_gc = XCreateGC (x_current_display, FRAME_X_WINDOW (f),
2998 GCLineStyle | GCJoinStyle | GCCapStyle
2999 | GCLineWidth | GCForeground | GCBackground,
3000 &gc_values);
3001 XSetDashes (x_current_display, erase_gc, 0, dash_list, dashes);
3002 #endif
3003
3004 while (1)
3005 {
3006 BLOCK_INPUT;
3007 if (x_mouse_y >= XINT (w->top)
3008 && x_mouse_y < XINT (w->top) + XINT (w->height) - 1)
3009 {
3010 previous_y = x_mouse_y;
3011 line = (x_mouse_y + 1) * FONT_HEIGHT (f->display.x->font)
3012 + f->display.x->internal_border_width;
3013 XDrawLine (x_current_display, FRAME_X_WINDOW (f),
3014 line_gc, left, line, right, line);
3015 }
3016 XFlushQueue ();
3017 UNBLOCK_INPUT;
3018
3019 do
3020 {
3021 obj = read_char (-1, 0, 0, Qnil, 0);
3022 if ((XTYPE (obj) != Lisp_Cons)
3023 || (! EQ (Fcar (Fcdr (Fcdr (obj))),
3024 Qvertical_scroll_bar))
3025 || x_mouse_grabbed)
3026 {
3027 BLOCK_INPUT;
3028 XDrawLine (x_current_display, FRAME_X_WINDOW (f),
3029 erase_gc, left, line, right, line);
3030 UNBLOCK_INPUT;
3031 unread_command_event = obj;
3032 #if 0
3033 XFreeGC (x_current_display, line_gc);
3034 XFreeGC (x_current_display, erase_gc);
3035 #endif
3036 return Qnil;
3037 }
3038 }
3039 while (x_mouse_y == previous_y);
3040
3041 BLOCK_INPUT;
3042 XDrawLine (x_current_display, FRAME_X_WINDOW (f),
3043 erase_gc, left, line, right, line);
3044 UNBLOCK_INPUT;
3045 }
3046 }
3047 #endif
3048 \f
3049 /* Offset in buffer of character under the pointer, or 0. */
3050 int mouse_buffer_offset;
3051
3052 #if 0
3053 /* These keep track of the rectangle following the pointer. */
3054 int mouse_track_top, mouse_track_left, mouse_track_width;
3055
3056 DEFUN ("x-track-pointer", Fx_track_pointer, Sx_track_pointer, 0, 0, 0,
3057 "Track the pointer.")
3058 ()
3059 {
3060 static Cursor current_pointer_shape;
3061 FRAME_PTR f = x_mouse_frame;
3062
3063 BLOCK_INPUT;
3064 if (EQ (Vmouse_frame_part, Qtext_part)
3065 && (current_pointer_shape != f->display.x->nontext_cursor))
3066 {
3067 unsigned char c;
3068 struct buffer *buf;
3069
3070 current_pointer_shape = f->display.x->nontext_cursor;
3071 XDefineCursor (x_current_display,
3072 FRAME_X_WINDOW (f),
3073 current_pointer_shape);
3074
3075 buf = XBUFFER (XWINDOW (Vmouse_window)->buffer);
3076 c = *(BUF_CHAR_ADDRESS (buf, mouse_buffer_offset));
3077 }
3078 else if (EQ (Vmouse_frame_part, Qmodeline_part)
3079 && (current_pointer_shape != f->display.x->modeline_cursor))
3080 {
3081 current_pointer_shape = f->display.x->modeline_cursor;
3082 XDefineCursor (x_current_display,
3083 FRAME_X_WINDOW (f),
3084 current_pointer_shape);
3085 }
3086
3087 XFlushQueue ();
3088 UNBLOCK_INPUT;
3089 }
3090 #endif
3091
3092 #if 0
3093 DEFUN ("x-track-pointer", Fx_track_pointer, Sx_track_pointer, 1, 1, "e",
3094 "Draw rectangle around character under mouse pointer, if there is one.")
3095 (event)
3096 Lisp_Object event;
3097 {
3098 struct window *w = XWINDOW (Vmouse_window);
3099 struct frame *f = XFRAME (WINDOW_FRAME (w));
3100 struct buffer *b = XBUFFER (w->buffer);
3101 Lisp_Object obj;
3102
3103 if (! EQ (Vmouse_window, selected_window))
3104 return Qnil;
3105
3106 if (EQ (event, Qnil))
3107 {
3108 int x, y;
3109
3110 x_read_mouse_position (selected_frame, &x, &y);
3111 }
3112
3113 BLOCK_INPUT;
3114 mouse_track_width = 0;
3115 mouse_track_left = mouse_track_top = -1;
3116
3117 do
3118 {
3119 if ((x_mouse_x != mouse_track_left
3120 && (x_mouse_x < mouse_track_left
3121 || x_mouse_x > (mouse_track_left + mouse_track_width)))
3122 || x_mouse_y != mouse_track_top)
3123 {
3124 int hp = 0; /* Horizontal position */
3125 int len = FRAME_CURRENT_GLYPHS (f)->used[x_mouse_y];
3126 int p = FRAME_CURRENT_GLYPHS (f)->bufp[x_mouse_y];
3127 int tab_width = XINT (b->tab_width);
3128 int ctl_arrow_p = !NILP (b->ctl_arrow);
3129 unsigned char c;
3130 int mode_line_vpos = XFASTINT (w->height) + XFASTINT (w->top) - 1;
3131 int in_mode_line = 0;
3132
3133 if (! FRAME_CURRENT_GLYPHS (f)->enable[x_mouse_y])
3134 break;
3135
3136 /* Erase previous rectangle. */
3137 if (mouse_track_width)
3138 {
3139 x_rectangle (f, f->display.x->reverse_gc,
3140 mouse_track_left, mouse_track_top,
3141 mouse_track_width, 1);
3142
3143 if ((mouse_track_left == f->phys_cursor_x
3144 || mouse_track_left == f->phys_cursor_x - 1)
3145 && mouse_track_top == f->phys_cursor_y)
3146 {
3147 x_display_cursor (f, 1);
3148 }
3149 }
3150
3151 mouse_track_left = x_mouse_x;
3152 mouse_track_top = x_mouse_y;
3153 mouse_track_width = 0;
3154
3155 if (mouse_track_left > len) /* Past the end of line. */
3156 goto draw_or_not;
3157
3158 if (mouse_track_top == mode_line_vpos)
3159 {
3160 in_mode_line = 1;
3161 goto draw_or_not;
3162 }
3163
3164 if (tab_width <= 0 || tab_width > 20) tab_width = 8;
3165 do
3166 {
3167 c = FETCH_CHAR (p);
3168 if (len == f->width && hp == len - 1 && c != '\n')
3169 goto draw_or_not;
3170
3171 switch (c)
3172 {
3173 case '\t':
3174 mouse_track_width = tab_width - (hp % tab_width);
3175 p++;
3176 hp += mouse_track_width;
3177 if (hp > x_mouse_x)
3178 {
3179 mouse_track_left = hp - mouse_track_width;
3180 goto draw_or_not;
3181 }
3182 continue;
3183
3184 case '\n':
3185 mouse_track_width = -1;
3186 goto draw_or_not;
3187
3188 default:
3189 if (ctl_arrow_p && (c < 040 || c == 0177))
3190 {
3191 if (p > ZV)
3192 goto draw_or_not;
3193
3194 mouse_track_width = 2;
3195 p++;
3196 hp +=2;
3197 if (hp > x_mouse_x)
3198 {
3199 mouse_track_left = hp - mouse_track_width;
3200 goto draw_or_not;
3201 }
3202 }
3203 else
3204 {
3205 mouse_track_width = 1;
3206 p++;
3207 hp++;
3208 }
3209 continue;
3210 }
3211 }
3212 while (hp <= x_mouse_x);
3213
3214 draw_or_not:
3215 if (mouse_track_width) /* Over text; use text pointer shape. */
3216 {
3217 XDefineCursor (x_current_display,
3218 FRAME_X_WINDOW (f),
3219 f->display.x->text_cursor);
3220 x_rectangle (f, f->display.x->cursor_gc,
3221 mouse_track_left, mouse_track_top,
3222 mouse_track_width, 1);
3223 }
3224 else if (in_mode_line)
3225 XDefineCursor (x_current_display,
3226 FRAME_X_WINDOW (f),
3227 f->display.x->modeline_cursor);
3228 else
3229 XDefineCursor (x_current_display,
3230 FRAME_X_WINDOW (f),
3231 f->display.x->nontext_cursor);
3232 }
3233
3234 XFlush (x_current_display);
3235 UNBLOCK_INPUT;
3236
3237 obj = read_char (-1, 0, 0, Qnil, 0);
3238 BLOCK_INPUT;
3239 }
3240 while (XTYPE (obj) == Lisp_Cons /* Mouse event */
3241 && EQ (Fcar (Fcdr (Fcdr (obj))), Qnil) /* Not scroll bar */
3242 && EQ (Vmouse_depressed, Qnil) /* Only motion events */
3243 && EQ (Vmouse_window, selected_window) /* In this window */
3244 && x_mouse_frame);
3245
3246 unread_command_event = obj;
3247
3248 if (mouse_track_width)
3249 {
3250 x_rectangle (f, f->display.x->reverse_gc,
3251 mouse_track_left, mouse_track_top,
3252 mouse_track_width, 1);
3253 mouse_track_width = 0;
3254 if ((mouse_track_left == f->phys_cursor_x
3255 || mouse_track_left - 1 == f->phys_cursor_x)
3256 && mouse_track_top == f->phys_cursor_y)
3257 {
3258 x_display_cursor (f, 1);
3259 }
3260 }
3261 XDefineCursor (x_current_display,
3262 FRAME_X_WINDOW (f),
3263 f->display.x->nontext_cursor);
3264 XFlush (x_current_display);
3265 UNBLOCK_INPUT;
3266
3267 return Qnil;
3268 }
3269 #endif
3270 \f
3271 #if 0
3272 #include "glyphs.h"
3273
3274 /* Draw a pixmap specified by IMAGE_DATA of dimensions WIDTH and HEIGHT
3275 on the frame F at position X, Y. */
3276
3277 x_draw_pixmap (f, x, y, image_data, width, height)
3278 struct frame *f;
3279 int x, y, width, height;
3280 char *image_data;
3281 {
3282 Pixmap image;
3283
3284 image = XCreateBitmapFromData (x_current_display,
3285 FRAME_X_WINDOW (f), image_data,
3286 width, height);
3287 XCopyPlane (x_current_display, image, FRAME_X_WINDOW (f),
3288 f->display.x->normal_gc, 0, 0, width, height, x, y);
3289 }
3290 #endif
3291 \f
3292 #if 0
3293
3294 #ifdef HAVE_X11
3295 #define XMouseEvent XEvent
3296 #define WhichMouseButton xbutton.button
3297 #define MouseWindow xbutton.window
3298 #define MouseX xbutton.x
3299 #define MouseY xbutton.y
3300 #define MouseTime xbutton.time
3301 #define ButtonReleased ButtonRelease
3302 #define ButtonPressed ButtonPress
3303 #else
3304 #define XMouseEvent XButtonEvent
3305 #define WhichMouseButton detail
3306 #define MouseWindow window
3307 #define MouseX x
3308 #define MouseY y
3309 #define MouseTime time
3310 #endif /* X11 */
3311
3312 DEFUN ("x-mouse-events", Fx_mouse_events, Sx_mouse_events, 0, 0, 0,
3313 "Return number of pending mouse events from X window system.")
3314 ()
3315 {
3316 return make_number (queue_event_count (&x_mouse_queue));
3317 }
3318
3319 /* Encode the mouse button events in the form expected by the
3320 mouse code in Lisp. For X11, this means moving the masks around. */
3321
3322 static int
3323 encode_mouse_button (mouse_event)
3324 XMouseEvent mouse_event;
3325 {
3326 register int event_code;
3327 register char key_mask;
3328
3329 event_code = mouse_event.detail & 3;
3330 key_mask = (mouse_event.detail >> 8) & 0xf0;
3331 event_code |= key_mask >> 1;
3332 if (mouse_event.type == ButtonReleased) event_code |= 0x04;
3333 return event_code;
3334 }
3335
3336 DEFUN ("x-get-mouse-event", Fx_get_mouse_event, Sx_get_mouse_event,
3337 0, 1, 0,
3338 "Get next mouse event out of mouse event buffer.\n\
3339 Optional ARG non-nil means return nil immediately if no pending event;\n\
3340 otherwise, wait for an event. Returns a four-part list:\n\
3341 ((X-POS Y-POS) WINDOW FRAME-PART KEYSEQ TIMESTAMP).\n\
3342 Normally X-POS and Y-POS are the position of the click on the frame\n\
3343 (measured in characters and lines), and WINDOW is the window clicked in.\n\
3344 KEYSEQ is a string, the key sequence to be looked up in the mouse maps.\n\
3345 If FRAME-PART is non-nil, the event was on a scroll bar;\n\
3346 then Y-POS is really the total length of the scroll bar, while X-POS is\n\
3347 the relative position of the scroll bar's value within that total length,\n\
3348 and a third element OFFSET appears in that list: the height of the thumb-up\n\
3349 area at the top of the scroll bar.\n\
3350 FRAME-PART is one of the following symbols:\n\
3351 `vertical-scroll-bar', `vertical-thumbup', `vertical-thumbdown',\n\
3352 `horizontal-scroll-bar', `horizontal-thumbleft', `horizontal-thumbright'.\n\
3353 TIMESTAMP is the lower 23 bits of the X-server's timestamp for\n\
3354 the mouse event.")
3355 (arg)
3356 Lisp_Object arg;
3357 {
3358 XMouseEvent xrep;
3359 register int com_letter;
3360 register Lisp_Object tempx;
3361 register Lisp_Object tempy;
3362 Lisp_Object part, pos, timestamp;
3363 int prefix;
3364 struct frame *f;
3365
3366 int tem;
3367
3368 while (1)
3369 {
3370 BLOCK_INPUT;
3371 tem = dequeue_event (&xrep, &x_mouse_queue);
3372 UNBLOCK_INPUT;
3373
3374 if (tem)
3375 {
3376 switch (xrep.type)
3377 {
3378 case ButtonPressed:
3379 case ButtonReleased:
3380
3381 com_letter = encode_mouse_button (xrep);
3382 mouse_timestamp = xrep.MouseTime;
3383
3384 if ((f = x_window_to_frame (xrep.MouseWindow)) != 0)
3385 {
3386 Lisp_Object frame;
3387
3388 if (f->display.x->icon_desc == xrep.MouseWindow)
3389 {
3390 x_make_frame_visible (f);
3391 continue;
3392 }
3393
3394 XSET (tempx, Lisp_Int,
3395 min (f->width-1, max (0, (xrep.MouseX - f->display.x->internal_border_width)/FONT_WIDTH (f->display.x->font))));
3396 XSET (tempy, Lisp_Int,
3397 min (f->height-1, max (0, (xrep.MouseY - f->display.x->internal_border_width)/FONT_HEIGHT (f->display.x->font))));
3398 XSET (timestamp, Lisp_Int, (xrep.MouseTime & 0x7fffff));
3399 XSET (frame, Lisp_Frame, f);
3400
3401 pos = Fcons (tempx, Fcons (tempy, Qnil));
3402 Vmouse_window
3403 = Flocate_window_from_coordinates (frame, pos);
3404
3405 Vmouse_event
3406 = Fcons (pos,
3407 Fcons (Vmouse_window,
3408 Fcons (Qnil,
3409 Fcons (Fchar_to_string (make_number (com_letter)),
3410 Fcons (timestamp, Qnil)))));
3411 return Vmouse_event;
3412 }
3413 else if ((f = x_window_to_scroll_bar (xrep.MouseWindow, &part, &prefix)) != 0)
3414 {
3415 int pos, len;
3416 Lisp_Object keyseq;
3417 char *partname;
3418
3419 keyseq = concat2 (Fchar_to_string (make_number (prefix)),
3420 Fchar_to_string (make_number (com_letter)));
3421
3422 pos = xrep.MouseY - (f->display.x->v_scroll_bar_width - 2);
3423 XSET (tempx, Lisp_Int, pos);
3424 len = ((FONT_HEIGHT (f->display.x->font) * f->height)
3425 + f->display.x->internal_border_width
3426 - (2 * (f->display.x->v_scroll_bar_width - 2)));
3427 XSET (tempy, Lisp_Int, len);
3428 XSET (timestamp, Lisp_Int, (xrep.MouseTime & 0x7fffff));
3429 Vmouse_window = f->selected_window;
3430 Vmouse_event
3431 = Fcons (Fcons (tempx, Fcons (tempy,
3432 Fcons (make_number (f->display.x->v_scroll_bar_width - 2),
3433 Qnil))),
3434 Fcons (Vmouse_window,
3435 Fcons (intern (part),
3436 Fcons (keyseq, Fcons (timestamp,
3437 Qnil)))));
3438 return Vmouse_event;
3439 }
3440 else
3441 continue;
3442
3443 #ifdef HAVE_X11
3444 case MotionNotify:
3445
3446 com_letter = x11_encode_mouse_button (xrep);
3447 if ((f = x_window_to_frame (xrep.MouseWindow)) != 0)
3448 {
3449 Lisp_Object frame;
3450
3451 XSET (tempx, Lisp_Int,
3452 min (f->width-1,
3453 max (0, (xrep.MouseX - f->display.x->internal_border_width)
3454 / FONT_WIDTH (f->display.x->font))));
3455 XSET (tempy, Lisp_Int,
3456 min (f->height-1,
3457 max (0, (xrep.MouseY - f->display.x->internal_border_width)
3458 / FONT_HEIGHT (f->display.x->font))));
3459
3460 XSET (frame, Lisp_Frame, f);
3461 XSET (timestamp, Lisp_Int, (xrep.MouseTime & 0x7fffff));
3462
3463 pos = Fcons (tempx, Fcons (tempy, Qnil));
3464 Vmouse_window
3465 = Flocate_window_from_coordinates (frame, pos);
3466
3467 Vmouse_event
3468 = Fcons (pos,
3469 Fcons (Vmouse_window,
3470 Fcons (Qnil,
3471 Fcons (Fchar_to_string (make_number (com_letter)),
3472 Fcons (timestamp, Qnil)))));
3473 return Vmouse_event;
3474 }
3475
3476 break;
3477 #endif /* HAVE_X11 */
3478
3479 default:
3480 if (f = x_window_to_frame (xrep.MouseWindow))
3481 Vmouse_window = f->selected_window;
3482 else if (f = x_window_to_scroll_bar (xrep.MouseWindow, &part, &prefix))
3483 Vmouse_window = f->selected_window;
3484 return Vmouse_event = Qnil;
3485 }
3486 }
3487
3488 if (!NILP (arg))
3489 return Qnil;
3490
3491 /* Wait till we get another mouse event. */
3492 wait_reading_process_input (0, 0, 2, 0);
3493 }
3494 }
3495 #endif
3496
3497 \f
3498 #ifndef HAVE_X11
3499 DEFUN ("x-store-cut-buffer", Fx_store_cut_buffer, Sx_store_cut_buffer,
3500 1, 1, "sStore text in cut buffer: ",
3501 "Store contents of STRING into the cut buffer of the X window system.")
3502 (string)
3503 register Lisp_Object string;
3504 {
3505 int mask;
3506
3507 CHECK_STRING (string, 1);
3508 if (! FRAME_X_P (selected_frame))
3509 error ("Selected frame does not understand X protocol.");
3510
3511 BLOCK_INPUT;
3512 XStoreBytes ((char *) XSTRING (string)->data, XSTRING (string)->size);
3513 UNBLOCK_INPUT;
3514
3515 return Qnil;
3516 }
3517
3518 DEFUN ("x-get-cut-buffer", Fx_get_cut_buffer, Sx_get_cut_buffer, 0, 0, 0,
3519 "Return contents of cut buffer of the X window system, as a string.")
3520 ()
3521 {
3522 int len;
3523 register Lisp_Object string;
3524 int mask;
3525 register char *d;
3526
3527 BLOCK_INPUT;
3528 d = XFetchBytes (&len);
3529 string = make_string (d, len);
3530 XFree (d);
3531 UNBLOCK_INPUT;
3532 return string;
3533 }
3534 #endif /* X10 */
3535 \f
3536 #ifdef HAVE_X11
3537 DEFUN ("x-rebind-key", Fx_rebind_key, Sx_rebind_key, 3, 3, 0,
3538 "Rebind X keysym KEYSYM, with MODIFIERS, to generate NEWSTRING.\n\
3539 KEYSYM is a string which conforms to the X keysym definitions found\n\
3540 in X11/keysymdef.h, sans the initial XK_. MODIFIERS is nil or a\n\
3541 list of strings specifying modifier keys such as Control_L, which must\n\
3542 also be depressed for NEWSTRING to appear.")
3543 (x_keysym, modifiers, newstring)
3544 register Lisp_Object x_keysym;
3545 register Lisp_Object modifiers;
3546 register Lisp_Object newstring;
3547 {
3548 char *rawstring;
3549 register KeySym keysym;
3550 KeySym modifier_list[16];
3551
3552 CHECK_STRING (x_keysym, 1);
3553 CHECK_STRING (newstring, 3);
3554
3555 keysym = XStringToKeysym ((char *) XSTRING (x_keysym)->data);
3556 if (keysym == NoSymbol)
3557 error ("Keysym does not exist");
3558
3559 if (NILP (modifiers))
3560 XRebindKeysym (x_current_display, keysym, modifier_list, 0,
3561 XSTRING (newstring)->data, XSTRING (newstring)->size);
3562 else
3563 {
3564 register Lisp_Object rest, mod;
3565 register int i = 0;
3566
3567 for (rest = modifiers; !NILP (rest); rest = Fcdr (rest))
3568 {
3569 if (i == 16)
3570 error ("Can't have more than 16 modifiers");
3571
3572 mod = Fcar (rest);
3573 CHECK_STRING (mod, 3);
3574 modifier_list[i] = XStringToKeysym ((char *) XSTRING (mod)->data);
3575 if (modifier_list[i] == NoSymbol
3576 || !IsModifierKey (modifier_list[i]))
3577 error ("Element is not a modifier keysym");
3578 i++;
3579 }
3580
3581 XRebindKeysym (x_current_display, keysym, modifier_list, i,
3582 XSTRING (newstring)->data, XSTRING (newstring)->size);
3583 }
3584
3585 return Qnil;
3586 }
3587
3588 DEFUN ("x-rebind-keys", Fx_rebind_keys, Sx_rebind_keys, 2, 2, 0,
3589 "Rebind KEYCODE to list of strings STRINGS.\n\
3590 STRINGS should be a list of 16 elements, one for each shift combination.\n\
3591 nil as element means don't change.\n\
3592 See the documentation of `x-rebind-key' for more information.")
3593 (keycode, strings)
3594 register Lisp_Object keycode;
3595 register Lisp_Object strings;
3596 {
3597 register Lisp_Object item;
3598 register unsigned char *rawstring;
3599 KeySym rawkey, modifier[1];
3600 int strsize;
3601 register unsigned i;
3602
3603 CHECK_NUMBER (keycode, 1);
3604 CHECK_CONS (strings, 2);
3605 rawkey = (KeySym) ((unsigned) (XINT (keycode))) & 255;
3606 for (i = 0; i <= 15; strings = Fcdr (strings), i++)
3607 {
3608 item = Fcar (strings);
3609 if (!NILP (item))
3610 {
3611 CHECK_STRING (item, 2);
3612 strsize = XSTRING (item)->size;
3613 rawstring = (unsigned char *) xmalloc (strsize);
3614 bcopy (XSTRING (item)->data, rawstring, strsize);
3615 modifier[1] = 1 << i;
3616 XRebindKeysym (x_current_display, rawkey, modifier, 1,
3617 rawstring, strsize);
3618 }
3619 }
3620 return Qnil;
3621 }
3622 #else
3623 DEFUN ("x-rebind-key", Fx_rebind_key, Sx_rebind_key, 3, 3, 0,
3624 "Rebind KEYCODE, with shift bits SHIFT-MASK, to new string NEWSTRING.\n\
3625 KEYCODE and SHIFT-MASK should be numbers representing the X keyboard code\n\
3626 and shift mask respectively. NEWSTRING is an arbitrary string of keystrokes.\n\
3627 If SHIFT-MASK is nil, then KEYCODE's key will be bound to NEWSTRING for\n\
3628 all shift combinations.\n\
3629 Shift Lock 1 Shift 2\n\
3630 Meta 4 Control 8\n\
3631 \n\
3632 For values of KEYCODE, see /usr/lib/Xkeymap.txt (remember that the codes\n\
3633 in that file are in octal!)\n\
3634 \n\
3635 NOTE: due to an X bug, this function will not take effect unless one has\n\
3636 a `~/.Xkeymap' file. (See the documentation for the `keycomp' program.)\n\
3637 This problem will be fixed in X version 11.")
3638
3639 (keycode, shift_mask, newstring)
3640 register Lisp_Object keycode;
3641 register Lisp_Object shift_mask;
3642 register Lisp_Object newstring;
3643 {
3644 char *rawstring;
3645 int keysym, rawshift;
3646 int i, strsize;
3647
3648 CHECK_NUMBER (keycode, 1);
3649 if (!NILP (shift_mask))
3650 CHECK_NUMBER (shift_mask, 2);
3651 CHECK_STRING (newstring, 3);
3652 strsize = XSTRING (newstring)->size;
3653 rawstring = (char *) xmalloc (strsize);
3654 bcopy (XSTRING (newstring)->data, rawstring, strsize);
3655
3656 keysym = ((unsigned) (XINT (keycode))) & 255;
3657
3658 if (NILP (shift_mask))
3659 {
3660 for (i = 0; i <= 15; i++)
3661 XRebindCode (keysym, i<<11, rawstring, strsize);
3662 }
3663 else
3664 {
3665 rawshift = (((unsigned) (XINT (shift_mask))) & 15) << 11;
3666 XRebindCode (keysym, rawshift, rawstring, strsize);
3667 }
3668 return Qnil;
3669 }
3670
3671 DEFUN ("x-rebind-keys", Fx_rebind_keys, Sx_rebind_keys, 2, 2, 0,
3672 "Rebind KEYCODE to list of strings STRINGS.\n\
3673 STRINGS should be a list of 16 elements, one for each shift combination.\n\
3674 nil as element means don't change.\n\
3675 See the documentation of `x-rebind-key' for more information.")
3676 (keycode, strings)
3677 register Lisp_Object keycode;
3678 register Lisp_Object strings;
3679 {
3680 register Lisp_Object item;
3681 register char *rawstring;
3682 KeySym rawkey, modifier[1];
3683 int strsize;
3684 register unsigned i;
3685
3686 CHECK_NUMBER (keycode, 1);
3687 CHECK_CONS (strings, 2);
3688 rawkey = (KeySym) ((unsigned) (XINT (keycode))) & 255;
3689 for (i = 0; i <= 15; strings = Fcdr (strings), i++)
3690 {
3691 item = Fcar (strings);
3692 if (!NILP (item))
3693 {
3694 CHECK_STRING (item, 2);
3695 strsize = XSTRING (item)->size;
3696 rawstring = (char *) xmalloc (strsize);
3697 bcopy (XSTRING (item)->data, rawstring, strsize);
3698 XRebindCode (rawkey, i << 11, rawstring, strsize);
3699 }
3700 }
3701 return Qnil;
3702 }
3703 #endif /* not HAVE_X11 */
3704 \f
3705 #ifdef HAVE_X11
3706 Visual *
3707 select_visual (screen, depth)
3708 Screen *screen;
3709 unsigned int *depth;
3710 {
3711 Visual *v;
3712 XVisualInfo *vinfo, vinfo_template;
3713 int n_visuals;
3714
3715 v = DefaultVisualOfScreen (screen);
3716
3717 #ifdef HAVE_X11R4
3718 vinfo_template.visualid = XVisualIDFromVisual (v);
3719 #else
3720 vinfo_template.visualid = x->visualid;
3721 #endif
3722
3723 vinfo = XGetVisualInfo (x_current_display, VisualIDMask, &vinfo_template,
3724 &n_visuals);
3725 if (n_visuals != 1)
3726 fatal ("Can't get proper X visual info");
3727
3728 if ((1 << vinfo->depth) == vinfo->colormap_size)
3729 *depth = vinfo->depth;
3730 else
3731 {
3732 int i = 0;
3733 int n = vinfo->colormap_size - 1;
3734 while (n)
3735 {
3736 n = n >> 1;
3737 i++;
3738 }
3739 *depth = i;
3740 }
3741
3742 XFree ((char *) vinfo);
3743 return v;
3744 }
3745 #endif /* HAVE_X11 */
3746
3747 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
3748 1, 2, 0, "Open a connection to an X server.\n\
3749 DISPLAY is the name of the display to connect to. Optional second\n\
3750 arg XRM_STRING is a string of resources in xrdb format.")
3751 (display, xrm_string)
3752 Lisp_Object display, xrm_string;
3753 {
3754 unsigned int n_planes;
3755 unsigned char *xrm_option;
3756
3757 CHECK_STRING (display, 0);
3758 if (x_current_display != 0)
3759 error ("X server connection is already initialized");
3760
3761 /* This is what opens the connection and sets x_current_display.
3762 This also initializes many symbols, such as those used for input. */
3763 x_term_init (XSTRING (display)->data);
3764
3765 #ifdef HAVE_X11
3766 XFASTINT (Vwindow_system_version) = 11;
3767
3768 if (!EQ (xrm_string, Qnil))
3769 {
3770 CHECK_STRING (xrm_string, 1);
3771 xrm_option = (unsigned char *) XSTRING (xrm_string);
3772 }
3773 else
3774 xrm_option = (unsigned char *) 0;
3775 xrdb = x_load_resources (x_current_display, xrm_option, EMACS_CLASS);
3776 #ifdef HAVE_X11R5
3777 XrmSetDatabase (x_current_display, xrdb);
3778 #else
3779 x_current_display->db = xrdb;
3780 #endif
3781
3782 x_screen = DefaultScreenOfDisplay (x_current_display);
3783
3784 screen_visual = select_visual (x_screen, &n_planes);
3785 x_screen_planes = n_planes;
3786 x_screen_height = HeightOfScreen (x_screen);
3787 x_screen_width = WidthOfScreen (x_screen);
3788
3789 /* X Atoms used by emacs. */
3790 Xatoms_of_xselect ();
3791 BLOCK_INPUT;
3792 Xatom_wm_protocols = XInternAtom (x_current_display, "WM_PROTOCOLS",
3793 False);
3794 Xatom_wm_take_focus = XInternAtom (x_current_display, "WM_TAKE_FOCUS",
3795 False);
3796 Xatom_wm_save_yourself = XInternAtom (x_current_display, "WM_SAVE_YOURSELF",
3797 False);
3798 Xatom_wm_delete_window = XInternAtom (x_current_display, "WM_DELETE_WINDOW",
3799 False);
3800 Xatom_wm_change_state = XInternAtom (x_current_display, "WM_CHANGE_STATE",
3801 False);
3802 Xatom_wm_configure_denied = XInternAtom (x_current_display,
3803 "WM_CONFIGURE_DENIED", False);
3804 Xatom_wm_window_moved = XInternAtom (x_current_display, "WM_MOVED",
3805 False);
3806 UNBLOCK_INPUT;
3807 #else /* not HAVE_X11 */
3808 XFASTINT (Vwindow_system_version) = 10;
3809 #endif /* not HAVE_X11 */
3810 return Qnil;
3811 }
3812
3813 DEFUN ("x-close-current-connection", Fx_close_current_connection,
3814 Sx_close_current_connection,
3815 0, 0, 0, "Close the connection to the current X server.")
3816 ()
3817 {
3818 #ifdef HAVE_X11
3819 /* This is ONLY used when killing emacs; For switching displays
3820 we'll have to take care of setting CloseDownMode elsewhere. */
3821
3822 if (x_current_display)
3823 {
3824 BLOCK_INPUT;
3825 XSetCloseDownMode (x_current_display, DestroyAll);
3826 XCloseDisplay (x_current_display);
3827 }
3828 else
3829 fatal ("No current X display connection to close\n");
3830 #endif
3831 return Qnil;
3832 }
3833
3834 DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize,
3835 1, 1, 0, "If ON is non-nil, report X errors as soon as the erring request is made.\n\
3836 If ON is nil, allow buffering of requests.\n\
3837 Turning on synchronization prohibits the Xlib routines from buffering\n\
3838 requests and seriously degrades performance, but makes debugging much\n\
3839 easier.")
3840 (on)
3841 Lisp_Object on;
3842 {
3843 XSynchronize (x_current_display, !EQ (on, Qnil));
3844
3845 return Qnil;
3846 }
3847
3848 \f
3849 syms_of_xfns ()
3850 {
3851 /* This is zero if not using X windows. */
3852 x_current_display = 0;
3853
3854 /* The section below is built by the lisp expression at the top of the file,
3855 just above where these variables are declared. */
3856 /*&&& init symbols here &&&*/
3857 Qauto_raise = intern ("auto-raise");
3858 staticpro (&Qauto_raise);
3859 Qauto_lower = intern ("auto-lower");
3860 staticpro (&Qauto_lower);
3861 Qbackground_color = intern ("background-color");
3862 staticpro (&Qbackground_color);
3863 Qbar = intern ("bar");
3864 staticpro (&Qbar);
3865 Qborder_color = intern ("border-color");
3866 staticpro (&Qborder_color);
3867 Qborder_width = intern ("border-width");
3868 staticpro (&Qborder_width);
3869 Qbox = intern ("box");
3870 staticpro (&Qbox);
3871 Qcursor_color = intern ("cursor-color");
3872 staticpro (&Qcursor_color);
3873 Qcursor_type = intern ("cursor-type");
3874 staticpro (&Qcursor_type);
3875 Qfont = intern ("font");
3876 staticpro (&Qfont);
3877 Qforeground_color = intern ("foreground-color");
3878 staticpro (&Qforeground_color);
3879 Qgeometry = intern ("geometry");
3880 staticpro (&Qgeometry);
3881 Qicon = intern ("icon");
3882 staticpro (&Qicon);
3883 Qicon_left = intern ("icon-left");
3884 staticpro (&Qicon_left);
3885 Qicon_top = intern ("icon-top");
3886 staticpro (&Qicon_top);
3887 Qicon_type = intern ("icon-type");
3888 staticpro (&Qicon_type);
3889 Qinternal_border_width = intern ("internal-border-width");
3890 staticpro (&Qinternal_border_width);
3891 Qleft = intern ("left");
3892 staticpro (&Qleft);
3893 Qmouse_color = intern ("mouse-color");
3894 staticpro (&Qmouse_color);
3895 Qnone = intern ("none");
3896 staticpro (&Qnone);
3897 Qparent_id = intern ("parent-id");
3898 staticpro (&Qparent_id);
3899 Qtop = intern ("top");
3900 staticpro (&Qtop);
3901 Qundefined_color = intern ("undefined-color");
3902 staticpro (&Qundefined_color);
3903 Qvertical_scroll_bars = intern ("vertical-scroll-bars");
3904 staticpro (&Qvertical_scroll_bars);
3905 Qvisibility = intern ("visibility");
3906 staticpro (&Qvisibility);
3907 Qwindow_id = intern ("window-id");
3908 staticpro (&Qwindow_id);
3909 Qx_frame_parameter = intern ("x-frame-parameter");
3910 staticpro (&Qx_frame_parameter);
3911 /* This is the end of symbol initialization. */
3912
3913 Fput (Qundefined_color, Qerror_conditions,
3914 Fcons (Qundefined_color, Fcons (Qerror, Qnil)));
3915 Fput (Qundefined_color, Qerror_message,
3916 build_string ("Undefined color"));
3917
3918 init_x_parm_symbols ();
3919
3920 DEFVAR_INT ("mouse-buffer-offset", &mouse_buffer_offset,
3921 "The buffer offset of the character under the pointer.");
3922 mouse_buffer_offset = 0;
3923
3924 DEFVAR_INT ("x-pointer-shape", &Vx_pointer_shape,
3925 "The shape of the pointer when over text.");
3926 Vx_pointer_shape = Qnil;
3927
3928 DEFVAR_INT ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape,
3929 "The shape of the pointer when not over text.");
3930 Vx_nontext_pointer_shape = Qnil;
3931
3932 DEFVAR_INT ("x-mode-pointer-shape", &Vx_mode_pointer_shape,
3933 "The shape of the pointer when over the mode line.");
3934 Vx_mode_pointer_shape = Qnil;
3935
3936 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel,
3937 "A string indicating the foreground color of the cursor box.");
3938 Vx_cursor_fore_pixel = Qnil;
3939
3940 DEFVAR_LISP ("mouse-grabbed", &Vmouse_depressed,
3941 "Non-nil if a mouse button is currently depressed.");
3942 Vmouse_depressed = Qnil;
3943
3944 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
3945 "t if no X window manager is in use.");
3946
3947 #ifdef HAVE_X11
3948 defsubr (&Sx_get_resource);
3949 #if 0
3950 defsubr (&Sx_draw_rectangle);
3951 defsubr (&Sx_erase_rectangle);
3952 defsubr (&Sx_contour_region);
3953 defsubr (&Sx_uncontour_region);
3954 #endif
3955 defsubr (&Sx_display_color_p);
3956 defsubr (&Sx_defined_color);
3957 defsubr (&Sx_server_vendor);
3958 defsubr (&Sx_server_version);
3959 defsubr (&Sx_display_pixel_width);
3960 defsubr (&Sx_display_pixel_height);
3961 defsubr (&Sx_display_mm_width);
3962 defsubr (&Sx_display_mm_height);
3963 defsubr (&Sx_display_screens);
3964 defsubr (&Sx_display_planes);
3965 defsubr (&Sx_display_color_cells);
3966 defsubr (&Sx_display_visual_class);
3967 defsubr (&Sx_display_backing_store);
3968 defsubr (&Sx_display_save_under);
3969 #if 0
3970 defsubr (&Sx_track_pointer);
3971 defsubr (&Sx_grab_pointer);
3972 defsubr (&Sx_ungrab_pointer);
3973 #endif
3974 #else
3975 defsubr (&Sx_get_default);
3976 defsubr (&Sx_store_cut_buffer);
3977 defsubr (&Sx_get_cut_buffer);
3978 defsubr (&Sx_set_face);
3979 #endif
3980 defsubr (&Sx_geometry);
3981 defsubr (&Sx_create_frame);
3982 defsubr (&Sfocus_frame);
3983 defsubr (&Sunfocus_frame);
3984 #if 0
3985 defsubr (&Sx_horizontal_line);
3986 #endif
3987 defsubr (&Sx_rebind_key);
3988 defsubr (&Sx_rebind_keys);
3989 defsubr (&Sx_open_connection);
3990 defsubr (&Sx_close_current_connection);
3991 defsubr (&Sx_synchronize);
3992
3993 /* This was used in the old event interface which used a separate
3994 event queue.*/
3995 #if 0
3996 defsubr (&Sx_mouse_events);
3997 defsubr (&Sx_get_mouse_event);
3998 #endif
3999 }
4000
4001 #endif /* HAVE_X_WINDOWS */