/*
* asapm is the APM (Advanced Power Management) monitor utility for X Windows
* Copyright (c) 1998-99 Albert Dorofeev <Albert@mail.dma.be>
* For the updates see http://bewoner.dma.be/Albert/linux/
*
* This software is distributed under GPL. For details see LICENSE file.
*/
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/xpm.h>
#include <X11/Xatom.h>
#include "background_in.xpm"
#include "background_out.xpm"
#include "alphabet_in.xpm"
#include "alphabet_out.xpm"
#include "state.h"
extern struct apm_state state;
/* nice idea from ascd */
typedef struct _XpmIcon {
Pixmap pixmap;
Pixmap mask;
XpmAttributes attributes;
} XpmIcon;
XpmIcon backgroundXpm;
XpmIcon alphabetXpm;
char alphabetColor[12];
char alphabetLowColor[12];
char BGColor8bpp[9][12];
int alphabetPosition[15] = {
0, 7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 78, 82, 90, 94
};
int alphabetSize[15] = {
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 4, 8, 4, 7
};
int percentPosition[4] = { 13, 21, 29, 37 };
int timePosition[5] = { 12, 19, 26, 30, 37 };
#define BATTERY_IMAGE_X 14
#define BATTERY_IMAGE_Y 4
XPoint batteryImage[9] = {
{ BATTERY_IMAGE_X+12, BATTERY_IMAGE_Y+4 },
{ BATTERY_IMAGE_X+12, BATTERY_IMAGE_Y+1 },
{ BATTERY_IMAGE_X+13, BATTERY_IMAGE_Y+1 },
{ BATTERY_IMAGE_X+13, BATTERY_IMAGE_Y+4 },
{ BATTERY_IMAGE_X+11, BATTERY_IMAGE_Y+4 },
{ BATTERY_IMAGE_X+11, BATTERY_IMAGE_Y+0 },
{ BATTERY_IMAGE_X+0, BATTERY_IMAGE_Y+0 },
{ BATTERY_IMAGE_X+0, BATTERY_IMAGE_Y+5 },
{ BATTERY_IMAGE_X+12, BATTERY_IMAGE_Y+5 }
};
#define AC_IMAGE_X 31
#define AC_IMAGE_Y 4
XPoint acImage[28] = {
{ AC_IMAGE_X+0, AC_IMAGE_Y+2 },
{ AC_IMAGE_X+1, AC_IMAGE_Y+1 },
{ AC_IMAGE_X+2, AC_IMAGE_Y+1 },
{ AC_IMAGE_X+3, AC_IMAGE_Y+2 },
{ AC_IMAGE_X+4, AC_IMAGE_Y+2 },
{ AC_IMAGE_X+4, AC_IMAGE_Y+3 },
{ AC_IMAGE_X+5, AC_IMAGE_Y+1 },
{ AC_IMAGE_X+5, AC_IMAGE_Y+2 },
{ AC_IMAGE_X+5, AC_IMAGE_Y+3 },
{ AC_IMAGE_X+5, AC_IMAGE_Y+4 },
{ AC_IMAGE_X+6, AC_IMAGE_Y+0 },
{ AC_IMAGE_X+7, AC_IMAGE_Y+0 },
{ AC_IMAGE_X+8, AC_IMAGE_Y+0 },
{ AC_IMAGE_X+9, AC_IMAGE_Y+0 },
{ AC_IMAGE_X+10, AC_IMAGE_Y+0 },
{ AC_IMAGE_X+10, AC_IMAGE_Y+1 },
{ AC_IMAGE_X+10, AC_IMAGE_Y+2 },
{ AC_IMAGE_X+10, AC_IMAGE_Y+3 },
{ AC_IMAGE_X+10, AC_IMAGE_Y+4 },
{ AC_IMAGE_X+10, AC_IMAGE_Y+5 },
{ AC_IMAGE_X+9, AC_IMAGE_Y+5 },
{ AC_IMAGE_X+8, AC_IMAGE_Y+5 },
{ AC_IMAGE_X+7, AC_IMAGE_Y+5 },
{ AC_IMAGE_X+6, AC_IMAGE_Y+5 },
{ AC_IMAGE_X+11, AC_IMAGE_Y+1 },
{ AC_IMAGE_X+12, AC_IMAGE_Y+1 },
{ AC_IMAGE_X+11, AC_IMAGE_Y+4 },
{ AC_IMAGE_X+12, AC_IMAGE_Y+4 }
};
/* X windows related global variables */
Display * mainDisplay = 0; /* The display we are working on */
Window Root; /* The root window of X11 */
Window mainWindow; /* Application window */
Window iconWindow; /* Icon window */
XGCValues mainGCV; /* graphics context values */
GC mainGC; /* Graphics context */
Pixel greenPixel, redPixel;
Pixel lightgreenPixel, lightredPixel;
Pixel semilightgreenPixel, semilightredPixel;
Pixel bitlightgreenPixel, bitlightredPixel;
Pixel darkgreenPixel, darkredPixel;
Pixel semidarkgreenPixel, semidarkredPixel;
Pixel bitdarkgreenPixel, bitdarkredPixel;
Pixel greenTextPixel, yellowTextPixel, redTextPixel;
Atom wm_delete_window;
Atom wm_protocols;
/*
* This function clears up all X related
* stuff and exits. It is called in case
* of emergencies too.
*/
void Cleanup()
{
if ( mainDisplay )
{
XCloseDisplay(mainDisplay);
}
exit(0);
}
/*
* this function was taken out of ascd,
* it seems to translate the given name
* into the corresponding color
*/
Pixel GetColor(char *ColorName)
{
XColor Color;
XWindowAttributes Attributes;
XGetWindowAttributes(mainDisplay,Root,&Attributes);
Color.pixel = 0;
if (!XParseColor (mainDisplay, Attributes.colormap, ColorName, &Color))
printf("asapm: can't parse %s\n", ColorName);
else if(!XAllocColor (mainDisplay, Attributes.colormap, &Color))
printf("asapm: can't allocate %s\n", ColorName);
return Color.pixel;
}
/* parses the given color */
XColor ParseColor(char *ColorName)
{
XColor Color;
XWindowAttributes Attributes;
XGetWindowAttributes(mainDisplay,Root,&Attributes);
Color.pixel = 0;
if (!XParseColor (mainDisplay, Attributes.colormap, ColorName, &Color))
printf("asapm: can't parse %s\n", ColorName);
else if(!XAllocColor (mainDisplay, Attributes.colormap, &Color))
printf("asapm: can't allocate %s\n", ColorName);
return Color;
}
/* darkens the given color using the supplied rate */
Pixel DarkenColor(char *ColorName, float rate)
{
XColor tmp_color;
char tmp_char[50];
#ifdef DEBUG
printf("darkening %s ->", ColorName);
#endif
tmp_color = ParseColor(ColorName);
#ifdef DEBUG
printf(" #%x %x %x ", tmp_color.red, tmp_color.green, tmp_color.blue);
#endif
tmp_color.red = tmp_color.red / 257 / rate;
tmp_color.green = tmp_color.green / 257 / rate;
tmp_color.blue = tmp_color.blue / 257 / rate;
sprintf(tmp_char, "#%.2x%.2x%.2x",
(int) tmp_color.red,
(int) tmp_color.green,
(int) tmp_color.blue);
#ifdef DEBUG
printf("-> %s\n", tmp_char);
#endif
return GetColor(tmp_char);
}
Pixel LightenColor(char *ColorName, float rate)
{
XColor tmp_color;
char tmp_char[50];
#ifdef DEBUG
printf("lightening %s ->", ColorName);
#endif
tmp_color = ParseColor(ColorName);
#ifdef DEBUG
printf(" #%x %x %x ", tmp_color.red, tmp_color.green, tmp_color.blue);
#endif
tmp_color.red = tmp_color.red / 257 * rate;
tmp_color.green = tmp_color.green / 257 * rate;
tmp_color.blue = tmp_color.blue / 257 * rate;
if (tmp_color.red > 255) tmp_color.red = 255;
if (tmp_color.green > 255) tmp_color.green = 255;
if (tmp_color.blue > 255) tmp_color.blue = 255;
sprintf(tmp_char, "#%.2x%.2x%.2x",
(int) tmp_color.red,
(int) tmp_color.green,
(int) tmp_color.blue);
#ifdef DEBUG
printf("-> %s\n", tmp_char);
#endif
return GetColor(tmp_char);
}
void Redraw();
/*
* Initialize X specific global variables
* and create two windows. One window is
* the main application window, the other
* serves as an icon for the first (although
* they are exactly identical in drawing).
*/
void initializeWindow(int argc, char** argv,
char * display_name,
char * mainGeometry,
char * statuscolor,
char * greencolor,
char * yellowcolor,
char * redcolor,
char * slidercolor,
char * sliderbgcolor,
char * app_name,
int withdrawn,
int iconic,
int embossed)
{
int screen;
Status status;
XWindowAttributes winAttr;
Pixel back_pix, fore_pix;
XSizeHints SizeHints;
XTextProperty title;
XClassHint classHint;
int gravity;
XWMHints WmHints;
XEvent Event;
XColor tmp_color;
char ** background;
char ** alphabet;
int color_depth;
int tmp;
int result;
int x_negative = 0;
int y_negative = 0;
/* XIconSize * xiconsize; */
mainDisplay = XOpenDisplay(display_name);
if ( ! mainDisplay ) {
printf("asapm : can't open display %s. Sorry ...\n",
XDisplayName(display_name));
exit(1);
}
screen = DefaultScreen(mainDisplay);
Root = RootWindow(mainDisplay, screen);
back_pix = GetColor("white");
fore_pix = GetColor("black");
color_depth = DefaultDepth(mainDisplay, screen);
if ( ! state.color_depth )
state.color_depth = color_depth;
#ifdef DEBUG
printf("Detected color depth %d bpp, using %d bpp\n",
color_depth, state.color_depth);
#endif
backgroundXpm.attributes.valuemask |=
(XpmReturnPixels | XpmReturnExtensions
| XpmExactColors | XpmCloseness);
backgroundXpm.attributes.exactColors = False;
backgroundXpm.attributes.closeness = 65536;
background = embossed ? background_in : background_out;
if ( state.color_depth == 8 ) {
/* degrade the background */
sprintf(BGColor8bpp[0], "r c #303030");
sprintf(BGColor8bpp[1], "s c #303030");
sprintf(BGColor8bpp[2], "t c #303030");
sprintf(BGColor8bpp[3], "u c #303030");
sprintf(BGColor8bpp[4], "v c #303030");
sprintf(BGColor8bpp[5], "w c #303030");
sprintf(BGColor8bpp[6], "x c #303030");
sprintf(BGColor8bpp[7], "a c #202020");
sprintf(BGColor8bpp[8], "b c #202020");
for (tmp = 0; tmp < 7; ++tmp)
background[tmp+7] = BGColor8bpp[tmp];
background[2] = BGColor8bpp[7];
background[3] = BGColor8bpp[8];
}
status = XpmCreatePixmapFromData(
mainDisplay, /* display */
Root, /* window */
background, /* xpm */
&backgroundXpm.pixmap, /* resulting pixmap */
&backgroundXpm.mask,
&backgroundXpm.attributes
);
if(status != XpmSuccess) {
printf("asapm : (%d) not enough free color cells for background.\n", status);
XCloseDisplay(mainDisplay);
exit(1);
}
if (strlen(mainGeometry)) {
/* Check the user-specified size */
result = XParseGeometry(
mainGeometry,
&SizeHints.x,
&SizeHints.y,
&SizeHints.width,
&SizeHints.height
);
if (result & XNegative)
x_negative = 1;
if (result & YNegative)
y_negative = 1;
}
SizeHints.flags= USSize|USPosition;
SizeHints.x = 0;
SizeHints.y = 0;
XWMGeometry(
mainDisplay,
screen,
mainGeometry, /* user_geometry */
NULL, /* default_geometry */
1, /* border_width */
& SizeHints, /* hints */
&SizeHints.x, /* x_return */
&SizeHints.y, /* y_return */
&SizeHints.width, /* width_return */
&SizeHints.height, /* height_return */
&gravity /* gravity_return */
);
/* printf("Icon size: min %dx%d max %dx%d WM req %dx%d\n",
SizeHints.min_width, SizeHints.min_height,
SizeHints.max_width, SizeHints.max_height,
SizeHints.width, SizeHints.height); */
SizeHints.min_width =
SizeHints.max_width =
SizeHints.width = backgroundXpm.attributes.width;
SizeHints.min_height =
SizeHints.max_height =
SizeHints.height= backgroundXpm.attributes.height;
SizeHints.flags |= PMinSize|PMaxSize;
/* Correct the offsets if the X/Y are negative */
SizeHints.win_gravity = NorthWestGravity;
if (x_negative) {
SizeHints.x -= SizeHints.width;
SizeHints.win_gravity = NorthEastGravity;
}
if (y_negative) {
SizeHints.y -= SizeHints.height;
if (x_negative)
SizeHints.win_gravity = SouthEastGravity;
else
SizeHints.win_gravity = SouthWestGravity;
}
SizeHints.flags |= PWinGravity;
mainWindow = XCreateSimpleWindow(
mainDisplay, /* display */
Root, /* parent */
SizeHints.x, /* x */
SizeHints.y, /* y */
SizeHints.width, /* width */
SizeHints.height, /* height */
0, /* border_width */
fore_pix, /* border */
back_pix /* background */
);
iconWindow = XCreateSimpleWindow(
mainDisplay, /* display */
Root, /* parent */
SizeHints.x, /* x */
SizeHints.y, /* y */
SizeHints.width, /* width */
SizeHints.height, /* height */
0, /* border_width */
fore_pix, /* border */
back_pix /* background */
);
XSetWMNormalHints(mainDisplay, mainWindow, &SizeHints);
XSetWMNormalHints(mainDisplay, iconWindow, &SizeHints);
status = XClearWindow(mainDisplay, mainWindow);
status = XClearWindow(mainDisplay, iconWindow);
/*xiconsize = XAllocIconSize();
xiconsize->min_width =
xiconsize->max_width = SizeHints.width;
xiconsize->min_height =
xiconsize->max_height = SizeHints.height;
XSetIconSizes(mainDisplay,mainWindow,xiconsize,1);
XSetIconSizes(mainDisplay,iconWindow,xiconsize,1);
status = XGetIconSizes( mainDisplay,mainWindow,&xiconsize,&tmp );
printf("Got icon size: min %dx%d max %dx%d\n",
xiconsize->min_width, xiconsize->min_height,
xiconsize->max_width, xiconsize->max_height);
printf("Status %d, count %d\n", status, tmp);*/
status = XGetWindowAttributes(
mainDisplay, /* display */
mainWindow, /* window */
& winAttr /* window_attributes_return */
);
status = XSetWindowBackgroundPixmap(
mainDisplay, /* display */
mainWindow, /* window */
backgroundXpm.pixmap /* background_pixmap */
);
status = XSetWindowBackgroundPixmap(
mainDisplay, /* display */
iconWindow, /* window */
backgroundXpm.pixmap /* background_pixmap */
);
status = XStringListToTextProperty(&app_name, 1, &title);
XSetWMName(mainDisplay, mainWindow, &title);
XSetWMName(mainDisplay, iconWindow, &title);
classHint.res_name = "asapm" ;
classHint.res_class = "ASAPM";
XSetClassHint(mainDisplay, mainWindow, &classHint);
XStoreName(mainDisplay, mainWindow, "asapm");
XSetIconName(mainDisplay, mainWindow, "asapm");
status = XSelectInput(
mainDisplay, /* display */
mainWindow, /* window */
ExposureMask /* event_mask */
);
status = XSelectInput(
mainDisplay, /* display */
iconWindow, /* window */
ExposureMask /* event_mask */
);
/* Creating Graphics context */
mainGCV.foreground = fore_pix;
mainGCV.background = back_pix;
mainGCV.graphics_exposures = False;
mainGCV.line_style = LineSolid;
mainGCV.fill_style = FillSolid;
mainGCV.line_width = 1;
mainGC = XCreateGC(
mainDisplay,
mainWindow,
GCForeground|GCBackground|GCLineWidth|
GCLineStyle|GCFillStyle,
&mainGCV
);
status = XSetCommand(mainDisplay, mainWindow, argv, argc);
/* Set up the event for quitting the window */
wm_delete_window = XInternAtom(
mainDisplay,
"WM_DELETE_WINDOW", /* atom_name */
False /* only_if_exists */
);
wm_protocols = XInternAtom(
mainDisplay,
"WM_PROTOCOLS", /* atom_name */
False /* only_if_exists */
);
status = XSetWMProtocols(
mainDisplay,
mainWindow,
&wm_delete_window,
1
);
status = XSetWMProtocols(
mainDisplay,
iconWindow,
&wm_delete_window,
1
);
WmHints.flags = StateHint | IconWindowHint;
WmHints.initial_state =
withdrawn ? WithdrawnState :
iconic ? IconicState : NormalState;
WmHints.icon_window = iconWindow;
if ( withdrawn ) {
WmHints.window_group = mainWindow;
WmHints.flags |= WindowGroupHint;
}
if ( iconic || withdrawn ) {
WmHints.icon_x = SizeHints.x;
WmHints.icon_y = SizeHints.y;
WmHints.flags |= IconPositionHint;
}
XSetWMHints(
mainDisplay,
mainWindow,
&WmHints);
/* Finally show the window */
status = XMapWindow(
mainDisplay,
mainWindow
);
/* get the colors */
greenPixel = GetColor(slidercolor);
redPixel = GetColor(sliderbgcolor);
greenTextPixel = GetColor(greencolor);
yellowTextPixel = GetColor(yellowcolor);
redTextPixel = GetColor(redcolor);
if ( state.color_depth == 8 ) {
darkgreenPixel = greenPixel;
semidarkgreenPixel = greenPixel;
bitdarkgreenPixel = greenPixel;
darkredPixel = redPixel;
semidarkredPixel = redPixel;
bitdarkredPixel = redPixel;
lightgreenPixel = greenPixel;
semilightgreenPixel = greenPixel;
bitlightgreenPixel = greenPixel;
lightredPixel = redPixel;
semilightredPixel = redPixel;
bitlightredPixel = redPixel;
} else {
/* scale the colors */
darkgreenPixel = DarkenColor(slidercolor, 1.4);
semidarkgreenPixel = DarkenColor(slidercolor, 1.2);
bitdarkgreenPixel = DarkenColor(slidercolor, 1.1);
darkredPixel = DarkenColor(sliderbgcolor, 1.4);
semidarkredPixel = DarkenColor(sliderbgcolor, 1.2);
bitdarkredPixel = DarkenColor(sliderbgcolor, 1.1);
lightgreenPixel = LightenColor(slidercolor, 1.4);
semilightgreenPixel = LightenColor(slidercolor, 1.2);
bitlightgreenPixel = LightenColor(slidercolor, 1.1);
lightredPixel = LightenColor(sliderbgcolor, 1.4);
semilightredPixel = LightenColor(sliderbgcolor, 1.2);
bitlightredPixel = LightenColor(sliderbgcolor, 1.1);
}
alphabet = embossed ? alphabet_in : alphabet_out;
/* adjust the color for digits */
tmp_color = ParseColor(statuscolor);
sprintf(alphabetColor, "# c #%.2x%.2x%.2x",
(int) (tmp_color.red / 257),
(int) (tmp_color.green / 257),
(int) (tmp_color.blue / 257));
alphabet[2] = alphabetColor;
#ifdef DEBUG
printf("alphabet color [%s]\n", alphabetColor);
#endif
if ( state.color_depth == 8 ) {
sprintf(alphabetLowColor, "c c #303030");
alphabet[4] = alphabetLowColor;
} else {
sprintf(alphabetLowColor, "c c #%.2x%.2x%.2x",
(int) (tmp_color.red / 257 / 1.5),
(int) (tmp_color.green / 257 / 1.6),
(int) (tmp_color.blue / 257 / 1.6));
alphabet[4] = alphabetLowColor;
}
#ifdef DEBUG
printf("alphabet low color [%s]\n", alphabetLowColor);
#endif
alphabetXpm.attributes.valuemask |=
(XpmReturnPixels | XpmReturnExtensions
| XpmExactColors | XpmCloseness);
alphabetXpm.attributes.exactColors = False;
alphabetXpm.attributes.closeness = 65536;
status = XpmCreatePixmapFromData(
mainDisplay, /* display */
Root, /* window */
alphabet, /* xpm */
&alphabetXpm.pixmap, /* resulting pixmap */
&alphabetXpm.mask,
&alphabetXpm.attributes
);
if(status != XpmSuccess) {
printf("asapm : (%d) not enough free color cells for alphabet.\n", status);
XCloseDisplay(mainDisplay);
exit(1);
}
/* wait for the Expose event now */
XNextEvent(mainDisplay, &Event);
/* We 've got Expose -> draw the parts of the window. */
Redraw();
XFlush(mainDisplay);
}
/*
* Draw the slider bar. The slider bar has two
* colors. The bottom side shows the percent left
* of the battery's charge (greenPixel) and
* the top shows the rest (redPixel)
*/
void DrawIndicator(Window win)
{
int points;
if (state.percent < 0) {
/* clear previously drawn label */
XClearArea(
mainDisplay,
win,
2,
4,
7,
42,
False
);
return;
}
points = (state.percent==100) ? 42 : (42.0/100 * state.percent);
/* set green color */
mainGCV.foreground = greenPixel;
XChangeGC(
mainDisplay,
mainGC,
GCForeground,
&mainGCV
);
/* draw the bottom part of the indicator */
XFillRectangle(
mainDisplay,
win,
mainGC,
5,
4+42-points, /*4,*/
1,
points
);
mainGCV.foreground = darkgreenPixel;
XChangeGC(
mainDisplay,
mainGC,
GCForeground,
&mainGCV
);
XFillRectangle(
mainDisplay,
win,
mainGC,
8,
4+42-points, /*4,*/
1,
points
);
mainGCV.foreground = semidarkgreenPixel;
XChangeGC(
mainDisplay,
mainGC,
GCForeground,
&mainGCV
);
XFillRectangle(
mainDisplay,
win,
mainGC,
7,
4+42-points, /*4,*/
1,
points
);
mainGCV.foreground = bitdarkgreenPixel;
XChangeGC(
mainDisplay,
mainGC,
GCForeground,
&mainGCV
);
XFillRectangle(
mainDisplay,
win,
mainGC,
6,
4+42-points, /*4,*/
1,
points
);
mainGCV.foreground = lightgreenPixel;
XChangeGC(
mainDisplay,
mainGC,
GCForeground,
&mainGCV
);
XFillRectangle(
mainDisplay,
win,
mainGC,
2,
4+42-points, /*4,*/
1,
points
);
mainGCV.foreground = semilightgreenPixel;
XChangeGC(
mainDisplay,
mainGC,
GCForeground,
&mainGCV
);
XFillRectangle(
mainDisplay,
win,
mainGC,
3,
4+42-points, /*4,*/
1,
points
);
mainGCV.foreground = bitlightgreenPixel;
XChangeGC(
mainDisplay,
mainGC,
GCForeground,
&mainGCV
);
XFillRectangle(
mainDisplay,
win,
mainGC,
4,
4+42-points, /*4,*/
1,
points
);
/* set red color */
mainGCV.foreground = redPixel;
XChangeGC(
mainDisplay,
mainGC,
GCForeground,
&mainGCV
);
/* draw right side of the indicator */
XFillRectangle(
mainDisplay,
win,
mainGC,
3,
4, /*4+points,*/
4,
42-points
);
mainGCV.foreground = lightredPixel;
XChangeGC(
mainDisplay,
mainGC,
GCForeground,
&mainGCV
);
XFillRectangle(
mainDisplay,
win,
mainGC,
8,
4, /*4+points,*/
1,
42-points
);
mainGCV.foreground = semilightredPixel;
XChangeGC(
mainDisplay,
mainGC,
GCForeground,
&mainGCV
);
XFillRectangle(
mainDisplay,
win,
mainGC,
7,
4, /*4+points,*/
1,
42-points
);
mainGCV.foreground = bitlightredPixel;
XChangeGC(
mainDisplay,
mainGC,
GCForeground,
&mainGCV
);
XFillRectangle(
mainDisplay,
win,
mainGC,
6,
4, /*4+points,*/
1,
42-points
);
mainGCV.foreground = darkredPixel;
XChangeGC(
mainDisplay,
mainGC,
GCForeground,
&mainGCV
);
XFillRectangle(
mainDisplay,
win,
mainGC,
2,
4, /*4+points,*/
1,
42-points
);
mainGCV.foreground = semidarkredPixel;
XChangeGC(
mainDisplay,
mainGC,
GCForeground,
&mainGCV
);
XFillRectangle(
mainDisplay,
win,
mainGC,
3,
4, /*4+points,*/
1,
42-points
);
mainGCV.foreground = bitdarkredPixel;
XChangeGC(
mainDisplay,
mainGC,
GCForeground,
&mainGCV
);
XFillRectangle(
mainDisplay,
win,
mainGC,
4,
4, /*4+points,*/
1,
42-points
);
}
void DrawBattery( Window win )
{
Pixel theColor;
switch ( state.battery_status )
{
case BATTERY_CRITICAL:
/* third is "red" */
theColor = redTextPixel;
break;
case BATTERY_LOW:
/* second is "yellow" */
theColor = yellowTextPixel;
break;
case BATTERY_UNKNOWN:
theColor = BlackPixel(mainDisplay, DefaultScreen(mainDisplay));
break;
case BATTERY_HIGH:
case BATTERY_CHARGING:
default:
/* first is "green" */
theColor = greenTextPixel;
break;
}
/* set the chosen color */
mainGCV.foreground = theColor;
XChangeGC(
mainDisplay,
mainGC,
GCForeground,
&mainGCV
);
/* draw the battery image */
XDrawLines(
mainDisplay,
win,
mainGC,
batteryImage,
9,
CoordModeOrigin
);
/* clear previously drawn label */
XClearArea(
mainDisplay,
win,
AC_IMAGE_X,
AC_IMAGE_Y,
13,
6,
False
);
if ( state.ac_line_status == AC_ONLINE )
{
if ( state.battery_status == BATTERY_CHARGING ) {
/* set red color */
mainGCV.foreground = redTextPixel;
} else {
/* set green color */
mainGCV.foreground = greenTextPixel;
}
XChangeGC(
mainDisplay,
mainGC,
GCForeground,
&mainGCV
);
XDrawPoints(
mainDisplay,
win,
mainGC,
acImage,
28,
CoordModeOrigin
);
}
}
void DrawPercent(Window win)
{
int tmp[4];
int i;
if ( state.percent > 0 ) {
if ( state.percent / 100 )
tmp[0] = state.percent / 100;
else
tmp[0] = 10;
tmp[1] = state.percent % 100 / 10;
tmp[2] = state.percent % 100 % 10;
tmp[3] = 12;
} else {
tmp[0] = 10;
tmp[1] = 10;
tmp[2] = 10;
tmp[3] = 14;
}
for (i=0; i<4; ++i)
XCopyArea(
mainDisplay,
alphabetXpm.pixmap,
win,
mainGC,
alphabetPosition[tmp[i]],
0,
alphabetSize[tmp[i]],
11,
percentPosition[i],
16
);
}
void DrawTime(Window win)
{
int tmp[5];
int i;
int firstDigit = 0;
int time_left;
if ( (state.time_left > 0) && (state.system_time) )
time_left = state.time_left;
else
time_left = state.time_estimate;
if ( time_left > 0 ) {
if ( time_left / 60 / 10 % 10 ) {
tmp[0] = time_left / 60 / 10 % 10;
firstDigit = 1;
} else
tmp[0] = 10;
if ( firstDigit || (time_left / 60 % 10) )
tmp[1] = time_left / 60 % 10;
else
tmp[1] = 10;
tmp[2] = 11;
tmp[3] = time_left % 60 / 10;
tmp[4] = time_left % 60 % 10;
} else {
tmp[0] = 10;
tmp[1] = 10;
tmp[2] = 13;
tmp[3] = 10;
tmp[4] = 10;
}
for (i=0; i<5; ++i)
XCopyArea(
mainDisplay,
alphabetXpm.pixmap,
win,
mainGC,
alphabetPosition[tmp[i]],
0,
alphabetSize[tmp[i]],
11,
timePosition[i],
33
);
}
/* This requests redrawing of all elements */
void Redraw()
{
DrawIndicator(mainWindow);
DrawBattery(mainWindow);
DrawPercent(mainWindow);
DrawTime(mainWindow);
DrawIndicator(iconWindow);
DrawBattery(iconWindow);
DrawPercent(iconWindow);
DrawTime(iconWindow);
}
/*
* This checks for X11 events. We distinguish the following:
* - request to repaint the window
* - request to quit (Close button)
*/
void CheckX11Events()
{
XEvent Event;
while (XPending(mainDisplay)) {
XNextEvent(mainDisplay, &Event);
switch(Event.type)
{
case Expose:
if(Event.xexpose.count == 0)
++state.update;
break;
case ClientMessage:
if ((Event.xclient.message_type == wm_protocols)
&& (Event.xclient.data.l[0] == wm_delete_window))
Cleanup();
break;
}
}
}
syntax highlighted by Code2HTML, v. 0.9.1