home *** CD-ROM | disk | FTP | other *** search
- /*
- * x11.c
- * kirk johnson
- * october 1990
- */
-
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
- #include <X11/cursorfont.h>
- #include "mosaic.h"
- #include "x11.h"
- #include "patchlevel.h"
-
- #define BufSize (256)
-
- #define BoundVarVal(var, min, max) \
- { \
- if ((var) < (min)) \
- (var) = (min); \
- else if ((var) > (max)) \
- (var) = (max); \
- }
-
- typedef unsigned long Pixel;
- typedef XFontStruct XFS;
-
- static void GetDisplayName();
- static void GetResourceOptions();
- static int IsTrue();
- static char *strdup();
- static void GetCmdLineOptions();
- static void Help();
- static void doKey();
- static void doMotion();
- static void doBoardExpose();
- static void doHelpExpose();
- static void doNextExpose();
- static void doMainExpose();
- static void doHighExpose();
- static void doButtonPress();
- static Pixel GetColor();
- static Window GetWindow();
- static Pixmap MakePixmap();
- static void SetCursor();
- static void TopWindowStuff();
- static void AddEventHandler();
- static void (*GetEventHandler())();
-
- static char buf[BufSize];
- static char *TileBits[4];
-
- static char *dpyname; /* display name */
- static int mono; /* mono mode flag */
- static int solid; /* solid mode flag */
- static int expert; /* expert mode flag */
- static int gwidth; /* gutter width */
- static int bwidth; /* border width */
- static char *fgname; /* fg color name */
- static char *bgname; /* bg color name */
- static char *bdname; /* border color name */
- static char *cname[4]; /* tile color names */
- static char *fntname; /* font name */
-
- static Display *dpy; /* display connection */
- static int scrn; /* screen number */
- static Window root; /* root window */
- static Visual *visl; /* visual */
- static Colormap cmap; /* colormap */
- static int dpth; /* display depth */
- static GC gc; /* graphics context */
-
- static Pixel fore; /* foreground color */
- static Pixel back; /* background color */
- static Pixel brdr; /* border color */
- static Pixel tilec[4]; /* tile colors */
- static Pixmap tilep[4]; /* tile pixmaps */
- static XFS *font; /* text font */
-
- static Window mainw; /* main window */
- static Window boardw; /* board window */
- static Window helpw; /* help window */
- static Window nextw; /* next piece window */
- static Window scoresw; /* high scores window */
-
- static int crow = 0; /* controller position */
- static int ccol = 0;
-
- static int scoresvis; /* high scores visible? */
- static int helpvis; /* help window visible? */
-
- static int swidth; /* width of score text area */
- static int hswidth; /* width of high score window */
-
-
- void InitDisplay(argc, argv)
- int argc;
- char **argv;
- {
- int i;
- int w, h;
- int x, y;
-
- /* set standard defaults */
- dpyname = NULL; /* default to DISPLAY */
- expert = False; /* default to novice mode */
- mono = False; /* default to color (if possible) */
- solid = False; /* default to patterned tiles */
- gwidth = DfltGutterWidth; /* gutter width */
- bwidth = DfltBorderWidth; /* border width */
- fgname = DfltForeName; /* foreground color name */
- bgname = DfltBackName; /* background color name */
- bdname = DfltBrdrName; /* border color name */
- cname[0] = DfltC0Name; /* color 0 name */
- cname[1] = DfltC1Name; /* color 1 name */
- cname[2] = DfltC2Name; /* color 2 name */
- cname[3] = DfltC3Name; /* color 3 name */
- fntname = DfltFontName; /* font name */
-
- GetDisplayName(argc, argv);
-
- /* general X11 setup */
- dpy = XOpenDisplay(dpyname);
- if (dpy == NULL)
- {
- sprintf(buf, "unable to open display \"%s\"", dpyname);
- fatal(buf);
- }
- scrn = DefaultScreen(dpy);
- root = RootWindow(dpy, scrn);
- visl = DefaultVisual(dpy, scrn);
- cmap = DefaultColormap(dpy, scrn);
- dpth = DefaultDepth(dpy, scrn);
-
- GetResourceOptions();
-
- /*
- * if running with a StaticGray or GrayScale
- * display class, default to mono mode
- */
- switch (visl->class)
- {
- case StaticGray:
- case GrayScale:
- mono = True;
- break;
- }
-
- GetCmdLineOptions(argc, argv);
-
- /* check for mono mode */
- if (mono)
- {
- bdname = fgname;
- for (i=0; i<4; i++)
- cname[i] = fgname;
- }
-
- #ifdef DEBUG
- /* debug: color names */
- fflush(stdout);
- fprintf(stderr, "%s: color names\n", AppName);
- fprintf(stderr, " fgname %s\n", fgname);
- fprintf(stderr, " bgname %s\n", bgname);
- fprintf(stderr, " bdname %s\n", bdname);
- fprintf(stderr, " c0name %s\n", cname[0]);
- fprintf(stderr, " c1name %s\n", cname[1]);
- fprintf(stderr, " c2name %s\n", cname[2]);
- fprintf(stderr, " c3name %s\n", cname[3]);
- fprintf(stderr, "\n");
- fflush(stderr);
- #endif /* DEBUG */
-
- /* color allocation */
- fore = GetColor(fgname);
- back = GetColor(bgname);
- brdr = GetColor(bdname);
- for (i=0; i<4; i++)
- tilec[i] = GetColor(cname[i]);
-
- /* graphics context */
- gc = XCreateGC(dpy, root, 0, NULL);
- XSetState(dpy, gc, fore, back, GXcopy, AllPlanes);
-
- /* select the tile patterns */
- if (solid)
- {
- TileBits[0] = zerobits;
- TileBits[1] = solidbits;
- TileBits[2] = solidbits;
- TileBits[3] = solidbits;
- }
- else
- {
- TileBits[0] = zerobits;
- TileBits[1] = onebits;
- TileBits[2] = twobits;
- TileBits[3] = threebits;
- }
-
- /* build the tiles */
- for (i=0; i<4; i++)
- tilep[i] = MakePixmap(TileBits[i], TileSize, TileSize, tilec[i], back);
-
- /* fonts */
- font = XLoadQueryFont(dpy, fntname);
- if (font == NULL)
- {
- sprintf(buf, "unable to load font \"%s\"", fntname);
- fatal(buf);
- }
-
- swidth = XTextWidth(font, MaxPossibleScore, strlen(MaxPossibleScore));
- swidth += TileSize + (gwidth*4);
-
- /* main window */
- w = (gwidth*4) + (bwidth*2) + (TileSize*BoardSize);
- h = (gwidth*4) + (bwidth*2) + (TileSize*BoardSize);
- w += gwidth + swidth;
- h += gwidth + font->ascent + font->descent;
- mainw = GetWindow(root, 0, 0, w, h, bwidth);
- SetCursor(mainw, MainCurs);
- XSelectInput(dpy, mainw, PointerMotionMask|KeyPressMask|ExposureMask);
- AddEventHandler(mainw, MotionNotify, doMotion);
- AddEventHandler(mainw, KeyPress, doKey);
- AddEventHandler(mainw, Expose, doMainExpose);
-
- /* playing board window */
- x = gwidth;
- y = gwidth;
- w = (gwidth*2) + (TileSize*BoardSize);
- h = (gwidth*2) + (TileSize*BoardSize);
- boardw = GetWindow(mainw, x, y, w, h, bwidth);
- SetCursor(boardw, BoardCurs);
- XSelectInput(dpy, boardw, ExposureMask|ButtonPressMask);
- AddEventHandler(boardw, Expose, doBoardExpose);
- AddEventHandler(boardw, ButtonPress, doButtonPress);
- XMapWindow(dpy, boardw);
-
- /* help window */
- w = (TileSize*(BoardSize-6)) + (gwidth*2);
- h = NHelpLines*(font->ascent + font->descent) + (gwidth*2);
- x = ((TileSize*BoardSize + gwidth*2) - (w + bwidth*2)) / 2;
- y = ((TileSize*BoardSize + gwidth*2) - (h + bwidth*2)) / 2;
- helpw = GetWindow(boardw, x, y, w, h, bwidth);
- XSelectInput(dpy, helpw, ExposureMask);
- AddEventHandler(helpw, Expose, doHelpExpose);
-
- /* if we're in "expert" mode, don't map the silly help window initially */
- if (expert)
- {
- helpvis = False;
- }
- else
- {
- XMapWindow(dpy, helpw);
- helpvis = True;
- }
-
- /* next piece window */
- x = (gwidth*4) + (bwidth*2) + (TileSize*BoardSize);
- y = gwidth;
- w = (gwidth*2) + (TileSize*2);
- h = (gwidth*2) + (TileSize*2);
- nextw = GetWindow(mainw, x, y, w, h, bwidth);
- XSelectInput(dpy, nextw, ExposureMask);
- AddEventHandler(nextw, Expose, doNextExpose);
- XMapWindow(dpy, nextw);
-
- /* scores window */
- hswidth = XTextWidth(font, HighScoreTitle, strlen(HighScoreTitle));
- hswidth += 2*gwidth;
- w = font->max_bounds.width * MaxUnameLen;
- w += XTextWidth(font, MaxPossibleScore, strlen(MaxPossibleScore));
- w += 3*gwidth;
- if (hswidth > w)
- w = hswidth;
- else
- hswidth = w;
- h = (NHighScores+2)*(font->ascent + font->descent) + 2*gwidth;
- scoresw = GetWindow(root, 0, 0, w, h, bwidth);
- SetCursor(scoresw, MainCurs);
- XSelectInput(dpy, scoresw, KeyPressMask|ExposureMask);
- AddEventHandler(scoresw, KeyPress, doKey);
- AddEventHandler(scoresw, Expose, doHighExpose);
- scoresvis = False;
-
- /* various magic incantations (window manager) */
- TopWindowStuff(mainw, MainWindowName);
- TopWindowStuff(scoresw, ScoresWindowName);
-
- /* map the main window */
- XMapWindow(dpy, mainw);
- }
-
-
- static void GetDisplayName(argc, argv)
- int argc;
- char **argv;
- {
- int i;
-
- /* get display name from command line */
- for (i=1; i<argc; i++)
- if (strcmp(argv[i], "-display") == 0)
- {
- i += 1;
- if (i < argc)
- dpyname = argv[i];
- else
- Help("no display arg provided");
- }
- }
-
-
- static void GetResourceOptions()
- {
- char *tmp;
-
- tmp = XGetDefault(dpy, AppName, "Mono");
- if (tmp != NULL)
- mono = IsTrue(tmp);
-
- tmp = XGetDefault(dpy, AppName, "Solid");
- if (tmp != NULL)
- solid = IsTrue(tmp);
-
- tmp = XGetDefault(dpy, AppName, "Expert");
- if (tmp != NULL)
- expert = IsTrue(tmp);
-
- tmp = XGetDefault(dpy, AppName, "GutterWidth");
- if (tmp != NULL)
- {
- sscanf(tmp, "%d", &gwidth);
- if (gwidth < 0)
- fatal("gutterwidth must be non-negative");
- }
-
- tmp = XGetDefault(dpy, AppName, "BorderWidth");
- if (tmp != NULL)
- {
- sscanf(tmp, "%d", &bwidth);
- if (bwidth < 0)
- fatal("borderwidth must be non-negative");
- }
-
- tmp = XGetDefault(dpy, AppName, "Foreground");
- if (tmp != NULL)
- fgname = strdup(tmp);
-
- tmp = XGetDefault(dpy, AppName, "Background");
- if (tmp != NULL)
- bgname = strdup(tmp);
-
- tmp = XGetDefault(dpy, AppName, "BorderColor");
- if (tmp != NULL)
- bdname = strdup(tmp);
-
- tmp = XGetDefault(dpy, AppName, "Color0");
- if (tmp != NULL)
- cname[0] = strdup(tmp);
-
- tmp = XGetDefault(dpy, AppName, "Color1");
- if (tmp != NULL)
- cname[1] = strdup(tmp);
-
- tmp = XGetDefault(dpy, AppName, "Color2");
- if (tmp != NULL)
- cname[2] = strdup(tmp);
-
- tmp = XGetDefault(dpy, AppName, "Color3");
- if (tmp != NULL)
- cname[3] = strdup(tmp);
-
- tmp = XGetDefault(dpy, AppName, "Font");
- if (tmp != NULL)
- fntname = strdup(tmp);
- }
-
-
- static int IsTrue(s)
- char *s;
- {
- return ((strcasecmp(s, "true") == 0) ||
- (strcasecmp(s, "on") == 0) ||
- (strcasecmp(s, "yes") == 0));
- }
-
-
- static char *strdup(s)
- char *s;
- {
- char *rslt;
-
- rslt = (char *) malloc(sizeof(char) * (strlen(s) + 1));
- if (rslt == NULL)
- fatal("unable to malloc");
-
- strcpy(rslt, s);
-
- return rslt;
- }
-
-
- static void GetCmdLineOptions(argc, argv)
- int argc;
- char **argv;
- {
- int i;
-
- /* get options from command line */
- for (i=1; i<argc; i++)
- if (strcmp(argv[i], "-display") == 0)
- {
- /* already got the display name */
- i += 1;
- }
- else if (strcmp(argv[i], "-expert") == 0)
- {
- /* run in "expert" mode */
- expert = True;
- }
- else if (strcmp(argv[i], "-color") == 0)
- {
- /* try to use colors */
- mono = False;
- }
- else if (strcmp(argv[i], "-mono") == 0)
- {
- /* skip the colors */
- mono = True;
- }
- else if (strcmp(argv[i], "-patterns") == 0)
- {
- /* use patterned tiles */
- solid = False;
- }
- else if (strcmp(argv[i], "-solid") == 0)
- {
- /* use solid tiles */
- solid = True;
- }
- else if (strcmp(argv[i], "-gw") == 0)
- {
- /* get gutter width from next arg */
- i += 1;
- if (i < argc)
- sscanf(argv[i], "%d", &gwidth);
- else
- Help("no gutterwidth arg provided");
-
- /* ensure the gutter width is non-negative */
- if (gwidth < 0)
- fatal("gutterwidth must be non-negative");
- }
- else if (strcmp(argv[i], "-bw") == 0)
- {
- /* get border width from next arg */
- i += 1;
- if (i < argc)
- sscanf(argv[i], "%d", &bwidth);
- else
- Help("no borderwidth arg provided");
-
- /* ensure the border width is non-negative */
- if (bwidth < 0)
- fatal("borderwidth must be non-negative");
- }
- else if (strcmp(argv[i], "-fg") == 0)
- {
- /* get foreground color name from next arg */
- i += 1;
- if (i < argc)
- fgname = argv[i];
- else
- Help("no foreground arg provided");
- }
- else if (strcmp(argv[i], "-bg") == 0)
- {
- /* get background color name from next arg */
- i += 1;
- if (i < argc)
- bgname = argv[i];
- else
- Help("no background arg provided");
- }
- else if (strcmp(argv[i], "-bd") == 0)
- {
- /* get border color name from next arg */
- i += 1;
- if (i < argc)
- bdname = argv[i];
- else
- Help("no bordercolor arg provided");
- }
- else if (strcmp(argv[i], "-c0") == 0)
- {
- /* get color 0 name from next arg */
- i += 1;
- if (i < argc)
- cname[0] = argv[i];
- else
- Help("no color0 arg provided");
- }
- else if (strcmp(argv[i], "-c1") == 0)
- {
- /* get color 1 name from next arg */
- i += 1;
- if (i < argc)
- cname[1] = argv[i];
- else
- Help("no color1 arg provided");
- }
- else if (strcmp(argv[i], "-c2") == 0)
- {
- /* get color 2 name from next arg */
- i += 1;
- if (i < argc)
- cname[2] = argv[i];
- else
- Help("no color2 arg provided");
- }
- else if (strcmp(argv[i], "-c3") == 0)
- {
- /* get color 3 name from next arg */
- i += 1;
- if (i < argc)
- cname[3] = argv[i];
- else
- Help("no color3 arg provided");
- }
- else if (strcmp(argv[i], "-fn") == 0)
- {
- /* get font name from next arg */
- i += 1;
- if (i < argc)
- fntname = argv[i];
- else
- Help("no font arg provided");
- }
- else if (strcmp(argv[i], "-help") == 0)
- {
- Help(NULL);
- }
- else
- {
- sprintf(buf, "unknown option: %s", argv[i]);
- Help(buf);
- }
- }
-
-
- static void Help(msg)
- char *msg;
- {
- if (msg != NULL)
- fprintf(stderr, "\n%s\n", msg);
- else
- fprintf(stderr, "\n%s (v %d.%d)\n", AppName, MajorVersion, MinorVersion);
-
- fprintf(stderr, "\ncommand line options:\n");
- fprintf(stderr, " -help print this message\n");
- fprintf(stderr, " -display <d> use display <d>\n");
- fprintf(stderr, " -expert don't show quick help initially\n");
- fprintf(stderr, " -color run in color mode\n");
- fprintf(stderr, " -mono run in mono mode\n");
- fprintf(stderr, " -patterns use patterned tiles\n");
- fprintf(stderr, " -solid use solid tiles\n");
- fprintf(stderr, " -gw <n> use gutter width of <n> pixels\n");
- fprintf(stderr, " -bw <n> use border width of <n> pixels\n");
- fprintf(stderr, " -fg <c> use <c> as forground color\n");
- fprintf(stderr, " -bg <c> use <c> as background color\n");
- fprintf(stderr, " -bd <c> use <c> as border color\n");
- fprintf(stderr, " -c0 <c> use <c> as board color 0\n");
- fprintf(stderr, " -c1 <c> use <c> as board color 1\n");
- fprintf(stderr, " -c2 <c> use <c> as board color 2\n");
- fprintf(stderr, " -c3 <c> use <c> as board color 3\n");
- fprintf(stderr, " -fn <f> use font <f> for drawing text\n");
-
- fprintf(stderr, "\nSee the man page for more info.\n\n");
-
- exit(1);
- }
-
-
- void MainLoop()
- {
- XEvent xev;
- void (*handler)();
-
- while (1)
- {
- XNextEvent(dpy, &xev);
- handler = GetEventHandler(&xev);
- if (handler != NULL) handler(&xev);
- }
- }
-
-
- void drawBoard()
- {
- int r, c;
-
- /* redraw the tiles */
- for (c=0; c<BoardSize; c++)
- for (r=0; r<BoardSize; r++)
- drawTile(r, c);
-
- /* redraw controller */
- drawController();
- }
-
-
- void drawHelp()
- {
- /*
- * mosaic quick help
- *
- * q quit
- * s toggle high scores window visibility
- * h toggle help window visibility
- * n new game (only enabled when current game is completed)
- * a automatic -- randomly place any remaining tiles
- *
- * try `man mosaic' for further info
- * press `h' to hide this window
- */
-
- int fontsize;
- int x, y;
- int len;
- char *txt;
-
- fontsize = font->ascent + font->descent;
-
- x = 10;
- y = font->ascent + gwidth;
-
- y += fontsize/2;
- txt = "xtile quick help";
- len = strlen(txt);
- XDrawString(dpy, helpw, gc, x, y, txt, len);
- y += fontsize/2;
- y += fontsize;
-
- txt = "q";
- len = strlen(txt);
- XDrawString(dpy, helpw, gc, x, y, txt, len);
-
- txt = "quit";
- len = strlen(txt);
- XDrawString(dpy, helpw, gc, x+2*font->max_bounds.width, y, txt, len);
- y += fontsize;
-
- txt = "s";
- len = strlen(txt);
- XDrawString(dpy, helpw, gc, x, y, txt, len);
-
- txt = "toggle high scores window";
- len = strlen(txt);
- XDrawString(dpy, helpw, gc, x+2*font->max_bounds.width, y, txt, len);
- y += fontsize;
-
- txt = "h";
- len = strlen(txt);
- XDrawString(dpy, helpw, gc, x, y, txt, len);
-
- txt = "toggle help window";
- len = strlen(txt);
- XDrawString(dpy, helpw, gc, x+2*font->max_bounds.width, y, txt, len);
- y += fontsize;
-
- txt = "n";
- len = strlen(txt);
- XDrawString(dpy, helpw, gc, x, y, txt, len);
-
- txt = "new game";
- len = strlen(txt);
- XDrawString(dpy, helpw, gc, x+2*font->max_bounds.width, y, txt, len);
- y += fontsize;
-
- txt = "a";
- len = strlen(txt);
- XDrawString(dpy, helpw, gc, x, y, txt, len);
-
- txt = "automatic";
- len = strlen(txt);
- XDrawString(dpy, helpw, gc, x+2*font->max_bounds.width, y, txt, len);
- y += fontsize;
-
- y += fontsize/2;
- txt = "try `man xtile' for further info";
- len = strlen(txt);
- XDrawString(dpy, helpw, gc, x, y, txt, len);
- y += fontsize;
-
- txt = "(press `h' to hide this window)";
- len = strlen(txt);
- XDrawString(dpy, helpw, gc, x, y, txt, len);
- y += fontsize;
- y += fontsize/2;
- }
-
-
- void drawTile(r, c)
- int r, c; /* tile position */
- {
- int x, y;
-
- x = c * TileSize + gwidth;
- y = r * TileSize + gwidth;
-
- XCopyArea(dpy, tilep[tile[r*BoardSize+c]], boardw, gc,
- 0, 0, TileSize, TileSize, x, y);
- }
-
-
- void drawController()
- {
- int x, y;
-
- x = ccol * TileSize + gwidth;
- y = crow * TileSize + gwidth;
-
- XDrawRectangle(dpy, boardw, gc, x, y,
- TileSize*2-1, TileSize*2-1);
- XDrawRectangle(dpy, boardw, gc, x+1, y+1,
- TileSize*2-3, TileSize*2-3);
- }
-
-
- void drawNext()
- {
- int p;
-
- p = (nextpiece < NPieces) ? piece[nextpiece] : 0;
-
- XCopyArea(dpy, tilep[p&0x03], nextw, gc, 0, 0, TileSize, TileSize,
- gwidth, gwidth);
- p >>= 2;
- XCopyArea(dpy, tilep[p&0x03], nextw, gc, 0, 0, TileSize, TileSize,
- gwidth+TileSize, gwidth);
- p >>= 2;
- XCopyArea(dpy, tilep[p&0x03], nextw, gc, 0, 0, TileSize, TileSize,
- gwidth, gwidth+TileSize);
- p >>= 2;
- XCopyArea(dpy, tilep[p&0x03], nextw, gc, 0, 0, TileSize, TileSize,
- gwidth+TileSize, gwidth+TileSize);
- }
-
-
- void drawTitle()
- {
- int x, y;
- int len;
- char *txt;
-
- x = (gwidth*2) + (bwidth) + (TileSize*BoardSize/2);
- y = (gwidth*4) + (bwidth*2) + (TileSize*BoardSize);
- txt = AppName;
-
- len = strlen(txt);
- x -= XTextWidth(font, txt, len) / 2;
- y += font->ascent;
-
- XSetFont(dpy, gc, font->fid);
- XDrawString(dpy, mainw, gc, x, y, txt, len);
- }
-
-
- void drawScore()
- {
- int i, total;
- int top, left;
- int xtra, len;
- int x, y;
- char *txt;
- char buf[16];
-
- XSetFont(dpy, gc, font->fid);
-
- left = (gwidth*5) + (bwidth*2) + (TileSize*BoardSize);
- top = (gwidth*4) + (TileSize*4);
- xtra = (TileSize - (font->ascent + font->descent)) / 2;
-
- txt = "to play";
- len = strlen(txt);
- x = left + (swidth - XTextWidth(font, txt, len)) / 2;
- y = top + xtra + font->ascent;
- XDrawString(dpy, mainw, gc, x, y, txt, len);
- top += TileSize + gwidth;
-
- for (i=0; i<3; i++)
- {
- XClearArea(dpy, mainw, left, top, swidth, TileSize, False);
- XCopyArea(dpy, tilep[i+1], mainw, gc, 0, 0,
- TileSize, TileSize, left, top);
- sprintf(buf, "%d", remain[i]);
- len = strlen(buf);
- x = left + swidth - gwidth - XTextWidth(font, buf, len);
- y = top + xtra + font->ascent;
- XDrawString(dpy, mainw, gc, x, y, buf, len);
- top += TileSize + gwidth;
- }
- top += TileSize + gwidth;
-
- txt = "total";
- len = strlen(txt);
- x = left + (swidth - XTextWidth(font, txt, len)) / 2;
- y = top + xtra + font->ascent;
- XDrawString(dpy, mainw, gc, x, y, txt, len);
- top += TileSize + gwidth;
-
- total = 0;
- for (i=0; i<3; i++)
- {
- total += tscore[i];
- XClearArea(dpy, mainw, left, top, swidth, TileSize, False);
- XCopyArea(dpy, tilep[i+1], mainw, gc, 0, 0,
- TileSize, TileSize, left, top);
- sprintf(buf, "%d", tscore[i]);
- len = strlen(buf);
- x = left + swidth - gwidth - XTextWidth(font, buf, len);
- y = top + xtra + font->ascent;
- XDrawString(dpy, mainw, gc, x, y, buf, len);
- top += TileSize + gwidth;
- }
-
- XClearArea(dpy, mainw, left, top, swidth, TileSize, False);
- sprintf(buf, "%d", total);
- len = strlen(buf);
- x = left + swidth - gwidth - XTextWidth(font, buf, len);
- y = top + xtra + font->ascent;
- XDrawString(dpy, mainw, gc, x, y, buf, len);
- top += TileSize + gwidth;
- top += TileSize + gwidth;
-
- txt = "piece";
- len = strlen(txt);
- x = left + (swidth - XTextWidth(font, txt, len)) / 2;
- y = top + xtra + font->ascent;
- XDrawString(dpy, mainw, gc, x, y, txt, len);
- top += TileSize + gwidth;
-
- total = 0;
- for (i=0; i<3; i++)
- {
- total += pscore[i];
- XClearArea(dpy, mainw, left, top, swidth, TileSize, False);
- XCopyArea(dpy, tilep[i+1], mainw, gc, 0, 0,
- TileSize, TileSize, left, top);
- sprintf(buf, "%d", pscore[i]);
- len = strlen(buf);
- x = left + swidth - gwidth - XTextWidth(font, buf, len);
- y = top + xtra + font->ascent;
- XDrawString(dpy, mainw, gc, x, y, buf, len);
- top += TileSize + gwidth;
- }
-
- XClearArea(dpy, mainw, left, top, swidth, TileSize, False);
- sprintf(buf, "%d", total);
- len = strlen(buf);
- x = left + swidth - gwidth - XTextWidth(font, buf, len);
- y = top + xtra + font->ascent;
- XDrawString(dpy, mainw, gc, x, y, buf, len);
- top += TileSize + gwidth;
- }
-
-
- void drawHighScores()
- {
- int i;
- int fontsize;
- int x, y;
- int len;
- char *txt;
-
- fontsize = font->ascent + font->descent;
-
- txt = HighScoreTitle;
- len = strlen(txt);
- x = (hswidth - XTextWidth(font, txt, len)) / 2;
- y = fontsize/2 + font->ascent + gwidth;
- XDrawString(dpy, scoresw, gc, x, y, txt, len);
-
- y = fontsize*2 + gwidth;
- for (i=0; i<NHighScores; i++)
- if (highscore[i].score > 0)
- {
- XClearArea(dpy, scoresw, 0, y, hswidth, fontsize, False);
- y += font->ascent;
-
- txt = highscore[i].uname;
- len = strlen(txt);
- XDrawString(dpy, scoresw, gc, gwidth*2, y, txt, len);
-
- sprintf(buf, "%d", highscore[i].score);
- len = strlen(buf);
- x = hswidth - gwidth*2 - XTextWidth(font, buf, len);
- XDrawString(dpy, scoresw, gc, x, y, buf, len);
-
- y += font->descent;
- }
- }
-
-
- void drawAll()
- {
- drawBoard();
- drawHelp();
- drawNext();
- drawTitle();
- drawScore();
- drawHighScores();
- }
-
-
- static void doKey(xev)
- XEvent *xev;
- {
- if (XLookupString((XKeyEvent *) xev, buf, BufSize, NULL, NULL) > 0)
- switch (buf[0])
- {
- case 'q':
- case 'Q':
- QuitGame();
- break;
-
- case 'n':
- case 'N':
- case '\n':
- case '\r':
- if (nextpiece == NPieces)
- {
- InitGame();
- drawAll();
- }
- break;
-
- case 's':
- case 'S':
- if (scoresvis)
- {
- XUnmapWindow(dpy, scoresw);
- scoresvis = False;
- }
- else
- {
- XMapWindow(dpy, scoresw);
- XRaiseWindow(dpy, scoresw);
- scoresvis = True;
- }
- break;
-
- case 'h':
- case 'H':
- if (helpvis)
- {
- XUnmapWindow(dpy, helpw);
- helpvis = False;
- }
- else
- {
- XMapWindow(dpy, helpw);
- helpvis = True;
- }
- break;
-
- case 'a':
- case 'A':
- AutoPlay();
- break;
-
- case '\f':
- drawAll();
- break;
- }
- }
-
-
- static void doMotion(xev)
- XEvent *xev;
- {
- int x, y;
- Window dummyw;
- int row, col;
- int oldcr, oldcc;
- int redraw;
-
- /* motion event compression */
- while (XCheckTypedEvent(dpy, MotionNotify, xev));
-
- /* convert to boardw coordinates */
- XTranslateCoordinates(dpy, xev->xmotion.window, boardw,
- xev->xmotion.x, xev->xmotion.y,
- &x, &y, &dummyw);
-
- /* convert (x, y) to (row, col) */
- row = (y - gwidth) / TileSize;
- BoundVarVal(row, 0, (BoardSize-1));
- col = (x - gwidth) / TileSize;
- BoundVarVal(col, 0, (BoardSize-1));
-
- /* check if redraw is necessary */
- oldcr = crow;
- oldcc = ccol;
- redraw = False;
- if (row < crow)
- {
- crow = row;
- redraw = True;
- }
- else if ((row - 1) > crow)
- {
- crow = row - 1;
- redraw = True;
- }
- if (col < ccol)
- {
- ccol = col;
- redraw = True;
- }
- else if ((col - 1) > ccol)
- {
- ccol = col - 1;
- redraw = True;
- }
-
- /* if necessary, redraw */
- if (redraw)
- {
- /* redraw tiles */
- drawTile(oldcr++, oldcc);
- drawTile(oldcr, oldcc++);
- drawTile(oldcr--, oldcc);
- drawTile(oldcr, oldcc--);
-
- /* draw controller at (crow, ccol) */
- drawController();
- }
- }
-
-
- static void doBoardExpose(xev)
- XEvent *xev;
- {
- /* exposure event compression */
- while (XCheckTypedWindowEvent(dpy, boardw, Expose, xev));
-
- drawBoard();
- }
-
-
- static void doHelpExpose(xev)
- XEvent *xev;
- {
- while (XCheckTypedWindowEvent(dpy, helpw, Expose, xev));
-
- drawHelp();
- }
-
-
- static void doNextExpose(xev)
- XEvent *xev;
- {
- /* exposure event compression */
- while (XCheckTypedWindowEvent(dpy, nextw, Expose, xev));
-
- drawNext();
- }
-
-
- static void doMainExpose(xev)
- XEvent *xev;
- {
- /* exposure event compression */
- while (XCheckTypedWindowEvent(dpy, mainw, Expose, xev));
-
- drawTitle();
- drawScore();
- }
-
-
- static void doHighExpose(xev)
- XEvent *xev;
- {
- /* exposure event compression */
- while (XCheckTypedWindowEvent(dpy, scoresw, Expose, xev));
-
- drawHighScores();
- }
-
-
- static void doButtonPress(xev)
- XEvent *xev;
- {
- if (helpvis)
- {
- XBell(dpy, 0);
- }
- else if ((nextpiece < NPieces) &&
- (DropPiece(crow, ccol, piece[nextpiece])))
- {
- nextpiece += 1;
- drawNext();
-
- if (nextpiece == NPieces)
- CheckHighScore();
- }
- }
-
-
- static Pixel GetColor(name)
- char *name;
- {
- XColor xc;
-
- if (XParseColor(dpy, cmap, name, &xc) == 0)
- {
- sprintf(buf, "unable to parse color \"%s\"", name);
- fatal(buf);
- }
-
- if (XAllocColor(dpy, cmap, &xc) == 0)
- fatal("unable to alloc color");
-
- return xc.pixel;
- }
-
-
- static Window GetWindow(parent, x, y, w, h, b)
- Window parent;
- int x, y; /* position */
- int w, h; /* dimensions */
- int b; /* border width */
- {
- return XCreateSimpleWindow(dpy, parent, x, y, w, h, b, brdr, back);
- }
-
-
- static Pixmap MakePixmap(bits, w, h, fg, bg)
- char *bits;
- int w, h;
- Pixel fg, bg;
- {
- return XCreatePixmapFromBitmapData(dpy, root, bits, w, h, fg, bg, dpth);
- }
-
-
- static void SetCursor(w, idx)
- Window w;
- int idx;
- {
- Cursor curs;
- XColor fg, bg;
-
- curs = XCreateFontCursor(dpy, idx);
-
- if (XParseColor(dpy, cmap, fgname, &fg) == 0)
- {
- sprintf(buf, "unable to parse color \"%s\"", fgname);
- fatal(buf);
- }
- if (XParseColor(dpy, cmap, bgname, &bg) == 0)
- {
- sprintf(buf, "unable to parse color \"%s\"", bgname);
- fatal(buf);
- }
-
- XRecolorCursor(dpy, curs, &fg, &bg);
- XDefineCursor(dpy, w, curs);
- }
-
-
- static void TopWindowStuff(w, name)
- Window w;
- char *name;
- {
- XWindowAttributes xwa;
- XSizeHints *xsh;
-
- XGetWindowAttributes(dpy, w, &xwa);
-
- xsh = XAllocSizeHints();
- xsh->width = xwa.width;
- xsh->height = xwa.height;
- xsh->min_width = xwa.width;
- xsh->min_height = xwa.height;
- xsh->max_width = xwa.width;
- xsh->max_height = xwa.height;
- xsh->base_width = xwa.width;
- xsh->base_height = xwa.height;
- xsh->flags = (PSize|PMinSize|PMaxSize|PBaseSize);
-
- XSetWMNormalHints(dpy, w, xsh);
- XStoreName(dpy, w, name);
- XSetIconName(dpy, w, name);
-
- XFree((char *) xsh);
- }
-
-
- static void AddEventHandler(w, type, proc)
- Window w;
- int type;
- void (*proc)();
- {
- if (XSaveContext(dpy, w,
- (XContext) type,
- (caddr_t) proc) != 0)
- fatal("unable to XSaveContext");
- }
-
-
- static void (*GetEventHandler(xev))()
- XEvent *xev;
- {
- void (*rslt)();
-
- if (XFindContext(dpy, xev->xany.window,
- (XContext) xev->xany.type,
- (caddr_t *) &rslt) != 0)
- rslt = NULL;
-
- return rslt;
- }
-