From 64e1d442e46eb65ae79ce707763f9d0884435a9d Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Wed, 5 Jun 2013 22:02:46 +0000 Subject: remove flicker by using pixmap for drawing add WM_DELETE_WINDOW event handling --- stern.c | 46 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/stern.c b/stern.c index 81eaaa5..b9c1ac1 100644 --- a/stern.c +++ b/stern.c @@ -114,16 +114,18 @@ struct line world[] = { /* XGCValues values; */ Display *display; Window win; -GC gc; +Pixmap pix; +GC wingc, pixgc; +int black, white; +int die = 0; int main(int argc, char **argv) { - XEvent event; int screen; - int black, white; int r = 0; int pause = 0; + Atom delwin; display = XOpenDisplay(argc == 2 ? argv[1] : NULL); screen = DefaultScreen(display); @@ -132,19 +134,24 @@ main(int argc, char **argv) win = XCreateSimpleWindow(display, DefaultRootWindow(display), 0, 0, Width, Height, 0, black, white); XStoreName(display, win, "Stern $Revision$"); + delwin = XInternAtom(display, "WM_DELETE_WINDOW", 0); + XSetWMProtocols(display, win, &delwin, 1); - XSelectInput(display, win, KeyPressMask); + wingc = XCreateGC(display, win, 0, NULL); + XSetGraphicsExposures(display, wingc, False); + XSetBackground(display, wingc, white); - gc = XCreateGC(display, win, 0, NULL); - XSetForeground(display, gc, black); - XSetBackground(display, gc, white); - XSetLineAttributes(display, gc, 2, LineSolid, CapButt, JoinBevel); - XSetFillStyle(display, gc, FillSolid); + pix = XCreatePixmap(display, win, Width, Height, 1); + pixgc = XCreateGC(display, pix, 0, NULL); + XSetLineAttributes(display, pixgc, 2, LineSolid, CapButt, JoinBevel); + XSelectInput(display, win, KeyPressMask); XMapWindow(display, win); - for (;;) { + while (!die) { if (XPending(display)) { + XEvent event; + XNextEvent(display, &event); switch (event.type) { case KeyPress: @@ -157,21 +164,26 @@ main(int argc, char **argv) XCloseDisplay(display); exit(0); } + case ClientMessage: + die = *event.xclient.data.l == delwin; + break; default: break; } } if (!pause) { - XClearWindow(display, win); - if (r >= 360) - r = 0; + r %= 360; DrawObject(++r, world, NMELM(world)); } usleep(Usleep); } + XFreePixmap(display, pix); + XDestroyWindow(display, win); + XCloseDisplay(display); + return 0; } @@ -187,11 +199,17 @@ DrawObject(int r, struct line *p, int nelem) Sr = sin(R); Cr = cos(R); + XSetForeground(display, pixgc, 0); + XFillRectangle(display, pix, pixgc, 0, 0, Width, Height); + XSetForeground(display, pixgc, 1); + for(i = 0; i < nelem; ++i) { Calc3D(&p[i].a, Sr, Cr, &x1, &y1); Calc3D(&p[i].b, Sr, Cr, &x2, &y2); - XDrawLine(display, win, gc, x1, y1, x2, y2); + XDrawLine(display, pix, pixgc, x1, y1, x2, y2); } + + XCopyPlane(display, pix, win, wingc, 0, 0, Width, Height, 0, 0, 1); } int -- cgit v1.2.3