/* EXPORT->HGetEvent: return next relevant event in event queue */ HEventRec HGetEvent(Boolean anyEvent, void (*action)(void)) { XEvent xev; HEventRec hev; Boolean found,dummy; XFlush(theDisp); found = FALSE; do { if(XEventsQueued(theDisp, QueuedAfterFlush) > 0 || action==NULL){ XNextEvent(theDisp, &xev); found = TRUE; if (xev.xany.window==theWindow || anyEvent){ switch (xev.type) { case ButtonPress: hev.event = HMOUSEDOWN; hev.x = xev.xbutton.x; hev.y = xev.xbutton.y; break; case ButtonRelease: hev.event = HMOUSEUP; hev.x = xev.xbutton.x; hev.y = xev.xbutton.y; break; case MotionNotify: hev.event = HMOUSEMOVE; hev.x = xev.xmotion.x; hev.y = xev.xmotion.y; break; case KeyPress: hev.event = HKEYPRESS; hev.x = xev.xkey.x; hev.y = xev.xkey.y; DecodeKeyPress(&(xev.xkey), &hev); break; case KeyRelease: hev.event = HKEYRELEASE; hev.x = xev.xkey.x; hev.y = xev.xkey.y; DecodeKeyPress(&(xev.xkey), &hev); break; case Expose: if (xev.xexpose.count==0) hev.event = HREDRAW; else found = FALSE; break; default: found = FALSE; } } } else if (action!=NULL){ (*action)(); XFlush(theDisp); /* execute a round-robin command to make sure that */ /* client doesnt get too far ahead of the server */ dummy = HMousePos(&hev.x,&hev.y); } } while (!found); return hev; }
// main routine main(int argc, char **argv) { char string[BUFSIZ]; // connect to x-server int screen; Window rootwindow; Display *display = ConnectToServer(NULL, screen, rootwindow); if (display == NULL) { ERROR("connect to server failed.", EINVAL); return(2); } // get basic colors black = BlackPixel(display, screen); white = WhitePixel(display, screen); // create a window Visual *visual = CopyFromParent; int x = 10; int y = 10; int width = 300; int height = 300; Window window = OpenWindow(display, rootwindow, x, y, width, height, black, white, EVENT_MASK, visual); // set hints for window SetStandardHints(display, window, argv[0], argv[0], x, y, width, height); // create GC for drawing GC gc = CreateGC(display, window, black, white); // load a font XFontStruct *font_struct = LoadFont(display, FONT_NAME, FALLBACK_FONT_NAME); // set up gc with font structure XSetFont(display, gc, font_struct->fid); // map window XMapRaised(display, window); XFlush(display); // event loop: max of 20 events, then exit. KeySym keysym; XEvent event; for (int done = False; done != True; ) { XNextEvent(display, &event); switch (event.type) { case Expose: cout << "Expose: <x, y, w, h> = <"; cout << event.xexpose.x << ","; cout << event.xexpose.y << ","; cout << event.xexpose.width << ","; cout << event.xexpose.height; cout << ">" << endl; if (event.xexpose.count == 0) { cout << "last expose event." << endl; } break; case MapNotify: cout << "MapNotify: window was mapped." << endl; break; case ButtonPress: cout << "ButtonPress: "; cout << ButtonIds[event.xbutton.button]; cout << " at <"; cout << event.xbutton.x << ","; cout << event.xbutton.y << ">" << endl; AppendKeyStateMessage(event.xbutton.state); break; case EnterNotify: cout << "EnterNotify: pointer enters window" << endl; break; case LeaveNotify: cout << "LeaveNotify: pointer enters window" << endl; break; case ButtonRelease: cout << "ButtonRelease: "; cout << ButtonIds[event.xbutton.button]; cout << " at <"; cout << event.xbutton.x << ","; cout << event.xbutton.y << ">" << endl; AppendKeyStateMessage(event.xbutton.state); break; case KeyPress: done = DecodeKeyPress(&event.xkey, &keysym, string); HandleKeyPress(&event.xkey, keysym, string); break; case ConfigureNotify: cout << "ConfigureNotify: <x, y, w, h> = <"; cout << event.xconfigure.x << ","; cout << event.xconfigure.y << ","; cout << event.xconfigure.width << ","; cout << event.xconfigure.height; cout << ">" << endl; break; } // redraw for all events. if ( ! done) redraw(display, window, gc); } // close connection XFreeFont(display, font_struct); XCloseDisplay(display); // all done return(0); }
// main entry point main(int argc, char **argv) { // get command line options int nextarg; if (cmdopts(argc, argv, nextarg) != OK) { fprintf(stderr, "invalid command line option [%s].\n", argv[nextarg]); return(2); } // get data if (getdata(argc, argv, nextarg) != OK) { fprintf(stderr, "unable to get data."); return(2); } // connect to server Display *xdisplay = NULL; if (OpenDisplay(display, xdisplay) != OK) { fprintf(stderr, "unable to open display to server %s.\n", XDisplayName(display)); return(2); } // get physical screen attributes int xscreen; unsigned int display_width, display_height; if (GetDisplayAttributes(xdisplay, xscreen, display_width, display_height) != OK) { fprintf(stderr, "unable to get display attributes.\n"); CloseDisplay(xdisplay); return(2); } // determine window geometry and location int window_width, window_height, window_x, window_y; if (GetWindowGeometry(display_width, display_height, window_width, window_height, window_x, window_y) != OK) { fprintf(stderr, "unable to get window geometry.\n"); CloseDisplay(xdisplay); return(2); } // default black and white pixels unsigned long black = BlackPixel(xdisplay, xscreen); unsigned long white = WhitePixel(xdisplay, xscreen); // get pseudo-color display, if any int window_depth; Visual *window_visual; if (GetPseudoColorVisual(xdisplay, xscreen, window_visual, window_depth) != OK) { fprintf(stderr, "unable to get a color visual.\n"); CloseDisplay(xdisplay); return(2); } // create a window unsigned int window_border_width = 4; Window root_window = RootWindow(xdisplay, xscreen); window_visual=CopyFromParent; window_depth=CopyFromParent; Window window = CreateWindow( xdisplay, root_window, window_x, window_y, window_width, window_height, black, white, EventMask, window_visual, window_border_width, window_depth); // set size hints if (SetSizeHints(xdisplay, window, window_x, window_y, window_width, window_height) != OK) { fprintf(stderr, "unable to set window size hints.\n"); CloseDisplay(xdisplay); return(2); } // set window name if (SetWindowName(xdisplay, window, title) != OK) { fprintf(stderr, "unable to set window title.\n"); CloseDisplay(xdisplay); return(2); } // set class hints if (SetClassHints(xdisplay, window, argv[0], argv[0]) != OK) { fprintf(stderr, "unable to set class hints.\n"); CloseDisplay(xdisplay); return(2); } // set other window manager hints int initstate = (strcmp(iconic, "YES") == 0) ? IconicState : NormalState; if (SetWMHints(xdisplay, window, initstate) != OK) { fprintf(stderr, "unable to set WM hints.\n"); CloseDisplay(xdisplay); return(2); } // set up color map for window Colormap window_colormap; if (SetUpColorMap(xdisplay, xscreen, window, window_visual, window_colormap) != OK) { fprintf(stderr, "unable to set up a color map.\n"); CloseDisplay(xdisplay); return(2); } // allocate colors for background and foreground unsigned long window_background = AllocateColorByName(xdisplay, window_colormap, background, white); unsigned long window_foreground = AllocateColorByName(xdisplay, window_colormap, foreground, black); // get font for writing XFontStruct *xfont = LoadFont(xdisplay, font, "fixed"); if (xfont == NULL) { fprintf(stderr, "unable to load font.\n"); CloseDisplay(xdisplay); return(2); } // create GC for drawing GC gc = CreateGC(xdisplay, window, xfont, window_foreground, window_background); GC xor_gc = CreateXorGC(xdisplay, window, xfont, window_foreground, window_background); // map window XMapRaised(xdisplay, window); XFlush(xdisplay); // event loop int start_x = -1; int start_y = -1; int last_x = -1; int last_y = -1; XEvent event; KeySym keysym; char string[BUFSIZ]; for (int done = 0; !done; ) { XNextEvent(xdisplay, &event); switch (event.type) { case Expose: if (event.xexpose.count == 0) { redraw(xdisplay, window, gc, xfont, window_width, window_height); } break; case ConfigureNotify: window_x = event.xconfigure.x; window_y = event.xconfigure.y; window_width = event.xconfigure.width; window_height = event.xconfigure.height; break; case KeyPress: done = DecodeKeyPress(&event.xkey, &keysym, string); break; case MappingNotify: XRefreshKeyboardMapping(&event.xmapping); break; case ButtonPress: if (event.xbutton.button == Button1) { start_x = event.xbutton.x; start_y = event.xbutton.y; last_x = start_x; last_y = start_y; DrawBox(xdisplay, window, xor_gc, start_x, start_y, last_x, last_y); XFlush(xdisplay); } break; case ButtonRelease: if (event.xbutton.button == Button1) { if (start_x != last_x && start_y != last_y) { DrawBox(xdisplay, window, xor_gc, start_x, start_y, last_x, last_y); XFlush(xdisplay); UpdateLimits(start_x, start_y, last_x, last_y, window_width, window_height); XClearWindow(xdisplay, window); XFlush(xdisplay); redraw(xdisplay, window, gc, xfont, window_width, window_height); XFlush(xdisplay); } start_x = -1; start_y = -1; last_x = -1; last_y = -1; } else { // reset to original values. rminxval = reset_rminxval; rmaxxval = reset_rmaxxval; rminyval = reset_rminyval; rmaxyval = reset_rmaxyval; XClearWindow(xdisplay, window); XFlush(xdisplay); redraw(xdisplay, window, gc, xfont, window_width, window_height); XFlush(xdisplay); } break; case MotionNotify: if (event.xbutton.button == Button1) { DrawBox(xdisplay, window, xor_gc, start_x, start_y, last_x, last_y); last_x = event.xmotion.x; last_y = event.xmotion.y; DrawBox(xdisplay, window, xor_gc, start_x, start_y, last_x, last_y); XFlush(xdisplay); } break; } } // close display CloseDisplay(xdisplay); // all done return(0); }