Add battery replicant
This commit is contained in:
parent
0e99b0ceed
commit
5872791bfb
2
replicants/Battery/build.sh
Executable file
2
replicants/Battery/build.sh
Executable file
@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
../../scripts/buildreplicant.sh Battery "$@"
|
15
replicants/Battery/src/icons/charging.xbm
Normal file
15
replicants/Battery/src/icons/charging.xbm
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#define charging_width 48
|
||||||
|
#define charging_height 24
|
||||||
|
static unsigned char charging_bits[] = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f,
|
||||||
|
0x18, 0x03, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xf6, 0xff, 0xff, 0xff, 0x33,
|
||||||
|
0x0c, 0xf6, 0xff, 0xff, 0xff, 0x37, 0x0c, 0xe6, 0xff, 0x3f, 0xfe, 0x37,
|
||||||
|
0x46, 0xec, 0xff, 0x07, 0xff, 0x67, 0xe6, 0xec, 0xff, 0x80, 0xff, 0x6f,
|
||||||
|
0xe6, 0xec, 0x1f, 0xc0, 0xff, 0x6f, 0xe6, 0xec, 0x07, 0xe3, 0xff, 0x6f,
|
||||||
|
0xe6, 0xec, 0xff, 0x63, 0xf0, 0x6f, 0xe6, 0xec, 0xff, 0x01, 0xfc, 0x6f,
|
||||||
|
0xe6, 0xec, 0xff, 0x80, 0xff, 0x6f, 0x46, 0xec, 0x7f, 0xf0, 0xff, 0x67,
|
||||||
|
0x0c, 0xe6, 0x3f, 0xfe, 0xff, 0x37, 0x0c, 0xf6, 0xff, 0xff, 0xff, 0x37,
|
||||||
|
0x0c, 0xf6, 0xff, 0xff, 0xff, 0x33, 0x18, 0x03, 0x00, 0x00, 0x00, 0x18,
|
||||||
|
0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
15
replicants/Battery/src/icons/error.xbm
Normal file
15
replicants/Battery/src/icons/error.xbm
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#define error_width 48
|
||||||
|
#define error_height 24
|
||||||
|
static unsigned char error_bits[] = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f,
|
||||||
|
0x18, 0x03, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x30,
|
||||||
|
0x0c, 0x06, 0x40, 0x80, 0x00, 0x30, 0x0c, 0x06, 0xe0, 0xc0, 0x01, 0x30,
|
||||||
|
0x46, 0x0c, 0xc0, 0xe1, 0x00, 0x60, 0xe6, 0x0c, 0x80, 0x73, 0x00, 0x60,
|
||||||
|
0xe6, 0x0c, 0x00, 0x3f, 0x00, 0x60, 0xe6, 0x0c, 0x00, 0x1e, 0x00, 0x60,
|
||||||
|
0xe6, 0x0c, 0x00, 0x1e, 0x00, 0x60, 0xe6, 0x0c, 0x00, 0x3f, 0x00, 0x60,
|
||||||
|
0xe6, 0x0c, 0x80, 0x73, 0x00, 0x60, 0x46, 0x0c, 0xc0, 0xe1, 0x00, 0x60,
|
||||||
|
0x0c, 0x06, 0xe0, 0xc0, 0x01, 0x30, 0x0c, 0x06, 0x40, 0x80, 0x00, 0x30,
|
||||||
|
0x0c, 0x06, 0x00, 0x00, 0x00, 0x30, 0x18, 0x03, 0x00, 0x00, 0x00, 0x18,
|
||||||
|
0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
15
replicants/Battery/src/icons/level0.xbm
Normal file
15
replicants/Battery/src/icons/level0.xbm
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#define level0_width 48
|
||||||
|
#define level0_height 24
|
||||||
|
static unsigned char level0_bits[] = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f,
|
||||||
|
0x18, 0x03, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x32,
|
||||||
|
0x0c, 0x06, 0x00, 0x02, 0x00, 0x37, 0x0c, 0x06, 0x00, 0x07, 0x00, 0x37,
|
||||||
|
0x46, 0x0c, 0x00, 0x07, 0x00, 0x67, 0xe6, 0x0c, 0x00, 0x07, 0x80, 0x6f,
|
||||||
|
0xe6, 0x0c, 0x00, 0x07, 0x80, 0x6f, 0xe6, 0x0c, 0x00, 0x07, 0x80, 0x6f,
|
||||||
|
0xe6, 0x0c, 0x00, 0x02, 0x80, 0x6f, 0xe6, 0x0c, 0x00, 0x02, 0x80, 0x6f,
|
||||||
|
0xe6, 0x0c, 0x00, 0x00, 0x80, 0x6f, 0x46, 0x0c, 0x00, 0x02, 0x00, 0x67,
|
||||||
|
0x0c, 0x06, 0x00, 0x07, 0x00, 0x37, 0x0c, 0x06, 0x00, 0x02, 0x00, 0x37,
|
||||||
|
0x0c, 0x06, 0x00, 0x00, 0x00, 0x32, 0x18, 0x03, 0x00, 0x00, 0x00, 0x18,
|
||||||
|
0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
15
replicants/Battery/src/icons/level1.xbm
Normal file
15
replicants/Battery/src/icons/level1.xbm
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#define level1_width 48
|
||||||
|
#define level1_height 24
|
||||||
|
static unsigned char level1_bits[] = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f,
|
||||||
|
0x18, 0x03, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x06, 0x00, 0x00, 0xfe, 0x33,
|
||||||
|
0x0c, 0x06, 0x00, 0x00, 0xff, 0x37, 0x0c, 0x06, 0x00, 0x00, 0xff, 0x37,
|
||||||
|
0x46, 0x0c, 0x00, 0x00, 0xff, 0x67, 0xe6, 0x0c, 0x00, 0x80, 0xff, 0x6f,
|
||||||
|
0xe6, 0x0c, 0x00, 0x80, 0xff, 0x6f, 0xe6, 0x0c, 0x00, 0x80, 0xff, 0x6f,
|
||||||
|
0xe6, 0x0c, 0x00, 0x80, 0xff, 0x6f, 0xe6, 0x0c, 0x00, 0x80, 0xff, 0x6f,
|
||||||
|
0xe6, 0x0c, 0x00, 0x80, 0xff, 0x6f, 0x46, 0x0c, 0x00, 0x00, 0xff, 0x67,
|
||||||
|
0x0c, 0x06, 0x00, 0x00, 0xff, 0x37, 0x0c, 0x06, 0x00, 0x00, 0xff, 0x37,
|
||||||
|
0x0c, 0x06, 0x00, 0x00, 0xfe, 0x33, 0x18, 0x03, 0x00, 0x00, 0x00, 0x18,
|
||||||
|
0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
15
replicants/Battery/src/icons/level2.xbm
Normal file
15
replicants/Battery/src/icons/level2.xbm
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#define level2_width 48
|
||||||
|
#define level2_height 24
|
||||||
|
static unsigned char level2_bits[] = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f,
|
||||||
|
0x18, 0x03, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x06, 0x00, 0xf8, 0xff, 0x33,
|
||||||
|
0x0c, 0x06, 0x00, 0xfc, 0xff, 0x37, 0x0c, 0x06, 0x00, 0xfc, 0xff, 0x37,
|
||||||
|
0x46, 0x0c, 0x00, 0xfc, 0xff, 0x67, 0xe6, 0x0c, 0x00, 0xfe, 0xff, 0x6f,
|
||||||
|
0xe6, 0x0c, 0x00, 0xfe, 0xff, 0x6f, 0xe6, 0x0c, 0x00, 0xfe, 0xff, 0x6f,
|
||||||
|
0xe6, 0x0c, 0x00, 0xfe, 0xff, 0x6f, 0xe6, 0x0c, 0x00, 0xfe, 0xff, 0x6f,
|
||||||
|
0xe6, 0x0c, 0x00, 0xfe, 0xff, 0x6f, 0x46, 0x0c, 0x00, 0xfc, 0xff, 0x67,
|
||||||
|
0x0c, 0x06, 0x00, 0xfc, 0xff, 0x37, 0x0c, 0x06, 0x00, 0xfc, 0xff, 0x37,
|
||||||
|
0x0c, 0x06, 0x00, 0xf8, 0xff, 0x33, 0x18, 0x03, 0x00, 0x00, 0x00, 0x18,
|
||||||
|
0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
15
replicants/Battery/src/icons/level3.xbm
Normal file
15
replicants/Battery/src/icons/level3.xbm
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#define level3_width 48
|
||||||
|
#define level3_height 24
|
||||||
|
static unsigned char level3_bits[] = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f,
|
||||||
|
0x18, 0x03, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x06, 0xfe, 0xff, 0xff, 0x33,
|
||||||
|
0x0c, 0x06, 0xff, 0xff, 0xff, 0x37, 0x0c, 0x06, 0xff, 0xff, 0xff, 0x37,
|
||||||
|
0x46, 0x0c, 0xff, 0xff, 0xff, 0x67, 0xe6, 0x8c, 0xff, 0xff, 0xff, 0x6f,
|
||||||
|
0xe6, 0x8c, 0xff, 0xff, 0xff, 0x6f, 0xe6, 0x8c, 0xff, 0xff, 0xff, 0x6f,
|
||||||
|
0xe6, 0x8c, 0xff, 0xff, 0xff, 0x6f, 0xe6, 0x8c, 0xff, 0xff, 0xff, 0x6f,
|
||||||
|
0xe6, 0x8c, 0xff, 0xff, 0xff, 0x6f, 0x46, 0x0c, 0xff, 0xff, 0xff, 0x67,
|
||||||
|
0x0c, 0x06, 0xff, 0xff, 0xff, 0x37, 0x0c, 0x06, 0xff, 0xff, 0xff, 0x37,
|
||||||
|
0x0c, 0x06, 0xfe, 0xff, 0xff, 0x33, 0x18, 0x03, 0x00, 0x00, 0x00, 0x18,
|
||||||
|
0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
15
replicants/Battery/src/icons/level4.xbm
Normal file
15
replicants/Battery/src/icons/level4.xbm
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#define level4_width 48
|
||||||
|
#define level4_height 24
|
||||||
|
static unsigned char level4_bits[] = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f,
|
||||||
|
0x18, 0x03, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xf6, 0xff, 0xff, 0xff, 0x33,
|
||||||
|
0x0c, 0xf6, 0xff, 0xff, 0xff, 0x37, 0x0c, 0xe6, 0xff, 0xff, 0xff, 0x37,
|
||||||
|
0x46, 0xec, 0xff, 0xff, 0xff, 0x67, 0xe6, 0xec, 0xff, 0xff, 0xff, 0x6f,
|
||||||
|
0xe6, 0xec, 0xff, 0xff, 0xff, 0x6f, 0xe6, 0xec, 0xff, 0xff, 0xff, 0x6f,
|
||||||
|
0xe6, 0xec, 0xff, 0xff, 0xff, 0x6f, 0xe6, 0xec, 0xff, 0xff, 0xff, 0x6f,
|
||||||
|
0xe6, 0xec, 0xff, 0xff, 0xff, 0x6f, 0x46, 0xec, 0xff, 0xff, 0xff, 0x67,
|
||||||
|
0x0c, 0xe6, 0xff, 0xff, 0xff, 0x37, 0x0c, 0xf6, 0xff, 0xff, 0xff, 0x37,
|
||||||
|
0x0c, 0xf6, 0xff, 0xff, 0xff, 0x33, 0x18, 0x03, 0x00, 0x00, 0x00, 0x18,
|
||||||
|
0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
15
replicants/Battery/src/icons/not.xbm
Normal file
15
replicants/Battery/src/icons/not.xbm
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#define not_width 48
|
||||||
|
#define not_height 24
|
||||||
|
static unsigned char not_bits[] = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xa0, 0xaa, 0xaa, 0xaa, 0xaa, 0x02, 0x50, 0x55, 0x55, 0x55, 0x55, 0x05,
|
||||||
|
0x08, 0x02, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0x00, 0x00, 0x00, 0x10,
|
||||||
|
0x08, 0x02, 0x00, 0x00, 0x00, 0x20, 0x04, 0x04, 0x00, 0x00, 0x00, 0x10,
|
||||||
|
0x02, 0x08, 0x00, 0x00, 0x00, 0x20, 0x44, 0x04, 0x00, 0x00, 0x00, 0x40,
|
||||||
|
0xa2, 0x08, 0x00, 0x00, 0x00, 0x20, 0x44, 0x04, 0x00, 0x00, 0x00, 0x40,
|
||||||
|
0xa2, 0x08, 0x00, 0x00, 0x00, 0x20, 0x44, 0x04, 0x00, 0x00, 0x00, 0x40,
|
||||||
|
0xa2, 0x08, 0x00, 0x00, 0x00, 0x20, 0x44, 0x04, 0x00, 0x00, 0x00, 0x40,
|
||||||
|
0x08, 0x02, 0x00, 0x00, 0x00, 0x20, 0x04, 0x04, 0x00, 0x00, 0x00, 0x10,
|
||||||
|
0x08, 0x02, 0x00, 0x00, 0x00, 0x20, 0x10, 0x01, 0x00, 0x00, 0x00, 0x10,
|
||||||
|
0xa0, 0xaa, 0xaa, 0xaa, 0xaa, 0x0a, 0x40, 0x55, 0x55, 0x55, 0x55, 0x05,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
292
replicants/Battery/src/main.c
Normal file
292
replicants/Battery/src/main.c
Normal file
@ -0,0 +1,292 @@
|
|||||||
|
#define _XOPEN_SOURCE
|
||||||
|
#include <Xm/Xm.h>
|
||||||
|
#include <Xm/Frame.h>
|
||||||
|
#include <Xm/PushB.h>
|
||||||
|
#include <Xm/LabelG.h>
|
||||||
|
#include <Xm/MessageB.h>
|
||||||
|
#include <Xm/RowColumn.h>
|
||||||
|
#include <Xm/Separator.h>
|
||||||
|
|
||||||
|
#include <Xmd/Icon.h>
|
||||||
|
#include <Xmd/Exec.h>
|
||||||
|
#include <Xmd/Replicant.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
|
#include "icons/level0.xbm"
|
||||||
|
#include "icons/level1.xbm"
|
||||||
|
#include "icons/level2.xbm"
|
||||||
|
#include "icons/level3.xbm"
|
||||||
|
#include "icons/level4.xbm"
|
||||||
|
#include "icons/charging.xbm"
|
||||||
|
#include "icons/error.xbm"
|
||||||
|
#include "icons/not.xbm"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BatteryStateCharging,
|
||||||
|
BatteryStateNotCharging,
|
||||||
|
BatteryStateFull,
|
||||||
|
BatteryStateDischarging,
|
||||||
|
BatteryStateError
|
||||||
|
} BatteryState;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int level;
|
||||||
|
BatteryState state;
|
||||||
|
int hours;
|
||||||
|
int minutes;
|
||||||
|
int seconds;
|
||||||
|
} BatteryInfo;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned long pollInterval;
|
||||||
|
XtAppContext application;
|
||||||
|
Widget root;
|
||||||
|
Widget layout;
|
||||||
|
Widget icon;
|
||||||
|
Widget text;
|
||||||
|
XtIntervalId timer;
|
||||||
|
Pixmap levels[8];
|
||||||
|
} BatteryReplicant;
|
||||||
|
|
||||||
|
static BatteryInfo getBatteryInfo (void);
|
||||||
|
static Pixmap selectBatteryIcon (BatteryReplicant *, BatteryInfo);
|
||||||
|
static void loadAllPixmaps (BatteryReplicant *);
|
||||||
|
static void batteryPoll (XtPointer, XtIntervalId *);
|
||||||
|
static void resetBatteryPollTimeout (BatteryReplicant *);
|
||||||
|
static void handleBatteryInfoDialog (Widget, XtPointer, XtPointer);
|
||||||
|
static void handleDestroy (Widget, XtPointer, XtPointer);
|
||||||
|
|
||||||
|
int Battery_XmdReplicantVersion (void) {
|
||||||
|
return XmdREPLICANT_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget Battery_XmdReplicantCreate (
|
||||||
|
XtAppContext application,
|
||||||
|
Widget parent,
|
||||||
|
XmdReplicantState *state
|
||||||
|
) {
|
||||||
|
(void)(state);
|
||||||
|
|
||||||
|
BatteryReplicant *this = XtNew(BatteryReplicant);
|
||||||
|
memset(this, 0, sizeof(*this));
|
||||||
|
this->application = application;
|
||||||
|
|
||||||
|
String pollIntervalString = XmdReplicantStateQuery(state, "Interval");
|
||||||
|
if (pollIntervalString != NULL) {
|
||||||
|
this->pollInterval = 1000 * atoi(pollIntervalString);
|
||||||
|
}
|
||||||
|
if (this->pollInterval == 0) this->pollInterval = 2000;
|
||||||
|
XtFree(pollIntervalString);
|
||||||
|
|
||||||
|
this->root = XtVaCreateWidget (
|
||||||
|
"battery", xmFrameWidgetClass, parent,
|
||||||
|
XmNshadowType, XmSHADOW_ETCHED_IN,
|
||||||
|
NULL);
|
||||||
|
XtAddCallback(this->root, XmNdestroyCallback, handleDestroy, NULL);
|
||||||
|
this->layout = XtVaCreateWidget (
|
||||||
|
"batteryLayout", xmRowColumnWidgetClass, this->root,
|
||||||
|
XmNorientation, XmHORIZONTAL,
|
||||||
|
NULL);
|
||||||
|
this->icon = XtVaCreateManagedWidget (
|
||||||
|
"batteryIcon", xmPushButtonWidgetClass, this->layout,
|
||||||
|
XmNleftAttachment, XmATTACH_FORM,
|
||||||
|
XmNlabelType, XmPIXMAP,
|
||||||
|
NULL);
|
||||||
|
loadAllPixmaps(this);
|
||||||
|
XtAddCallback (
|
||||||
|
this->icon,
|
||||||
|
XmNactivateCallback, handleBatteryInfoDialog,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
XtVaCreateManagedWidget (
|
||||||
|
"batterySeparator", xmSeparatorWidgetClass, this->layout,
|
||||||
|
XmNorientation, XmVERTICAL,
|
||||||
|
NULL);
|
||||||
|
this->text = XtVaCreateManagedWidget (
|
||||||
|
"batteryText", xmLabelGadgetClass, this->layout,
|
||||||
|
XmNalignment, XmALIGNMENT_CENTER,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
batteryPoll(this, NULL);
|
||||||
|
|
||||||
|
XtManageChild(this->layout);
|
||||||
|
XtManageChild(this->root);
|
||||||
|
return this->layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
BatteryInfo getBatteryInfo (void) {
|
||||||
|
BatteryInfo result = { 0 };
|
||||||
|
char charging[16] = { 0 };
|
||||||
|
int battery;
|
||||||
|
|
||||||
|
pid_t child;
|
||||||
|
FILE *stream = XmdVaPipedExecPath (
|
||||||
|
"acpi", &child, "r",
|
||||||
|
"acpi", "-b",
|
||||||
|
NULL);
|
||||||
|
if (stream == NULL) {
|
||||||
|
result.state = BatteryStateError;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
fscanf (
|
||||||
|
stream, "Battery %d: %16s %d%%, %d:%d:%d",
|
||||||
|
&battery, charging, &result.level,
|
||||||
|
&result.hours, &result.minutes, &result.seconds);
|
||||||
|
|
||||||
|
switch (charging[0]) {
|
||||||
|
case 'C': result.state = BatteryStateCharging; break;
|
||||||
|
case 'N': result.state = BatteryStateNotCharging; break;
|
||||||
|
case 'D': result.state = BatteryStateDischarging; break;
|
||||||
|
case 'F': result.state = BatteryStateFull; break;
|
||||||
|
default: result.state = BatteryStateError; break;
|
||||||
|
}
|
||||||
|
if (fclose(stream) != 0) {
|
||||||
|
result.state = BatteryStateError;
|
||||||
|
}
|
||||||
|
waitpid(child, NULL, 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Pixmap selectBatteryIcon (BatteryReplicant *this, BatteryInfo info) {
|
||||||
|
if (info.state == BatteryStateCharging) {
|
||||||
|
return this->levels[5];
|
||||||
|
} else if (info.state == BatteryStateNotCharging) {
|
||||||
|
return this->levels[7];
|
||||||
|
} else if (info.state == BatteryStateError) {
|
||||||
|
return this->levels[6];
|
||||||
|
} else if (info.level < 15) {
|
||||||
|
return this->levels[0];
|
||||||
|
} else if (info.level < 35) {
|
||||||
|
return this->levels[1];
|
||||||
|
} else if (info.level < 65) {
|
||||||
|
return this->levels[2];
|
||||||
|
} else if (info.level < 85) {
|
||||||
|
return this->levels[3];
|
||||||
|
} else {
|
||||||
|
return this->levels[4];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadAllPixmaps (BatteryReplicant *this) {
|
||||||
|
this->levels[0] = XmdLoadBitmapIcon(this->icon, level0);
|
||||||
|
this->levels[1] = XmdLoadBitmapIcon(this->icon, level1);
|
||||||
|
this->levels[2] = XmdLoadBitmapIcon(this->icon, level2);
|
||||||
|
this->levels[3] = XmdLoadBitmapIcon(this->icon, level3);
|
||||||
|
this->levels[4] = XmdLoadBitmapIcon(this->icon, level4);
|
||||||
|
this->levels[5] = XmdLoadBitmapIcon(this->icon, charging);
|
||||||
|
this->levels[6] = XmdLoadBitmapIcon(this->icon, error);
|
||||||
|
this->levels[7] = XmdLoadBitmapIcon(this->icon, not);
|
||||||
|
}
|
||||||
|
|
||||||
|
void batteryPoll (XtPointer clientData, XtIntervalId *timer) {
|
||||||
|
(void)(clientData);
|
||||||
|
(void)(timer);
|
||||||
|
|
||||||
|
BatteryReplicant *this = clientData;
|
||||||
|
BatteryInfo info = getBatteryInfo();
|
||||||
|
|
||||||
|
XtVaSetValues (
|
||||||
|
this->icon,
|
||||||
|
XmNlabelType, XmPIXMAP,
|
||||||
|
XmNlabelPixmap, selectBatteryIcon(this, info),
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
char buffer[32];
|
||||||
|
snprintf(buffer, XtNumber(buffer), "%d%%", info.level);
|
||||||
|
|
||||||
|
/* if we don't unmanage and then re-manage the child, the text flies to
|
||||||
|
the top which is rather annoying. this little quirk bent me over and
|
||||||
|
fucked me for hours. */
|
||||||
|
XtUnmanageChild(this->text);
|
||||||
|
XmString string = XmStringCreateLocalized(buffer);
|
||||||
|
XtVaSetValues (
|
||||||
|
this->text,
|
||||||
|
XmNlabelString, string,
|
||||||
|
NULL);
|
||||||
|
XmStringFree(string);
|
||||||
|
XtManageChild(this->text);
|
||||||
|
|
||||||
|
resetBatteryPollTimeout(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetBatteryPollTimeout (BatteryReplicant *this) {
|
||||||
|
this->timer = XtAppAddTimeOut (
|
||||||
|
this->application, this->pollInterval, batteryPoll, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleBatteryInfoDialog (Widget button, XtPointer clientData, XtPointer callData) {
|
||||||
|
(void)(callData);
|
||||||
|
(void)(clientData);
|
||||||
|
|
||||||
|
BatteryInfo info = getBatteryInfo();
|
||||||
|
|
||||||
|
static const String states[] = {
|
||||||
|
"Charging",
|
||||||
|
"Not charging",
|
||||||
|
"Full",
|
||||||
|
"Discharging",
|
||||||
|
"Error"
|
||||||
|
};
|
||||||
|
|
||||||
|
String messageBuffer = NULL;
|
||||||
|
switch (info.state) {
|
||||||
|
case BatteryStateCharging:
|
||||||
|
XtAsprintf (
|
||||||
|
&messageBuffer,
|
||||||
|
"%d%%, %s\n"
|
||||||
|
"%d:%02d:%02d until charged.",
|
||||||
|
info.level, states[info.state],
|
||||||
|
info.hours, info.minutes, info.seconds);
|
||||||
|
break;
|
||||||
|
case BatteryStateDischarging:
|
||||||
|
XtAsprintf (
|
||||||
|
&messageBuffer,
|
||||||
|
"%d%%, %s\n"
|
||||||
|
"%d:%02d:%02d until empty.",
|
||||||
|
info.level, states[info.state],
|
||||||
|
info.hours, info.minutes, info.seconds);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
XtAsprintf (
|
||||||
|
&messageBuffer,
|
||||||
|
"%d%%, %s",
|
||||||
|
info.level, states[info.state]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Arg args[5] = { 0 };
|
||||||
|
int n = 0;
|
||||||
|
XmString message = XmStringCreateLocalized(messageBuffer);
|
||||||
|
XtSetArg(args[n], XmNmessageString, message); n ++;
|
||||||
|
XmString title = XmStringCreateLocalized("Battery Status");
|
||||||
|
XtSetArg(args[n], XmNdialogTitle, title); n ++;
|
||||||
|
|
||||||
|
Widget dialog = XmCreateInformationDialog(button, "batteryInfo", args, n);
|
||||||
|
|
||||||
|
XmStringFree(message);
|
||||||
|
XmStringFree(title);
|
||||||
|
|
||||||
|
XtManageChild(dialog);
|
||||||
|
XtPopup(XtParent(dialog), XtGrabNone);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handleDestroy (
|
||||||
|
Widget widget,
|
||||||
|
XtPointer clientData,
|
||||||
|
XtPointer callData
|
||||||
|
) {
|
||||||
|
(void)(callData);
|
||||||
|
(void)(widget);
|
||||||
|
|
||||||
|
BatteryReplicant *this = clientData;
|
||||||
|
XtRemoveTimeOut(this->timer);
|
||||||
|
for (Cardinal index = 0; index < XtNumber(this->levels); index ++) {
|
||||||
|
XFreePixmap(XtDisplay(this->layout), this->levels[index]);
|
||||||
|
}
|
||||||
|
XtFree((char *)(this));
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user