dmenu-qalc-5.2.diff - sites - public wiki contents of suckless.org
 (HTM) git clone git://git.suckless.org/sites
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       dmenu-qalc-5.2.diff (6671B)
       ---
            1 diff -up dmenu-5.2/config.mk dmenu-qalc-5.2/config.mk
            2 --- dmenu-5.2/config.mk        2022-10-04 13:36:58.000000000 -0400
            3 +++ dmenu-qalc-5.2/config.mk        2023-10-27 19:29:48.197693355 -0400
            4 @@ -24,7 +24,7 @@ INCS = -I$(X11INC) -I$(FREETYPEINC)
            5  LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS)
            6  
            7  # flags
            8 -CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS)
            9 +CPPFLAGS = -D_DEFAULT_SOURCE -D_GNU_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS)
           10  CFLAGS   = -std=c99 -pedantic -Wall -Os $(INCS) $(CPPFLAGS)
           11  LDFLAGS  = $(LIBS)
           12  
           13 diff -up dmenu-5.2/dmenu.1 dmenu-qalc-5.2/dmenu.1
           14 --- dmenu-5.2/dmenu.1        2022-10-04 13:36:58.000000000 -0400
           15 +++ dmenu-qalc-5.2/dmenu.1        2023-10-27 19:28:48.676578875 -0400
           16 @@ -40,6 +40,9 @@ which lists programs in the user's $PATH
           17  .B \-b
           18  dmenu appears at the bottom of the screen.
           19  .TP
           20 +.B \-C
           21 +dmenu becomes a calculator.
           22 +.TP
           23  .B \-f
           24  dmenu grabs the keyboard before reading stdin if not reading from a tty. This
           25  is faster, but will lock up X until stdin reaches end\-of\-file.
           26 diff -up dmenu-5.2/dmenu.c dmenu-qalc-5.2/dmenu.c
           27 --- dmenu-5.2/dmenu.c        2022-10-04 13:36:58.000000000 -0400
           28 +++ dmenu-qalc-5.2/dmenu.c        2023-10-27 20:00:21.438467597 -0400
           29 @@ -7,6 +7,11 @@
           30  #include <strings.h>
           31  #include <time.h>
           32  #include <unistd.h>
           33 +#include <errno.h>
           34 +#include <fcntl.h>
           35 +#include <signal.h>
           36 +#include <sys/prctl.h>
           37 +#include <sys/select.h>
           38  
           39  #include <X11/Xlib.h>
           40  #include <X11/Xatom.h>
           41 @@ -34,6 +39,12 @@ struct item {
           42          int out;
           43  };
           44  
           45 +static struct {
           46 +  pid_t pid;
           47 +  int enable, in[2], out[2];
           48 +  char buf[256];
           49 +} qalc;
           50 +
           51  static char text[BUFSIZ] = "";
           52  static char *embed;
           53  static int bh, mw, mh;
           54 @@ -228,8 +239,81 @@ grabkeyboard(void)
           55  }
           56  
           57  static void
           58 +init_qalc(void)
           59 +{
           60 +  pipe(qalc.in);
           61 +  pipe2(qalc.out, O_NONBLOCK);
           62 +  qalc.pid = fork();
           63 +  if (qalc.pid == -1)
           64 +    die("failed to fork for qalc");
           65 +  if (qalc.pid == 0) {
           66 +    dup2(qalc.in[0], STDIN_FILENO);
           67 +    dup2(qalc.out[1], STDOUT_FILENO);
           68 +    close(qalc.in[1]);
           69 +    close(qalc.out[0]);
           70 +    prctl(PR_SET_PDEATHSIG, SIGTERM);
           71 +    execl("/usr/bin/qalc", "qalc", "-c0", "-t", NULL);
           72 +    die ("execl qalc failed");
           73 +  } else { // parent
           74 +    close(qalc.in[0]);
           75 +    close(qalc.out[1]);
           76 +    items = malloc(sizeof(struct item)*2);
           77 +    items[0].text = malloc(LENGTH(qalc.buf));
           78 +    strcpy(items[0].text, "no result");
           79 +    items[1].out = 0;
           80 +    items[1].text = NULL;
           81 +  }
           82 +}
           83 +
           84 +static void
           85 +recv_qalc(void)
           86 +{
           87 +  ssize_t r = read(qalc.out[0], qalc.buf, LENGTH(qalc.buf));
           88 +
           89 +  if (r < 0)
           90 +    die("error reading qalc.out");
           91 +
           92 +  if (qalc.buf[0] == '\n') {
           93 +    int i;
           94 +    for (i = 3; i < LENGTH(qalc.buf) && qalc.buf[i] != '\n'; ++i)
           95 +      items[0].text[i-3] = qalc.buf[i];
           96 +    items[0].text[i-3] = 0;
           97 +    if (r != LENGTH(qalc.buf))
           98 +      return;
           99 +  }
          100 +
          101 +  while (read(qalc.out[0], qalc.buf, LENGTH(qalc.buf)) != -1)
          102 +    ; // empty the pipe
          103 +  if (errno != EAGAIN && errno != EWOULDBLOCK)
          104 +    die("error emptying qalc.out");
          105 +}
          106 +
          107 +static void
          108 +send_qalc(void)
          109 +{
          110 +  int s = strlen(text);
          111 +  text[s] = '\n';
          112 +  write(qalc.in[1], text, s+1);
          113 +  text[s] = 0;
          114 +}
          115 +
          116 +static void
          117 +match_qalc(void)
          118 +{
          119 +  matches = matchend = NULL;
          120 +  appenditem(items, &matches, &matchend);
          121 +  curr = sel = matches;
          122 +  calcoffsets();
          123 +}
          124 +
          125 +static void
          126  match(void)
          127  {
          128 +  if (qalc.enable) {
          129 +    match_qalc();
          130 +    return;
          131 +  }
          132 +
          133          static char **tokv = NULL;
          134          static int tokn = 0;
          135  
          136 @@ -524,6 +608,9 @@ insert:
          137                  break;
          138          }
          139  
          140 +  if (qalc.enable)
          141 +    send_qalc();
          142 +
          143  draw:
          144          drawmenu();
          145  }
          146 @@ -573,37 +660,52 @@ run(void)
          147  {
          148          XEvent ev;
          149  
          150 -        while (!XNextEvent(dpy, &ev)) {
          151 -                if (XFilterEvent(&ev, win))
          152 -                        continue;
          153 -                switch(ev.type) {
          154 -                case DestroyNotify:
          155 -                        if (ev.xdestroywindow.window != win)
          156 -                                break;
          157 -                        cleanup();
          158 -                        exit(1);
          159 -                case Expose:
          160 -                        if (ev.xexpose.count == 0)
          161 -                                drw_map(drw, win, 0, 0, mw, mh);
          162 -                        break;
          163 -                case FocusIn:
          164 -                        /* regrab focus from parent window */
          165 -                        if (ev.xfocus.window != win)
          166 -                                grabfocus();
          167 -                        break;
          168 -                case KeyPress:
          169 -                        keypress(&ev.xkey);
          170 -                        break;
          171 -                case SelectionNotify:
          172 -                        if (ev.xselection.property == utf8)
          173 -                                paste();
          174 -                        break;
          175 -                case VisibilityNotify:
          176 -                        if (ev.xvisibility.state != VisibilityUnobscured)
          177 -                                XRaiseWindow(dpy, win);
          178 -                        break;
          179 -                }
          180 -        }
          181 +  fd_set rfds;
          182 +  int xfd = ConnectionNumber(dpy);
          183 +
          184 +  for (;;) {
          185 +    FD_ZERO(&rfds);
          186 +    FD_SET(xfd, &rfds);
          187 +    FD_SET(qalc.out[0], &rfds);
          188 +
          189 +    if (select(MAX(xfd, qalc.out[0])+1, &rfds, NULL, NULL, NULL) > 0) {
          190 +      if (qalc.enable && FD_ISSET(qalc.out[0], &rfds)) {
          191 +        recv_qalc();
          192 +        drawmenu();
          193 +      }
          194 +      while (XPending(dpy) && !XNextEvent(dpy, &ev)) {
          195 +        if (XFilterEvent(&ev, win))
          196 +          continue;
          197 +        switch(ev.type) {
          198 +          case DestroyNotify:
          199 +            if (ev.xdestroywindow.window != win)
          200 +              break;
          201 +            cleanup();
          202 +            exit(1);
          203 +          case Expose:
          204 +            if (ev.xexpose.count == 0)
          205 +              drw_map(drw, win, 0, 0, mw, mh);
          206 +            break;
          207 +          case FocusIn:
          208 +            /* regrab focus from parent window */
          209 +            if (ev.xfocus.window != win)
          210 +              grabfocus();
          211 +            break;
          212 +          case KeyPress:
          213 +            keypress(&ev.xkey);
          214 +            break;
          215 +          case SelectionNotify:
          216 +            if (ev.xselection.property == utf8)
          217 +              paste();
          218 +            break;
          219 +          case VisibilityNotify:
          220 +            if (ev.xvisibility.state != VisibilityUnobscured)
          221 +              XRaiseWindow(dpy, win);
          222 +            break;
          223 +        }
          224 +      }
          225 +    }
          226 +  }
          227  }
          228  
          229  static void
          230 @@ -710,7 +812,7 @@ setup(void)
          231  static void
          232  usage(void)
          233  {
          234 -        die("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
          235 +        die("usage: dmenu [-bCfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
          236              "             [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]");
          237  }
          238  
          239 @@ -727,6 +829,8 @@ main(int argc, char *argv[])
          240                          exit(0);
          241                  } else if (!strcmp(argv[i], "-b")) /* appears at the bottom of the screen */
          242                          topbar = 0;
          243 +                else if (!strcmp(argv[i], "-C"))   /* grabs keyboard before reading stdin */
          244 +                        qalc.enable = 1;
          245                  else if (!strcmp(argv[i], "-f"))   /* grabs keyboard before reading stdin */
          246                          fast = 1;
          247                  else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */
          248 @@ -777,7 +881,10 @@ main(int argc, char *argv[])
          249                  die("pledge");
          250  #endif
          251  
          252 -        if (fast && !isatty(0)) {
          253 +        if (qalc.enable) {
          254 +                init_qalc();
          255 +                grabkeyboard();
          256 +        } else if (fast && !isatty(0)) {
          257                  grabkeyboard();
          258                  readstdin();
          259          } else {