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