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
;
108 Atom _XA_WM_DELETE_WINDOW
= None
;
110 mywmhints
.initial_state
= NormalState
;
112 /* Parse command line options */
115 for(i
=1;i
<argc
;i
++) {
121 if(++i
>=argc
) usage();
122 sscanf(argv
[i
], "%d", &updatespeed
);
125 if(++i
>=argc
) usage();
126 strcpy(&Execute
[0], argv
[i
]);
127 strcat(&Execute
[0], " &");
133 if(++i
>=argc
) usage();
137 mywmhints
.initial_state
= IconicState
;
140 mywmhints
.initial_state
= WithdrawnState
;
143 if(++i
>=argc
) usage();
147 fprintf(stdout
, "\nwmload version: %i.%i.%i\n", major_VER
, minor_VER
, patch_VER
);
148 if(argc
== 2) exit(0);
156 fprintf(stderr
, "\nInvalid argument: %s\n", arg
);
161 /* Open the display */
162 if (!(dpy
= XOpenDisplay(display_name
)))
164 fprintf(stderr
,"wmload: can't open display %s\n",
165 XDisplayName(display_name
));
169 screen
= DefaultScreen(dpy
);
170 Root
= RootWindow(dpy
, screen
);
171 d_depth
= DefaultDepth(dpy
, screen
);
172 x_fd
= XConnectionNumber(dpy
);
173 _XA_WM_DELETE_WINDOW
= XInternAtom (dpy
, "WM_DELETE_WINDOW", False
);
175 /* Convert XPM Data to XImage */
178 /* Create a window to hold the banner */
179 mysizehints
.flags
= USSize
|USPosition
;
183 back_pix
= GetColor("white");
184 fore_pix
= GetColor("black");
186 XWMGeometry(dpy
, screen
, Geometry
, NULL
, (borderwidth
=1), &mysizehints
,
187 &mysizehints
.x
,&mysizehints
.y
,&mysizehints
.width
,&mysizehints
.height
, &i
);
189 mysizehints
.width
= wmload
.attributes
.width
;
190 mysizehints
.height
= wmload
.attributes
.height
;
192 win
= XCreateSimpleWindow(dpy
,Root
,mysizehints
.x
,mysizehints
.y
,
193 mysizehints
.width
,mysizehints
.height
,
194 borderwidth
,fore_pix
,back_pix
);
195 iconwin
= XCreateSimpleWindow(dpy
,win
,mysizehints
.x
,mysizehints
.y
,
196 mysizehints
.width
,mysizehints
.height
,
197 borderwidth
,fore_pix
,back_pix
);
200 XSetWMNormalHints(dpy
, win
, &mysizehints
);
201 classHint
.res_name
= "wmload";
202 classHint
.res_class
= "WMLoad";
203 XSetClassHint(dpy
, win
, &classHint
);
205 XSelectInput(dpy
,win
,MW_EVENTS
);
206 XSelectInput(dpy
,iconwin
,MW_EVENTS
);
207 XSetCommand(dpy
,win
,argv
,argc
);
209 if (XStringListToTextProperty(&wname
, 1, &name
) ==0) {
210 fprintf(stderr
, "wmload: can't allocate window name\n");
213 XSetWMName(dpy
, win
, &name
);
215 /* Create a GC for drawing */
216 gcm
= GCForeground
|GCBackground
|GCGraphicsExposures
;
217 gcv
.foreground
= fore_pix
;
218 gcv
.background
= back_pix
;
219 gcv
.graphics_exposures
= FALSE
;
220 NormalGC
= XCreateGC(dpy
, Root
, gcm
, &gcv
);
222 if (ONLYSHAPE
) { /* try to make shaped window here */
223 pixmask
= XCreateBitmapFromData(dpy
, win
, (char *)mask2_bits
, mask2_width
,
225 XShapeCombineMask(dpy
, win
, ShapeBounding
, 0, 0, pixmask
, ShapeSet
);
226 XShapeCombineMask(dpy
, iconwin
, ShapeBounding
, 0, 0, pixmask
, ShapeSet
);
229 mywmhints
.icon_window
= iconwin
;
230 mywmhints
.icon_x
= mysizehints
.x
;
231 mywmhints
.icon_y
= mysizehints
.y
;
232 mywmhints
.window_group
= win
;
233 mywmhints
.flags
= StateHint
| IconWindowHint
| IconPositionHint
235 XSetWMHints(dpy
, win
, &mywmhints
);
236 XSetWMProtocols (dpy
, win
, &_XA_WM_DELETE_WINDOW
, 1);
241 RedrawWindow(&visible
);
244 if (actualtime
!= time(0))
246 actualtime
= time(0);
248 if(actualtime
% updatespeed
== 0)
251 RedrawWindow(&visible
);
255 while (XPending(dpy
))
257 XNextEvent(dpy
,&Event
);
261 if(Event
.xexpose
.count
== 0 )
262 RedrawWindow(&visible
);
268 if ((Event
.xclient
.format
!= 32) ||
269 (Event
.xclient
.data
.l
[0] != _XA_WM_DELETE_WINDOW
))
272 XFreeGC(dpy
, NormalGC
);
273 XDestroyWindow(dpy
, iconwin
);
274 XDestroyWindow(dpy
, win
);
284 poll((struct poll
*) 0, (size_t) 0, 50);
286 usleep(50000L); /* 5/100 sec */
292 /*****************************************************************************/
293 void nocolor(char *a
, char *b
)
295 fprintf(stderr
,"wmload: can't %s %s\n", a
,b
);
298 /*****************************************************************************/
299 /* convert the XPMIcons to XImage */
302 static char **alt_xpm
;
304 XWindowAttributes attributes
;
306 char tempc1
[12],tempc2
[12],tempc3
[12];
307 float colr
,colg
,colb
;
309 alt_xpm
=ONLYSHAPE
? mask_xpm
: back_xpm
;
311 /* for the colormap */
312 XGetWindowAttributes(dpy
,Root
,&attributes
);
314 /* get user-defined color or validate the default */
315 if (!XParseColor (dpy
, attributes
.colormap
, LedColor
, &col
))
317 nocolor("parse",LedColor
);
321 /* scale down the Xcolor values */
322 colr
= col
.red
/ 257;
323 colg
= col
.green
/ 257;
324 colb
= col
.blue
/ 257;
325 /* the brightest color */
326 sprintf(tempc1
, "S c #%.2x%.2x%.2x", (int)colr
, (int)colg
, (int)colb
);
327 back_xpm
[47] = tempc1
;
329 /* make medium color */
330 colr
= (colr
/100) *89;
331 colg
= (colg
/100) *89;
332 colb
= (colb
/100) *89;
333 sprintf(tempc2
, "R c #%.2x%.2x%.2x", (int)colr
, (int)colg
, (int)colb
);
334 back_xpm
[46] = tempc2
;
336 /* make darkest color */
337 colr
= (colr
/100) *89;
338 colg
= (colg
/100) *89;
339 colb
= (colb
/100) *89;
340 sprintf(tempc3
, "Q c #%.2x%.2x%.2x", (int)colr
, (int)colg
, (int)colb
);
341 back_xpm
[45] = tempc3
;
344 wmload
.attributes
.valuemask
|= (XpmReturnPixels
| XpmReturnExtensions
);
345 ret
= XpmCreatePixmapFromData(dpy
, Root
, alt_xpm
, &wmload
.pixmap
,
346 &wmload
.mask
, &wmload
.attributes
);
347 if(ret
!= XpmSuccess
)
348 {fprintf(stderr
, "%s\n", ERR_colorcells
);exit(1);}
350 visible
.attributes
.valuemask
|= (XpmReturnPixels
| XpmReturnExtensions
);
351 ret
= XpmCreatePixmapFromData(dpy
, Root
, back_xpm
, &visible
.pixmap
,
352 &visible
.mask
, &visible
.attributes
);
353 if(ret
!= XpmSuccess
)
354 {fprintf(stderr
, "%s\n", ERR_colorcells
);exit(1);}
358 /*****************************************************************************/
359 /* Removes expose events for a specific window from the queue */
360 int flush_expose (Window w
)
365 while (XCheckTypedWindowEvent (dpy
, w
, Expose
, &dummy
))i
++;
369 /*****************************************************************************/
370 /* Draws the icon window */
371 void RedrawWindow( XpmIcon
*v
)
373 flush_expose (iconwin
);
374 XCopyArea(dpy
,v
->pixmap
,iconwin
,NormalGC
,
375 0,0,v
->attributes
.width
, v
->attributes
.height
,0,0);
377 XCopyArea(dpy
,v
->pixmap
,win
,NormalGC
,
378 0,0,v
->attributes
.width
, v
->attributes
.height
,0,0);
382 /*****************************************************************************/
383 Pixel
GetColor(char *name
)
386 XWindowAttributes attributes
;
388 XGetWindowAttributes(dpy
,Root
,&attributes
);
390 if (!XParseColor (dpy
, attributes
.colormap
, name
, &color
))
392 nocolor("parse",name
);
394 else if(!XAllocColor (dpy
, attributes
.colormap
, &color
))
396 nocolor("alloc",name
);
401 /*****************************************************************************/
404 /* Save the 4 base colors in wmload */
405 XCopyArea(dpy
, visible
.pixmap
, wmload
.pixmap
, NormalGC
,
406 6,6,3,52, Shape(6), Shape(6));
408 /* Copy the base panel to visible */
409 XCopyArea(dpy
, wmload
.pixmap
, visible
.pixmap
, NormalGC
,
410 0,0,mysizehints
.width
, mysizehints
.height
, 0 ,0);
412 /* Remove the 4 base colors from visible */
413 XCopyArea(dpy
, visible
.pixmap
, visible
.pixmap
, NormalGC
,
414 Shape(9),Shape(6),3,52, Shape(6), Shape(6));
418 skip_token(const char *p
)
420 while (isspace(*p
)) p
++;
421 while (*p
&& !isspace(*p
)) p
++;
425 void GetLoad(int Maximum
, int *usr
, int *nice
, int *sys
, int *free
)
427 char buffer
[100];/*[4096+1];*/
432 fd
= open("/proc/stat", O_RDONLY
);
433 len
= read(fd
, buffer
, sizeof(buffer
)-1);
437 p
= skip_token(buffer
); /* "cpu" */
439 cp_time
[0] = strtoul(p
, &p
, 0); /* user */
440 cp_time
[1] = strtoul(p
, &p
, 0); /* nice */
441 cp_time
[2] = strtoul(p
, &p
, 0); /* system */
442 cp_time
[3] = strtoul(p
, &p
, 0); /* idle */
444 if( (*usr
= cp_time
[0] - last
[0]) < 0 ) *usr
= 0 ;
445 if( (*nice
= cp_time
[1] - last
[1]) < 0 ) *nice
= 0 ;
446 if( (*sys
= cp_time
[2] - last
[2]) < 0 ) *sys
= 0 ;
447 if( (*free
= cp_time
[3] - last
[3]) < 0 ) *free
= 0 ;
449 total
= *usr
+ *nice
+ *sys
+ *free
;
451 last
[0] = cp_time
[0];
452 last
[1] = cp_time
[1];
453 last
[2] = cp_time
[2];
454 last
[3] = cp_time
[3];
456 *usr
= rint(Maximum
* (float)(*usr
) /total
);
457 *nice
=rint(Maximum
* (float)(*nice
) /total
);
458 *sys
= rint(Maximum
* (float)(*sys
) /total
);
459 *free
= rint(Maximum
* (float)(*free
) /total
);
464 int UserTime
, NiceTime
, SystemTime
, FreeTime
, act
, constrain
;
465 GetLoad( 52, &UserTime
, &NiceTime
, &SystemTime
, &FreeTime
);
467 constrain
= (UserTime
+ NiceTime
+ SystemTime
+ FreeTime
);
470 if(FreeTime
> 0) FreeTime
--;
471 else if(SystemTime
> 0) SystemTime
--;
472 else if(NiceTime
> 0) NiceTime
--;
473 else if(UserTime
> 0) UserTime
--;
475 else if(constrain
== 51) FreeTime
++;
478 XCopyArea(dpy
, visible
.pixmap
, visible
.pixmap
, NormalGC
,
479 Shape(7), Shape(6), 51, 52, Shape(6), Shape(6));
485 XCopyArea(dpy
, wmload
.pixmap
, visible
.pixmap
, NormalGC
,
486 Shape(6), Shape(6), 1, UserTime
, Shape(57), Shape(act
));
489 act
= act
- NiceTime
;
491 XCopyArea(dpy
, wmload
.pixmap
, visible
.pixmap
, NormalGC
,
492 Shape(7), Shape(6), 1, NiceTime
, Shape(57), Shape(act
));
495 act
= act
- SystemTime
;
497 XCopyArea(dpy
, wmload
.pixmap
, visible
.pixmap
, NormalGC
,
498 Shape(8), Shape(6), 1, SystemTime
, Shape(57), Shape(act
));
502 XCopyArea(dpy
, wmload
.pixmap
, visible
.pixmap
, NormalGC
,
503 Shape(9), Shape(6), 1, FreeTime
, Shape(57), Shape(6));