You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

175 lines
3.1 KiB

  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. void getstatus(char *str);
  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[256];
  31. static char *statuscat;
  32. static const char *volupcmd[] = { "volup", NULL };
  33. static const char *voldowncmd[] = { "voldown", NULL };
  34. static const char *volmutecmd[] = { "volmute", NULL };
  35. static int statusContinue = 1,volmuted = 0;
  36. void replace(char *str, char old, char new)
  37. {
  38. int N = strlen(str);
  39. for(int i = 0; i < N; i++)
  40. if(str[i] == old)
  41. str[i] = new;
  42. }
  43. //opens process *cmd and stores output in *output
  44. void getcmd(const Block *block, char *output)
  45. {
  46. strcpy(output, block->icon);
  47. char *cmd = block->command;
  48. FILE *cmdf = popen(cmd,"r");
  49. if (!cmdf)
  50. return;
  51. //int N = strlen(output);
  52. char c;
  53. int sl;
  54. int i = sl = strlen(block->icon);
  55. while((c = fgetc(cmdf)) != EOF)
  56. output[i++] = c;
  57. pclose(cmdf);
  58. if (i == sl) { //return empty string if command has no output
  59. output[0] = '\0';
  60. return;
  61. }
  62. if (delim[0] != '\0' && --i)
  63. for (int j = 0; delim[j]; j++)
  64. output[i++] = delim[j];
  65. else
  66. output[--i] = '\0';
  67. }
  68. void getcmds(int time)
  69. {
  70. const Block* current;
  71. for(int i = 0; i < LENGTH(blocks); i++)
  72. {
  73. current = blocks + i;
  74. if ((current->interval != 0 && time % current->interval == 0) || time == -1)
  75. getcmd(current,statusbar[i]);
  76. }
  77. }
  78. void getsigcmds(int signal)
  79. {
  80. const Block *current;
  81. for (int i = 0; i < LENGTH(blocks); i++)
  82. {
  83. current = blocks + i;
  84. if (current->signal == signal)
  85. getcmd(current,statusbar[i]);
  86. }
  87. }
  88. void setupsignals()
  89. {
  90. for(int i = 0; i < LENGTH(blocks); i++)
  91. {
  92. if (blocks[i].signal > 0)
  93. signal(SIGRTMIN+blocks[i].signal, sighandler);
  94. }
  95. }
  96. void getstatus(char *str)
  97. {
  98. int j = 0;
  99. for(int i = 0; i < LENGTH(blocks); j+=strlen(statusbar[i++]))
  100. {
  101. strcpy(str + j, statusbar[i]);
  102. }
  103. for (int i = 0; delim[i]; i++)
  104. str[--j] = '\0';
  105. }
  106. void setroot()
  107. {
  108. Display *d = XOpenDisplay(NULL);
  109. if (d) {
  110. dpy = d;
  111. }
  112. screen = DefaultScreen(dpy);
  113. root = RootWindow(dpy, screen);
  114. getstatus(statusstr);
  115. XStoreName(dpy, root, statusstr);
  116. XCloseDisplay(dpy);
  117. }
  118. void statusloop()
  119. {
  120. setupsignals();
  121. int i = 0;
  122. getcmds(-1);
  123. while(statusContinue)
  124. {
  125. getcmds(i);
  126. setroot();
  127. sleep(1.0);
  128. i++;
  129. }
  130. }
  131. void statusinit()
  132. {
  133. statusloop();
  134. }
  135. void sighandler(int signum)
  136. {
  137. getsigcmds(signum-SIGRTMIN);
  138. setroot();
  139. }
  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];
  151. }
  152. signal(SIGTERM, termhandler);
  153. signal(SIGINT, termhandler);
  154. statusinit();
  155. }