1 /* This file contains code for X-CHESS.
2 Copyright (C) 1986 Free Software Foundation, Inc.
3
4 This file is part of X-CHESS.
5
6 X-CHESS is distributed in the hope that it will be useful,
7 but WITHOUT ANY WARRANTY. No author or distributor
8 accepts responsibility to anyone for the consequences of using it
9 or for whether it serves any particular purpose or works at all,
10 unless he says so in writing. Refer to the X-CHESS General Public
11 License for full details.
12
13 Everyone is granted permission to copy, modify and redistribute
14 X-CHESS, but only under the conditions described in the
15 X-CHESS General Public License. A copy of this license is
16 supposed to have been given to you along with X-CHESS so you
17 can know your rights and responsibilities. It should be in a
18 file named COPYING. Among other things, the copyright notice
19 and this notice must be preserved on all copies. */
20
21
22 /* RCS Info: $Revision: 1.5 $ on $Date: 86/11/26 12:11:15 $
23 * $Source: /users/faustus/xchess/RCS/window.c,v $
24 * Copyright (c) 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
25 * Permission is granted to do anything with this code except sell it
26 * or remove this message.
27 *
28 * Deal with the two (or one) windows.
29 */
30
31 #include "xchess.h"
32 #include <X11/Xutil.h>
33 #include <sys/time.h>
34
35 #include "pawn.bitmap"
36 #include "rook.bitmap"
37 #include "knight.bitmap"
38 #include "bishop.bitmap"
39 #include "queen.bitmap"
40 #include "king.bitmap"
41
42 #include "pawn_outline.bitmap"
43 #include "rook_outline.bitmap"
44 #include "knight_outline.bitmap"
45 #include "bishop_outline.bitmap"
46 #include "queen_outline.bitmap"
47 #include "king_outline.bitmap"
48
49 #include "pawn_mask.bitmap"
50 #include "rook_mask.bitmap"
51 #include "knight_mask.bitmap"
52 #include "bishop_mask.bitmap"
53 #include "queen_mask.bitmap"
54 #include "king_mask.bitmap"
55
56 #include "shade.bitmap"
57
58 #include "xchess.cur"
59 #include "xchess_mask.cur"
60
61 #include "xchess.icon"
62
63 windata *win1, *win2;
64 bool win_flashmove = false;
65
66 extern bool setup();
67 extern void service(), drawgrid(), icon_refresh();
68
69 bool
win_setup(disp1,disp2)70 win_setup(disp1, disp2)
71 char *disp1, *disp2;
72 {
73 win1 = alloc(windata);
74 if (!oneboard)
75 win2 = alloc(windata);
76
77 if (!setup(disp1, win1) || (!oneboard && !setup(disp2, win2)))
78 return (false);
79
80 if (blackflag) {
81 win1->color = BLACK;
82 win1->flipped = true;
83 } else
84 win1->color = WHITE;
85 win_drawboard(win1);
86
87 if (!oneboard) {
88 win2->color = BLACK;
89 win2->flipped = true;
90 win_drawboard(win2);
91 }
92
93 return(true);
94 }
95
96 /* Draw the chess board... */
97
98 void
win_drawboard(win)99 win_drawboard(win)
100 windata *win;
101 {
102 int i, j;
103
104 drawgrid(win);
105
106 /* Now toss on the squares... */
107 for (i = 0; i < SIZE; i++)
108 for (j = 0; j < SIZE; j++)
109 win_erasepiece(j, i, win->color);
110
111 return;
112 }
113
114 /* Draw one piece. */
115
116 void
win_drawpiece(p,y,x,wnum)117 win_drawpiece(p, y, x, wnum)
118 piece *p;
119 int y, x;
120 color wnum;
121 {
122 char *bits, *maskbits, *outline;
123 windata *win;
124 char buf[BSIZE];
125 XImage *tmpImage;
126 Pixmap tmpPM, maskPM;
127 XGCValues gc;
128
129 if (oneboard || (wnum == win1->color))
130 win = win1;
131 else
132 win = win2;
133
134 if (win->flipped) {
135 y = SIZE - y - 1;
136 x = SIZE - x - 1;
137 }
138
139 /*
140 if (debug)
141 fprintf(stderr, "draw a %s at (%d, %d) on board %d\n",
142 piecenames[(int) p->type], y, x, wnum);
143 */
144
145 if ((x < 0) || (x > 7) || (y < 0) || (y > 7)) exit(1);
146
147 switch (p->type) {
148 case PAWN:
149 bits = pawn_bits;
150 maskbits = pawn_mask_bits;
151 outline = pawn_outline_bits;
152 break;
153
154 case ROOK:
155 bits = rook_bits;
156 maskbits = rook_mask_bits;
157 outline = rook_outline_bits;
158 break;
159
160 case KNIGHT:
161 bits = knight_bits;
162 maskbits = knight_mask_bits;
163 outline = knight_outline_bits;
164 break;
165
166 case BISHOP:
167 bits = bishop_bits;
168 maskbits = bishop_mask_bits;
169 outline = bishop_outline_bits;
170 break;
171
172 case QUEEN:
173 bits = queen_bits;
174 maskbits = queen_mask_bits;
175 outline = queen_outline_bits;
176 break;
177
178 case KING:
179 bits = king_bits;
180 maskbits = king_mask_bits;
181 outline = king_outline_bits;
182 break;
183
184 default:
185 fprintf(stderr,
186 "Internal Error: win_drawpiece: bad piece type %d\n",
187 p->type);
188 }
189
190 /* There are two things we can do... If this is a black and white
191 * display, we have to shade the square and use an outline if the piece
192 * is white. We also have to use a mask... Since we don't want
193 * to use up too many bitmaps, create the mask bitmap, put the bits,
194 * and then destroy it.
195 */
196 if (win->bnw && (p->color == WHITE))
197 bits = outline;
198 if (win->bnw && !iswhite(win, x, y)) {
199 XSetState(win->display, DefaultGC(win->display, 0),
200 BlackPixel(win->display, 0),
201 WhitePixel(win->display, 0), GXcopy, AllPlanes);
202
203 tmpPM = XCreateBitmapFromData(win->display, win->boardwin,
204 shade_bits, SQUARE_WIDTH, SQUARE_HEIGHT);
205
206 XCopyPlane(win->display, tmpPM, win->boardwin, DefaultGC(win->display, 0),
207 0, 0, SQUARE_WIDTH, SQUARE_HEIGHT,
208 x * (SQUARE_WIDTH + BORDER_WIDTH),
209 y * (SQUARE_HEIGHT + BORDER_WIDTH), 1);
210
211 XFreePixmap(win->display, tmpPM);
212
213 XSetFunction(win->display, DefaultGC(win->display, 0),
214 GXandInverted);
215 maskPM = XCreateBitmapFromData(win->display, win->boardwin,
216 maskbits, SQUARE_WIDTH, SQUARE_HEIGHT);
217 XCopyPlane(win->display, maskPM, win->boardwin, DefaultGC(win->display, 0),
218 0, 0, SQUARE_WIDTH, SQUARE_HEIGHT,
219 x * (SQUARE_WIDTH + BORDER_WIDTH),
220 y * (SQUARE_HEIGHT + BORDER_WIDTH), 1);
221 XFreePixmap(win->display, maskPM);
222
223 XSetFunction(win->display, DefaultGC(win->display, 0),
224 GXor);
225 tmpPM = XCreateBitmapFromData(win->display, win->boardwin,
226 bits, SQUARE_WIDTH, SQUARE_HEIGHT);
227 XCopyPlane(win->display, tmpPM, win->boardwin, DefaultGC(win->display, 0),
228 0, 0, SQUARE_WIDTH, SQUARE_HEIGHT,
229 x * (SQUARE_WIDTH + BORDER_WIDTH),
230 y * (SQUARE_HEIGHT + BORDER_WIDTH), 1);
231 XFreePixmap(win->display, tmpPM);
232
233 XSetFunction(win->display, DefaultGC(win->display, 0), GXcopy);
234
235 } else if (win->bnw){
236 XSetState(win->display, DefaultGC(win->display, 0),
237 BlackPixel(win->display, 0),
238 WhitePixel(win->display, 0), GXcopy, AllPlanes);
239
240 tmpPM = XCreateBitmapFromData(win->display, win->boardwin,
241 bits, SQUARE_WIDTH, SQUARE_HEIGHT);
242 XCopyPlane(win->display, tmpPM, win->boardwin, DefaultGC(win->display, 0),
243 0, 0, SQUARE_WIDTH, SQUARE_HEIGHT,
244 x * (SQUARE_WIDTH + BORDER_WIDTH),
245 y * (SQUARE_HEIGHT + BORDER_WIDTH), 1);
246 XFreePixmap(win->display, tmpPM);
247 } else {
248 XSetState(win->display, DefaultGC(win->display, 0),
249 ((p->color == WHITE) ? win->whitepiece.pixel :
250 win->blackpiece.pixel),
251 (iswhite(win, x, y) ? win->whitesquare.pixel :
252 win->blacksquare.pixel),
253 GXcopy, AllPlanes);
254 tmpPM = XCreateBitmapFromData(win->display, win->boardwin,
255 bits, SQUARE_WIDTH, SQUARE_HEIGHT);
256 XCopyPlane(win->display, tmpPM, win->boardwin, DefaultGC(win->display, 0),
257 0, 0, SQUARE_WIDTH, SQUARE_HEIGHT,
258 x * (SQUARE_WIDTH + BORDER_WIDTH),
259 y * (SQUARE_HEIGHT + BORDER_WIDTH), 1);
260 XFreePixmap(win->display, tmpPM);
261 }
262
263 if (!record_english) {
264 gc.foreground = win->textcolor.pixel;
265 if (iswhite(win, x, y) || win->bnw)
266 gc.background = win->whitesquare.pixel;
267 else
268 gc.background = win->blacksquare.pixel;
269
270 gc.font = win->small->fid;
271
272 XChangeGC(win->display, DefaultGC(win->display, 0),
273 GCForeground | GCBackground | GCFont, &gc);
274
275 if (!x) {
276 sprintf(buf, " %d", SIZE - y);
277 XDrawImageString(win->display, win->boardwin,
278 DefaultGC(win->display, 0),
279 1, (y + 1) * (SQUARE_HEIGHT +
280 BORDER_WIDTH) - BORDER_WIDTH +
281 win->small->max_bounds.ascent - 1, buf, 2);
282 }
283 if (y == SIZE - 1) {
284 sprintf(buf, "%c", 'A' + x);
285 XDrawImageString(win->display, win->boardwin,
286 DefaultGC(win->display, 0),
287 x * (SQUARE_WIDTH + BORDER_WIDTH) + 1,
288 SIZE * (SQUARE_HEIGHT + BORDER_WIDTH) - BORDER_WIDTH +
289 win->small->max_bounds.ascent - 1, buf, 1);
290 }
291 }
292 return;
293 }
294
295 void
win_erasepiece(y,x,wnum)296 win_erasepiece(y, x, wnum)
297 int y, x;
298 color wnum;
299 {
300 windata *win;
301 char buf[BSIZE];
302 XGCValues gc;
303 Pixmap tmpPM;
304
305 if (oneboard || (wnum == win1->color))
306 win = win1;
307 else
308 win = win2;
309
310 if (win->flipped) {
311 y = SIZE - y - 1;
312 x = SIZE - x - 1;
313 }
314
315 /*
316 if (debug)
317 fprintf(stderr, "erase square (%d, %d) on board %d\n", y, x,
318 wnum);
319 */
320
321 if ((x < 0) || (x > 7) || (y < 0) || (y > 7)) exit(1);
322
323 if (win->bnw && !iswhite(win, x, y)) {
324 XSetState(win->display, DefaultGC(win->display, 0),
325 BlackPixel(win->display, 0),
326 WhitePixel(win->display, 0), GXcopy, AllPlanes);
327 tmpPM = XCreateBitmapFromData(win->display, win->boardwin,
328 shade_bits, SQUARE_WIDTH, SQUARE_HEIGHT);
329
330 XCopyPlane(win->display, tmpPM, win->boardwin, DefaultGC(win->display, 0),
331 0, 0, SQUARE_WIDTH, SQUARE_HEIGHT,
332 x * (SQUARE_WIDTH + BORDER_WIDTH),
333 y * (SQUARE_HEIGHT + BORDER_WIDTH), 1);
334
335 XFreePixmap(win->display, tmpPM);
336 } else {
337 XSetFillStyle(win->display, DefaultGC(win->display, 0),
338 FillSolid);
339 XSetForeground(win->display, DefaultGC(win->display, 0),
340 iswhite(win, x, y) ? win->whitesquare.pixel :
341 win->blacksquare.pixel);
342 XFillRectangle(win->display, win->boardwin,
343 DefaultGC(win->display, 0),
344 x * (SQUARE_WIDTH + BORDER_WIDTH),
345 y * (SQUARE_HEIGHT + BORDER_WIDTH),
346 SQUARE_WIDTH, SQUARE_HEIGHT);
347 }
348
349 if (!record_english) {
350 gc.foreground = win->textcolor.pixel;
351 if (iswhite(win, x, y) || win->bnw)
352 gc.background = win->whitesquare.pixel;
353 else
354 gc.background = win->blacksquare.pixel;
355
356 gc.font = win->small->fid;
357
358 XChangeGC(win->display, DefaultGC(win->display, 0),
359 GCForeground | GCBackground | GCFont, &gc);
360
361 if (!x) {
362 sprintf(buf, " %d", SIZE - y);
363 XDrawImageString(win->display, win->boardwin,
364 DefaultGC(win->display, 0),
365 1, (y + 1) * (SQUARE_HEIGHT +
366 BORDER_WIDTH) - BORDER_WIDTH +
367 win->small->max_bounds.ascent - 1, buf, 2);
368 }
369 if (y == SIZE - 1) {
370 sprintf(buf, "%c", 'A' + x);
371 XDrawImageString(win->display, win->boardwin,
372 DefaultGC(win->display, 0),
373 x * (SQUARE_WIDTH + BORDER_WIDTH) + 1,
374 SIZE * (SQUARE_HEIGHT + BORDER_WIDTH) - BORDER_WIDTH +
375 win->small->max_bounds.ascent - 1, buf, 1);
376 }
377 }
378
379
380 return;
381 }
382
383 void
win_flash(m,wnum)384 win_flash(m, wnum)
385 move *m;
386 color wnum;
387 {
388 windata *win;
389 int sx, sy, ex, ey, i;
390
391 if (oneboard || (wnum == win1->color))
392 win = win1;
393 else
394 win = win2;
395
396 if (win->flipped) {
397 sx = SIZE - m->fromx - 1;
398 sy = SIZE - m->fromy - 1;
399 ex = SIZE - m->tox - 1;
400 ey = SIZE - m->toy - 1;
401 } else {
402 sx = m->fromx;
403 sy = m->fromy;
404 ex = m->tox;
405 ey = m->toy;
406 }
407 sx = sx * (SQUARE_WIDTH + BORDER_WIDTH) + SQUARE_WIDTH / 2;
408 sy = sy * (SQUARE_HEIGHT + BORDER_WIDTH) + SQUARE_HEIGHT / 2;
409 ex = ex * (SQUARE_WIDTH + BORDER_WIDTH) + SQUARE_WIDTH / 2;
410 ey = ey * (SQUARE_HEIGHT + BORDER_WIDTH) + SQUARE_HEIGHT / 2;
411
412 XSetFunction(win->display, DefaultGC(win->display, 0), GXinvert);
413 XSetLineAttributes(win->display, DefaultGC(win->display, 0),
414 0, LineSolid, 0, 0);
415 for (i = 0; i < num_flashes * 2; i++) {
416 XDrawLine(win->display,win->boardwin,
417 DefaultGC(win->display, 0),
418 sx, sy, ex, ey);
419 }
420
421 XSetFunction(win->display, DefaultGC(win->display, 0), GXcopy);
422 return;
423 }
424
425 /* Handle input from the players. */
426
427 void
win_process(quick)428 win_process(quick)
429 bool quick;
430 {
431 int i, rfd = 0, wfd = 0, xfd = 0;
432 struct timeval timeout;
433
434 timeout.tv_sec = 0;
435 timeout.tv_usec = (quick ? 0 : 500000);
436
437 if (XPending(win1->display))
438 service(win1);
439 if (!oneboard) {
440 if (XPending(win1->display))
441 service(win2);
442 }
443
444 if (oneboard)
445 rfd = 1 << win1->display->fd;
446 else
447 rfd = (1 << win1->display->fd) | (1 << win2->display->fd);
448 if (!(i = select(32, &rfd, &wfd, &xfd, &timeout)))
449 return;
450 if (i == -1) {
451 perror("select");
452 exit(1);
453 }
454 if (rfd & (1 << win1->display->fd))
455 service(win1);
456 if (!oneboard && (rfd & (1 << win2->display->fd)))
457 service(win2);
458
459 return;
460 }
461
462 static void
service(win)463 service(win)
464 windata *win;
465 {
466 XEvent ev;
467
468 while(XPending(win->display)) {
469 XNextEvent(win->display, &ev);
470 if (TxtFilter(win->display, &ev))
471 continue;
472
473 if (ev.xany.window == win->boardwin) {
474 switch (ev.type) {
475 case ButtonPress:
476 button_pressed(&ev, win);
477 break;
478
479 case ButtonRelease:
480 button_released(&ev, win);
481 break;
482
483 case Expose:
484 /* Redraw... */
485 win_redraw(win, &ev);
486 break;
487
488 case 0:
489 case NoExpose:
490 break;
491 default:
492 fprintf(stderr, "Bad event type %d\n", ev.type);
493 exit(1);
494 }
495 } else if (ev.xany.window == win->wclockwin) {
496 switch (ev.type) {
497 case Expose:
498 clock_draw(win, WHITE);
499 break;
500
501 case 0:
502 case NoExpose:
503 break;
504 default:
505 fprintf(stderr, "Bad event type %d\n", ev.type);
506 exit(1);
507 }
508 } else if (ev.xany.window == win->bclockwin) {
509 switch (ev.type) {
510 case Expose:
511 clock_draw(win, BLACK);
512 break;
513
514 case 0:
515 case NoExpose:
516 break;
517 default:
518 fprintf(stderr, "Bad event type %d\n", ev.type);
519 exit(1);
520 }
521 } else if (ev.xany.window == win->jailwin) {
522 switch (ev.type) {
523 case Expose:
524 jail_draw(win);
525 break;
526
527 case 0:
528 case NoExpose:
529 break;
530 default:
531 fprintf(stderr, "Bad event type %d\n", ev.type);
532 exit(1);
533 }
534 } else if (ev.xany.window == win->buttonwin) {
535 switch (ev.type) {
536 case ButtonPress:
537 button_service(win, &ev);
538 break;
539
540 case Expose:
541 button_draw(win);
542 break;
543
544 case 0:
545 case NoExpose:
546 break;
547 default:
548 fprintf(stderr, "Bad event type %d\n", ev.type);
549 exit(1);
550 }
551 } else if (ev.xany.window == win->icon) {
552 icon_refresh(win);
553 } else if (ev.xany.window == win->basewin) {
554 message_send(win, &ev);
555 } else {
556 fprintf(stderr, "Internal Error: service: bad win\n");
557 fprintf(stderr, "window = %d, event = %d\n", ev.xany.window,
558 ev.type);
559 }
560 }
561 return;
562 }
563
564 void
win_redraw(win,event)565 win_redraw(win, event)
566 windata *win;
567 XEvent *event;
568 {
569 XExposeEvent *ev = &event->xexpose;
570 int x1, y1, x2, y2, i, j;
571
572 drawgrid(win);
573 if (ev) {
574 x1 = ev->x / (SQUARE_WIDTH + BORDER_WIDTH);
575 y1 = ev->y / (SQUARE_HEIGHT + BORDER_WIDTH);
576 x2 = (ev->x + ev->width) / (SQUARE_WIDTH + BORDER_WIDTH);
577 y2 = (ev->y + ev->height) / (SQUARE_HEIGHT + BORDER_WIDTH);
578 } else {
579 x1 = 0;
580 y1 = 0;
581 x2 = SIZE - 1;
582 y2 = SIZE - 1;
583 }
584
585 if (x1 < 0) x1 = 0;
586 if (y1 < 0) y1 = 0;
587 if (x2 < 0) x2 = 0;
588 if (y2 < 0) y2 = 0;
589 if (x1 > SIZE - 1) x1 = SIZE - 1;
590 if (y1 > SIZE - 1) y1 = SIZE - 1;
591 if (x2 > SIZE - 1) x2 = SIZE - 1;
592 if (y2 > SIZE - 1) y2 = SIZE - 1;
593
594 if (win->flipped) {
595 y1 = SIZE - y2 - 1;
596 y2 = SIZE - y1 - 1;
597 x1 = SIZE - x2 - 1;
598 x2 = SIZE - x1 - 1;
599 }
600
601 for (i = x1; i <= x2; i++)
602 for (j = y1; j <= y2; j++) {
603 if (chessboard->square[j][i].color == NONE)
604 win_erasepiece(j, i, WHITE);
605 else
606 win_drawpiece(&chessboard->square[j][i], j, i,
607 WHITE);
608 if (!oneboard) {
609 if (chessboard->square[j][i].color == NONE)
610 win_erasepiece(j, i, BLACK);
611 else
612 win_drawpiece(&chessboard->square[j][i],
613 j, i, BLACK);
614 }
615 }
616
617 return;
618 }
619
620 static bool
setup(dispname,win)621 setup(dispname, win)
622 char *dispname;
623 windata *win;
624 {
625 char buf[BSIZE], *s;
626 Pixmap bm, bmask;
627 Cursor cur;
628 extern char *program, *recfile;
629 XSizeHints xsizes;
630
631
632 if (!(win->display = XOpenDisplay(dispname)))
633 return (false);
634
635
636 /* Now get boolean defaults... */
637 if ((s = XGetDefault(win->display, program, "noisy")) && eq(s, "on"))
638 noisyflag = true;
639 if ((s = XGetDefault(win->display, program, "savemoves")) && eq(s, "on"))
640 saveflag = true;
641 if ((s = XGetDefault(win->display, program, "algebraic")) && eq(s, "on"))
642 record_english = false;
643 if ((s = XGetDefault(win->display, program, "blackandwhite")) && eq(s, "on"))
644 bnwflag = true;
645 if ((s = XGetDefault(win->display, program, "quickrestore")) && eq(s, "on"))
646 quickflag = true;
647 if ((s = XGetDefault(win->display, program, "flash")) && eq(s, "on"))
648 win_flashmove = true;
649
650 /* ... numeric variables ... */
651 if (s = XGetDefault(win->display, program, "numflashes"))
652 num_flashes = atoi(s);
653 if (s = XGetDefault(win->display, program, "flashsize"))
654 flash_size = atoi(s);
655
656 /* ... and strings. */
657 if (s = XGetDefault(win->display, program, "progname"))
658 progname = s;
659 if (s = XGetDefault(win->display, program, "proghost"))
660 proghost = s;
661 if (s = XGetDefault(win->display, program, "recordfile"))
662 recfile = s;
663 if (s = XGetDefault(win->display, program, "blackpiece"))
664 black_piece_color = s;
665 if (s = XGetDefault(win->display, program, "whitepiece"))
666 white_piece_color = s;
667 if (s = XGetDefault(win->display, program, "blacksquare"))
668 black_square_color = s;
669 if (s = XGetDefault(win->display, program, "whitesquare"))
670 white_square_color = s;
671 if (s = XGetDefault(win->display, program, "bordercolor"))
672 border_color = s;
673 if (s = XGetDefault(win->display, program, "textcolor"))
674 text_color = s;
675 if (s = XGetDefault(win->display, program, "textback"))
676 text_back = s;
677 if (s = XGetDefault(win->display, program, "errortext"))
678 error_text = s;
679 if (s = XGetDefault(win->display, program, "playertext"))
680 player_text = s;
681 if (s = XGetDefault(win->display, program, "cursorcolor"))
682 cursor_color = s;
683
684 if ((DisplayPlanes(win->display, 0) == 1) || bnwflag)
685 win->bnw = true;
686
687 /* Allocate colors... */
688 if (win->bnw) {
689 win->blackpiece.pixel = BlackPixel (win->display, 0);
690 win->whitepiece.pixel = WhitePixel (win->display, 0);
691 win->blacksquare.pixel = BlackPixel (win->display, 0);
692 win->whitesquare.pixel = WhitePixel (win->display, 0);
693 win->border.pixel = BlackPixel (win->display, 0);
694 win->textcolor.pixel = BlackPixel (win->display, 0);
695 win->textback.pixel = WhitePixel (win->display, 0);
696 win->playertext.pixel = BlackPixel (win->display, 0);
697 win->errortext.pixel = BlackPixel (win->display, 0);
698 win->cursorcolor.pixel = BlackPixel (win->display, 0) ;
699 } else {
700 if (!XParseColor(win->display,
701 DefaultColormap(win->display, 0),
702 black_piece_color, &win->blackpiece) ||
703 !XParseColor(win->display,
704 DefaultColormap(win->display, 0),
705 white_piece_color, &win->whitepiece) ||
706 !XParseColor(win->display,
707 DefaultColormap(win->display, 0),
708 black_square_color, &win->blacksquare) ||
709 !XParseColor(win->display,
710 DefaultColormap(win->display, 0),
711 white_square_color, &win->whitesquare) ||
712 !XParseColor(win->display,
713 DefaultColormap(win->display, 0),
714 border_color, &win->border) ||
715 !XParseColor(win->display,
716 DefaultColormap(win->display, 0),
717 text_color, &win->textcolor) ||
718 !XParseColor(win->display,
719 DefaultColormap(win->display, 0),
720 text_back, &win->textback) ||
721 !XParseColor(win->display,
722 DefaultColormap(win->display, 0),
723 error_text, &win->errortext) ||
724 !XParseColor(win->display,
725 DefaultColormap(win->display, 0),
726 player_text, &win->playertext) ||
727 !XParseColor(win->display,
728 DefaultColormap(win->display, 0),
729 cursor_color, &win->cursorcolor) ||
730 !XAllocColor(win->display,
731 DefaultColormap(win->display, 0),
732 &win->blackpiece) ||
733 !XAllocColor(win->display,
734 DefaultColormap(win->display, 0),
735 &win->whitepiece) ||
736 !XAllocColor(win->display,
737 DefaultColormap(win->display, 0),
738 &win->blacksquare) ||
739 !XAllocColor(win->display,
740 DefaultColormap(win->display, 0),
741 &win->whitesquare) ||
742 !XAllocColor(win->display,
743 DefaultColormap(win->display, 0),
744 &win->border) ||
745 !XAllocColor(win->display,
746 DefaultColormap(win->display, 0),
747 &win->textcolor) ||
748 !XAllocColor(win->display,
749 DefaultColormap(win->display, 0),
750 &win->textback) ||
751 !XAllocColor(win->display,
752 DefaultColormap(win->display, 0),
753 &win->errortext) ||
754 !XAllocColor(win->display,
755 DefaultColormap(win->display, 0),
756 &win->playertext) ||
757 !XAllocColor(win->display,
758 DefaultColormap(win->display, 0),
759 &win->cursorcolor))
760 fprintf(stderr, "Can't get colors...\n");
761 }
762
763 /* Get fonts... */
764 if ((win->small = XLoadQueryFont(win->display,SMALL_FONT)) ==
765 NULL)
766 fprintf(stderr, "Can't get small font...\n");
767
768 if ((win->medium = XLoadQueryFont(win->display,MEDIUM_FONT))
769 == NULL)
770 fprintf(stderr, "Can't get medium font...\n");
771
772 if ((win->large = XLoadQueryFont(win->display,LARGE_FONT)) ==
773 NULL)
774 fprintf(stderr, "Can't get large font...\n");
775
776
777 /* Create the windows... */
778
779 win->basewin =
780 XCreateSimpleWindow(win->display,DefaultRootWindow(win->display),
781 BASE_XPOS, BASE_YPOS,
782 BASE_WIDTH, BASE_HEIGHT, 0,
783 BlackPixel(win->display, 0),
784 WhitePixel(win->display, 0));
785 win->boardwin = XCreateSimpleWindow(win->display,win->basewin,
786 BOARD_XPOS, BOARD_YPOS,
787 BOARD_WIDTH, BOARD_HEIGHT,
788 BORDER_WIDTH,
789 win->border.pixel,
790 WhitePixel(win->display, 0));
791 win->recwin = XCreateSimpleWindow(win->display,win->basewin,
792 RECORD_XPOS, RECORD_YPOS,
793 RECORD_WIDTH, RECORD_HEIGHT,
794 BORDER_WIDTH, win->border.pixel,
795 win->textback.pixel);
796 win->jailwin = XCreateSimpleWindow(win->display,win->basewin,
797 JAIL_XPOS, JAIL_YPOS,
798 JAIL_WIDTH, JAIL_HEIGHT,
799 BORDER_WIDTH,
800 win->border.pixel,
801 win->textback.pixel);
802 win->wclockwin = XCreateSimpleWindow(win->display,win->basewin,
803 WCLOCK_XPOS, WCLOCK_YPOS,
804 CLOCK_WIDTH, CLOCK_HEIGHT,
805 BORDER_WIDTH, win->border.pixel,
806 win->textback.pixel);
807 win->bclockwin = XCreateSimpleWindow(win->display,win->basewin,
808 BCLOCK_XPOS, BCLOCK_YPOS,
809 CLOCK_WIDTH, CLOCK_HEIGHT,
810 BORDER_WIDTH, win->border.pixel,
811 win->textback.pixel);
812 win->messagewin = XCreateSimpleWindow(win->display,win->basewin,
813 MESS_XPOS, MESS_YPOS,
814 MESS_WIDTH, MESS_HEIGHT,
815 BORDER_WIDTH, win->border.pixel,
816 win->textback.pixel);
817 win->buttonwin = XCreateSimpleWindow(win->display,win->basewin,
818 BUTTON_XPOS, BUTTON_YPOS,
819 BUTTON_WIDTH, BUTTON_HEIGHT,
820 BORDER_WIDTH, win->border.pixel,
821 win->textback.pixel);
822
823 /* Let's define an icon... */
824 win->iconpixmap = XCreatePixmapFromBitmapData(win->display,
825 win->basewin, icon_bits,
826 icon_width, icon_height,
827 win->blacksquare.pixel,
828 win->whitesquare.pixel,
829 1);
830 xsizes.flags = PSize | PMinSize | PPosition;
831 xsizes.min_width = BASE_WIDTH;
832 xsizes.min_height = BASE_HEIGHT;
833 xsizes.x = BASE_XPOS;
834 xsizes.y = BASE_YPOS;
835 XSetStandardProperties(win->display, win->basewin,
836 program, program, win->iconpixmap,
837 0, NULL, &xsizes);
838
839 bm = XCreateBitmapFromData(win->display,
840 win->basewin, xchess_bits,
841 xchess_width, xchess_height);
842 bmask = XCreateBitmapFromData(win->display,
843 win->basewin, xchess_mask_bits,
844 xchess_width, xchess_height);
845 cur = XCreatePixmapCursor(win->display, bm, bmask,
846 &win->cursorcolor,
847 &WhitePixel(win->display, 0),
848 xchess_x_hot, xchess_y_hot);
849 XFreePixmap(win->display, bm);
850 XFreePixmap(win->display, bmask);
851
852 XDefineCursor(win->display,win->basewin, cur);
853
854 XMapSubwindows(win->display,win->basewin);
855 XMapRaised(win->display,win->basewin);
856
857 XSelectInput(win->display,win->basewin, KeyPressMask);
858 XSelectInput(win->display,win->boardwin,
859 ButtonPressMask | ButtonReleaseMask | ExposureMask);
860 XSelectInput(win->display,win->recwin,
861 ButtonReleaseMask | ExposureMask);
862 XSelectInput(win->display,win->jailwin, ExposureMask);
863 XSelectInput(win->display,win->wclockwin, ExposureMask);
864 XSelectInput(win->display,win->bclockwin, ExposureMask);
865 XSelectInput(win->display,win->messagewin,
866 ButtonReleaseMask | ExposureMask);
867 XSelectInput(win->display,win->buttonwin,
868 ButtonPressMask | ExposureMask);
869
870 message_init(win);
871 record_init(win);
872 button_draw(win);
873 jail_init(win);
874 clock_init(win, WHITE);
875 clock_init(win, BLACK);
876 if (timeunit) {
877 if (timeunit > 1800)
878 sprintf(buf, "%d moves every %.2lg hours.\n",
879 movesperunit, ((double) timeunit) / 3600);
880 else if (timeunit > 30)
881 sprintf(buf, "%d moves every %.2lg minutes.\n",
882 movesperunit, ((double) timeunit) / 60);
883 else
884 sprintf(buf, "%d moves every %d seconds.\n",
885 movesperunit, timeunit);
886 message_add(win, buf, false);
887 }
888 return (true);
889 }
890
891 static void
drawgrid(win)892 drawgrid(win)
893 windata *win;
894 {
895 int i;
896 XGCValues gc;
897
898 gc.function = GXcopy;
899 gc.plane_mask = AllPlanes;
900 gc.foreground = win->border.pixel;
901 gc.line_width = 0;
902 gc.line_style = LineSolid;
903
904 XChangeGC(win->display,
905 DefaultGC(win->display, 0),
906 GCFunction | GCPlaneMask | GCForeground |
907 GCLineWidth | GCLineStyle, &gc);
908
909 /* Draw the lines... horizontal, */
910 for (i = 1; i < SIZE; i++)
911 XDrawLine(win->display, win->boardwin,
912 DefaultGC(win->display, 0), 0,
913 i * (SQUARE_WIDTH + BORDER_WIDTH) -
914 BORDER_WIDTH / 2,
915 SIZE * (SQUARE_WIDTH + BORDER_WIDTH),
916 i * (SQUARE_WIDTH + BORDER_WIDTH) -
917 BORDER_WIDTH / 2);
918
919 /* and vertical... */
920 for (i = 1; i < SIZE; i++)
921 XDrawLine(win->display, win->boardwin,
922 DefaultGC(win->display, 0),
923 i * (SQUARE_WIDTH + BORDER_WIDTH) -
924 BORDER_WIDTH / 2, 0,
925 i * (SQUARE_WIDTH + BORDER_WIDTH) -
926 BORDER_WIDTH / 2,
927 SIZE * (SQUARE_WIDTH + BORDER_WIDTH));
928 return;
929 }
930
931 void
win_restart()932 win_restart()
933 {
934 win1->flipped = false;
935 win_redraw(win1, (XEvent *) NULL);
936 if (!oneboard) {
937 win2->flipped = true;
938 win_redraw(win2, (XEvent *) NULL);
939 }
940 return;
941 }
942
943 static void
icon_refresh(win)944 icon_refresh(win)
945 windata *win;
946 {
947 XCopyArea(win->display, win->iconpixmap, win->icon,
948 DefaultGC(win->display, 0),
949 0, 0, icon_width, icon_height, 0, 0);
950 return;
951 }
952
953