dwmblocks.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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. typedef struct {
  10. char* icon;
  11. char* command;
  12. unsigned int interval;
  13. unsigned int signal;
  14. } Block;
  15. void dummysighandler(int num);
  16. void sighandler(int num);
  17. void getcmds(int time);
  18. #ifndef __OpenBSD__
  19. void getsigcmds(int signal);
  20. void setupsignals();
  21. void sighandler(int signum);
  22. #endif
  23. int getstatus(char *str, char *last);
  24. void setroot();
  25. void statusloop();
  26. void termhandler(int signum);
  27. #include "blocks.h"
  28. static Display *dpy;
  29. static int screen;
  30. static Window root;
  31. static char statusbar[LENGTH(blocks)][CMDLENGTH] = {0};
  32. static char statusstr[2][256];
  33. static int statusContinue = 1;
  34. static void (*writestatus) () = setroot;
  35. //opens process *cmd and stores output in *output
  36. void getcmd(const Block *block, char *output)
  37. {
  38. strcpy(output, block->icon);
  39. char *cmd = block->command;
  40. FILE *cmdf = popen(cmd,"r");
  41. if (!cmdf)
  42. return;
  43. char c;
  44. int i = strlen(block->icon);
  45. fgets(output+i, CMDLENGTH-i, cmdf);
  46. i = strlen(output);
  47. if (delim != '\0' && --i)
  48. output[i++] = delim;
  49. output[i++] = '\0';
  50. pclose(cmdf);
  51. }
  52. void getcmds(int time)
  53. {
  54. const Block* current;
  55. for(int i = 0; i < LENGTH(blocks); i++)
  56. {
  57. current = blocks + i;
  58. if ((current->interval != 0 && time % current->interval == 0) || time == -1)
  59. getcmd(current,statusbar[i]);
  60. }
  61. }
  62. #ifndef __OpenBSD__
  63. void getsigcmds(int signal)
  64. {
  65. const Block *current;
  66. for (int i = 0; i < LENGTH(blocks); i++)
  67. {
  68. current = blocks + i;
  69. if (current->signal == signal)
  70. getcmd(current,statusbar[i]);
  71. }
  72. }
  73. void setupsignals()
  74. {
  75. /* initialize all real time signals with dummy handler */
  76. for(int i = SIGRTMIN; i <= SIGRTMAX; i++)
  77. signal(i, dummysighandler);
  78. for(int i = 0; i < LENGTH(blocks); i++)
  79. {
  80. if (blocks[i].signal > 0)
  81. signal(SIGRTMIN+blocks[i].signal, sighandler);
  82. }
  83. }
  84. #endif
  85. int getstatus(char *str, char *last)
  86. {
  87. strcpy(last, str);
  88. str[0] = '\0';
  89. for(int i = 0; i < LENGTH(blocks); i++)
  90. strcat(str, statusbar[i]);
  91. str[strlen(str)-1] = '\0';
  92. return strcmp(str, last);//0 if they are the same
  93. }
  94. void setroot()
  95. {
  96. if (!getstatus(statusstr[0], statusstr[1]))//Only set root if text has changed.
  97. return;
  98. Display *d = XOpenDisplay(NULL);
  99. if (d) {
  100. dpy = d;
  101. }
  102. screen = DefaultScreen(dpy);
  103. root = RootWindow(dpy, screen);
  104. XStoreName(dpy, root, statusstr[0]);
  105. XCloseDisplay(dpy);
  106. }
  107. void pstdout()
  108. {
  109. if (!getstatus(statusstr[0], statusstr[1]))//Only write out if text has changed.
  110. return;
  111. printf("%s\n",statusstr[0]);
  112. fflush(stdout);
  113. }
  114. void statusloop()
  115. {
  116. #ifndef __OpenBSD__
  117. setupsignals();
  118. #endif
  119. int i = 0;
  120. getcmds(-1);
  121. while(statusContinue)
  122. {
  123. getcmds(i);
  124. writestatus();
  125. sleep(1.0);
  126. i++;
  127. }
  128. }
  129. #ifndef __OpenBSD__
  130. /* this signal handler should do nothing */
  131. void dummysighandler(int signum)
  132. {
  133. return;
  134. }
  135. #endif
  136. #ifndef __OpenBSD__
  137. void sighandler(int signum)
  138. {
  139. getsigcmds(signum-SIGRTMIN);
  140. writestatus();
  141. }
  142. #endif
  143. void termhandler(int signum)
  144. {
  145. statusContinue = 0;
  146. exit(0);
  147. }
  148. int main(int argc, char** argv)
  149. {
  150. for(int i = 0; i < argc; i++)
  151. {
  152. if (!strcmp("-d",argv[i]))
  153. delim = argv[++i][0];
  154. else if(!strcmp("-p",argv[i]))
  155. writestatus = pstdout;
  156. }
  157. signal(SIGTERM, termhandler);
  158. signal(SIGINT, termhandler);
  159. statusloop();
  160. }