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