comparison x11window.c @ 3:5a977ccbc7a9 default tip

Empty changelog
author darius
date Sat, 06 Dec 1997 05:41:29 +0000
parents
children
comparison
equal deleted inserted replaced
2:fba0b6e6cdc7 3:5a977ccbc7a9
1 /* $Id: x11window.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */
2
3
4 /* x11window.c
5 *
6 * Kevin P. Smith 6/11/89
7 * Much modified by Jerry Frain and Joe Young
8 */
9
10 #include <stdio.h>
11 #ifdef __STDC__
12 #include <stdlib.h>
13 #endif
14 #include <X11/Xlib.h>
15 #include <X11/Xutil.h>
16 #ifdef RFCURSORS
17 #include <X11/Xmu/CurUtil.h>
18 #endif
19 #include <X11/cursorfont.h>
20 #include <assert.h>
21 #include <string.h>
22 #include "Wlib.h"
23 #include "defs.h"
24 #include "struct.h"
25 #include "data.h"
26 #include "proto.h"
27
28 #define INVALID_POSITION -10000 /* gotta be a big negative */
29 /* XFIX speedup */
30 #define MAXCACHE 128
31
32 /* changes too good to risk leaving out, by Richard Caley (rjc@cstr.ed.ac.uk)*/
33 #define RJC
34 #define FOURPLANEFIX
35
36 /*
37 #define NORMAL_FONT "-*-fixed-medium-r-*-*-10-*-*-*-*-*-*-*"
38 #define BOLD_FONT "-*-fixed-medium-r-*-*-10-*-*-*-*-*-*-*"
39 #define ITALIC_FONT "-*-fixed-medium-r-*-*-10-*-*-*-*-*-*-*"
40 */
41
42 #define NORMAL_FONT "6x10"
43 #define BOLD_FONT "6x10"
44 #define BOLD_FONT2 "-*-clean-bold-r-normal--10-100-75-75-c-60-*"
45 #define ITALIC_FONT "6x10"
46 #define ITALIC_FONT2 "-*-clean-bold-r-normal--10-100-75-75-c-60-*"
47 #define BIG_FONT "-adobe-helvetica-bold-r-normal--34-*-*-*-*-*-*-*"
48 #define IND_FONT "-*-clean-bold-r-normal--10-100-75-75-c-60-*"
49 /*#define BOLD_FONT2 "-schumacher-clean-bold-r-normal--10-100-75-75-c-60-iso8859-1"
50 #define ITALIC_FONT2 "-misc-fixed-medium-i-normal--10-100-75-75-c-60-iso8859-1"
51 #define BIG_FONT "-adobe-helvetica-bold-r-normal--34-*-*-*-*-*-*-*"
52 */
53
54 static char *_nfonts[] = {
55 NORMAL_FONT,
56 "-*-clean-medium-r-normal--10-100-75-75-c-60-*",
57 "fixed",
58 NULL,
59 };
60 static char *_bfonts[] = {
61 BOLD_FONT,
62 "-*-clean-bold-r-normal--10-100-75-75-c-60-*",
63 "fixed",
64 NULL,
65 };
66 static char *_ifonts[] = {
67 ITALIC_FONT,
68 "-*-clean-bold-r-normal--10-100-75-75-c-60-*",
69 "fixed",
70 NULL,
71 };
72 static char *_bgfonts[] = {
73 BIG_FONT,
74 "-*-lucidatypewriter-*-*-*-*-40-*-*-*-*-*-*-*",
75 "fixed",
76 NULL,
77 };
78
79 #define FONTS 4
80 #define BITGC 4
81
82 #define WHITE 0
83 #define BLACK 1
84 #define RED 2
85 #define GREEN 3
86 #define YELLOW 4
87 #define CYAN 5
88 #define GREY 6
89
90 static int zero = 0;
91 static int one = 1;
92 static int two = 2;
93 static int three = 3;
94
95 int controlkey = 0;
96 #define BillsScrewyAltMask (Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)
97 int altkey = 0;
98 int W_FastClear = 0;
99 #ifdef CONTINUOUS_MOUSE
100 int buttonDown = 0;
101 #endif /* CONTINUOUS_MOUSE */
102 Display *W_Display;
103 Window W_Root;
104 Colormap W_Colormap;
105 int W_Screen;
106 #ifdef FOURPLANEFIX
107 Visual *W_Visual;
108 #endif
109 W_Font W_BigFont = (W_Font) & zero, W_RegularFont = (W_Font) & one;
110 W_Font W_HighlightFont = (W_Font) & two, W_UnderlineFont = (W_Font) & three;
111 W_Color W_White = WHITE, W_Black = BLACK, W_Red = RED, W_Green = GREEN;
112 W_Color W_Yellow = YELLOW, W_Cyan = CYAN, W_Grey = GREY;
113 int W_Textwidth, W_Textheight;
114 char *getdefault();
115 char *strdup();
116
117 int W_in_message = 0; /* jfy -- for Jerry's warp message hack */
118
119 #ifdef RJC
120 extern W_Window baseWin;
121 static XClassHint class_hint = {
122 "netrek", "Netrek",
123 };
124
125 static XWMHints wm_hint = {
126 InputHint | StateHint,
127 True,
128 WithdrawnState,
129 None,
130 None,
131 0, 0,
132 None,
133 None,
134 };
135
136 static XSizeHints wm_size_hint;
137 #endif /* RJC */
138
139 static W_Event W_myevent;
140 static int W_isEvent = 0;
141
142 struct fontInfo {
143 XFontStruct *fontstruct;
144 int baseline;
145 };
146
147 struct colors {
148 char *name;
149 GC contexts[FONTS + 1];
150 Pixmap pixmap;
151 long pixelValue;
152 };
153
154 struct icon {
155 Window window;
156 Pixmap bitmap;
157 int width, height;
158 Pixmap pixmap;
159 };
160
161 #define WIN_GRAPH 1
162 #define WIN_TEXT 2
163 #define WIN_MENU 3
164 #define WIN_SCROLL 4
165
166 struct window {
167 Window window;
168 int type;
169 char *data;
170 int mapped;
171 int width, height;
172 char *name;
173 Cursor cursor;
174 #ifdef SHORT_PACKETS
175 int insensitive;
176 #endif
177 #if 0
178 W_Callback handle_keydown;
179 W_Callback handle_keyup;
180 W_Callback handle_button;
181 W_Callback handle_expose;
182 #endif /* 0 */
183 };
184
185 struct stringList {
186 char *string;
187 W_Color color;
188 struct stringList *next;
189 };
190
191 struct menuItem {
192 char *string;
193 W_Color color;
194 W_Font font;
195 };
196
197 struct colors colortable[] = {
198 {"white"},
199 {"black"},
200 {"red"},
201 {"green"},
202 {"yellow"},
203 {"cyan"},
204 {"light grey"}
205 };
206
207 struct windowlist {
208 struct window *window;
209 struct windowlist *next;
210 };
211
212 #define HASHSIZE 29
213 #define hash(x) (((int) (x)) % HASHSIZE)
214
215 struct windowlist *hashtable[HASHSIZE];
216 struct fontInfo fonts[FONTS];
217
218 struct window *newWindow();
219 #ifndef NeXT
220 #ifndef __STDC__
221 char *malloc();
222 #endif
223 #endif /* NeXT */
224 short *x11tox10bits();
225
226 struct window myroot;
227
228 #define NCOLORS (sizeof(colortable)/sizeof(colortable[0]))
229 #define W_Void2Window(win) ((win) ? (struct window *) (win) : &myroot)
230 #define W_Window2Void(window) ((W_Window) (window))
231 #define W_Void2Icon(bit) ((struct icon *) (bit))
232 #define W_Icon2Void(bit) ((W_Icon) (bit))
233 #define fontNum(font) (*((int *) font))
234 #define TILESIDE 16
235
236 #define WIN_EDGE 5 /* border on l/r edges of text windows */
237 #define MENU_PAD 4 /* border on t/b edges of text windows */
238 #define MENU_BAR 2 /* width of menu bar */
239
240 static unsigned char gray[] = {
241 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55,
242 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55,
243 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55,
244 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55
245 };
246
247 static unsigned char striped[] = {
248 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
249 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f,
250 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
251 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0
252 };
253
254 static unsigned char solid[] = {
255 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
256 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
257 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
258 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
259 };
260
261 /* Prototypes */
262 /*static int _myerror P((Display *d , XErrorEvent *e ));*/
263 static void GetFonts P((void));
264 static XFontStruct *find_font P((char *oldf, char **fonts));
265 static void GetColors P((void));
266 static void FlushClearAreaCache P((Window win));
267 static int W_SpNextEvent P((W_Event * wevent));
268 static void FlushLineCache P((Window win, int color));
269 static void FlushPointCache P((Window win, int color));
270 static struct window *findWindow P((Window window));
271 static void addToHash P((struct window * win));
272 static void AddToScrolling P((struct window * win, W_Color color, char *str, int len));
273 static void redrawScrolling P((struct window * win));
274 static void resizeScrolling P((struct window * win, int width, int height));
275 static void redrawMenu P((struct window * win));
276 static void redrawMenuItem P((struct window * win, int n));
277 static void changeMenuItem P((struct window * win, int n, W_Color color, char *str, int len, W_Font font));
278 /*static void W_SetTransientForHint P((W_Window w , W_Window pw ));*/
279 static void checkGeometry P((char *name, int *x, int *y, int *width, int *height));
280 static void checkParent P((char *name, W_Window * parent));
281 static void checkCursor P((char *name, char *cursname, Cursor * cursor));
282 static void findMouse P((int *x, int *y));
283 #ifdef AUTOKEY
284 static void W_Flush P((void));
285 #endif /* AUTOKEY */
286 static void deleteWindow P((struct window * window));
287
288 /* X debugging */
289 #if 0
290 static int
291 _myerror(d, e)
292 Display *d;
293 XErrorEvent *e;
294 {
295 abort();
296 }
297 #endif /* 0 */
298
299 void
300 W_Initialize(str)
301 char *str;
302 {
303 int i;
304
305 #ifdef DEBUG
306 printf("Initializing...\n");
307 #endif
308 for (i = 0; i < HASHSIZE; i++) {
309 hashtable[i] = NULL;
310 }
311 if ((W_Display = XOpenDisplay(str)) == NULL) {
312 fprintf(stderr, "Cannot open display \"%s\"\n", str ? str : "(null)");
313 EXIT(1);
314 }
315 #if 0
316 /* tmp */
317 XSynchronize(W_Display, True);
318 XSetErrorHandler(_myerror);
319 #endif
320
321 W_Root = DefaultRootWindow(W_Display);
322 #ifdef FOURPLANEFIX
323 W_Visual = DefaultVisual(W_Display, DefaultScreen(W_Display));
324 #endif
325 W_Screen = DefaultScreen(W_Display);
326 W_Colormap = DefaultColormap(W_Display, W_Screen);
327 myroot.window = W_Root;
328 myroot.type = WIN_GRAPH;
329 GetFonts();
330 GetColors();
331 }
332
333 static void
334 GetFonts()
335 {
336 Font regular, italic, bold, big;
337 int i;
338 XGCValues values;
339 XFontStruct *fontinfo;
340 char *fontname;
341
342 fontname = getdefault("font");
343 if (fontname == NULL)
344 fontname = NORMAL_FONT;
345 fontinfo = XLoadQueryFont(W_Display, fontname);
346 if (fontinfo == NULL) {
347 fontinfo = find_font(fontname, _nfonts);
348 }
349 if (fontinfo == NULL) {
350 printf("netrek: Can't find any fonts!\n");
351 EXIT(1);
352 }
353 regular = fontinfo->fid;
354 W_Textwidth = fontinfo->max_bounds.width;
355 W_Textheight = fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent;
356 fonts[1].baseline = fontinfo->max_bounds.ascent;
357 fonts[1].fontstruct = fontinfo;
358
359 fontname = getdefault("boldfont");
360 if (fontname == NULL) {
361 if (DisplayCells(W_Display, W_Screen) <= 4)
362 fontname = BOLD_FONT2;
363 else
364 fontname = BOLD_FONT;
365 }
366 fontinfo = XLoadQueryFont(W_Display, fontname);
367 if (fontinfo == NULL) {
368 fontinfo = find_font(fontname, _bfonts);
369 }
370 if (fontinfo == NULL) {
371 bold = regular;
372 fonts[2].baseline = fonts[1].baseline;
373 fonts[2].fontstruct = fonts[1].fontstruct;
374 } else {
375 bold = fontinfo->fid;
376 fonts[2].baseline = fontinfo->max_bounds.ascent;
377 fonts[2].fontstruct = fontinfo;
378 if (fontinfo->max_bounds.width > W_Textwidth)
379 W_Textwidth = fontinfo->max_bounds.width;
380 if (fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent > W_Textheight)
381 W_Textheight = fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent;
382 }
383
384 fontname = getdefault("italicfont");
385 if (fontname == NULL) {
386 if (DisplayCells(W_Display, W_Screen) <= 4)
387 fontname = ITALIC_FONT2;
388 else
389 fontname = ITALIC_FONT;
390 }
391 fontinfo = XLoadQueryFont(W_Display, fontname);
392 if (fontinfo == NULL) {
393 fontinfo = find_font(fontname, _ifonts);
394 }
395 if (fontinfo == NULL) {
396 italic = regular;
397 fonts[3].baseline = fonts[1].baseline;
398 fonts[3].fontstruct = fonts[1].fontstruct;
399 } else {
400 italic = fontinfo->fid;
401 fonts[3].baseline = fontinfo->max_bounds.ascent;
402 fonts[3].fontstruct = fontinfo;
403 if (fontinfo->max_bounds.width > W_Textwidth)
404 W_Textwidth = fontinfo->max_bounds.width;
405 if (fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent > W_Textheight)
406 W_Textheight = fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent;
407 }
408
409 fontname = getdefault("bigfont");
410 if (fontname == NULL)
411 fontname = BIG_FONT;
412 fontinfo = XLoadQueryFont(W_Display, fontname);
413 if (fontinfo == NULL) {
414 fontinfo = find_font(fontname, _bgfonts);
415 }
416 if (fontinfo == NULL) {
417 big = regular;
418 fonts[0].baseline = fonts[1].baseline;
419 fonts[0].fontstruct = fonts[1].fontstruct;
420 } else {
421 big = fontinfo->fid;
422 fonts[0].baseline = fontinfo->max_bounds.ascent;
423 fonts[0].fontstruct = fontinfo;
424 }
425 for (i = 0; i < NCOLORS; i++) {
426 values.font = big;
427 colortable[i].contexts[0] = XCreateGC(W_Display, W_Root, GCFont, &values);
428 XSetGraphicsExposures(W_Display, colortable[i].contexts[0], False);
429 values.font = regular;
430 colortable[i].contexts[1] = XCreateGC(W_Display, W_Root, GCFont, &values);
431 XSetGraphicsExposures(W_Display, colortable[i].contexts[1], False);
432 values.font = bold;
433 colortable[i].contexts[2] = XCreateGC(W_Display, W_Root, GCFont, &values);
434 XSetGraphicsExposures(W_Display, colortable[i].contexts[2], False);
435 values.font = italic;
436 colortable[i].contexts[3] = XCreateGC(W_Display, W_Root, GCFont, &values);
437 XSetGraphicsExposures(W_Display, colortable[i].contexts[3], False);
438 {
439 static char dl[] = {1, 4};
440 XSetLineAttributes(W_Display, colortable[i].contexts[3],
441 0, LineOnOffDash, CapButt, JoinMiter);
442 XSetDashes(W_Display, colortable[i].contexts[3], 0, dl, 2);
443 }
444 values.function = GXor;
445 colortable[i].contexts[BITGC] = XCreateGC(W_Display, W_Root, GCFunction, &values);
446 XSetGraphicsExposures(W_Display, colortable[i].contexts[BITGC], False);
447 }
448 }
449
450 static XFontStruct *
451 find_font(oldf, fonts)
452 char *oldf, **fonts;
453 {
454 XFontStruct *fi;
455 char **f;
456 fprintf(stderr, "netrek: Can't find font %s. Trying others...\n",
457 oldf);
458 for (f = fonts; *f; f++) {
459 if (strcmp(*f, oldf) != 0) {
460 if ((fi = XLoadQueryFont(W_Display, *f)))
461 return fi;
462 }
463 }
464 printf("Error - can't find any font!\n");
465 return NULL;
466 }
467
468 #ifdef FOURPLANEFIX
469 static unsigned short extrared[8] = {0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xb0, 0xc0};
470 static unsigned short extragreen[8] = {0x40, 0x60, 0x80, 0xa0, 0xb0, 0xc0, 0x00, 0x20};
471 static unsigned short extrablue[8] = {0x80, 0xa0, 0xb0, 0xc0, 0x00, 0x20, 0x40, 0x60};
472 #endif
473
474 int
475 W_Mono()
476 {
477 return forceMono;
478 }
479
480 static void
481 GetColors()
482 {
483 int i, j;
484 XColor foo;
485 int white, black;
486 unsigned long pixel;
487 unsigned long planes[3];
488 char defaultstring[100];
489 char *defaults;
490 #ifdef FOURPLANEFIX
491 unsigned long extracolors[8];
492 XColor colordef;
493 #endif
494 extern int forceMono;
495 forceMono = booleanDefault("forcemono", forceMono);
496
497 if ((DisplayCells(W_Display, W_Screen) <= 4) || forceMono) {
498 forceMono = 1;
499 white = WhitePixel(W_Display, W_Screen);
500 black = BlackPixel(W_Display, W_Screen);
501 for (i = 0; i < NCOLORS; i++) {
502 if (i != W_Black) {
503 colortable[i].pixelValue = white;
504 } else {
505 colortable[i].pixelValue = black;
506 }
507 if (i == W_Red) {
508 colortable[i].pixmap = XCreatePixmapFromBitmapData
509 (W_Display,
510 W_Root, (char *) striped, TILESIDE, TILESIDE,
511 white, black,
512 DefaultDepth(W_Display, W_Screen));
513 } else if (i == W_Yellow) {
514 colortable[i].pixmap = XCreatePixmapFromBitmapData
515 (W_Display,
516 W_Root, (char *) gray, TILESIDE, TILESIDE,
517 white, black,
518 DefaultDepth(W_Display, W_Screen));
519 } else {
520 colortable[i].pixmap = XCreatePixmapFromBitmapData
521 (W_Display,
522 W_Root, (char *) solid, TILESIDE, TILESIDE,
523 colortable[i].pixelValue,
524 colortable[i].pixelValue,
525 DefaultDepth(W_Display, W_Screen));
526 }
527
528 /*
529 We assume white is 0 or 1, and black is 0 or 1. We adjust
530 graphics function based upon who is who.
531 */
532 if (white == 0) { /* Black is 1 */
533 XSetFunction(W_Display, colortable[i].contexts[BITGC], GXand);
534 }
535 }
536 } else if (DefaultVisual(W_Display, W_Screen)->class == TrueColor) {
537 /* Stuff added by sheldon@iastate.edu 5/28/93
538 * This is supposed to detect a TrueColor display, and then do a lookup of
539 * the colors in default colormap, instead of creating new colormap
540 */
541 for (i = 0; i < NCOLORS; i++) {
542 sprintf(defaultstring, "color.%s", colortable[i].name);
543
544 defaults = getdefault(defaultstring);
545 if (defaults == NULL)
546 defaults = colortable[i].name;
547 XParseColor(W_Display, W_Colormap, defaults, &foo);
548 XAllocColor(W_Display, W_Colormap, &foo);
549 colortable[i].pixelValue = foo.pixel;
550 colortable[i].pixmap = XCreatePixmapFromBitmapData(W_Display,
551 W_Root, (char *) solid, TILESIDE, TILESIDE, foo.pixel, foo.pixel,
552 DefaultDepth(W_Display, W_Screen));
553 }
554 } else {
555 #ifdef FOURPLANEFIX
556 if (!XAllocColorCells(W_Display, W_Colormap, False, planes, 3,
557 &pixel, 1)) {
558 /* couldn't allocate 3 planes, make a new colormap */
559 W_Colormap = XCreateColormap(W_Display, W_Root, W_Visual, AllocNone);
560 if (!XAllocColorCells(W_Display, W_Colormap, False, planes, 3,
561 &pixel, 1)) {
562 fprintf(stderr, "Cannot create new colormap\n");
563 EXIT(1);
564 }
565 /*
566 and fill it with at least 8 more colors so when mouse is
567 inside netrek windows, use might be able to see his other
568 windows
569 */
570 if (XAllocColorCells(W_Display, W_Colormap, False, NULL, 0,
571 extracolors, 8)) {
572 colordef.flags = DoRed | DoGreen | DoBlue;
573 for (i = 0; i < 8; i++) {
574 colordef.pixel = extracolors[i];
575 colordef.red = extrared[i] << 8;
576 colordef.green = extragreen[i] << 8;
577 colordef.blue = extrablue[i] << 8;
578 XStoreColor(W_Display, W_Colormap, &colordef);
579 }
580 }
581 }
582 #else
583 XAllocColorCells(W_Display, W_Colormap, False, planes, 3, &pixel, 1);
584 #endif
585 for (i = 0; i < NCOLORS; i++) {
586 /*
587 strcpy(defaultstring, "color.%s", colortable[i].name);
588 */
589 sprintf(defaultstring, "color.%s", colortable[i].name);
590
591 defaults = getdefault(defaultstring);
592 if (defaults == NULL)
593 defaults = colortable[i].name;
594 XParseColor(W_Display, W_Colormap, defaults, &foo);
595 /*
596 Black must be the color with all the planes off. That is the
597 only restriction I concerned myself with in the following case
598 statement.
599 */
600 switch (i) {
601 case WHITE:
602 foo.pixel = pixel | planes[0] | planes[1] | planes[2];
603 break;
604 case BLACK:
605 foo.pixel = pixel;
606 break;
607 case RED:
608 foo.pixel = pixel | planes[0];
609 break;
610 case CYAN:
611 foo.pixel = pixel | planes[1];
612 break;
613 case YELLOW:
614 foo.pixel = pixel | planes[2];
615 break;
616 case GREY:
617 foo.pixel = pixel | planes[0] | planes[1];
618 break;
619 case GREEN:
620 foo.pixel = pixel | planes[1] | planes[2];
621 break;
622 }
623 XStoreColor(W_Display, W_Colormap, &foo);
624 colortable[i].pixelValue = foo.pixel;
625 colortable[i].pixmap = XCreatePixmapFromBitmapData(W_Display,
626 W_Root, (char *) solid, TILESIDE, TILESIDE, foo.pixel, foo.pixel,
627 DefaultDepth(W_Display, W_Screen));
628 }
629 }
630 for (i = 0; i < NCOLORS; i++) {
631 for (j = 0; j < FONTS + 1; j++) {
632 XSetForeground(W_Display, colortable[i].contexts[j],
633 colortable[i].pixelValue);
634 XSetBackground(W_Display, colortable[i].contexts[j],
635 colortable[W_Black].pixelValue);
636 }
637 }
638 }
639
640 void
641 W_RenameWindow(window, str)
642 W_Window window;
643 char *str;
644 {
645 XStoreName(W_Display, ((struct window *) window)->window, str);
646 }
647
648 static W_Window
649 w_MakeWindow(name, x, y, width, height, parent,
650 cursname, border, color, wsort)
651 char *name;
652 int x, y, width, height;
653 W_Window parent;
654 char *cursname;
655 int border;
656 W_Color color;
657 int wsort; /* WIN_? */
658 {
659 int gx, gy;
660 struct window *newwin;
661 Window wparent;
662 Cursor cursor;
663 XSetWindowAttributes attrs;
664 int pwidth, pheight; /* pixel width and height */
665
666
667 checkGeometry(name, &gx, &gy, &width, &height);
668 if (gx != INVALID_POSITION)
669 x = gx;
670 if (gy != INVALID_POSITION)
671 y = gy;
672
673 checkParent(name, &parent);
674 wparent = W_Void2Window(parent)->window;
675
676 checkCursor(name, cursname, &cursor);
677 attrs.cursor = cursor;
678
679 attrs.border_pixel = colortable[color].pixelValue;
680 attrs.background_pixel = colortable[W_Black].pixelValue;
681
682 if (wsort == WIN_TEXT || wsort == WIN_SCROLL || wsort == WIN_MENU) {
683 pwidth = width * W_Textwidth + WIN_EDGE * 2;
684 if (wsort == WIN_MENU)
685 pheight = height * (W_Textheight + MENU_PAD * 2 + MENU_BAR) - MENU_BAR;
686 else
687 pheight = height * W_Textheight + MENU_PAD * 2;
688 } else {
689 pwidth = width;
690 pheight = height;
691 }
692
693 switch (wsort) {
694 case WIN_TEXT:
695 case WIN_MENU:
696 attrs.event_mask = KeyPressMask | ButtonPressMask | ExposureMask | ButtonReleaseMask;
697 attrs.do_not_propagate_mask = ExposureMask | KeyPressMask | ButtonPressMask;
698 break;
699 case WIN_GRAPH:
700 attrs.event_mask = KeyPressMask | ButtonPressMask | ExposureMask | LeaveWindowMask | ButtonReleaseMask | ButtonMotionMask;
701 attrs.do_not_propagate_mask = ExposureMask;
702 break;
703 case WIN_SCROLL:
704 attrs.event_mask = ResizeRedirectMask | ExposureMask | KeyPressMask | ButtonReleaseMask | ButtonPressMask;
705 attrs.do_not_propagate_mask = ResizeRedirectMask | ExposureMask;
706 break;
707 default:
708 fprintf(stderr, "x11window.c: w_MakeWindow: unknown wsort %d\n", wsort);
709 }
710
711 #ifdef AUTOKEY
712 if (attrs.event_mask & KeyPressMask)
713 attrs.event_mask |= KeyReleaseMask;
714 #endif /* AUTOKEY */
715
716 if (strcmp(name, "netrek_icon") == 0) /* icon should not select for
717 input */
718 attrs.event_mask = ExposureMask;
719 if (strcmp(name, "wait_icon") == 0) /* same here [BDyess] */
720 attrs.event_mask = ExposureMask;
721
722 if (strcmp(name, "info") == 0) /* make info window passthru [BDyess] */
723 attrs.event_mask = ExposureMask;
724
725 newwin = newWindow
726 (XCreateWindow(W_Display, wparent, x, y, pwidth, pheight, border,
727 CopyFromParent, InputOutput, CopyFromParent,
728 CWBackPixel | CWBorderPixel | CWEventMask |
729 (cursor ? CWCursor : 0),
730 &attrs),
731 wsort);
732
733 newwin->cursor = cursor;
734
735 {
736 char *s;
737
738 if (0 == strcmp(name, "wait"))
739 s = serverName;
740 else if (0 == strcmp(name, "Motd"))
741 s = "Motd - [f] forward, [b] back, [tab] sysdefs, [space] unmap";
742 else if (0 == strcmp(name, "netrek")) {
743 if (!title) {
744 char buf[80];
745 sprintf(buf, "Netrek @ %s", serverName);
746 s = buf;
747 } else {
748 /* but title on command line will override */
749 /* from -h arg */
750 s = title;
751 }
752 } else
753 s = name;
754
755 XStoreName(W_Display, newwin->window, s);
756 }
757
758 wm_size_hint.width = wm_size_hint.min_width =
759 wm_size_hint.max_width = wm_size_hint.base_width = pwidth;
760 wm_size_hint.min_height = wm_size_hint.height =
761 wm_size_hint.max_height = wm_size_hint.base_height = pheight;
762 wm_size_hint.flags = USSize | PMinSize | PMaxSize | PBaseSize;
763 if (gx > INVALID_POSITION || gy > INVALID_POSITION) {
764 wm_size_hint.flags |= USPosition;
765 wm_size_hint.x = x;
766 wm_size_hint.y = y;
767 }
768 XSetWMNormalHints(W_Display, newwin->window, &wm_size_hint);
769
770 class_hint.res_name = name;
771 class_hint.res_class = "Netrek";
772 XSetClassHint(W_Display, newwin->window, &class_hint);
773
774 XSetWMHints(W_Display, newwin->window, &wm_hint);
775
776 if (((wparent == W_Root &&
777 baseWin != NULL &&
778 strcmp(name, "wait") != 0)
779 || wsort == WIN_MENU) &&
780 strcmp(name, "MetaServer List") != 0 &&
781 strcmp(name, "Motd") != 0) {
782 XSetTransientForHint(W_Display, newwin->window,
783 W_Void2Window(baseWin)->window);
784 }
785 newwin->name = strdup(name);
786 newwin->width = width;
787 newwin->height = height;
788 if (wsort == WIN_MENU) {
789 int i;
790 struct menuItem *items;
791 items = (struct menuItem *) malloc(height * sizeof(struct menuItem));
792 for (i = 0; i < height; i++) {
793 items[i].string = NULL;
794 items[i].color = W_White;
795 items[i].font = W_RegularFont;
796 }
797 newwin->data = (char *) items;
798 } else {
799 newwin->data = 0;
800 }
801
802 if (wparent != W_Root)
803 if (checkMapped(name))
804 W_MapWindow(W_Window2Void(newwin));
805
806 #ifdef DEBUG
807 printf("New graphics window %d, child of %d\n", newwin, parent);
808 #endif
809
810 #ifdef FOURPLANEFIX
811 XSetWindowColormap(W_Display, newwin->window, W_Colormap);
812 #endif
813
814 return (W_Window2Void(newwin));
815 }
816
817
818
819
820 W_Window
821 W_MakeWindow(name, x, y, width, height, parent, cursname, border, color)
822 char *name;
823 int x, y, width, height;
824 W_Window parent;
825 char *cursname;
826 int border;
827 W_Color color;
828 {
829 return w_MakeWindow(name, x, y, width, height, parent,
830 cursname, border, color, WIN_GRAPH);
831 }
832
833 void
834 W_ChangeBorder(window, color)
835 W_Window window;
836 int color;
837 {
838 #ifdef DEBUG
839 printf("Changing border of %d\n", window);
840 #endif
841
842 /* fix inexplicable color bug */
843 if (DisplayCells(W_Display, W_Screen) <= 2)
844 XSetWindowBorderPixmap(W_Display, W_Void2Window(window)->window,
845 colortable[color].pixmap);
846 else
847 XSetWindowBorder(W_Display, W_Void2Window(window)->window,
848 colortable[color].pixelValue);
849 }
850
851 void
852 W_MapWindow(window)
853 W_Window window;
854 {
855 struct window *win;
856
857 #ifdef DEBUG
858 printf("Mapping %d\n", window);
859 #endif
860 win = W_Void2Window(window);
861 if (win->mapped)
862 return;
863 win->mapped = 1;
864 XMapRaised(W_Display, win->window);
865 }
866
867 void
868 W_UnmapWindow(window)
869 W_Window window;
870 {
871 struct window *win;
872
873 #ifdef DEBUG
874 printf("UnMapping %d\n", window);
875 #endif
876 win = W_Void2Window(window);
877 if (win->mapped == 0)
878 return;
879 win->mapped = 0;
880 XUnmapWindow(W_Display, win->window);
881 }
882
883 int
884 W_IsMapped(window)
885 W_Window window;
886 {
887 struct window *win;
888
889 win = W_Void2Window(window);
890 if (win == NULL)
891 return (0);
892 return (win->mapped);
893 }
894
895 void
896 W_FillArea(window, x, y, width, height, color)
897 W_Window window;
898 int x, y, width, height;
899 W_Color color;
900 {
901 struct window *win;
902
903 #ifdef DEBUG
904 printf("Clearing (%d %d) x (%d %d) with %d on %d\n", x, y, width, height,
905 color, window);
906 #endif
907 win = W_Void2Window(window);
908 switch (win->type) {
909 case WIN_GRAPH:
910 XFillRectangle(W_Display, win->window, colortable[color].contexts[0],
911 x, y, width, height);
912 break;
913 default:
914 XFillRectangle(W_Display, win->window, colortable[color].contexts[0],
915 WIN_EDGE + x * W_Textwidth, MENU_PAD + y * W_Textheight,
916 width * W_Textwidth, height * W_Textheight);
917 }
918 }
919
920 /* XFIX */
921
922 static XRectangle _rcache[MAXCACHE];
923 static int _rcache_index;
924
925 static void
926 FlushClearAreaCache(win)
927 Window win;
928 {
929 XFillRectangles(W_Display, win, colortable[backColor].contexts[0],
930 _rcache, _rcache_index);
931 _rcache_index = 0;
932 }
933
934 /* local window only */
935 void
936 W_CacheClearArea(window, x, y, width, height)
937 W_Window window;
938 int x, y, width, height;
939 {
940 Window win = W_Void2Window(window)->window;
941 register XRectangle *r;
942
943 if (_rcache_index == MAXCACHE)
944 FlushClearAreaCache(win);
945
946 r = &_rcache[_rcache_index++];
947 r->x = (short) x;
948 r->y = (short) y;
949 r->width = (unsigned short) width;
950 r->height = (unsigned short) height;
951 }
952
953 void
954 W_FlushClearAreaCache(window)
955 W_Window window;
956 {
957 Window win = W_Void2Window(window)->window;
958
959 if (_rcache_index)
960 FlushClearAreaCache(win);
961 }
962
963 /* XFIX: clears now instead of filling. */
964 void
965 W_ClearArea(window, x, y, width, height)
966 W_Window window;
967 int x, y, width, height;
968 {
969 struct window *win;
970
971 #ifdef DEBUG
972 printf("Clearing (%d %d) x (%d %d) with %d on %d\n", x, y, width, height,
973 color, window);
974 #endif
975 win = W_Void2Window(window);
976 switch (win->type) {
977 case WIN_GRAPH:
978 /* XFIX: changed */
979 XClearArea(W_Display, win->window, x, y, width, height, False);
980 break;
981 default:
982 /* XFIX: changed */
983 XClearArea(W_Display, win->window, WIN_EDGE + x * W_Textwidth,
984 MENU_PAD + y * W_Textheight, width * W_Textwidth, height * W_Textheight, False);
985 break;
986 }
987 }
988
989 void
990 W_ClearWindow(window)
991 W_Window window;
992 {
993 #ifdef DEBUG
994 printf("Clearing %d\n", window);
995 #endif
996 XClearWindow(W_Display, W_Void2Window(window)->window);
997 }
998
999 void
1000 W_GetEvent(wevent)
1001 W_Event *wevent;
1002 {
1003 /* blocks until an event is received [BDyess] */
1004 XEvent event;
1005
1006 if (W_isEvent) {
1007 *wevent = W_myevent;
1008 W_isEvent = 0;
1009 return;
1010 }
1011 XNextEvent(W_Display, &event);
1012 XPutBackEvent(W_Display, &event);
1013 W_SpNextEvent(wevent);
1014 }
1015
1016 int
1017 W_EventsPending()
1018 {
1019 if (W_isEvent)
1020 return (1);
1021 while (XPending(W_Display) || buttonDown) {
1022 if (W_SpNextEvent(&W_myevent)) {
1023 W_isEvent = 1;
1024 return (1);
1025 }
1026 }
1027 return (0);
1028 }
1029
1030 void
1031 W_NextEvent(wevent)
1032 W_Event *wevent;
1033 {
1034 if (W_isEvent) {
1035 *wevent = W_myevent;
1036 W_isEvent = 0;
1037 return;
1038 }
1039 while (W_SpNextEvent(wevent) == 0);
1040 }
1041
1042 static int
1043 W_SpNextEvent(wevent)
1044 W_Event *wevent;
1045 {
1046 XEvent event;
1047 XKeyEvent *key;
1048 XButtonEvent *button;
1049 XExposeEvent *expose;
1050 XResizeRequestEvent *resize;
1051 char ch;
1052 struct window *win;
1053 #ifdef CONTINUOUS_MOUSE
1054 static W_Event buttonEvent;
1055 static int delay, cupd = -1;
1056 #endif /* CONTINUOUS_MOUSE */
1057
1058 #ifdef DEBUG
1059 printf("Getting an event...\n");
1060 #endif
1061 key = (XKeyEvent *) & event;
1062 button = (XButtonEvent *) & event;
1063 expose = (XExposeEvent *) & event;
1064 resize = (XResizeRequestEvent *) & event;
1065 for (;;) {
1066 if (XPending(W_Display))
1067 XNextEvent(W_Display, &event);
1068 #ifdef CONTINUOUS_MOUSE
1069 else if (buttonDown) {
1070 if (continuousMouse && allowContinuousMouse) {
1071 if (cupd != udcounter) {
1072 cupd = udcounter;
1073 if (delay == 0) {
1074 bcopy(&buttonEvent, wevent, sizeof(W_Event));
1075 delay = clickDelay;
1076 } else {
1077 delay--;
1078 wevent->type = -1;
1079 }
1080 } else
1081 wevent->type = -1;
1082 exitInputLoop = 1;
1083 } else {
1084 wevent->type = -1;
1085 buttonDown = 0;
1086 }
1087 return (1);
1088 }
1089 #endif
1090 else
1091 return (0);
1092 /*
1093 printf("read an event %d\n", event.type);
1094 */
1095 win = findWindow(key->window);
1096 if (win == NULL)
1097 return (0);
1098 if ((event.type == KeyPress || event.type == ButtonPress) &&
1099 win->type == WIN_MENU) {
1100 if (key->y % (W_Textheight + MENU_PAD * 2 + MENU_BAR) >=
1101 W_Textheight + MENU_PAD * 2)
1102 return (0);
1103 key->y = key->y / (W_Textheight + MENU_PAD * 2 + MENU_BAR);
1104 }
1105 switch ((int) event.type) {
1106 case LeaveNotify: /* for message window -- jfy */
1107 if (win == (struct window *) messagew) {
1108 W_in_message = 0;
1109 }
1110 return (0);
1111 break;
1112 case KeyPress:
1113 if (key->state & ControlMask) {
1114 controlkey = 1;
1115 key->state &= ~ControlMask;
1116 } else
1117 controlkey = 0;
1118 if (key->state & BillsScrewyAltMask) {
1119 altkey = 1;
1120 key->state &= ~BillsScrewyAltMask;
1121 } else
1122 altkey = 0;
1123 if (XLookupString(key, &ch, 1, NULL, NULL) > 0) {
1124 wevent->type = W_EV_KEY;
1125 wevent->Window = W_Window2Void(win);
1126 wevent->x = key->x;
1127 wevent->y = key->y;
1128 if (controlkey)
1129 wevent->key = (int) ch + 128;
1130 else if (altkey)
1131 wevent->key = (int) ch + 256;
1132 else
1133 wevent->key = ch;
1134 return (1);
1135 }
1136 return (0);
1137 break;
1138 #ifdef AUTOKEY
1139 case KeyRelease:
1140 if (XLookupString(key, &ch, 1, NULL, NULL) > 0) {
1141 wevent->type = W_EV_KEY_OFF;
1142 wevent->Window = W_Window2Void(win);
1143 wevent->x = key->x;
1144 wevent->y = key->y;
1145 wevent->key = ch;
1146 return (1);
1147 }
1148 return (0);
1149 break;
1150 #endif /* AUTOKEY */
1151 case ButtonPress:
1152 wevent->type = W_EV_BUTTON;
1153 wevent->Window = W_Window2Void(win);
1154 wevent->x = button->x;
1155 wevent->y = button->y;
1156 switch (button->button & 0xf) {
1157 case Button3:
1158 wevent->key = W_RBUTTON;
1159 break;
1160 case Button1:
1161 wevent->key = W_LBUTTON;
1162 break;
1163 case Button2:
1164 wevent->key = W_MBUTTON;
1165 break;
1166 }
1167 if (key->state & ControlMask)
1168 wevent->key += 6;
1169 if (key->state & ShiftMask)
1170 wevent->key += 3;
1171 if (key->state & BillsScrewyAltMask)
1172 wevent->key += 12; /* alt */
1173 #ifdef CONTINUOUS_MOUSE
1174 if (continuousMouse && allowContinuousMouse &&
1175 (wevent->Window == w || wevent->Window == mapw) &&
1176 /*
1177 buttonRepeatMask allows only certain buttons to repeat
1178 [BDyess]
1179 */
1180 (1 << (wevent->key) & buttonRepeatMask)) {
1181 buttonDown = 1;
1182 exitInputLoop = 1;
1183 delay = clickDelay;
1184 bcopy(wevent, &buttonEvent, sizeof(W_Event));
1185 }
1186 return (1);
1187 case ButtonRelease:
1188 /* bcopy(&buttonEvent,wevent,sizeof(W_Event)); */
1189 wevent->type = -1;
1190 buttonDown = 0;
1191 return (1);
1192 case MotionNotify:
1193 /*
1194 the !buttonDown ensures that if you press a button and then
1195 press another, release just the second, and then move the
1196 mouse that nothing happens.
1197 */
1198 if (!(continuousMouse && allowContinuousMouse) || !buttonDown) {
1199 wevent->type = -1;
1200 return (1);
1201 }
1202 wevent->type = W_EV_BUTTON;
1203 wevent->Window = W_Window2Void(win);
1204 wevent->x = button->x;
1205 wevent->y = button->y;
1206 wevent->key = buttonEvent.key;
1207 bcopy(wevent, &buttonEvent, sizeof(W_Event));
1208 if (cupd == udcounter)
1209 wevent->type = -1;
1210 else
1211 cupd = udcounter;
1212
1213 return (1);
1214 #else
1215 return (1);
1216 #endif /* CONTINUOUS_MOUSE */
1217 case Expose:
1218 if (expose->count != 0)
1219 return (0);
1220 if (win->type == WIN_SCROLL) {
1221 redrawScrolling(win);
1222 return (0);
1223 }
1224 if (win->type == WIN_MENU) {
1225 redrawMenu(win);
1226 return (0);
1227 }
1228 wevent->type = W_EV_EXPOSE;
1229 wevent->Window = W_Window2Void(win);
1230 return (1);
1231 case ResizeRequest:
1232 resizeScrolling(win, resize->width, resize->height);
1233 break;
1234 default:
1235 return (0);
1236 break;
1237 }
1238 }
1239 }
1240
1241 void
1242 W_MakeLine(window, x0, y0, x1, y1, color)
1243 W_Window window;
1244 int x0, y0, x1, y1;
1245 W_Color color;
1246 {
1247 Window win;
1248
1249 #ifdef DEBUG
1250 printf("Line on %d\n", window);
1251 #endif
1252 win = W_Void2Window(window)->window;
1253 XDrawLine(W_Display, win, colortable[color].contexts[0], x0, y0, x1, y1);
1254 }
1255
1256 void
1257 W_DrawPoint(window, x, y, color)
1258 W_Window window;
1259 int x, y;
1260 W_Color color;
1261 {
1262 Window win;
1263
1264 #ifdef DEBUG
1265 printf("Point on %d\n", window);
1266 #endif
1267 win = W_Void2Window(window)->window;
1268 XDrawPoint(W_Display, win, colortable[color].contexts[0], x, y);
1269 }
1270
1271 /* XFIX */
1272
1273 static XSegment _lcache[NCOLORS][MAXCACHE];
1274 static int _lcache_index[NCOLORS];
1275
1276 static void
1277 FlushLineCache(win, color)
1278 Window win;
1279 int color;
1280 {
1281 XDrawSegments(W_Display, win, colortable[color].contexts[0],
1282 _lcache[color], _lcache_index[color]);
1283 _lcache_index[color] = 0;
1284 }
1285
1286 /* for local window only */
1287 void
1288 W_CacheLine(window, x0, y0, x1, y1, color)
1289 W_Window window;
1290 int x0, y0, x1, y1, color;
1291 {
1292 Window win = W_Void2Window(window)->window;
1293 register XSegment *s;
1294
1295 if (_lcache_index[color] == MAXCACHE)
1296 FlushLineCache(win, color);
1297
1298 s = &_lcache[color][_lcache_index[color]++];
1299 s->x1 = (short) x0;
1300 s->y1 = (short) y0;
1301 s->x2 = (short) x1;
1302 s->y2 = (short) y1;
1303 }
1304
1305 void
1306 W_FlushLineCaches(window)
1307 W_Window window;
1308 {
1309 Window win = W_Void2Window(window)->window;
1310 register i;
1311 for (i = 0; i < NCOLORS; i++) {
1312 if (_lcache_index[i])
1313 FlushLineCache(win, i);
1314 }
1315 }
1316
1317 static XPoint _pcache[NCOLORS][MAXCACHE];
1318 static int _pcache_index[NCOLORS];
1319
1320 static void
1321 FlushPointCache(win, color)
1322 Window win;
1323 int color;
1324 {
1325 XDrawPoints(W_Display, win, colortable[color].contexts[0],
1326 _pcache[color], _pcache_index[color], CoordModeOrigin);
1327 _pcache_index[color] = 0;
1328 }
1329
1330 void
1331 W_CachePoint(window, x, y, color)
1332 W_Window window;
1333 int x, y, color;
1334 {
1335 Window win = W_Void2Window(window)->window;
1336 register XPoint *p;
1337
1338 if (_pcache_index[color] == MAXCACHE)
1339 FlushPointCache(win, color);
1340
1341 p = &_pcache[color][_pcache_index[color]++];
1342 p->x = (short) x;
1343 p->y = (short) y;
1344 }
1345
1346 void
1347 W_FlushPointCaches(window)
1348 W_Window window;
1349 {
1350 Window win = W_Void2Window(window)->window;
1351 register i;
1352 for (i = 0; i < NCOLORS; i++) {
1353 if (_pcache_index[i])
1354 FlushPointCache(win, i);
1355 }
1356 }
1357
1358 void
1359 W_MakeTractLine(window, x0, y0, x1, y1, color)
1360 W_Window window;
1361 int x0, y0, x1, y1;
1362 W_Color color;
1363 {
1364 Window win;
1365
1366 #ifdef DEBUG
1367 printf("Line on %d\n", window);
1368 #endif
1369 win = W_Void2Window(window)->window;
1370 XDrawLine(W_Display, win, colortable[color].contexts[3], x0, y0, x1, y1);
1371 }
1372
1373 void
1374 W_DrawSectorHighlight(window, x, y, w, h, color)
1375 W_Window window;
1376 int x, y, w, h;
1377 W_Color color;
1378 {
1379 Window win;
1380 #ifdef YUCK
1381 XRectangle r[2];
1382
1383 r[0].x = (short) x;
1384 r[0].y = (short) y;
1385 r[0].width = (unsigned short) w;
1386 r[0].height = (unsigned short) h;
1387 r[1].x = (short) x + 2;
1388 r[1].y = (short) y + 2;
1389 r[1].width = (unsigned short) w - 4;
1390 r[1].height = (unsigned short) h - 4;
1391
1392 win = W_Void2Window(window)->window;
1393 XDrawRectangles(W_Display, win, colortable[color].contexts[3],
1394 r, 2);
1395 #else
1396 XRectangle r[1];
1397
1398 r[0].x = (short) x + 2;
1399 r[0].y = (short) y + 2;
1400 r[0].width = (unsigned short) w - 4;
1401 r[0].height = (unsigned short) h - 4;
1402
1403 win = W_Void2Window(window)->window;
1404 XDrawRectangles(W_Display, win, colortable[color].contexts[3],
1405 r, 1);
1406 #endif
1407 }
1408
1409 void
1410 W_WriteTriangle(window, x, y, s, t, color)
1411 W_Window window;
1412 int x, y, s;
1413 int t;
1414 W_Color color;
1415 {
1416 struct window *win = W_Void2Window(window);
1417 XPoint points[3];
1418
1419 if (t == 0) {
1420 points[0].x = x;
1421 points[0].y = y;
1422 points[1].x = x + s;
1423 points[1].y = y - s;
1424 points[2].x = x - s;
1425 points[2].y = y - s;
1426 } else {
1427 points[0].x = x;
1428 points[0].y = y;
1429 points[1].x = x + s;
1430 points[1].y = y + s;
1431 points[2].x = x - s;
1432 points[2].y = y + s;
1433 }
1434
1435
1436 XFillPolygon(W_Display, win->window, colortable[color].contexts[0],
1437 points, 3, Convex, CoordModeOrigin);
1438 }
1439
1440 void
1441 W_WriteText(window, x, y, color, str, len, font)
1442 W_Window window;
1443 int x, y, len;
1444 W_Color color;
1445 W_Font font;
1446 char *str;
1447 {
1448 struct window *win;
1449 int addr;
1450
1451 if (!font)
1452 font = W_RegularFont;
1453 #ifdef DEBUG
1454 printf("Text for %d @ (%d, %d) in %d: [%s]\n", window, x, y, color, str);
1455 #endif
1456 win = W_Void2Window(window);
1457 switch (win->type) {
1458 case WIN_GRAPH:
1459 addr = fonts[fontNum(font)].baseline;
1460 XDrawImageString(W_Display, win->window,
1461 colortable[color].contexts[fontNum(font)], x, y + addr, str, len);
1462 break;
1463 case WIN_SCROLL:
1464 if (y<0) {
1465 XCopyArea(W_Display, win->window, win->window,
1466
1467 colortable[W_White].contexts[0], WIN_EDGE, MENU_PAD,
1468 win->width * W_Textwidth, (win->height - 1) * W_Textheight,
1469 WIN_EDGE, MENU_PAD+W_Textheight);
1470 XClearArea(W_Display, win->window,
1471 WIN_EDGE, MENU_PAD,
1472 W_Textwidth * win->width, W_Textheight, False);
1473 XDrawImageString(W_Display, win->window,
1474 colortable[color].contexts[1],
1475 WIN_EDGE, MENU_PAD + fonts[1].baseline,
1476 str, len);
1477 } else {
1478 XCopyArea(W_Display, win->window, win->window,
1479 colortable[W_White].contexts[0], WIN_EDGE, MENU_PAD + W_Textheight,
1480 win->width * W_Textwidth, (win->height - 1) * W_Textheight,
1481 WIN_EDGE, MENU_PAD);
1482 XClearArea(W_Display, win->window,
1483 WIN_EDGE, MENU_PAD + W_Textheight * (win->height - 1),
1484 W_Textwidth * win->width, W_Textheight, False);
1485 XDrawImageString(W_Display, win->window,
1486 colortable[color].contexts[1],
1487 WIN_EDGE, MENU_PAD + W_Textheight * (win->height - 1) + fonts[1].baseline,
1488 str, len);
1489 }
1490 AddToScrolling(win, color, str, len);
1491 break;
1492 case WIN_MENU:
1493 changeMenuItem(win, y, color, str, len, font);
1494 break;
1495 default:
1496 addr = fonts[fontNum(font)].baseline;
1497 XDrawImageString(W_Display, win->window,
1498 colortable[color].contexts[fontNum(font)],
1499 x * W_Textwidth + WIN_EDGE, MENU_PAD + y * W_Textheight + addr,
1500 str, len);
1501 break;
1502 }
1503 }
1504
1505 void
1506 W_MaskText(window, x, y, color, str, len, font)
1507 W_Window window;
1508 int x, y, len;
1509 W_Color color;
1510 W_Font font;
1511 char *str;
1512 {
1513 struct window *win;
1514 int addr;
1515
1516 addr = fonts[fontNum(font)].baseline;
1517 #ifdef DEBUG
1518 printf("TextMask for %d @ (%d, %d) in %d: [%s]\n", window, x, y, color, str);
1519 #endif
1520 win = W_Void2Window(window);
1521 XDrawString(W_Display, win->window,
1522 colortable[color].contexts[fontNum(font)], x, y + addr, str, len);
1523 }
1524
1525 W_Icon
1526 W_StoreBitmap(width, height, data, window)
1527 int width, height;
1528 W_Window window;
1529 char *data;
1530 {
1531 struct icon *newicon;
1532 struct window *win;
1533
1534 #ifdef DEBUG
1535 printf("Storing bitmap for %d (%d x %d)\n", window, width, height);
1536 fflush(stdout);
1537 #endif
1538 win = W_Void2Window(window);
1539 newicon = (struct icon *) malloc(sizeof(struct icon));
1540 newicon->width = width;
1541 newicon->height = height;
1542 newicon->bitmap = XCreateBitmapFromData(W_Display, win->window,
1543 data, width, height);
1544 newicon->window = win->window;
1545 newicon->pixmap = 0;
1546 return (W_Icon2Void(newicon));
1547 }
1548
1549 void
1550 W_FreeBitmap(bit)
1551 W_Icon bit;
1552 {
1553 struct icon *icon;
1554 icon = W_Void2Icon(bit);
1555 XFreePixmap(W_Display, icon->bitmap);
1556 free(icon);
1557 }
1558
1559 void
1560 W_WriteBitmap(x, y, bit, color)
1561 int x, y;
1562 W_Icon bit;
1563 W_Color color;
1564 {
1565 struct icon *icon;
1566
1567 icon = W_Void2Icon(bit);
1568 #ifdef DEBUG
1569 printf("Writing bitmap to %d\n", icon->window);
1570 #endif
1571
1572 XCopyPlane(W_Display, icon->bitmap, icon->window,
1573 colortable[color].contexts[BITGC], 0, 0, icon->width, icon->height,
1574 x, y, 1);
1575
1576 }
1577
1578 void
1579 W_WriteWinBitmap(win, x, y, bit, color)
1580 W_Window win;
1581 int x, y;
1582 W_Icon bit;
1583 W_Color color;
1584 {
1585 struct icon *icon;
1586 Window original;
1587
1588 icon = W_Void2Icon(bit);
1589 original = icon->window;
1590 icon->window = W_Void2Window(win)->window;
1591 W_WriteBitmap(x, y, bit, color);
1592 icon->window = original;
1593 return;
1594 }
1595
1596 void
1597 W_TileWindow(window, bit)
1598 W_Window window;
1599 W_Icon bit;
1600 {
1601 Window win;
1602 struct icon *icon;
1603
1604 #ifdef DEBUG
1605 printf("Tiling window %d\n", window);
1606 #endif
1607 icon = W_Void2Icon(bit);
1608 win = W_Void2Window(window)->window;
1609
1610 if (icon->pixmap == 0) {
1611 icon->pixmap = XCreatePixmap(W_Display, W_Root,
1612 icon->width, icon->height, DefaultDepth(W_Display, W_Screen));
1613 XCopyPlane(W_Display, icon->bitmap, icon->pixmap,
1614 colortable[W_White].contexts[0], 0, 0, icon->width, icon->height,
1615 0, 0, 1);
1616 }
1617 XSetWindowBackgroundPixmap(W_Display, win, icon->pixmap);
1618 XClearWindow(W_Display, win);
1619
1620 /*
1621 if (icon->pixmap==0) { icon->pixmap=XMakePixmap(icon->bitmap,
1622 colortable[W_White].pixelValue, colortable[W_Black].pixelValue); }
1623 XChangeBackground(win, icon->pixmap); XClear(win);
1624 */
1625 }
1626
1627 void
1628 W_UnTileWindow(window)
1629 W_Window window;
1630 {
1631 Window win;
1632
1633 #ifdef DEBUG
1634 printf("Untiling window %d\n", window);
1635 #endif
1636 win = W_Void2Window(window)->window;
1637
1638 XSetWindowBackground(W_Display, win, colortable[W_Black].pixelValue);
1639 XClearWindow(W_Display, win);
1640 }
1641
1642 W_Window
1643 W_MakeTextWindow(name, x, y, width, height, parent, cursname, border)
1644 char *name;
1645 int x, y, width, height;
1646 W_Window parent;
1647 char *cursname;
1648 int border;
1649 {
1650 return w_MakeWindow(name, x, y, width, height,
1651 parent, cursname, border, W_White, WIN_TEXT);
1652 }
1653
1654 struct window *
1655 newWindow(window, type)
1656 Window window;
1657 int type;
1658 {
1659 struct window *newwin;
1660
1661 newwin = (struct window *) malloc(sizeof(struct window));
1662 newwin->window = window;
1663 newwin->type = type;
1664 newwin->mapped = 0;
1665 newwin->insensitive = 0;
1666 addToHash(newwin);
1667 return (newwin);
1668 }
1669
1670
1671 static struct window *
1672 findWindow(window)
1673 Window window;
1674 {
1675 struct windowlist *entry;
1676
1677 entry = hashtable[hash(window)];
1678 while (entry != NULL) {
1679 if (entry->window->window == window)
1680 return (entry->window);
1681 entry = entry->next;
1682 }
1683 return (NULL);
1684 }
1685
1686 static void
1687 addToHash(win)
1688 struct window *win;
1689 {
1690 struct windowlist **new;
1691
1692 #ifdef DEBUG
1693 printf("Adding to %d\n", hash(win->window));
1694 #endif
1695 new = &hashtable[hash(win->window)];
1696 while (*new != NULL) {
1697 new = &((*new)->next);
1698 }
1699 *new = (struct windowlist *) malloc(sizeof(struct windowlist));
1700 (*new)->next = NULL;
1701 (*new)->window = win;
1702 }
1703
1704 W_Window
1705 W_MakeScrollingWindow(name, x, y, width, height, parent, cursname, border)
1706 char *name;
1707 int x, y, width, height;
1708 W_Window parent;
1709 char *cursname;
1710 int border;
1711 {
1712 return w_MakeWindow(name, x, y, width, height, parent, cursname,
1713 border, W_White, WIN_SCROLL);
1714 }
1715
1716 /* Add a string to the string list of the scrolling window.
1717 */
1718 static void
1719 AddToScrolling(win, color, str, len)
1720 struct window *win;
1721 W_Color color;
1722 char *str;
1723 int len;
1724 {
1725 struct stringList **strings;
1726 char *newstring;
1727 int count;
1728
1729 strings = (struct stringList **) & (win->data);
1730 count = 0;
1731 while ((*strings) != NULL) {
1732 count++;
1733 strings = &((*strings)->next);
1734 }
1735 (*strings) = (struct stringList *) malloc(sizeof(struct stringList));
1736 (*strings)->next = NULL;
1737 (*strings)->color = color;
1738 newstring = (char *) malloc(len + 1);
1739 strncpy(newstring, str, len);
1740 newstring[len] = 0;
1741 (*strings)->string = newstring;
1742 if (count >= 100) { /* Arbitrary large size. */
1743 struct stringList *temp;
1744
1745 temp = (struct stringList *) win->data;
1746 free(temp->string);
1747 temp = temp->next;
1748 free((char *) win->data);
1749 win->data = (char *) temp;
1750 }
1751 }
1752
1753 #ifdef SHORT_PACKETS
1754 void
1755 W_SetSensitive(w, v)
1756 W_Window w;
1757 int v;
1758 {
1759 struct window *win = W_Void2Window(w);
1760
1761 win->insensitive = !v;
1762
1763 if (win->type == WIN_SCROLL)
1764 redrawScrolling(win);
1765 }
1766 #endif
1767
1768 static void
1769 redrawScrolling(win)
1770 struct window *win;
1771 {
1772 int count;
1773 struct stringList *list;
1774 int y;
1775
1776 XClearWindow(W_Display, win->window);
1777 count = 0;
1778 list = (struct stringList *) win->data;
1779 while (list != NULL) {
1780 list = list->next;
1781 count++;
1782 }
1783 list = (struct stringList *) win->data;
1784 while (count > win->height) {
1785 list = list->next;
1786 count--;
1787 }
1788 y = (win->height - count) * W_Textheight + fonts[1].baseline;
1789 if (count == 0)
1790 return;
1791 while (list != NULL) {
1792 XDrawImageString(W_Display, win->window,
1793 colortable[list->color].contexts[1],
1794 WIN_EDGE, MENU_PAD + y, list->string, strlen(list->string));
1795 list = list->next;
1796 y = y + W_Textheight;
1797 }
1798 }
1799
1800 static void
1801 resizeScrolling(win, width, height)
1802 struct window *win;
1803 int width, height;
1804 {
1805 win->height = (height - MENU_PAD * 2) / W_Textheight;
1806 win->width = (width - WIN_EDGE * 2) / W_Textwidth;
1807 XResizeWindow(W_Display, win->window, win->width * W_Textwidth + WIN_EDGE * 2,
1808 win->height * W_Textheight + MENU_PAD * 2);
1809 }
1810
1811 W_Window
1812 W_MakeMenu(name, x, y, width, height, parent, border)
1813 char *name;
1814 int x, y, width, height;
1815 W_Window parent;
1816 int border;
1817 {
1818 return w_MakeWindow(name, x, y, width, height, parent,
1819 "left_ptr", border, W_White, WIN_MENU);
1820 }
1821
1822 static void
1823 redrawMenu(win)
1824 struct window *win;
1825 {
1826 int count;
1827
1828 for (count = 1; count < win->height; count++) {
1829 XFillRectangle(W_Display, win->window,
1830 colortable[W_Grey].contexts[0],
1831 0, count * (W_Textheight + MENU_PAD * 2) + (count - 1) * MENU_BAR,
1832 win->width * W_Textwidth + WIN_EDGE * 2, MENU_BAR);
1833 }
1834 for (count = 0; count < win->height; count++) {
1835 redrawMenuItem(win, count);
1836 }
1837 }
1838
1839 static void
1840 redrawMenuItem(win, n)
1841 struct window *win;
1842 int n;
1843 {
1844 struct menuItem *items;
1845 int addr;
1846
1847 items = (struct menuItem *) win->data;
1848
1849 XFillRectangle(W_Display, win->window,
1850 colortable[W_Black].contexts[0],
1851 WIN_EDGE, n * (W_Textheight + MENU_PAD * 2 + MENU_BAR) + MENU_PAD,
1852 win->width * W_Textwidth, W_Textheight);
1853 if (items[n].string) {
1854 addr = fonts[fontNum(items[n].font)].baseline;
1855 XDrawImageString(W_Display, win->window,
1856 colortable[items[n].color].contexts[fontNum(items[n].font)],
1857 WIN_EDGE,
1858 n * (W_Textheight + MENU_PAD * 2 + MENU_BAR) + MENU_PAD + addr,
1859 items[n].string, strlen(items[n].string));
1860 }
1861 }
1862
1863 static void
1864 changeMenuItem(win, n, color, str, len, font)
1865 struct window *win;
1866 int n;
1867 W_Color color;
1868 char *str;
1869 int len;
1870 W_Font font;
1871 {
1872 struct menuItem *items;
1873 char *news;
1874
1875 items = (struct menuItem *) win->data;
1876 if (items[n].string) {
1877 free(items[n].string);
1878 }
1879 news = malloc(len + 1);
1880 strncpy(news, str, len);
1881 news[len] = 0;
1882 items[n].string = news;
1883 items[n].color = color;
1884 items[n].font = font;
1885 redrawMenuItem(win, n);
1886 XFlush(W_Display);
1887 }
1888
1889 static Cursor
1890 make_cursor(bits, mask, width, height, xhot, yhot)
1891 char *bits, *mask;
1892 int width, height, xhot, yhot;
1893 {
1894 Pixmap cursbits;
1895 Pixmap cursmask;
1896 XColor whiteCol, blackCol;
1897 Cursor curs;
1898
1899 whiteCol.pixel = colortable[W_White].pixelValue;
1900 XQueryColor(W_Display, W_Colormap, &whiteCol);
1901 blackCol.pixel = colortable[W_Black].pixelValue;
1902 XQueryColor(W_Display, W_Colormap, &blackCol);
1903
1904 cursbits = XCreateBitmapFromData(W_Display, DefaultRootWindow(W_Display),
1905 bits, width, height);
1906 cursmask = XCreateBitmapFromData(W_Display, DefaultRootWindow(W_Display),
1907 mask, width, height);
1908
1909 curs = XCreatePixmapCursor(W_Display, cursbits, cursmask,
1910 &whiteCol, &blackCol, xhot, yhot);
1911
1912 XFreePixmap(W_Display, cursbits);
1913 XFreePixmap(W_Display, cursmask);
1914 return curs;
1915 }
1916
1917 #ifdef TCURSORS
1918 #if 1
1919
1920 void
1921 W_DefineTCrossCursor(window)
1922 W_Window window;
1923 {
1924 return;
1925 }
1926
1927 void
1928 W_DefineTextCursor(window)
1929 W_Window window;
1930 {
1931 static Cursor new = 0;
1932 struct window *win = W_Void2Window(window);
1933 XColor f, b;
1934
1935 if (!new) {
1936 f.pixel = colortable[W_Yellow].pixelValue;
1937 b.pixel = colortable[W_Black].pixelValue;
1938
1939 XQueryColor(W_Display, W_Colormap, &f);
1940 XQueryColor(W_Display, W_Colormap, &b);
1941
1942 new = XCreateFontCursor(W_Display, XC_xterm);
1943
1944 XRecolorCursor(W_Display, new, &f, &b);
1945 }
1946 XDefineCursor(W_Display, win->window, new);
1947
1948 return;
1949 }
1950
1951 void
1952 W_RevertCursor(window)
1953 W_Window window;
1954 {
1955 struct window *win = W_Void2Window(window);
1956
1957 XDefineCursor(W_Display, win->window, win->cursor);
1958
1959 return;
1960 }
1961
1962 void
1963 W_DefineCursor(window, width, height, bits, mask, xhot, yhot)
1964 W_Window window;
1965 int width, height, xhot, yhot;
1966 char *bits, *mask;
1967 {
1968 return;
1969 }
1970
1971 #else
1972
1973 #ifdef YUCK
1974 void
1975 W_DefineTCrossCursor(window)
1976 W_Window window;
1977 {
1978 static
1979 Cursor new;
1980 struct window *win = W_Void2Window(window);
1981 static
1982 XColor f, b;
1983
1984 if (new) {
1985 XDefineCursor(W_Display, win->window, new);
1986 return;
1987 }
1988 f.pixel = colortable[W_White].pixelValue;
1989 b.pixel = colortable[W_Black].pixelValue;
1990
1991 XQueryColor(W_Display, W_Colormap, &f);
1992 XQueryColor(W_Display, W_Colormap, &b);
1993
1994 new = XCreateFontCursor(W_Display, XC_tcross);
1995 XRecolorCursor(W_Display, new, &f, &b);
1996 XDefineCursor(W_Display, win->window, new);
1997 }
1998
1999 #else
2000 W_DefineTCrossCursor(window)
2001 W_Window window;
2002 {
2003 W_DefineCursor(window, cross_width, cross_height,
2004 cross_bits, crossmask_bits, cross_x_hot, cross_y_hot);
2005 }
2006
2007 #endif
2008
2009 void
2010 W_DefineTextCursor(window)
2011 W_Window window;
2012 {
2013 static
2014 Cursor new;
2015 struct window *win = W_Void2Window(window);
2016 XColor f, b;
2017
2018 if (new) {
2019 XDefineCursor(W_Display, win->window, new);
2020 return;
2021 }
2022 f.pixel = colortable[W_Yellow].pixelValue;
2023 b.pixel = colortable[W_Black].pixelValue;
2024
2025 XQueryColor(W_Display, W_Colormap, &f);
2026 XQueryColor(W_Display, W_Colormap, &b);
2027
2028 new = XCreateFontCursor(W_Display, XC_xterm);
2029 XRecolorCursor(W_Display, new, &f, &b);
2030 XDefineCursor(W_Display, win->window, new);
2031 }
2032
2033 void
2034 W_DefineCursor(window, width, height, bits, mask, xhot, yhot)
2035 W_Window window;
2036 int width, height, xhot, yhot;
2037 char *bits, *mask;
2038 {
2039 static char *oldbits = NULL;
2040 static Cursor curs;
2041 struct window *win;
2042
2043 #ifdef DEBUG
2044 printf("Defining cursor for %d\n", window);
2045 #endif
2046 win = W_Void2Window(window);
2047 if (!oldbits || oldbits != bits) {
2048 oldbits = bits;
2049 curs = make_cursor(bits, mask, width, height, xhot, yhot);
2050 }
2051 XDefineCursor(W_Display, win->window, curs);
2052 }
2053 #endif
2054 #endif
2055
2056 void
2057 W_Beep()
2058 {
2059 XBell(W_Display, 0);
2060 }
2061
2062 int
2063 W_WindowWidth(window)
2064 W_Window window;
2065 {
2066 return (W_Void2Window(window)->width);
2067 }
2068
2069 int
2070 W_WindowHeight(window)
2071 W_Window window;
2072 {
2073 return (W_Void2Window(window)->height);
2074 }
2075
2076 int
2077 W_Socket()
2078 {
2079 return (ConnectionNumber(W_Display));
2080 }
2081
2082 void
2083 W_DestroyWindow(window)
2084 W_Window window;
2085 {
2086 struct window *win;
2087
2088 #ifdef DEBUG
2089 printf("Destroying %d\n", window);
2090 #endif
2091 win = W_Void2Window(window);
2092 deleteWindow(win);
2093 XDestroyWindow(W_Display, win->window);
2094 free((char *) win);
2095 }
2096
2097 static void
2098 deleteWindow(window)
2099 struct window *window;
2100 {
2101 struct windowlist **rm;
2102 struct windowlist *temp;
2103
2104 rm = &hashtable[hash(window->window)];
2105 while (*rm != NULL && (*rm)->window != window) {
2106 rm = &((*rm)->next);
2107 }
2108 if (*rm == NULL) {
2109 printf("Attempt to delete non-existent window!\n");
2110 return;
2111 }
2112 temp = *rm;
2113 *rm = temp->next;
2114 free((char *) temp);
2115 }
2116
2117 void
2118 W_SetIconWindow(main, icon)
2119 W_Window main;
2120 W_Window icon;
2121 {
2122 XWMHints hints;
2123
2124 XSetIconName(W_Display, W_Void2Window(icon)->window, W_Void2Window(main)->name);
2125
2126 hints.flags = IconWindowHint;
2127 hints.icon_window = W_Void2Window(icon)->window;
2128 XSetWMHints(W_Display, W_Void2Window(main)->window, &hints);
2129 }
2130
2131 static void
2132 checkGeometry(name, x, y, width, height)
2133 char *name;
2134 int *x, *y, *width, *height;
2135 /* fixed so that it handles negative positions 12/21/93 */
2136 /* note that this is NOT standard X syntax, but it was requested */
2137 /* and it's how BRM-Hadley works. [BDyess] */
2138 {
2139 char *adefault;
2140 char buf[100];
2141 char *s;
2142
2143 #ifdef RJC
2144 *x = *y = INVALID_POSITION;
2145 #endif /* RJC */
2146
2147 sprintf(buf, "%s.geometry", name);
2148 adefault = getdefault(buf);
2149 if (adefault == NULL)
2150 return;
2151 /* geometry should be of the form 502x885+1+1, 502x885, or +1+1 */
2152 s = adefault;
2153 if (*s != '+' && *s != '-') {
2154 while (*s != 'x' && *s != 0)
2155 s++;
2156 *width = atoi(adefault);
2157 if (*s == 0)
2158 return;
2159 s++;
2160 adefault = s;
2161 while (*s != '+' && *s != '-' && *s != 0)
2162 s++;
2163 *height = atoi(adefault);
2164 if (*s == 0)
2165 return;
2166 }
2167 adefault = s;
2168 s++;
2169 if (*s == '-')
2170 s++; /* for the case where they have wxh+-x+y */
2171 while (*s != '+' && *s != '-' && *s != 0)
2172 s++;
2173 *x = atoi(adefault + 1);
2174 if (*adefault == '-')
2175 *x = -*x;
2176 if (*s == 0)
2177 return;
2178 *y = atoi(s + 1);
2179 if (*s == '-')
2180 *y = -*y;
2181 /* printf("width: %d, height: %d, x: %d, y: %d\n",*width, *height,*x,*y); */
2182 return;
2183 }
2184
2185 static void
2186 checkParent(name, parent)
2187 char *name;
2188 W_Window *parent;
2189 {
2190 char *adefault;
2191 char buf[100];
2192 int i;
2193 struct windowlist *windows;
2194
2195 sprintf(buf, "%s.parent", name);
2196 adefault = getdefault(buf);
2197 if (adefault == NULL)
2198 return;
2199 /* parent must be name of other window or "root" */
2200 if (strcmpi(adefault, "root") == 0) {
2201 *parent = W_Window2Void(&myroot);
2202 return;
2203 }
2204 for (i = 0; i < HASHSIZE; i++) {
2205 windows = hashtable[i];
2206 while (windows != NULL) {
2207 if (strcmpi(adefault, windows->window->name) == 0) {
2208 *parent = W_Window2Void(windows->window);
2209 return;
2210 }
2211 windows = windows->next;
2212 }
2213 }
2214 }
2215
2216 #ifdef YUCK
2217 #define cross_width 15
2218 #define cross_height 15
2219 #define cross_x_hot 7
2220 #define cross_y_hot 7
2221 static unsigned char cross_bits[] = {
2222 0x00, 0x00, 0xc0, 0x01, 0xa0, 0x02, 0x00, 0x00, 0x80, 0x00, 0x04, 0x10, 0x82, 0x20, 0x56,
2223 0x35, 0x82, 0x20, 0x04, 0x10, 0x80, 0x00, 0x00, 0x00, 0xa0, 0x02, 0xc0, 0x01, 0x00, 0x00};
2224 static unsigned char crossmask_bits[] = {
2225 0xe0, 0x03, 0xf0, 0x07, 0xf0, 0x07, 0xf0, 0x07, 0xce, 0x39, 0xcf, 0x79, 0xff, 0x7f, 0xff,
2226 0x7f, 0xff, 0x7f, 0xcf, 0x79, 0xce, 0x39, 0xf0, 0x07, 0xf0, 0x07, 0xf0, 0x07, 0xe0, 0x03};
2227 #else
2228 #define cross_width 16
2229 #define cross_height 16
2230 #define cross_x_hot 7
2231 #define cross_y_hot 7
2232 static unsigned char cross_bits[] = {
2233 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0xc0, 0x01, 0x80, 0x00,
2234 0x10, 0x04, 0x3f, 0x7e, 0x10, 0x04, 0x80, 0x00, 0xc0, 0x01, 0x80, 0x00,
2235 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00};
2236 static unsigned char crossmask_bits[] = {
2237 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xe0, 0x03, 0xd0, 0x05,
2238 0xbf, 0x7e, 0x7f, 0x7f, 0xbf, 0x7e, 0xd0, 0x05, 0xe0, 0x03, 0xc0, 0x01,
2239 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0x00, 0x00};
2240 #endif
2241
2242 static void
2243 checkCursor(name, cursname, cursor)
2244 char *name;
2245 char *cursname;
2246 Cursor *cursor;
2247 {
2248 char buf[100];
2249 unsigned cnum;
2250 char *adefault;
2251
2252 *cursor = 0;
2253
2254 sprintf(buf, "%s.cursor", name);
2255 adefault = getdefault(buf);
2256 if (adefault == NULL)
2257 adefault = cursname;
2258 if (adefault == NULL)
2259 return;
2260
2261 #ifdef RFCURSORS
2262 cnum = XmuCursorNameToIndex(adefault);
2263 if (cnum != -1) {
2264 XColor f, b;
2265 *cursor = XCreateFontCursor(W_Display, cnum);
2266 if (cnum == XC_xterm) {
2267
2268 f.pixel = colortable[W_Yellow].pixelValue;
2269 b.pixel = colortable[W_Black].pixelValue;
2270
2271 XQueryColor(W_Display, W_Colormap, &f);
2272 XQueryColor(W_Display, W_Colormap, &b);
2273
2274 XRecolorCursor(W_Display, *cursor, &f, &b);
2275 } else if (cnum == XC_pirate) {
2276 f.pixel = colortable[W_Red].pixelValue;
2277 b.pixel = colortable[W_Black].pixelValue;
2278
2279 XQueryColor(W_Display, W_Colormap, &f);
2280 XQueryColor(W_Display, W_Colormap, &b);
2281
2282 XRecolorCursor(W_Display, *cursor, &f, &b);
2283 }
2284 } else
2285 #endif
2286 if (0 == strcmp("bomb here", adefault)) {
2287 static Cursor bomb_here = 0;
2288 if (bomb_here == 0) {
2289 bomb_here = make_cursor(cross_bits, crossmask_bits,
2290 cross_width, cross_height,
2291 cross_x_hot, cross_y_hot);
2292 }
2293 *cursor = bomb_here;
2294 }
2295 }
2296
2297 int
2298 checkMapped(name)
2299 char *name;
2300 {
2301 char buf[100];
2302
2303 sprintf(buf, "%s.mapped", name);
2304 return (booleanDefault(buf, 0));
2305 }
2306
2307 void
2308 W_WarpPointer(window, x, y)
2309 W_Window window;
2310 int x, y;
2311 {
2312 static int warped_from_x = 0, warped_from_y = 0;
2313
2314 if (window == NULL) {
2315 if (W_in_message) {
2316 XWarpPointer(W_Display, None, W_Root, 0, 0, 0, 0, warped_from_x, warped_from_y);
2317 W_in_message = 0;
2318 }
2319 } else {
2320 findMouse(&warped_from_x, &warped_from_y);
2321 XWarpPointer(W_Display, None, W_Void2Window(window)->window, 0, 0, 0, 0, 0, 0);
2322 W_in_message = 1;
2323 }
2324 }
2325
2326 static void
2327 findMouse(x, y)
2328 int *x, *y;
2329 {
2330 Window theRoot, theChild;
2331 int wX, wY, rootX, rootY, status;
2332 unsigned int wButtons;
2333
2334 status = XQueryPointer(W_Display, W_Root, &theRoot, &theChild, &rootX, &rootY, &wX, &wY, &wButtons);
2335 if (status == True) {
2336 *x = wX;
2337 *y = wY;
2338 } else {
2339 *x = 0;
2340 *y = 0;
2341 }
2342 }
2343
2344 int
2345 findMouseInWin(x, y, w)
2346 int *x, *y;
2347 W_Window w;
2348 {
2349 Window theRoot, theChild;
2350 int wX, wY, rootX, rootY, status;
2351 unsigned int wButtons;
2352 struct window *win = W_Void2Window(w);
2353 Window thisWin = win->window;
2354
2355 status = XQueryPointer(W_Display, thisWin, &theRoot, &theChild,
2356 &rootX, &rootY, &wX, &wY, &wButtons);
2357 if (status == True) {
2358 /*
2359 if it's in the window we specified then the values returned should
2360 be within the with and height of the window
2361 */
2362 if (wX <= win->width && wY <= win->height) {
2363 *x = wX;
2364 *y = wY;
2365 return 1;
2366 }
2367 }
2368 *x = 0;
2369 *y = 0;
2370 return 0;
2371 }
2372
2373 #ifdef AUTOKEY
2374 static void
2375 W_Flush()
2376 {
2377 XFlush(W_Display);
2378 }
2379
2380 W_AutoRepeatOff()
2381 {
2382 XAutoRepeatOff(W_Display);
2383 W_Flush();
2384 }
2385
2386 W_AutoRepeatOn()
2387 {
2388 XAutoRepeatOn(W_Display);
2389 W_Flush();
2390 }
2391 #endif /* AUTOKEY */
2392
2393 /* find the width of a font */
2394 int
2395 W_StringWidth(string, font)
2396 char string[];
2397 W_Font font;
2398 {
2399 int x, y;
2400
2401 y = strlen(string);
2402 x = XTextWidth(fonts[fontNum(font)].fontstruct, string, y);
2403 return (x); /* just a guess ?? old never returned! WHS
2404 4/6/93 */
2405 }
2406
2407 void
2408 W_TranslatePoints(w, x, y)
2409 int *x, *y;
2410 W_Window w;
2411 {
2412 struct window *win;
2413 win = W_Void2Window(w);
2414
2415 if (win->type == WIN_TEXT) {
2416 *y = (*y - MENU_PAD) / W_Textheight;
2417 *x = (*x - MENU_PAD) / W_Textwidth;
2418 }
2419 return;
2420 }
2421
2422 #if 0
2423 #define MAKE_WINDOW_GETTER(name, part) \
2424 W_Callback name(w) \
2425 W_Window w; \
2426 { \
2427 return W_Void2Window(w)->part; \
2428 }
2429
2430 #define MAKE_WINDOW_SETTER(name, port) \
2431 W_Callback name(w, c) \
2432 W_Window w; \
2433 W_Callback c; \
2434 { \
2435 W_Void2Window(w)->port = c; \
2436 }
2437
2438 MAKE_WINDOW_GETTER(W_GetWindowKeyDownHandler, handle_keydown);
2439 MAKE_WINDOW_SETTER(W_SetWindowKeyDownHandler, handle_keydown);
2440
2441 MAKE_WINDOW_GETTER(W_GetWindowKeyUpHandler, handle_keyup);
2442 MAKE_WINDOW_SETTER(W_SetWindowKeyUpHandler, handle_keyup);
2443
2444 MAKE_WINDOW_GETTER(W_GetWindowButtonHandler, handle_button);
2445 MAKE_WINDOW_SETTER(W_SetWindowButtonHandler, handle_button);
2446
2447 MAKE_WINDOW_GETTER(W_GetWindowExposeHandler, handle_expose);
2448 MAKE_WINDOW_SETTER(W_SetWindowExposeHandler, handle_expose);
2449 #endif /* 0 */
2450
2451 void
2452 W_ResizeWindow(window, neww, newh) /* TSH 2/93 */
2453 W_Window window;
2454 int neww, newh;
2455 {
2456 Window win = W_Void2Window(window)->window;
2457
2458 XResizeWindow(W_Display, win, (unsigned int) neww, (unsigned int) newh);
2459 }
2460
2461 void
2462 W_ResizeMenu(window, neww, newh)/* TSH 2/93 */
2463 W_Window window;
2464 int neww, newh;
2465 {
2466 W_ResizeWindow(window, neww * W_Textwidth + WIN_EDGE * 2,
2467 newh * (W_Textheight + MENU_PAD * 2) + (newh - 1) * MENU_BAR);
2468 }
2469
2470 void
2471 W_ResizeText(window, neww, newh)/* TSH 2/93 */
2472 W_Window window;
2473 int neww, newh;
2474 {
2475 W_ResizeWindow(window, neww * W_Textwidth + WIN_EDGE * 2,
2476 newh * W_Textheight + MENU_PAD * 2);
2477 }
2478
2479 void
2480 W_Deiconify(window)
2481 W_Window window;
2482 {
2483 struct window *win;
2484 win = W_Void2Window(window);
2485 /* according to ICCCM 4.1.4, this is how you deiconify a window. */
2486 XMapWindow(W_Display, win->window);
2487 }
2488
2489 W_Icon
2490 W_MakeShieldBitmap(width, height, window)
2491 int width, height;
2492 W_Window window;
2493 {
2494 static GC pen = 0;
2495 struct window *win;
2496 struct icon *newicon;
2497
2498 win = W_Void2Window(window);
2499
2500 newicon = (struct icon *) malloc(sizeof(struct icon));
2501 newicon->width = width;
2502 newicon->height = height;
2503 newicon->bitmap = XCreatePixmap(W_Display, win->window, width, height, 1);
2504 newicon->window = win->window;
2505 newicon->pixmap = 0;
2506
2507 pen = XCreateGC(W_Display, newicon->bitmap, 0L, 0);
2508 XSetForeground(W_Display, pen, 0L);
2509 XFillRectangle(W_Display, newicon->bitmap, pen, 0, 0, width, height);
2510 XSetForeground(W_Display, pen, 1L);
2511 XDrawArc(W_Display, newicon->bitmap, pen, 0, 0, width - 1, height - 1, 0, 360 * 64);
2512 XFreeGC(W_Display, pen);
2513
2514 return W_Icon2Void(newicon);
2515 }
2516
2517 #ifdef BEEPLITE
2518 void
2519 W_OverlayBitmap(x, y, bit, color)
2520 int x, y;
2521 W_Icon bit;
2522 W_Color color;
2523 {
2524 struct icon *icon = W_Void2Icon(bit);
2525 #ifdef DEBUG
2526 printf("Overlaying bitmap to %d\n", icon->window);
2527 #endif
2528 XCopyPlane(W_Display, icon->bitmap, icon->window,
2529 colortable[color].contexts[0], 0, 0, icon->width, icon->height,
2530 x, y, 1);
2531 }
2532 #endif