diff --git a/replicants/Battery/src/main.c b/replicants/Battery/src/main.c index 50bdc9e..b10f158 100644 --- a/replicants/Battery/src/main.c +++ b/replicants/Battery/src/main.c @@ -115,7 +115,7 @@ Widget Battery_XmdReplicantCreate ( XtManageChild(this->layout); XtManageChild(this->root); - return this->layout; + return this->root; } BatteryInfo getBatteryInfo (void) { diff --git a/replicants/Clock/build.sh b/replicants/Clock/build.sh new file mode 100755 index 0000000..2bb3cd2 --- /dev/null +++ b/replicants/Clock/build.sh @@ -0,0 +1,2 @@ +#!/bin/sh +../../scripts/buildreplicant.sh Clock "$@" diff --git a/replicants/Clock/src/main.c b/replicants/Clock/src/main.c new file mode 100644 index 0000000..b634959 --- /dev/null +++ b/replicants/Clock/src/main.c @@ -0,0 +1,148 @@ +#define _XOPEN_SOURCE +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +typedef struct { + unsigned long pollInterval; + Bool analog; + String format; + XtAppContext application; + Widget root; + Widget face; + GC gc; + XtIntervalId timer; +} ClockReplicant; + +static void clockPoll (XtPointer, XtIntervalId *); +static void resetClockPollTimeout (ClockReplicant *); +static void handleDestroy (Widget, XtPointer, XtPointer); + +int Clock_XmdReplicantVersion (void) { + return XmdREPLICANT_VERSION; +} + +Widget Clock_XmdReplicantCreate ( + XtAppContext application, + Widget parent, + XmdReplicantState *state +) { + (void)(state); + + ClockReplicant *this = XtNew(ClockReplicant); + memset(this, 0, sizeof(*this)); + this->application = application; + + /* read state */ + String pollIntervalString = XmdReplicantStateQuery(state, "Interval"); + if (pollIntervalString != NULL) { + this->pollInterval = 1000 * atoi(pollIntervalString); + } + if (this->pollInterval == 0) this->pollInterval = 1000; + XtFree(pollIntervalString); + String typeString = XmdReplicantStateQuery(state, "Type"); + this->analog = strcmp(typeString, "Analog") == 0; + XtFree(typeString); + this->format = XmdReplicantStateQuery(state, "Format"); + if (this->format == NULL) this->format = XtNewString("%H:%M:%S"); + + /* create widgets */ + this->root = XtVaCreateWidget ( + "clock", xmFrameWidgetClass, parent, + XmNshadowType, XmSHADOW_ETCHED_IN, + NULL); + XtAddCallback(this->root, XmNdestroyCallback, handleDestroy, NULL); + if (this->analog) { + /* analog */ + this->face = XtVaCreateWidget ( + "clockFace", xmDrawingAreaWidgetClass, this->root, + XmNwidth, 48, + XmNheight, 48, + XmNresizePolicy, XmRESIZE_NONE, + NULL); + XGCValues values = { 0 }; + XtVaGetValues (parent, + XmNforeground, &values.foreground, + XmNbackground, &values.background, + NULL); + this->gc = XCreateGC ( + XtDisplay(this->face), + RootWindowOfScreen(XtScreen(this->face)), + GCForeground | GCBackground, &values); + XtManageChild(this->face); + } else { + /* digital */ + this->face = XtVaCreateManagedWidget ( + "clockFace", xmLabelWidgetClass, this->root, + XmNmarginWidth, 8, + XmNmarginHeight, 8, + NULL); + } + + clockPoll(this, NULL); + XtManageChild(this->root); + return this->root; +} + +void clockPoll (XtPointer clientData, XtIntervalId *timer) { + (void)(clientData); + (void)(timer); + + ClockReplicant *this = clientData; + + if (this->analog) { + /*Display *display = XtDisplay(this->face); + Window window = XtWindow(this->face); + + XDrawLine(display, window, this->gc, 0, 0, 32, 32); + + XClearWindow(display, window);*/ + } else { + time_t now = time(NULL); + struct tm *local = localtime(&now); + char timeBuffer[64]; + strftime(timeBuffer, XtNumber(timeBuffer), this->format, local); + + XmString timeString = XmStringCreateLocalized(timeBuffer); + XtUnmanageChild(this->face); + XtVaSetValues ( + this->face, + XmNlabelString, timeString, + NULL); + XtManageChild(this->face); + XmStringFree(timeString); + } + + resetClockPollTimeout(this); +} + +void resetClockPollTimeout (ClockReplicant *this) { + this->timer = XtAppAddTimeOut ( + this->application, this->pollInterval, clockPoll, this); +} + +static void handleDestroy ( + Widget widget, + XtPointer clientData, + XtPointer callData +) { + (void)(callData); + (void)(widget); + + ClockReplicant *this = clientData; + XtRemoveTimeOut(this->timer); + XtFree(this->format); + XtFree((char *)(this)); +}