Start development on 386BSD 0.0
[unix-history] / .ref-BSD-4_3_Net_2 / usr / src / games / chess / Xchess / window.c
CommitLineData
cb290b32
C
1/* This file contains code for X-CHESS.
2 Copyright (C) 1986 Free Software Foundation, Inc.
3
4This file is part of X-CHESS.
5
6X-CHESS is distributed in the hope that it will be useful,
7but WITHOUT ANY WARRANTY. No author or distributor
8accepts responsibility to anyone for the consequences of using it
9or for whether it serves any particular purpose or works at all,
10unless he says so in writing. Refer to the X-CHESS General Public
11License for full details.
12
13Everyone is granted permission to copy, modify and redistribute
14X-CHESS, but only under the conditions described in the
15X-CHESS General Public License. A copy of this license is
16supposed to have been given to you along with X-CHESS so you
17can know your rights and responsibilities. It should be in a
18file named COPYING. Among other things, the copyright notice
19and 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
63windata *win1, *win2;
64bool win_flashmove = false;
65
66extern bool setup();
67extern void service(), drawgrid(), icon_refresh();
68
69bool
70win_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
98void
99win_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
116void
117win_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
295void
296win_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
383void
384win_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
427void
428win_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
462static void
463service(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
564void
565win_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
620static bool
621setup(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
891static void
892drawgrid(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
931void
932win_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
943static void
944icon_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