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