dwmblocks.c 3.2 KB

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