8 enum { QUIT = 1, REDRAW = 2 };
10 static Window create_win(int width, int height, int bpp);
11 static void handle_event(XEvent *ev);
12 static int translate_keysym(KeySym sym);
13 static int parse_args(int argc, char **argv);
15 static int win_width, win_height;
17 static unsigned int pending;
19 static Window win, root;
20 static Atom xa_wm_proto, xa_wm_delwin;
22 int main(int argc, char **argv)
26 read_config("rbench.cfg");
28 if(parse_args(argc, argv) == -1) {
32 if(!(dpy = XOpenDisplay(0))) {
33 fprintf(stderr, "failed to connect to the X server\n");
36 root = DefaultRootWindow(dpy);
37 xa_wm_proto = XInternAtom(dpy, "WM_PROTOCOLS", 0);
38 xa_wm_delwin = XInternAtom(dpy, "WM_DELETE_WINDOW", 0);
40 if(!(win = create_win(opt.width, opt.height, opt.bpp))) {
46 while(XPending(dpy)) {
49 if(pending & QUIT) goto end;
55 if(pending & QUIT) goto end;
60 XDestroyWindow(dpy, win);
65 static Window create_win(int width, int height, int bpp)
69 XVisualInfo *vis, vinf;
70 unsigned int vinf_mask;
71 XSetWindowAttributes xattr;
74 const char *name = "retrobench X11";
76 scr = DefaultScreen(dpy);
80 vinf.class = bpp <= 8 ? PseudoColor : TrueColor;
81 vinf_mask = VisualScreenMask | VisualDepthMask | VisualClassMask;
82 if(!(vis = XGetVisualInfo(dpy, vinf_mask, &vinf, &num_vis))) {
83 fprintf(stderr, "failed to find appropriate visual for %d bpp\n", bpp);
87 if(!(cmap = XCreateColormap(dpy, root, vis->visual, bpp <= 8 ? AllocAll : AllocNone))) {
88 fprintf(stderr, "failed to allocate colormap\n");
92 xattr.background_pixel = BlackPixel(dpy, scr);
93 xattr.colormap = cmap;
94 win = XCreateWindow(dpy, root, 0, 0, width, height, 0, vis->depth,
95 InputOutput, vis->visual, CWColormap | CWBackPixel, &xattr);
98 XSelectInput(dpy, win, StructureNotifyMask | ExposureMask | KeyPressMask |
101 XStringListToTextProperty((char**)&name, 1, &txname);
102 XSetWMName(dpy, win, &txname);
103 XSetWMIconName(dpy, win, &txname);
106 XSetWMProtocols(dpy, win, &xa_wm_delwin, 1);
108 XMapWindow(dpy, win);
112 static void handle_event(XEvent *ev)
130 case ConfigureNotify:
131 if(ev->xconfigure.width != win_width || ev->xconfigure.height != win_height) {
132 win_width = ev->xconfigure.width;
133 win_height = ev->xconfigure.height;
140 if((sym = XKeycodeToKeysym(dpy, ev->xkey.keycode, 0))) {
141 if(sym == XK_Escape) {
145 if((key = translate_keysym(sym))) {
146 key_event(key, ev->xkey.type == KeyPress);
152 if(ev->xclient.message_type == xa_wm_proto) {
153 if(ev->xclient.data.l[0] == xa_wm_delwin) {
164 static int translate_keysym(KeySym sym)
166 if(sym < 128) return sym;
178 static const char *usage_str =
179 "Usage: %s [options]\n"
181 " -s <WxH>: resolution\n"
182 " -b <bpp>: color depth\n"
183 " -h: print usage and exit\n";
185 static int parse_args(int argc, char **argv)
189 for(i=1; i<argc; i++) {
190 if(argv[i][0] == '-') {
196 if(!argv[++i] || sscanf(argv[i], "%dx%d", &opt.width, &opt.height) != 2) {
197 fprintf(stderr, "-s must be followed by WxH\n");
203 if(!argv[++i] || !(opt.bpp = atoi(argv[i]))) {
204 fprintf(stderr, "-b must be followed by the color depth\n");
210 printf(usage_str, argv[0]);
217 inval_arg: fprintf(stderr, "invalid argument: %s\n", argv[i]);