1 /* x11window.c
2 *
3 * Kevin P. Smith 6/11/89 Much modified by Jerry Frain and Joe Young
4 *
5 */
6
7 #define DEBUG 0
8
9 #include "config.h"
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <unistd.h>
13 #include <fcntl.h>
14 #include <errno.h>
15 #include INC_SYS_SELECT
16 #include INC_STRINGS
17 #include <X11/Xlib.h>
18 #include <X11/Xutil.h>
19 #include <X11/cursorfont.h>
20 #include <X11/Xatom.h>
21 #include <X11/keysym.h>
22 #include <assert.h>
23 #include <time.h>
24 #include <sys/time.h>
25 #include INC_SYS_TIMEB
26 #include "Wlib.h"
27 #include "defs.h"
28 #include "struct.h"
29 #include "data.h"
30 #include "teams.bitmap"
31 #include "mapcursor.bitmap"
32 #include "localcursor.bitmap"
33 #include "smessage.h"
34 #include "defaults.h"
35 #include "x11window.h"
36 #include "x11sprite.h"
37 #include "camera.h"
38
39 extern void terminate(int error);
40
41 /* XFIX speedup */
42 #define MAXCACHE 128
43 #define MAX_TEXT_WIDTH 100
44
45 /* changes too good to risk leaving out, by Richard Caley (rjc@cstr.ed.ac.uk) */
46 /* Was #ifdef RJC, but now they're just part of the code */
47
48 #define FONT_SMALL "5x7"
49 #define FONT_NORMAL "6x10"
50 #define FONT_BOLD "-*-clean-bold-r-normal--10-100-75-75-c-60-*"
51 #define FONT_ITALIC "-*-clean-bold-r-normal--10-100-75-75-c-60-*"
52 #define FONT_INDEPENDENT "-*-clean-bold-r-normal--10-100-75-75-c-60-*"
53 #define FONT_BIG "-*-lucidatypewriter-*-*-*-*-40-*-*-*-*-*-*-*"
54 int forceMono = 0;
55
56
57 #ifdef BEEPLITE
58 #define TTS_FONT "10x20"
59 extern void init_tts(void);
60
61 #endif
62
63 #define G_SET_WIDTH 0x1
64 #define G_SET_HEIGHT 0x2
65 #define G_SET_X 0x4
66 #define G_SET_Y 0x8
67
68
69 static char *_nfonts[] =
70 {
71 FONT_NORMAL,
72 "-*-clean-medium-r-normal--10-100-75-75-c-60-*",
73 "fixed",
74 NULL,
75 };
76 static char *_bfonts[] =
77 {
78 FONT_BOLD,
79 "-*-clean-bold-r-normal--10-100-75-75-c-60-*",
80 "fixed",
81 NULL,
82 };
83 static char *_ifonts[] =
84 {
85 FONT_ITALIC,
86 "-*-clean-bold-r-normal--10-100-75-75-c-60-*",
87 "fixed",
88 NULL,
89 };
90 static char *_bgfonts[] =
91 {
92 FONT_BIG,
93 "fixed",
94 "fixed",
95 NULL,
96 };
97 XFontStruct *find_font(char *oldf, char **fonts);
98
99 #define FONTS 4
100 #define BITGC 4
101
102 #define WHITE 0
103 #define BLACK 1
104 #define RED 2
105 #define GREEN 3
106 #define YELLOW 4
107 #define CYAN 5
108 #define GREY 6
109
110 #ifdef RACE_COLORS
111 #define C_ROM 7
112 #define C_KLI 8
113 #define C_FED 9
114 #define C_ORI 10
115 #define C_IND 11
116 #endif
117
118 #ifdef RACE_COLORS
119 #define COLORS 16
120 #define PLANES 4
121 #else
122 #define COLORS 8
123 #define PLANES 3
124 #endif
125
126 #define RaceDefaultOffset (C_ROM - RED)
127
128 extern int takeNearest;
129
130 static int zero = 0;
131 static int one = 1;
132 static int two = 2;
133 static int three = 3;
134
135
136 int W_FastClear = 0;
137 Window W_Root;
138 Colormap W_Colormap;
139 int W_Screen;
140
141 Visual *W_Visual;
142
143 W_Font W_BigFont = (W_Font) & zero, W_RegularFont = (W_Font) & one;
144 W_Font W_HighlightFont = (W_Font) & two, W_UnderlineFont = (W_Font) & three;
145 Display *W_Display;
146 W_Color W_White = WHITE, W_Black = BLACK, W_Red = RED, W_Green = GREEN;
147 W_Color W_Yellow = YELLOW, W_Cyan = CYAN, W_Grey = GREY;
148
149 #ifdef RACE_COLORS
150 W_Color W_Ind = C_IND, W_Fed = C_FED, W_Rom = C_ROM, W_Kli = C_KLI, W_Ori = C_ORI;
151
152 #endif
153 int W_BigTextwidth, W_BigTextheight, W_Textwidth, W_Textheight;
154 char *getdefault(char *str);
155
156 int W_in_message = 0; /* jfy -- for Jerry's warp *
157
158 *
159 *
160 * * message hack */
161
162 /* TTS: moved this out so we can use the 8th color */
163
164 static unsigned long planes[PLANES];
165
166 /* Scrollable message windows */
167 #define SCROLL_THUMB_WIDTH 5
168 static int scrollbar = 1;
169 static int scroll_thumb_width = SCROLL_THUMB_WIDTH;
170 static GC scroll_thumb_gc;
171 static Pixmap scroll_thumb_pixmap;
172 static int scroll_lines = 100; /* save 100 lines */
173
174 Atom wm_protocols, wm_delete_window;
175
176 extern W_Window baseWin;
177 static XClassHint class_hint =
178 {
179 "netrek", "Netrek",
180 };
181
182 static XWMHints wm_hint =
183 {
184 InputHint | StateHint,
185 True,
186 NormalState,
187 None,
188 None,
189 0, 0,
190 None,
191 None,
192 };
193
194 #ifdef WINDOWMAKER
195 char **wm_argv;
196 int wm_argc;
197 #endif
198
199 static W_Event W_myevent;
200 static int W_isEvent = 0; /* an event is being held here for the caller */
201
202 struct fontInfo
203 {
204 int baseline;
205 };
206
207 struct colors
208 {
209 char *name;
210 GC contexts[FONTS + 1];
211 GC insens_contexts[FONTS + 1];
212 Pixmap pixmap;
213 int pixelValue;
214 };
215
216 Pixmap insens_tile;
217
218 struct icon
219 {
220 Window window;
221 Pixmap bitmap;
222 int width, height;
223 Pixmap pixmap;
224 };
225
226 #define WIN_GRAPH 1
227 #define WIN_TEXT 2
228 #define WIN_MENU 3
229 #define WIN_SCROLL 4
230
231 static void changeMenuItem(struct window *win, int col, int n, char *str, W_Color color);
232 static void scrollUp(struct window *win, int y);
233 static void scrollDown(struct window *win, int y);
234 static void scrollPosition(struct window *win, int y);
235 static void scrollTo(struct window *win, struct scrollingWindow *sw, int topline);
236 static void scrollScrolling(W_Event * wevent);
237 static void configureScrolling(struct window *win, int x, int y, int width, int height);
238 static void AddToScrolling(struct window *win, W_Color color, W_Font font, char *str, int len);
239 static void drawThumb(struct window *win, struct scrollingWindow *sw);
240 static void redrawScrolling(struct window *win);
241 static int checkGeometry(char *name, int *x, int *y, int *width, int *height);
242
243 struct stringList
244 {
245 char string[MAX_TEXT_WIDTH];
246 W_Color color;
247 W_Font font;
248 struct stringList *next, *prev;
249 };
250
251 struct menuItem
252 {
253 int column;
254 char *string;
255 W_Color color;
256 };
257
258 struct colors colortable[] =
259 {
260 {"white"},
261 {"black"},
262 {"red"},
263 {"green"},
264 {"yellow"},
265 {"cyan"},
266 {"dark grey"}
267
268 #ifdef RACE_COLORS
269 ,
270 {"Rom"},
271 {"Kli"},
272 {"Fed"},
273 {"Ori"},
274 {"Ind"}
275 #endif
276
277 };
278
279 struct windowlist
280 {
281 struct window *window;
282 struct windowlist *next;
283 };
284
285 #define HASHSIZE 101
286 #define hash(x) (((int) (x)) % HASHSIZE)
287
288 struct windowlist *hashtable[HASHSIZE];
289 struct fontInfo fonts[FONTS];
290
291 struct window *newWindow(Window window, int type);
292 struct window *findWindow(Window window);
293
294 /* char *malloc (size_t); */
295 short *x11tox10bits();
296
297 struct window myroot;
298
299 #define NCOLORS (sizeof(colortable)/sizeof(colortable[0]))
300 #define W_Void2Window(win) ((win) ? ((struct window *) (win)) : (&myroot))
301 #define W_Window2Void(window) ((W_Window) (window))
302 #define W_Void2Icon(bit) ((struct icon *) (bit))
303 #define W_Icon2Void(bit) ((W_Icon) (bit))
304 #define fontNum(font) (*((int *) font))
305 #define TILESIDE 16
306
307 #define WIN_EDGE 5 /* border on l/r edges of *
308 * * text windows */
309 #define MENU_PAD 6 /* border on t/b edges of *
310 * * text windows */
311 #define MENU_BAR 1 /* width of menu bar */
312
313 static char gray[] =
314 {
315 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55,
316 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55,
317 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55,
318 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55
319 };
320
321 static char striped[] =
322 {
323 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
324 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f,
325 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
326 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0
327 };
328
329 static char solid[] =
330 {
331 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
332 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
333 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
334 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
335 };
336
337 int full_screen_default, full_screen_enabled;
338
339 #ifdef FULLSCREEN
340 static void video_mode_off(void);
341 static int video_mode_initialise(void);
342 static void video_mode_on(void);
343 static void view_port_warp(W_Window window);
344 static void pointer_grab_on(W_Window window);
345 static void pointer_grab_off(W_Window window);
346 static void kde_fullscreen_on(W_Window window);
347 static void kde_fullscreen_off(W_Window window);
348 #endif
349
350 /* X debugging */
351 int
_myerror(Display * d,XErrorEvent * e)352 _myerror(Display * d, XErrorEvent * e)
353 {
354 fprintf(stderr, "netrek: x11window: _myerror\n");
355 abort();
356 }
357
pastebuffer(void)358 void pastebuffer(void)
359 {
360 int nbytes, x;
361 char *buff, c;
362
363 buff = XFetchBuffer(W_Display, &nbytes, 0);
364 for (x = 0; x < nbytes; x++)
365 {
366 c = buff[x];
367 smessage(c);
368 }
369 }
370
371 static long
WMXYHintMode_default(void)372 WMXYHintMode_default(void)
373 {
374 static int fetched = 0;
375 static long WMXYHM_default;
376 char *hm_default_string;
377
378 if (!fetched)
379 {
380 hm_default_string = getdefault("WMXYHintMode");
381 if (!hm_default_string || strcmp(hm_default_string, "USPosition") == 0)
382 WMXYHM_default = USPosition;
383 else
384 WMXYHM_default = PPosition;
385 fetched = 1;
386 }
387 return WMXYHM_default;
388 }
389
390
391 void
W_Initialize(char * str)392 W_Initialize(char *str)
393 {
394 int i;
395
396 #if DEBUG > 0
397 printf("Initializing...\n");
398 #endif
399
400 for (i = 0; i < HASHSIZE; i++)
401 {
402 hashtable[i] = NULL;
403 }
404 if ((W_Display = XOpenDisplay(str)) == NULL)
405 {
406 fprintf(stderr, "I can't open your display, twink!\n");
407 terminate(1);
408 }
409
410 /* prevent X socket from being copied to forked exec'd process */
411 if (fcntl(ConnectionNumber(W_Display), F_SETFD, FD_CLOEXEC) < 0)
412 {
413 fprintf(stderr, "failed to set the X socket to close on exec(),\n"
414 "fcntl F_SETFD FD_CLOEXEC failure,\n'%s'",
415 strerror(errno));
416 }
417
418 // uncomment this to synchronise display for testing
419 // XSynchronize(W_Display, True);
420
421 // uncomment this to enable a fatal error handler
422 // XSetErrorHandler(_myerror);
423
424 wm_protocols = XInternAtom(W_Display, "WM_PROTOCOLS", False);
425 wm_delete_window = XInternAtom(W_Display, "WM_DELETE_WINDOW", False);
426
427 W_Root = DefaultRootWindow(W_Display);
428 W_Visual = DefaultVisual(W_Display, DefaultScreen(W_Display));
429 W_Screen = DefaultScreen(W_Display);
430 W_Colormap = DefaultColormap(W_Display, W_Screen);
431 myroot.window = W_Root;
432 myroot.type = WIN_GRAPH;
433 GetFonts();
434 GetColors();
435
436 /* display scroll thumb */
437 scrollbar = booleanDefault("ScrollBar", scrollbar);
438 scroll_lines = intDefault("ScrollSaveLines", scroll_lines);
439 scroll_thumb_width = intDefault("ScrollBarWidth", scroll_thumb_width);
440
441 #ifdef BEEPLITE
442 init_tts();
443 #endif
444 }
445
W_GetPixmaps(W_Window t,W_Window g)446 void W_GetPixmaps(W_Window t, W_Window g)
447 {
448 GetPixmaps(W_Display, &myroot, t, g);
449 }
450
451 /* Make sure the font will work, ie: that it fits in the 6x10 character cell
452 * that we expect. */
checkFont(XFontStruct * fontinfo,char * fontname)453 void checkFont(XFontStruct * fontinfo, char *fontname)
454 {
455 if (small_screen) return;
456 if (fontinfo->max_bounds.width != 6 ||
457 fontinfo->min_bounds.width != 6 ||
458 fontinfo->descent + fontinfo->ascent != 10 ||
459 fontinfo->min_bounds.lbearing < 0 ||
460 fontinfo->max_bounds.rbearing > 6 ||
461 fontinfo->max_bounds.ascent > 8 ||
462 fontinfo->max_bounds.descent > 2) {
463 fprintf(stderr, "Warning: font '%s'\ndoes not conform to 6x10 character cell rules.\n", fontname);
464 }
465 }
466
GetFonts(void)467 void GetFonts(void)
468 {
469 Font regular, italic, bold, big;
470 int i;
471 XGCValues values;
472 XFontStruct *fontinfo;
473 char *fontname;
474 int black, white;
475
476 fontname = getdefault("font");
477 if (fontname == NULL)
478 fontname = small_screen ? FONT_SMALL : FONT_NORMAL;
479 fontinfo = XLoadQueryFont(W_Display, fontname);
480 if (fontinfo == NULL)
481 {
482 fontinfo = find_font(fontname, _nfonts);
483 }
484 if (fontinfo == NULL)
485 {
486 printf("netrek: Can't find any fonts!\n");
487 terminate(1);
488 }
489 checkFont(fontinfo, fontname);
490 regular = fontinfo->fid;
491 W_Textwidth = fontinfo->max_bounds.width;
492 W_Textheight = fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent;
493 fonts[1].baseline = fontinfo->max_bounds.ascent;
494
495 fontname = getdefault("boldfont");
496 if (fontname == NULL)
497 fontname = small_screen ? FONT_SMALL : FONT_BOLD;
498 fontinfo = XLoadQueryFont(W_Display, fontname);
499 if (fontinfo == NULL)
500 {
501 fontinfo = find_font(fontname, _bfonts);
502 }
503 if (fontinfo == NULL)
504 {
505 bold = regular;
506 fonts[2].baseline = fonts[1].baseline;
507 }
508 else
509 {
510 checkFont(fontinfo, fontname);
511 bold = fontinfo->fid;
512 fonts[2].baseline = fontinfo->max_bounds.ascent;
513 if (fontinfo->max_bounds.width > W_Textwidth)
514 W_Textwidth = fontinfo->max_bounds.width;
515 if (fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent > W_Textheight)
516 W_Textheight = fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent;
517 }
518
519 fontname = getdefault("italicfont");
520 if (fontname == NULL)
521 fontname = small_screen ? FONT_SMALL : FONT_ITALIC;
522 fontinfo = XLoadQueryFont(W_Display, fontname);
523 if (fontinfo == NULL)
524 {
525 fontinfo = find_font(fontname, _ifonts);
526 }
527 if (fontinfo == NULL)
528 {
529 italic = regular;
530 fonts[3].baseline = fonts[1].baseline;
531 }
532 else
533 {
534 checkFont(fontinfo, fontname);
535 italic = fontinfo->fid;
536 fonts[3].baseline = fontinfo->max_bounds.ascent;
537 if (fontinfo->max_bounds.width > W_Textwidth)
538 W_Textwidth = fontinfo->max_bounds.width;
539 if (fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent > W_Textheight)
540 W_Textheight = fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent;
541 }
542
543 fontname = getdefault("bigfont");
544 if (fontname == NULL)
545 fontname = small_screen ? FONT_SMALL : FONT_BIG;
546 fontinfo = XLoadQueryFont(W_Display, fontname);
547 if (fontinfo == NULL)
548 {
549 fontinfo = find_font(fontname, _bgfonts);
550 }
551 if (fontinfo == NULL)
552 {
553 big = regular;
554 fonts[0].baseline = fonts[1].baseline;
555 W_BigTextwidth = W_Textwidth;
556 W_BigTextheight = W_Textheight;
557 }
558 else
559 {
560 big = fontinfo->fid;
561 fonts[0].baseline = fontinfo->max_bounds.ascent;
562 W_BigTextwidth = fontinfo->max_bounds.width;
563 W_BigTextheight = fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent;
564 }
565 white = WhitePixel(W_Display, W_Screen);
566 black = BlackPixel(W_Display, W_Screen);
567 insens_tile = XCreatePixmapFromBitmapData(W_Display, W_Root, gray,
568 TILESIDE, TILESIDE, black, white, DefaultDepth(W_Display, W_Screen));
569 for (i = 0; i < NCOLORS; i++)
570 {
571 values.font = big;
572 colortable[i].contexts[0] = XCreateGC(W_Display, W_Root, GCFont, &values);
573 XSetGraphicsExposures(W_Display, colortable[i].contexts[0], False);
574 values.font = regular;
575 colortable[i].contexts[1] = XCreateGC(W_Display, W_Root, GCFont, &values);
576 XSetGraphicsExposures(W_Display, colortable[i].contexts[1], False);
577
578 values.fill_style = FillTiled;
579 values.tile = insens_tile;
580 colortable[i].insens_contexts[1] = XCreateGC(W_Display, W_Root,
581 GCFont | GCFillStyle | GCTile, &values);
582 XSetGraphicsExposures(W_Display, colortable[i].insens_contexts[1],
583 False);
584 values.font = bold;
585 colortable[i].contexts[2] = XCreateGC(W_Display, W_Root, GCFont, &values);
586 XSetGraphicsExposures(W_Display, colortable[i].contexts[2], False);
587 values.font = italic;
588 colortable[i].contexts[3] = XCreateGC(W_Display, W_Root, GCFont, &values);
589 XSetGraphicsExposures(W_Display, colortable[i].contexts[3], False);
590 {
591 char dl[] = {1, 8};
592
593 XSetLineAttributes(W_Display, colortable[i].contexts[3],
594 0, LineOnOffDash, CapButt, JoinMiter);
595 XSetDashes(W_Display, colortable[i].contexts[3], 0, dl, 2);
596 }
597 values.function = GXor;
598 colortable[i].contexts[BITGC] = XCreateGC(W_Display, W_Root, GCFunction,
599 &values);
600 XSetGraphicsExposures(W_Display, colortable[i].contexts[BITGC], False);
601 }
602 }
603 XFontStruct *
find_font(char * oldf,char ** fonts)604 find_font(char *oldf, char **fonts)
605 {
606 XFontStruct *fi;
607 char **f;
608
609 fprintf(stderr, "netrek: Can't find font %s. Trying others...\n",
610 oldf);
611 for (f = fonts; *f; f++)
612 {
613 if (strcmp(*f, oldf) != 0)
614 {
615 if ((fi = XLoadQueryFont(W_Display, *f)))
616 return fi;
617 }
618 }
619 return NULL;
620 }
621
622 static unsigned short extrared[COLORS] =
623 {0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xb0, 0xc0};
624 static unsigned short extragreen[COLORS] =
625 {0x40, 0x60, 0x80, 0xa0, 0xb0, 0xc0, 0x00, 0x20};
626 static unsigned short extrablue[COLORS] =
627 {0x80, 0xa0, 0xb0, 0xc0, 0x00, 0x20, 0x40, 0x60};
628
629
GetColors(void)630 void GetColors(void)
631 {
632 int i, j;
633 XGCValues values;
634 XColor foo;
635 int white, black;
636 unsigned long pixel;
637 char defaultstring[100];
638 char *defaults;
639 unsigned long extracolors[COLORS];
640 XColor colordef;
641
642
643 forceMono = booleanDefault("forcemono", forceMono); /* 11/14/91 TC */
644
645 if ((DisplayCells(W_Display, W_Screen) <= 2) || forceMono)
646 {
647 white = WhitePixel(W_Display, W_Screen);
648 black = BlackPixel(W_Display, W_Screen);
649 for (i = 0; i < NCOLORS; i++)
650 {
651 if (i != W_Black)
652 {
653 colortable[i].pixelValue = white;
654 }
655 else
656 {
657 colortable[i].pixelValue = black;
658 }
659 if (i == W_Red)
660 {
661 colortable[i].pixmap = XCreatePixmapFromBitmapData(W_Display,
662 W_Root, striped, TILESIDE, TILESIDE, white, black,
663 DefaultDepth(W_Display, W_Screen));
664 }
665 else if (i == W_Yellow)
666 {
667 colortable[i].pixmap = XCreatePixmapFromBitmapData(W_Display,
668 W_Root, gray, TILESIDE, TILESIDE, white, black,
669 DefaultDepth(W_Display, W_Screen));
670 }
671 else
672 {
673 colortable[i].pixmap = XCreatePixmapFromBitmapData(W_Display,
674 W_Root, solid, TILESIDE, TILESIDE,
675 colortable[i].pixelValue,
676 colortable[i].pixelValue,
677 DefaultDepth(W_Display, W_Screen));
678 }
679 /* We assume white is 0 or 1, and black is 0 or 1. We adjust * *
680 * graphics function based upon who is who. */
681 if (white == 0)
682 { /* Black is 1 */
683 XSetFunction(W_Display, colortable[i].contexts[BITGC],
684 GXand);
685 }
686 }
687 }
688 else if (W_Visual->class == PseudoColor)
689 {
690 if (!XAllocColorCells(W_Display, W_Colormap, False, planes, PLANES,
691 &pixel, 1) && !takeNearest)
692 {
693 /* couldn't allocate 3 planes, make a new colormap */
694 W_Colormap = XCreateColormap(W_Display, W_Root, W_Visual, AllocNone);
695
696 if (!XAllocColorCells(W_Display, W_Colormap, False, planes, PLANES,
697 &pixel, 1))
698 {
699 fprintf(stderr, "Cannot create new colormap\n");
700 terminate(1);
701 }
702 /* and fill it with at least 8 more colors so when mouse is inside
703 * * * netrek windows, use might be able to see his other windows */
704 if (XAllocColorCells(W_Display, W_Colormap, False, NULL, 0,
705 extracolors, COLORS))
706 {
707 colordef.flags = DoRed | DoGreen | DoBlue;
708
709 for (i = 0; i < COLORS; i++)
710 {
711 colordef.pixel = extracolors[i];
712 colordef.red = extrared[i] << 8;
713 colordef.green = extragreen[i] << 8;
714 colordef.blue = extrablue[i] << 8;
715 XStoreColor(W_Display, W_Colormap, &colordef);
716 }
717 }
718 }
719
720 for (i = 0; i < NCOLORS; i++)
721 {
722 sprintf(defaultstring, "color.%s", colortable[i].name);
723 defaults = getdefault(defaultstring);
724
725 if (defaults == NULL)
726 {
727
728 #ifdef RACE_COLORS
729 if (i > GREY)
730 {
731 /* The default colour from the ROMS is the colour defined *
732 *
733 * * to be RED and not the colour which is actually RED. */
734
735 sprintf(defaultstring, "color.%s",
736 colortable[i - RaceDefaultOffset].name);
737 defaults = getdefault(defaultstring);
738
739 if (defaults == NULL)
740 defaults = colortable[i - RaceDefaultOffset].name;
741 }
742 else
743 #endif
744
745 defaults = colortable[i].name;
746 }
747
748 XParseColor(W_Display, W_Colormap, defaults, &foo);
749
750 switch (i)
751 {
752
753 #ifndef RACE_COLORS
754 case WHITE:
755 foo.pixel = pixel | planes[0] | planes[1] | planes[2];
756 break;
757 case BLACK:
758 foo.pixel = pixel;
759 break;
760 case RED:
761 foo.pixel = pixel | planes[0];
762 break;
763 case CYAN:
764 foo.pixel = pixel | planes[1];
765 break;
766 case YELLOW:
767 foo.pixel = pixel | planes[2];
768 break;
769 case GREY:
770 foo.pixel = pixel | planes[0] | planes[1];
771 break;
772 case GREEN:
773 foo.pixel = pixel | planes[1] | planes[2];
774 break;
775 #else
776 /*
777 * Choose colors so that when two ships overlap, things look
778 * ok. When players overlab, the bits are ORed together. */
779
780 /* Background color */
781 case BLACK:
782 foo.pixel = pixel;
783 break;
784
785 /* Alert colors (sum to grey usually) */
786 case RED:
787 foo.pixel = pixel | planes[1] | planes[2];
788 break;
789 case CYAN:
790 foo.pixel = pixel | planes[1] | planes[3];
791 break;
792 case YELLOW:
793 foo.pixel = pixel | planes[2] | planes[3];
794 break;
795 case GREEN:
796 foo.pixel = pixel | planes[1];
797 break;
798 case GREY:
799 foo.pixel = pixel | planes[1] | planes[2] | planes[3];
800 break;
801
802 /* Your color */
803 case WHITE:
804 foo.pixel = pixel | planes[0];
805 break;
806
807 /* The color of other ships should dominate over your color * *
808 * and should sum to C_IND where possible. */
809 case C_FED:
810 foo.pixel = pixel | planes[0] | planes[1] | planes[2];
811 break;
812 case C_ROM:
813 foo.pixel = pixel | planes[0] | planes[1] | planes[3];
814 break;
815 case C_KLI:
816 foo.pixel = pixel | planes[0] | planes[2] | planes[3];
817 break;
818 case C_ORI:
819 foo.pixel = pixel | planes[0] | planes[1];
820 break;
821 case C_IND:
822 foo.pixel = pixel | planes[0] | planes[1] | planes[2] | planes[3];
823 break;
824 #endif
825 }
826 if (takeNearest)
827 XAllocColor(W_Display, W_Colormap, &foo);
828 else
829 XStoreColor(W_Display, W_Colormap, &foo);
830 colortable[i].pixelValue = foo.pixel;
831 colortable[i].pixmap = XCreatePixmapFromBitmapData(W_Display,
832 W_Root, solid, TILESIDE, TILESIDE, foo.pixel, foo.pixel,
833 DefaultDepth(W_Display, W_Screen));
834 }
835 }
836 else if (W_Visual->class >= TrueColor)
837 {
838 /* Stuff added by sheldon@iastate.edu 5/28/93 This is supposed to * *
839 * detect a TrueColor display, and then do a lookup of the colors in *
840 * * default colormap, instead of creating new colormap. */
841 for (i = 0; i < NCOLORS; i++)
842 {
843 sprintf(defaultstring, "color.%s", colortable[i].name);
844
845 defaults = getdefault(defaultstring);
846 if (defaults == NULL)
847 {
848
849 #ifdef RACE_COLORS
850 if (i > GREY)
851 {
852 /* The default color from the ROMS is the color defined to
853 * * * be RED and not the color which is actually RED. */
854
855 sprintf(defaultstring, "color.%s",
856 colortable[i - RaceDefaultOffset].name);
857 defaults = getdefault(defaultstring);
858
859 if (defaults == NULL)
860 defaults = colortable[i - RaceDefaultOffset].name;
861 }
862 else
863 #endif
864
865 defaults = colortable[i].name;
866 }
867
868
869 XParseColor(W_Display, W_Colormap, defaults, &foo);
870 XAllocColor(W_Display, W_Colormap, &foo);
871 colortable[i].pixelValue = foo.pixel;
872 colortable[i].pixmap = XCreatePixmapFromBitmapData(W_Display,
873 W_Root, solid, TILESIDE, TILESIDE, foo.pixel, foo.pixel,
874 DefaultDepth(W_Display, W_Screen));
875 }
876 }
877 else
878 {
879
880 fprintf(stderr, "Don't know how to deal with a Class %d Visual\n",
881 W_Visual->class);
882 fprintf(stderr, "Your X server is not supported at %d bpp!\n",
883 DefaultDepth(W_Display, W_Screen));
884 terminate(1);
885 }
886 for (i = 0; i < NCOLORS; i++)
887 {
888 for (j = 0; j < FONTS + 1; j++)
889 {
890 XSetForeground(W_Display, colortable[i].contexts[j],
891 colortable[i].pixelValue);
892 XSetBackground(W_Display, colortable[i].contexts[j],
893 colortable[W_Black].pixelValue);
894 }
895 }
896
897 if (scrollbar)
898 {
899 scroll_thumb_pixmap = XCreatePixmapFromBitmapData(W_Display,
900 W_Root, gray, TILESIDE, TILESIDE,
901 colortable[W_White].pixelValue,
902 colortable[W_Black].pixelValue,
903 DefaultDepth(W_Display, W_Screen));
904
905 values.fill_style = FillTiled;
906 values.tile = scroll_thumb_pixmap;
907
908 scroll_thumb_gc = XCreateGC(W_Display, W_Root,
909 GCFillStyle | GCTile, &values);
910 }
911 }
912
W_RenameWindow(W_Window window,char * str)913 void W_RenameWindow(W_Window window, char *str)
914 {
915 struct window *win = W_Void2Window(window);
916 XStoreName(W_Display, win->window, str);
917 }
918
919 W_Window
W_MakeWindow(char * name,int x,int y,int width,int height,W_Window parent,int border,W_Color color)920 W_MakeWindow(char *name, int x, int y, int width, int height, W_Window parent, int border, W_Color color)
921 {
922 struct window *newwin;
923 Window wparent;
924 XSetWindowAttributes attrs;
925 char *window_title = "Netrek", title_buff[257];
926 XSizeHints *sz_hints;
927 int gcheck_result;
928
929 #if DEBUG > 0
930 printf("New window...\n");
931 #endif
932
933 gcheck_result = checkGeometry(name, &x, &y, &width, &height);
934 checkParent(name, &parent);
935 wparent = W_Void2Window(parent)->window;
936 attrs.border_pixel = colortable[color].pixelValue;
937 attrs.event_mask = KeyPressMask | ButtonPressMask | ExposureMask | LeaveWindowMask;
938
939 #ifdef AUTOKEY
940 attrs.event_mask |= KeyReleaseMask;
941 #endif /* AUTOKEY */
942
943 #ifdef MOTION_MOUSE
944 attrs.event_mask |= ButtonMotionMask;
945 #endif
946
947 if (strcmp(name, "netrek_icon") == 0) /* icon should not select *
948 * for input */
949 attrs.event_mask = ExposureMask;
950 attrs.background_pixel = colortable[W_Black].pixelValue;
951 attrs.do_not_propagate_mask = KeyPressMask | ButtonPressMask | ExposureMask;
952 newwin = newWindow(
953 XCreateWindow(W_Display, wparent, x, y, width, height, border,
954 CopyFromParent, InputOutput, CopyFromParent,
955 CWBackPixel | CWEventMask | CWBorderPixel,
956 &attrs),
957 WIN_GRAPH);
958
959 if (!strcmp(name, "netrek")) {
960 if (full_screen_enabled) {
961 #ifdef FULLSCREEN
962 kde_fullscreen_on(W_Window2Void(newwin));
963 #endif
964 }
965 }
966
967 /* top window */
968 sz_hints = XAllocSizeHints();
969 if (strcmp(name, "netrek") == 0 || strcmp(name, "wait") == 0 ||
970 strcmp(name, "waitmotd") == 0)
971 {
972 if (!title && serverName)
973 {
974 if (strcmp(name, "wait") == 0)
975 strcpy(title_buff, serverName);
976 else if (strcmp(name, "waitmotd") == 0)
977 strcpy(title_buff, "Motd-[f]forward, [b]back, [space]unmap");
978 else
979 sprintf(title_buff, "Netrek @ %s", serverName);
980 window_title = title_buff;
981 }
982 else
983 /* but title on command line will override */ if (title)
984 window_title = title;
985 sz_hints->min_width = width;
986 sz_hints->max_width = width;
987 sz_hints->min_height = height;
988 sz_hints->max_height = height;
989 sz_hints->flags = PMinSize | PMaxSize;
990
991 if (!small_screen)
992 /* avoid this check for small_screen; otherwise root window
993 may not be aligned with upper-left corner of screen */
994 if (gcheck_result & G_SET_X || gcheck_result & G_SET_Y)
995 sz_hints->flags |= WMXYHintMode_default();
996 }
997 else
998 {
999 window_title = name;
1000 if (gcheck_result & G_SET_X || gcheck_result & G_SET_Y)
1001 sz_hints->flags |= WMXYHintMode_default();
1002 }
1003 XStoreName(W_Display, newwin->window, window_title);
1004 XSetWMNormalHints(W_Display, newwin->window, sz_hints);
1005 class_hint.res_name = name;
1006 XSetClassHint(W_Display, newwin->window, &class_hint);
1007 XSetWMHints(W_Display, newwin->window, &wm_hint);
1008 newwin->name = strdup(name);
1009 newwin->width = width;
1010 newwin->height = height;
1011 if (wparent != W_Root)
1012 if (checkMapped(name))
1013 W_MapWindow(W_Window2Void(newwin));
1014
1015 #if DEBUG > 0
1016 printf("New graphics window %d, child of %d\n", newwin, parent);
1017 #endif
1018
1019 XSetWindowColormap(W_Display, newwin->window, W_Colormap);
1020 return W_Window2Void(newwin);
1021 }
1022
1023 void
W_ChangeBorder(W_Window window,int color)1024 W_ChangeBorder(W_Window window, int color)
1025 {
1026
1027 #if DEBUG > 2
1028 printf("Changing border of %d\n", window);
1029 #endif
1030
1031 /* fix inexplicable color bug */
1032 if ((DisplayCells(W_Display, W_Screen) <= 2) || forceMono)
1033
1034 XSetWindowBorderPixmap(W_Display, W_Void2Window(window)->window,
1035 colortable[color].pixmap);
1036 else
1037 XSetWindowBorder(W_Display, W_Void2Window(window)->window,
1038 colortable[color].pixelValue);
1039
1040
1041 }
1042
1043 void
W_MapWindow(W_Window window)1044 W_MapWindow(W_Window window)
1045 {
1046 struct window *win;
1047
1048 #if DEBUG > 2
1049 printf("Mapping %d\n", window);
1050 #endif
1051
1052 win = W_Void2Window(window);
1053 if (win->mapped)
1054 return;
1055 win->mapped = 1;
1056 XMapRaised(W_Display, win->window);
1057 }
1058
1059 void
W_UnmapWindow(W_Window window)1060 W_UnmapWindow(W_Window window)
1061 {
1062 struct window *win;
1063
1064 #if DEBUG > 2
1065 printf("UnMapping %d\n", window);
1066 #endif
1067
1068 win = W_Void2Window(window);
1069 if (win->mapped == 0)
1070 return;
1071 win->mapped = 0;
1072 XUnmapWindow(W_Display, win->window);
1073 }
1074
1075 int
W_IsMapped(W_Window window)1076 W_IsMapped(W_Window window)
1077 {
1078 struct window *win;
1079
1080 win = W_Void2Window(window);
1081 if (win == NULL)
1082 return 0;
1083 return win->mapped;
1084 }
1085
1086 void
W_FillArea(W_Window window,int x,int y,int width,int height,W_Color color)1087 W_FillArea(W_Window window, int x, int y, int width, int height, W_Color color)
1088 {
1089 struct window *win;
1090
1091 #if DEBUG > 2
1092 printf("Clearing (%d %d) x (%d %d) with %d on %d\n", x, y, width, height,
1093 color, window);
1094 #endif
1095
1096 win = W_Void2Window(window);
1097 switch (win->type)
1098 {
1099 case WIN_GRAPH:
1100 XFillRectangle(W_Display, win->window, colortable[color].contexts[0],
1101 x, y, width, height);
1102 break;
1103 case WIN_SCROLL:
1104 XFillRectangle(W_Display, win->window, colortable[color].contexts[0],
1105 WIN_EDGE + x * W_Textwidth,
1106 MENU_PAD + y * W_Textheight,
1107 width * W_Textwidth, height * W_Textheight);
1108 break;
1109 default:
1110 XFillRectangle(W_Display, win->window, colortable[color].contexts[0],
1111 WIN_EDGE + x * W_Textwidth, MENU_PAD + y * W_Textheight,
1112 width * W_Textwidth, height * W_Textheight);
1113 }
1114 }
1115
1116 /* XFIX */
1117
1118 static XRectangle _rcache[MAXCACHE];
1119 static int _rcache_index;
1120
1121 static void
FlushClearAreaCache(Window win)1122 FlushClearAreaCache(Window win)
1123 {
1124 XFillRectangles(W_Display, win, colortable[backColor].contexts[0],
1125 _rcache, _rcache_index);
1126 _rcache_index = 0;
1127 }
1128
1129 /* local window only */
1130 void
W_CacheClearArea(W_Window window,int x,int y,int width,int height)1131 W_CacheClearArea(W_Window window, int x, int y, int width, int height)
1132 {
1133 Window win = W_Void2Window(window)->window;
1134 register XRectangle *r;
1135
1136 if (_rcache_index == MAXCACHE)
1137 FlushClearAreaCache(win);
1138
1139 r = &_rcache[_rcache_index++];
1140 r->x = (short) x;
1141 r->y = (short) y;
1142 r->width = (unsigned short) width;
1143 r->height = (unsigned short) height;
1144 }
1145
1146 void
W_FlushClearAreaCache(W_Window window)1147 W_FlushClearAreaCache(W_Window window)
1148 {
1149 Window win = W_Void2Window(window)->window;
1150
1151 if (_rcache_index)
1152 FlushClearAreaCache(win);
1153 }
1154
1155 /* XFIX: clears now instead of filling. */
1156 void
W_ClearArea(W_Window window,int x,int y,int width,int height)1157 W_ClearArea(W_Window window, int x, int y, int width, int height)
1158 {
1159 struct window *win;
1160
1161 win = W_Void2Window(window);
1162 switch (win->type)
1163 {
1164 case WIN_GRAPH:
1165 /* XFIX: changed */
1166 XClearArea(W_Display, win->window, x, y, width, height, False);
1167 break;
1168 case WIN_SCROLL:
1169 XClearArea(W_Display, win->window, WIN_EDGE + x * W_Textwidth,
1170 MENU_PAD + y * W_Textheight,
1171 width * W_Textwidth, height * W_Textheight, False);
1172 break;
1173 default:
1174 /* XFIX: changed */
1175 XClearArea(W_Display, win->window, WIN_EDGE + x * W_Textwidth,
1176 MENU_PAD + y * W_Textheight, width * W_Textwidth, height * W_Textheight, False);
1177 break;
1178 }
1179 }
1180
1181 void
W_ClearWindow(W_Window window)1182 W_ClearWindow(W_Window window)
1183 {
1184
1185 #if DEBUG > 2
1186 printf("Clearing %d\n", window);
1187 #endif
1188
1189 XClearWindow(W_Display, W_Void2Window(window)->window);
1190 }
1191
1192 int
W_Pending(void)1193 W_Pending(void)
1194 {
1195 return XPending(W_Display);
1196 }
1197
1198 int
W_EventsPending(void)1199 W_EventsPending(void)
1200 {
1201 if (W_isEvent)
1202 return 1;
1203 while (XPending(W_Display))
1204 {
1205 if (W_SpNextEvent(&W_myevent))
1206 {
1207 W_isEvent = 1;
1208 return 1;
1209 }
1210 }
1211 return 0;
1212 }
1213
1214 void
W_NextEvent(W_Event * wevent)1215 W_NextEvent(W_Event * wevent)
1216 {
1217 if (W_isEvent)
1218 {
1219 *wevent = W_myevent;
1220 W_isEvent = 0;
1221 return;
1222 }
1223 while (W_SpNextEvent(wevent) == 0);
1224 }
1225
sym_to_key(int sym)1226 static unsigned char sym_to_key(int sym)
1227 {
1228 switch (sym) {
1229 case XK_Up: return W_Key_Up;
1230 case XK_Down: return W_Key_Down;
1231 }
1232 return 0;
1233 }
1234
1235 int
W_SpNextEvent(W_Event * wevent)1236 W_SpNextEvent(W_Event * wevent)
1237 {
1238 XEvent event;
1239 XKeyEvent *key;
1240 XButtonEvent *button;
1241 XExposeEvent *expose;
1242 XConfigureEvent *configure;
1243
1244 #ifdef MOTION_MOUSE
1245 XMotionEvent *motion;
1246 static int prev_x, prev_y;
1247 int thresh;
1248 #endif
1249
1250 #ifdef CONTROL_KEY
1251 int control_key = 0;
1252 #endif
1253 unsigned char ch;
1254 int nch;
1255 struct window *win;
1256 KeySym sym;
1257
1258 #if DEBUG > 1
1259 printf("event");
1260 #endif
1261
1262 key = (XKeyEvent *) & event;
1263 button = (XButtonEvent *) & event;
1264 expose = (XExposeEvent *) & event;
1265 configure = (XConfigureEvent *) & event;
1266
1267 #ifdef MOTION_MOUSE
1268 motion = (XMotionEvent *) & event;
1269 #endif
1270
1271 for (;;)
1272 {
1273 XNextEvent(W_Display, &event);
1274
1275 #if DEBUG > 1
1276 printf(", read type=%d\n", event.type);
1277 #endif
1278 win = findWindow(key->window);
1279 if (win == NULL)
1280 return 0;
1281 if (key->send_event == True && event.type != ClientMessage)
1282 return 0; /* event sent by another client */
1283 if ((event.type == KeyPress || event.type == ButtonPress) &&
1284 win->type == WIN_MENU)
1285 {
1286 if (key->y % (W_Textheight + MENU_PAD * 2 + MENU_BAR) >=
1287 W_Textheight + MENU_PAD * 2)
1288 return 0;
1289 key->y = key->y / (W_Textheight + MENU_PAD * 2 + MENU_BAR);
1290 }
1291 switch ((int) event.type)
1292 {
1293 case ClientMessage:
1294 if (event.xclient.message_type == wm_protocols &&
1295 event.xclient.data.l[0] == wm_delete_window)
1296 {
1297 W_UnmapWindow(W_Window2Void(win));
1298 wevent->type = W_EV_CLOSED;
1299 wevent->Window = W_Window2Void(win);
1300 wevent->key = wevent->x = wevent->y = 0;
1301 return 1;
1302 }
1303 break;
1304
1305 case LeaveNotify: /* for message window -- jfy */
1306 if (win == (struct window *) messagew)
1307 {
1308 W_in_message = 0;
1309 }
1310 return 0;
1311 break;
1312 case KeyPress:
1313 if ((key->state & LockMask) && !(key->state & ShiftMask) &&
1314 (ignoreCaps))
1315 {
1316 printf("Got a capslock!\n");
1317 key->state = key->state & ~LockMask;
1318 }
1319
1320 #ifdef CONTROL_KEY
1321 if (key->state & ControlMask && use_control_key)
1322 {
1323 control_key = 1;
1324 key->state = key->state & ~ControlMask;
1325 }
1326 else
1327 control_key = 0;
1328 #endif
1329
1330 nch = XLookupString(key, (char *) &ch, 1, &sym, NULL);
1331 if (nch == 0) {
1332 ch = sym_to_key(sym);
1333 if (ch == 0) return 0;
1334 }
1335 #ifdef MOUSE_AS_SHIFT
1336 if (mouse_as_shift)
1337 {
1338 if (key->state & Button1Mask)
1339 {
1340 wevent->modifier = W_LBUTTON;
1341 wevent->type = W_EV_MKEY;
1342 }
1343 else if (key->state & Button2Mask)
1344 {
1345 wevent->modifier = W_MBUTTON;
1346 wevent->type = W_EV_MKEY;
1347 }
1348 else if (key->state & Button3Mask)
1349 {
1350 wevent->modifier = W_RBUTTON;
1351 wevent->type = W_EV_MKEY;
1352 }
1353 else
1354 {
1355 wevent->type = W_EV_KEY;
1356 }
1357 }
1358 else
1359 wevent->type = W_EV_KEY;
1360 #else
1361 wevent->type = W_EV_KEY;
1362 #endif
1363
1364 wevent->Window = W_Window2Void(win);
1365 wevent->x = key->x;
1366 wevent->y = key->y;
1367
1368 #ifdef CONTROL_KEY
1369 if (control_key)
1370 wevent->key = (unsigned char) (ch + 96);
1371 else
1372 wevent->key = ch;
1373 #else
1374 wevent->key = ch;
1375 #endif
1376
1377 return 1;
1378 break;
1379
1380 #ifdef AUTOKEY
1381 case KeyRelease:
1382 if (XLookupString(key, &ch, 1, NULL, NULL) > 0)
1383 {
1384 wevent->type = W_EV_KEY_OFF;
1385 wevent->Window = W_Window2Void(win);
1386 wevent->x = key->x;
1387 wevent->y = key->y;
1388 wevent->key = ch;
1389 return 1;
1390 }
1391 return 0;
1392 break;
1393 #endif /* AUTOKEY */
1394
1395 case ButtonPress:
1396 wevent->type = W_EV_BUTTON;
1397 wevent->Window = W_Window2Void(win);
1398
1399 #ifdef MOTION_MOUSE
1400 prev_x = wevent->x = button->x;
1401 prev_y = wevent->y = button->y;
1402 #else
1403 wevent->x = button->x;
1404 wevent->y = button->y;
1405 #endif
1406
1407
1408 #ifdef MOUSE_AS_SHIFT
1409 if (mouse_as_shift &&
1410 (wevent->Window == mapw || wevent->Window == w))
1411 switch (button->button & 0xf)
1412 {
1413 case Button3:
1414 if (b3_as_shift)
1415 return 0;
1416 break;
1417 case Button1:
1418 if (b1_as_shift)
1419 return 0;
1420 break;
1421 case Button2:
1422 if (b2_as_shift)
1423 return 0;
1424 break;
1425 }
1426 #endif
1427
1428 switch (button->button & 0xf)
1429 {
1430 case Button3:
1431 wevent->key = W_RBUTTON;
1432 break;
1433 case Button1:
1434 wevent->key = W_LBUTTON;
1435 break;
1436 case Button2:
1437 wevent->key = W_MBUTTON;
1438 break;
1439 #ifdef Button4
1440 case Button4:
1441 wevent->key = W_WUBUTTON;
1442 break;
1443 #endif
1444 #ifdef Button5
1445 case Button5:
1446 wevent->key = W_WDBUTTON;
1447 break;
1448 #endif
1449 #ifdef Button6
1450 case Button6:
1451 wevent->key = W_X1BUTTON;
1452 break;
1453 #endif
1454 #ifdef Button7
1455 case Button7:
1456 wevent->key = W_X2BUTTON;
1457 break;
1458 #endif
1459 }
1460
1461 #ifdef SHIFTED_MOUSE
1462 if (extended_mouse)
1463 {
1464 if (button->state & (ControlMask | ShiftMask))
1465 {
1466
1467 if (button->state & ShiftMask)
1468 {
1469 wevent->key |= W_SHIFT_BUTTON;
1470 }
1471
1472 if (button->state & ControlMask)
1473 {
1474 wevent->key |= W_CTRL_BUTTON;
1475 }
1476
1477 return 1;
1478 }
1479
1480 }
1481 #endif
1482
1483 if (win->type == WIN_SCROLL)
1484 {
1485 scrollScrolling(wevent);
1486 return 0;
1487 }
1488 return 1;
1489
1490 #ifdef MOTION_MOUSE
1491 case MotionNotify:
1492 if (!motion_mouse ||
1493 (!motion_mouse_enablable && !motion_mouse_steering))
1494 return 0;
1495 wevent->type = W_EV_CM_BUTTON;
1496 wevent->Window = W_Window2Void(win);
1497
1498 thresh = abs(prev_x - motion->x) + abs(prev_y - motion->y);
1499
1500 if (thresh < user_motion_thresh)
1501 return 0;
1502
1503 prev_x = wevent->x = motion->x;
1504 prev_y = wevent->y = motion->y;
1505
1506
1507 #ifdef MOUSE_AS_SHIFT
1508 if (mouse_as_shift &&
1509 (wevent->Window == mapw || wevent->Window == w))
1510 switch (button->button & 0xf)
1511 {
1512 case Button3:
1513 if (b3_as_shift)
1514 return 0;
1515 break;
1516 case Button1:
1517 if (b1_as_shift)
1518 return 0;
1519 break;
1520 case Button2:
1521 if (b2_as_shift)
1522 return 0;
1523 break;
1524 }
1525 #endif
1526
1527 switch (button->button & 0xf)
1528 {
1529 case Button3:
1530 wevent->key = W_RBUTTON;
1531 break;
1532 case Button1:
1533 wevent->key = W_LBUTTON;
1534 break;
1535 case Button2:
1536 wevent->key = W_MBUTTON;
1537 break;
1538 #ifdef Button4
1539 case Button4:
1540 wevent->key = W_WUBUTTON;
1541 break;
1542 #endif
1543 #ifdef Button5
1544 case Button5:
1545 wevent->key = W_WDBUTTON;
1546 break;
1547 #endif
1548 #ifdef Button6
1549 case Button6:
1550 wevent->key = W_X1BUTTON;
1551 break;
1552 #endif
1553 #ifdef Button7
1554 case Button7:
1555 wevent->key = W_X2BUTTON;
1556 break;
1557 #endif
1558 }
1559
1560 #ifdef SHIFTED_MOUSE
1561 if (extended_mouse)
1562 {
1563 if (button->state & (ControlMask | ShiftMask))
1564 {
1565
1566 if (button->state & ShiftMask)
1567 {
1568 wevent->key |= W_SHIFT_BUTTON;
1569 }
1570
1571 if (button->state & ControlMask)
1572 {
1573 wevent->key |= W_CTRL_BUTTON;
1574 }
1575
1576 return 1;
1577 }
1578 }
1579 #endif
1580
1581 return 1;
1582 #endif
1583
1584 case Expose:
1585 if (expose->count != 0)
1586 return 0;
1587 if (win->type == WIN_SCROLL)
1588 {
1589 configureScrolling(win, expose->x, expose->y,
1590 expose->width, expose->height);
1591 redrawScrolling(win);
1592 return 0;
1593 }
1594 if (win->type == WIN_MENU)
1595 {
1596 redrawMenu(win);
1597 return 0;
1598 }
1599
1600 wevent->type = W_EV_EXPOSE;
1601 wevent->Window = W_Window2Void(win);
1602 return 1;
1603 case ConfigureNotify:
1604 configureScrolling(win, configure->x, configure->y,
1605 configure->width, configure->height);
1606 break;
1607 default:
1608 return 0;
1609 break;
1610 }
1611 }
1612 }
1613
1614 void
W_MakeLine(W_Window window,int x0,int y0,int x1,int y1,W_Color color)1615 W_MakeLine(W_Window window, int x0, int y0, int x1, int y1, W_Color color)
1616 {
1617 Window win;
1618
1619 #if DEBUG > 3
1620 printf("Line on %d\n", window);
1621 #endif
1622
1623 win = W_Void2Window(window)->window;
1624 XDrawLine(W_Display, win, colortable[color].contexts[0], x0, y0, x1, y1);
1625 }
1626
1627 /* XFIX */
1628
1629 static XSegment _lcache[NCOLORS][MAXCACHE];
1630 static int _lcache_index[NCOLORS];
1631
1632 static void
FlushLineCache(Window win,int color)1633 FlushLineCache(Window win, int color)
1634 {
1635 XDrawSegments(W_Display, win, colortable[color].contexts[0],
1636 _lcache[color], _lcache_index[color]);
1637 _lcache_index[color] = 0;
1638 }
1639
1640 /* for local window only */
1641 void
W_CacheLine(W_Window window,int x0,int y0,int x1,int y1,int color)1642 W_CacheLine(W_Window window, int x0, int y0, int x1, int y1, int color)
1643 {
1644 Window win = W_Void2Window(window)->window;
1645 register XSegment *s;
1646
1647 if (_lcache_index[color] == MAXCACHE)
1648 FlushLineCache(win, color);
1649
1650 s = &_lcache[color][_lcache_index[color]++];
1651 s->x1 = (short) x0;
1652 s->y1 = (short) y0;
1653 s->x2 = (short) x1;
1654 s->y2 = (short) y1;
1655 }
1656
1657 void
W_FlushLineCaches(W_Window window)1658 W_FlushLineCaches(W_Window window)
1659 {
1660 Window win = W_Void2Window(window)->window;
1661 int i;
1662
1663 for (i = 0; i < NCOLORS; i++)
1664 {
1665 if (_lcache_index[i])
1666 FlushLineCache(win, i);
1667 }
1668 }
1669
1670 void
W_MakeTractLine(W_Window window,int x0,int y0,int x1,int y1,W_Color color)1671 W_MakeTractLine(W_Window window, int x0, int y0, int x1, int y1, W_Color color)
1672 {
1673 Window win;
1674
1675 #if DEBUG > 3
1676 printf("Line on %d\n", window);
1677 #endif
1678
1679 win = W_Void2Window(window)->window;
1680 XDrawLine(W_Display, win, colortable[color].contexts[3], x0, y0, x1, y1);
1681 }
1682
1683 void
W_MakePhaserLine(W_Window window,int x0,int y0,int x1,int y1,W_Color color)1684 W_MakePhaserLine(W_Window window, int x0, int y0, int x1, int y1, W_Color color)
1685 {
1686 Window win;
1687
1688 #if DEBUG > 3
1689 printf("Line on %d\n", window);
1690 #endif
1691
1692 win = W_Void2Window(window)->window;
1693 XDrawLine(W_Display, win, colortable[color].contexts[1], x0, y0, x1, y1);
1694 }
1695
W_WriteCircle(W_Window window,int x,int y,int r,W_Color color)1696 void W_WriteCircle (W_Window window,
1697 int x,
1698 int y,
1699 int r,
1700 W_Color color)
1701 {
1702 struct window *win = W_Void2Window(window);
1703
1704 XSetForeground(W_Display, colortable[color].contexts[0],
1705 colortable[color].pixelValue);
1706 XDrawArc(W_Display, win->window, colortable[color].contexts[0],
1707 x, y, r, r, 0, 23040);
1708 }
1709
1710 void
W_WriteTriangle(W_Window window,int x,int y,int s,int t,W_Color color)1711 W_WriteTriangle(W_Window window, int x, int y, int s, int t, W_Color color)
1712 {
1713 struct window *win = W_Void2Window(window);
1714 XPoint points[4];
1715
1716 if (t == 0)
1717 {
1718 points[0].x = x;
1719 points[0].y = y;
1720 points[1].x = x + s;
1721 points[1].y = y - s;
1722 points[2].x = x - s;
1723 points[2].y = y - s;
1724 points[3].x = x;
1725 points[3].y = y;
1726 }
1727 else
1728 {
1729 points[0].x = x;
1730 points[0].y = y;
1731 points[1].x = x + s;
1732 points[1].y = y + s;
1733 points[2].x = x - s;
1734 points[2].y = y + s;
1735 points[3].x = x;
1736 points[3].y = y;
1737 }
1738
1739
1740 XDrawLines(W_Display, win->window, colortable[color].contexts[0],
1741 points, 4, CoordModeOrigin);
1742 }
1743
1744 void
W_WriteText(W_Window window,int x,int y,W_Color color,char * str,int len,W_Font font)1745 W_WriteText(W_Window window, int x, int y, W_Color color, char *str, int len, W_Font font)
1746 {
1747 struct window *win;
1748 int addr;
1749
1750 #if DEBUG > 3
1751 printf("Text for %d @ (%d, %d) in %d: [%s]\n", window, x, y, color, str);
1752 #endif
1753
1754 if (font == 0)
1755 font = W_RegularFont;
1756 win = W_Void2Window(window);
1757
1758 switch (win->type)
1759 {
1760 case WIN_GRAPH:
1761 addr = fonts[fontNum(font)].baseline;
1762 if (len < 0) len = strlen(str);
1763 XDrawImageString(W_Display, win->window,
1764
1765 #ifdef SHORT_PACKETS
1766 win->insensitive ?
1767 colortable[color].insens_contexts[1] :
1768 colortable[color].contexts[fontNum(font)],
1769 #else
1770 colortable[color].contexts[fontNum(font)],
1771 #endif
1772
1773 x, y + addr, str, len);
1774 break;
1775 case WIN_SCROLL:
1776 XCopyArea(W_Display, win->window, win->window,
1777 colortable[W_White].contexts[0], WIN_EDGE, MENU_PAD + W_Textheight,
1778 win->width * W_Textwidth, (win->height - 1) * W_Textheight,
1779 WIN_EDGE, MENU_PAD);
1780 XClearArea(W_Display, win->window,
1781 WIN_EDGE, MENU_PAD + W_Textheight * (win->height - 1),
1782 W_Textwidth * win->width, W_Textheight, False);
1783 if (len < 0) len = strlen(str);
1784 XDrawImageString(W_Display, win->window,
1785
1786 #ifdef SHORT_PACKETS
1787 win->insensitive ?
1788 colortable[color].insens_contexts[1] :
1789 colortable[color].contexts[fontNum(font)],
1790 #else
1791 colortable[color].contexts[fontNum(font)],
1792 #endif
1793
1794 WIN_EDGE, MENU_PAD + W_Textheight * (win->height - 1) + fonts[fontNum(font)].baseline,
1795 str, len);
1796 AddToScrolling(win, color, font, str, len);
1797 break;
1798 case WIN_MENU:
1799 changeMenuItem(win, x, y, str, color);
1800 break;
1801 default:
1802 addr = fonts[fontNum(font)].baseline;
1803 if (len < 0) len = strlen(str);
1804 XDrawImageString(W_Display, win->window,
1805
1806 #ifdef SHORT_PACKETS
1807 win->insensitive ?
1808 colortable[color].insens_contexts[1] :
1809 colortable[color].contexts[fontNum(font)],
1810 #else
1811 colortable[color].contexts[fontNum(font)],
1812 #endif
1813
1814 x * W_Textwidth + WIN_EDGE, MENU_PAD + y * W_Textheight + addr,
1815 str, len);
1816 break;
1817 }
1818 }
1819
1820 void
W_MaskText(W_Window window,int x,int y,W_Color color,char * str,int len,W_Font font)1821 W_MaskText(W_Window window, int x, int y, W_Color color, char *str, int len, W_Font font)
1822 {
1823 struct window *win;
1824 int addr;
1825
1826 addr = fonts[fontNum(font)].baseline;
1827
1828 #if DEBUG > 3
1829 printf("TextMask for %d @ (%d, %d) in %d: [%s]\n", window, x, y, color, str);
1830 #endif
1831
1832 win = W_Void2Window(window);
1833 XDrawString(W_Display, win->window,
1834 colortable[color].contexts[fontNum(font)], x, y + addr, str, len);
1835 }
1836
1837 W_Icon
W_StoreBitmap(int width,int height,char * data,W_Window window)1838 W_StoreBitmap(int width, int height, char *data, W_Window window)
1839 {
1840 struct icon *newicon;
1841 struct window *win;
1842
1843 #if DEBUG > 0
1844 printf("Storing bitmap for %d (%d x %d)\n", window, width, height);
1845 fflush(stdout);
1846 #endif
1847
1848 win = W_Void2Window(window);
1849 newicon = (struct icon *) malloc(sizeof(struct icon));
1850
1851 newicon->width = width;
1852 newicon->height = height;
1853 newicon->bitmap = XCreateBitmapFromData(W_Display, win->window,
1854 data, width, height);
1855
1856 #ifdef nodef
1857 /* XFIX: changed to Pixmap */
1858 white = WhitePixel(W_Display, W_Screen);
1859 black = BlackPixel(W_Display, W_Screen);
1860 newicon->bitmap = XCreatePixmapFromBitmapData(W_Display, W_Root, data,
1861 width, height, white, black,
1862 DefaultDepth(W_Display,
1863 W_Screen));
1864 #endif /* nodef */
1865
1866 newicon->window = win->window;
1867 newicon->pixmap = 0;
1868 return W_Icon2Void(newicon);
1869 }
1870
1871 void
W_WriteBitmap(int x,int y,W_Icon bit,W_Color color)1872 W_WriteBitmap(int x, int y, W_Icon bit, W_Color color)
1873 {
1874 struct icon *icon;
1875
1876 icon = W_Void2Icon(bit);
1877
1878 #if DEBUG > 4
1879 printf("Writing bitmap to %d\n", icon->window);
1880 #endif
1881
1882 XCopyPlane(W_Display, icon->bitmap, icon->window,
1883 colortable[color].contexts[BITGC], 0, 0, icon->width, icon->height,
1884 x, y, 1);
1885
1886 #ifdef nodef
1887 /* XFIX : copyarea */
1888 XCopyArea(W_Display, icon->bitmap, icon->window,
1889 colortable[color].contexts[BITGC], 0, 0, icon->width, icon->height,
1890 x, y);
1891 #endif
1892 }
1893
1894
1895 void
W_TileWindow(W_Window window,W_Icon bit)1896 W_TileWindow(W_Window window, W_Icon bit)
1897 {
1898 Window win;
1899 struct icon *icon;
1900
1901 #if DEBUG > 4
1902 printf("Tiling window %d\n", window);
1903 #endif
1904
1905 icon = W_Void2Icon(bit);
1906 win = W_Void2Window(window)->window;
1907
1908 if (icon->pixmap == 0)
1909 {
1910 icon->pixmap = XCreatePixmap(W_Display, W_Root,
1911 icon->width, icon->height, DefaultDepth(W_Display, W_Screen));
1912 XCopyPlane(W_Display, icon->bitmap, icon->pixmap,
1913 colortable[W_White].contexts[0], 0, 0, icon->width, icon->height,
1914 0, 0, 1);
1915 }
1916 XSetWindowBackgroundPixmap(W_Display, win, icon->pixmap);
1917 XClearWindow(W_Display, win);
1918
1919 /* if (icon->pixmap==0) { icon->pixmap=XMakePixmap(icon->bitmap, * *
1920 * colortable[W_White].pixelValue, colortable[W_Black].pixelValue); } * *
1921 * XChangeBackground(win, icon->pixmap); XClear(win); */
1922 }
1923
1924 void
W_UnTileWindow(W_Window window)1925 W_UnTileWindow(W_Window window)
1926 {
1927 Window win;
1928
1929 #if DEBUG > 4
1930 printf("Untiling window %d\n", window);
1931 #endif
1932
1933 win = W_Void2Window(window)->window;
1934
1935 XSetWindowBackground(W_Display, win, colortable[W_Black].pixelValue);
1936 XClearWindow(W_Display, win);
1937 }
1938
1939 W_Window
W_MakeTextWindow(char * name,int x,int y,int width,int height,W_Window parent,int border)1940 W_MakeTextWindow(char *name, int x, int y, int width, int height, W_Window parent, int border)
1941 {
1942 struct window *newwin;
1943 Window wparent;
1944 XSetWindowAttributes attrs;
1945 XSizeHints *sz_hints;
1946 int gcheck_result;
1947
1948 #if DEBUG > 0
1949 printf("New window...\n");
1950 #endif
1951
1952 gcheck_result = checkGeometry(name, &x, &y, &width, &height);
1953 checkParent(name, &parent);
1954 attrs.border_pixel = colortable[W_White].pixelValue;
1955 attrs.event_mask = ExposureMask;
1956
1957 #ifdef AUTOKEY
1958 attrs.event_mask |= KeyReleaseMask;
1959 #endif /* AUTOKEY */
1960
1961 #ifdef SHORT_PACKETS
1962 attrs.event_mask |= ButtonPressMask;
1963 #endif
1964
1965 attrs.background_pixel = colortable[W_Black].pixelValue;
1966 attrs.do_not_propagate_mask = ExposureMask;
1967 wparent = W_Void2Window(parent)->window;
1968 newwin = newWindow(
1969 XCreateWindow(W_Display, wparent, x, y,
1970 width * W_Textwidth + WIN_EDGE * 2, MENU_PAD * 2 + height * W_Textheight,
1971 border, CopyFromParent, InputOutput, CopyFromParent,
1972 CWBackPixel | CWEventMask |
1973 CWBorderPixel,
1974 &attrs),
1975 WIN_TEXT);
1976 class_hint.res_name = name;
1977 sz_hints = XAllocSizeHints();
1978 sz_hints->min_width = WIN_EDGE * 2 + width * W_Textwidth;
1979 sz_hints->max_width = WIN_EDGE * 2 + width * W_Textwidth;
1980 sz_hints->base_width = WIN_EDGE * 2;
1981 sz_hints->width_inc = W_Textwidth;
1982 sz_hints->min_height = MENU_PAD * 2 + 3 * W_Textheight;
1983 sz_hints->max_height = MENU_PAD * 2 + height * W_Textheight;
1984 sz_hints->base_height = MENU_PAD * 2 + 2 * W_Textheight;
1985 sz_hints->height_inc = W_Textheight;
1986 sz_hints->flags = PResizeInc | PMinSize | PMaxSize | PBaseSize;
1987 if (gcheck_result & G_SET_X || gcheck_result & G_SET_Y)
1988 sz_hints->flags |= WMXYHintMode_default();
1989 XStoreName(W_Display, newwin->window, name);
1990 XSetWMNormalHints(W_Display, newwin->window, sz_hints);
1991 XSetClassHint(W_Display, newwin->window, &class_hint);
1992 XSetWMHints(W_Display, newwin->window, &wm_hint);
1993 newwin->name = strdup(name);
1994 newwin->width = width;
1995 newwin->height = height;
1996 if (wparent != W_Root)
1997 if (checkMapped(name))
1998 W_MapWindow(W_Window2Void(newwin));
1999
2000 #if DEBUG > 0
2001 printf("New text window %d, child of %d\n", newwin, parent);
2002 #endif
2003
2004 XSetWindowColormap(W_Display, newwin->window, W_Colormap);
2005 return W_Window2Void(newwin);
2006 }
2007
2008 struct window *
newWindow(Window window,int type)2009 newWindow(Window window, int type)
2010 {
2011 struct window *newwin;
2012
2013 XSetWMProtocols (W_Display, window, &wm_delete_window, 1);
2014 newwin = (struct window *) malloc(sizeof(struct window));
2015
2016 newwin->window = window;
2017 newwin->type = type;
2018 newwin->mapped = 0;
2019 newwin->handle_keydown = 0;
2020 newwin->handle_keyup = 0;
2021 newwin->handle_button = 0;
2022 newwin->handle_expose = 0;
2023 addToHash(newwin);
2024
2025 #ifdef SHORT_PACKETS
2026 newwin->insensitive = 0;
2027 #endif
2028
2029 newwin->cursor = (Cursor) 0; /* about the best I can do *
2030 *
2031 * * -jw */
2032 return newwin;
2033 }
2034
2035 struct window *
findWindow(Window window)2036 findWindow(Window window)
2037 {
2038 struct windowlist *entry;
2039
2040 entry = hashtable[hash(window)];
2041 while (entry != NULL)
2042 {
2043 if (entry->window->window == window)
2044 return entry->window;
2045 entry = entry->next;
2046 }
2047 return NULL;
2048 }
2049
addToHash(struct window * win)2050 void addToHash(struct window * win)
2051 {
2052 struct windowlist **new;
2053
2054 #if DEBUG > 0
2055 printf("Adding to %d\n", hash(win->window));
2056 #endif
2057
2058 new = &hashtable[hash(win->window)];
2059 while (*new != NULL)
2060 {
2061 new = &((*new)->next);
2062 }
2063 *new = (struct windowlist *) malloc(sizeof(struct windowlist));
2064
2065 (*new)->next = NULL;
2066 (*new)->window = win;
2067 }
2068
2069 W_Window
W_MakeScrollingWindow(name,x,y,width,height,parent,border)2070 W_MakeScrollingWindow(name, x, y, width, height, parent, border)
2071 char *name;
2072 int x, y, width, height;
2073 W_Window parent;
2074 int border;
2075 {
2076 struct window *newwin;
2077 Window wparent;
2078 XSetWindowAttributes attrs;
2079 XSizeHints *sz_hints;
2080 int gcheck_result;
2081 struct scrollingWindow *sw;
2082 int scw = (scrollbar ? scroll_thumb_width : 0);
2083
2084 #if DEBUG > 0
2085 printf("New window...\n");
2086 #endif
2087
2088 gcheck_result = checkGeometry(name, &x, &y, &width, &height);
2089 checkParent(name, &parent);
2090 wparent = W_Void2Window(parent)->window;
2091 attrs.border_pixel = colortable[W_White].pixelValue;
2092 attrs.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask;
2093
2094 #ifdef AUTOKEY
2095 attrs.event_mask |= KeyReleaseMask;
2096 #endif /* AUTOKEY */
2097
2098 attrs.background_pixel = colortable[W_Black].pixelValue;
2099
2100 /* NOTE: CWDontPropagate seems to crash in OpenWindows */
2101 attrs.do_not_propagate_mask = ResizeRedirectMask | ExposureMask;
2102 newwin = newWindow(
2103 XCreateWindow(W_Display, wparent, x, y,
2104 width * W_Textwidth + WIN_EDGE * 2 + scw,
2105 MENU_PAD * 2 + height * W_Textheight,
2106 border, CopyFromParent, InputOutput, CopyFromParent,
2107 CWBackPixel | CWEventMask |
2108 CWBorderPixel /* | CWDontPropagate */ ,
2109 &attrs), WIN_SCROLL);
2110 class_hint.res_name = name;
2111 sz_hints = XAllocSizeHints();
2112 sz_hints->width_inc = W_Textwidth;
2113 sz_hints->height_inc = W_Textheight;
2114 sz_hints->min_width = WIN_EDGE * 2 + W_Textwidth + scw;
2115 sz_hints->min_height = MENU_PAD * 2 + W_Textheight;
2116 sz_hints->base_width = WIN_EDGE * 2 + scw;
2117 sz_hints->base_height = MENU_PAD * 2;
2118 sz_hints->flags = PResizeInc | PMinSize | PBaseSize;
2119 if (gcheck_result & XValue || gcheck_result & YValue)
2120 sz_hints->flags |= WMXYHintMode_default();
2121 XStoreName(W_Display, newwin->window, name);
2122 XSetWMNormalHints(W_Display, newwin->window, sz_hints);
2123 XFree((void *) sz_hints);
2124 XSetClassHint(W_Display, newwin->window, &class_hint);
2125 XSetWMHints(W_Display, newwin->window, &wm_hint);
2126 newwin->name = strdup(name);
2127 sw = (struct scrollingWindow *) malloc(sizeof(struct scrollingWindow));
2128
2129 sw->lines = 0;
2130 sw->updated = 0;
2131 sw->head = sw->tail = sw->index = NULL;
2132 sw->topline = 0;
2133 newwin->data = (char *) sw;
2134 newwin->width = width;
2135 newwin->height = height;
2136 if (wparent != W_Root)
2137 if (checkMapped(name))
2138 W_MapWindow(W_Window2Void(newwin));
2139
2140 #if DEBUG > 0
2141 printf("New scroll window %d, child of %d\n", newwin, parent);
2142 #endif
2143
2144 XSetWindowColormap(W_Display, newwin->window, W_Colormap);
2145 return W_Window2Void(newwin);
2146 }
2147
2148 /*
2149 * Add a string to the string list of the scrolling window.
2150 */
2151 static void
AddToScrolling(win,color,font,str,len)2152 AddToScrolling(win, color, font, str, len)
2153 struct window *win;
2154 W_Color color;
2155 W_Font font;
2156 char *str;
2157 int len;
2158 {
2159 struct scrollingWindow *sw;
2160 struct stringList *new;
2161
2162 /* simple, fast */
2163
2164 sw = (struct scrollingWindow *) win->data;
2165 if (sw->lines > 0 && sw->lines > scroll_lines /* some large number */ )
2166 {
2167 /* resuse tail */
2168 new = sw->tail;
2169 sw->tail = new->prev;
2170 new->prev->next = NULL;
2171 new->prev = NULL;
2172 new->next = sw->head;
2173 sw->head->prev = new;
2174 sw->head = new;
2175 }
2176 else
2177 {
2178 new = (struct stringList *) malloc(sizeof(struct stringList));
2179
2180 new->next = sw->head;
2181 new->prev = NULL;
2182 if (sw->head)
2183 sw->head->prev = new;
2184 sw->head = new;
2185 if (!sw->tail)
2186 sw->tail = new;
2187 sw->lines++;
2188 /*
2189 * printf("adding one line \"%s\" C:%d F:%d.\n", str, color,
2190 * fontNum(font)); */
2191 }
2192 sw->index = sw->head; /* input forces to end of *
2193 * list */
2194 sw->topline = 0;
2195
2196 sw->updated++; /* mark for *
2197 * W_FlushScrollingWindow */
2198
2199 STRNCPY(new->string, str, MAX_TEXT_WIDTH - 1);
2200 new->color = color;
2201 new->font = font;
2202
2203 if (len >= MAX_TEXT_WIDTH)
2204 {
2205 new->string[MAX_TEXT_WIDTH - 1] = 0;
2206 }
2207 else
2208 {
2209 /* we pad out the string with spaces so we don't have to clear the *
2210 * window */
2211 memset(&new->string[len], ' ', MAX_TEXT_WIDTH - len - 1);
2212 new->string[MAX_TEXT_WIDTH - 1] = 0;
2213 }
2214 }
2215
2216 void
W_FlushScrollingWindow(window)2217 W_FlushScrollingWindow(window)
2218
2219 W_Window window;
2220 {
2221 struct window *win = W_Void2Window(window);
2222 struct scrollingWindow *sw;
2223
2224 if (!win->mapped)
2225 return;
2226 if (win->type != WIN_SCROLL)
2227 {
2228 fprintf(stderr, "bad window type in W_FlushScrollingWindow.\n");
2229 return;
2230 }
2231 sw = (struct scrollingWindow *) win->data;
2232 if (!sw->updated)
2233 return;
2234
2235 #ifndef NO_COPYAREA
2236 else
2237 {
2238 struct stringList *item;
2239 int y;
2240
2241 if (win->height > sw->updated)
2242 {
2243 XCopyArea(W_Display, win->window, win->window,
2244 colortable[W_White].contexts[0],
2245 WIN_EDGE, MENU_PAD + sw->updated * W_Textheight,
2246 win->width * W_Textwidth,
2247 (win->height - sw->updated) * W_Textheight,
2248 WIN_EDGE, MENU_PAD);
2249 }
2250
2251
2252 y = (win->height - 1) * W_Textheight + fonts[1].baseline;
2253
2254 for (item = sw->index; item && y > 0 && sw->updated; item = item->next,
2255 y -= W_Textheight,
2256 sw->updated--)
2257 {
2258 XDrawImageString(W_Display, win->window,
2259 colortable[item->color].contexts[fontNum(item->font)],
2260 WIN_EDGE, MENU_PAD + y, item->string,
2261 win->width);
2262 }
2263 sw->updated = 0;
2264 if (scrollbar)
2265 drawThumb(win, sw);
2266 }
2267 #else
2268 redrawScrolling(win);
2269 #endif
2270 }
2271
2272 static void
drawThumb(win,sw)2273 drawThumb(win, sw)
2274
2275 struct window *win;
2276 struct scrollingWindow *sw;
2277 {
2278 int x, y, h;
2279 int savedlines, maxrow, thumbTop, thumbHeight, totalHeight, winheight;
2280
2281 /*
2282 * savedlines : Number of offscreen text lines,
2283 * sw->lines - win->height
2284 *
2285 * maxrow + 1 : Number of onscreen text lines,
2286 *
2287 * min(sw->lines + 1, win->height+1)
2288 *
2289 * sw->topline : -Number of lines above the last max_row+1 lines
2290 *
2291 * thumbTop = screen->topline + screen->savedlines;
2292 * thumbHeight = screen->max_row + 1;
2293 * totalHeight = thumbHeight + screen->savedlines;
2294 *
2295 * XawScrollbarSetThumb(scrollWidget,
2296 * ((float)thumbTop) / totalHeight,
2297 * ((float)thumbHeight) / totalHeight);
2298 */
2299
2300 savedlines = sw->lines - win->height;
2301 if (savedlines < 0)
2302 savedlines = 0;
2303 maxrow = sw->lines < win->height ? sw->lines : win->height;
2304 winheight = win->height * W_Textheight + MENU_PAD * 2;
2305
2306 thumbTop = sw->topline + savedlines;
2307 thumbHeight = maxrow + 1;
2308 totalHeight = thumbHeight + savedlines;
2309
2310 x = win->width * W_Textwidth + WIN_EDGE * 2;
2311 y = winheight * thumbTop / totalHeight;
2312 h = winheight * thumbHeight / totalHeight;
2313
2314 XClearArea(W_Display, win->window, x, 0, scroll_thumb_width, winheight,
2315 False);
2316 XFillRectangle(W_Display, win->window, scroll_thumb_gc,
2317 x, y,
2318 scroll_thumb_width, h);
2319 XDrawLine(W_Display, win->window, colortable[W_Red].contexts[0],
2320 x, 0, x, winheight);
2321 }
2322
2323 static void
redrawScrolling(win)2324 redrawScrolling(win)
2325 struct window *win;
2326 {
2327 int y;
2328 struct scrollingWindow *sw;
2329 register struct stringList *item;
2330
2331 if (!win->mapped)
2332 return;
2333
2334 /* simple, fast */
2335
2336 sw = (struct scrollingWindow *) win->data;
2337 if (!sw->lines)
2338 return;
2339 sw->updated = 0;
2340
2341 y = (win->height - 1) * W_Textheight + fonts[1].baseline;
2342 for (item = sw->index; item && y > 0; item = item->next, y -= W_Textheight)
2343 {
2344 XDrawImageString(W_Display, win->window,
2345 colortable[item->color].contexts[fontNum(item->font)],
2346 WIN_EDGE, MENU_PAD + y, item->string,
2347 win->width);
2348 }
2349 if (scrollbar)
2350 drawThumb(win, sw);
2351 }
2352
2353 #ifdef SHORT_PACKETS
W_SetSensitive(W_Window w,int v)2354 void W_SetSensitive(W_Window w, int v)
2355 {
2356 struct window *win = W_Void2Window(w);
2357
2358 win->insensitive = !v;
2359
2360 if (win->type == WIN_SCROLL)
2361 redrawScrolling(win);
2362 }
2363 #endif
2364
2365 W_Window
W_MakeMenu(char * name,int x,int y,int width,int height,W_Window parent,int border)2366 W_MakeMenu(char *name, int x, int y, int width, int height, W_Window parent, int border)
2367 {
2368 struct window *newwin;
2369 struct menuItem *items;
2370 Window wparent;
2371 int i;
2372 XSetWindowAttributes attrs;
2373
2374 #if DEBUG > 0
2375 printf("New window...\n");
2376 #endif
2377
2378 checkGeometry(name, &x, &y, &width, &height);
2379 checkParent(name, &parent);
2380 wparent = W_Void2Window(parent)->window;
2381 attrs.border_pixel = colortable[W_White].pixelValue;
2382 attrs.event_mask = KeyPressMask | ButtonPressMask | ExposureMask;
2383
2384 #ifdef AUTOKEY
2385 attrs.event_mask |= KeyReleaseMask;
2386 #endif /* AUTOKEY */
2387
2388 attrs.background_pixel = colortable[W_Black].pixelValue;
2389 attrs.do_not_propagate_mask = KeyPressMask | ButtonPressMask | ExposureMask;
2390 newwin = newWindow(
2391 XCreateWindow(W_Display, wparent, x, y,
2392 width * W_Textwidth + WIN_EDGE * 2,
2393 height * (W_Textheight + MENU_PAD * 2) + (height - 1) * MENU_BAR, border,
2394 CopyFromParent, InputOutput, CopyFromParent,
2395 CWBackPixel | CWEventMask |
2396 CWBorderPixel,
2397 &attrs),
2398 WIN_MENU);
2399 class_hint.res_name = name;
2400 XSetClassHint(W_Display, newwin->window, &class_hint);
2401 XSetWMHints(W_Display, newwin->window, &wm_hint);
2402 XStoreName(W_Display, newwin->window, name);
2403 newwin->name = strdup(name);
2404 items = (struct menuItem *) malloc(height * sizeof(struct menuItem));
2405
2406 for (i = 0; i < height; i++)
2407 {
2408 /* new: allocate once and reuse -tsh */
2409 items[i].column = 0;
2410 items[i].string = (char *) malloc(MAX_TEXT_WIDTH);
2411 items[i].color = W_White;
2412 }
2413 newwin->data = (char *) items;
2414 newwin->width = width;
2415 newwin->height = height;
2416 if (wparent != W_Root)
2417 if (checkMapped(name))
2418 W_MapWindow(W_Window2Void(newwin));
2419
2420 #if DEBUG > 0
2421 printf("New menu window %d, child of %d\n", newwin, parent);
2422 #endif
2423
2424 XSetWindowColormap(W_Display, newwin->window, W_Colormap);
2425 return W_Window2Void(newwin);
2426 }
2427
redrawMenu(struct window * win)2428 void redrawMenu(struct window * win)
2429 {
2430 int count;
2431
2432 for (count = 1; count < win->height; count++)
2433 {
2434 XFillRectangle(W_Display, win->window,
2435 colortable[W_Grey].contexts[0],
2436 0, count * (W_Textheight + MENU_PAD * 2) + (count - 1) * MENU_BAR,
2437 win->width * W_Textwidth + WIN_EDGE * 2, MENU_BAR);
2438 }
2439 for (count = 0; count < win->height; count++)
2440 {
2441 redrawMenuItem(win, count);
2442 }
2443 }
2444
redrawMenuItem(struct window * win,int n)2445 void redrawMenuItem(struct window *win, int n)
2446 {
2447 struct menuItem *items;
2448
2449 items = (struct menuItem *) win->data;
2450 XFillRectangle(W_Display, win->window,
2451 colortable[W_Black].contexts[0],
2452 WIN_EDGE, n * (W_Textheight + MENU_PAD * 2 + MENU_BAR) + MENU_PAD,
2453 win->width * W_Textwidth, W_Textheight);
2454 if (items[n].string)
2455 {
2456 XDrawImageString(W_Display, win->window,
2457 colortable[items[n].color].contexts[1],
2458 WIN_EDGE + W_Textwidth * items[n].column,
2459 n * (W_Textheight + MENU_PAD * 2 + MENU_BAR) + MENU_PAD + fonts[1].baseline,
2460 items[n].string, strlen(items[n].string));
2461 }
2462 }
2463
changeMenuItem(struct window * win,int col,int n,char * str,W_Color color)2464 static void changeMenuItem(struct window *win, int col, int n, char *str, W_Color color)
2465 {
2466 struct menuItem *items;
2467
2468 items = (struct menuItem *) win->data;
2469
2470 STRNCPY(items[n].string, str, MAX_TEXT_WIDTH - 1);
2471 items[n].string[MAX_TEXT_WIDTH - 1] = 0;
2472 items[n].color = color;
2473 items[n].column = col;
2474 redrawMenuItem(win, n);
2475 }
2476
2477 void
W_DefineMapcursor(W_Window window)2478 W_DefineMapcursor(W_Window window)
2479 {
2480 Cursor new;
2481 Pixmap mapcursmaskbit;
2482 Pixmap mapcursbit;
2483 struct window *win = W_Void2Window(window);
2484 char *path;
2485 static
2486 XColor f, b;
2487 int w, h, xh, yh;
2488
2489 xh = yh = 5;
2490 f.pixel = colortable[W_White].pixelValue;
2491 b.pixel = colortable[W_Black].pixelValue;
2492
2493 XQueryColor(W_Display, W_Colormap, &f);
2494 XQueryColor(W_Display, W_Colormap, &b);
2495
2496 mapcursbit = XCreateBitmapFromData(W_Display, win->window, mapcursor_bits,
2497 mapcursor_width, mapcursor_height);
2498
2499 if ((path = getdefault("mapCursorDef")))
2500 {
2501
2502 if (W_LoadBitmap(window, path, &mapcursmaskbit, &w, &h, &xh, &yh) != 1)
2503 {
2504 mapcursmaskbit = XCreateBitmapFromData(W_Display, win->window,
2505 mapmask_bits, mapmask_width, mapmask_height);
2506 xh = yh = 5;
2507 }
2508 else
2509 {
2510 mapcursbit = XCreatePixmap(W_Display, win->window, w, h, 1);
2511 XFillRectangle(W_Display, mapcursbit,
2512 colortable[W_White].contexts[0], 0, 0, w, h);
2513 }
2514 }
2515
2516 else
2517 mapcursmaskbit = XCreateBitmapFromData(W_Display, win->window,
2518 mapmask_bits, mapmask_width, mapmask_height);
2519
2520 if (win->cursor)
2521 XFreeCursor(W_Display, win->cursor);
2522
2523 new = XCreatePixmapCursor(W_Display, mapcursbit, mapcursmaskbit,
2524 &b, &f, xh, yh);
2525 XRecolorCursor(W_Display, new, &b, &f);
2526 XDefineCursor(W_Display, win->window, new);
2527 win->cursor = new;
2528 }
2529
2530 void
W_DefineLocalcursor(W_Window window)2531 W_DefineLocalcursor(W_Window window)
2532 {
2533 Cursor new;
2534 Pixmap localcursmaskbit;
2535 Pixmap localcursbit;
2536 struct window *win = W_Void2Window(window);
2537 char *path;
2538 static
2539 XColor f, b;
2540 int w, h, xh, yh;
2541
2542 xh = yh = 5;
2543 f.pixel = colortable[W_White].pixelValue;
2544 b.pixel = colortable[W_Black].pixelValue;
2545
2546 XQueryColor(W_Display, W_Colormap, &f);
2547 XQueryColor(W_Display, W_Colormap, &b);
2548
2549 localcursbit = XCreateBitmapFromData(W_Display, win->window,
2550 localcursor_bits, localcursor_width, localcursor_height);
2551
2552 if ((path = getdefault("localCursorDef")))
2553 {
2554 if (W_LoadBitmap(window, path, &localcursmaskbit, &w, &h, &xh, &yh) != 1)
2555 {
2556 localcursmaskbit = XCreateBitmapFromData(W_Display, win->window,
2557 localmask_bits, localmask_width, localmask_height);
2558 xh = yh = 5;
2559 }
2560 else
2561 {
2562 localcursbit = XCreatePixmap(W_Display, win->window, w, h, 1);
2563 XFillRectangle(W_Display, localcursbit,
2564 colortable[W_White].contexts[0], 0, 0, w, h);
2565 }
2566 }
2567 else
2568 localcursmaskbit = XCreateBitmapFromData(W_Display, win->window,
2569 localmask_bits, localmask_width, localmask_height);
2570
2571 if (win->cursor)
2572 XFreeCursor(W_Display, win->cursor);
2573
2574 new = XCreatePixmapCursor(W_Display, localcursbit, localcursmaskbit,
2575 &b, &f, xh, yh);
2576 XRecolorCursor(W_Display, new, &b, &f);
2577 XDefineCursor(W_Display, win->window, new);
2578 win->cursor = new;
2579 }
2580
2581 void
W_DefineFedCursor(W_Window window)2582 W_DefineFedCursor(W_Window window)
2583 {
2584 Cursor new;
2585 Pixmap fedcursmaskbit;
2586 Pixmap fedcursbit;
2587 struct window *win = W_Void2Window(window);
2588
2589 static
2590 XColor f, b;
2591
2592 f.pixel = colortable[W_White].pixelValue;
2593 b.pixel = colortable[W_Black].pixelValue;
2594
2595 XQueryColor(W_Display, W_Colormap, &f);
2596 XQueryColor(W_Display, W_Colormap, &b);
2597
2598 fedcursbit = XCreateBitmapFromData(W_Display, win->window, fed_cruiser_bits,
2599 fed_cruiser_width, fed_cruiser_height);
2600 fedcursmaskbit = XCreateBitmapFromData(W_Display, win->window,
2601 fed_mask_bits, fed_mask_width, fed_mask_height);
2602 if (win->cursor)
2603 XFreeCursor(W_Display, win->cursor);
2604
2605 new = XCreatePixmapCursor(W_Display, fedcursmaskbit, fedcursbit,
2606 &b, &f, 10, 10);
2607 XRecolorCursor(W_Display, new, &b, &f);
2608 XDefineCursor(W_Display, win->window, new);
2609 win->cursor = new;
2610 }
2611
2612 void
W_DefineRomCursor(W_Window window)2613 W_DefineRomCursor(W_Window window)
2614 {
2615 Cursor new;
2616 Pixmap romcursmaskbit;
2617 Pixmap romcursbit;
2618 struct window *win = W_Void2Window(window);
2619
2620 static
2621 XColor f, b;
2622
2623 f.pixel = colortable[W_White].pixelValue;
2624 b.pixel = colortable[W_Black].pixelValue;
2625
2626 XQueryColor(W_Display, W_Colormap, &f);
2627 XQueryColor(W_Display, W_Colormap, &b);
2628
2629 romcursbit = XCreateBitmapFromData(W_Display, win->window, rom_cruiser_bits,
2630 rom_cruiser_width, rom_cruiser_height);
2631 romcursmaskbit = XCreateBitmapFromData(W_Display, win->window,
2632 rom_mask_bits, rom_cruiser_width, rom_cruiser_height);
2633 if (win->cursor)
2634 XFreeCursor(W_Display, win->cursor);
2635
2636 new = XCreatePixmapCursor(W_Display, romcursmaskbit, romcursbit,
2637 &b, &f, 10, 10);
2638 XRecolorCursor(W_Display, new, &b, &f);
2639 XDefineCursor(W_Display, win->window, new);
2640 win->cursor = new;
2641 }
2642
2643 void
W_DefineKliCursor(W_Window window)2644 W_DefineKliCursor(W_Window window)
2645 {
2646 Cursor new;
2647 Pixmap klicursmaskbit;
2648 Pixmap klicursbit;
2649 struct window *win = W_Void2Window(window);
2650
2651 static
2652 XColor f, b;
2653
2654 f.pixel = colortable[W_White].pixelValue;
2655 b.pixel = colortable[W_Black].pixelValue;
2656
2657 XQueryColor(W_Display, W_Colormap, &f);
2658 XQueryColor(W_Display, W_Colormap, &b);
2659
2660 klicursbit = XCreateBitmapFromData(W_Display, win->window, kli_cruiser_bits,
2661 kli_cruiser_width, kli_cruiser_height);
2662 klicursmaskbit = XCreateBitmapFromData(W_Display, win->window,
2663 fed_mask_bits, kli_cruiser_width, kli_cruiser_height);
2664 if (win->cursor)
2665 XFreeCursor(W_Display, win->cursor);
2666
2667 new = XCreatePixmapCursor(W_Display, klicursmaskbit, klicursbit,
2668 &b, &f, 10, 10);
2669 XRecolorCursor(W_Display, new, &b, &f);
2670 XDefineCursor(W_Display, win->window, new);
2671 win->cursor = new;
2672 }
2673
2674 void
W_DefineOriCursor(W_Window window)2675 W_DefineOriCursor(W_Window window)
2676 {
2677 Cursor new;
2678 Pixmap oricursmaskbit;
2679 Pixmap oricursbit;
2680 struct window *win = W_Void2Window(window);
2681
2682 static
2683 XColor f, b;
2684
2685 f.pixel = colortable[W_White].pixelValue;
2686 b.pixel = colortable[W_Black].pixelValue;
2687
2688 XQueryColor(W_Display, W_Colormap, &f);
2689 XQueryColor(W_Display, W_Colormap, &b);
2690
2691 oricursbit = XCreateBitmapFromData(W_Display, win->window, ori_cruiser_bits,
2692 ori_cruiser_width, ori_cruiser_height);
2693 oricursmaskbit = XCreateBitmapFromData(W_Display, win->window,
2694 fed_mask_bits, ori_cruiser_width, ori_cruiser_height);
2695 if (win->cursor)
2696 XFreeCursor(W_Display, win->cursor);
2697
2698 new = XCreatePixmapCursor(W_Display, oricursmaskbit, oricursbit,
2699 &b, &f, 10, 10);
2700 XRecolorCursor(W_Display, new, &b, &f);
2701 XDefineCursor(W_Display, win->window, new);
2702 win->cursor = new;
2703 }
2704
2705 void
W_DefineTrekCursor(W_Window window)2706 W_DefineTrekCursor(W_Window window)
2707 {
2708 Cursor new;
2709 struct window *win = W_Void2Window(window);
2710 XColor f, b;
2711 char *path;
2712 int w, h, xh, yh, mw, mh, mxh, myh;
2713
2714 f.pixel = colortable[W_Yellow].pixelValue;
2715 b.pixel = colortable[W_Black].pixelValue;
2716
2717 XQueryColor(W_Display, W_Colormap, &f);
2718 XQueryColor(W_Display, W_Colormap, &b);
2719
2720 if (win->cursor)
2721 XFreeCursor(W_Display, win->cursor);
2722
2723 if ((path = getdefault("infoCursorDef")))
2724 {
2725 Pixmap pm, mpm;
2726
2727 if (W_LoadBitmap(window, path, &pm, &w, &h, &xh, &yh) != 1)
2728 new = XCreateFontCursor(W_Display, XC_trek);
2729 else
2730 {
2731 char mask_path[512];
2732
2733 strcpy(mask_path, path);
2734 strcat(mask_path, ".mask");
2735
2736 if (W_LoadBitmap(window, mask_path, &mpm, &mw, &mh, &mxh, &myh) != 1)
2737 {
2738 mw = w;
2739 mh = h;
2740 mpm = XCreatePixmap(W_Display, win->window, w, h, 1);
2741 XFillRectangle(W_Display, mpm,
2742 colortable[W_White].contexts[0], 0, 0, w, h);
2743 }
2744
2745 if ((w != mw) || (h != mh))
2746 {
2747 printf("Cursor and mask are not the same size. %s\n", path);
2748 new = XCreateFontCursor(W_Display, XC_trek);
2749 }
2750 else
2751 new = XCreatePixmapCursor(W_Display, pm, mpm,
2752 &b, &f, xh, yh);
2753 }
2754 }
2755 else
2756 new = XCreateFontCursor(W_Display, XC_trek);
2757
2758 XRecolorCursor(W_Display, new, &f, &b);
2759 XDefineCursor(W_Display, win->window, new);
2760 win->cursor = new;
2761 }
2762
2763 void
W_DefineWarningCursor(W_Window window)2764 W_DefineWarningCursor(W_Window window)
2765 {
2766 Cursor new;
2767 struct window *win = W_Void2Window(window);
2768 XColor f, b;
2769
2770 f.pixel = colortable[W_Red].pixelValue;
2771 b.pixel = colortable[W_Black].pixelValue;
2772
2773 XQueryColor(W_Display, W_Colormap, &f);
2774 XQueryColor(W_Display, W_Colormap, &b);
2775
2776 if (win->cursor)
2777 XFreeCursor(W_Display, win->cursor);
2778
2779 new = XCreateFontCursor(W_Display, XC_pirate);
2780 XRecolorCursor(W_Display, new, &f, &b);
2781 XDefineCursor(W_Display, win->window, new);
2782 win->cursor = new;
2783 }
2784
2785 void
W_DefineArrowCursor(W_Window window)2786 W_DefineArrowCursor(W_Window window)
2787 {
2788 Cursor new;
2789 struct window *win = W_Void2Window(window);
2790 XColor f, b;
2791 char *path;
2792 int w, h, xh, yh, mw, mh, mxh, myh;
2793
2794 f.pixel = colortable[W_Black].pixelValue;
2795 b.pixel = colortable[W_White].pixelValue;
2796
2797 XQueryColor(W_Display, W_Colormap, &f);
2798 XQueryColor(W_Display, W_Colormap, &b);
2799
2800 if (win->cursor)
2801 XFreeCursor(W_Display, win->cursor);
2802
2803 if ((path = getdefault("arrowCursorDef")))
2804 {
2805 Pixmap pm, mpm;
2806
2807 if (W_LoadBitmap(window, path, &pm, &w, &h, &xh, &yh) != 1)
2808 new = XCreateFontCursor(W_Display, XC_left_ptr);
2809 else
2810 {
2811 char mask_path[512];
2812
2813 strcpy(mask_path, path);
2814 strcat(mask_path, ".mask");
2815
2816 if (W_LoadBitmap(window, mask_path, &mpm, &mw, &mh, &mxh, &myh) != 1)
2817 {
2818 mw = w;
2819 mh = h;
2820 mpm = XCreatePixmap(W_Display, win->window, w, h, 1);
2821 XFillRectangle(W_Display, mpm,
2822 colortable[W_White].contexts[0], 0, 0, w, h);
2823 }
2824
2825 if ((w != mw) || (h != mh))
2826 {
2827 printf("Cursor and mask are not the same size. %s\n", path);
2828 new = XCreateFontCursor(W_Display, XC_left_ptr);
2829 }
2830 else
2831 new = XCreatePixmapCursor(W_Display, pm, mpm,
2832 &b, &f, xh, yh);
2833 }
2834 }
2835 else
2836 new = XCreateFontCursor(W_Display, XC_left_ptr);
2837
2838 XRecolorCursor(W_Display, new, &f, &b);
2839 XDefineCursor(W_Display, win->window, new);
2840 win->cursor = new;
2841 }
2842
2843 void
W_DefineTextCursor(W_Window window)2844 W_DefineTextCursor(W_Window window)
2845 {
2846 Cursor new;
2847 struct window *win = W_Void2Window(window);
2848 XColor f, b;
2849 char *path;
2850 int w, h, xh, yh, mw, mh, mxh, myh;
2851
2852 f.pixel = colortable[W_Yellow].pixelValue;
2853 b.pixel = colortable[W_Black].pixelValue;
2854
2855 XQueryColor(W_Display, W_Colormap, &f);
2856 XQueryColor(W_Display, W_Colormap, &b);
2857
2858 if (win->cursor)
2859 XFreeCursor(W_Display, win->cursor);
2860
2861 if ((path = getdefault("textCursorDef")))
2862 {
2863 Pixmap pm, mpm;
2864
2865 if (W_LoadBitmap(window, path, &pm, &w, &h, &xh, &yh) != 1)
2866 new = XCreateFontCursor(W_Display, XC_xterm);
2867 else
2868 {
2869 char mask_path[512];
2870
2871 strcpy(mask_path, path);
2872 strcat(mask_path, ".mask");
2873
2874 if (W_LoadBitmap(window, mask_path, &mpm, &mw, &mh, &mxh, &myh) != 1)
2875 {
2876 mw = w;
2877 mh = h;
2878 mpm = XCreatePixmap(W_Display, win->window, w, h, 1);
2879 XFillRectangle(W_Display, mpm,
2880 colortable[W_White].contexts[0], 0, 0, w, h);
2881 }
2882
2883 if ((w != mw) || (h != mh))
2884 {
2885 printf("Cursor and mask are not the same size. %s\n", path);
2886 new = XCreateFontCursor(W_Display, XC_xterm);
2887 }
2888 else
2889 new = XCreatePixmapCursor(W_Display, pm, mpm,
2890 &b, &f, xh, yh);
2891 }
2892 }
2893 else
2894 new = XCreateFontCursor(W_Display, XC_xterm);
2895
2896 XRecolorCursor(W_Display, new, &f, &b);
2897 XDefineCursor(W_Display, win->window, new);
2898 win->cursor = new;
2899 }
2900
2901 void
W_DefineCursor(W_Window window,int width,int height,char * bits,char * mask,int xhot,int yhot)2902 W_DefineCursor(W_Window window, int width, int height, char *bits, char *mask, int xhot, int yhot)
2903 {
2904 static char *oldbits = NULL;
2905 static Cursor curs;
2906 Pixmap cursbits;
2907 Pixmap cursmask;
2908 struct window *win;
2909 XColor whiteCol, blackCol;
2910
2911 #if DEBUG > 0
2912 printf("Defining cursor for %d\n", window);
2913 #endif
2914
2915 win = W_Void2Window(window);
2916 whiteCol.pixel = colortable[W_White].pixelValue;
2917 XQueryColor(W_Display, W_Colormap, &whiteCol);
2918 blackCol.pixel = colortable[W_Black].pixelValue;
2919 XQueryColor(W_Display, W_Colormap, &blackCol);
2920 if (!oldbits || oldbits != bits)
2921 {
2922 cursbits = XCreateBitmapFromData(W_Display, win->window,
2923 bits, width, height);
2924 cursmask = XCreateBitmapFromData(W_Display, win->window,
2925 mask, width, height);
2926 oldbits = bits;
2927 curs = XCreatePixmapCursor(W_Display, cursbits, cursmask,
2928 &whiteCol, &blackCol, xhot, yhot);
2929 XFreePixmap(W_Display, cursbits);
2930 XFreePixmap(W_Display, cursmask);
2931 }
2932 XDefineCursor(W_Display, win->window, curs);
2933 }
2934
2935 int
W_LoadBitmap(W_Window window,char * path,Pixmap * pixmap,int * width,int * height,int * x_hot,int * y_hot)2936 W_LoadBitmap(W_Window window, char *path, Pixmap * pixmap, int *width, int *height, int *x_hot, int *y_hot)
2937 {
2938 int status;
2939 struct window *win;
2940
2941 win = W_Void2Window(window);
2942
2943 status = XReadBitmapFile(W_Display, win->window, path, (unsigned int *) width,
2944 (unsigned int *) height, pixmap, x_hot, y_hot);
2945
2946 if (status == BitmapSuccess)
2947 {
2948 if (*x_hot < 0)
2949 {
2950 *x_hot = *width / 2;
2951 *y_hot = *height / 2;
2952 }
2953
2954 return 1;
2955 }
2956 else
2957 return 0;
2958 }
2959
2960 void
W_Beep(void)2961 W_Beep(void)
2962 {
2963 XBell(W_Display, 0);
2964 }
2965
2966 int
W_WindowWidth(W_Window window)2967 W_WindowWidth(W_Window window)
2968 {
2969 return W_Void2Window(window)->width;
2970 }
2971
2972 int
W_WindowHeight(W_Window window)2973 W_WindowHeight(W_Window window)
2974 {
2975 return W_Void2Window(window)->height;
2976 }
2977
2978 int
W_Socket(void)2979 W_Socket(void)
2980 {
2981 return ConnectionNumber(W_Display);
2982 }
2983
2984 void
W_DestroyWindow(W_Window window)2985 W_DestroyWindow(W_Window window)
2986 {
2987 struct window *win;
2988
2989 #if DEBUG > 0
2990 printf("Destroying %d\n", window);
2991 #endif
2992
2993 win = W_Void2Window(window);
2994 deleteWindow(win);
2995 XDestroyWindow(W_Display, win->window);
2996 free((char *) win);
2997 }
2998
deleteWindow(struct window * window)2999 void deleteWindow(struct window *window)
3000 {
3001 struct windowlist **rm;
3002 struct windowlist *temp;
3003
3004 rm = &hashtable[hash(window->window)];
3005 while (*rm != NULL && (*rm)->window != window)
3006 {
3007 rm = &((*rm)->next);
3008 }
3009 if (*rm == NULL)
3010 {
3011 printf("Attempt to delete non-existent window!\n");
3012 return;
3013 }
3014 temp = *rm;
3015 *rm = temp->next;
3016 free((char *) temp);
3017 }
3018
3019 void
W_SetIconWindow(W_Window main,W_Window icon)3020 W_SetIconWindow(W_Window main, W_Window icon)
3021 {
3022 XWMHints hints;
3023
3024 XSetIconName(W_Display, W_Void2Window(icon)->window, W_Void2Window(main)->name);
3025
3026 hints.flags = IconWindowHint;
3027 hints.icon_window = W_Void2Window(icon)->window;
3028 #ifdef WINDOWMAKER
3029 hints.window_group = W_Void2Window(main)->window;
3030 hints.flags |= WindowGroupHint;
3031
3032 XSetCommand(W_Display, W_Void2Window(main)->window, wm_argv, wm_argc);
3033 #endif
3034
3035 XSetWMHints(W_Display, W_Void2Window(main)->window, &hints);
3036 }
3037
3038 static void
scrollUp(win,y)3039 scrollUp(win, y)
3040
3041 struct window *win;
3042 int y;
3043 {
3044 struct scrollingWindow *sw = (struct scrollingWindow *) win->data;
3045 int savedlines = sw->lines - win->height;
3046
3047 if (savedlines < 0)
3048 savedlines = 0;
3049
3050 if (sw->topline + savedlines > 0)
3051 {
3052 if (!sw->index)
3053 {
3054 fprintf(stderr, "scroll error, NULL index (scrollUp).\n");
3055 return;
3056 }
3057 sw->index = sw->index->next;
3058 sw->topline--;
3059 redrawScrolling(win);
3060 }
3061 }
3062
3063 static void
scrollDown(win,y)3064 scrollDown(win, y)
3065
3066 struct window *win;
3067 int y;
3068 {
3069 struct scrollingWindow *sw = (struct scrollingWindow *) win->data;
3070
3071 if (sw->topline < 0)
3072 {
3073 if (!sw->index)
3074 {
3075 fprintf(stderr, "scroll error, NULL index (scrollDown).\n");
3076 return;
3077 }
3078 sw->index = sw->index->prev;
3079 sw->topline++;
3080 redrawScrolling(win);
3081 }
3082 }
3083
3084
3085 static void
scrollPosition(win,y)3086 scrollPosition(win, y)
3087
3088 struct window *win;
3089 int y;
3090 {
3091 struct scrollingWindow *sw = (struct scrollingWindow *) win->data;
3092 int savedlines, maxrow, winheight, newtop;
3093
3094 savedlines = sw->lines - win->height;
3095 if (savedlines < 0)
3096 savedlines = 0;
3097 maxrow = sw->lines < win->height ? sw->lines : win->height;
3098 winheight = win->height * W_Textheight + MENU_PAD * 2;
3099
3100 newtop = (y * (savedlines + maxrow + 1)) / winheight - savedlines;
3101 if (newtop < -savedlines)
3102 newtop = -savedlines;
3103 else if (newtop > 0)
3104 newtop = 0;
3105 scrollTo(win, sw, newtop);
3106 }
3107
3108 static void
scrollTo(win,sw,topline)3109 scrollTo(win, sw, topline)
3110
3111 struct window *win;
3112 struct scrollingWindow *sw;
3113 int topline;
3114 {
3115 while (topline < sw->topline)
3116 {
3117 if (!sw->index)
3118 {
3119 fprintf(stderr, "scroll error, NULL index (1).\n");
3120 break;
3121 }
3122 sw->index = sw->index->next;
3123 sw->topline--;
3124 }
3125 while (topline > sw->topline)
3126 {
3127 if (!sw->index)
3128 {
3129 fprintf(stderr, "scroll error, NULL index (2).\n");
3130 break;
3131 }
3132 sw->index = sw->index->prev;
3133 sw->topline++;
3134 }
3135 redrawScrolling(win);
3136 }
3137
3138 static void
scrollScrolling(wevent)3139 scrollScrolling(wevent)
3140
3141 W_Event *wevent;
3142 {
3143 switch (wevent->key)
3144 {
3145 case W_RBUTTON:
3146 case W_WUBUTTON:
3147 scrollUp(W_Void2Window(wevent->Window), wevent->y);
3148 break;
3149 case W_LBUTTON:
3150 case W_WDBUTTON:
3151 scrollDown(W_Void2Window(wevent->Window), wevent->y);
3152 break;
3153 case W_MBUTTON:
3154 scrollPosition(W_Void2Window(wevent->Window), wevent->y);
3155 break;
3156 default:
3157 break;
3158 }
3159 }
3160
3161 static void
configureScrolling(win,x,y,width,height)3162 configureScrolling(win, x, y, width, height)
3163
3164 struct window *win;
3165 int x, y; /* TODO */
3166 int width, height;
3167
3168 {
3169 int new_text_width, new_text_height;
3170 int new_real_width, new_real_height;
3171 XWindowAttributes wa;
3172 int sw = scrollbar ? scroll_thumb_width : 0;
3173
3174 #if 0
3175 /* XXX: can't shrink window */
3176
3177 if (width <= win->width * W_Textwidth + WIN_EDGE * 2 &&
3178 height <= win->height * W_Textheight + MENU_PAD * 2)
3179 return;
3180 #endif
3181
3182 XGetWindowAttributes(W_Display, win->window, &wa);
3183
3184 new_text_width = (wa.width - WIN_EDGE * 2 - sw) / W_Textwidth;
3185 new_text_height = (wa.height - MENU_PAD * 2) / W_Textheight;
3186
3187 if (new_text_width <= 0)
3188 new_text_width = 1;
3189 if (new_text_height <= 0)
3190 new_text_height = 1;
3191 if (new_text_width >= MAX_TEXT_WIDTH)
3192 new_text_width = MAX_TEXT_WIDTH - 1;
3193
3194 new_real_width = new_text_width * W_Textwidth + WIN_EDGE * 2 + sw;
3195 new_real_height = new_text_height * W_Textheight + MENU_PAD * 2;
3196
3197 if (new_real_height != wa.height || new_real_width != wa.width)
3198 {
3199 XResizeWindow(W_Display, win->window, new_real_width, new_real_height);
3200 }
3201
3202 win->width = new_text_width;
3203 win->height = new_text_height;
3204
3205 /* an expose event will follow a resize request, triggering *
3206 * redrawScrolling */
3207 }
3208
3209 /*****************************************************************************/
3210 /* Looks up any default geometry specified in the defaults file and */
3211 /* returns the values found there. Geometry should be of the form */
3212 /* [=][<width>x<height>][{+-}<xoffset>{+-}<yoffset>] */
3213 /* */
3214 /* The result returned indicates which values were set. */
3215 /* XValue, YValue, WidthValue, HeightValue */
3216 /* */
3217 /*****************************************************************************/
3218
3219 static int
checkGeometry(char * name,int * x,int * y,int * width,int * height)3220 checkGeometry(char *name, int *x, int *y, int *width, int *height)
3221 {
3222 char buf[80], *geom_default;
3223
3224 sprintf(buf, "%s.geometry", name);
3225 geom_default = getdefault(buf);
3226 if (!geom_default)
3227 return 0; /* nothing set */
3228
3229 return XParseGeometry(geom_default, x, y, (unsigned int *) width, (unsigned int *) height);
3230 }
3231
checkParent(char * name,W_Window * parent)3232 void checkParent(char *name, W_Window * parent)
3233 {
3234 char *adefault;
3235 char buf[100];
3236 int i;
3237 struct windowlist *windows;
3238
3239 sprintf(buf, "%s.parent", name);
3240 adefault = getdefault(buf);
3241 if (adefault == NULL)
3242 return;
3243 /* parent must be name of other window or "root" */
3244 if (strcmpi(adefault, "root") == 0)
3245 {
3246 *parent = W_Window2Void(&myroot);
3247 return;
3248 }
3249 for (i = 0; i < HASHSIZE; i++)
3250 {
3251 windows = hashtable[i];
3252 while (windows != NULL)
3253 {
3254 if (strcmpi(adefault, windows->window->name) == 0)
3255 {
3256 *parent = W_Window2Void(windows->window);
3257 return;
3258 }
3259 windows = windows->next;
3260 }
3261 }
3262 }
3263
checkMapped(char * name)3264 int checkMapped(char *name)
3265 {
3266 char buf[100];
3267
3268 sprintf(buf, "%s.mapped", name);
3269 return booleanDefault(buf, 0);
3270 }
3271
checkMappedPref(char * name,int preferred)3272 int checkMappedPref(char *name, int preferred)
3273 {
3274 char buf[100];
3275
3276 sprintf(buf, "%s.mapped", name);
3277 return booleanDefault(buf, preferred);
3278 }
3279
3280 void
W_WarpPointer(W_Window window,int x,int y)3281 W_WarpPointer(W_Window window, int x, int y)
3282 {
3283 static int warped_from_x = 0, warped_from_y = 0;
3284
3285 if (window == NULL)
3286 {
3287 if (W_in_message)
3288 {
3289 XWarpPointer(W_Display, None, W_Root, 0, 0, 0, 0, warped_from_x, warped_from_y);
3290 W_in_message = 0;
3291 }
3292 }
3293 else
3294 {
3295 findMouse(&warped_from_x, &warped_from_y);
3296 XWarpPointer(W_Display, None, W_Void2Window(window)->window, 0, 0, 0, 0, 0, 0);
3297 W_in_message = 1;
3298 }
3299 }
3300
findMouse(int * x,int * y)3301 void findMouse(int *x, int *y)
3302 {
3303 Window theRoot, theChild;
3304 int wX, wY, rootX, rootY, status;
3305 unsigned int wButtons;
3306
3307 status = XQueryPointer(W_Display, W_Root, &theRoot, &theChild, &rootX, &rootY, &wX, &wY, &wButtons);
3308 if (status == True)
3309 {
3310 *x = wX;
3311 *y = wY;
3312 }
3313 else
3314 {
3315 *x = 0;
3316 *y = 0;
3317 }
3318 }
3319
3320 int
findMouseInWin(int * x,int * y,W_Window w)3321 findMouseInWin(int *x, int *y, W_Window w)
3322 {
3323 Window theRoot, theChild;
3324 int wX, wY, rootX, rootY, status;
3325 unsigned int wButtons;
3326 struct window *win = W_Void2Window(w);
3327 Window thisWin = win->window;
3328
3329 status = XQueryPointer(W_Display, thisWin, &theRoot, &theChild,
3330 &rootX, &rootY, &wX, &wY, &wButtons);
3331 if (status == True)
3332 {
3333 /* if it's in the window we specified then the values returned should *
3334 *
3335 * * be within the with and height of the window */
3336 if (wX <= win->width && wY <= win->height)
3337 {
3338 *x = wX;
3339 *y = wY;
3340 return 1;
3341 }
3342 }
3343 *x = 0;
3344 *y = 0;
3345 return 0;
3346 }
3347
W_Flush(void)3348 void W_Flush(void)
3349 {
3350 XFlush(W_Display);
3351 }
3352
3353 #define MAKE_WINDOW_GETTER(name, part) \
3354 W_Callback name(W_Window w) \
3355 { \
3356 return W_Void2Window(w)->part; \
3357 }
3358
3359 #define MAKE_WINDOW_SETTER(name, part) \
3360 void name(W_Window w, W_Callback c) \
3361 { \
3362 W_Void2Window(w)->part = c; \
3363 }
3364
MAKE_WINDOW_GETTER(W_GetWindowKeyDownHandler,handle_keydown)3365 MAKE_WINDOW_GETTER(W_GetWindowKeyDownHandler, handle_keydown)
3366 MAKE_WINDOW_SETTER(W_SetWindowKeyDownHandler, handle_keydown)
3367
3368 MAKE_WINDOW_GETTER(W_GetWindowKeyUpHandler, handle_keyup)
3369 MAKE_WINDOW_SETTER(W_SetWindowKeyUpHandler, handle_keyup)
3370
3371 MAKE_WINDOW_GETTER(W_GetWindowButtonHandler, handle_button)
3372 MAKE_WINDOW_SETTER(W_SetWindowButtonHandler, handle_button)
3373
3374 MAKE_WINDOW_GETTER(W_GetWindowExposeHandler, handle_expose)
3375 MAKE_WINDOW_SETTER(W_SetWindowExposeHandler, handle_expose)
3376
3377 void
3378 W_ResizeWindow(W_Window window, int neww, int newh) /* TSH 2/93 */
3379
3380
3381
3382 {
3383 struct window *w = W_Void2Window(window);
3384 XSizeHints *sz_hints;
3385
3386 sz_hints = XAllocSizeHints();
3387 sz_hints->min_width = neww;
3388 sz_hints->max_width = neww;
3389 sz_hints->min_height = newh;
3390 sz_hints->max_height = newh;
3391 sz_hints->flags = PMinSize | PMaxSize;
3392 XSetWMNormalHints(W_Display, w->window, sz_hints);
3393 XResizeWindow(W_Display, w->window, neww, newh);
3394 }
3395
3396 void
W_ReinitMenu(W_Window window,int neww,int newh)3397 W_ReinitMenu(W_Window window, int neww, int newh)
3398 {
3399 struct window *win = W_Void2Window(window);
3400 struct menuItem *items;
3401 int i;
3402
3403 items = (struct menuItem *) win->data;
3404 for(i=0; i< win->height; i++){
3405 free((char *) items[i].string);
3406 }
3407 free ((char *)items);
3408 items = (struct menuItem *) malloc(newh * sizeof(struct menuItem));
3409 for(i=0; i< newh; i++){
3410 items[i].column = 0;
3411 items[i].string = (char *) malloc(MAX_TEXT_WIDTH);
3412 items[i].color = W_White;
3413 }
3414 win->data = (char *) items;
3415 }
3416
3417 /* this procedure should only be used if the menu is initially defined
3418 by W_MakeMenu as large as it will get. If menu may grow, call
3419 W_ReinitMenu first */
3420
3421 void
W_ResizeMenu(W_Window window,int neww,int newh)3422 W_ResizeMenu(W_Window window, int neww, int newh) /* TSH 2/93 */
3423 {
3424 struct window *w = W_Void2Window(window);
3425
3426 w->width = neww;
3427 w->height = newh;
3428
3429 W_ResizeWindow(window, neww*W_Textwidth+WIN_EDGE*2,
3430 newh*(W_Textheight+MENU_PAD*2)+(newh-1)*MENU_BAR);
3431 }
3432
3433 void
W_ResizeTextWindow(W_Window window,int neww,int newh)3434 W_ResizeTextWindow(W_Window window, int neww, int newh) /* TSH 2/93 */
3435 {
3436 W_ResizeWindow(window, neww * W_Textwidth + WIN_EDGE * 2,
3437 newh * W_Textheight + WIN_EDGE * 2);
3438 }
3439
3440 int
W_Mono(void)3441 W_Mono(void)
3442 {
3443 return (DisplayCells(W_Display, W_Screen) <= 2) || forceMono;
3444 }
3445
3446 int
W_EventsQueued(void)3447 W_EventsQueued(void)
3448 {
3449 return XEventsQueued(W_Display, QueuedAlready);
3450 }
3451
3452 int
W_EventsQueuedCk(void)3453 W_EventsQueuedCk(void)
3454 {
3455 return XEventsQueued(W_Display, QueuedAfterReading);
3456 }
3457
W_ReadEvents(void)3458 int W_ReadEvents(void)
3459 {
3460 XEvent event;
3461 struct timeval timeout = {0, 0};
3462 fd_set readfds;
3463
3464 FD_ZERO(&readfds);
3465 FD_SET(ConnectionNumber(W_Display), &readfds);
3466 if (SELECT(max_fd, &readfds, 0, 0, &timeout) == 1)
3467 {
3468 XPeekEvent(W_Display, &event);
3469 return 1;
3470 }
3471 return 0;
3472 }
3473
W_OverlayBitmap(int x,int y,W_Icon bit,W_Color color)3474 void W_OverlayBitmap(int x, int y, W_Icon bit, W_Color color)
3475 {
3476 struct icon *icon = W_Void2Icon(bit);
3477
3478 #if DEBUG > 4
3479 printf("Overlaying bitmap to %d\n", icon->window);
3480 #endif
3481
3482 XCopyPlane(W_Display, icon->bitmap, icon->window,
3483 colortable[color].contexts[0], 0, 0, icon->width, icon->height,
3484 x, y, 1);
3485 }
3486
W_SetWindowName(W_Window w,char * name)3487 void W_SetWindowName(W_Window w, char *name)
3488 {
3489 struct window *win = W_Void2Window(w);
3490
3491 XStoreName(W_Display, win->window, name);
3492
3493 return;
3494 }
3495
3496 #ifdef BEEPLITE
3497 static GC _tts_gc;
3498 static XFontStruct *_tts_fontinfo;
3499 static int _tts_th, _tts_tw;
3500
3501 int
W_TTSTextHeight(void)3502 W_TTSTextHeight(void)
3503 {
3504 return _tts_th;
3505 }
3506
3507 int
W_TTSTextWidth(char * s,int l)3508 W_TTSTextWidth(char *s, int l)
3509 {
3510 return XTextWidth(_tts_fontinfo, s, l);
3511 }
3512
3513
3514 void
init_tts(void)3515 init_tts(void)
3516 {
3517 char *fontname;
3518 XGCValues values;
3519 char *color;
3520 XColor xc;
3521
3522 fontname = getdefault("tts_font");
3523 if (!fontname)
3524 fontname = TTS_FONT;
3525
3526 #ifdef SHOW_DEFAULTS
3527 show_defaults("TTS", "tts_font", fontname, "TTS font.");
3528 #endif
3529
3530 #ifdef nodef
3531 if (forceMono || DisplayCells(W_Display, W_Screen) <= 2)
3532 {
3533 /* this is not going to work at all for b/w */
3534 tts_time = 0;
3535 F_beeplite_flags &= ~LITE_TTS;
3536 return;
3537 }
3538 #endif
3539
3540 _tts_fontinfo = XLoadQueryFont(W_Display, fontname);
3541 if (!_tts_fontinfo)
3542 {
3543 fprintf(stderr, "netrek: Can't find font \"%s\".\n", fontname);
3544 _tts_fontinfo = XLoadQueryFont(W_Display, "fixed");
3545 }
3546 if (!_tts_fontinfo)
3547 {
3548 fprintf(stderr, "netrek: Can't find any fonts.\n");
3549 terminate(1);
3550 }
3551 _tts_th = _tts_fontinfo->max_bounds.descent +
3552 _tts_fontinfo->max_bounds.ascent;
3553 _tts_tw = _tts_fontinfo->max_bounds.width;
3554
3555 values.font = _tts_fontinfo->fid;
3556
3557 if (forceMono || DisplayCells(W_Display, W_Screen) <= 2)
3558 {
3559 values.foreground = colortable[W_White].pixelValue;
3560 values.function = GXor;
3561 }
3562
3563 else
3564 {
3565
3566 color = getdefault("tts_color");
3567 if (!color)
3568 color = "grey";
3569
3570 #ifdef SHOW_DEFAULTS
3571 show_defaults("TTS", "tts_color", color, "TTS msg color.");
3572 #endif
3573
3574 if (!XParseColor(W_Display, W_Colormap, color, &xc))
3575 {
3576 fprintf(stderr, "netrek: Unknown tts_color \"%s\", using #777\n", color);
3577 (void) XParseColor(W_Display, W_Colormap, "#777", &xc);
3578 }
3579 /* using the 8th color allocated in GetColors() */
3580 xc.pixel = colortable[W_Black].pixelValue | planes[0] | planes[2];
3581 if ((takeNearest) || (W_Visual->class != PseudoColor))
3582 XAllocColor(W_Display, W_Colormap, &xc);
3583 else
3584 XStoreColor(W_Display, W_Colormap, &xc);
3585 values.foreground = xc.pixel;
3586 values.function = GXor;
3587 }
3588
3589 _tts_gc = XCreateGC(W_Display, W_Root, GCFont | GCForeground | GCFunction,
3590 &values);
3591
3592 XSetGraphicsExposures(W_Display, _tts_gc, False);
3593 }
3594
3595 void
W_EraseTTSText(W_Window window,int max_width,int y,int width)3596 W_EraseTTSText(W_Window window, int max_width, int y, int width)
3597 {
3598 // struct window *win = W_Void2Window(window);
3599 int x = (max_width - width) / 2;
3600
3601 if (x < 0)
3602 x = 4;
3603 y -= W_TTSTextHeight();
3604
3605 W_ClearArea(window, x, y, width, W_TTSTextHeight());
3606 }
3607
3608 void
W_WriteTTSText(W_Window window,int max_width,int y,int width,char * str,int len)3609 W_WriteTTSText(W_Window window, int max_width, int y, int width, char *str, int len)
3610
3611
3612 /* max_width of window */
3613 /* y coordinate */
3614 /* actual width */
3615 /* string */
3616 /* length of string */
3617 {
3618 struct window *win = W_Void2Window(window);
3619 int x = (max_width - width) / 2;
3620
3621 if (x < 0)
3622 x = 4;
3623
3624 y -= _tts_fontinfo->max_bounds.descent;
3625
3626 /* y -= W_TTSTextHeight(); y += _tts_fontinfo->max_bounds.ascent; */
3627
3628 XDrawString(W_Display, win->window, _tts_gc, x, y, str, len);
3629 }
3630 #endif
3631
W_Halo(int x,int y,W_Color color)3632 void W_Halo(int x, int y, W_Color color)
3633 {
3634 struct window *win = W_Void2Window(mapw);
3635
3636 if ((color != W_Ind) && (color != W_Grey))
3637 {
3638 XSetForeground(W_Display, colortable[color].contexts[0],
3639 colortable[color].pixelValue);
3640 XDrawArc(W_Display, win->window, colortable[color].contexts[0],
3641 x - (mplanet_width / 2), y - (mplanet_width / 2),
3642 mplanet_width, mplanet_height, 0, 23040);
3643 }
3644 }
3645
W_CameraSnap(W_Window window)3646 void W_CameraSnap(W_Window window)
3647 {
3648 #ifdef CAMERA
3649 struct window *win = W_Void2Window(window);
3650 camera_snap(W_Display, win->window);
3651 #else
3652 fprintf(stderr, "W_CameraSnap: function not implemented in this build.");
3653 #endif
3654 }
3655
3656 #ifdef FULLSCREEN
3657
3658 /* XFree86 VidMode X extension handling */
3659
3660 #include <X11/extensions/xf86vmode.h>
3661
3662 XF86VidModeModeInfo **video_mode_list;
3663 XF86VidModeModeInfo *video_mode_current, *video_mode_original;
3664 int video_mode_dotclock, video_mode_list_size;
3665
3666 /* restore video mode to known previous mode */
video_mode_off()3667 static void video_mode_off()
3668 {
3669 if (video_mode_current != video_mode_original) {
3670 XF86VidModeSwitchToMode(W_Display, W_Screen, video_mode_original);
3671 video_mode_current = video_mode_original;
3672 }
3673 }
3674
3675 /* check if X server has support for changing modes */
video_mode_initialise()3676 static int video_mode_initialise() {
3677 int major, minor;
3678 if (!XF86VidModeQueryVersion(W_Display, &major, &minor)) {
3679 fprintf(stderr, "video_mode_initialise: XFree86-VidMode X extension absent\n");
3680 return 0;
3681 }
3682
3683 static int done = 0;
3684 if (done) return 1;
3685 done++;
3686
3687 int line;
3688 XF86VidModeModeLine current;
3689
3690 /* obtain the current mode line and list of known mode lines */
3691 XF86VidModeGetModeLine(W_Display, W_Screen, &video_mode_dotclock, ¤t);
3692 XF86VidModeGetAllModeLines(W_Display, W_Screen,
3693 &video_mode_list_size, &video_mode_list);
3694
3695 /* find the current mode within the list of known mode lines */
3696 video_mode_current = NULL;
3697 for (line=0; line < video_mode_list_size; line++) {
3698 XF86VidModeModeInfo *mode = video_mode_list[line];
3699 if (mode->hdisplay == current.hdisplay &&
3700 mode->vdisplay == current.vdisplay &&
3701 mode->dotclock == video_mode_dotclock &&
3702 mode->htotal == current.htotal &&
3703 mode->vtotal == current.vtotal &&
3704 mode->flags == current.flags) {
3705 video_mode_original = video_mode_current = mode;
3706 }
3707 }
3708
3709 /* do not change if the current mode was not found */
3710 if (video_mode_current == NULL) {
3711 fprintf(stderr, "video_mode_begin: this mode not found, "
3712 "cannot switch back, so not switching\n");
3713 return 0;
3714 }
3715
3716 return 1;
3717 }
3718
video_mode_on()3719 static void video_mode_on()
3720 {
3721 int line;
3722
3723 /* if there is a mode line for 1024x768 then use it */
3724 for (line=0; line < video_mode_list_size; line++) {
3725 XF86VidModeModeInfo *mode = video_mode_list[line];
3726 if (mode->hdisplay == (small_screen ? 800 : 1024) &&
3727 mode->vdisplay == (small_screen ? 600 : 768)) {
3728 XF86VidModeSwitchToMode(W_Display, W_Screen, mode);
3729 /*! @bug: if this is done on a non-local display, the X error
3730 XF86VidModeClientNotLocal occurs. */
3731 video_mode_current = mode;
3732 return;
3733 }
3734 }
3735 }
3736
view_port_warp(W_Window window)3737 static void view_port_warp(W_Window window)
3738 {
3739 struct window *win = W_Void2Window(window);
3740
3741 /* force the video view port to cover the window */
3742 int tx = 0, ty = 0;
3743 Window child;
3744 XTranslateCoordinates(W_Display, win->window, W_Root, 0, 0, &tx, &ty, &child);
3745 XF86VidModeSetViewPort(W_Display, W_Screen, tx, ty);
3746 XMapRaised(W_Display, win->window);
3747 XRaiseWindow(W_Display, win->window);
3748 }
3749
3750 /* force the cursor to stay within the window */
pointer_grab_on(W_Window window)3751 static void pointer_grab_on(W_Window window)
3752 {
3753 struct window *win = W_Void2Window(window);
3754
3755 XGrabPointer(W_Display, win->window, True, ButtonPressMask |
3756 ButtonReleaseMask | EnterWindowMask | LeaveWindowMask |
3757 PointerMotionMask | PointerMotionHintMask |
3758 Button1MotionMask | Button2MotionMask |
3759 Button3MotionMask | Button4MotionMask |
3760 Button5MotionMask | ButtonMotionMask |
3761 KeymapStateMask, GrabModeAsync, GrabModeAsync,
3762 win->window, None, CurrentTime);
3763 XGrabKeyboard(W_Display, win->window, True, GrabModeAsync,
3764 GrabModeAsync, CurrentTime);
3765 XFlush(W_Display);
3766 }
3767
pointer_grab_off(W_Window window)3768 static void pointer_grab_off(W_Window window)
3769 {
3770 XUngrabPointer(W_Display, CurrentTime);
3771 XUngrabKeyboard(W_Display, CurrentTime);
3772 }
3773
kde_fullscreen_on(W_Window window)3774 static void kde_fullscreen_on(W_Window window) {
3775 struct window *win = W_Void2Window(window);
3776 Atom WM_HINTS;
3777 WM_HINTS = XInternAtom(W_Display, "_NET_WM_STATE", True);
3778 if (WM_HINTS != None) {
3779 Atom p[1];
3780 p[0] = XInternAtom(W_Display, "_NET_WM_STATE_FULLSCREEN", True);
3781 XChangeProperty(W_Display, win->window, WM_HINTS, XA_ATOM, 32,
3782 PropModeReplace, (unsigned char *)p, 1);
3783 }
3784 }
3785
kde_fullscreen_off(W_Window window)3786 static void kde_fullscreen_off(W_Window window) {
3787 struct window *win = W_Void2Window(window);
3788 Atom WM_HINTS;
3789 WM_HINTS = XInternAtom(W_Display, "_NET_WM_STATE", True);
3790 if (WM_HINTS != None) {
3791 XDeleteProperty(W_Display, win->window, WM_HINTS);
3792 }
3793 }
3794
3795 #endif /* FULLSCREEN */
3796
W_FullScreenOn(W_Window window)3797 void W_FullScreenOn(W_Window window)
3798 {
3799 struct window *win = W_Void2Window(window);
3800 #ifdef FULLSCREEN
3801 #if DEBUG > 0
3802 fprintf(stderr, "W_FullScreenOn\n");
3803 #endif
3804 XResizeWindow(W_Display, win->window,
3805 small_screen ? 800 : 1024,
3806 small_screen ? 600 : 768);
3807 pointer_grab_on(window);
3808 video_mode_on();
3809 view_port_warp(window);
3810 kde_fullscreen_on(window);
3811 #endif
3812 }
3813
W_FullScreenOff(W_Window window)3814 void W_FullScreenOff(W_Window window)
3815 {
3816 #ifdef FULLSCREEN
3817 #if DEBUG > 0
3818 fprintf(stderr, "W_FullScreenOff\n");
3819 #endif
3820 pointer_grab_off(window);
3821 kde_fullscreen_off(window);
3822 video_mode_off();
3823 #endif
3824 }
3825
W_FullScreenInitialise()3826 void W_FullScreenInitialise() {
3827 #ifdef FULLSCREEN
3828 #if DEBUG > 0
3829 fprintf(stderr, "W_FullScreenInitialise\n");
3830 #endif
3831 full_screen_enabled = 0;
3832 full_screen_default = 0;
3833 if (booleanDefault("FullScreen", 0)) {
3834 full_screen_default++;
3835 if (video_mode_initialise())
3836 full_screen_enabled++;
3837 }
3838 #endif
3839 }
3840
W_FullScreenToggle(W_Window window)3841 int W_FullScreenToggle(W_Window window) {
3842 #ifdef FULLSCREEN
3843 #if DEBUG > 0
3844 fprintf(stderr, "W_FullScreenToggle\n");
3845 #endif
3846 if (full_screen_enabled) {
3847 full_screen_enabled = 0;
3848 W_FullScreenOff(window);
3849 } else {
3850 if (!full_screen_default) {
3851 if (!video_mode_initialise()) {
3852 return FULLSCREEN_FAILED;
3853 }
3854 }
3855 full_screen_enabled++;
3856 W_FullScreenOn(window);
3857 }
3858 return FULLSCREEN_OK;
3859 #else
3860 return FULLSCREEN_NOT_COMPILED;
3861 #endif
3862 }
3863
W_FullScreenBegin(W_Window window)3864 void W_FullScreenBegin(W_Window window) {
3865 #ifdef FULLSCREEN
3866 #if DEBUG > 0
3867 fprintf(stderr, "W_FullScreenBegin\n");
3868 #endif
3869 if (full_screen_enabled) {
3870 W_FullScreenOn(window);
3871 }
3872 #endif
3873 }
3874
3875 /* regularly enforce */
W_FullScreen(W_Window window)3876 void W_FullScreen(W_Window window) {
3877 #ifdef FULLSCREEN
3878 if (full_screen_enabled) {
3879 view_port_warp(window);
3880 pointer_grab_on(window);
3881 }
3882 #endif
3883 }
3884