removed -t, now using isatty() instead of select() to prevent execution from an interactive shell
66b2e837
2 file(s) · +15 −31
| 10 | 10 | .RB [ \-p " <prompt>"] |
|
| 11 | 11 | .RB [ \-sb " <color>"] |
|
| 12 | 12 | .RB [ \-sf " <color>"] |
|
| 13 | - | .RB [ \-t " <seconds>"] |
|
| 14 | 13 | .RB [ \-v ] |
|
| 15 | 14 | .SH DESCRIPTION |
|
| 16 | 15 | .SS Overview |
|
| 40 | 39 | .TP |
|
| 41 | 40 | .B \-sf <color> |
|
| 42 | 41 | defines the selected foreground color (#RGB, #RRGGBB, and color names are supported). |
|
| 43 | - | .TP |
|
| 44 | - | .B \-t <seconds> |
|
| 45 | - | defines the seconds to wait for standard input, before exiting (default is 3). |
|
| 46 | 42 | .TP |
|
| 47 | 43 | .B \-v |
|
| 48 | 44 | prints version information to standard output, then exits. |
|
| 10 | 10 | #include <stdio.h> |
|
| 11 | 11 | #include <string.h> |
|
| 12 | 12 | #include <unistd.h> |
|
| 13 | - | #include <sys/select.h> |
|
| 14 | - | #include <sys/time.h> |
|
| 15 | 13 | #include <X11/Xutil.h> |
|
| 16 | 14 | #include <X11/keysym.h> |
|
| 17 | 15 | ||
| 457 | 455 | return maxname; |
|
| 458 | 456 | } |
|
| 459 | 457 | ||
| 458 | + | static void |
|
| 459 | + | usage(void) { |
|
| 460 | + | eprint("usage: dmenu [-b] [-fn <font>] [-nb <color>] [-nf <color>]\n" |
|
| 461 | + | " [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n"); |
|
| 462 | + | } |
|
| 463 | + | ||
| 460 | 464 | /* extern */ |
|
| 461 | 465 | ||
| 462 | 466 | int screen; |
|
| 472 | 476 | char *normfg = NORMFGCOLOR; |
|
| 473 | 477 | char *selbg = SELBGCOLOR; |
|
| 474 | 478 | char *selfg = SELFGCOLOR; |
|
| 475 | - | fd_set rd; |
|
| 476 | 479 | int i, j; |
|
| 477 | - | struct timeval timeout; |
|
| 478 | 480 | Item *itm; |
|
| 479 | 481 | XEvent ev; |
|
| 480 | 482 | XModifierKeymap *modmap; |
|
| 481 | 483 | XSetWindowAttributes wa; |
|
| 482 | 484 | ||
| 483 | - | timeout.tv_usec = 0; |
|
| 484 | - | timeout.tv_sec = 3; |
|
| 485 | + | if(isatty(STDIN_FILENO)) { |
|
| 486 | + | fputs("error: dmenu can't run in an interactive shell\n", stdout); |
|
| 487 | + | usage(); |
|
| 488 | + | } |
|
| 485 | 489 | /* command line args */ |
|
| 486 | 490 | for(i = 1; i < argc; i++) |
|
| 487 | 491 | if(!strncmp(argv[i], "-b", 3)) { |
|
| 505 | 509 | else if(!strncmp(argv[i], "-sf", 4)) { |
|
| 506 | 510 | if(++i < argc) selfg = argv[i]; |
|
| 507 | 511 | } |
|
| 508 | - | else if(!strncmp(argv[i], "-t", 3)) { |
|
| 509 | - | if(++i < argc) timeout.tv_sec = atoi(argv[i]); |
|
| 510 | - | } |
|
| 511 | - | else if(!strncmp(argv[i], "-v", 3)) { |
|
| 512 | - | fputs("dmenu-"VERSION", (C)opyright MMVI-MMVII Anselm R. Garbe\n", stdout); |
|
| 513 | - | exit(EXIT_SUCCESS); |
|
| 514 | - | } |
|
| 512 | + | else if(!strncmp(argv[i], "-v", 3)) |
|
| 513 | + | eprint("dmenu-"VERSION", (C)opyright MMVI-MMVII Anselm R. Garbe\n"); |
|
| 515 | 514 | else |
|
| 516 | - | eprint("usage: dmenu [-b] [-fn <font>] [-nb <color>] [-nf <color>] [-p <prompt>]\n" |
|
| 517 | - | " [-sb <color>] [-sf <color>] [-t <seconds>] [-v]\n", stdout); |
|
| 515 | + | usage(); |
|
| 518 | 516 | setlocale(LC_CTYPE, ""); |
|
| 519 | 517 | dpy = XOpenDisplay(0); |
|
| 520 | 518 | if(!dpy) |
|
| 521 | 519 | eprint("dmenu: cannot open display\n"); |
|
| 522 | 520 | screen = DefaultScreen(dpy); |
|
| 523 | 521 | root = RootWindow(dpy, screen); |
|
| 524 | - | ||
| 525 | - | /* Note, the select() construction allows to grab all keypresses as |
|
| 526 | - | * early as possible, to not loose them. But if there is no standard |
|
| 527 | - | * input supplied, we will make sure to exit after MAX_WAIT_STDIN |
|
| 528 | - | * seconds. This is convenience behavior for rapid typers. |
|
| 529 | - | */ |
|
| 530 | 522 | while(XGrabKeyboard(dpy, root, True, GrabModeAsync, |
|
| 531 | 523 | GrabModeAsync, CurrentTime) != GrabSuccess) |
|
| 532 | 524 | usleep(1000); |
|
| 533 | - | FD_ZERO(&rd); |
|
| 534 | - | FD_SET(STDIN_FILENO, &rd); |
|
| 535 | - | if(select(ConnectionNumber(dpy) + 1, &rd, NULL, NULL, &timeout) < 1) |
|
| 536 | - | goto UninitializedEnd; |
|
| 537 | 525 | maxname = readstdin(); |
|
| 538 | 526 | /* init modifier map */ |
|
| 539 | 527 | modmap = XGetModifierMapping(dpy); |
|
| 540 | 528 | for (i = 0; i < 8; i++) { |
|
| 541 | 529 | for (j = 0; j < modmap->max_keypermod; j++) { |
|
| 542 | - | if(modmap->modifiermap[i * modmap->max_keypermod + j] == XKeysymToKeycode(dpy, XK_Num_Lock)) |
|
| 530 | + | if(modmap->modifiermap[i * modmap->max_keypermod + j] |
|
| 531 | + | == XKeysymToKeycode(dpy, XK_Num_Lock)) |
|
| 543 | 532 | numlockmask = (1 << i); |
|
| 544 | 533 | } |
|
| 545 | 534 | } |
|
| 607 | 596 | XFreePixmap(dpy, dc.drawable); |
|
| 608 | 597 | XFreeGC(dpy, dc.gc); |
|
| 609 | 598 | XDestroyWindow(dpy, win); |
|
| 610 | - | UninitializedEnd: |
|
| 611 | 599 | XUngrabKeyboard(dpy, CurrentTime); |
|
| 612 | 600 | XCloseDisplay(dpy); |
|
| 613 | 601 | return ret; |
|