/* status.c status lines, game clock */ /* * xcheckers: a point and click checkerboard * (C): 1999, 2000 Peter Chiocchetti */ #include #include #include #include #include #include "xcheckers.h" #include "board.h" #include "status.h" #define sgutter (XTextWidth (font, "n", 1)) #define sline(i) ((font->ascent + font->descent) * (i + 1)) #define STATUSMASK (ExposureMask) Pixmap spix; /* holds a picture of the satusline */ GC bgc; /* foreground and background reversed */ /* draw the status lines */ static void drawStatus(void) { int tmp; XFillRectangle(dpy, spix, bgc, 0, 0, board_width, status_height); XDrawLine(dpy, spix, gc, 0, 0, board_width, 0); /* player names */ XDrawString(dpy, spix, gc, sgutter, sline(0), &statusline[0][0], strlen(&statusline[0][0])); XDrawString(dpy, spix, gc, sgutter, sline(1), &statusline[1][0], strlen(&statusline[1][0])); /* player clocks */ tmp = board_width - XTextWidth(font, &clockline[0][0], strlen(&clockline[0][0])) - sgutter; XDrawString(dpy, spix, gc, tmp, sline(0), &clockline[0][0], strlen(&clockline[0][0])); tmp = board_width - XTextWidth(font, &clockline[1][0], strlen(&clockline[1][0])) - sgutter; XDrawString(dpy, spix, gc, tmp, sline(1), &clockline[1][0], strlen(&clockline[1][0])); } /* prepare the status window */ void initStatus(unsigned long paper, unsigned long pen, char *myname) { swin = XCreateSimpleWindow(dpy, win, 0, board_height, board_width, status_height, 0, pen, paper); spix = XCreatePixmap(dpy, swin, board_width, status_height, DefaultDepth(dpy, screen)); bgc = XCreateGC(dpy, swin, 0, NULL); XSetForeground(dpy, bgc, paper); XSetBackground(dpy, bgc, pen); XSelectInput(dpy, swin, STATUSMASK); /* set clock to be invisible first */ currClock = 0; currTime = time(NULL); clockline[0][0] = '\0'; clockline[1][0] = '\0'; snprintf(&statusline[0][0], 30, "Welcome %s!", myname); drawStatus(); XMapWindow(dpy, swin); } /* handle exposures */ void paintStatus(XExposeEvent * e) { XCopyArea(dpy, spix, swin, gc, e->x, e->y, e->width, e->height, e->x, e->y); } /* display status in window after engine move */ void showStatus(void) { drawStatus(); XCopyArea(dpy, spix, swin, gc, 0, 0, board_width, status_height, 0, 0); XFlush(dpy); } /* resize status window to fit board */ void resizeStatus(void) { XMoveWindow(dpy,swin,0,board_height); XResizeWindow(dpy, swin, board_width, status_height); XFreePixmap(dpy, spix); spix = XCreatePixmap(dpy, swin, board_width, status_height, DefaultDepth(dpy, screen)); drawStatus(); } /* redraw the clock, i.e. the status line */ void freshenClock(void) { /* could be smarter */ showStatus(); } /* update game clock display */ void checkClock(void) { time_t dummy; if ((clockline[currPlayer][0] != '\0') && (currTime != (dummy = time(NULL)))) { currClock -= dummy - currTime; currTime = dummy; // stop at +/- 9:59 if (currClock / 60 >= 10) return; if (currClock / 60 <= -10) return; if (currClock < 0) sprintf(&clockline[currPlayer][0], "-%d : %02d", abs((int) (currClock / 60)), abs((int) (currClock % 60))); else sprintf(&clockline[currPlayer][0], " %d : %02d", abs((int) (currClock / 60)), abs((int) (currClock % 60))); freshenClock(); } }