/* xcheckers.c X setup, image load, font, main routine */ /* * xcheckers: a point and click checkerboard * (C): 1999, 2000 Peter Chiocchetti */ #include #include #include #include #include #include #include #include "xcheckers.xbm" #include "xcheckers.h" #include "board.h" #include "help.h" #include "resource.h" #include "sprite.h" #include "child.h" #include "status.h" #define EVENTMASK (ExposureMask | StructureNotifyMask \ | ButtonPressMask | ButtonReleaseMask \ | EnterWindowMask | LeaveWindowMask \ | Button1MotionMask | KeyPressMask) #define GCMASK (GCBackground | GCForeground | GCGraphicsExposures) int screen; /* screen number to use on that server */ XpmImage image; /* image to preload */ unsigned long paper; /* color entries in colormap */ unsigned long pen; /* color entries in colormap */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Checkers Theme * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* prepare an X color value */ static int getColor(Colormap cmap, char *color_name) { XColor color, exact; if (!XAllocNamedColor(dpy, cmap, color_name, &color, &exact)) fprintf(stderr, "%s: Warning, could not allocate color %s\n", progname, color_name); return (color.pixel); } /* load xpm file, set fg and bg colors, node width and height */ static void loadImage(void) { int status, n; XpmColor *colorTable; char *thisScene; /* try to get scene from user-defined resource setting */ if ((thisScene = resGet("scene")) == NULL) { fprintf(stderr, "%s: Error, no scene specified\n", progname); exit(1); } status = XpmReadFileToXpmImage(thisScene, &image, NULL); if (status != XpmSuccess) { fprintf(stderr, "%s: Error, %s\n", progname, XpmGetErrorString(status)); exit(1); } width = image.width / 6; height = image.height; colorTable = image.colorTable; for (n = 0; n < image.ncolors; n++) { if (colorTable[n].symbolic != NULL) { if (!strcmp(colorTable[n].symbolic, "paper")) paper = getColor(DefaultColormap(dpy, screen), colorTable[n].c_color); else if (!strcmp(colorTable[n].symbolic, "pen")) pen = getColor(DefaultColormap(dpy, screen), colorTable[n].c_color); } } if (!paper || !pen) { paper = WhitePixel(dpy, screen); pen = BlackPixel(dpy, screen); } } /* turn the xpm image into an X pixmap */ static void putImage(void) { int status; status = XpmCreatePixmapFromXpmImage(dpy, win, &image, &scene, &clip, NULL); if (status != XpmSuccess) { fprintf(stderr, "%s: Error, %s\n", progname, XpmGetErrorString(status)); exit(1); } XpmFreeXpmImage(&image); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * A Nice Font * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* prepare the applications font */ static void initFont(void) { char *fontname; /* try to get font from user-defined resource setting */ if ((fontname = resGet("font")) == NULL) { fontname = strdup("fixed"); } if ((font = XLoadQueryFont(dpy, fontname)) == NULL) { /* not an available font */ fprintf(stderr, "%s: Error, could not load font %s\n", progname, fontname); exit(1); } status_height = (font->ascent + font->descent) * 12 / 5; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Main Window * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* connect to the X server */ static void connectDisplay(void) { char *displayname; /* try to get X server from user-defined resource setting */ displayname = resGet("display"); /* attempt to connect to the server and use the chosen screen */ if ((dpy = XOpenDisplay(displayname)) == NULL) { fprintf(stderr, "%s: Error, could not open display\n", progname); exit(1); } screen = DefaultScreen(dpy); } /* prepare main window */ static void initWindow(int argc, char **argv) { Pixmap icon; char *geometry; XWMHints *wmhints; XSizeHints *sizehints; XClassHint *classhints; XTextProperty wname, iname; XGCValues gcv; /* try to get geometry from user-defined resource setting */ geometry = resGet("geometry"); if ((sizehints = XAllocSizeHints()) == NULL) { fprintf(stderr, "%s: Error, could not allocate size hints\n", progname); exit(1); } if ((wmhints = XAllocWMHints()) == NULL) { fprintf(stderr, "%s: Error, could not allocate window manager hints\n", progname); exit(1); } if ((classhints = XAllocClassHint()) == NULL) { fprintf(stderr, "%s: Error, could not allocate class hints\n", progname); exit(1); } /* fill in hints in order to parse geometry spec */ sizehints->width = sizehints->min_width = sizehints->max_width = board_width; sizehints->height = sizehints->min_height = sizehints->max_height = board_height + status_height; sizehints->flags = PSize | PMinSize | PMaxSize; if (XWMGeometry(dpy, screen, geometry, NULL, 0, sizehints, &sizehints->x, &sizehints->y, &sizehints->width, &sizehints->height, &sizehints->win_gravity) & (XValue | YValue)) sizehints->flags |= USPosition; /* override -geometry for size of window */ sizehints->width = sizehints->min_width = sizehints->max_width = board_width; sizehints->height = sizehints->min_height = sizehints->max_height = board_height + status_height; /* actually create the window */ win = XCreateSimpleWindow(dpy, RootWindow(dpy, screen), sizehints->x, sizehints->y, sizehints->width, sizehints->height, 0, pen, paper); /* set up which event types the window will handle */ XSelectInput(dpy, win, EVENTMASK); /* set up graphics context resources in the display server */ gcv.graphics_exposures = False; gcv.background = paper; gcv.foreground = pen; gc = XCreateGC(dpy, win, GCMASK, &gcv); /* care for the window manager properties */ if (XStringListToTextProperty(&progname, 1, &wname) == 0) { fprintf(stderr, "%s: Error, could not allocate window name structure\n", progname); exit(1); } if (XStringListToTextProperty(&progname, 1, &iname) == 0) { fprintf(stderr, "%s: Error, could not allocate icon name structure\n", progname); exit(1); } icon = XCreateBitmapFromData(dpy, win, icon_bits, icon_width, icon_height); wmhints->icon_pixmap = icon; wmhints->input = True; wmhints->initial_state = NormalState; wmhints->flags = IconPixmapHint | StateHint | InputHint; classhints->res_name = progname; classhints->res_class = "XCheckers"; XSetWMProperties(dpy, win, &wname, &iname, argv, argc, sizehints, wmhints, classhints); /* let the window manager close the program */ wm_protocols = XInternAtom(dpy, "WM_PROTOCOLS", False); wm_delete_window = XInternAtom(dpy, "WM_DELETE_WINDOW", False); if ((XSetWMProtocols(dpy, win, &wm_delete_window, 1)) != True) fprintf(stderr, "%s: Warning, could not ask for clean delete\n", progname); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Main Function * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* hopefully start and end of program run */ int main(int argc, char *argv[]) { int icds; char *hostname, *portnum; if(!isatty(0)) { system("xmessage \" Please run xcheckers from a terminal \""); exit(1); } icds = resInit(&argc, argv, &hostname, &portnum); connectDisplay(); //XSynchronize(dpy, True); loadImage(); initFont(); initWindow(argc, argv); XSetFont(dpy, gc, font->fid); putImage(); initBoard(ENGLISH); initStatus(paper, pen, myname); initHelp(paper, pen); initSprite(); XMapWindow(dpy, win); XFlush(dpy); loop(hostname, portnum, icds); XCloseDisplay(dpy); exit(0); }