wmload: Add more missing headers.
[dockapps.git] / wmload / wmload.c
bloba7743ce0f192a6a3976f815c2421867f36ad02e7
1 #include <ctype.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <unistd.h>
6 #include <X11/Xlib.h>
7 #include <X11/xpm.h>
8 #include <X11/extensions/shape.h>
9 #include <time.h>
10 #include <math.h>
11 #include <fcntl.h>
12 #include <X11/Xatom.h>
14 #include "back.xpm"
15 #include "mask2.xbm"
16 #include "mask.xpm"
18 #define major_VER 0
19 #define minor_VER 9
20 #define patch_VER 2
21 #define MW_EVENTS (ExposureMask | ButtonPressMask | StructureNotifyMask)
22 #define FALSE 0
23 #define Shape(num) (ONLYSHAPE ? num-5 : num)
24 #define NCPUSTATES 4
26 /* Global Data storage/structures ********************************************/
27 static long cp_time[NCPUSTATES];
28 static long last[NCPUSTATES];
29 int ONLYSHAPE=0; /* default value is noshape */
30 int updatespeed = 4;
31 static char *help_message[] = {
32 "where options include:",
33 " -u <secs> updatespeed",
34 " -exe <program> program to start on click",
35 " -led <color> color of the led",
36 " -position [+|-]x[+|-]y position of wmload",
37 " -shape without groundplate",
38 " -iconic start up as icon",
39 " -withdrawn start up withdrawn",
40 " -ver output version",
41 NULL
44 /* X11 Variables *************************************************************/
45 Display *dpy; /* welches DISPLAY */
46 Window Root; /* Hintergrund-Drawable */
47 int screen;
48 int x_fd;
49 int d_depth;
50 XSizeHints mysizehints;
51 XWMHints mywmhints;
52 Pixel back_pix, fore_pix;
53 GC NormalGC;
54 Window iconwin, win; /* My home is my window */
55 char *ProgName;
56 char *Geometry;
57 char *LedColor = "LightSeaGreen";
58 char Execute[] = "echo no program has been specified >/dev/console";
59 char *ERR_colorcells = "not enough free color cells\n";
60 char *ampers = " &";
62 /* XPM Structures & Variables ************************************************/
63 typedef struct _XpmIcon {
64 Pixmap pixmap;
65 Pixmap mask;
66 XpmAttributes attributes;
67 } XpmIcon;
69 XpmIcon wmload;
70 XpmIcon visible;
71 time_t actualtime;
72 long actualmin;
74 /* Function definitions ******************************************************/
75 void GetXPM(void);
76 Pixel GetColor(char *name);
77 void RedrawWindow( XpmIcon *v);
78 void InitLoad();
79 void InsertLoad();
81 /*****************************************************************************/
82 /* Source Code <--> Function Implementations */
83 /*****************************************************************************/
84 void usage()
86 char **cpp;
88 fprintf(stderr,"\nusage: %s [-options ...] \n", ProgName);
89 for (cpp = help_message; *cpp; cpp++) {
90 fprintf(stderr, "%s\n", *cpp);
92 fprintf(stderr,"\n");
93 exit(1);
96 int main(int argc,char *argv[])
98 int i;
99 unsigned int borderwidth ;
100 char *display_name = NULL;
101 char *wname = "wmload";
102 XGCValues gcv;
103 unsigned long gcm;
104 XEvent Event;
105 XTextProperty name;
106 XClassHint classHint;
107 Pixmap pixmask;
108 Geometry = "";
109 mywmhints.initial_state = NormalState;
111 /* Parse command line options */
112 ProgName = argv[0];
114 for(i=1;i<argc;i++) {
115 char *arg= argv[i];
117 if (arg[0] == '-') {
118 switch(arg[1]) {
119 case 'u':
120 if(++i >=argc) usage();
121 sscanf(argv[i], "%d", &updatespeed);
122 continue;
123 case 'e':
124 if(++i >=argc) usage();
125 strcpy(&Execute[0], argv[i]);
126 strcat(&Execute[0], " &");
127 continue;
128 case 's':
129 ONLYSHAPE=1;
130 continue;
131 case 'p':
132 if(++i >=argc) usage();
133 Geometry = argv[i];
134 continue;
135 case 'i':
136 mywmhints.initial_state = IconicState;
137 continue;
138 case 'w':
139 mywmhints.initial_state = WithdrawnState;
140 continue;
141 case 'l':
142 if(++i >=argc) usage();
143 LedColor = argv[i];
144 continue;
145 case 'v':
146 fprintf(stdout, "\nwmload version: %i.%i.%i\n", major_VER, minor_VER, patch_VER);
147 if(argc == 2) exit(0);
148 continue;
149 default:
150 usage();
153 else
155 fprintf(stderr, "\nInvalid argument: %s\n", arg);
156 usage();
160 /* Open the display */
161 if (!(dpy = XOpenDisplay(display_name)))
163 fprintf(stderr,"wmload: can't open display %s\n",
164 XDisplayName(display_name));
165 exit (1);
168 screen= DefaultScreen(dpy);
169 Root = RootWindow(dpy, screen);
170 d_depth = DefaultDepth(dpy, screen);
171 x_fd = XConnectionNumber(dpy);
173 /* Convert XPM Data to XImage */
174 GetXPM();
176 /* Create a window to hold the banner */
177 mysizehints.flags= USSize|USPosition;
178 mysizehints.x = 0;
179 mysizehints.y = 0;
181 back_pix = GetColor("white");
182 fore_pix = GetColor("black");
184 XWMGeometry(dpy, screen, Geometry, NULL, (borderwidth =1), &mysizehints,
185 &mysizehints.x,&mysizehints.y,&mysizehints.width,&mysizehints.height, &i);
187 mysizehints.width = wmload.attributes.width;
188 mysizehints.height= wmload.attributes.height;
190 win = XCreateSimpleWindow(dpy,Root,mysizehints.x,mysizehints.y,
191 mysizehints.width,mysizehints.height,
192 borderwidth,fore_pix,back_pix);
193 iconwin = XCreateSimpleWindow(dpy,win,mysizehints.x,mysizehints.y,
194 mysizehints.width,mysizehints.height,
195 borderwidth,fore_pix,back_pix);
197 /* activate hints */
198 XSetWMNormalHints(dpy, win, &mysizehints);
199 classHint.res_name = "wmload";
200 classHint.res_class = "WMLoad";
201 XSetClassHint(dpy, win, &classHint);
203 XSelectInput(dpy,win,MW_EVENTS);
204 XSelectInput(dpy,iconwin,MW_EVENTS);
205 XSetCommand(dpy,win,argv,argc);
207 if (XStringListToTextProperty(&wname, 1, &name) ==0) {
208 fprintf(stderr, "wmload: can't allocate window name\n");
209 exit(-1);
211 XSetWMName(dpy, win, &name);
213 /* Create a GC for drawing */
214 gcm = GCForeground|GCBackground|GCGraphicsExposures;
215 gcv.foreground = fore_pix;
216 gcv.background = back_pix;
217 gcv.graphics_exposures = FALSE;
218 NormalGC = XCreateGC(dpy, Root, gcm, &gcv);
220 if (ONLYSHAPE) { /* try to make shaped window here */
221 pixmask = XCreateBitmapFromData(dpy, win, mask2_bits, mask2_width,
222 mask2_height);
223 XShapeCombineMask(dpy, win, ShapeBounding, 0, 0, pixmask, ShapeSet);
224 XShapeCombineMask(dpy, iconwin, ShapeBounding, 0, 0, pixmask, ShapeSet);
227 mywmhints.icon_window = iconwin;
228 mywmhints.icon_x = mysizehints.x;
229 mywmhints.icon_y = mysizehints.y;
230 mywmhints.window_group = win;
231 mywmhints.flags = StateHint | IconWindowHint | IconPositionHint
232 | WindowGroupHint;
233 XSetWMHints(dpy, win, &mywmhints);
235 XMapWindow(dpy,win);
236 InitLoad();
237 InsertLoad();
238 RedrawWindow(&visible);
239 while(1)
241 if (actualtime != time(0))
243 actualtime = time(0);
245 if(actualtime % updatespeed == 0)
246 InsertLoad();
248 RedrawWindow(&visible);
251 /* read a packet */
252 while (XPending(dpy))
254 XNextEvent(dpy,&Event);
255 switch(Event.type)
257 case Expose:
258 if(Event.xexpose.count == 0 )
259 RedrawWindow(&visible);
260 break;
261 case ButtonPress:
262 system(Execute);
263 break;
264 case DestroyNotify:
265 XFreeGC(dpy, NormalGC);
266 XDestroyWindow(dpy, win);
267 XDestroyWindow(dpy, iconwin);
268 XCloseDisplay(dpy);
269 exit(0);
270 default:
271 break;
274 XFlush(dpy);
275 #ifdef SYSV
276 poll((struct poll *) 0, (size_t) 0, 50);
277 #else
278 usleep(50000L); /* 5/100 sec */
279 #endif
281 return 0;
284 /*****************************************************************************/
285 void nocolor(char *a, char *b)
287 fprintf(stderr,"wmload: can't %s %s\n", a,b);
290 /*****************************************************************************/
291 /* convert the XPMIcons to XImage */
292 void GetXPM(void)
294 static char **alt_xpm;
295 XColor col;
296 XWindowAttributes attributes;
297 int ret;
298 char tempc1[12],tempc2[12],tempc3[12];
299 float colr,colg,colb;
301 alt_xpm =ONLYSHAPE ? mask_xpm : back_xpm;
303 /* for the colormap */
304 XGetWindowAttributes(dpy,Root,&attributes);
306 /* get user-defined color or validate the default */
307 if (!XParseColor (dpy, attributes.colormap, LedColor, &col))
309 nocolor("parse",LedColor);
311 else
313 /* scale down the Xcolor values */
314 colr = col.red / 257;
315 colg = col.green / 257;
316 colb = col.blue / 257;
317 /* the brightest color */
318 sprintf(tempc1, "S c #%.2x%.2x%.2x", (int)colr, (int)colg, (int)colb);
319 back_xpm[47] = tempc1;
321 /* make medium color */
322 colr = (colr /100) *89;
323 colg = (colg /100) *89;
324 colb = (colb /100) *89;
325 sprintf(tempc2, "R c #%.2x%.2x%.2x", (int)colr, (int)colg, (int)colb);
326 back_xpm[46] = tempc2;
328 /* make darkest color */
329 colr = (colr /100) *89;
330 colg = (colg /100) *89;
331 colb = (colb /100) *89;
332 sprintf(tempc3, "Q c #%.2x%.2x%.2x", (int)colr, (int)colg, (int)colb);
333 back_xpm[45] = tempc3;
336 wmload.attributes.valuemask |= (XpmReturnPixels | XpmReturnExtensions);
337 ret = XpmCreatePixmapFromData(dpy, Root, alt_xpm, &wmload.pixmap,
338 &wmload.mask, &wmload.attributes);
339 if(ret != XpmSuccess)
340 {fprintf(stderr, "%s\n", ERR_colorcells);exit(1);}
342 visible.attributes.valuemask |= (XpmReturnPixels | XpmReturnExtensions);
343 ret = XpmCreatePixmapFromData(dpy, Root, back_xpm, &visible.pixmap,
344 &visible.mask, &visible.attributes);
345 if(ret != XpmSuccess)
346 {fprintf(stderr, "%s\n", ERR_colorcells);exit(1);}
350 /*****************************************************************************/
351 /* Removes expose events for a specific window from the queue */
352 int flush_expose (Window w)
354 XEvent dummy;
355 int i=0;
357 while (XCheckTypedWindowEvent (dpy, w, Expose, &dummy))i++;
358 return i;
361 /*****************************************************************************/
362 /* Draws the icon window */
363 void RedrawWindow( XpmIcon *v)
365 flush_expose (iconwin);
366 XCopyArea(dpy,v->pixmap,iconwin,NormalGC,
367 0,0,v->attributes.width, v->attributes.height,0,0);
368 flush_expose (win);
369 XCopyArea(dpy,v->pixmap,win,NormalGC,
370 0,0,v->attributes.width, v->attributes.height,0,0);
374 /*****************************************************************************/
375 Pixel GetColor(char *name)
377 XColor color;
378 XWindowAttributes attributes;
380 XGetWindowAttributes(dpy,Root,&attributes);
381 color.pixel = 0;
382 if (!XParseColor (dpy, attributes.colormap, name, &color))
384 nocolor("parse",name);
386 else if(!XAllocColor (dpy, attributes.colormap, &color))
388 nocolor("alloc",name);
390 return color.pixel;
393 /*****************************************************************************/
394 void InitLoad()
396 /* Save the 4 base colors in wmload */
397 XCopyArea(dpy, visible.pixmap, wmload.pixmap, NormalGC,
398 6,6,3,52, Shape(6), Shape(6));
400 /* Copy the base panel to visible */
401 XCopyArea(dpy, wmload.pixmap, visible.pixmap, NormalGC,
402 0,0,mysizehints.width, mysizehints.height, 0 ,0);
404 /* Remove the 4 base colors from visible */
405 XCopyArea(dpy, visible.pixmap, visible.pixmap, NormalGC,
406 Shape(9),Shape(6),3,52, Shape(6), Shape(6));
409 static char *
410 skip_token(const char *p)
412 while (isspace(*p)) p++;
413 while (*p && !isspace(*p)) p++;
414 return (char *)p;
417 void GetLoad(int Maximum, int *usr, int *nice, int *sys, int *free)
419 char buffer[100];/*[4096+1];*/
420 int fd, len;
421 int total;
422 char *p;
424 fd = open("/proc/stat", O_RDONLY);
425 len = read(fd, buffer, sizeof(buffer)-1);
426 close(fd);
427 buffer[len] = '\0';
429 p = skip_token(buffer); /* "cpu" */
431 cp_time[0] = strtoul(p, &p, 0); /* user */
432 cp_time[1] = strtoul(p, &p, 0); /* nice */
433 cp_time[2] = strtoul(p, &p, 0); /* system */
434 cp_time[3] = strtoul(p, &p, 0); /* idle */
436 *usr = cp_time[0] - last[0];
437 *nice = cp_time[1] - last[1];
438 *sys = cp_time[2] - last[2];
439 *free = cp_time[3] - last[3];
440 total = *usr + *nice + *sys + *free;
442 last[0] = cp_time[0];
443 last[1] = cp_time[1];
444 last[2] = cp_time[2];
445 last[3] = cp_time[3];
447 *usr = rint(Maximum * (float)(*usr) /total);
448 *nice =rint(Maximum * (float)(*nice) /total);
449 *sys = rint(Maximum * (float)(*sys) /total);
450 *free = rint(Maximum * (float)(*free) /total);
453 void InsertLoad()
455 int UserTime, NiceTime, SystemTime, FreeTime, act, constrain;
456 GetLoad( 52, &UserTime, &NiceTime, &SystemTime, &FreeTime);
458 constrain = (UserTime + NiceTime + SystemTime + FreeTime);
459 if(constrain == 53)
461 if(FreeTime > 0) FreeTime--;
462 else if(SystemTime > 0) SystemTime--;
463 else if(NiceTime > 0) NiceTime--;
464 else if(UserTime > 0) UserTime--;
466 else if(constrain == 51) FreeTime++;
468 /* Move the area */
469 XCopyArea(dpy, visible.pixmap, visible.pixmap, NormalGC,
470 Shape(7), Shape(6), 51, 52, Shape(6), Shape(6));
473 /* User Time */
474 act = 58 - UserTime;
475 if(UserTime > 0)
476 XCopyArea(dpy, wmload.pixmap, visible.pixmap, NormalGC,
477 Shape(6), Shape(6), 1, UserTime, Shape(57), Shape(act));
479 /* Nice Time */
480 act = act - NiceTime;
481 if(NiceTime > 0)
482 XCopyArea(dpy, wmload.pixmap, visible.pixmap, NormalGC,
483 Shape(7), Shape(6), 1, NiceTime, Shape(57), Shape(act));
485 /* System Time */
486 act = act - SystemTime;
487 if(SystemTime > 0)
488 XCopyArea(dpy, wmload.pixmap, visible.pixmap, NormalGC,
489 Shape(8), Shape(6), 1, SystemTime, Shape(57), Shape(act));
491 /* Free Time */
492 if(FreeTime > 0)
493 XCopyArea(dpy, wmload.pixmap, visible.pixmap, NormalGC,
494 Shape(9), Shape(6), 1, FreeTime, Shape(57), Shape(6));