17a84e134Smrg/* 27a84e134Smrg * 37a84e134SmrgCopyright 1990, 1994, 1998 The Open Group 47a84e134Smrg 57a84e134SmrgPermission to use, copy, modify, distribute, and sell this software and its 67a84e134Smrgdocumentation for any purpose is hereby granted without fee, provided that 77a84e134Smrgthe above copyright notice appear in all copies and that both that 87a84e134Smrgcopyright notice and this permission notice appear in supporting 97a84e134Smrgdocumentation. 107a84e134Smrg 117a84e134SmrgThe above copyright notice and this permission notice shall be included in 127a84e134Smrgall copies or substantial portions of the Software. 137a84e134Smrg 147a84e134SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 157a84e134SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 167a84e134SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 177a84e134SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 187a84e134SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 197a84e134SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 207a84e134Smrg 217a84e134SmrgExcept as contained in this notice, the name of The Open Group shall not be 227a84e134Smrgused in advertising or otherwise to promote the sale, use or other dealings 237a84e134Smrgin this Software without prior written authorization from The Open Group. 247a84e134Smrg * 257a84e134Smrg * Author: Jim Fulton, MIT X Consortium 26421c997bSmrg * 277a84e134Smrg * This widget is used for press-and-hold style buttons. 287a84e134Smrg */ 297a84e134Smrg 307a84e134Smrg#ifdef HAVE_CONFIG_H 317a84e134Smrg#include <config.h> 327a84e134Smrg#endif 337a84e134Smrg#include <X11/IntrinsicP.h> 347a84e134Smrg#include <X11/StringDefs.h> 357a84e134Smrg#include <X11/Xaw/RepeaterP.h> 367a84e134Smrg#include <X11/Xaw/XawInit.h> 377a84e134Smrg 387a84e134Smrg#define DO_CALLBACK(rw) \ 397a84e134SmrgXtCallCallbackList((Widget)rw, rw->command.callbacks, NULL) 407a84e134Smrg 417a84e134Smrg#define ADD_TIMEOUT(rw, delay) \ 427a84e134SmrgXtAppAddTimeOut(XtWidgetToApplicationContext((Widget)rw), \ 437a84e134Smrg delay, tic, (XtPointer)rw) 447a84e134Smrg 457a84e134Smrg#define CLEAR_TIMEOUT(rw) \ 467a84e134Smrgif ((rw)->repeater.timer) { \ 477a84e134Smrg XtRemoveTimeOut((rw)->repeater.timer); \ 487a84e134Smrg (rw)->repeater.timer = 0; \ 497a84e134Smrg} 507a84e134Smrg 517a84e134Smrg/* 527a84e134Smrg * Class Methods 537a84e134Smrg */ 547a84e134Smrgstatic void XawRepeaterInitialize(Widget, Widget, ArgList, Cardinal*); 557a84e134Smrgstatic void XawRepeaterDestroy(Widget); 567a84e134Smrgstatic Boolean XawRepeaterSetValues(Widget, Widget, Widget, 577a84e134Smrg ArgList, Cardinal*); 587a84e134Smrg 597a84e134Smrg/* 607a84e134Smrg * Prototypes 617a84e134Smrg */ 627a84e134Smrgstatic void tic(XtPointer, XtIntervalId*); 637a84e134Smrg 647a84e134Smrg/* 657a84e134Smrg * Actions 667a84e134Smrg */ 677a84e134Smrgstatic void ActionStart(Widget, XEvent*, String*, Cardinal*); 687a84e134Smrgstatic void ActionStop(Widget, XEvent*, String*, Cardinal*); 697a84e134Smrg 707a84e134Smrg/* 717a84e134Smrg * Initialization 727a84e134Smrg */ 737a84e134Smrgstatic char defaultTranslations[] = 747a84e134Smrg"<Enter>:" "highlight()\n" 757a84e134Smrg"<Leave>:" "unhighlight()\n" 767a84e134Smrg"<Btn1Down>:" "set() start()\n" 777a84e134Smrg"<Btn1Up>:" "stop() unset()\n" 787a84e134Smrg; 797a84e134Smrg 807a84e134Smrgstatic XtActionsRec actions[] = { 817a84e134Smrg {"start", ActionStart}, 827a84e134Smrg {"stop", ActionStop}, 837a84e134Smrg}; 847a84e134Smrg 857a84e134Smrg#define offset(field) XtOffsetOf(RepeaterRec, repeater.field) 867a84e134Smrgstatic XtResource resources[] = { 877a84e134Smrg { 887a84e134Smrg XtNdecay, 897a84e134Smrg XtCDecay, 907a84e134Smrg XtRInt, 917a84e134Smrg sizeof(int), 927a84e134Smrg offset(decay), 937a84e134Smrg XtRImmediate, 947a84e134Smrg (XtPointer)REP_DEF_DECAY 957a84e134Smrg }, 967a84e134Smrg { 977a84e134Smrg XtNinitialDelay, 987a84e134Smrg XtCDelay, 997a84e134Smrg XtRInt, 1007a84e134Smrg sizeof(int), 1017a84e134Smrg offset(initial_delay), 1027a84e134Smrg XtRImmediate, 1037a84e134Smrg (XtPointer)REP_DEF_INITIAL_DELAY 1047a84e134Smrg }, 1057a84e134Smrg { 1067a84e134Smrg XtNminimumDelay, 1077a84e134Smrg XtCMinimumDelay, 1087a84e134Smrg XtRInt, 1097a84e134Smrg sizeof(int), 1107a84e134Smrg offset(minimum_delay), 1117a84e134Smrg XtRImmediate, 1127a84e134Smrg (XtPointer)REP_DEF_MINIMUM_DELAY 1137a84e134Smrg }, 1147a84e134Smrg { 1157a84e134Smrg XtNrepeatDelay, 1167a84e134Smrg XtCDelay, 1177a84e134Smrg XtRInt, 1187a84e134Smrg sizeof(int), 1197a84e134Smrg offset(repeat_delay), 1207a84e134Smrg XtRImmediate, 1217a84e134Smrg (XtPointer)REP_DEF_REPEAT_DELAY 1227a84e134Smrg }, 1237a84e134Smrg { 1247a84e134Smrg XtNflash, 1257a84e134Smrg XtCBoolean, 1267a84e134Smrg XtRBoolean, 1277a84e134Smrg sizeof(Boolean), 1287a84e134Smrg offset(flash), 1297a84e134Smrg XtRImmediate, 1307a84e134Smrg (XtPointer)False 1317a84e134Smrg }, 1327a84e134Smrg { 1337a84e134Smrg XtNstartCallback, 1347a84e134Smrg XtCStartCallback, 1357a84e134Smrg XtRCallback, 1367a84e134Smrg sizeof(XtPointer), 1377a84e134Smrg offset(start_callbacks), 1387a84e134Smrg XtRImmediate, 1397a84e134Smrg NULL 1407a84e134Smrg }, 1417a84e134Smrg { 1427a84e134Smrg XtNstopCallback, 1437a84e134Smrg XtCStopCallback, 1447a84e134Smrg XtRCallback, 1457a84e134Smrg sizeof(XtPointer), 1467a84e134Smrg offset(stop_callbacks), 1477a84e134Smrg XtRImmediate, 1487a84e134Smrg NULL 1497a84e134Smrg }, 1507a84e134Smrg}; 1517a84e134Smrg#undef offset 1527a84e134Smrg 1537a84e134Smrg#define Superclass (&commandClassRec) 1547a84e134SmrgRepeaterClassRec repeaterClassRec = { 1557a84e134Smrg /* core */ 1567a84e134Smrg { 1577a84e134Smrg (WidgetClass)Superclass, /* superclass */ 1587a84e134Smrg "Repeater", /* class_name */ 1597a84e134Smrg sizeof(RepeaterRec), /* widget_size */ 1607a84e134Smrg XawInitializeWidgetSet, /* class_initialize */ 1617a84e134Smrg NULL, /* class_part_initialize */ 1627a84e134Smrg False, /* class_inited */ 1637a84e134Smrg XawRepeaterInitialize, /* initialize */ 1647a84e134Smrg NULL, /* initialize_hook */ 1657a84e134Smrg XtInheritRealize, /* realize */ 1667a84e134Smrg actions, /* actions */ 1677a84e134Smrg XtNumber(actions), /* num_actions */ 1687a84e134Smrg resources, /* resources */ 1697a84e134Smrg XtNumber(resources), /* num_resources */ 1707a84e134Smrg NULLQUARK, /* xrm_class */ 1717a84e134Smrg True, /* compress_motion */ 1727a84e134Smrg True, /* compress_exposure */ 1737a84e134Smrg True, /* compress_enterleave */ 1747a84e134Smrg False, /* visible_interest */ 1757a84e134Smrg XawRepeaterDestroy, /* destroy */ 1767a84e134Smrg XtInheritResize, /* resize */ 1777a84e134Smrg XtInheritExpose, /* expose */ 1787a84e134Smrg XawRepeaterSetValues, /* set_values */ 1797a84e134Smrg NULL, /* set_values_hook */ 1807a84e134Smrg XtInheritSetValuesAlmost, /* set_values_almost */ 1817a84e134Smrg NULL, /* get_values_hook */ 1827a84e134Smrg NULL, /* accept_focus */ 1837a84e134Smrg XtVersion, /* version */ 1847a84e134Smrg NULL, /* callback_private */ 1857a84e134Smrg defaultTranslations, /* tm_table */ 1867a84e134Smrg XtInheritQueryGeometry, /* query_geometry */ 1877a84e134Smrg XtInheritDisplayAccelerator, /* display_accelerator */ 1887a84e134Smrg NULL, /* extension */ 1897a84e134Smrg }, 1907a84e134Smrg /* simple */ 1917a84e134Smrg { 1927a84e134Smrg XtInheritChangeSensitive, /* change_sensitive */ 193efbcb2bfSmrg#ifndef OLDXAW 194efbcb2bfSmrg NULL, 195efbcb2bfSmrg#endif 1967a84e134Smrg }, 1977a84e134Smrg /* label */ 1987a84e134Smrg { 1997a84e134Smrg NULL, /* extension */ 2007a84e134Smrg }, 2017a84e134Smrg /* command */ 2027a84e134Smrg { 2037a84e134Smrg NULL, /* extension */ 2047a84e134Smrg }, 2057a84e134Smrg /* repeater */ 2067a84e134Smrg { 2077a84e134Smrg NULL, /* extension */ 2087a84e134Smrg }, 2097a84e134Smrg}; 2107a84e134Smrg 2117a84e134SmrgWidgetClass repeaterWidgetClass = (WidgetClass) &repeaterClassRec; 2127a84e134Smrg 2137a84e134Smrg 2147a84e134Smrg/* 2157a84e134Smrg * Implementation 2167a84e134Smrg */ 2177a84e134Smrg/*ARGSUSED*/ 2187a84e134Smrgstatic void 2195ec34c4cSmrgtic(XtPointer client_data, XtIntervalId *id _X_UNUSED) 2207a84e134Smrg{ 2217a84e134Smrg RepeaterWidget rw = (RepeaterWidget)client_data; 2227a84e134Smrg 2237a84e134Smrg rw->repeater.timer = 0; /* timer is removed */ 2247a84e134Smrg if (rw->repeater.flash) { 2257a84e134Smrg Widget w = (Widget)rw; 2267a84e134Smrg 2277a84e134Smrg XClearWindow(XtDisplay(w), XtWindow(w)); 2287a84e134Smrg XtCallActionProc(w, "reset", NULL, NULL, 0); 2297a84e134Smrg XClearWindow(XtDisplay(w), XtWindow(w)); 2307a84e134Smrg XtCallActionProc(w, "set", NULL, NULL, 0); 2317a84e134Smrg } 2327a84e134Smrg DO_CALLBACK(rw); 2337a84e134Smrg 2345ec34c4cSmrg rw->repeater.timer = ADD_TIMEOUT(rw, (unsigned long)rw->repeater.next_delay); 2357a84e134Smrg 2367a84e134Smrg if (rw->repeater.decay) { 2377a84e134Smrg rw->repeater.next_delay -= rw->repeater.decay; 2387a84e134Smrg if (rw->repeater.next_delay < rw->repeater.minimum_delay) 2397a84e134Smrg rw->repeater.next_delay = rw->repeater.minimum_delay; 2407a84e134Smrg } 2417a84e134Smrg} 2427a84e134Smrg 2437a84e134Smrg/*ARGSUSED*/ 2447a84e134Smrgstatic void 2455ec34c4cSmrgXawRepeaterInitialize(Widget greq _X_UNUSED, Widget gnew, 2465ec34c4cSmrg ArgList args _X_UNUSED, Cardinal *num_args _X_UNUSED) 2477a84e134Smrg{ 2487a84e134Smrg RepeaterWidget cnew = (RepeaterWidget)gnew; 2497a84e134Smrg 2507a84e134Smrg if (cnew->repeater.minimum_delay < 0) 2517a84e134Smrg cnew->repeater.minimum_delay = 0; 2527a84e134Smrg cnew->repeater.timer = 0; 2537a84e134Smrg} 2547a84e134Smrg 2557a84e134Smrgstatic void 2567a84e134SmrgXawRepeaterDestroy(Widget gw) 2577a84e134Smrg{ 2587a84e134Smrg CLEAR_TIMEOUT((RepeaterWidget)gw); 2597a84e134Smrg} 2607a84e134Smrg 2617a84e134Smrg/*ARGSUSED*/ 2627a84e134Smrgstatic Boolean 2635ec34c4cSmrgXawRepeaterSetValues(Widget gcur, Widget greq _X_UNUSED, Widget gnew, 2645ec34c4cSmrg ArgList args _X_UNUSED, Cardinal *num_args _X_UNUSED) 2657a84e134Smrg{ 2667a84e134Smrg RepeaterWidget cur = (RepeaterWidget)gcur; 2677a84e134Smrg RepeaterWidget cnew = (RepeaterWidget)gnew; 2687a84e134Smrg 2697a84e134Smrg if (cur->repeater.minimum_delay != cnew->repeater.minimum_delay) { 2707a84e134Smrg if (cnew->repeater.next_delay < cnew->repeater.minimum_delay) 2717a84e134Smrg cnew->repeater.next_delay = cnew->repeater.minimum_delay; 2727a84e134Smrg } 2737a84e134Smrg 2747a84e134Smrg return (False); 2757a84e134Smrg} 2767a84e134Smrg 2777a84e134Smrg/*ARGSUSED*/ 2787a84e134Smrgstatic void 2795ec34c4cSmrgActionStart(Widget gw, XEvent *event _X_UNUSED, String *params _X_UNUSED, Cardinal *num_params _X_UNUSED) 2807a84e134Smrg{ 2817a84e134Smrg RepeaterWidget rw = (RepeaterWidget)gw; 2827a84e134Smrg 2837a84e134Smrg CLEAR_TIMEOUT(rw); 284421c997bSmrg if (rw->repeater.start_callbacks) 2857a84e134Smrg XtCallCallbackList(gw, rw->repeater.start_callbacks, NULL); 2867a84e134Smrg 2877a84e134Smrg DO_CALLBACK(rw); 2885ec34c4cSmrg rw->repeater.timer = ADD_TIMEOUT(rw, (unsigned long)rw->repeater.initial_delay); 2897a84e134Smrg rw->repeater.next_delay = rw->repeater.repeat_delay; 2907a84e134Smrg} 2917a84e134Smrg 2927a84e134Smrg/*ARGSUSED*/ 2937a84e134Smrgstatic void 2945ec34c4cSmrgActionStop(Widget gw, XEvent *event _X_UNUSED, String *params _X_UNUSED, Cardinal *num_params _X_UNUSED) 2957a84e134Smrg{ 2967a84e134Smrg RepeaterWidget rw = (RepeaterWidget)gw; 2977a84e134Smrg 2987a84e134Smrg CLEAR_TIMEOUT((RepeaterWidget)gw); 299421c997bSmrg if (rw->repeater.stop_callbacks) 3007a84e134Smrg XtCallCallbackList(gw, rw->repeater.stop_callbacks, NULL); 3017a84e134Smrg} 302