8 #include <X11/extensions/shape.h>
12 #include <X11/Xatom.h>
21 #define MW_EVENTS (ExposureMask | ButtonPressMask | StructureNotifyMask)
23 #define Shape(num) (ONLYSHAPE ? num-5 : num)
26 /* Global Data storage/structures ********************************************/
27 static long cp_time
[NCPUSTATES
];
28 static long last
[NCPUSTATES
];
29 int ONLYSHAPE
=0; /* default value is noshape */
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",
44 /* X11 Variables *************************************************************/
45 Display
*dpy
; /* welches DISPLAY */
46 Window Root
; /* Hintergrund-Drawable */
50 XSizeHints mysizehints
;
52 Pixel back_pix
, fore_pix
;
54 Window iconwin
, win
; /* My home is my window */
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";
62 /* XPM Structures & Variables ************************************************/
63 typedef struct _XpmIcon
{
66 XpmAttributes attributes
;
74 /* Function definitions ******************************************************/
76 Pixel
GetColor(char *name
);
77 void RedrawWindow( XpmIcon
*v
);
81 /*****************************************************************************/
82 /* Source Code <--> Function Implementations */
83 /*****************************************************************************/
88 fprintf(stderr
,"\nusage: %s [-options ...] \n", ProgName
);
89 for (cpp
= help_message
; *cpp
; cpp
++) {
90 fprintf(stderr
, "%s\n", *cpp
);
96 int main(int argc
,char *argv
[])
99 unsigned int borderwidth
;
100 char *display_name
= NULL
;
101 char *wname
= "wmload";
106 XClassHint classHint
;
109 mywmhints
.initial_state
= NormalState
;
111 /* Parse command line options */
114 for(i
=1;i
<argc
;i
++) {
120 if(++i
>=argc
) usage();
121 sscanf(argv
[i
], "%d", &updatespeed
);
124 if(++i
>=argc
) usage();
125 strcpy(&Execute
[0], argv
[i
]);
126 strcat(&Execute
[0], " &");
132 if(++i
>=argc
) usage();
136 mywmhints
.initial_state
= IconicState
;
139 mywmhints
.initial_state
= WithdrawnState
;
142 if(++i
>=argc
) usage();
146 fprintf(stdout
, "\nwmload version: %i.%i.%i\n", major_VER
, minor_VER
, patch_VER
);
147 if(argc
== 2) exit(0);
155 fprintf(stderr
, "\nInvalid argument: %s\n", arg
);
160 /* Open the display */
161 if (!(dpy
= XOpenDisplay(display_name
)))
163 fprintf(stderr
,"wmload: can't open display %s\n",
164 XDisplayName(display_name
));
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 */
176 /* Create a window to hold the banner */
177 mysizehints
.flags
= USSize
|USPosition
;
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
);
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");
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
, (char *)mask2_bits
, mask2_width
,
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
233 XSetWMHints(dpy
, win
, &mywmhints
);
238 RedrawWindow(&visible
);
241 if (actualtime
!= time(0))
243 actualtime
= time(0);
245 if(actualtime
% updatespeed
== 0)
248 RedrawWindow(&visible
);
252 while (XPending(dpy
))
254 XNextEvent(dpy
,&Event
);
258 if(Event
.xexpose
.count
== 0 )
259 RedrawWindow(&visible
);
265 XFreeGC(dpy
, NormalGC
);
266 XDestroyWindow(dpy
, win
);
267 XDestroyWindow(dpy
, iconwin
);
276 poll((struct poll
*) 0, (size_t) 0, 50);
278 usleep(50000L); /* 5/100 sec */
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 */
294 static char **alt_xpm
;
296 XWindowAttributes attributes
;
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
);
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
)
357 while (XCheckTypedWindowEvent (dpy
, w
, Expose
, &dummy
))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);
369 XCopyArea(dpy
,v
->pixmap
,win
,NormalGC
,
370 0,0,v
->attributes
.width
, v
->attributes
.height
,0,0);
374 /*****************************************************************************/
375 Pixel
GetColor(char *name
)
378 XWindowAttributes attributes
;
380 XGetWindowAttributes(dpy
,Root
,&attributes
);
382 if (!XParseColor (dpy
, attributes
.colormap
, name
, &color
))
384 nocolor("parse",name
);
386 else if(!XAllocColor (dpy
, attributes
.colormap
, &color
))
388 nocolor("alloc",name
);
393 /*****************************************************************************/
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));
410 skip_token(const char *p
)
412 while (isspace(*p
)) p
++;
413 while (*p
&& !isspace(*p
)) p
++;
417 void GetLoad(int Maximum
, int *usr
, int *nice
, int *sys
, int *free
)
419 char buffer
[100];/*[4096+1];*/
424 fd
= open("/proc/stat", O_RDONLY
);
425 len
= read(fd
, buffer
, sizeof(buffer
)-1);
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
);
455 int UserTime
, NiceTime
, SystemTime
, FreeTime
, act
, constrain
;
456 GetLoad( 52, &UserTime
, &NiceTime
, &SystemTime
, &FreeTime
);
458 constrain
= (UserTime
+ NiceTime
+ SystemTime
+ FreeTime
);
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
++;
469 XCopyArea(dpy
, visible
.pixmap
, visible
.pixmap
, NormalGC
,
470 Shape(7), Shape(6), 51, 52, Shape(6), Shape(6));
476 XCopyArea(dpy
, wmload
.pixmap
, visible
.pixmap
, NormalGC
,
477 Shape(6), Shape(6), 1, UserTime
, Shape(57), Shape(act
));
480 act
= act
- NiceTime
;
482 XCopyArea(dpy
, wmload
.pixmap
, visible
.pixmap
, NormalGC
,
483 Shape(7), Shape(6), 1, NiceTime
, Shape(57), Shape(act
));
486 act
= act
- SystemTime
;
488 XCopyArea(dpy
, wmload
.pixmap
, visible
.pixmap
, NormalGC
,
489 Shape(8), Shape(6), 1, SystemTime
, Shape(57), Shape(act
));
493 XCopyArea(dpy
, wmload
.pixmap
, visible
.pixmap
, NormalGC
,
494 Shape(9), Shape(6), 1, FreeTime
, Shape(57), Shape(6));