~ubuntu-branches/ubuntu/trusty/netrek-client-cow/trusty

« back to all changes in this revision

Viewing changes to x11window.c

  • Committer: Bazaar Package Importer
  • Author(s): Barry deFreese
  • Date: 2008-09-26 21:44:49 UTC
  • Revision ID: james.westby@ubuntu.com-20080926214449-ylybi4033uv3lz2q
Tags: upstream-3.2.8
ImportĀ upstreamĀ versionĀ 3.2.8

Show diffs side-by-side

added added

removed removed

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