1 /* -*-C-*-
2 
3 Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
4     1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
5     2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Massachusetts
6     Institute of Technology
7 
8 This file is part of MIT/GNU Scheme.
9 
10 MIT/GNU Scheme is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or (at
13 your option) any later version.
14 
15 MIT/GNU Scheme is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License
21 along with MIT/GNU Scheme; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
23 USA.
24 
25 */
26 
27 /* Common X11 support. */
28 
29 #include "scheme.h"
30 #include "prims.h"
31 #include "ux.h"
32 #include "osio.h"
33 #include "x11.h"
34 #include <X11/Xmd.h>
35 #include <X11/keysym.h>
36 
37 extern void block_signals (void);
38 extern void unblock_signals (void);
39 
40 #ifndef X_DEFAULT_FONT
41 #  define X_DEFAULT_FONT "fixed"
42 #endif
43 
44 int x_debug = 0;
45 static int initialization_done = 0;
46 static const char * x_default_font = 0;
47 
48 #define INITIALIZE_ONCE()						\
49 {									\
50   if (!initialization_done)						\
51     initialize_once ();							\
52 }
53 
54 static void initialize_once (void);
55 
56 static void move_window (struct xwindow *, int, int);
57 static void check_expected_move (struct xwindow *);
58 
59 void *
x_malloc(unsigned int size)60 x_malloc (unsigned int size)
61 {
62   void * result = (UX_malloc (size));
63   if (result == 0)
64     error_external_return ();
65   return (result);
66 }
67 
68 void *
x_realloc(void * ptr,unsigned int size)69 x_realloc (void * ptr, unsigned int size)
70 {
71   void * result = (UX_realloc (ptr, size));
72   if (result == 0)
73     error_external_return ();
74   return (result);
75 }
76 
77 /* Allocation Tables */
78 
79 struct allocation_table
80 {
81   void ** items;
82   int length;
83 };
84 
85 static struct allocation_table x_display_table;
86 static struct allocation_table x_window_table;
87 static struct allocation_table x_image_table;
88 static struct allocation_table x_visual_table;
89 static struct allocation_table x_colormap_table;
90 
91 static void
allocation_table_initialize(struct allocation_table * table)92 allocation_table_initialize (struct allocation_table * table)
93 {
94   (table->length) = 0;
95 }
96 
97 static unsigned int
allocate_table_index(struct allocation_table * table,void * item)98 allocate_table_index (struct allocation_table * table, void * item)
99 {
100   unsigned int length = (table->length);
101   unsigned int new_length;
102   void ** items = (table->items);
103   void ** new_items;
104   void ** scan;
105   void ** end;
106   if (length == 0)
107     {
108       new_length = 4;
109       new_items = (x_malloc ((sizeof (void *)) * new_length));
110     }
111   else
112     {
113       scan = items;
114       end = (scan + length);
115       while (scan < end)
116 	if ((*scan++) == 0)
117 	  {
118 	    (*--scan) = item;
119 	    return (scan - items);
120 	  }
121       new_length = (length * 2);
122       new_items = (x_realloc (items, ((sizeof (void *)) * new_length)));
123     }
124   scan = (new_items + length);
125   end = (new_items + new_length);
126   (*scan++) = item;
127   while (scan < end)
128     (*scan++) = 0;
129   (table->items) = new_items;
130   (table->length) = new_length;
131   return (length);
132 }
133 
134 static void *
allocation_item_arg(unsigned int arg,struct allocation_table * table)135 allocation_item_arg (unsigned int arg, struct allocation_table * table)
136 {
137   unsigned int index = (arg_index_integer (arg, (table->length)));
138   void * item = ((table->items) [index]);
139   if (item == 0)
140     error_bad_range_arg (arg);
141   return (item);
142 }
143 
144 struct xdisplay *
x_display_arg(unsigned int arg)145 x_display_arg (unsigned int arg)
146 {
147   INITIALIZE_ONCE ();
148   return (allocation_item_arg (arg, (&x_display_table)));
149 }
150 
151 struct xwindow *
x_window_arg(unsigned int arg)152 x_window_arg (unsigned int arg)
153 {
154   INITIALIZE_ONCE ();
155   return (allocation_item_arg (arg, (&x_window_table)));
156 }
157 
158 static struct xwindow *
x_window_to_xw(Display * display,Window window)159 x_window_to_xw (Display * display, Window window)
160 {
161   struct xwindow ** scan = ((struct xwindow **) (x_window_table.items));
162   struct xwindow ** end = (scan + (x_window_table.length));
163   while (scan < end)
164     {
165       struct xwindow * xw = (*scan++);
166       if ((xw != 0)
167 	  && ((XW_DISPLAY (xw)) == display)
168 	  && ((XW_WINDOW (xw)) == window))
169 	return (xw);
170     }
171   return (0);
172 }
173 
174 struct ximage *
x_image_arg(unsigned int arg)175 x_image_arg (unsigned int arg)
176 {
177   INITIALIZE_ONCE ();
178   return (allocation_item_arg (arg, (&x_image_table)));
179 }
180 
181 unsigned int
allocate_x_image(XImage * image)182 allocate_x_image (XImage * image)
183 {
184   struct ximage * xi = (x_malloc (sizeof (struct ximage)));
185   unsigned int index = (allocate_table_index ((&x_image_table), xi));
186   (XI_ALLOCATION_INDEX (xi)) = index;
187   (XI_IMAGE (xi)) = image;
188   return (index);
189 }
190 
191 void
deallocate_x_image(struct ximage * xi)192 deallocate_x_image (struct ximage * xi)
193 {
194   ((x_image_table.items) [XI_ALLOCATION_INDEX (xi)]) = 0;
195   free (xi);
196 }
197 
198 struct xvisual *
x_visual_arg(unsigned int arg)199 x_visual_arg (unsigned int arg)
200 {
201   INITIALIZE_ONCE ();
202   return (allocation_item_arg (arg, (&x_visual_table)));
203 }
204 
205 unsigned int
allocate_x_visual(Visual * visual)206 allocate_x_visual (Visual * visual)
207 {
208   struct xvisual * xv = (x_malloc (sizeof (struct xvisual)));
209   unsigned int index = (allocate_table_index ((&x_visual_table), xv));
210   (XV_ALLOCATION_INDEX (xv)) = index;
211   (XV_VISUAL (xv)) = visual;
212   return (index);
213 }
214 
215 void
deallocate_x_visual(struct xvisual * xv)216 deallocate_x_visual (struct xvisual * xv)
217 {
218   ((x_visual_table.items) [XV_ALLOCATION_INDEX (xv)]) = 0;
219   free (xv);
220 }
221 
222 struct xcolormap *
x_colormap_arg(unsigned int arg)223 x_colormap_arg (unsigned int arg)
224 {
225   INITIALIZE_ONCE ();
226   return (allocation_item_arg (arg, (&x_colormap_table)));
227 }
228 
229 unsigned int
allocate_x_colormap(Colormap colormap,struct xdisplay * xd)230 allocate_x_colormap (Colormap colormap, struct xdisplay * xd)
231 {
232   struct xcolormap * xcm = (x_malloc (sizeof (struct xcolormap)));
233   unsigned int index = (allocate_table_index ((&x_colormap_table), xcm));
234   (XCM_ALLOCATION_INDEX (xcm)) = index;
235   (XCM_COLORMAP (xcm)) = colormap;
236   (XCM_XD (xcm)) = xd;
237   return (index);
238 }
239 
240 void
deallocate_x_colormap(struct xcolormap * xcm)241 deallocate_x_colormap (struct xcolormap * xcm)
242 {
243   ((x_colormap_table.items) [XCM_ALLOCATION_INDEX (xcm)]) = 0;
244   free (xcm);
245 }
246 
247 /* Error Handlers */
248 
249 static int
x_io_error_handler(Display * display)250 x_io_error_handler (Display * display)
251 {
252   fprintf (stderr, "\nX IO Error\n");
253   fflush (stderr);
254   termination_eof ();
255   return (0);
256 }
257 
258 typedef struct
259 {
260   char message [2048];
261   char terminate_p;
262   unsigned char code;
263 } x_error_info_t;
264 
265 static x_error_info_t x_error_info;
266 
267 static int
x_error_handler(Display * display,XErrorEvent * error_event)268 x_error_handler (Display * display, XErrorEvent * error_event)
269 {
270   (x_error_info.code) = (error_event->error_code);
271   XGetErrorText (display,
272 		 (error_event->error_code),
273 		 (x_error_info.message),
274 		 (sizeof (x_error_info.message)));
275   if (x_error_info.terminate_p)
276     {
277       fprintf (stderr, "\nX Error: %s\n", (x_error_info.message));
278       fprintf (stderr, "         Request code: %d\n",
279 	       (error_event->request_code));
280       fprintf (stderr, "         Error serial: %lx\n", (error_event->serial));
281       fflush (stderr);
282       termination_eof ();
283     }
284   return (0);
285 }
286 
287 static void
unbind_x_error_info(void * storage)288 unbind_x_error_info (void * storage)
289 {
290   x_error_info = (* ((x_error_info_t *) storage));
291 }
292 
293 static void *
push_x_error_info(Display * display)294 push_x_error_info (Display * display)
295 {
296   void * handle;
297   x_error_info_t * storage;
298 
299   XSync (display, False);
300   handle = dstack_position;
301   storage = (dstack_alloc (sizeof (x_error_info_t)));
302   (*storage) = x_error_info;
303   ((x_error_info.message) [0]) = '\0';
304   (x_error_info.terminate_p) = 0;
305   (x_error_info.code) = 0;
306   dstack_protect (unbind_x_error_info, storage);
307   return (handle);
308 }
309 
310 static void
pop_x_error_info(void * handle)311 pop_x_error_info (void * handle)
312 {
313   dstack_set_position (handle);
314 }
315 
316 static unsigned char
x_error_code(Display * display)317 x_error_code (Display * display)
318 {
319   XSync (display, False);
320   return (x_error_info.code);
321 }
322 
323 static int
any_x_errors_p(Display * display)324 any_x_errors_p (Display * display)
325 {
326   return ((x_error_code (display)) != 0);
327 }
328 
329 /* Defaults and Attributes */
330 
331 static int
x_decode_color(Display * display,Colormap color_map,const char * color_name,unsigned long * color_return)332 x_decode_color (Display * display,
333 		Colormap color_map,
334 		const char * color_name,
335 		unsigned long * color_return)
336 {
337   XColor cdef;
338   if ((XParseColor (display, color_map, color_name, (&cdef)))
339       && (XAllocColor (display, color_map, (&cdef))))
340     {
341       (*color_return) = (cdef.pixel);
342       return (1);
343     }
344   return (0);
345 }
346 
347 Colormap
xw_color_map(struct xwindow * xw)348 xw_color_map (struct xwindow * xw)
349 {
350   XWindowAttributes a;
351   if (! (XGetWindowAttributes ((XW_DISPLAY (xw)), (XW_WINDOW (xw)), (&a))))
352     error_external_return ();
353   return (a.colormap);
354 }
355 
356 static unsigned long
arg_window_color(unsigned int arg,Display * display,struct xwindow * xw)357 arg_window_color (unsigned int arg, Display * display, struct xwindow * xw)
358 {
359   unsigned long result;
360   SCHEME_OBJECT object = (ARG_REF (arg));
361   if (INTEGER_P (object))
362     {
363       if (! (integer_to_ulong_p (object)))
364 	error_bad_range_arg (arg);
365       result = (integer_to_ulong (object));
366     }
367   else if (! (x_decode_color
368 	      (display, (xw_color_map (xw)), (STRING_ARG (arg)), (&result))))
369     error_bad_range_arg (arg);
370   return (result);
371 }
372 
373 static void
x_set_mouse_colors(Display * display,Colormap color_map,Cursor mouse_cursor,unsigned long mouse_pixel,unsigned long background_pixel)374 x_set_mouse_colors (Display * display,
375 		    Colormap color_map,
376 		    Cursor mouse_cursor,
377 		    unsigned long mouse_pixel,
378 		    unsigned long background_pixel)
379 {
380   XColor mouse_color;
381   XColor background_color;
382   (mouse_color.pixel) = mouse_pixel;
383   XQueryColor (display, color_map, (&mouse_color));
384   (background_color.pixel) = background_pixel;
385   XQueryColor (display, color_map, (&background_color));
386   XRecolorCursor (display, mouse_cursor, (&mouse_color), (&background_color));
387 }
388 
389 const char *
x_get_default(Display * display,const char * resource_name,const char * resource_class,const char * property_name,const char * property_class,const char * sdefault)390 x_get_default (Display * display,
391 	       const char * resource_name,
392 	       const char * resource_class,
393 	       const char * property_name,
394 	       const char * property_class,
395 	       const char * sdefault)
396 {
397   const char * result = (XGetDefault (display, resource_name, property_name));
398   if (result != 0)
399     return (result);
400   result = (XGetDefault (display, resource_class, property_name));
401   if (result != 0)
402     return (result);
403   result = (XGetDefault (display, resource_name, property_class));
404   if (result != 0)
405     return (result);
406   result = (XGetDefault (display, resource_class, property_class));
407   if (result != 0)
408     return (result);
409   return (sdefault);
410 }
411 
412 static unsigned long
x_default_color(Display * display,const char * resource_name,const char * resource_class,const char * property_name,const char * property_class,unsigned long default_color)413 x_default_color (Display * display,
414 		 const char * resource_name,
415 		 const char * resource_class,
416 		 const char * property_name,
417 		 const char * property_class,
418 		 unsigned long default_color)
419 {
420   const char * color_name
421     = (x_get_default (display, resource_name, resource_class,
422 		      property_name, property_class, 0));
423   unsigned long result;
424   return
425     (((color_name != 0)
426       && (x_decode_color (display,
427 			  (DefaultColormap (display,
428 					    (DefaultScreen (display)))),
429 			  color_name,
430 			  (&result))))
431      ? result
432      : default_color);
433 }
434 
435 void
x_default_attributes(Display * display,const char * resource_name,const char * resource_class,struct drawing_attributes * attributes)436 x_default_attributes (Display * display,
437 		      const char * resource_name,
438 		      const char * resource_class,
439 		      struct drawing_attributes * attributes)
440 {
441   int screen_number = (DefaultScreen (display));
442   (attributes->font)
443     = (XLoadQueryFont (display,
444 		       ((x_default_font != 0)
445 			? x_default_font
446 			: (x_get_default (display,
447 					  resource_name, resource_class,
448 					  "font", "Font",
449 					  X_DEFAULT_FONT)))));
450   if ((attributes->font) == 0)
451     error_external_return ();
452   {
453     const char * s
454       = (x_get_default (display,
455 			resource_name, resource_class,
456 			"borderWidth", "BorderWidth",
457 			0));
458     (attributes->border_width) = ((s == 0) ? 0 : (atoi (s)));
459   }
460   {
461     const char * s
462       = (x_get_default (display,
463 			resource_name, resource_class,
464 			"internalBorder", "BorderWidth",
465 			0));
466     (attributes->internal_border_width)
467       = ((s == 0) ? (attributes->border_width) : (atoi (s)));
468   }
469   {
470     unsigned long white_pixel = (WhitePixel (display, screen_number));
471     unsigned long black_pixel = (BlackPixel (display, screen_number));
472     unsigned long foreground_pixel;
473     (attributes->background_pixel)
474       = (x_default_color (display,
475 			  resource_name, resource_class,
476 			  "background", "Background",
477 			  white_pixel));
478     foreground_pixel
479       = (x_default_color (display,
480 			  resource_name, resource_class,
481 			  "foreground", "Foreground",
482 			  black_pixel));
483     (attributes->foreground_pixel) = foreground_pixel;
484     (attributes->border_pixel)
485       = (x_default_color (display,
486 			  resource_name, resource_class,
487 			  "borderColor", "BorderColor",
488 			  foreground_pixel));
489     (attributes->cursor_pixel)
490       = (x_default_color (display,
491 			  resource_name, resource_class,
492 			  "cursorColor", "Foreground",
493 			  foreground_pixel));
494     (attributes->mouse_pixel)
495       = (x_default_color (display,
496 			  resource_name, resource_class,
497 			  "pointerColor", "Foreground",
498 			  foreground_pixel));
499   }
500 }
501 
502 static int
get_wm_decor_geometry(struct xwindow * xw)503 get_wm_decor_geometry (struct xwindow * xw)
504 {
505   Display * display = (XW_DISPLAY (xw));
506   Window decor = (XW_WINDOW (xw));
507   void * handle = (push_x_error_info (display));
508   Window root;
509   unsigned int depth;
510 
511   {
512     Window parent;
513     Window * children;
514     unsigned int n_children;
515     while (1)
516       {
517 	if ((!XQueryTree (display, decor,
518 			  (&root), (&parent), (&children), (&n_children)))
519 	    || (any_x_errors_p (display)))
520 	  {
521 	    pop_x_error_info (handle);
522 	    error_external_return ();
523 	  }
524 	if (children != 0)
525 	  XFree (children);
526 	if (parent == root)
527 	  break;
528 	decor = parent;
529       }
530   }
531   if ((!XGetGeometry (display,
532 		      decor,
533 		      (&root),
534 		      (& (XW_WM_DECOR_X (xw))),
535 		      (& (XW_WM_DECOR_Y (xw))),
536 		      (& (XW_WM_DECOR_PIXEL_WIDTH (xw))),
537 		      (& (XW_WM_DECOR_PIXEL_HEIGHT (xw))),
538 		      (& (XW_WM_DECOR_BORDER_WIDTH (xw))),
539 		      (&depth)))
540       || (any_x_errors_p (display)))
541     {
542       pop_x_error_info (handle);
543       error_external_return ();
544     }
545   pop_x_error_info (handle);
546   /* Return true iff the window has been reparented by the WM.  */
547   return (decor != (XW_WINDOW (xw)));
548 }
549 
550 /* Open/Close Windows */
551 
552 #define MAKE_GC(gc, fore, back)						\
553 {									\
554   XGCValues gcv;							\
555   (gcv.font) = fid;							\
556   (gcv.foreground) = (fore);						\
557   (gcv.background) = (back);						\
558   (gc) =								\
559     (XCreateGC (display,						\
560 		window,							\
561 		(GCFont | GCForeground | GCBackground),			\
562 		(& gcv)));						\
563 }
564 
565 struct xwindow *
x_make_window(struct xdisplay * xd,Window window,int x_size,int y_size,struct drawing_attributes * attributes,struct xwindow_methods * methods,unsigned int size)566 x_make_window (struct xdisplay * xd,
567 	       Window window,
568 	       int x_size,
569 	       int y_size,
570 	       struct drawing_attributes * attributes,
571 	       struct xwindow_methods * methods,
572 	       unsigned int size)
573 {
574   GC normal_gc;
575   GC reverse_gc;
576   GC cursor_gc;
577   struct xwindow * xw;
578   Display * display = (XD_DISPLAY (xd));
579   Font fid = ((attributes->font) -> fid);
580   unsigned long foreground_pixel = (attributes->foreground_pixel);
581   unsigned long background_pixel = (attributes->background_pixel);
582   Cursor mouse_cursor = (XCreateFontCursor (display, XC_left_ptr));
583   MAKE_GC (normal_gc, foreground_pixel, background_pixel);
584   MAKE_GC (reverse_gc, background_pixel, foreground_pixel);
585   MAKE_GC (cursor_gc, background_pixel, (attributes->cursor_pixel));
586   x_set_mouse_colors
587     (display,
588      (DefaultColormap (display, (DefaultScreen (display)))),
589      mouse_cursor,
590      (attributes->mouse_pixel),
591      background_pixel);
592   XDefineCursor (display, window, mouse_cursor);
593   XSelectInput (display, window, 0);
594   if (size < (sizeof (struct xwindow)))
595     error_external_return ();
596   xw = (x_malloc (size));
597   (XW_ALLOCATION_INDEX (xw)) = (allocate_table_index ((&x_window_table), xw));
598   (XW_XD (xw)) = xd;
599   (XW_WINDOW (xw)) = window;
600   (XW_X_SIZE (xw)) = x_size;
601   (XW_Y_SIZE (xw)) = y_size;
602   (XW_CLIP_X (xw)) = 0;
603   (XW_CLIP_Y (xw)) = 0;
604   (XW_CLIP_WIDTH (xw)) = x_size;
605   (XW_CLIP_HEIGHT (xw)) = y_size;
606   (xw->attributes) = (*attributes);
607   (xw->methods) = (*methods);
608   (XW_NORMAL_GC (xw)) = normal_gc;
609   (XW_REVERSE_GC (xw)) = reverse_gc;
610   (XW_CURSOR_GC (xw)) = cursor_gc;
611   (XW_MOUSE_CURSOR (xw)) = mouse_cursor;
612   (XW_EVENT_MASK (xw)) = 0;
613   (XW_CHECK_EXPECTED_MOVE_P (xw)) = 0;
614   (XW_MOVE_OFFSET_X (xw)) = 0;
615   (XW_MOVE_OFFSET_Y (xw)) = 0;
616   return (xw);
617 }
618 
619 static jmp_buf x_close_window_jmp_buf;
620 
621 static int
x_close_window_io_error(Display * display)622 x_close_window_io_error (Display * display)
623 {
624   longjmp (x_close_window_jmp_buf, 1);
625   /*NOTREACHED*/
626   return (0);
627 }
628 
629 static void
x_close_window(struct xwindow * xw)630 x_close_window (struct xwindow * xw)
631 {
632   Display * display = (XW_DISPLAY (xw));
633   ((x_window_table.items) [XW_ALLOCATION_INDEX (xw)]) = 0;
634   if ((setjmp (x_close_window_jmp_buf)) == 0)
635     {
636       XSetIOErrorHandler (x_close_window_io_error);
637       {
638 	x_deallocator_t deallocator = (XW_DEALLOCATOR (xw));
639 	if (deallocator != 0)
640 	  (*deallocator) (xw);
641       }
642       {
643 	XFontStruct * font = (XW_FONT (xw));
644 	if (font != 0)
645 	  XFreeFont (display, font);
646       }
647       XDestroyWindow (display, (XW_WINDOW (xw)));
648       /* Guarantee that the IO error occurs while the IO error handler
649 	 is rebound, if at all. */
650       XFlush (display);
651     }
652   XSetIOErrorHandler (x_io_error_handler);
653   free (xw);
654 }
655 
656 /* Initialize/Close Displays */
657 
658 #define MODIFIER_INDEX_TO_MASK(N) (1 << (N))
659 
660 /* Grovel through the X server's keycode and modifier mappings to find
661    out what we ought to interpret as Meta, Hyper, and Super, based on
662    what modifiers are associated with keycodes that are associated with
663    keysyms Meta_L, Meta_R, Alt_L, Alt_R, Hyper_L, &c.
664 
665    Adapted from GNU Emacs. */
666 
667 static void
x_initialize_display_modifier_masks(struct xdisplay * xd)668 x_initialize_display_modifier_masks (struct xdisplay * xd)
669 {
670   int min_keycode;
671   int max_keycode;
672   XModifierKeymap * modifier_keymap;
673   KeyCode * modifier_to_keycodes_table;
674   int keycodes_per_modifier;
675   KeySym * keycode_to_keysyms_table;
676   int keysyms_per_keycode;
677 
678   (XD_MODIFIER_MASK_META (xd)) = 0;
679   (XD_MODIFIER_MASK_SUPER (xd)) = 0;
680   (XD_MODIFIER_MASK_HYPER (xd)) = 0;
681 
682   modifier_keymap = (XGetModifierMapping ((XD_DISPLAY (xd))));
683   modifier_to_keycodes_table = (modifier_keymap->modifiermap);
684   keycodes_per_modifier = (modifier_keymap->max_keypermod);
685 
686   XDisplayKeycodes ((XD_DISPLAY (xd)), (& min_keycode), (& max_keycode));
687 
688   keycode_to_keysyms_table
689     = (XGetKeyboardMapping ((XD_DISPLAY (xd)),
690 			    min_keycode,
691 			    (max_keycode - min_keycode + 1),
692 			    (& keysyms_per_keycode)));
693 
694   /* Go through each of the 8 non-preassigned modifiers, which start at
695      3 (Mod1), after Shift, Control, and Lock.  For each modifier, go
696      through all of the (non-zero) keycodes attached to it; for each
697      keycode, go through all of the keysyms attached to it; check each
698      keysym for the modifiers that we're interested in (Meta, Hyper,
699      and Super). */
700 
701   {
702     int modifier_index;
703 
704     for (modifier_index = 3; (modifier_index < 8); modifier_index += 1)
705       {
706         int modifier_mask = (MODIFIER_INDEX_TO_MASK (modifier_index));
707         KeyCode * keycodes
708 	  = (& (modifier_to_keycodes_table
709 		[modifier_index * keycodes_per_modifier]));
710 
711         /* This is a flag specifying whether the modifier has already
712            been identified as Meta, which takes precedence over Hyper
713            and Super.  (What about precedence between Hyper and
714            Super...?  This is GNU Emacs's behaviour.) */
715         int modifier_is_meta_p = 0;
716 
717         int keycode_index;
718 
719         for (keycode_index = 0;
720              (keycode_index < keycodes_per_modifier);
721              keycode_index += 1)
722           {
723             KeyCode keycode = (keycodes [keycode_index]);
724 
725             if (keycode == 0)
726               continue;
727 
728             {
729               int keysym_index;
730               KeySym * keysyms
731 		= (& (keycode_to_keysyms_table
732 		      [(keycode - min_keycode) * keysyms_per_keycode]));
733 
734               for (keysym_index = 0;
735                    (keysym_index < keysyms_per_keycode);
736                    keysym_index += 1)
737                 switch (keysyms [keysym_index])
738                   {
739                   case XK_Meta_L:
740                   case XK_Meta_R:
741                   case XK_Alt_L:
742                   case XK_Alt_R:
743                     modifier_is_meta_p = 1;
744                     (XD_MODIFIER_MASK_META (xd)) |= modifier_mask;
745                     break;
746 
747                   case XK_Hyper_L:
748                   case XK_Hyper_R:
749                     if (! modifier_is_meta_p)
750                       (XD_MODIFIER_MASK_HYPER (xd)) |= modifier_mask;
751                     goto next_modifier;
752 
753                   case XK_Super_L:
754                   case XK_Super_R:
755                     if (! modifier_is_meta_p)
756                       (XD_MODIFIER_MASK_SUPER (xd)) |= modifier_mask;
757                     goto next_modifier;
758                   }
759             }
760           }
761 
762       next_modifier:
763         continue;
764       }
765   }
766 
767   XFree (((char *) keycode_to_keysyms_table));
768   XFreeModifiermap (modifier_keymap);
769 }
770 
771 static void
x_close_display(struct xdisplay * xd)772 x_close_display (struct xdisplay * xd)
773 {
774   struct xwindow ** scan = ((struct xwindow **) (x_window_table.items));
775   struct xwindow ** end = (scan + (x_window_table.length));
776   while (scan < end)
777     {
778       struct xwindow * xw = (*scan++);
779       if ((xw != 0) && ((XW_XD (xw)) == xd))
780 	x_close_window (xw);
781     }
782   ((x_display_table.items) [XD_ALLOCATION_INDEX (xd)]) = 0;
783   XCloseDisplay (XD_DISPLAY (xd));
784 }
785 
786 static void
x_close_all_displays(void)787 x_close_all_displays (void)
788 {
789   struct xdisplay ** scan = ((struct xdisplay **) (x_display_table.items));
790   struct xdisplay ** end = (scan + (x_display_table.length));
791   while (scan < end)
792     {
793       struct xdisplay * xd = (*scan++);
794       if (xd != 0)
795 	x_close_display (xd);
796     }
797 }
798 
799 /* Window Manager Properties */
800 
801 static void
xw_set_class_hint(struct xwindow * xw,const char * name,const char * class)802 xw_set_class_hint (struct xwindow * xw, const char * name, const char * class)
803 {
804   XClassHint * class_hint = (XAllocClassHint ());
805   if (class_hint == 0)
806     error_external_return ();
807   /* This structure is misdeclared, so cast the args. */
808   (class_hint->res_name) = ((char *) name);
809   (class_hint->res_class) = ((char *) class);
810   XSetClassHint ((XW_DISPLAY (xw)), (XW_WINDOW (xw)), class_hint);
811   XFree (class_hint);
812 }
813 
814 void
xw_set_wm_input_hint(struct xwindow * xw,int input_hint)815 xw_set_wm_input_hint (struct xwindow * xw, int input_hint)
816 {
817   XWMHints * hints = (XAllocWMHints ());
818   if (hints == 0)
819     error_external_return ();
820   (hints->flags) = InputHint;
821   (hints->input) = (input_hint != 0);
822   XSetWMHints ((XW_DISPLAY (xw)), (XW_WINDOW (xw)), hints);
823   XFree (hints);
824 }
825 
826 void
xw_set_wm_name(struct xwindow * xw,const char * name)827 xw_set_wm_name (struct xwindow * xw, const char * name)
828 {
829   XTextProperty property;
830   if ((XStringListToTextProperty (((char **) (&name)), 1, (&property))) == 0)
831     error_external_return ();
832   XSetWMName ((XW_DISPLAY (xw)), (XW_WINDOW (xw)), (&property));
833 }
834 
835 void
xw_set_wm_icon_name(struct xwindow * xw,const char * name)836 xw_set_wm_icon_name (struct xwindow * xw, const char * name)
837 {
838   XTextProperty property;
839   if ((XStringListToTextProperty (((char **) (&name)), 1, (&property))) == 0)
840     error_external_return ();
841   XSetWMIconName ((XW_DISPLAY (xw)), (XW_WINDOW (xw)), (&property));
842 }
843 
844 void
x_decode_window_map_arg(SCHEME_OBJECT map_arg,const char ** resource_name,const char ** resource_class,int * map_p)845 x_decode_window_map_arg (SCHEME_OBJECT map_arg,
846 			 const char ** resource_name,
847 			 const char ** resource_class,
848 			 int * map_p)
849 {
850   (*map_p) = 0;
851   if (map_arg == SHARP_F)
852     (*map_p) = 1;
853   else if ((PAIR_P (map_arg))
854 	   && (STRING_P (PAIR_CAR (map_arg)))
855 	   && (STRING_P (PAIR_CDR (map_arg))))
856     {
857       (*resource_name) = (STRING_POINTER (PAIR_CAR (map_arg)));
858       (*resource_class) = (STRING_POINTER (PAIR_CDR (map_arg)));
859       (*map_p) = 1;
860     }
861   else if ((VECTOR_P (map_arg))
862 	   && ((VECTOR_LENGTH (map_arg)) == 3)
863 	   && (BOOLEAN_P (VECTOR_REF (map_arg, 0)))
864 	   && (STRING_P (VECTOR_REF (map_arg, 1)))
865 	   && (STRING_P (VECTOR_REF (map_arg, 2))))
866     {
867       (*resource_name) = (STRING_POINTER (VECTOR_REF (map_arg, 1)));
868       (*resource_class) = (STRING_POINTER (VECTOR_REF (map_arg, 2)));
869       (*map_p) = (OBJECT_TO_BOOLEAN (VECTOR_REF (map_arg, 0)));
870     }
871 }
872 
873 void
xw_make_window_map(struct xwindow * xw,const char * resource_name,const char * resource_class,int map_p)874 xw_make_window_map (struct xwindow * xw,
875 		    const char * resource_name,
876 		    const char * resource_class,
877 		    int map_p)
878 {
879   xw_set_class_hint (xw, resource_name, resource_class);
880   if (map_p)
881     {
882       XMapWindow ((XW_DISPLAY (xw)), (XW_WINDOW (xw)));
883       XFlush (XW_DISPLAY (xw));
884     }
885 }
886 
887 /* Event Processing */
888 
889 /* Returns non-zero value if caller should ignore the event.  */
890 
891 static int
xw_process_event(struct xwindow * xw,XEvent * event)892 xw_process_event (struct xwindow * xw, XEvent * event)
893 {
894   if (x_debug > 0)
895     {
896       const char * type_name;
897       fprintf (stderr, "\nX event on 0x%lx: ", ((event->xany) . window));
898       switch (event->type)
899 	{
900 	case ButtonPress:	type_name = "ButtonPress"; break;
901 	case ButtonRelease:	type_name = "ButtonRelease"; break;
902 	case CirculateNotify:	type_name = "CirculateNotify"; break;
903 	case CreateNotify:	type_name = "CreateNotify"; break;
904 	case DestroyNotify:	type_name = "DestroyNotify"; break;
905 	case EnterNotify:	type_name = "EnterNotify"; break;
906 	case Expose:		type_name = "Expose"; break;
907 	case FocusIn:		type_name = "FocusIn"; break;
908 	case FocusOut:		type_name = "FocusOut"; break;
909 	case GraphicsExpose:	type_name = "GraphicsExpose"; break;
910 	case GravityNotify:	type_name = "GravityNotify"; break;
911 	case KeyPress:		type_name = "KeyPress"; break;
912 	case KeyRelease:	type_name = "KeyRelease"; break;
913 	case LeaveNotify:	type_name = "LeaveNotify"; break;
914 	case MapNotify:		type_name = "MapNotify"; break;
915 	case MappingNotify:	type_name = "MappingNotify"; break;
916 	case MotionNotify:	type_name = "MotionNotify"; break;
917 	case NoExpose:		type_name = "NoExpose"; break;
918 	case ReparentNotify:	type_name = "ReparentNotify"; break;
919 	case SelectionClear:	type_name = "SelectionClear"; break;
920 	case SelectionRequest:	type_name = "SelectionRequest"; break;
921 	case UnmapNotify:	type_name = "UnmapNotify"; break;
922 
923 	case VisibilityNotify:
924 	  fprintf (stderr, "VisibilityNotify; state=");
925 	  switch ((event->xvisibility) . state)
926 	    {
927 	    case VisibilityUnobscured:
928 	      fprintf (stderr, "unobscured");
929 	      break;
930 	    case VisibilityPartiallyObscured:
931 	      fprintf (stderr, "partially-obscured");
932 	      break;
933 	    case VisibilityFullyObscured:
934 	      fprintf (stderr, "fully-obscured");
935 	      break;
936 	    default:
937 	      fprintf (stderr, "%d", ((event->xvisibility) . state));
938 	      break;
939 	    }
940 	  goto debug_done;
941 
942 	case ConfigureNotify:
943 	  fprintf (stderr, "ConfigureNotify; x=%d y=%d width=%d height=%d",
944 		   ((event->xconfigure) . x),
945 		   ((event->xconfigure) . y),
946 		   ((event->xconfigure) . width),
947 		   ((event->xconfigure) . height));
948 	  goto debug_done;
949 
950 	case ClientMessage:
951 	  {
952 	    struct xdisplay * xd = (XW_XD (xw));
953 	    if ((((event->xclient) . message_type) == (XD_WM_PROTOCOLS (xd)))
954 		&& (((event->xclient) . format) == 32))
955 	      {
956 		if (((Atom) (((event->xclient) . data . l) [0]))
957 		    == (XD_WM_DELETE_WINDOW (xd)))
958 		  type_name = "WM_DELETE_WINDOW";
959 		else if (((Atom) (((event->xclient) . data . l) [0]))
960 			 == (XD_WM_TAKE_FOCUS (xd)))
961 		  type_name = "WM_TAKE_FOCUS";
962 		else
963 		  type_name = "WM_PROTOCOLS";
964 	      }
965 	    else
966 	      {
967 		fprintf (stderr, "ClientMessage; message_type=0x%x format=%d",
968 			 ((unsigned int) ((event->xclient) . message_type)),
969 			 ((event->xclient) . format));
970 		goto debug_done;
971 	      }
972 	  }
973 	  break;
974 	case PropertyNotify:
975 	  {
976 	    fprintf (stderr, "PropertyNotify; atom=%ld time=%ld state=%d",
977 		     ((event->xproperty) . atom),
978 		     ((event->xproperty) . time),
979 		     ((event->xproperty) . state));
980 	    goto debug_done;
981 	  }
982 	case SelectionNotify:
983 	  {
984 	    fprintf
985 	      (stderr, "SelectionNotify; sel=%ld targ=%ld prop=%ld t=%ld",
986 	       ((event->xselection) . selection),
987 	       ((event->xselection) . target),
988 	       ((event->xselection) . property),
989 	       ((event->xselection) . time));
990 	    goto debug_done;
991 	  }
992 	default:		type_name = 0; break;
993 	}
994       if (type_name != 0)
995 	fprintf (stderr, "%s", type_name);
996       else
997 	fprintf (stderr, "%d", (event->type));
998     debug_done:
999       fprintf (stderr, "%s\n",
1000 	       (((event->xany) . send_event) ? "; synthetic" : ""));
1001       fflush (stderr);
1002     }
1003   switch (event->type)
1004     {
1005     case MappingNotify:
1006       switch ((event->xmapping) . request)
1007 	{
1008 	case MappingModifier:
1009 	  x_initialize_display_modifier_masks ((XW_XD (xw)));
1010 	  /* Fall through. */
1011 	case MappingKeyboard:
1012 	  XRefreshKeyboardMapping (& (event->xmapping));
1013 	  break;
1014 	}
1015       break;
1016     }
1017   if (xw != 0)
1018     {
1019       switch (event->type)
1020 	{
1021 	case ReparentNotify:
1022 	  get_wm_decor_geometry (xw);
1023 	  /* Perhaps reparented due to a WM restart.  Reset this.  */
1024 	  (XW_WM_TYPE (xw)) = X_WMTYPE_UNKNOWN;
1025 	  break;
1026 
1027 	case ConfigureNotify:
1028 	  /* If the window has been reparented, don't check
1029 	     non-synthetic events.  */
1030 	  if ((XW_CHECK_EXPECTED_MOVE_P (xw))
1031 	      && (! ((get_wm_decor_geometry (xw))
1032 		     && (! ((event->xconfigure) . send_event)))))
1033 	    check_expected_move (xw);
1034 	  break;
1035 	}
1036       (* (XW_EVENT_PROCESSOR (xw))) (xw, event);
1037     }
1038   return (0);
1039 }
1040 
1041 enum event_type
1042 {
1043   event_type_button_down,
1044   event_type_button_up,
1045   event_type_configure,
1046   event_type_enter,
1047   event_type_focus_in,
1048   event_type_focus_out,
1049   event_type_key_press,
1050   event_type_leave,
1051   event_type_motion,
1052   event_type_expose,
1053   event_type_delete_window,
1054   event_type_map,
1055   event_type_unmap,
1056   event_type_take_focus,
1057   event_type_visibility,
1058   event_type_selection_clear,
1059   event_type_selection_notify,
1060   event_type_selection_request,
1061   event_type_property_notify,
1062   event_type_supremum
1063 };
1064 
1065 #define EVENT_MASK_ARG(arg)						\
1066   (arg_ulong_index_integer						\
1067    ((arg), (1 << ((unsigned int) event_type_supremum))))
1068 
1069 #define EVENT_ENABLED(xw, type)						\
1070   (((XW_EVENT_MASK (xw)) & (1 << ((unsigned int) (type)))) != 0)
1071 
1072 #define EVENT_0 2
1073 #define EVENT_1 3
1074 #define EVENT_2 4
1075 #define EVENT_3 5
1076 #define EVENT_4 6
1077 
1078 #define EVENT_INTEGER(event, slot, number)				\
1079   VECTOR_SET ((event), (slot), (long_to_integer (number)))
1080 
1081 #define EVENT_ULONG_INTEGER(event, slot, number)			\
1082   VECTOR_SET ((event), (slot), (ulong_to_integer (number)))
1083 
1084 static SCHEME_OBJECT
make_event_object(struct xwindow * xw,enum event_type type,unsigned int extra)1085 make_event_object (struct xwindow * xw,
1086 		   enum event_type type,
1087 		   unsigned int extra)
1088 {
1089   SCHEME_OBJECT result = (allocate_marked_vector (TC_VECTOR, (2 + extra), 1));
1090   VECTOR_SET (result, 0, (LONG_TO_UNSIGNED_FIXNUM ((long) type)));
1091   VECTOR_SET (result, 1, ((xw == 0) ? SHARP_F : (XW_TO_OBJECT (xw))));
1092   return (result);
1093 }
1094 
1095 /* This handles only the modifier bits that Scheme supports.
1096    At the moment, these are Control, Meta, Super, and Hyper.
1097    This might want to change if the character abstraction were ever to
1098    change, or if the X11 interface were to be changed to use something
1099    other than Scheme characters to convey key presses. */
1100 
1101 static unsigned long
x_modifier_mask_to_bucky_bits(unsigned int mask,struct xdisplay * xd)1102 x_modifier_mask_to_bucky_bits (unsigned int mask, struct xdisplay * xd)
1103 {
1104   unsigned long bucky = 0;
1105   if (X_MODIFIER_MASK_CONTROL_P (mask, xd)) bucky |= CHAR_BITS_CONTROL;
1106   if (X_MODIFIER_MASK_META_P    (mask, xd)) bucky |= CHAR_BITS_META;
1107   if (X_MODIFIER_MASK_SUPER_P   (mask, xd)) bucky |= CHAR_BITS_SUPER;
1108   if (X_MODIFIER_MASK_HYPER_P   (mask, xd)) bucky |= CHAR_BITS_HYPER;
1109   return (bucky);
1110 }
1111 
1112 /* I'm not sure why we have a function for this. */
1113 
1114 static SCHEME_OBJECT
x_key_button_mask_to_scheme(unsigned int x_state)1115 x_key_button_mask_to_scheme (unsigned int x_state)
1116 {
1117   unsigned long scheme_state = 0;
1118   if (x_state & ControlMask) scheme_state |= 0x0001;
1119   if (x_state & Mod1Mask)    scheme_state |= 0x0002;
1120   if (x_state & Mod2Mask)    scheme_state |= 0x0004;
1121   if (x_state & Mod3Mask)    scheme_state |= 0x0008;
1122   if (x_state & ShiftMask)   scheme_state |= 0x0010;
1123   if (x_state & LockMask)    scheme_state |= 0x0020;
1124   if (x_state & Mod4Mask)    scheme_state |= 0x0040;
1125   if (x_state & Mod5Mask)    scheme_state |= 0x0080;
1126   if (x_state & Button1Mask) scheme_state |= 0x0100;
1127   if (x_state & Button2Mask) scheme_state |= 0x0200;
1128   if (x_state & Button3Mask) scheme_state |= 0x0400;
1129   if (x_state & Button4Mask) scheme_state |= 0x0800;
1130   if (x_state & Button5Mask) scheme_state |= 0x1000;
1131   return (ULONG_TO_FIXNUM (scheme_state));
1132 }
1133 
1134 static SCHEME_OBJECT
button_event(struct xwindow * xw,XButtonEvent * event,enum event_type type)1135 button_event (struct xwindow * xw, XButtonEvent * event, enum event_type type)
1136 {
1137   SCHEME_OBJECT result = (make_event_object (xw, type, 4));
1138   EVENT_INTEGER (result, EVENT_0, (event->x));
1139   EVENT_INTEGER (result, EVENT_1, (event->y));
1140   VECTOR_SET
1141     (result, EVENT_2,
1142      ((((event->button) >= 1) && ((event->button) <= 256))
1143       ? (ULONG_TO_FIXNUM
1144 	 (((event->button) - 1)
1145 	  | ((x_modifier_mask_to_bucky_bits ((event->state), (XW_XD (xw))))
1146 	     << 8)))
1147       : SHARP_F));
1148   EVENT_ULONG_INTEGER (result, EVENT_3, (event->time));
1149   return (result);
1150 }
1151 
1152 static XComposeStatus compose_status;
1153 
1154 static SCHEME_OBJECT
key_event(struct xwindow * xw,XKeyEvent * event,enum event_type type)1155 key_event (struct xwindow * xw, XKeyEvent * event, enum event_type type)
1156 {
1157   char copy_buffer [80];
1158   KeySym keysym;
1159   int nbytes;
1160   SCHEME_OBJECT result;
1161 
1162   /* Make ShiftLock modifier not affect keys with other modifiers. */
1163   if ((event->state)
1164       & (ShiftMask || ControlMask
1165 	 || Mod1Mask || Mod2Mask || Mod3Mask || Mod4Mask || Mod5Mask))
1166     {
1167       if (((event->state) & LockMask) != 0)
1168 	(event->state) &=~ LockMask;
1169     }
1170   nbytes
1171     = (XLookupString (event,
1172 		      copy_buffer,
1173 		      (sizeof (copy_buffer)),
1174 		      (&keysym),
1175 		      (&compose_status)));
1176   if (keysym == NoSymbol)
1177     return (SHARP_F);
1178   /* If the BackSpace keysym is received, and XLookupString has
1179      translated it into ASCII backspace, substitute ASCII DEL
1180      instead.  */
1181   if ((keysym == XK_BackSpace)
1182       && (nbytes == 1)
1183       && ((copy_buffer[0]) == '\b'))
1184     (copy_buffer[0]) = '\177';
1185   if (IsModifierKey (keysym))
1186     return (SHARP_F);
1187 
1188   result = (make_event_object (xw, type, 4));
1189   VECTOR_SET (result, EVENT_0,
1190 	      (memory_to_string (nbytes, ((unsigned char *) copy_buffer))));
1191   /* Create Scheme bucky bits (kept independent of the character).
1192      X has already controlified, so Scheme may choose to ignore
1193      the control bucky bit.  */
1194   VECTOR_SET (result, EVENT_1,
1195 	      (ULONG_TO_FIXNUM
1196 	       (x_modifier_mask_to_bucky_bits ((event->state),
1197 					       (XW_XD (xw))))));
1198   VECTOR_SET (result, EVENT_2, (ulong_to_integer (keysym)));
1199   EVENT_ULONG_INTEGER (result, EVENT_3, (event->time));
1200   return (result);
1201 }
1202 
1203 #define CONVERT_TRIVIAL_EVENT(scheme_name)				\
1204   if (EVENT_ENABLED (xw, scheme_name))					\
1205     result = (make_event_object (xw, scheme_name, 0));			\
1206   break
1207 
1208 static SCHEME_OBJECT
x_event_to_object(XEvent * event)1209 x_event_to_object (XEvent * event)
1210 {
1211   struct xwindow * xw
1212     = (x_window_to_xw (((event->xany) . display),
1213 		       ((event->xany) . window)));
1214   SCHEME_OBJECT result = SHARP_F;
1215   if (xw == 0)
1216     return result;
1217   switch (event->type)
1218     {
1219     case KeyPress:
1220       if (EVENT_ENABLED (xw, event_type_key_press))
1221 	result = (key_event (xw, (& (event->xkey)), event_type_key_press));
1222       break;
1223     case ButtonPress:
1224       if (EVENT_ENABLED (xw, event_type_button_down))
1225 	result
1226 	  = (button_event (xw, (& (event->xbutton)), event_type_button_down));
1227       break;
1228     case ButtonRelease:
1229       if (EVENT_ENABLED (xw, event_type_button_up))
1230 	result
1231 	  = (button_event (xw, (& (event->xbutton)), event_type_button_up));
1232       break;
1233     case MotionNotify:
1234       if (EVENT_ENABLED (xw, event_type_motion))
1235 	{
1236 	  result = (make_event_object (xw, event_type_motion, 3));
1237 	  EVENT_INTEGER (result, EVENT_0, ((event->xmotion) . x));
1238 	  EVENT_INTEGER (result, EVENT_1, ((event->xmotion) . y));
1239 	  VECTOR_SET (result, EVENT_2,
1240                       (x_key_button_mask_to_scheme
1241                        (((event->xmotion) . state))));
1242 	}
1243       break;
1244     case ConfigureNotify:
1245       if (EVENT_ENABLED (xw, event_type_configure))
1246 	{
1247 	  result = (make_event_object (xw, event_type_configure, 2));
1248 	  EVENT_ULONG_INTEGER
1249 	    (result, EVENT_0, ((event->xconfigure) . width));
1250 	  EVENT_ULONG_INTEGER
1251 	    (result, EVENT_1, ((event->xconfigure) . height));
1252 	}
1253       break;
1254     case Expose:
1255       if (EVENT_ENABLED (xw, event_type_expose))
1256 	{
1257 	  result = (make_event_object (xw, event_type_expose, 5));
1258 	  EVENT_INTEGER (result, EVENT_0, ((event->xexpose) . x));
1259 	  EVENT_INTEGER (result, EVENT_1, ((event->xexpose) . y));
1260 	  EVENT_ULONG_INTEGER (result, EVENT_2, ((event->xexpose) . width));
1261 	  EVENT_ULONG_INTEGER (result, EVENT_3, ((event->xexpose) . height));
1262 	  VECTOR_SET (result, EVENT_4, (LONG_TO_UNSIGNED_FIXNUM (0)));
1263 	}
1264       break;
1265     case GraphicsExpose:
1266       if (EVENT_ENABLED (xw, event_type_expose))
1267 	{
1268 	  result = (make_event_object (xw, event_type_expose, 5));
1269 	  EVENT_INTEGER (result, EVENT_0, ((event->xgraphicsexpose) . x));
1270 	  EVENT_INTEGER (result, EVENT_1, ((event->xgraphicsexpose) . y));
1271 	  EVENT_ULONG_INTEGER
1272 	    (result, EVENT_2, ((event->xgraphicsexpose) . width));
1273 	  EVENT_ULONG_INTEGER
1274 	    (result, EVENT_3, ((event->xgraphicsexpose) . height));
1275 	  VECTOR_SET (result, EVENT_4, (LONG_TO_UNSIGNED_FIXNUM (1)));
1276 	}
1277       break;
1278     case ClientMessage:
1279       {
1280 	struct xdisplay * xd = (XW_XD (xw));
1281 	if ((((event->xclient) . message_type) == (XD_WM_PROTOCOLS (xd)))
1282 	    && (((event->xclient) . format) == 32))
1283 	  {
1284 	    if (((Atom) (((event->xclient) . data . l) [0]))
1285 		== (XD_WM_DELETE_WINDOW (xd)))
1286 	      {
1287 		if (EVENT_ENABLED (xw, event_type_delete_window))
1288 		  result
1289 		    = (make_event_object (xw, event_type_delete_window, 0));
1290 	      }
1291 	    else if (((Atom) (((event->xclient) . data . l) [0]))
1292 		     == (XD_WM_TAKE_FOCUS (xd)))
1293 	      {
1294 		if (EVENT_ENABLED (xw, event_type_take_focus))
1295 		  {
1296 		    result
1297 		      = (make_event_object (xw, event_type_take_focus, 1));
1298 		    EVENT_ULONG_INTEGER
1299 		      (result, EVENT_0, (((event->xclient) . data . l) [1]));
1300 		  }
1301 	      }
1302 	  }
1303       }
1304       break;
1305     case VisibilityNotify:
1306       if (EVENT_ENABLED (xw, event_type_visibility))
1307 	{
1308 	  unsigned int state;
1309 	  switch ((event->xvisibility) . state)
1310 	    {
1311 	    case VisibilityUnobscured:
1312 	      state = 0;
1313 	      break;
1314 	    case VisibilityPartiallyObscured:
1315 	      state = 1;
1316 	      break;
1317 	    case VisibilityFullyObscured:
1318 	      state = 2;
1319 	      break;
1320 	    default:
1321 	      state = 3;
1322 	      break;
1323 	    }
1324 	  result = (make_event_object (xw, event_type_visibility, 1));
1325 	  EVENT_ULONG_INTEGER (result, EVENT_0, state);
1326 	}
1327       break;
1328     case SelectionClear:
1329       if (EVENT_ENABLED (xw, event_type_selection_clear))
1330 	{
1331 	  result = (make_event_object (xw, event_type_selection_clear, 2));
1332 	  EVENT_ULONG_INTEGER
1333 	    (result, EVENT_0, ((event->xselectionclear) . selection));
1334 	  EVENT_ULONG_INTEGER
1335 	    (result, EVENT_1, ((event->xselectionclear) . time));
1336 	}
1337       break;
1338     case SelectionNotify:
1339       if (EVENT_ENABLED (xw, event_type_selection_notify))
1340 	{
1341 	  result = (make_event_object (xw, event_type_selection_notify, 5));
1342 	  EVENT_ULONG_INTEGER
1343 	    (result, EVENT_0, ((event->xselection) . requestor));
1344 	  EVENT_ULONG_INTEGER
1345 	    (result, EVENT_1, ((event->xselection) . selection));
1346 	  EVENT_ULONG_INTEGER
1347 	    (result, EVENT_2, ((event->xselection) . target));
1348 	  EVENT_ULONG_INTEGER
1349 	    (result, EVENT_3, ((event->xselection) . property));
1350 	  EVENT_ULONG_INTEGER
1351 	    (result, EVENT_4, ((event->xselection) . time));
1352 	}
1353       break;
1354     case SelectionRequest:
1355       if (EVENT_ENABLED (xw, event_type_selection_request))
1356 	{
1357 	  result = (make_event_object (xw, event_type_selection_request, 5));
1358 	  EVENT_ULONG_INTEGER
1359 	    (result, EVENT_0, ((event->xselectionrequest) . requestor));
1360 	  EVENT_ULONG_INTEGER
1361 	    (result, EVENT_1, ((event->xselectionrequest) . selection));
1362 	  EVENT_ULONG_INTEGER
1363 	    (result, EVENT_2, ((event->xselectionrequest) . target));
1364 	  EVENT_ULONG_INTEGER
1365 	    (result, EVENT_3, ((event->xselectionrequest) . property));
1366 	  EVENT_ULONG_INTEGER
1367 	    (result, EVENT_4, ((event->xselectionrequest) . time));
1368 	}
1369       break;
1370     case PropertyNotify:
1371       if (EVENT_ENABLED (xw, event_type_property_notify))
1372 	{
1373 	  result = (make_event_object (xw, event_type_property_notify, 4));
1374 	  /* Must store window element separately because this window
1375 	     might not have a corresponding XW object.  */
1376 	  EVENT_ULONG_INTEGER
1377 	    (result, EVENT_0, ((event->xproperty) . window));
1378 	  EVENT_ULONG_INTEGER
1379 	    (result, EVENT_1, ((event->xproperty) . atom));
1380 	  EVENT_ULONG_INTEGER
1381 	    (result, EVENT_2, ((event->xproperty) . time));
1382 	  EVENT_ULONG_INTEGER
1383 	    (result, EVENT_3, ((event->xproperty) . state));
1384 	}
1385       break;
1386     case EnterNotify: CONVERT_TRIVIAL_EVENT (event_type_enter);
1387     case LeaveNotify: CONVERT_TRIVIAL_EVENT (event_type_leave);
1388     case FocusIn: CONVERT_TRIVIAL_EVENT (event_type_focus_in);
1389     case FocusOut: CONVERT_TRIVIAL_EVENT (event_type_focus_out);
1390     case MapNotify: CONVERT_TRIVIAL_EVENT (event_type_map);
1391     case UnmapNotify: CONVERT_TRIVIAL_EVENT (event_type_unmap);
1392     }
1393   return (result);
1394 }
1395 
1396 static void
update_input_mask(struct xwindow * xw)1397 update_input_mask (struct xwindow * xw)
1398 {
1399   {
1400     unsigned long event_mask = 0;
1401     if (EVENT_ENABLED (xw, event_type_expose))
1402       event_mask |= ExposureMask;
1403     if ((EVENT_ENABLED (xw, event_type_configure))
1404 	|| (EVENT_ENABLED (xw, event_type_map))
1405 	|| (EVENT_ENABLED (xw, event_type_unmap)))
1406       event_mask |= StructureNotifyMask;
1407     if (EVENT_ENABLED (xw, event_type_button_down))
1408       event_mask |= ButtonPressMask;
1409     if (EVENT_ENABLED (xw, event_type_button_up))
1410       event_mask |= ButtonReleaseMask;
1411     if (EVENT_ENABLED (xw, event_type_key_press))
1412       event_mask |= KeyPressMask;
1413     if (EVENT_ENABLED (xw, event_type_enter))
1414       event_mask |= EnterWindowMask;
1415     if (EVENT_ENABLED (xw, event_type_leave))
1416       event_mask |= LeaveWindowMask;
1417     if ((EVENT_ENABLED (xw, event_type_focus_in))
1418 	|| (EVENT_ENABLED (xw, event_type_focus_out)))
1419       event_mask |= FocusChangeMask;
1420     if (EVENT_ENABLED (xw, event_type_motion))
1421       event_mask |= (PointerMotionMask | PointerMotionHintMask);
1422     if (EVENT_ENABLED (xw, event_type_visibility))
1423       event_mask |= VisibilityChangeMask;
1424     if (EVENT_ENABLED (xw, event_type_property_notify))
1425       event_mask |= PropertyChangeMask;
1426     XSelectInput ((XW_DISPLAY (xw)), (XW_WINDOW (xw)), event_mask);
1427   }
1428   {
1429     struct xdisplay * xd = (XW_XD (xw));
1430     Atom protocols [2];
1431     unsigned int n_protocols = 0;
1432     if (EVENT_ENABLED (xw, event_type_delete_window))
1433       (protocols[n_protocols++]) = (XD_WM_DELETE_WINDOW (xd));
1434     if (EVENT_ENABLED (xw, event_type_take_focus))
1435       (protocols[n_protocols++]) = (XD_WM_TAKE_FOCUS (xd));
1436     if (n_protocols > 0)
1437       XSetWMProtocols
1438 	((XW_DISPLAY (xw)), (XW_WINDOW (xw)), (&protocols[0]), n_protocols);
1439   }
1440 }
1441 
1442 static void
ping_server(struct xdisplay * xd)1443 ping_server (struct xdisplay * xd)
1444 {
1445   /* Periodically ping the server connection to see if it has died.  */
1446   (XD_SERVER_PING_TIMER (xd)) += 1;
1447   if ((XD_SERVER_PING_TIMER (xd)) >= 100)
1448     {
1449       (XD_SERVER_PING_TIMER (xd)) = 0;
1450       XNoOp (XD_DISPLAY (xd));
1451       XFlush (XD_DISPLAY (xd));
1452     }
1453 }
1454 
1455 /* The use of `XD_CACHED_EVENT' prevents an event from being lost due
1456    to garbage collection.  First `XD_CACHED_EVENT' is set to hold the
1457    current event, then the allocations are performed.  If one of them
1458    fails, the primitive will exit, and when it reenters it will notice
1459    the cached event and use it.  It is important that this be the only
1460    entry that reads events -- or else that all other event readers
1461    cooperate with this strategy.  */
1462 
1463 static SCHEME_OBJECT
xd_process_events(struct xdisplay * xd)1464 xd_process_events (struct xdisplay * xd)
1465 {
1466   Display * display = (XD_DISPLAY (xd));
1467   unsigned int events_queued;
1468   XEvent event;
1469   SCHEME_OBJECT result = SHARP_F;
1470   if (x_debug > 1)
1471     {
1472       fprintf (stderr, "Enter xd_process_events\n");
1473       fflush (stderr);
1474     }
1475   if (XD_CACHED_EVENT_P (xd))
1476     {
1477       events_queued = (XEventsQueued (display, QueuedAlready));
1478       event = (XD_CACHED_EVENT (xd));
1479       goto restart;
1480     }
1481   ping_server (xd);
1482   events_queued = (XEventsQueued (display, QueuedAfterReading));
1483   while (0 < events_queued)
1484     {
1485       events_queued -= 1;
1486       XNextEvent (display, (&event));
1487       if ((event.type) == KeymapNotify)
1488 	continue;
1489       {
1490 	struct xwindow * xw
1491 	  = (x_window_to_xw (display, (event.xany.window)));
1492 	if ((xw == 0)
1493 	    && (! (((event.type) == PropertyNotify)
1494 		   || ((event.type) == SelectionClear)
1495 		   || ((event.type) == SelectionNotify)
1496 		   || ((event.type) == SelectionRequest))))
1497 	  continue;
1498 	if (xw_process_event (xw, (&event)))
1499 	  continue;
1500       }
1501       (XD_CACHED_EVENT (xd)) = event;
1502       (XD_CACHED_EVENT_P (xd)) = 1;
1503     restart:
1504       result = (x_event_to_object (&event));
1505       (XD_CACHED_EVENT_P (xd)) = 0;
1506       if (result != SHARP_F)
1507 	break;
1508     }
1509   if (x_debug > 1)
1510     {
1511       fprintf (stderr, "Return from xd_process_events: ");
1512       if (result == SHARP_F)
1513 	fprintf (stderr, "#f");
1514       else if (VECTOR_P (result))
1515 	fprintf (stderr, "[vector]");
1516       else
1517 	fprintf (stderr, "[other: 0x%lx]", ((unsigned long) result));
1518       fprintf (stderr, "\n");
1519       fflush (stderr);
1520     }
1521   return (result);
1522 }
1523 
1524 /* Open/Close Primitives */
1525 
1526 static void
initialize_once(void)1527 initialize_once (void)
1528 {
1529   allocation_table_initialize (&x_display_table);
1530   allocation_table_initialize (&x_window_table);
1531   allocation_table_initialize (&x_image_table);
1532   ((x_error_info.message) [0]) = '\0';
1533   (x_error_info.terminate_p) = 1;
1534   (x_error_info.code) = 0;
1535   XSetErrorHandler (x_error_handler);
1536   XSetIOErrorHandler (x_io_error_handler);
1537 #ifndef COMPILE_AS_MODULE
1538   add_reload_cleanup (x_close_all_displays);
1539 #endif
1540   initialization_done = 1;
1541 }
1542 
1543 DEFINE_PRIMITIVE ("X-DEBUG", Prim_x_debug, 1, 1, 0)
1544 {
1545   PRIMITIVE_HEADER (1);
1546   {
1547     SCHEME_OBJECT object = (ARG_REF (1));
1548     if (object == SHARP_F)
1549       x_debug = 0;
1550     else if (UNSIGNED_FIXNUM_P (object))
1551       x_debug = (UNSIGNED_FIXNUM_TO_LONG (object));
1552     else
1553       x_debug = 1;
1554   }
1555   PRIMITIVE_RETURN (UNSPECIFIC);
1556 }
1557 
1558 DEFINE_PRIMITIVE ("X-OPEN-DISPLAY", Prim_x_open_display, 1, 1, 0)
1559 {
1560   PRIMITIVE_HEADER (1);
1561   INITIALIZE_ONCE ();
1562   {
1563     struct xdisplay * xd = (x_malloc (sizeof (struct xdisplay)));
1564     /* Added 7/95 by Nick in an attempt to fix problem Hal was having
1565        with SWAT over PPP (i.e. slow connections).  */
1566     block_signals ();
1567     (XD_DISPLAY (xd))
1568       = (XOpenDisplay (((ARG_REF (1)) == SHARP_F) ? 0 : (STRING_ARG (1))));
1569     unblock_signals ();
1570     if ((XD_DISPLAY (xd)) == 0)
1571       {
1572 	free (xd);
1573 	PRIMITIVE_RETURN (SHARP_F);
1574       }
1575     (XD_ALLOCATION_INDEX (xd))
1576       = (allocate_table_index ((&x_display_table), xd));
1577     (XD_SERVER_PING_TIMER (xd)) = 0;
1578     (XD_WM_PROTOCOLS (xd))
1579       = (XInternAtom ((XD_DISPLAY (xd)), "WM_PROTOCOLS", False));
1580     (XD_WM_DELETE_WINDOW (xd))
1581       = (XInternAtom ((XD_DISPLAY (xd)), "WM_DELETE_WINDOW", False));
1582     (XD_WM_TAKE_FOCUS (xd))
1583       = (XInternAtom ((XD_DISPLAY (xd)), "WM_TAKE_FOCUS", False));
1584     (XD_CACHED_EVENT_P (xd)) = 0;
1585     x_initialize_display_modifier_masks (xd);
1586     XRebindKeysym ((XD_DISPLAY (xd)), XK_BackSpace, 0, 0,
1587 		   ((unsigned char *) "\177"), 1);
1588     PRIMITIVE_RETURN (XD_TO_OBJECT (xd));
1589   }
1590 }
1591 
1592 DEFINE_PRIMITIVE ("X-CLOSE-DISPLAY", Prim_x_close_display, 1, 1, 0)
1593 {
1594   PRIMITIVE_HEADER (1);
1595   x_close_display (x_display_arg (1));
1596   PRIMITIVE_RETURN (UNSPECIFIC);
1597 }
1598 
1599 DEFINE_PRIMITIVE ("X-CLOSE-ALL-DISPLAYS", Prim_x_close_all_displays, 0, 0, 0)
1600 {
1601   PRIMITIVE_HEADER (0);
1602   INITIALIZE_ONCE ();
1603   x_close_all_displays ();
1604   PRIMITIVE_RETURN (UNSPECIFIC);
1605 }
1606 
1607 DEFINE_PRIMITIVE ("X-DISPLAY-GET-SIZE", Prim_x_display_get_size, 2, 2, 0)
1608 {
1609   PRIMITIVE_HEADER (2);
1610   {
1611     struct xdisplay * xd = (x_display_arg (1));
1612     Display * display = (XD_DISPLAY (xd));
1613     long screen = (arg_nonnegative_integer (2));
1614     PRIMITIVE_RETURN
1615       (cons ((ulong_to_integer (DisplayWidth (display, screen))),
1616 	     (ulong_to_integer (DisplayHeight (display, screen)))));
1617   }
1618 }
1619 
1620 DEFINE_PRIMITIVE ("X-CLOSE-WINDOW", Prim_x_close_window, 1, 1, 0)
1621 {
1622   PRIMITIVE_HEADER (1);
1623   {
1624     struct xwindow * xw = (x_window_arg (1));
1625     Display * display = (XW_DISPLAY (xw));
1626     x_close_window (xw);
1627     XFlush (display);
1628   }
1629   PRIMITIVE_RETURN (UNSPECIFIC);
1630 }
1631 
1632 DEFINE_PRIMITIVE ("X-SET-DEFAULT-FONT", Prim_x_set_default_font, 2, 2, 0)
1633 {
1634   PRIMITIVE_HEADER (2);
1635   {
1636     struct xdisplay * xd = (x_display_arg (1));
1637     Display * display = (XD_DISPLAY (xd));
1638     const char * name = (STRING_ARG (2));
1639     XFontStruct * font = (XLoadQueryFont (display, name));
1640     if (font == 0)
1641       PRIMITIVE_RETURN (SHARP_F);
1642     XFreeFont (display, font);
1643     if (x_default_font != 0)
1644       OS_free ((void *) x_default_font);
1645     {
1646       char * copy = (OS_malloc ((strlen (name)) + 1));
1647       const char * s1 = name;
1648       char * s2 = copy;
1649       while (1)
1650 	{
1651 	  char c = (*s1++);
1652 	  (*s2++) = c;
1653 	  if (c == '\0')
1654 	    break;
1655 	}
1656       x_default_font = copy;
1657     }
1658   }
1659   PRIMITIVE_RETURN (SHARP_T);
1660 }
1661 
1662 /* Event Processing Primitives */
1663 
1664 DEFINE_PRIMITIVE ("X-DISPLAY-DESCRIPTOR", Prim_x_display_descriptor, 1, 1, 0)
1665 {
1666   PRIMITIVE_HEADER (1);
1667   PRIMITIVE_RETURN
1668     (long_to_integer (ConnectionNumber (XD_DISPLAY (x_display_arg (1)))));
1669 }
1670 
1671 DEFINE_PRIMITIVE ("X-MAX-REQUEST-SIZE", Prim_x_max_request_size, 1, 1, 0)
1672 {
1673   PRIMITIVE_HEADER (1);
1674   PRIMITIVE_RETURN
1675     (long_to_integer (XMaxRequestSize (XD_DISPLAY (x_display_arg (1)))));
1676 }
1677 
1678 DEFINE_PRIMITIVE ("X-DISPLAY-PROCESS-EVENTS", Prim_x_display_process_events, 2, 2, 0)
1679 {
1680   PRIMITIVE_HEADER (2);
1681   {
1682     struct xdisplay * xd = (x_display_arg (1));
1683     SCHEME_OBJECT how = (ARG_REF (2));
1684     /* Previously, the `how' argument could be #F (block, select), 0
1685        (don't block, select), 1 (block, don't select), 2 (don't block,
1686        don't select).  Now we never select or block -- it is up to the
1687        caller to do that.  #F and 0 have been unused for a long time,
1688        and the only caller that used 1 in the system already selected
1689        and blocked anyway.  */
1690     if ((how != (LONG_TO_UNSIGNED_FIXNUM (1)))
1691 	&& (how != (LONG_TO_UNSIGNED_FIXNUM (2))))
1692       error_bad_range_arg (2);
1693     PRIMITIVE_RETURN (xd_process_events (xd));
1694   }
1695 }
1696 
1697 DEFINE_PRIMITIVE ("X-SELECT-INPUT", Prim_x_select_input, 3, 3, 0)
1698 {
1699   PRIMITIVE_HEADER (3);
1700   XSelectInput ((XD_DISPLAY (x_display_arg (1))),
1701 		(arg_ulong_integer (2)),
1702 		(arg_integer (3)));
1703   PRIMITIVE_RETURN (UNSPECIFIC);
1704 }
1705 
1706 DEFINE_PRIMITIVE ("X-WINDOW-EVENT-MASK", Prim_x_window_event_mask, 1, 1, 0)
1707 {
1708   PRIMITIVE_HEADER (1);
1709   PRIMITIVE_RETURN (ulong_to_integer (XW_EVENT_MASK (x_window_arg (1))));
1710 }
1711 
1712 DEFINE_PRIMITIVE ("X-WINDOW-SET-EVENT-MASK", Prim_x_window_set_event_mask, 2, 2, 0)
1713 {
1714   PRIMITIVE_HEADER (2);
1715   {
1716     struct xwindow * xw = (x_window_arg (1));
1717     (XW_EVENT_MASK (xw)) = (EVENT_MASK_ARG (2));
1718     update_input_mask (xw);
1719   }
1720   PRIMITIVE_RETURN (UNSPECIFIC);
1721 }
1722 
1723 DEFINE_PRIMITIVE ("X-WINDOW-OR-EVENT-MASK", Prim_x_window_or_event_mask, 2, 2, 0)
1724 {
1725   PRIMITIVE_HEADER (2);
1726   {
1727     struct xwindow * xw = (x_window_arg (1));
1728     (XW_EVENT_MASK (xw)) |= (EVENT_MASK_ARG (2));
1729     update_input_mask (xw);
1730   }
1731   PRIMITIVE_RETURN (UNSPECIFIC);
1732 }
1733 
1734 DEFINE_PRIMITIVE ("X-WINDOW-ANDC-EVENT-MASK", Prim_x_window_andc_event_mask, 2, 2, 0)
1735 {
1736   PRIMITIVE_HEADER (2);
1737   {
1738     struct xwindow * xw = (x_window_arg (1));
1739     (XW_EVENT_MASK (xw)) &=~ (EVENT_MASK_ARG (2));
1740     update_input_mask (xw);
1741   }
1742   PRIMITIVE_RETURN (UNSPECIFIC);
1743 }
1744 
1745 /* Miscellaneous Primitives */
1746 
1747 DEFINE_PRIMITIVE ("X-WINDOW-DISPLAY", Prim_x_window_display, 1, 1, 0)
1748 {
1749   PRIMITIVE_HEADER (1);
1750   PRIMITIVE_RETURN (XD_TO_OBJECT (XW_XD (x_window_arg (1))));
1751 }
1752 
1753 DEFINE_PRIMITIVE ("X-WINDOW-X-SIZE", Prim_x_window_x_size, 1, 1, 0)
1754 {
1755   PRIMITIVE_HEADER (1);
1756   PRIMITIVE_RETURN (ulong_to_integer (XW_X_SIZE (x_window_arg (1))));
1757 }
1758 
1759 DEFINE_PRIMITIVE ("X-WINDOW-Y-SIZE", Prim_x_window_y_size, 1, 1, 0)
1760 {
1761   PRIMITIVE_HEADER (1);
1762   PRIMITIVE_RETURN (ulong_to_integer (XW_Y_SIZE (x_window_arg (1))));
1763 }
1764 
1765 DEFINE_PRIMITIVE ("X-WINDOW-BEEP", Prim_x_window_beep, 1, 1, 0)
1766 {
1767   PRIMITIVE_HEADER (1);
1768   XBell ((XW_DISPLAY (x_window_arg (1))), 0); /* base value */
1769   PRIMITIVE_RETURN (UNSPECIFIC);
1770 }
1771 
1772 DEFINE_PRIMITIVE ("X-WINDOW-CLEAR", Prim_x_window_clear, 1, 1, 0)
1773 {
1774   PRIMITIVE_HEADER (1);
1775   {
1776     struct xwindow * xw = (x_window_arg (1));
1777     if (((XW_CLIP_X (xw)) == 0)
1778 	&& ((XW_CLIP_Y (xw)) == 0)
1779 	&& ((XW_CLIP_WIDTH (xw)) == (XW_X_SIZE (xw)))
1780 	&& ((XW_CLIP_HEIGHT (xw)) == (XW_Y_SIZE (xw))))
1781       XClearWindow ((XW_DISPLAY (xw)), (XW_WINDOW (xw)));
1782     else
1783       XClearArea ((XW_DISPLAY (xw)),
1784 		  (XW_WINDOW (xw)),
1785 		  ((XW_CLIP_X (xw)) + (XW_INTERNAL_BORDER_WIDTH (xw))),
1786 		  ((XW_CLIP_Y (xw)) + (XW_INTERNAL_BORDER_WIDTH (xw))),
1787 		  (XW_CLIP_WIDTH (xw)),
1788 		  (XW_CLIP_HEIGHT (xw)),
1789 		  False);
1790   }
1791   PRIMITIVE_RETURN (UNSPECIFIC);
1792 }
1793 
1794 DEFINE_PRIMITIVE ("X-DISPLAY-FLUSH", Prim_x_display_flush, 1, 1, 0)
1795 {
1796   PRIMITIVE_HEADER (1);
1797   XFlush (XD_DISPLAY (x_display_arg (1)));
1798   PRIMITIVE_RETURN (UNSPECIFIC);
1799 }
1800 
1801 DEFINE_PRIMITIVE ("X-WINDOW-FLUSH", Prim_x_window_flush, 1, 1, 0)
1802 {
1803   PRIMITIVE_HEADER (1);
1804   XFlush (XW_DISPLAY (x_window_arg (1)));
1805   PRIMITIVE_RETURN (UNSPECIFIC);
1806 }
1807 
1808 DEFINE_PRIMITIVE ("X-DISPLAY-SYNC", Prim_x_display_sync, 2, 2, 0)
1809 {
1810   PRIMITIVE_HEADER (2);
1811   XSync ((XD_DISPLAY (x_display_arg (1))), (BOOLEAN_ARG (2)));
1812   PRIMITIVE_RETURN (UNSPECIFIC);
1813 }
1814 
1815 DEFINE_PRIMITIVE ("X-DISPLAY-GET-DEFAULT", Prim_x_display_get_default, 3, 3, 0)
1816 {
1817   PRIMITIVE_HEADER (3);
1818   {
1819     char * result
1820       = (XGetDefault ((XD_DISPLAY (x_display_arg (1))),
1821 		      (STRING_ARG (2)),
1822 		      (STRING_ARG (3))));
1823     PRIMITIVE_RETURN
1824       ((result == 0)
1825        ? SHARP_F
1826        : (char_pointer_to_string (result)));
1827   }
1828 }
1829 
1830 DEFINE_PRIMITIVE ("X-WINDOW-COORDS-ROOT->LOCAL", Prim_x_window_coords_root2local, 3, 3, 0)
1831 {
1832   PRIMITIVE_HEADER (3);
1833   {
1834     SCHEME_OBJECT result = (cons (SHARP_F, SHARP_F));
1835     struct xwindow * xw = (x_window_arg (1));
1836     Display * display = (XW_DISPLAY (xw));
1837     int rx = (arg_integer (2));
1838     int ry = (arg_integer (3));
1839     int wx;
1840     int wy;
1841     Window child;
1842     if (! (XTranslateCoordinates
1843 	   (display,
1844 	    (RootWindow (display, (DefaultScreen (display)))),
1845 	    (XW_WINDOW (xw)),
1846 	    rx, ry, (&wx), (&wy), (&child))))
1847       error_bad_range_arg (1);
1848     SET_PAIR_CAR (result, (long_to_integer (wx)));
1849     SET_PAIR_CDR (result, (long_to_integer (wy)));
1850     PRIMITIVE_RETURN (result);
1851   }
1852 }
1853 
1854 DEFINE_PRIMITIVE ("X-WINDOW-COORDS-LOCAL->ROOT", Prim_x_window_coords_local2root, 3, 3, 0)
1855 {
1856   PRIMITIVE_HEADER (3);
1857   {
1858     SCHEME_OBJECT result = (cons (SHARP_F, SHARP_F));
1859     struct xwindow * xw = (x_window_arg (1));
1860     Display * display = (XW_DISPLAY (xw));
1861     int wx = (arg_integer (2));
1862     int wy = (arg_integer (3));
1863     int rx;
1864     int ry;
1865     Window child;
1866     if (! (XTranslateCoordinates
1867 	   (display,
1868 	    (XW_WINDOW (xw)),
1869 	    (RootWindow (display, (DefaultScreen (display)))),
1870 	    wx, wy, (&rx), (&ry), (&child))))
1871       error_bad_range_arg (1);
1872     SET_PAIR_CAR (result, (long_to_integer (rx)));
1873     SET_PAIR_CDR (result, (long_to_integer (ry)));
1874     PRIMITIVE_RETURN (result);
1875   }
1876 }
1877 
1878 DEFINE_PRIMITIVE ("X-WINDOW-QUERY-POINTER", Prim_x_window_query_pointer, 1, 1, 0)
1879 {
1880   PRIMITIVE_HEADER (1);
1881   {
1882     SCHEME_OBJECT result = (allocate_marked_vector (TC_VECTOR, 5, 1));
1883     struct xwindow * xw = (x_window_arg (1));
1884     Window root;
1885     Window child;
1886     int root_x;
1887     int root_y;
1888     int win_x;
1889     int win_y;
1890     unsigned int keys_buttons;
1891     if (!XQueryPointer ((XW_DISPLAY (xw)),
1892 			(XW_WINDOW (xw)),
1893 			(&root), (&child),
1894 			(&root_x), (&root_y),
1895 			(&win_x), (&win_y),
1896 			(&keys_buttons)))
1897       PRIMITIVE_RETURN (SHARP_F);
1898     VECTOR_SET (result, 0, (long_to_integer (root_x)));
1899     VECTOR_SET (result, 1, (long_to_integer (root_y)));
1900     VECTOR_SET (result, 2, (long_to_integer (win_x)));
1901     VECTOR_SET (result, 3, (long_to_integer (win_y)));
1902     VECTOR_SET (result, 4, (x_key_button_mask_to_scheme (keys_buttons)));
1903     PRIMITIVE_RETURN (result);
1904   }
1905 }
1906 
1907 DEFINE_PRIMITIVE ("X-WINDOW-ID", Prim_x_window_id, 1, 1, 0)
1908 {
1909   PRIMITIVE_HEADER (1);
1910   PRIMITIVE_RETURN (ulong_to_integer (XW_WINDOW (x_window_arg (1))));
1911 }
1912 
1913 DEFINE_PRIMITIVE ("X-ID->WINDOW", Prim_x_id_to_window, 2, 2, 0)
1914 {
1915   PRIMITIVE_HEADER (2);
1916   {
1917     struct xwindow * xw
1918       = (x_window_to_xw ((XD_DISPLAY (x_display_arg (1))),
1919 			 (arg_ulong_integer (2))));
1920     PRIMITIVE_RETURN ((xw == 0) ? SHARP_F : (XW_TO_OBJECT (xw)));
1921   }
1922 }
1923 
1924 /* Appearance Control Primitives */
1925 
1926 DEFINE_PRIMITIVE ("X-WINDOW-SET-FOREGROUND-COLOR", Prim_x_window_set_foreground_color, 2, 2, 0)
1927 {
1928   PRIMITIVE_HEADER (2);
1929   {
1930     struct xwindow * xw = (x_window_arg (1));
1931     Display * display = (XW_DISPLAY (xw));
1932     unsigned long foreground_pixel = (arg_window_color (2, display, xw));
1933     (XW_FOREGROUND_PIXEL (xw)) = foreground_pixel;
1934     XSetForeground (display, (XW_NORMAL_GC (xw)), foreground_pixel);
1935     XSetBackground (display, (XW_REVERSE_GC (xw)), foreground_pixel);
1936   }
1937   PRIMITIVE_RETURN (UNSPECIFIC);
1938 }
1939 
1940 DEFINE_PRIMITIVE ("X-WINDOW-SET-BACKGROUND-COLOR", Prim_x_window_set_background_color, 2, 2, 0)
1941 {
1942   PRIMITIVE_HEADER (2);
1943   {
1944     struct xwindow * xw = (x_window_arg (1));
1945     Display * display = (XW_DISPLAY (xw));
1946     unsigned long background_pixel = (arg_window_color (2, display, xw));
1947     (XW_BACKGROUND_PIXEL (xw)) = background_pixel;
1948     XSetWindowBackground (display, (XW_WINDOW (xw)), background_pixel);
1949     XSetBackground (display, (XW_NORMAL_GC (xw)), background_pixel);
1950     XSetForeground (display, (XW_REVERSE_GC (xw)), background_pixel);
1951     XSetForeground (display, (XW_CURSOR_GC (xw)), background_pixel);
1952     x_set_mouse_colors (display,
1953 			(xw_color_map (xw)),
1954 			(XW_MOUSE_CURSOR (xw)),
1955 			(XW_MOUSE_PIXEL (xw)),
1956 			background_pixel);
1957   }
1958   PRIMITIVE_RETURN (UNSPECIFIC);
1959 }
1960 
1961 DEFINE_PRIMITIVE ("X-WINDOW-SET-BORDER-COLOR", Prim_x_window_set_border_color, 2, 2, 0)
1962 {
1963   PRIMITIVE_HEADER (2);
1964   {
1965     struct xwindow * xw = (x_window_arg (1));
1966     Display * display = (XW_DISPLAY (xw));
1967     unsigned long border_pixel = (arg_window_color (2, display, xw));
1968     (XW_BORDER_PIXEL (xw)) = border_pixel;
1969     XSetWindowBorder (display, (XW_WINDOW (xw)), border_pixel);
1970   }
1971   PRIMITIVE_RETURN (UNSPECIFIC);
1972 }
1973 
1974 DEFINE_PRIMITIVE ("X-WINDOW-SET-CURSOR-COLOR", Prim_x_window_set_cursor_color, 2, 2, 0)
1975 {
1976   PRIMITIVE_HEADER (2);
1977   {
1978     struct xwindow * xw = (x_window_arg (1));
1979     Display * display = (XW_DISPLAY (xw));
1980     unsigned long cursor_pixel = (arg_window_color (2, display, xw));
1981     (XW_CURSOR_PIXEL (xw)) = cursor_pixel;
1982     XSetBackground (display, (XW_CURSOR_GC (xw)), cursor_pixel);
1983   }
1984   PRIMITIVE_RETURN (UNSPECIFIC);
1985 }
1986 
1987 DEFINE_PRIMITIVE ("X-WINDOW-SET-MOUSE-COLOR", Prim_x_window_set_mouse_color, 2, 2, 0)
1988 {
1989   PRIMITIVE_HEADER (2);
1990   {
1991     struct xwindow * xw = (x_window_arg (1));
1992     Display * display = (XW_DISPLAY (xw));
1993     unsigned long mouse_pixel = (arg_window_color (2, display, xw));
1994     (XW_MOUSE_PIXEL (xw)) = mouse_pixel;
1995     x_set_mouse_colors (display,
1996 			(xw_color_map (xw)),
1997 			(XW_MOUSE_CURSOR (xw)),
1998 			mouse_pixel,
1999 			(XW_BACKGROUND_PIXEL (xw)));
2000   }
2001   PRIMITIVE_RETURN (UNSPECIFIC);
2002 }
2003 
2004 DEFINE_PRIMITIVE ("X-WINDOW-SET-MOUSE-SHAPE", Prim_x_window_set_mouse_shape, 2, 2, 0)
2005 {
2006   PRIMITIVE_HEADER (2);
2007   {
2008     struct xwindow * xw = (x_window_arg (1));
2009     Display * display = (XW_DISPLAY (xw));
2010     Window window = (XW_WINDOW (xw));
2011     {
2012       Cursor old_cursor = (XW_MOUSE_CURSOR (xw));
2013       Cursor mouse_cursor
2014 	= (XCreateFontCursor
2015 	   (display, (2 * (arg_index_integer (2, (XC_num_glyphs / 2))))));
2016       x_set_mouse_colors (display,
2017 			  (xw_color_map (xw)),
2018 			  mouse_cursor,
2019 			  (XW_MOUSE_PIXEL (xw)),
2020 			  (XW_BACKGROUND_PIXEL (xw)));
2021       (XW_MOUSE_CURSOR (xw)) = mouse_cursor;
2022       XDefineCursor (display, window, mouse_cursor);
2023       XFreeCursor (display, old_cursor);
2024     }
2025   }
2026   PRIMITIVE_RETURN (UNSPECIFIC);
2027 }
2028 
2029 DEFINE_PRIMITIVE ("X-WINDOW-SET-FONT", Prim_x_window_set_font, 2, 2, 0)
2030 {
2031   PRIMITIVE_HEADER (2);
2032   {
2033     struct xwindow * xw = (x_window_arg (1));
2034     Display * display = (XW_DISPLAY (xw));
2035     XFontStruct * font = (XLoadQueryFont (display, (STRING_ARG (2))));
2036     if (font == 0)
2037       PRIMITIVE_RETURN (SHARP_F);
2038     XFreeFont (display, (XW_FONT (xw)));
2039     (XW_FONT (xw)) = font;
2040     {
2041       Font fid = (font->fid);
2042       XSetFont (display, (XW_NORMAL_GC (xw)), fid);
2043       XSetFont (display, (XW_REVERSE_GC (xw)), fid);
2044       XSetFont (display, (XW_CURSOR_GC (xw)), fid);
2045     }
2046     if ((XW_UPDATE_NORMAL_HINTS (xw)) != 0)
2047       (* (XW_UPDATE_NORMAL_HINTS (xw))) (xw);
2048   }
2049   PRIMITIVE_RETURN (SHARP_T);
2050 }
2051 
2052 DEFINE_PRIMITIVE ("X-WINDOW-SET-BORDER-WIDTH", Prim_x_window_set_border_width, 2, 2, 0)
2053 {
2054   PRIMITIVE_HEADER (2);
2055   {
2056     struct xwindow * xw = (x_window_arg (1));
2057     Display * display = (XW_DISPLAY (xw));
2058     unsigned int border_width = (arg_nonnegative_integer (2));
2059     (XW_BORDER_WIDTH (xw)) = border_width;
2060     XSetWindowBorderWidth (display, (XW_WINDOW (xw)), border_width);
2061   }
2062   PRIMITIVE_RETURN (UNSPECIFIC);
2063 }
2064 
2065 DEFINE_PRIMITIVE ("X-WINDOW-SET-INTERNAL-BORDER-WIDTH", Prim_x_window_set_internal_border_width, 2, 2, 0)
2066 {
2067   PRIMITIVE_HEADER (2);
2068   {
2069     struct xwindow * xw = (x_window_arg (1));
2070     unsigned int internal_border_width = (arg_nonnegative_integer (2));
2071     (XW_INTERNAL_BORDER_WIDTH (xw)) = internal_border_width;
2072     if ((XW_UPDATE_NORMAL_HINTS (xw)) != 0)
2073       (* (XW_UPDATE_NORMAL_HINTS (xw))) (xw);
2074     XResizeWindow ((XW_DISPLAY (xw)),
2075 		   (XW_WINDOW (xw)),
2076 		   ((XW_X_SIZE (xw)) + (2 * internal_border_width)),
2077 		   ((XW_Y_SIZE (xw)) + (2 * internal_border_width)));
2078   }
2079   PRIMITIVE_RETURN (UNSPECIFIC);
2080 }
2081 
2082 /* WM Communication Primitives */
2083 
2084 DEFINE_PRIMITIVE ("X-WINDOW-SET-NAME", Prim_x_window_set_name, 2, 2,
2085   "Set the name of WINDOW to STRING.")
2086 {
2087   PRIMITIVE_HEADER (2);
2088   xw_set_wm_name ((x_window_arg (1)), (STRING_ARG (2)));
2089   PRIMITIVE_RETURN (UNSPECIFIC);
2090 }
2091 
2092 DEFINE_PRIMITIVE ("X-WINDOW-SET-ICON-NAME", Prim_x_window_set_icon_name, 2, 2,
2093   "Set the icon name of WINDOW to STRING.")
2094 {
2095   PRIMITIVE_HEADER (2);
2096   xw_set_wm_icon_name ((x_window_arg (1)), (STRING_ARG (2)));
2097   PRIMITIVE_RETURN (UNSPECIFIC);
2098 }
2099 
2100 DEFINE_PRIMITIVE ("X-WINDOW-SET-CLASS-HINT", Prim_x_window_set_class_hint, 3, 3,
2101   "Set the class hint of WINDOW to RESOURCE_NAME and RESOURCE_CLASS.")
2102 {
2103   PRIMITIVE_HEADER (3);
2104   xw_set_class_hint ((x_window_arg (1)), (STRING_ARG (2)), (STRING_ARG (3)));
2105   PRIMITIVE_RETURN (UNSPECIFIC);
2106 }
2107 
2108 DEFINE_PRIMITIVE ("X-WINDOW-SET-INPUT-HINT", Prim_x_window_set_input_hint, 2, 2,
2109   "Set the input hint of WINDOW to INPUT.")
2110 {
2111   PRIMITIVE_HEADER (2);
2112   xw_set_wm_input_hint ((x_window_arg (1)), (BOOLEAN_ARG (2)));
2113   PRIMITIVE_RETURN (UNSPECIFIC);
2114 }
2115 
2116 DEFINE_PRIMITIVE ("X-WINDOW-SET-INPUT-FOCUS", Prim_x_window_set_input_focus, 2, 2, 0)
2117 {
2118   PRIMITIVE_HEADER (2);
2119   {
2120     struct xwindow * xw = (x_window_arg (1));
2121     Display * display = (XW_DISPLAY (xw));
2122     void * handle = (push_x_error_info (display));
2123 
2124     XSetInputFocus (display,
2125 		    (XW_WINDOW (xw)),
2126 		    RevertToParent,
2127 		    ((Time) (arg_ulong_integer (2))));
2128     if (any_x_errors_p (display))
2129       {
2130 	pop_x_error_info (handle);
2131 	error_bad_range_arg (1);
2132       }
2133     pop_x_error_info (handle);
2134   }
2135   PRIMITIVE_RETURN (UNSPECIFIC);
2136 }
2137 
2138 DEFINE_PRIMITIVE ("X-WINDOW-SET-TRANSIENT-FOR-HINT", Prim_x_window_set_transient_for, 2, 2,
2139   "Set the transient-for hint of WINDOW to PRIMARY-WINDOW.")
2140 {
2141   PRIMITIVE_HEADER (2);
2142   {
2143     struct xwindow * xw = (x_window_arg (1));
2144     struct xwindow * transient_for = (x_window_arg (2));
2145     if ((xw == transient_for) || ((XW_XD (xw)) != (XW_XD (transient_for))))
2146       error_bad_range_arg (2);
2147     XSetTransientForHint
2148       ((XW_DISPLAY (xw)),
2149        (XW_WINDOW (xw)),
2150        (XW_WINDOW (transient_for)));
2151   }
2152   PRIMITIVE_RETURN (UNSPECIFIC);
2153 }
2154 
2155 /* WM Control Primitives */
2156 
2157 DEFINE_PRIMITIVE ("X-WINDOW-MAP", Prim_x_window_map, 1, 1, 0)
2158 {
2159   PRIMITIVE_HEADER (1);
2160   {
2161     struct xwindow * xw = (x_window_arg (1));
2162     XMapWindow ((XW_DISPLAY (xw)), (XW_WINDOW (xw)));
2163   }
2164   PRIMITIVE_RETURN (UNSPECIFIC);
2165 }
2166 
2167 DEFINE_PRIMITIVE ("X-WINDOW-ICONIFY", Prim_x_window_iconify, 1, 1, 0)
2168 {
2169   PRIMITIVE_HEADER (1);
2170   {
2171     struct xwindow * xw = (x_window_arg (1));
2172     Display * display = (XW_DISPLAY (xw));
2173     XIconifyWindow (display, (XW_WINDOW (xw)), (DefaultScreen (display)));
2174   }
2175   PRIMITIVE_RETURN (UNSPECIFIC);
2176 }
2177 
2178 DEFINE_PRIMITIVE ("X-WINDOW-WITHDRAW", Prim_x_window_withdraw, 1, 1, 0)
2179 {
2180   PRIMITIVE_HEADER (1);
2181   {
2182     struct xwindow * xw = (x_window_arg (1));
2183     Display * display = (XW_DISPLAY (xw));
2184     XWithdrawWindow (display, (XW_WINDOW (xw)), (DefaultScreen (display)));
2185   }
2186   PRIMITIVE_RETURN (UNSPECIFIC);
2187 }
2188 
2189 /* The following shouldn't be used on top-level windows.  Instead use
2190    ICONIFY or WITHDRAW.  */
2191 DEFINE_PRIMITIVE ("X-WINDOW-UNMAP", Prim_x_window_unmap, 1, 1, 0)
2192 {
2193   PRIMITIVE_HEADER (1);
2194   {
2195     struct xwindow * xw = (x_window_arg (1));
2196     XUnmapWindow ((XW_DISPLAY (xw)), (XW_WINDOW (xw)));
2197   }
2198   PRIMITIVE_RETURN (UNSPECIFIC);
2199 }
2200 
2201 DEFINE_PRIMITIVE ("X-WINDOW-SET-SIZE", Prim_x_window_set_size, 3, 3, 0)
2202 {
2203   PRIMITIVE_HEADER (3);
2204   {
2205     struct xwindow * xw = (x_window_arg (1));
2206     unsigned int extra = (2 * (XW_INTERNAL_BORDER_WIDTH (xw)));
2207     XResizeWindow ((XW_DISPLAY (xw)),
2208 		   (XW_WINDOW (xw)),
2209 		   ((arg_ulong_integer (2)) + extra),
2210 		   ((arg_ulong_integer (3)) + extra));
2211   }
2212   PRIMITIVE_RETURN (UNSPECIFIC);
2213 }
2214 
2215 DEFINE_PRIMITIVE ("X-WINDOW-RAISE", Prim_x_window_raise, 1, 1, 0)
2216 {
2217   PRIMITIVE_HEADER (1);
2218   {
2219     struct xwindow * xw = (x_window_arg (1));
2220     XRaiseWindow ((XW_DISPLAY (xw)), (XW_WINDOW (xw)));
2221   }
2222   PRIMITIVE_RETURN (UNSPECIFIC);
2223 }
2224 
2225 DEFINE_PRIMITIVE ("X-WINDOW-LOWER", Prim_x_window_lower, 1, 1, 0)
2226 {
2227   PRIMITIVE_HEADER (1);
2228   {
2229     struct xwindow * xw = (x_window_arg (1));
2230     XLowerWindow ((XW_DISPLAY (xw)), (XW_WINDOW (xw)));
2231   }
2232   PRIMITIVE_RETURN (UNSPECIFIC);
2233 }
2234 
2235 DEFINE_PRIMITIVE ("X-WINDOW-GET-SIZE", Prim_x_window_get_size, 1, 1, 0)
2236 {
2237   PRIMITIVE_HEADER (1);
2238   {
2239     struct xwindow * xw = (x_window_arg (1));
2240     unsigned int extra;
2241 
2242     get_wm_decor_geometry (xw);
2243     extra = (2 * (XW_WM_DECOR_BORDER_WIDTH (xw)));
2244     PRIMITIVE_RETURN
2245       (cons ((ulong_to_integer ((XW_WM_DECOR_PIXEL_WIDTH (xw)) + extra)),
2246 	     (ulong_to_integer ((XW_WM_DECOR_PIXEL_HEIGHT (xw)) + extra))));
2247   }
2248 }
2249 
2250 DEFINE_PRIMITIVE ("X-WINDOW-GET-POSITION", Prim_x_window_get_position, 1, 1, 0)
2251 {
2252   PRIMITIVE_HEADER (1);
2253   {
2254     struct xwindow * xw = (x_window_arg (1));
2255     get_wm_decor_geometry (xw);
2256     PRIMITIVE_RETURN (cons ((long_to_integer (XW_WM_DECOR_X (xw))),
2257 			    (long_to_integer (XW_WM_DECOR_Y (xw)))));
2258   }
2259 }
2260 
2261 DEFINE_PRIMITIVE ("X-WINDOW-SET-POSITION", Prim_x_window_set_position, 3, 3, 0)
2262 {
2263   PRIMITIVE_HEADER (3);
2264   move_window ((x_window_arg (1)),
2265 	       (arg_integer (2)),
2266 	       (arg_integer (3)));
2267   PRIMITIVE_RETURN (UNSPECIFIC);
2268 }
2269 
2270 static void
move_window(struct xwindow * xw,int x,int y)2271 move_window (struct xwindow * xw, int x, int y)
2272 {
2273   if ((XW_UPDATE_NORMAL_HINTS (xw)) != 0)
2274     (* (XW_UPDATE_NORMAL_HINTS (xw))) (xw);
2275   if ((XW_WM_TYPE (xw)) == X_WMTYPE_A)
2276     {
2277       x += (XW_MOVE_OFFSET_X (xw));
2278       y += (XW_MOVE_OFFSET_Y (xw));
2279     }
2280   XMoveWindow ((XW_DISPLAY (xw)), (XW_WINDOW (xw)), x, y);
2281   if ((XW_WM_TYPE (xw)) == X_WMTYPE_UNKNOWN)
2282     {
2283       (XW_EXPECTED_X (xw)) = x;
2284       (XW_EXPECTED_Y (xw)) = y;
2285       (XW_CHECK_EXPECTED_MOVE_P (xw)) = 1;
2286     }
2287 }
2288 
2289 static void
check_expected_move(struct xwindow * xw)2290 check_expected_move (struct xwindow * xw)
2291 {
2292   if (((XW_WM_DECOR_X (xw)) == (XW_EXPECTED_X (xw)))
2293       && ((XW_WM_DECOR_Y (xw)) == (XW_EXPECTED_Y (xw))))
2294     {
2295       if ((XW_WM_TYPE (xw)) == X_WMTYPE_UNKNOWN)
2296 	(XW_WM_TYPE (xw)) = X_WMTYPE_B;
2297     }
2298   else
2299     {
2300       (XW_WM_TYPE (xw)) = X_WMTYPE_A;
2301       (XW_MOVE_OFFSET_X (xw)) = ((XW_EXPECTED_X (xw)) - (XW_WM_DECOR_X (xw)));
2302       (XW_MOVE_OFFSET_Y (xw)) = ((XW_EXPECTED_Y (xw)) - (XW_WM_DECOR_Y (xw)));
2303       move_window (xw, (XW_EXPECTED_X (xw)), (XW_EXPECTED_Y (xw)));
2304     }
2305   (XW_CHECK_EXPECTED_MOVE_P (xw)) = 0;
2306 }
2307 
2308 /* Font Structure Primitive */
2309 
2310 #define FONT_STRUCTURE_MAX_CONVERTED_SIZE (10+1 + 256+1 + ((5+1) * (256+2)))
2311   /* font-structure-words +
2312      char-struct-vector +
2313      char-struct-words * maximum-number-possible */
2314 
2315 static SCHEME_OBJECT
convert_char_struct(XCharStruct * char_struct)2316 convert_char_struct (XCharStruct * char_struct)
2317 {
2318   if (((char_struct->lbearing) == 0)
2319       && ((char_struct->rbearing) == 0)
2320       && ((char_struct->width) == 0)
2321       && ((char_struct->ascent) == 0)
2322       && ((char_struct->descent) == 0))
2323     return (SHARP_F);
2324   {
2325     SCHEME_OBJECT result = (allocate_marked_vector (TC_VECTOR, 5, true));
2326     VECTOR_SET (result, 0, (long_to_integer (char_struct->lbearing)));
2327     VECTOR_SET (result, 1, (long_to_integer (char_struct->rbearing)));
2328     VECTOR_SET (result, 2, (long_to_integer (char_struct->width)));
2329     VECTOR_SET (result, 3, (long_to_integer (char_struct->ascent)));
2330     VECTOR_SET (result, 4, (long_to_integer (char_struct->descent)));
2331     return (result);
2332   }
2333 }
2334 
2335 static SCHEME_OBJECT
convert_font_struct(SCHEME_OBJECT font_name,XFontStruct * font)2336 convert_font_struct (SCHEME_OBJECT font_name, XFontStruct * font)
2337 {
2338   SCHEME_OBJECT result;
2339   if (font == 0)
2340     return  SHARP_F;
2341   /* Handle only 8-bit fonts because of laziness. */
2342   if (((font->min_byte1) != 0) || ((font->max_byte1) != 0))
2343     return  SHARP_F;
2344 
2345   result = (allocate_marked_vector (TC_VECTOR, 10, true));
2346   if ((font->per_char) == 0)
2347     VECTOR_SET (result, 6, SHARP_F);
2348   else
2349     {
2350       unsigned int start_index = (font->min_char_or_byte2);
2351       unsigned int length = ((font->max_char_or_byte2) - start_index + 1);
2352       SCHEME_OBJECT character_vector
2353 	= (allocate_marked_vector (TC_VECTOR, length, true));
2354       unsigned int index;
2355       for (index = 0; (index < length); index += 1)
2356 	VECTOR_SET (character_vector,
2357 		    index,
2358 		    (convert_char_struct ((font->per_char) + index)));
2359       VECTOR_SET (result, 6, (ulong_to_integer (start_index)));
2360       VECTOR_SET (result, 7, character_vector);
2361     }
2362   VECTOR_SET (result, 0, font_name);
2363   VECTOR_SET (result, 1, (ulong_to_integer (font->direction)));
2364   VECTOR_SET (result, 2,
2365 	      (BOOLEAN_TO_OBJECT ((font->all_chars_exist) == True)));
2366   VECTOR_SET (result, 3, (ulong_to_integer (font->default_char)));
2367   VECTOR_SET (result, 4, (convert_char_struct (& (font->min_bounds))));
2368   VECTOR_SET (result, 5, (convert_char_struct (& (font->max_bounds))));
2369   VECTOR_SET (result, 8, (long_to_integer (font->ascent)));
2370   VECTOR_SET (result, 9, (long_to_integer (font->descent)));
2371 
2372   return  result;
2373 }
2374 
2375 DEFINE_PRIMITIVE ("X-FONT-STRUCTURE", Prim_x_font_structure, 2, 2,
2376 		  "(DISPLAY FONT)\n\
2377 FONT is either a font name or a font ID.")
2378 {
2379   PRIMITIVE_HEADER (2);
2380   Primitive_GC_If_Needed (FONT_STRUCTURE_MAX_CONVERTED_SIZE);
2381   {
2382     SCHEME_OBJECT font_name = (ARG_REF (2));
2383     Display * display = (XD_DISPLAY (x_display_arg (1)));
2384     XFontStruct * font = 0;
2385     bool by_name = STRING_P (font_name);
2386     SCHEME_OBJECT result;
2387 
2388     if (by_name)
2389       font = XLoadQueryFont (display, (STRING_POINTER (font_name)));
2390     else
2391       font = XQueryFont (display, ((XID) (integer_to_ulong (ARG_REF (2)))));
2392 
2393     if (font == 0)
2394       PRIMITIVE_RETURN (SHARP_F);
2395 
2396     result = convert_font_struct (font_name, font);
2397 
2398     if (by_name)
2399       XFreeFont (display, font);
2400     PRIMITIVE_RETURN (result);
2401   }
2402 }
2403 
2404 DEFINE_PRIMITIVE ("X-WINDOW-FONT-STRUCTURE", Prim_x_window_font_structure, 1, 1,
2405   "(X-WINDOW)\n\
2406 Returns the font-structure for the font currently associated with X-WINDOW.")
2407 {
2408   XFontStruct *font;
2409   PRIMITIVE_HEADER (1);
2410   Primitive_GC_If_Needed (FONT_STRUCTURE_MAX_CONVERTED_SIZE);
2411   font = XW_FONT (x_window_arg (1));
2412   PRIMITIVE_RETURN (convert_font_struct (ulong_to_integer (font->fid), font));
2413 }
2414 
2415 DEFINE_PRIMITIVE ("X-LIST-FONTS", Prim_x_list_fonts, 3, 3,
2416 		  "(DISPLAY PATTERN LIMIT)\n\
2417 LIMIT is an exact non-negative integer or #F for no limit.\n\
2418 Returns #F or a vector of at least one string.")
2419 {
2420   PRIMITIVE_HEADER (1);
2421   {
2422     int actual_count = 0;
2423     char ** names
2424       = (XListFonts ((XD_DISPLAY (x_display_arg (1))),
2425 		     (STRING_ARG (2)),
2426 		     ((FIXNUM_P (ARG_REF (3)))
2427 		      ? (FIXNUM_TO_LONG (ARG_REF (3)))
2428 		      : 1000000),
2429 		     (&actual_count)));
2430     if (names == 0)
2431       PRIMITIVE_RETURN (SHARP_F);
2432     {
2433       unsigned int words = (actual_count + 1); /* the vector of strings */
2434       unsigned int i;
2435       for (i = 0; (i < actual_count); i += 1)
2436 	words += (STRING_LENGTH_TO_GC_LENGTH (strlen (names[i])));
2437       if (GC_NEEDED_P (words))
2438 	{
2439 	  /* this causes the primitive to be restarted, so deallocate names */
2440 	  XFreeFontNames (names);
2441 	  Primitive_GC (words);
2442 	  /* notreached */
2443 	}
2444     }
2445     {
2446       SCHEME_OBJECT result
2447 	= (allocate_marked_vector (TC_VECTOR, actual_count, false));
2448       unsigned int i;
2449       for (i = 0;  (i < actual_count);  i += 1)
2450 	VECTOR_SET (result, i, (char_pointer_to_string (names[i])));
2451       XFreeFontNames (names);
2452       PRIMITIVE_RETURN (result);
2453     }
2454   }
2455 }
2456 
2457 /* Atoms */
2458 
2459 DEFINE_PRIMITIVE ("X-INTERN-ATOM", Prim_x_intern_atom, 3, 3, 0)
2460 {
2461   PRIMITIVE_HEADER (3);
2462   PRIMITIVE_RETURN
2463     (ulong_to_integer (XInternAtom ((XD_DISPLAY (x_display_arg (1))),
2464 				    (STRING_ARG (2)),
2465 				    (BOOLEAN_ARG (3)))));
2466 }
2467 
2468 DEFINE_PRIMITIVE ("X-GET-ATOM-NAME", Prim_x_get_atom_name, 2, 2, 0)
2469 {
2470   PRIMITIVE_HEADER (2);
2471   {
2472     struct xdisplay * xd = (x_display_arg (1));
2473     Display * display = (XD_DISPLAY (xd));
2474     void * handle = (push_x_error_info (display));
2475     char * name = (XGetAtomName (display, (arg_ulong_integer (2))));
2476     unsigned char error_code = (x_error_code (display));
2477     SCHEME_OBJECT result
2478       = ((error_code == 0)
2479 	 ? (char_pointer_to_string (name))
2480 	 : (ulong_to_integer (error_code)));
2481     if (name != 0)
2482       XFree (name);
2483     pop_x_error_info (handle);
2484     PRIMITIVE_RETURN (result);
2485   }
2486 }
2487 
2488 /* Window Properties */
2489 
2490 static SCHEME_OBJECT
char_ptr_to_prop_data_32(const unsigned char * data,unsigned long nitems)2491 char_ptr_to_prop_data_32 (const unsigned char * data, unsigned long nitems)
2492 {
2493   SCHEME_OBJECT result = (allocate_marked_vector (TC_VECTOR, nitems, 1));
2494   unsigned long index;
2495   for (index = 0; (index < nitems); index += 1)
2496     VECTOR_SET (result, index, (ulong_to_integer (((CARD32 *) data) [index])));
2497   return (result);
2498 }
2499 
2500 static SCHEME_OBJECT
char_ptr_to_prop_data_16(const unsigned char * data,unsigned long nitems)2501 char_ptr_to_prop_data_16 (const unsigned char * data, unsigned long nitems)
2502 {
2503   SCHEME_OBJECT result = (allocate_marked_vector (TC_VECTOR, nitems, 1));
2504   unsigned long index;
2505   for (index = 0; (index < nitems); index += 1)
2506     VECTOR_SET (result, index, (ulong_to_integer (((CARD16 *) data) [index])));
2507   return (result);
2508 }
2509 
2510 static const unsigned char *
prop_data_32_to_char_ptr(SCHEME_OBJECT vector,unsigned long * length_return)2511 prop_data_32_to_char_ptr (SCHEME_OBJECT vector, unsigned long * length_return)
2512 {
2513   unsigned long nitems = (VECTOR_LENGTH (vector));
2514   unsigned long length = (nitems * 4);
2515   unsigned char * data = (dstack_alloc (length));
2516   unsigned long index;
2517   for (index = 0; (index < nitems); index += 1)
2518     {
2519       SCHEME_OBJECT n = (VECTOR_REF (vector, index));
2520       if (!integer_to_ulong_p (n))
2521 	return (0);
2522       (((CARD32 *) data) [index]) = (integer_to_ulong (n));
2523     }
2524   (*length_return) = length;
2525   return (data);
2526 }
2527 
2528 static const unsigned char *
prop_data_16_to_char_ptr(SCHEME_OBJECT vector,unsigned long * length_return)2529 prop_data_16_to_char_ptr (SCHEME_OBJECT vector, unsigned long * length_return)
2530 {
2531   unsigned long nitems = (VECTOR_LENGTH (vector));
2532   unsigned long length = (nitems * 2);
2533   unsigned char * data = (dstack_alloc (length));
2534   unsigned long index;
2535   for (index = 0; (index < nitems); index += 1)
2536     {
2537       SCHEME_OBJECT n = (VECTOR_REF (vector, index));
2538       unsigned long un;
2539       if (!integer_to_ulong_p (n))
2540 	return (0);
2541       un = (integer_to_ulong (n));
2542       if (un >= 65536)
2543 	return (0);
2544       (((CARD16 *) data) [index]) = un;
2545     }
2546   (*length_return) = length;
2547   return (data);
2548 }
2549 
2550 DEFINE_PRIMITIVE ("X-GET-WINDOW-PROPERTY", Prim_x_get_window_property, 7, 7, 0)
2551 {
2552   PRIMITIVE_HEADER (7);
2553   {
2554     Display * display = (XD_DISPLAY (x_display_arg (1)));
2555     Window window = (arg_ulong_integer (2));
2556     Atom property = (arg_ulong_integer (3));
2557     long long_offset = (arg_nonnegative_integer (4));
2558     long long_length = (arg_nonnegative_integer (5));
2559     Bool delete = (BOOLEAN_ARG (6));
2560     Atom req_type = (arg_ulong_integer (7));
2561 
2562     Atom actual_type;
2563     int actual_format;
2564     unsigned long nitems;
2565     unsigned long bytes_after;
2566     unsigned char * data;
2567 
2568     if ((XGetWindowProperty (display, window, property, long_offset,
2569 			     long_length, delete, req_type, (&actual_type),
2570 			     (&actual_format), (&nitems), (&bytes_after),
2571 			     (&data)))
2572 	!= Success)
2573       error_external_return ();
2574     if (actual_format == 0)
2575       {
2576 	XFree (data);
2577 	PRIMITIVE_RETURN (SHARP_F);
2578       }
2579     if (! ((actual_format == 8)
2580 	   || (actual_format == 16)
2581 	   || (actual_format == 32)))
2582       error_external_return ();
2583     {
2584       SCHEME_OBJECT result = (allocate_marked_vector (TC_VECTOR, 4, 1));
2585       VECTOR_SET (result, 0, (ulong_to_integer (actual_type)));
2586       VECTOR_SET (result, 1, (long_to_integer (actual_format)));
2587       VECTOR_SET (result, 2, (ulong_to_integer (bytes_after)));
2588       VECTOR_SET (result, 3,
2589 		  (((req_type != AnyPropertyType)
2590 		    && (req_type != actual_type))
2591 		   ? SHARP_F
2592 		   : (actual_format == 32)
2593 		   ? (char_ptr_to_prop_data_32 (data, nitems))
2594 		   : (actual_format == 16)
2595 		   ? (char_ptr_to_prop_data_16 (data, nitems))
2596 		   : (memory_to_string (nitems, data))));
2597       XFree (data);
2598       PRIMITIVE_RETURN (result);
2599     }
2600   }
2601 }
2602 
2603 DEFINE_PRIMITIVE ("X-CHANGE-PROPERTY", Prim_x_change_property, 7, 7, 0)
2604 {
2605   PRIMITIVE_HEADER (7);
2606   {
2607     Display * display = (XD_DISPLAY (x_display_arg (1)));
2608     Window window = (arg_ulong_integer (2));
2609     Atom property = (arg_ulong_integer (3));
2610     Atom type = (arg_ulong_integer (4));
2611     int format = (arg_nonnegative_integer (5));
2612     int mode = (arg_index_integer (6, 3));
2613     unsigned long dlen = 0;
2614     const unsigned char * data = 0;
2615     void * handle;
2616     unsigned char error_code;
2617 
2618     handle = (push_x_error_info (display));
2619     switch (format)
2620       {
2621       case 8:
2622 	CHECK_ARG (7, STRING_P);
2623 	data = (STRING_BYTE_PTR (ARG_REF (7)));
2624 	dlen = (STRING_LENGTH (ARG_REF (7)));
2625 	break;
2626       case 16:
2627 	CHECK_ARG (7, VECTOR_P);
2628 	data = (prop_data_16_to_char_ptr ((ARG_REF (7)), (&dlen)));
2629 	if (data == 0)
2630 	  error_bad_range_arg (7);
2631 	break;
2632       case 32:
2633 	CHECK_ARG (7, VECTOR_P);
2634 	data = (prop_data_32_to_char_ptr ((ARG_REF (7)), (&dlen)));
2635 	if (data == 0)
2636 	  error_bad_range_arg (7);
2637 	break;
2638       default:
2639 	error_bad_range_arg (5);
2640 	break;
2641       }
2642     XChangeProperty (display, window, property, type, format, mode, data, dlen);
2643     error_code = (x_error_code (display));
2644     pop_x_error_info (handle);
2645     PRIMITIVE_RETURN (ulong_to_integer (error_code));
2646   }
2647 }
2648 
2649 DEFINE_PRIMITIVE ("X-DELETE-PROPERTY", Prim_x_delete_property, 3, 3, 0)
2650 {
2651   PRIMITIVE_HEADER (3);
2652   XDeleteProperty ((XD_DISPLAY (x_display_arg (1))),
2653 		   (arg_ulong_integer (2)),
2654 		   (arg_ulong_integer (3)));
2655   PRIMITIVE_RETURN (UNSPECIFIC);
2656 }
2657 
2658 /* Selections */
2659 
2660 DEFINE_PRIMITIVE ("X-SET-SELECTION-OWNER", Prim_x_set_selection_owner, 4, 4, 0)
2661 {
2662   PRIMITIVE_HEADER (4);
2663   XSetSelectionOwner ((XD_DISPLAY (x_display_arg (1))),
2664 		      (arg_ulong_integer (2)),
2665 		      (arg_ulong_integer (3)),
2666 		      (arg_ulong_integer (4)));
2667   PRIMITIVE_RETURN (UNSPECIFIC);
2668 }
2669 
2670 DEFINE_PRIMITIVE ("X-GET-SELECTION-OWNER", Prim_x_get_selection_owner, 2, 2, 0)
2671 {
2672   PRIMITIVE_HEADER (2);
2673   PRIMITIVE_RETURN
2674     (ulong_to_integer (XGetSelectionOwner ((XD_DISPLAY (x_display_arg (1))),
2675 					   (arg_ulong_integer (2)))));
2676 }
2677 
2678 DEFINE_PRIMITIVE ("X-CONVERT-SELECTION", Prim_x_convert_selection, 6, 6, 0)
2679 {
2680   PRIMITIVE_HEADER (6);
2681   XConvertSelection ((XD_DISPLAY (x_display_arg (1))),
2682 		     (arg_ulong_integer (2)),
2683 		     (arg_ulong_integer (3)),
2684 		     (arg_ulong_integer (4)),
2685 		     (arg_ulong_integer (5)),
2686 		     (arg_ulong_integer (6)));
2687   PRIMITIVE_RETURN (UNSPECIFIC);
2688 }
2689 
2690 DEFINE_PRIMITIVE ("X-SEND-SELECTION-NOTIFY", Prim_x_send_selection_notify, 6, 6, 0)
2691 {
2692   PRIMITIVE_HEADER (6);
2693   {
2694     struct xdisplay * xd = (x_display_arg (1));
2695     Window requestor = (arg_ulong_integer (2));
2696     XSelectionEvent event;
2697     (event.type) = SelectionNotify;
2698     (event.display) = (XD_DISPLAY (xd));
2699     (event.requestor) = requestor;
2700     (event.selection) = (arg_ulong_integer (3));
2701     (event.target) = (arg_ulong_integer (4));
2702     (event.property) = (arg_ulong_integer (5));
2703     (event.time) = (arg_ulong_integer (6));
2704     XSendEvent ((XD_DISPLAY (xd)), requestor, False, 0, ((XEvent *) (&event)));
2705   }
2706   PRIMITIVE_RETURN (UNSPECIFIC);
2707 }
2708 
2709 #ifdef COMPILE_AS_MODULE
2710 
2711 /* sed -n -e 's/^DEFINE_PRIMITIVE *(\([^)]*\))$/  declare_primitive (\1);/pg' \
2712      -e 's/^DEFINE_PRIMITIVE *(\([^)]*\)$/  declare_primitive (\1 0);/pg' */
2713 
2714 void
dload_initialize_x11base(void)2715 dload_initialize_x11base (void)
2716 {
2717   declare_primitive ("X-CHANGE-PROPERTY", Prim_x_change_property, 7, 7, 0);
2718   declare_primitive ("X-CLOSE-ALL-DISPLAYS", Prim_x_close_all_displays, 0, 0, 0);
2719   declare_primitive ("X-CLOSE-DISPLAY", Prim_x_close_display, 1, 1, 0);
2720   declare_primitive ("X-CLOSE-WINDOW", Prim_x_close_window, 1, 1, 0);
2721   declare_primitive ("X-CONVERT-SELECTION", Prim_x_convert_selection, 6, 6, 0);
2722   declare_primitive ("X-DEBUG", Prim_x_debug, 1, 1, 0);
2723   declare_primitive ("X-DELETE-PROPERTY", Prim_x_delete_property, 3, 3, 0);
2724   declare_primitive ("X-DISPLAY-DESCRIPTOR", Prim_x_display_descriptor, 1, 1, 0);
2725   declare_primitive ("X-DISPLAY-FLUSH", Prim_x_display_flush, 1, 1, 0);
2726   declare_primitive ("X-DISPLAY-GET-DEFAULT", Prim_x_display_get_default, 3, 3, 0);
2727   declare_primitive ("X-DISPLAY-GET-SIZE", Prim_x_display_get_size, 2, 2, 0);
2728   declare_primitive ("X-DISPLAY-PROCESS-EVENTS", Prim_x_display_process_events, 2, 2, 0);
2729   declare_primitive ("X-DISPLAY-SYNC", Prim_x_display_sync, 2, 2, 0);
2730   declare_primitive ("X-FONT-STRUCTURE", Prim_x_font_structure, 2, 2, 0);
2731   declare_primitive ("X-GET-ATOM-NAME", Prim_x_get_atom_name, 2, 2, 0);
2732   declare_primitive ("X-GET-SELECTION-OWNER", Prim_x_get_selection_owner, 2, 2, 0);
2733   declare_primitive ("X-GET-WINDOW-PROPERTY", Prim_x_get_window_property, 7, 7, 0);
2734   declare_primitive ("X-ID->WINDOW", Prim_x_id_to_window, 2, 2, 0);
2735   declare_primitive ("X-INTERN-ATOM", Prim_x_intern_atom, 3, 3, 0);
2736   declare_primitive ("X-LIST-FONTS", Prim_x_list_fonts, 3, 3, 0);
2737   declare_primitive ("X-MAX-REQUEST-SIZE", Prim_x_max_request_size, 1, 1, 0);
2738   declare_primitive ("X-OPEN-DISPLAY", Prim_x_open_display, 1, 1, 0);
2739   declare_primitive ("X-SELECT-INPUT", Prim_x_select_input, 3, 3, 0);
2740   declare_primitive ("X-SEND-SELECTION-NOTIFY", Prim_x_send_selection_notify, 6, 6, 0);
2741   declare_primitive ("X-SET-DEFAULT-FONT", Prim_x_set_default_font, 2, 2, 0);
2742   declare_primitive ("X-SET-SELECTION-OWNER", Prim_x_set_selection_owner, 4, 4, 0);
2743   declare_primitive ("X-WINDOW-ANDC-EVENT-MASK", Prim_x_window_andc_event_mask, 2, 2, 0);
2744   declare_primitive ("X-WINDOW-BEEP", Prim_x_window_beep, 1, 1, 0);
2745   declare_primitive ("X-WINDOW-CLEAR", Prim_x_window_clear, 1, 1, 0);
2746   declare_primitive ("X-WINDOW-COORDS-LOCAL->ROOT", Prim_x_window_coords_local2root, 3, 3, 0);
2747   declare_primitive ("X-WINDOW-COORDS-ROOT->LOCAL", Prim_x_window_coords_root2local, 3, 3, 0);
2748   declare_primitive ("X-WINDOW-DISPLAY", Prim_x_window_display, 1, 1, 0);
2749   declare_primitive ("X-WINDOW-EVENT-MASK", Prim_x_window_event_mask, 1, 1, 0);
2750   declare_primitive ("X-WINDOW-FLUSH", Prim_x_window_flush, 1, 1, 0);
2751   declare_primitive ("X-WINDOW-FONT-STRUCTURE", Prim_x_window_font_structure, 1, 1, 0);
2752   declare_primitive ("X-WINDOW-GET-POSITION", Prim_x_window_get_position, 1, 1, 0);
2753   declare_primitive ("X-WINDOW-GET-SIZE", Prim_x_window_get_size, 1, 1, 0);
2754   declare_primitive ("X-WINDOW-ICONIFY", Prim_x_window_iconify, 1, 1, 0);
2755   declare_primitive ("X-WINDOW-ID", Prim_x_window_id, 1, 1, 0);
2756   declare_primitive ("X-WINDOW-LOWER", Prim_x_window_lower, 1, 1, 0);
2757   declare_primitive ("X-WINDOW-MAP", Prim_x_window_map, 1, 1, 0);
2758   declare_primitive ("X-WINDOW-OR-EVENT-MASK", Prim_x_window_or_event_mask, 2, 2, 0);
2759   declare_primitive ("X-WINDOW-QUERY-POINTER", Prim_x_window_query_pointer, 1, 1, 0);
2760   declare_primitive ("X-WINDOW-RAISE", Prim_x_window_raise, 1, 1, 0);
2761   declare_primitive ("X-WINDOW-SET-BACKGROUND-COLOR", Prim_x_window_set_background_color, 2, 2, 0);
2762   declare_primitive ("X-WINDOW-SET-BORDER-COLOR", Prim_x_window_set_border_color, 2, 2, 0);
2763   declare_primitive ("X-WINDOW-SET-BORDER-WIDTH", Prim_x_window_set_border_width, 2, 2, 0);
2764   declare_primitive ("X-WINDOW-SET-CLASS-HINT", Prim_x_window_set_class_hint, 3, 3, 0);
2765   declare_primitive ("X-WINDOW-SET-CURSOR-COLOR", Prim_x_window_set_cursor_color, 2, 2, 0);
2766   declare_primitive ("X-WINDOW-SET-EVENT-MASK", Prim_x_window_set_event_mask, 2, 2, 0);
2767   declare_primitive ("X-WINDOW-SET-FONT", Prim_x_window_set_font, 2, 2, 0);
2768   declare_primitive ("X-WINDOW-SET-FOREGROUND-COLOR", Prim_x_window_set_foreground_color, 2, 2, 0);
2769   declare_primitive ("X-WINDOW-SET-ICON-NAME", Prim_x_window_set_icon_name, 2, 2, 0);
2770   declare_primitive ("X-WINDOW-SET-INPUT-FOCUS", Prim_x_window_set_input_focus, 2, 2, 0);
2771   declare_primitive ("X-WINDOW-SET-INPUT-HINT", Prim_x_window_set_input_hint, 2, 2, 0);
2772   declare_primitive ("X-WINDOW-SET-INTERNAL-BORDER-WIDTH", Prim_x_window_set_internal_border_width, 2, 2, 0);
2773   declare_primitive ("X-WINDOW-SET-MOUSE-COLOR", Prim_x_window_set_mouse_color, 2, 2, 0);
2774   declare_primitive ("X-WINDOW-SET-MOUSE-SHAPE", Prim_x_window_set_mouse_shape, 2, 2, 0);
2775   declare_primitive ("X-WINDOW-SET-NAME", Prim_x_window_set_name, 2, 2, 0);
2776   declare_primitive ("X-WINDOW-SET-POSITION", Prim_x_window_set_position, 3, 3, 0);
2777   declare_primitive ("X-WINDOW-SET-SIZE", Prim_x_window_set_size, 3, 3, 0);
2778   declare_primitive ("X-WINDOW-SET-TRANSIENT-FOR-HINT", Prim_x_window_set_transient_for, 2, 2, 0);
2779   declare_primitive ("X-WINDOW-UNMAP", Prim_x_window_unmap, 1, 1, 0);
2780   declare_primitive ("X-WINDOW-WITHDRAW", Prim_x_window_withdraw, 1, 1, 0);
2781   declare_primitive ("X-WINDOW-X-SIZE", Prim_x_window_x_size, 1, 1, 0);
2782   declare_primitive ("X-WINDOW-Y-SIZE", Prim_x_window_y_size, 1, 1, 0);
2783 }
2784 
2785 void
dload_finalize_x11base(void)2786 dload_finalize_x11base (void)
2787 {
2788   if (initialization_done)
2789     x_close_all_displays ();
2790 }
2791 
2792 #endif /* defined (COMPILE_AS_MODULE) */
2793