/* * asapm is the APM (Advanced Power Management) monitor utility for X Windows * Copyright (c) 1998-99 Albert Dorofeev * For the updates see http://bewoner.dma.be/Albert/linux/ * * This software is distributed under GPL. For details see LICENSE file. */ #include #include #include #include #include #include #include #include #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; } } }