home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / lib / Xaw / Repeater.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-03-14  |  8.8 KB  |  268 lines

  1. /*
  2.  * $XConsortium: Repeater.c,v 1.8 91/03/14 16:48:04 converse Exp $
  3.  *
  4.  * Copyright 1990 Massachusetts Institute of Technology
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and its
  7.  * documentation for any purpose is hereby granted without fee, provided that
  8.  * the above copyright notice appear in all copies and that both that
  9.  * copyright notice and this permission notice appear in supporting
  10.  * documentation, and that the name of M.I.T. not be used in advertising or
  11.  * publicity pertaining to distribution of the software without specific,
  12.  * written prior permission.  M.I.T. makes no representations about the
  13.  * suitability of this software for any purpose.  It is provided "as is"
  14.  * without express or implied warranty.
  15.  *
  16.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  17.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  18.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  20.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
  21.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  *
  23.  * Author:  Jim Fulton, MIT X Consortium
  24.  * 
  25.  * This widget is used for press-and-hold style buttons.
  26.  */
  27.  
  28. #include <X11/IntrinsicP.h>        /* for toolkit inheritance stuff */
  29. #include <X11/StringDefs.h>        /* for XtN and XtC defines */
  30. #include <X11/Xaw/XawInit.h>        /* for XawInitializeWidgetSet() */
  31. #include <X11/Xaw/RepeaterP.h>        /* us */
  32.  
  33. static void tic();            /* clock timeout */
  34.  
  35. #define DO_CALLBACK(rw) \
  36.     XtCallCallbackList ((Widget) rw, rw->command.callbacks, NULL)
  37.  
  38.  
  39. #define ADD_TIMEOUT(rw,delay) \
  40.   XtAppAddTimeOut (XtWidgetToApplicationContext ((Widget) rw), \
  41.            (unsigned long) delay, tic, (XtPointer) rw)
  42.  
  43. #define CLEAR_TIMEOUT(rw) \
  44.   if ((rw)->repeater.timer) { \
  45.       XtRemoveTimeOut ((rw)->repeater.timer); \
  46.       (rw)->repeater.timer = 0; \
  47.   }
  48.  
  49.  
  50. /*
  51.  * Translations to give user interface of press-notify...-release_or_leave
  52.  */
  53. static char defaultTranslations[] = 
  54.   "<EnterWindow>:     highlight() \n\
  55.    <LeaveWindow>:     unhighlight() \n\
  56.    <Btn1Down>:        set() start() \n\
  57.    <Btn1Up>:          stop() unset() ";
  58.  
  59.  
  60. /*
  61.  * Actions added by this widget
  62.  */
  63. static void ActionStart(), ActionStop();
  64.  
  65. static XtActionsRec actions[] = {
  66.     { "start", ActionStart },        /* trigger timers */
  67.     { "stop", ActionStop },        /* clear timers */
  68. };
  69.  
  70.  
  71. /*
  72.  * New resources added by this widget
  73.  */
  74. static XtResource resources[] = {
  75. #define off(field) XtOffsetOf(RepeaterRec, repeater.field)
  76.     { XtNdecay, XtCDecay, XtRInt, sizeof (int),
  77.     off(decay), XtRImmediate, (XtPointer) REP_DEF_DECAY },
  78.     { XtNinitialDelay, XtCDelay, XtRInt, sizeof (int),
  79.     off(initial_delay), XtRImmediate, (XtPointer) REP_DEF_INITIAL_DELAY },
  80.     { XtNminimumDelay, XtCMinimumDelay, XtRInt, sizeof (int),
  81.     off(minimum_delay), XtRImmediate, (XtPointer) REP_DEF_MINIMUM_DELAY },
  82.     { XtNrepeatDelay, XtCDelay, XtRInt, sizeof (int),
  83.     off(repeat_delay), XtRImmediate, (XtPointer) REP_DEF_REPEAT_DELAY },
  84.     { XtNflash, XtCBoolean, XtRBoolean, sizeof (Boolean),
  85.     off(flash), XtRImmediate, (XtPointer) FALSE },
  86.     { XtNstartCallback, XtCStartCallback, XtRCallback, sizeof (XtPointer),
  87.     off(start_callbacks), XtRImmediate, (XtPointer) NULL },
  88.     { XtNstopCallback, XtCStopCallback, XtRCallback, sizeof (XtPointer),
  89.     off(stop_callbacks), XtRImmediate, (XtPointer) NULL },
  90. #undef off
  91. };
  92.  
  93.  
  94. /*
  95.  * Class Methods
  96.  */
  97.  
  98. static void Initialize();        /* setup private data */
  99. static void Destroy();            /* clear timers */
  100. static Boolean SetValues();        /* set resources */
  101.  
  102. RepeaterClassRec repeaterClassRec = {
  103.   { /* core fields */
  104.     /* superclass        */    (WidgetClass) &commandClassRec,
  105.     /* class_name        */    "Repeater",
  106.     /* widget_size        */    sizeof(RepeaterRec),
  107.     /* class_initialize        */    XawInitializeWidgetSet,
  108.     /* class_part_initialize    */    NULL,
  109.     /* class_inited        */    FALSE,
  110.     /* initialize        */    Initialize,
  111.     /* initialize_hook        */    NULL,
  112.     /* realize            */    XtInheritRealize,
  113.     /* actions            */    actions,
  114.     /* num_actions        */    XtNumber(actions),
  115.     /* resources        */    resources,
  116.     /* num_resources        */    XtNumber(resources),
  117.     /* xrm_class        */    NULLQUARK,
  118.     /* compress_motion        */    TRUE,
  119.     /* compress_exposure    */    TRUE,
  120.     /* compress_enterleave    */    TRUE,
  121.     /* visible_interest        */    FALSE,
  122.     /* destroy            */    Destroy,
  123.     /* resize            */    XtInheritResize,
  124.     /* expose            */    XtInheritExpose,
  125.     /* set_values        */    SetValues,
  126.     /* set_values_hook        */    NULL,
  127.     /* set_values_almost    */    XtInheritSetValuesAlmost,
  128.     /* get_values_hook        */    NULL,
  129.     /* accept_focus        */    NULL,
  130.     /* version            */    XtVersion,
  131.     /* callback_private        */    NULL,
  132.     /* tm_table            */    defaultTranslations,
  133.     /* query_geometry        */    XtInheritQueryGeometry,
  134.     /* display_accelerator    */    XtInheritDisplayAccelerator,
  135.     /* extension        */    NULL
  136.   },
  137.   { /* simple fields */
  138.     /* change_sensitive        */    XtInheritChangeSensitive
  139.   },
  140.   { /* label fields */
  141.     /* ignore            */    0
  142.   },
  143.   { /* command fields */
  144.     /* ignore            */    0
  145.   },
  146.   { /* repeater fields */
  147.     /* ignore                   */    0
  148.   }
  149. };
  150.  
  151. WidgetClass repeaterWidgetClass = (WidgetClass) &repeaterClassRec;
  152.  
  153.  
  154. /*****************************************************************************
  155.  *                                                                           *
  156.  *               repeater utility routines                         *
  157.  *                                                                           *
  158.  *****************************************************************************/
  159.  
  160. /* ARGSUSED */
  161. static void tic (client_data, id)
  162.     XtPointer client_data;
  163.     XtIntervalId *id;
  164. {
  165.     RepeaterWidget rw = (RepeaterWidget) client_data;
  166.  
  167.     rw->repeater.timer = 0;        /* timer is removed */
  168.     if (rw->repeater.flash) {
  169.     XtExposeProc expose;
  170.     expose = repeaterWidgetClass->core_class.superclass->core_class.expose;
  171.     XClearWindow (XtDisplay((Widget) rw), XtWindow((Widget) rw));
  172.     rw->command.set = FALSE;
  173.     (*expose) ((Widget) rw, (XEvent *) NULL, (Region) NULL);
  174.     XClearWindow (XtDisplay((Widget) rw), XtWindow((Widget) rw));
  175.     rw->command.set = TRUE;
  176.     (*expose) ((Widget) rw, (XEvent *) NULL, (Region) NULL);
  177.     }
  178.     DO_CALLBACK (rw);
  179.  
  180.     rw->repeater.timer = ADD_TIMEOUT (rw, rw->repeater.next_delay);
  181.  
  182.                     /* decrement delay time, but clamp */
  183.     if (rw->repeater.decay) {
  184.     rw->repeater.next_delay -= rw->repeater.decay;
  185.     if (rw->repeater.next_delay < rw->repeater.minimum_delay)
  186.       rw->repeater.next_delay = rw->repeater.minimum_delay;
  187.     }
  188. }
  189.  
  190.  
  191. /*****************************************************************************
  192.  *                                                                           *
  193.  *                 repeater class methods                           *
  194.  *                                                                           *
  195.  *****************************************************************************/
  196.  
  197. /* ARGSUSED */
  198. static void Initialize (greq, gnew)
  199.     Widget greq, gnew;
  200. {
  201.     RepeaterWidget new = (RepeaterWidget) gnew;
  202.  
  203.     if (new->repeater.minimum_delay < 0) new->repeater.minimum_delay = 0;
  204.     new->repeater.timer = (XtIntervalId) 0;
  205. }
  206.  
  207. static void Destroy (gw)
  208.     Widget gw;
  209. {
  210.     CLEAR_TIMEOUT ((RepeaterWidget) gw);
  211. }
  212.  
  213. /* ARGSUSED */
  214. static Boolean SetValues (gcur, greq, gnew)
  215.     Widget gcur, greq, gnew;
  216. {
  217.     RepeaterWidget cur = (RepeaterWidget) gcur;
  218.     RepeaterWidget new = (RepeaterWidget) gnew;
  219.     Boolean redisplay = FALSE;
  220.  
  221.     if (cur->repeater.minimum_delay != new->repeater.minimum_delay) {
  222.     if (new->repeater.next_delay < new->repeater.minimum_delay) 
  223.       new->repeater.next_delay = new->repeater.minimum_delay;
  224.     }
  225.  
  226.     return redisplay;
  227. }
  228.  
  229. /*****************************************************************************
  230.  *                                                                           *
  231.  *                  repeater action procs                           *
  232.  *                                                                           *
  233.  *****************************************************************************/
  234.  
  235. /* ARGSUSED */
  236. static void ActionStart (gw, event, params, num_params)
  237.     Widget gw;
  238.     XEvent *event;
  239.     String *params;            /* unused */
  240.     Cardinal *num_params;        /* unused */
  241. {
  242.     RepeaterWidget rw = (RepeaterWidget) gw;
  243.  
  244.     CLEAR_TIMEOUT (rw);
  245.     if (rw->repeater.start_callbacks) 
  246.       XtCallCallbackList (gw, rw->repeater.start_callbacks, NULL);
  247.  
  248.     DO_CALLBACK (rw);
  249.     rw->repeater.timer = ADD_TIMEOUT (rw, rw->repeater.initial_delay);
  250.     rw->repeater.next_delay = rw->repeater.repeat_delay;
  251. }
  252.  
  253.  
  254. /* ARGSUSED */
  255. static void ActionStop (gw, event, params, num_params)
  256.     Widget gw;
  257.     XEvent *event;
  258.     String *params;            /* unused */
  259.     Cardinal *num_params;        /* unused */
  260. {
  261.     RepeaterWidget rw = (RepeaterWidget) gw;
  262.  
  263.     CLEAR_TIMEOUT ((RepeaterWidget) gw);
  264.     if (rw->repeater.stop_callbacks) 
  265.       XtCallCallbackList (gw, rw->repeater.stop_callbacks, NULL);
  266. }
  267.  
  268.