#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>
#include <X11/Xaw/RepeaterP.h>
#include <X11/Xaw/XawInit.h>
#define DO_CALLBACK(rw) \
XtCallCallbackList((Widget)rw, rw->command.callbacks, NULL)
#define ADD_TIMEOUT(rw, delay) \
XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)rw), \
delay, tic, (XtPointer)rw)
#define CLEAR_TIMEOUT(rw) \
if ((rw)->repeater.timer) { \
XtRemoveTimeOut((rw)->repeater.timer); \
(rw)->repeater.timer = 0; \
}
static void XawRepeaterInitialize(Widget, Widget, ArgList, Cardinal*);
static void XawRepeaterDestroy(Widget);
static Boolean XawRepeaterSetValues(Widget, Widget, Widget,
ArgList, Cardinal*);
static void tic(XtPointer, XtIntervalId*);
static void ActionStart(Widget, XEvent*, String*, Cardinal*);
static void ActionStop(Widget, XEvent*, String*, Cardinal*);
static char defaultTranslations[] =
"<Enter>:" "highlight()\n"
"<Leave>:" "unhighlight()\n"
"<Btn1Down>:" "set() start()\n"
"<Btn1Up>:" "stop() unset()\n"
;
static XtActionsRec actions[] = {
{"start", ActionStart},
{"stop", ActionStop},
};
#define offset(field) XtOffsetOf(RepeaterRec, repeater.field)
static XtResource resources[] = {
{
XtNdecay,
XtCDecay,
XtRInt,
sizeof(int),
offset(decay),
XtRImmediate,
(XtPointer)REP_DEF_DECAY
},
{
XtNinitialDelay,
XtCDelay,
XtRInt,
sizeof(int),
offset(initial_delay),
XtRImmediate,
(XtPointer)REP_DEF_INITIAL_DELAY
},
{
XtNminimumDelay,
XtCMinimumDelay,
XtRInt,
sizeof(int),
offset(minimum_delay),
XtRImmediate,
(XtPointer)REP_DEF_MINIMUM_DELAY
},
{
XtNrepeatDelay,
XtCDelay,
XtRInt,
sizeof(int),
offset(repeat_delay),
XtRImmediate,
(XtPointer)REP_DEF_REPEAT_DELAY
},
{
XtNflash,
XtCBoolean,
XtRBoolean,
sizeof(Boolean),
offset(flash),
XtRImmediate,
(XtPointer)False
},
{
XtNstartCallback,
XtCStartCallback,
XtRCallback,
sizeof(XtPointer),
offset(start_callbacks),
XtRImmediate,
NULL
},
{
XtNstopCallback,
XtCStopCallback,
XtRCallback,
sizeof(XtPointer),
offset(stop_callbacks),
XtRImmediate,
NULL
},
};
#undef offset
#define Superclass (&commandClassRec)
RepeaterClassRec repeaterClassRec = {
{
(WidgetClass)Superclass,
"Repeater",
sizeof(RepeaterRec),
XawInitializeWidgetSet,
NULL,
False,
XawRepeaterInitialize,
NULL,
XtInheritRealize,
actions,
XtNumber(actions),
resources,
XtNumber(resources),
NULLQUARK,
True,
True,
True,
False,
XawRepeaterDestroy,
XtInheritResize,
XtInheritExpose,
XawRepeaterSetValues,
NULL,
XtInheritSetValuesAlmost,
NULL,
NULL,
XtVersion,
NULL,
defaultTranslations,
XtInheritQueryGeometry,
XtInheritDisplayAccelerator,
NULL,
},
{
XtInheritChangeSensitive,
},
{
NULL,
},
{
NULL,
},
{
NULL,
},
};
WidgetClass repeaterWidgetClass = (WidgetClass) &repeaterClassRec;
static void
tic(XtPointer client_data, XtIntervalId *id)
{
RepeaterWidget rw = (RepeaterWidget)client_data;
rw->repeater.timer = 0;
if (rw->repeater.flash) {
Widget w = (Widget)rw;
XClearWindow(XtDisplay(w), XtWindow(w));
XtCallActionProc(w, "reset", NULL, NULL, 0);
XClearWindow(XtDisplay(w), XtWindow(w));
XtCallActionProc(w, "set", NULL, NULL, 0);
}
DO_CALLBACK(rw);
rw->repeater.timer = ADD_TIMEOUT(rw, rw->repeater.next_delay);
if (rw->repeater.decay) {
rw->repeater.next_delay -= rw->repeater.decay;
if (rw->repeater.next_delay < rw->repeater.minimum_delay)
rw->repeater.next_delay = rw->repeater.minimum_delay;
}
}
static void
XawRepeaterInitialize(Widget greq, Widget gnew,
ArgList args, Cardinal *num_args)
{
RepeaterWidget cnew = (RepeaterWidget)gnew;
if (cnew->repeater.minimum_delay < 0)
cnew->repeater.minimum_delay = 0;
cnew->repeater.timer = 0;
}
static void
XawRepeaterDestroy(Widget gw)
{
CLEAR_TIMEOUT((RepeaterWidget)gw);
}
static Boolean
XawRepeaterSetValues(Widget gcur, Widget greq, Widget gnew,
ArgList args, Cardinal *num_args)
{
RepeaterWidget cur = (RepeaterWidget)gcur;
RepeaterWidget cnew = (RepeaterWidget)gnew;
if (cur->repeater.minimum_delay != cnew->repeater.minimum_delay) {
if (cnew->repeater.next_delay < cnew->repeater.minimum_delay)
cnew->repeater.next_delay = cnew->repeater.minimum_delay;
}
return (False);
}
static void
ActionStart(Widget gw, XEvent *event, String *params, Cardinal *num_params)
{
RepeaterWidget rw = (RepeaterWidget)gw;
CLEAR_TIMEOUT(rw);
if (rw->repeater.start_callbacks)
XtCallCallbackList(gw, rw->repeater.start_callbacks, NULL);
DO_CALLBACK(rw);
rw->repeater.timer = ADD_TIMEOUT(rw, rw->repeater.initial_delay);
rw->repeater.next_delay = rw->repeater.repeat_delay;
}
static void
ActionStop(Widget gw, XEvent *event, String *params, Cardinal *num_params)
{
RepeaterWidget rw = (RepeaterWidget)gw;
CLEAR_TIMEOUT((RepeaterWidget)gw);
if (rw->repeater.stop_callbacks)
XtCallCallbackList(gw, rw->repeater.stop_callbacks, NULL);
}