/* A counter demonstrating Motif labels, buttons and containers. */
#include <stdio.h>
#include <X11/Intrinsic.h>
#include <Xm/Xm.h>
#include <Xm/Label.h>
#include <Xm/PushB.h>
#include <Xm/RowColumn.h>
#include <Xm/Protocols.h>

static unsigned int clicks;
static Widget status;

static void
update_status(void)
{
    char text[64];
    snprintf(text, sizeof text, "Clicks: %u", clicks);
    XmString label = XmStringCreateLocalized(text);
    XtVaSetValues(status, XmNlabelString, label, NULL);
    XmStringFree(label);
}

static void
count_click(Widget widget, XtPointer data, XtPointer call)
{
    (void)widget; (void)data; (void)call;
    ++clicks;
    update_status();
}

static void
reset_count(Widget widget, XtPointer data, XtPointer call)
{
    (void)widget; (void)data; (void)call;
    clicks = 0;
    update_status();
}

static void
quit(Widget widget, XtPointer data, XtPointer call)
{
    (void)data; (void)call;
    XtAppSetExitFlag(XtWidgetToApplicationContext(widget));
}

static Widget
labelled(Widget parent, const char *name, WidgetClass class, char *text)
{
    XmString label = XmStringCreateLocalized(text);
    Widget widget = XtVaCreateManagedWidget(name, class, parent,
                                            XmNlabelString, label, NULL);
    XmStringFree(label);
    return widget;
}

int
main(int argc, char **argv)
{
    XtAppContext app;
    Widget shell, panel, buttons, button;
    Display *display;
    Atom wm_delete;
    String fallback[] = {
        "*title: Motif widgets",
        "*fontList: 9x15",
        "*background: #c9c5b6",
        "*foreground: #202020",
        "*panel.marginWidth: 14",
        "*panel.marginHeight: 14",
        "*panel.spacing: 12",
        "*heading.labelString: Counter",
        "*heading.width: 310",
        "*heading.recomputeSize: False",
        "*buttons.orientation: horizontal",
        "*buttons.spacing: 8",
        "*XmPushButton.width: 94",
        "*XmPushButton.recomputeSize: False",
        "*XmPushButton.height: 32",
        NULL
    };

    XtSetLanguageProc(NULL, NULL, NULL);
    shell = XtVaAppInitialize(&app, "MotifCounter", NULL, 0,
                             &argc, argv, fallback, NULL);
    panel = XtVaCreateManagedWidget("panel", xmRowColumnWidgetClass,
                                     shell, NULL);
    labelled(panel, "heading", xmLabelWidgetClass, "Motif widgets on Xt");
    status = labelled(panel, "status", xmLabelWidgetClass, "Clicks: 0");
    buttons = XtVaCreateManagedWidget("buttons", xmRowColumnWidgetClass,
                                      panel, NULL);
    button = labelled(buttons, "count", xmPushButtonWidgetClass, "Count");
    XtAddCallback(button, XmNactivateCallback, count_click, NULL);
    button = labelled(buttons, "reset", xmPushButtonWidgetClass, "Reset");
    XtAddCallback(button, XmNactivateCallback, reset_count, NULL);
    button = labelled(buttons, "quit", xmPushButtonWidgetClass, "Quit");
    XtAddCallback(button, XmNactivateCallback, quit, NULL);

    display = XtDisplay(shell);
    wm_delete = XInternAtom(display, "WM_DELETE_WINDOW", False);
    XtVaSetValues(shell, XmNdeleteResponse, XmDO_NOTHING, NULL);
    XmAddWMProtocolCallback(shell, wm_delete, quit, NULL);
    XtRealizeWidget(shell);
    XtVaSetValues(shell, XmNtitle, "Motif widgets", NULL);
    XtAppMainLoop(app);
    XtDestroyWidget(shell);
    XtCloseDisplay(display);
    XtDestroyApplicationContext(app);
    return 0;
}
