apoorv569

dwmblocks.c (DWM)

Jun 5th, 2020
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.87 KB | None | 0 0
  1. #include<stdlib.h>
  2. #include<stdio.h>
  3. #include<string.h>
  4. #include<unistd.h>
  5. #include<signal.h>
  6. #include<X11/Xlib.h>
  7. #define LENGTH(X)               (sizeof(X) / sizeof (X[0]))
  8. #define CMDLENGTH       50
  9.  
  10. typedef struct {
  11.     char* icon;
  12.     char* command;
  13.     unsigned int interval;
  14.     unsigned int signal;
  15. } Block;
  16. void sighandler(int num);
  17. void buttonhandler(int sig, siginfo_t *si, void *ucontext);
  18. void getcmds(int time);
  19. #ifndef __OpenBSD__
  20. void getsigcmds(int signal);
  21. void setupsignals();
  22. void sighandler(int signum);
  23. #endif
  24. int getstatus(char *str, char *last);
  25. void setroot();
  26. void statusloop();
  27. void termhandler(int signum);
  28.  
  29.  
  30. #include "blocks.h"
  31.  
  32. static Display *dpy;
  33. static int screen;
  34. static Window root;
  35. static char statusbar[LENGTH(blocks)][CMDLENGTH] = {0};
  36. static char statusstr[2][256];
  37. static char button[] = "\0";
  38. static int statusContinue = 1;
  39. static void (*writestatus) () = setroot;
  40.  
  41. //opens process *cmd and stores output in *output
  42. void getcmd(const Block *block, char *output)
  43. {
  44.     if (block->signal)
  45.     {
  46.         output[0] = block->signal;
  47.         output++;
  48.     }
  49.     strcpy(output, block->icon);
  50.     char *cmd = block->command;
  51.     FILE *cmdf;
  52.     if (*button)
  53.     {
  54.         setenv("BUTTON", button, 1);
  55.         cmdf = popen(cmd,"r");
  56.         *button = '\0';
  57.         unsetenv("BUTTON");
  58.     }
  59.     else
  60.     {
  61.         cmdf = popen(cmd,"r");
  62.     }
  63.     if (!cmdf)
  64.         return;
  65.     char c;
  66.     int i = strlen(block->icon);
  67.     fgets(output+i, CMDLENGTH-i, cmdf);
  68.     i = strlen(output);
  69.     if (delim != '\0' && --i)
  70.         output[i++] = delim;
  71.     output[i++] = '\0';
  72.     pclose(cmdf);
  73. }
  74.  
  75. void getcmds(int time)
  76. {
  77.     const Block* current;
  78.     for(int i = 0; i < LENGTH(blocks); i++)
  79.     {  
  80.         current = blocks + i;
  81.         if ((current->interval != 0 && time % current->interval == 0) || time == -1)
  82.             getcmd(current,statusbar[i]);
  83.     }
  84. }
  85.  
  86. #ifndef __OpenBSD__
  87. void getsigcmds(int signal)
  88. {
  89.     const Block *current;
  90.     for (int i = 0; i < LENGTH(blocks); i++)
  91.     {
  92.         current = blocks + i;
  93.         if (current->signal == signal)
  94.             getcmd(current,statusbar[i]);
  95.     }
  96. }
  97.  
  98. void setupsignals()
  99. {
  100.     struct sigaction sa;
  101.     for(int i = 0; i < LENGTH(blocks); i++)
  102.     {    
  103.         if (blocks[i].signal > 0)
  104.         {
  105.             signal(SIGRTMIN+blocks[i].signal, sighandler);
  106.             sigaddset(&sa.sa_mask, SIGRTMIN+blocks[i].signal); // ignore signal when handling SIGUSR1
  107.         }
  108.     }
  109.     sa.sa_sigaction = buttonhandler;
  110.     sa.sa_flags = SA_SIGINFO;
  111.     sigaction(SIGUSR1, &sa, NULL);
  112. }
  113. #endif
  114.  
  115. int getstatus(char *str, char *last)
  116. {
  117.     strcpy(last, str);
  118.     str[0] = '\0';
  119.     for(int i = 0; i < LENGTH(blocks); i++)
  120.         strcat(str, statusbar[i]);
  121.     str[strlen(str)-1] = '\0';
  122.     return strcmp(str, last);//0 if they are the same
  123. }
  124.  
  125. void setroot()
  126. {
  127.     if (!getstatus(statusstr[0], statusstr[1]))//Only set root if text has changed.
  128.         return;
  129.     Display *d = XOpenDisplay(NULL);
  130.     if (d) {
  131.         dpy = d;
  132.     }
  133.     screen = DefaultScreen(dpy);
  134.     root = RootWindow(dpy, screen);
  135.     XStoreName(dpy, root, statusstr[0]);
  136.     XCloseDisplay(dpy);
  137. }
  138.  
  139. void pstdout()
  140. {
  141.     if (!getstatus(statusstr[0], statusstr[1]))//Only write out if text has changed.
  142.         return;
  143.     printf("%s\n",statusstr[0]);
  144.     fflush(stdout);
  145. }
  146.  
  147.  
  148. void statusloop()
  149. {
  150. #ifndef __OpenBSD__
  151.     setupsignals();
  152. #endif
  153.     int i = 0;
  154.     getcmds(-1);
  155.     while(statusContinue)
  156.     {
  157.         getcmds(i);
  158.         writestatus();
  159.         sleep(1.0);
  160.         i++;
  161.     }
  162. }
  163.  
  164. #ifndef __OpenBSD__
  165. void sighandler(int signum)
  166. {
  167.     getsigcmds(signum-SIGRTMIN);
  168.     writestatus();
  169. }
  170.  
  171. void buttonhandler(int sig, siginfo_t *si, void *ucontext)
  172. {
  173.     *button = '0' + si->si_value.sival_int & 0xff;
  174.     getsigcmds(si->si_value.sival_int >> 8);
  175.     writestatus();
  176. }
  177. #endif
  178.  
  179. void termhandler(int signum)
  180. {
  181.     statusContinue = 0;
  182.     exit(0);
  183. }
  184.  
  185. int main(int argc, char** argv)
  186. {
  187.     for(int i = 0; i < argc; i++)
  188.     {  
  189.         if (!strcmp("-d",argv[i]))
  190.             delim = argv[++i][0];
  191.         else if(!strcmp("-p",argv[i]))
  192.             writestatus = pstdout;
  193.     }
  194.     signal(SIGTERM, termhandler);
  195.     signal(SIGINT, termhandler);
  196.     statusloop();
  197. }
Add Comment
Please, Sign In to add comment