/*
 * hh-greeter-power.c - a tiny Athena (Xaw) button bar with Shutdown and
 * Reboot buttons for the xdm greeter, each guarded by a confirmation popup.
 *
 * xdm's classic xlogin greeter has no power buttons, and the greeter display
 * runs with no window manager. This standalone client is launched by
 * Xsetup_0 (as root, so `zygctl poweroff`/`reboot` have the privilege to run)
 * and killed by Xstartup when a session begins, so it never leaks into the
 * user's desktop. Styling comes from the HhGreeterPower* resources in
 * Xresources (loaded by xrdb); placement from the -geometry Xsetup_0 passes.
 *
 * Build: cc hh-greeter-power.c -I$PREFIX/include -L$PREFIX/lib -R$PREFIX/lib \
 *        -lXaw7 -lXmu -lXt -lX11 -o hh-greeter-power
 */
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include <X11/Xaw/Box.h>
#include <X11/Xaw/Command.h>
#include <X11/Xaw/Dialog.h>
#include <stdlib.h>

static Widget toplevel;
static Widget confirm_popup = NULL;
static const char *pending_cmd = NULL;

static void
dismiss(void)
{
    if (confirm_popup != NULL) {
        XtPopdown(confirm_popup);
        XtDestroyWidget(confirm_popup);
        confirm_popup = NULL;
    }
}

static void
do_it(Widget w, XtPointer client, XtPointer call)
{
    (void) w; (void) client; (void) call;
    if (pending_cmd != NULL)
        (void) system(pending_cmd);   /* machine goes down; no return expected */
    dismiss();
}

static void
cancel(Widget w, XtPointer client, XtPointer call)
{
    (void) w; (void) client; (void) call;
    dismiss();
}

/* Pop a centered confirmation dialog for a power action. */
static void
confirm(const char *prompt, const char *cmd, const char *okLabel)
{
    Widget dlg;
    Dimension pw, ph;
    Position px, py;
    int sw, sh;

    dismiss();                 /* only one popup at a time */
    pending_cmd = cmd;

    confirm_popup = XtVaCreatePopupShell("confirm",
        transientShellWidgetClass, toplevel, (char *)NULL);
    dlg = XtVaCreateManagedWidget("dialog", dialogWidgetClass, confirm_popup,
        XtNlabel, prompt, (char *)NULL);
    XawDialogAddButton(dlg, okLabel, do_it, NULL);
    XawDialogAddButton(dlg, "Cancel", cancel, NULL);

    /* Center on screen (no window manager to place it). */
    XtRealizeWidget(confirm_popup);
    XtVaGetValues(confirm_popup, XtNwidth, &pw, XtNheight, &ph, (char *)NULL);
    sw = WidthOfScreen(XtScreen(toplevel));
    sh = HeightOfScreen(XtScreen(toplevel));
    px = (Position)((sw - (int)pw) / 2);
    py = (Position)((sh - (int)ph) / 2);
    XtVaSetValues(confirm_popup, XtNx, px, XtNy, py, (char *)NULL);
    XtPopup(confirm_popup, XtGrabExclusive);
}

static void
shutdown_cb(Widget w, XtPointer client, XtPointer call)
{
    (void) w; (void) client; (void) call;
    confirm("Shut down this system?", "/sbin/zygctl poweroff", "Shut down");
}

static void
reboot_cb(Widget w, XtPointer client, XtPointer call)
{
    (void) w; (void) client; (void) call;
    confirm("Reboot this system?", "/sbin/zygctl reboot", "Reboot");
}

int
main(int argc, char **argv)
{
    XtAppContext app;
    Widget box, sd, rb;

    toplevel = XtOpenApplication(&app, "HhGreeterPower", NULL, 0, &argc, argv,
        NULL, applicationShellWidgetClass, NULL, 0);

    box = XtVaCreateManagedWidget("box", boxWidgetClass, toplevel,
        XtNorientation, XtorientHorizontal, (char *)NULL);

    sd = XtVaCreateManagedWidget("Shutdown", commandWidgetClass, box,
        (char *)NULL);
    XtAddCallback(sd, XtNcallback, shutdown_cb, NULL);

    rb = XtVaCreateManagedWidget("Reboot", commandWidgetClass, box,
        (char *)NULL);
    XtAddCallback(rb, XtNcallback, reboot_cb, NULL);

    XtRealizeWidget(toplevel);
    XtAppMainLoop(app);
    return 0;
}
