dwmblocks.c 2.9 KB

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