atexit cleanup
d9c24564
2 file(s) · +36 −46
| 26 | 26 | static Bool grabkeyboard(void); |
|
| 27 | 27 | static void kpress(XKeyEvent *e); |
|
| 28 | 28 | static void run(void); |
|
| 29 | - | static void setup(Bool topbar); |
|
| 29 | + | static void setup(void); |
|
| 30 | 30 | ||
| 31 | 31 | #include "config.h" |
|
| 32 | 32 | ||
| 34 | 34 | static char *prompt = NULL; |
|
| 35 | 35 | static char text[4096]; |
|
| 36 | 36 | static int promptw = 0; |
|
| 37 | - | static int ret = 0; |
|
| 38 | 37 | static int screen; |
|
| 39 | 38 | static unsigned int cursor = 0; |
|
| 40 | 39 | static unsigned int numlockmask = 0; |
|
| 41 | 40 | static unsigned int mw, mh; |
|
| 42 | 41 | static unsigned long normcol[ColLast]; |
|
| 43 | 42 | static unsigned long selcol[ColLast]; |
|
| 44 | - | static Bool running = True; |
|
| 43 | + | static Bool topbar = True; |
|
| 45 | 44 | static DC dc; |
|
| 46 | 45 | static Display *dpy; |
|
| 47 | 46 | static Window win, root; |
|
| 51 | 50 | cleanupdraw(&dc); |
|
| 52 | 51 | XDestroyWindow(dpy, win); |
|
| 53 | 52 | XUngrabKeyboard(dpy, CurrentTime); |
|
| 53 | + | XCloseDisplay(dpy); |
|
| 54 | 54 | } |
|
| 55 | 55 | ||
| 56 | 56 | void |
|
| 81 | 81 | drawtext(&dc, *text ? text : NULL, normcol, False); |
|
| 82 | 82 | drawcursor(); |
|
| 83 | 83 | XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0); |
|
| 84 | - | XFlush(dpy); |
|
| 85 | 84 | } |
|
| 86 | 85 | ||
| 87 | 86 | Bool |
|
| 200 | 199 | cursor = len; |
|
| 201 | 200 | break; |
|
| 202 | 201 | case XK_Escape: |
|
| 203 | - | ret = 1; |
|
| 204 | - | running = False; |
|
| 205 | - | return; |
|
| 202 | + | exit(EXIT_FAILURE); |
|
| 206 | 203 | case XK_Home: |
|
| 207 | 204 | cursor = 0; |
|
| 208 | 205 | break; |
|
| 214 | 211 | case XK_Return: |
|
| 215 | 212 | fprintf(stdout, "%s", text); |
|
| 216 | 213 | fflush(stdout); |
|
| 217 | - | running = False; |
|
| 218 | - | return; |
|
| 214 | + | exit(EXIT_SUCCESS); |
|
| 219 | 215 | case XK_Right: |
|
| 220 | 216 | if(cursor == len) |
|
| 221 | 217 | return; |
|
| 230 | 226 | XEvent ev; |
|
| 231 | 227 | ||
| 232 | 228 | /* main event loop */ |
|
| 233 | - | while(running && !XNextEvent(dpy, &ev)) |
|
| 229 | + | XSync(dpy, False); |
|
| 230 | + | while(!XNextEvent(dpy, &ev)) |
|
| 234 | 231 | switch(ev.type) { |
|
| 235 | 232 | case KeyPress: |
|
| 236 | 233 | kpress(&ev.xkey); |
|
| 240 | 237 | drawinput(); |
|
| 241 | 238 | break; |
|
| 242 | 239 | case VisibilityNotify: |
|
| 243 | - | if (ev.xvisibility.state != VisibilityUnobscured) |
|
| 240 | + | if(ev.xvisibility.state != VisibilityUnobscured) |
|
| 244 | 241 | XRaiseWindow(dpy, win); |
|
| 245 | 242 | break; |
|
| 246 | 243 | } |
|
| 244 | + | exit(EXIT_FAILURE); |
|
| 247 | 245 | } |
|
| 248 | 246 | ||
| 249 | 247 | void |
|
| 250 | - | setup(Bool topbar) { |
|
| 248 | + | setup(void) { |
|
| 251 | 249 | int i, j, x, y; |
|
| 252 | 250 | #if XINERAMA |
|
| 253 | 251 | int n; |
|
| 320 | 318 | int |
|
| 321 | 319 | main(int argc, char *argv[]) { |
|
| 322 | 320 | unsigned int i; |
|
| 323 | - | Bool topbar = True; |
|
| 324 | 321 | ||
| 325 | 322 | /* command line args */ |
|
| 326 | 323 | progname = "dinput"; |
|
| 364 | 361 | fprintf(stderr, "dinput: warning: no locale support\n"); |
|
| 365 | 362 | if(!(dpy = XOpenDisplay(NULL))) |
|
| 366 | 363 | eprint("cannot open display\n"); |
|
| 364 | + | if(atexit(&cleanup) != 0) |
|
| 365 | + | eprint("cannot register cleanup\n"); |
|
| 367 | 366 | screen = DefaultScreen(dpy); |
|
| 368 | 367 | root = RootWindow(dpy, screen); |
|
| 369 | 368 | ||
| 370 | - | running = grabkeyboard(); |
|
| 371 | - | setup(topbar); |
|
| 372 | - | drawinput(); |
|
| 373 | - | XSync(dpy, False); |
|
| 369 | + | grabkeyboard(); |
|
| 370 | + | setup(); |
|
| 374 | 371 | run(); |
|
| 375 | - | cleanup(); |
|
| 376 | - | XCloseDisplay(dpy); |
|
| 377 | - | return ret; |
|
| 372 | + | return 0; |
|
| 378 | 373 | } |
|
| 36 | 36 | static void drawmenu(void); |
|
| 37 | 37 | static void drawmenuh(void); |
|
| 38 | 38 | static void drawmenuv(void); |
|
| 39 | - | static Bool grabkeyboard(void); |
|
| 39 | + | static void grabkeyboard(void); |
|
| 40 | 40 | static void kpress(XKeyEvent *e); |
|
| 41 | 41 | static void match(char *pattern); |
|
| 42 | 42 | static void readstdin(void); |
|
| 52 | 52 | static char text[4096]; |
|
| 53 | 53 | static int cmdw = 0; |
|
| 54 | 54 | static int promptw = 0; |
|
| 55 | - | static int ret = 0; |
|
| 56 | 55 | static int screen; |
|
| 57 | 56 | static unsigned int lines = 0; |
|
| 58 | 57 | static unsigned int numlockmask = 0; |
|
| 59 | 58 | static unsigned int mw, mh; |
|
| 60 | 59 | static unsigned long normcol[ColLast]; |
|
| 61 | 60 | static unsigned long selcol[ColLast]; |
|
| 62 | - | static Bool running = True; |
|
| 63 | 61 | static Bool topbar = True; |
|
| 64 | 62 | static DC dc; |
|
| 65 | 63 | static Display *dpy; |
|
| 87 | 85 | ||
| 88 | 86 | void |
|
| 89 | 87 | calcoffsetsh(void) { |
|
| 90 | - | unsigned int w; |
|
| 88 | + | unsigned int x; |
|
| 91 | 89 | ||
| 92 | - | w = promptw + cmdw + (2 * spaceitem); |
|
| 90 | + | x = promptw + cmdw + (2 * spaceitem); |
|
| 93 | 91 | for(next = curr; next; next = next->right) |
|
| 94 | - | if((w += MIN(textw(&dc, next->text), mw / 3)) > mw) |
|
| 92 | + | if((x += MIN(textw(&dc, next->text), mw / 3)) > mw) |
|
| 95 | 93 | break; |
|
| 96 | - | w = promptw + cmdw + (2 * spaceitem); |
|
| 94 | + | x = promptw + cmdw + (2 * spaceitem); |
|
| 97 | 95 | for(prev = curr; prev && prev->left; prev = prev->left) |
|
| 98 | - | if((w += MIN(textw(&dc, prev->left->text), mw / 3)) > mw) |
|
| 96 | + | if((x += MIN(textw(&dc, prev->left->text), mw / 3)) > mw) |
|
| 99 | 97 | break; |
|
| 100 | 98 | } |
|
| 101 | 99 | ||
| 146 | 144 | cleanupdraw(&dc); |
|
| 147 | 145 | XDestroyWindow(dpy, win); |
|
| 148 | 146 | XUngrabKeyboard(dpy, CurrentTime); |
|
| 147 | + | XCloseDisplay(dpy); |
|
| 149 | 148 | } |
|
| 150 | 149 | ||
| 151 | 150 | void |
|
| 182 | 181 | else if(curr) |
|
| 183 | 182 | drawmenuh(); |
|
| 184 | 183 | XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0); |
|
| 185 | - | XFlush(dpy); |
|
| 186 | 184 | } |
|
| 187 | 185 | ||
| 188 | 186 | void |
|
| 219 | 217 | XMoveResizeWindow(dpy, win, wa.x, wa.y + (topbar ? 0 : wa.height - mh), mw, mh); |
|
| 220 | 218 | } |
|
| 221 | 219 | ||
| 222 | - | Bool |
|
| 220 | + | void |
|
| 223 | 221 | grabkeyboard(void) { |
|
| 224 | 222 | unsigned int len; |
|
| 225 | 223 | ||
| 229 | 227 | break; |
|
| 230 | 228 | usleep(1000); |
|
| 231 | 229 | } |
|
| 232 | - | return len > 0; |
|
| 230 | + | if(!len) |
|
| 231 | + | exit(EXIT_FAILURE); |
|
| 233 | 232 | } |
|
| 234 | 233 | ||
| 235 | 234 | void |
|
| 326 | 325 | sel = sel->right; |
|
| 327 | 326 | break; |
|
| 328 | 327 | case XK_Escape: |
|
| 329 | - | ret = 1; |
|
| 330 | - | running = False; |
|
| 331 | - | return; |
|
| 328 | + | exit(EXIT_FAILURE); |
|
| 332 | 329 | case XK_Home: |
|
| 333 | 330 | sel = curr = item; |
|
| 334 | 331 | calcoffsets(); |
|
| 360 | 357 | dinput(); |
|
| 361 | 358 | fprintf(stdout, "%s", sel ? sel->text : text); |
|
| 362 | 359 | fflush(stdout); |
|
| 363 | - | running = False; |
|
| 364 | - | return; |
|
| 360 | + | exit(EXIT_SUCCESS); |
|
| 365 | 361 | case XK_Right: |
|
| 366 | 362 | case XK_Down: |
|
| 367 | 363 | if(!sel || !sel->right) |
|
| 454 | 450 | XEvent ev; |
|
| 455 | 451 | ||
| 456 | 452 | /* main event loop */ |
|
| 457 | - | while(running && !XNextEvent(dpy, &ev)) |
|
| 453 | + | XSync(dpy, False); |
|
| 454 | + | while(!XNextEvent(dpy, &ev)) |
|
| 458 | 455 | switch(ev.type) { |
|
| 459 | 456 | case KeyPress: |
|
| 460 | 457 | kpress(&ev.xkey); |
|
| 464 | 461 | drawmenu(); |
|
| 465 | 462 | break; |
|
| 466 | 463 | case VisibilityNotify: |
|
| 467 | - | if (ev.xvisibility.state != VisibilityUnobscured) |
|
| 464 | + | if(ev.xvisibility.state != VisibilityUnobscured) |
|
| 468 | 465 | XRaiseWindow(dpy, win); |
|
| 469 | 466 | break; |
|
| 470 | 467 | } |
|
| 468 | + | exit(EXIT_FAILURE); |
|
| 471 | 469 | } |
|
| 472 | 470 | ||
| 473 | 471 | void |
|
| 586 | 584 | } |
|
| 587 | 585 | else { |
|
| 588 | 586 | fputs("usage: dmenu [-i] [-b] [-l <lines>] [-fn <font>] [-nb <color>]\n" |
|
| 589 | - | " [-nf <color>] [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n", stderr); |
|
| 587 | + | " [-nf <color>] [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n", stderr); |
|
| 590 | 588 | exit(EXIT_FAILURE); |
|
| 591 | 589 | } |
|
| 592 | 590 | if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) |
|
| 593 | 591 | fprintf(stderr, "dmenu: warning: no locale support\n"); |
|
| 594 | 592 | if(!(dpy = XOpenDisplay(NULL))) |
|
| 595 | 593 | eprint("cannot open display\n"); |
|
| 594 | + | if(atexit(&cleanup) != 0) |
|
| 595 | + | eprint("cannot register cleanup\n"); |
|
| 596 | 596 | screen = DefaultScreen(dpy); |
|
| 597 | 597 | root = RootWindow(dpy, screen); |
|
| 598 | 598 | if(!(argp = malloc(sizeof *argp * (argc+2)))) |
|
| 600 | 600 | memcpy(argp + 2, argv + 1, sizeof *argp * argc); |
|
| 601 | 601 | ||
| 602 | 602 | readstdin(); |
|
| 603 | - | running = grabkeyboard(); |
|
| 604 | - | ||
| 603 | + | grabkeyboard(); |
|
| 605 | 604 | setup(); |
|
| 606 | - | drawmenu(); |
|
| 607 | - | XSync(dpy, False); |
|
| 608 | 605 | run(); |
|
| 609 | - | cleanup(); |
|
| 610 | - | XCloseDisplay(dpy); |
|
| 611 | - | return ret; |
|
| 606 | + | return 0; |
|
| 612 | 607 | } |
|