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