window.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743
  1. /* This file contains code for X-CHESS.
  2. Copyright (C) 1986 Free Software Foundation, Inc.
  3. This file is part of X-CHESS.
  4. X-CHESS is distributed in the hope that it will be useful,
  5. but WITHOUT ANY WARRANTY. No author or distributor
  6. accepts responsibility to anyone for the consequences of using it
  7. or for whether it serves any particular purpose or works at all,
  8. unless he says so in writing. Refer to the X-CHESS General Public
  9. License for full details.
  10. Everyone is granted permission to copy, modify and redistribute
  11. X-CHESS, but only under the conditions described in the
  12. X-CHESS General Public License. A copy of this license is
  13. supposed to have been given to you along with X-CHESS so you
  14. can know your rights and responsibilities. It should be in a
  15. file named COPYING. Among other things, the copyright notice
  16. and this notice must be preserved on all copies. */
  17. /* RCS Info: $Revision: 1.5 $ on $Date: 86/11/26 12:11:15 $
  18. * $Source: /users/faustus/xchess/RCS/window.c,v $
  19. * Copyright (c) 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
  20. * Permission is granted to do anything with this code except sell it
  21. * or remove this message.
  22. *
  23. * Deal with the two (or one) windows.
  24. */
  25. #include "xchess.h"
  26. #include <sys/time.h>
  27. #include "pawn.bitmap"
  28. #include "rook.bitmap"
  29. #include "knight.bitmap"
  30. #include "bishop.bitmap"
  31. #include "queen.bitmap"
  32. #include "king.bitmap"
  33. #include "pawn_outline.bitmap"
  34. #include "rook_outline.bitmap"
  35. #include "knight_outline.bitmap"
  36. #include "bishop_outline.bitmap"
  37. #include "queen_outline.bitmap"
  38. #include "king_outline.bitmap"
  39. #include "pawn_mask.bitmap"
  40. #include "rook_mask.bitmap"
  41. #include "knight_mask.bitmap"
  42. #include "bishop_mask.bitmap"
  43. #include "queen_mask.bitmap"
  44. #include "king_mask.bitmap"
  45. #include "shade.bitmap"
  46. #include "xchess.cur"
  47. #include "xchess_mask.cur"
  48. #include "xchess.icon"
  49. windata *win1, *win2;
  50. bool win_flashmove = false;
  51. extern bool setup();
  52. extern void service(), drawgrid(), icon_refresh();
  53. bool
  54. win_setup(disp1, disp2)
  55. char *disp1, *disp2;
  56. {
  57. win1 = alloc(windata);
  58. if (!oneboard)
  59. win2 = alloc(windata);
  60. if (!setup(disp1, win1) || (!oneboard && !setup(disp2, win2)))
  61. return (false);
  62. if (blackflag) {
  63. win1->color = BLACK;
  64. win1->flipped = true;
  65. } else
  66. win1->color = WHITE;
  67. win_drawboard(win1);
  68. if (!oneboard) {
  69. win2->color = BLACK;
  70. win2->flipped = true;
  71. win_drawboard(win2);
  72. }
  73. return(true);
  74. }
  75. /* Draw the chess board... */
  76. void
  77. win_drawboard(win)
  78. windata *win;
  79. {
  80. int i, j;
  81. XSetDisplay(win->display);
  82. drawgrid(win);
  83. /* Now toss on the squares... */
  84. for (i = 0; i < SIZE; i++)
  85. for (j = 0; j < SIZE; j++)
  86. win_erasepiece(j, i, win->color);
  87. return;
  88. }
  89. /* Draw one piece. */
  90. void
  91. win_drawpiece(p, y, x, wnum)
  92. piece *p;
  93. int y, x;
  94. color wnum;
  95. {
  96. short *bits, *maskbits, *outline;
  97. windata *win;
  98. Bitmap mask;
  99. char buf[BSIZE];
  100. if (oneboard || (wnum == win1->color))
  101. win = win1;
  102. else
  103. win = win2;
  104. XSetDisplay(win->display);
  105. if (win->flipped) {
  106. y = SIZE - y - 1;
  107. x = SIZE - x - 1;
  108. }
  109. /*
  110. if (debug)
  111. fprintf(stderr, "draw a %s at (%d, %d) on board %d\n",
  112. piecenames[(int) p->type], y, x, wnum);
  113. */
  114. if ((x < 0) || (x > 7) || (y < 0) || (y > 7)) exit(1);
  115. switch (p->type) {
  116. case PAWN:
  117. bits = pawn_bits;
  118. maskbits = pawn_mask_bits;
  119. outline = pawn_outline_bits;
  120. break;
  121. case ROOK:
  122. bits = rook_bits;
  123. maskbits = rook_mask_bits;
  124. outline = rook_outline_bits;
  125. break;
  126. case KNIGHT:
  127. bits = knight_bits;
  128. maskbits = knight_mask_bits;
  129. outline = knight_outline_bits;
  130. break;
  131. case BISHOP:
  132. bits = bishop_bits;
  133. maskbits = bishop_mask_bits;
  134. outline = bishop_outline_bits;
  135. break;
  136. case QUEEN:
  137. bits = queen_bits;
  138. maskbits = queen_mask_bits;
  139. outline = queen_outline_bits;
  140. break;
  141. case KING:
  142. bits = king_bits;
  143. maskbits = king_mask_bits;
  144. outline = king_outline_bits;
  145. break;
  146. default:
  147. fprintf(stderr,
  148. "Internal Error: win_drawpiece: bad piece type %d\n",
  149. p->type);
  150. }
  151. /* There are two things we can do... If this is a black and white
  152. * display, we have to shade the square and use an outline if the piece
  153. * is white. We also have to use a mask... Since we don't want
  154. * to use up too many bitmaps, create the mask bitmap, put the bits,
  155. * and then destroy it.
  156. */
  157. if (win->bnw && (p->color == WHITE))
  158. bits = outline;
  159. if (win->bnw && !iswhite(win, x, y)) {
  160. XBitmapBitsPut(win->boardwin, x * (SQUARE_WIDTH + BORDER_WIDTH),
  161. y * (SQUARE_HEIGHT + BORDER_WIDTH), SQUARE_WIDTH,
  162. SQUARE_HEIGHT, shade_bits, BlackPixel, WhitePixel,
  163. 0, GXcopy, AllPlanes);
  164. mask = XStoreBitmap(SQUARE_WIDTH, SQUARE_HEIGHT, maskbits);
  165. XBitmapBitsPut(win->boardwin, x * (SQUARE_WIDTH + BORDER_WIDTH),
  166. y * (SQUARE_HEIGHT + BORDER_WIDTH), SQUARE_WIDTH,
  167. SQUARE_HEIGHT, bits, BlackPixel, WhitePixel,
  168. mask, GXcopy, AllPlanes);
  169. XFreeBitmap(mask);
  170. } else if (win->bnw){
  171. XBitmapBitsPut(win->boardwin, x * (SQUARE_WIDTH + BORDER_WIDTH),
  172. y * (SQUARE_HEIGHT + BORDER_WIDTH), SQUARE_WIDTH,
  173. SQUARE_HEIGHT, bits, BlackPixel, WhitePixel,
  174. 0, GXcopy, AllPlanes);
  175. } else {
  176. XBitmapBitsPut(win->boardwin, x * (SQUARE_WIDTH + BORDER_WIDTH),
  177. y * (SQUARE_HEIGHT + BORDER_WIDTH), SQUARE_WIDTH,
  178. SQUARE_HEIGHT, bits, ((p->color == WHITE) ?
  179. win->whitepiece.pixel : win->blackpiece.pixel),
  180. (iswhite(win, x, y) ? win->whitesquare.pixel :
  181. win->blacksquare.pixel), 0, GXcopy, AllPlanes);
  182. }
  183. if (!record_english) {
  184. if (!x) {
  185. sprintf(buf, " %d", SIZE - y);
  186. XText(win->boardwin, 1, (y + 1) * (SQUARE_HEIGHT +
  187. BORDER_WIDTH) - BORDER_WIDTH -
  188. win->small->height - 1, buf, 2,
  189. win->small->id, win->textcolor.pixel,
  190. ((iswhite(win, x, y) || win->bnw) ?
  191. win->whitesquare.pixel :
  192. win->blacksquare.pixel));
  193. }
  194. if (y == SIZE - 1) {
  195. sprintf(buf, "%c", 'A' + x);
  196. XText(win->boardwin, x * (SQUARE_WIDTH + BORDER_WIDTH)
  197. + 1, SIZE * (SQUARE_HEIGHT +
  198. BORDER_WIDTH) - BORDER_WIDTH -
  199. win->small->height - 1, buf, 1,
  200. win->small->id, win->textcolor.pixel,
  201. ((iswhite(win, x, y) || win->bnw) ?
  202. win->whitesquare.pixel :
  203. win->blacksquare.pixel));
  204. }
  205. }
  206. return;
  207. }
  208. void
  209. win_erasepiece(y, x, wnum)
  210. int y, x;
  211. color wnum;
  212. {
  213. windata *win;
  214. char buf[BSIZE];
  215. if (oneboard || (wnum == win1->color))
  216. win = win1;
  217. else
  218. win = win2;
  219. XSetDisplay(win->display);
  220. if (win->flipped) {
  221. y = SIZE - y - 1;
  222. x = SIZE - x - 1;
  223. }
  224. /*
  225. if (debug)
  226. fprintf(stderr, "erase square (%d, %d) on board %d\n", y, x,
  227. wnum);
  228. */
  229. if ((x < 0) || (x > 7) || (y < 0) || (y > 7)) exit(1);
  230. if (win->bnw && !iswhite(win, x, y)) {
  231. XBitmapBitsPut(win->boardwin, x * (SQUARE_WIDTH + BORDER_WIDTH),
  232. y * (SQUARE_HEIGHT + BORDER_WIDTH), SQUARE_WIDTH,
  233. SQUARE_HEIGHT, shade_bits, BlackPixel, WhitePixel,
  234. 0, GXcopy, AllPlanes);
  235. } else {
  236. XPixSet(win->boardwin, x * (SQUARE_WIDTH + BORDER_WIDTH),
  237. y * (SQUARE_HEIGHT + BORDER_WIDTH),
  238. SQUARE_WIDTH, SQUARE_HEIGHT, iswhite(win, x, y)
  239. ? win->whitesquare.pixel :
  240. win->blacksquare.pixel);
  241. }
  242. if (!record_english) {
  243. if (!x) {
  244. sprintf(buf, " %d", SIZE - y);
  245. XText(win->boardwin, 1, (y + 1) * (SQUARE_HEIGHT +
  246. BORDER_WIDTH) - BORDER_WIDTH -
  247. win->small->height - 1, buf, 2,
  248. win->small->id, win->textcolor.pixel,
  249. ((iswhite(win, x, y) || win->bnw) ?
  250. win->whitesquare.pixel :
  251. win->blacksquare.pixel));
  252. }
  253. if (y == SIZE - 1) {
  254. sprintf(buf, "%c", 'A' + x);
  255. XText(win->boardwin, x * (SQUARE_WIDTH + BORDER_WIDTH)
  256. + 1, SIZE * (SQUARE_HEIGHT +
  257. BORDER_WIDTH) - BORDER_WIDTH -
  258. win->small->height - 1, buf, 1,
  259. win->small->id, win->textcolor.pixel,
  260. ((iswhite(win, x, y) || win->bnw) ?
  261. win->whitesquare.pixel :
  262. win->blacksquare.pixel));
  263. }
  264. }
  265. return;
  266. }
  267. void
  268. win_flash(m, wnum)
  269. move *m;
  270. color wnum;
  271. {
  272. windata *win;
  273. int sx, sy, ex, ey, i;
  274. if (oneboard || (wnum == win1->color))
  275. win = win1;
  276. else
  277. win = win2;
  278. XSetDisplay(win->display);
  279. if (win->flipped) {
  280. sx = SIZE - m->fromx - 1;
  281. sy = SIZE - m->fromy - 1;
  282. ex = SIZE - m->tox - 1;
  283. ey = SIZE - m->toy - 1;
  284. } else {
  285. sx = m->fromx;
  286. sy = m->fromy;
  287. ex = m->tox;
  288. ey = m->toy;
  289. }
  290. sx = sx * (SQUARE_WIDTH + BORDER_WIDTH) + SQUARE_WIDTH / 2;
  291. sy = sy * (SQUARE_HEIGHT + BORDER_WIDTH) + SQUARE_HEIGHT / 2;
  292. ex = ex * (SQUARE_WIDTH + BORDER_WIDTH) + SQUARE_WIDTH / 2;
  293. ey = ey * (SQUARE_HEIGHT + BORDER_WIDTH) + SQUARE_HEIGHT / 2;
  294. for (i = 0; i < num_flashes * 2; i++)
  295. XLine(win->boardwin, sx, sy, ex, ey, flash_size, flash_size,
  296. BlackPixel, GXinvert, AllPlanes);
  297. return;
  298. }
  299. /* Handle input from the players. */
  300. void
  301. win_process(quick)
  302. bool quick;
  303. {
  304. int i, rfd = 0, wfd = 0, xfd = 0;
  305. struct timeval timeout;
  306. timeout.tv_sec = 0;
  307. timeout.tv_usec = (quick ? 0 : 500000);
  308. XSetDisplay(win1->display);
  309. if (XPending())
  310. service(win1);
  311. if (!oneboard) {
  312. XSetDisplay(win2->display);
  313. if (XPending())
  314. service(win2);
  315. }
  316. if (oneboard)
  317. rfd = 1 << win1->display->fd;
  318. else
  319. rfd = (1 << win1->display->fd) | (1 << win2->display->fd);
  320. if (!(i = select(32, &rfd, &wfd, &xfd, &timeout)))
  321. return;
  322. if (i == -1) {
  323. perror("select");
  324. exit(1);
  325. }
  326. if (rfd & (1 << win1->display->fd))
  327. service(win1);
  328. if (!oneboard && (rfd & (1 << win2->display->fd)))
  329. service(win2);
  330. return;
  331. }
  332. static void
  333. service(win)
  334. windata *win;
  335. {
  336. XEvent ev;
  337. XSetDisplay(win->display);
  338. while(XPending()) {
  339. XNextEvent(&ev);
  340. if (TxtFilter(&ev))
  341. continue;
  342. if (ev.window == win->boardwin) {
  343. switch (ev.type) {
  344. case ButtonPressed:
  345. button_pressed(&ev, win);
  346. break;
  347. case ButtonReleased:
  348. button_released(&ev, win);
  349. break;
  350. case ExposeRegion:
  351. case ExposeWindow:
  352. /* Redraw... */
  353. win_redraw(win, &ev);
  354. break;
  355. case 0:
  356. break;
  357. default:
  358. fprintf(stderr, "Bad event type %d\n", ev.type);
  359. exit(1);
  360. }
  361. } else if (ev.window == win->wclockwin) {
  362. switch (ev.type) {
  363. case ExposeRegion:
  364. case ExposeWindow:
  365. clock_draw(win, WHITE);
  366. break;
  367. case 0:
  368. break;
  369. default:
  370. fprintf(stderr, "Bad event type %d\n", ev.type);
  371. exit(1);
  372. }
  373. } else if (ev.window == win->bclockwin) {
  374. switch (ev.type) {
  375. case ExposeRegion:
  376. case ExposeWindow:
  377. clock_draw(win, BLACK);
  378. break;
  379. case 0:
  380. break;
  381. default:
  382. fprintf(stderr, "Bad event type %d\n", ev.type);
  383. exit(1);
  384. }
  385. } else if (ev.window == win->jailwin) {
  386. switch (ev.type) {
  387. case ExposeRegion:
  388. case ExposeWindow:
  389. jail_draw(win);
  390. break;
  391. case 0:
  392. break;
  393. default:
  394. fprintf(stderr, "Bad event type %d\n", ev.type);
  395. exit(1);
  396. }
  397. } else if (ev.window == win->buttonwin) {
  398. switch (ev.type) {
  399. case ButtonPressed:
  400. button_service(win, &ev);
  401. break;
  402. case ExposeRegion:
  403. case ExposeWindow:
  404. button_draw(win, &ev);
  405. break;
  406. case 0:
  407. break;
  408. default:
  409. fprintf(stderr, "Bad event type %d\n", ev.type);
  410. exit(1);
  411. }
  412. } else if (ev.window == win->icon) {
  413. icon_refresh(win);
  414. } else if (ev.window == win->basewin) {
  415. message_send(win, &ev);
  416. } else {
  417. fprintf(stderr, "Internal Error: service: bad win\n");
  418. fprintf(stderr, "window = %d, event = %d\n", ev.window,
  419. ev.type);
  420. }
  421. }
  422. return;
  423. }
  424. void
  425. win_redraw(win, event)
  426. windata *win;
  427. XEvent *event;
  428. {
  429. XExposeEvent *ev = (XExposeEvent *) event;
  430. int x1, y1, x2, y2, i, j;
  431. drawgrid(win);
  432. if (ev) {
  433. x1 = ev->x / (SQUARE_WIDTH + BORDER_WIDTH);
  434. y1 = ev->y / (SQUARE_HEIGHT + BORDER_WIDTH);
  435. x2 = (ev->x + ev->width) / (SQUARE_WIDTH + BORDER_WIDTH);
  436. y2 = (ev->y + ev->height) / (SQUARE_HEIGHT + BORDER_WIDTH);
  437. } else {
  438. x1 = 0;
  439. y1 = 0;
  440. x2 = SIZE - 1;
  441. y2 = SIZE - 1;
  442. }
  443. if (x1 < 0) x1 = 0;
  444. if (y1 < 0) y1 = 0;
  445. if (x2 < 0) x2 = 0;
  446. if (y2 < 0) y2 = 0;
  447. if (x1 > SIZE - 1) x1 = SIZE - 1;
  448. if (y1 > SIZE - 1) y1 = SIZE - 1;
  449. if (x2 > SIZE - 1) x2 = SIZE - 1;
  450. if (y2 > SIZE - 1) y2 = SIZE - 1;
  451. if (win->flipped) {
  452. y1 = SIZE - y2 - 1;
  453. y2 = SIZE - y1 - 1;
  454. x1 = SIZE - x2 - 1;
  455. x2 = SIZE - x1 - 1;
  456. }
  457. for (i = x1; i <= x2; i++)
  458. for (j = y1; j <= y2; j++) {
  459. if (chessboard->square[j][i].color == NONE)
  460. win_erasepiece(j, i, WHITE);
  461. else
  462. win_drawpiece(&chessboard->square[j][i], j, i,
  463. WHITE);
  464. if (!oneboard) {
  465. if (chessboard->square[j][i].color == NONE)
  466. win_erasepiece(j, i, BLACK);
  467. else
  468. win_drawpiece(&chessboard->square[j][i],
  469. j, i, BLACK);
  470. }
  471. }
  472. return;
  473. }
  474. static bool
  475. setup(dispname, win)
  476. char *dispname;
  477. windata *win;
  478. {
  479. Pixmap btile, ttile;
  480. char buf[BSIZE];
  481. Bitmap bm;
  482. Cursor cur;
  483. if (!(win->display = XOpenDisplay(dispname)))
  484. return (false);
  485. if ((DisplayPlanes() == 1) || bnwflag)
  486. win->bnw = true;
  487. /* Allocate colors... */
  488. if (win->bnw) {
  489. win->blackpiece.pixel = BlackPixel;
  490. win->whitepiece.pixel = WhitePixel;
  491. win->blacksquare.pixel = BlackPixel;
  492. win->whitesquare.pixel = WhitePixel;
  493. win->border.pixel = BlackPixel;
  494. win->textcolor.pixel = BlackPixel;
  495. win->textback.pixel = WhitePixel;
  496. win->playertext.pixel = BlackPixel;
  497. win->errortext.pixel = BlackPixel;
  498. win->cursorcolor.pixel = BlackPixel;
  499. } else {
  500. if (!XParseColor(black_piece_color, &win->blackpiece) ||
  501. !XParseColor(white_piece_color, &win->whitepiece) ||
  502. !XParseColor(black_square_color, &win->blacksquare) ||
  503. !XParseColor(white_square_color, &win->whitesquare) ||
  504. !XParseColor(border_color, &win->border) ||
  505. !XParseColor(text_color, &win->textcolor) ||
  506. !XParseColor(text_back, &win->textback) ||
  507. !XParseColor(error_text, &win->errortext) ||
  508. !XParseColor(player_text, &win->playertext) ||
  509. !XParseColor(cursor_color, &win->cursorcolor) ||
  510. !XGetHardwareColor(&win->blackpiece) ||
  511. !XGetHardwareColor(&win->whitepiece) ||
  512. !XGetHardwareColor(&win->blacksquare) ||
  513. !XGetHardwareColor(&win->whitesquare) ||
  514. !XGetHardwareColor(&win->border) ||
  515. !XGetHardwareColor(&win->textcolor) ||
  516. !XGetHardwareColor(&win->textback) ||
  517. !XGetHardwareColor(&win->errortext) ||
  518. !XGetHardwareColor(&win->playertext) ||
  519. !XGetHardwareColor(&win->cursorcolor))
  520. fprintf(stderr, "Can't get color...\n");
  521. }
  522. /* Get fonts... */
  523. win->small = XOpenFont(SMALL_FONT);
  524. win->medium = XOpenFont(MEDIUM_FONT);
  525. win->large = XOpenFont(LARGE_FONT);
  526. /* Create the windows... */
  527. btile = XMakeTile(win->border.pixel);
  528. ttile = XMakeTile(win->textback.pixel);
  529. win->basewin = XCreateWindow(RootWindow, BASE_XPOS, BASE_YPOS,
  530. BASE_WIDTH, BASE_HEIGHT, 0, WhitePixmap, WhitePixmap);
  531. win->boardwin = XCreateWindow(win->basewin, BOARD_XPOS, BOARD_YPOS,
  532. BOARD_WIDTH, BOARD_HEIGHT, BORDER_WIDTH, btile,
  533. WhitePixmap);
  534. win->recwin = XCreateWindow(win->basewin, RECORD_XPOS, RECORD_YPOS,
  535. RECORD_WIDTH, RECORD_HEIGHT, BORDER_WIDTH,
  536. btile, ttile);
  537. win->jailwin = XCreateWindow(win->basewin, JAIL_XPOS, JAIL_YPOS,
  538. JAIL_WIDTH, JAIL_HEIGHT, BORDER_WIDTH,
  539. btile, ttile);
  540. win->wclockwin = XCreateWindow(win->basewin, WCLOCK_XPOS, WCLOCK_YPOS,
  541. CLOCK_WIDTH, CLOCK_HEIGHT, BORDER_WIDTH, btile,
  542. ttile);
  543. win->bclockwin = XCreateWindow(win->basewin, BCLOCK_XPOS, BCLOCK_YPOS,
  544. CLOCK_WIDTH, CLOCK_HEIGHT, BORDER_WIDTH, btile,
  545. ttile);
  546. win->messagewin = XCreateWindow(win->basewin, MESS_XPOS, MESS_YPOS,
  547. MESS_WIDTH, MESS_HEIGHT, BORDER_WIDTH, btile, ttile);
  548. win->buttonwin = XCreateWindow(win->basewin, BUTTON_XPOS, BUTTON_YPOS,
  549. BUTTON_WIDTH, BUTTON_HEIGHT, BORDER_WIDTH, btile,
  550. ttile);
  551. /* Let's define an icon... */
  552. bm = XStoreBitmap(icon_width, icon_height, icon_bits);
  553. win->iconpixmap = XMakePixmap(bm, win->blacksquare.pixel,
  554. win->whitesquare.pixel);
  555. win->icon = XCreateWindow(RootWindow, BASE_XPOS, BASE_YPOS, icon_width,
  556. icon_height, 2, btile, WhitePixmap);
  557. XSetIconWindow(win->basewin, win->icon);
  558. XSelectInput(win->icon, ExposeRegion);
  559. cur = XCreateCursor(xchess_width, xchess_height, xchess_bits,
  560. xchess_mask_bits, xchess_x_hot, xchess_y_hot,
  561. win->cursorcolor.pixel, WhitePixel, GXcopy);
  562. XDefineCursor(win->basewin, cur);
  563. XMapWindow(win->basewin);
  564. XMapSubwindows(win->basewin);
  565. XSelectInput(win->basewin, KeyPressed);
  566. XSelectInput(win->boardwin, ButtonPressed | ButtonReleased |
  567. ExposeRegion | ExposeWindow);
  568. XSelectInput(win->recwin, ButtonReleased | ExposeRegion |
  569. ExposeWindow | ExposeCopy);
  570. XSelectInput(win->jailwin, ExposeRegion | ExposeWindow);
  571. XSelectInput(win->wclockwin, ExposeRegion | ExposeWindow);
  572. XSelectInput(win->bclockwin, ExposeRegion | ExposeWindow);
  573. XSelectInput(win->messagewin, ButtonReleased | ExposeRegion |
  574. ExposeWindow | ExposeCopy);
  575. XSelectInput(win->buttonwin, ButtonPressed | ExposeRegion |
  576. ExposeWindow);
  577. message_init(win);
  578. record_init(win);
  579. button_draw(win);
  580. jail_init(win);
  581. clock_init(win, WHITE);
  582. clock_init(win, BLACK);
  583. if (timeunit) {
  584. if (timeunit > 1800)
  585. sprintf(buf, "%d moves every %.2lg hours.\n",
  586. movesperunit, ((double) timeunit) / 3600);
  587. else if (timeunit > 30)
  588. sprintf(buf, "%d moves every %.2lg minutes.\n",
  589. movesperunit, ((double) timeunit) / 60);
  590. else
  591. sprintf(buf, "%d moves every %d seconds.\n",
  592. movesperunit, timeunit);
  593. message_add(win, buf, false);
  594. }
  595. XFreePixmap(btile);
  596. XFreePixmap(ttile);
  597. return (true);
  598. }
  599. static void
  600. drawgrid(win)
  601. windata *win;
  602. {
  603. int i;
  604. XSetDisplay(win->display);
  605. /* Draw the lines... horizontal, */
  606. for (i = 1; i < SIZE; i++)
  607. XLine(win->boardwin, 0, i * (SQUARE_WIDTH + BORDER_WIDTH) -
  608. (BORDER_WIDTH + 1) / 2 - 1, SIZE *
  609. (SQUARE_WIDTH + BORDER_WIDTH),
  610. i * (SQUARE_WIDTH +
  611. BORDER_WIDTH) - (BORDER_WIDTH + 1) / 2 - 1,
  612. BORDER_WIDTH, BORDER_WIDTH, win->border.pixel,
  613. GXcopy, AllPlanes);
  614. /* and vertical... */
  615. for (i = 1; i < SIZE; i++)
  616. XLine(win->boardwin, i * (SQUARE_WIDTH + BORDER_WIDTH) -
  617. (BORDER_WIDTH + 1) / 2 - 1, 0,
  618. i * (SQUARE_WIDTH +
  619. BORDER_WIDTH) - (BORDER_WIDTH + 1) / 2 - 1,
  620. SIZE * (SQUARE_WIDTH + BORDER_WIDTH),
  621. BORDER_WIDTH, BORDER_WIDTH, win->border.pixel,
  622. GXcopy, AllPlanes);
  623. return;
  624. }
  625. void
  626. win_restart()
  627. {
  628. win1->flipped = false;
  629. win_redraw(win1, (XEvent *) NULL);
  630. if (!oneboard) {
  631. win2->flipped = true;
  632. win_redraw(win2, (XEvent *) NULL);
  633. }
  634. return;
  635. }
  636. static void
  637. icon_refresh(win)
  638. windata *win;
  639. {
  640. XPixmapPut(win->icon, 0, 0, 0, 0, icon_width, icon_height,
  641. win->iconpixmap, GXcopy, AllPlanes);
  642. return;
  643. }