#include <stdio.h> #include <string.h> #include <X11/Xlib.h> #include <X11/Xutil.h> #define DEFAULT_BGCOLOR "white" #define DEFAULT_FGCOLOR "black" #define DEFAULT_BDWIDTH 1 #define DEFAULT_FONT "fixed" typedef struct APP_PARAMS { char *name; char **p_value_string; } APP_PARAMS; typedef struct XWIN { Window xid; Window parent; void *data; int (*event_handler)(); } XWIN; /* Default parameter values */ char *theBGcolor = DEFAULT_BGCOLOR, *theFGcolor = DEFAULT_FGCOLOR, *theFont = DEFAULT_FONT, *theGeom_rsrc = NULL, *display_name = NULL, *theGeom_cline = NULL, *theGeom = NULL; APP_PARAMS app_resources[] = { "background", &theBGcolor, "foreground", &theFGcolor, "font", &theFont, "geometry", &theGeom_rsrc }; int num_resources = sizeof(app_resources) / sizeof(APP_PARAMS); /* List of command-line options */ APP_PARAMS app_options[] = { "-display", &display_name, "-d", &display_name, "-geometry", &theGeom_cline, "-g", &theGeom_cline, }; int num_options = sizeof(app_options) / sizeof(APP_PARAMS); void usage(void); Display *theDisplay; GC theGC; int AppDone = 0; XEvent theEvent; XFontStruct *theFontStruct; unsigned long theBGpix, theFGpix; char *theAppName = " "; Window theMain; XWindowAttributes MainXWA; XContext xwin_context; void initapp(int argc, char **argv, int x, int y, unsigned width, unsigned height) { int i, j; char *tmpstr; Colormap default_cmap; XColor color; int bitmask; XGCValues gcv; XSetWindowAttributes xswa; XWMHints xwmh; XSizeHints xsh; char default_geometry[80]; AppDone = 0; if (argv != NULL){ theAppName = argv[0]; for(i=1; i<argc; i+=2) { for(j=1; j<num_options; j++){ if (strcmp(app_options[j].name, argv[i]) == 0) { *app_options[j].p_value_string = argv[i+1]; break; } } if (j>= num_options) usage(); } } if((theDisplay = XOpenDisplay(display_name)) == NULL){ fprintf(stderr, "%s: can't open display named %s\n", argv[0], XDisplayName(display_name)); exit(1); } for (i=0; i<num_resources; i++){ if((tmpstr = XGetDefault(theDisplay, theAppName, app_resources[i].name)) != NULL) *app_resources[i].p_value_string = tmpstr; } if((theFontStruct = XLoadQueryFont(theDisplay, theFont)) == NULL) { fprintf(stderr, "%s: display %s cannot load font %s\n", theAppName, DisplayString(theDisplay), theFont); exit(1); } default_cmap = DefaultColormap(theDisplay, DefaultScreen(theDisplay)); if (XParseColor(theDisplay, default_cmap, theBGcolor, &color) == 0 || XAllocColor(theDisplay, default_cmap, &color) == 0 ){ /* Use white background in case of failure */ theBGpix = WhitePixel(theDisplay, DefaultScreen(theDisplay)); } else { theBGpix = color.pixel; } if (XParseColor(theDisplay, default_cmap, theFGcolor, &color) == 0 || XAllocColor(theDisplay, default_cmap, &color) == 0 ){ /* Use white background in case of failure */ theFGpix = WhitePixel(theDisplay, DefaultScreen(theDisplay)); } else { theFGpix = color.pixel; } /* Fill out a XsizeHints structure to inform the window manager about the desired size and location of main window */ xsh.flags = (PPosition | PSize | PMinSize); xsh.height = height; xsh.width = width; xsh.min_width = xsh.width; xsh.x = x; xsh.y = y; /* make default geometry string */ sprintf(default_geometry, "%dx%d+%d+%d", xsh.width, xsh.height, xsh.x, xsh.y); theGeom = default_geometry; /* Override the geometry if necessary */ if(theGeom_cline != NULL) theGeom = theGeom_cline; else if(theGeom_rsrc != NULL) theGeom = theGeom_rsrc; /* process geometry specifications */ bitmask = XGeometry(theDisplay, DefaultScreen(theDisplay), theGeom, default_geometry, DEFAULT_BDWIDTH, theFontStruct->max_bounds.width, theFontStruct->max_bounds.ascent + theFontStruct->max_bounds.descent, 1, 1, &(xsh.x), &(xsh.y), &(xsh.width), &(xsh.height)); /* Check the bitmask and set flags in XSizeHints structure */ if (bitmask & (XValue | YValue)) xsh.flags |= USPosition; if (bitmask & (WidthValue | HeightValue)) xsh.flags |= USSize; /* Create the main window */ theMain = XCreateSimpleWindow(theDisplay, DefaultRootWindow(theDisplay), xsh.x, xsh.y, xsh.width, xsh.height, DEFAULT_BDWIDTH, theFGpix, theBGpix); /*Set window manager properties */ XSetStandardProperties(theDisplay, theMain, theAppName, theAppName, None, argv, argc, &xsh); /* Give other hints */ xwmh.flags = (InputHint | StateHint); xwmh.input = True; xwmh.initial_state = NormalState; XSetWMHints(theDisplay, theMain, &xwmh); /* Create a graphics context ofr the main window */ gcv.font = theFontStruct->fid; gcv.foreground = theFGpix; gcv.background = theBGpix; theGC = XCreateGC(theDisplay, theMain, (GCFont | GCForeground | GCBackground), &gcv); /* Set main window's attributes */ xswa.bit_gravity = NorthWestGravity; /* XChangeWindowAttributes(theDisplay, theMain, (CWColormap | CWBitGravity), &xswa); */ /* Select exposure events for the main window */ XSelectInput(theDisplay, theMain, ExposureMask); /* Map the main window */ XMapWindow(theDisplay, theMain); if(XGetWindowAttributes(theDisplay, theMain, &MainXWA) == 0){ fprintf(stderr, "Error getting attributes of main\n"); exit(2); } } void usage(void){ fprintf(stderr, "%s [-display name] [-geometry geom]\n", theAppName); } void xwin_init(void) { xwin_context = XUniqueContext(); } draw_rect(int x, int y) { XDrawRectangle(theDisplay, theMain, theGC, x, y, 2, 2); } draw_point(int x,int y) { XDrawPoint(theDisplay, theMain, theGC, x, y); } simple_init(int x, int y, unsigned width, unsigned height) { xwin_init(); initapp(0, NULL, x, y, width, height); } clear() { XClearWindow(theDisplay, theMain); }