home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 524.lha / MouseAccel_v1.01 / MouseAccelerator.c < prev    next >
C/C++ Source or Header  |  1991-07-01  |  32KB  |  1,068 lines

  1. /*
  2.  *  MouseAccelerator.c
  3.  *
  4.  *  Commodity
  5.  *
  6.  *  Author: Stefan Sticht
  7.  *
  8.  *  Copyright: source is public domain, no copyright
  9.  *
  10.  *  Version history:
  11.  *
  12.  *  V1.00   initial release
  13.  *  V1.01   two small changes in messages (thanks to Holger Gzella)
  14.  */
  15.  
  16. #define VERSION "V1.01"
  17.  
  18. /********************************************************************
  19.  *                             interfacing                          *
  20.  ********************************************************************/
  21.  
  22. /*
  23.  *  include files
  24.  */
  25.  
  26. #include <math.h>
  27. #include <stdarg.h>
  28. #include <stdlib.h>
  29. #include <string.h>
  30. #include <devices/inputevent.h>
  31. #include <intuition/intuitionbase.h>
  32. #include <libraries/commodities.h>
  33.  
  34. #include <clib/alib_protos.h>
  35. #include <clib/commodities_protos.h>
  36. #include <pragmas/commodities_pragmas.h>
  37. #include <clib/dos_protos.h>
  38. #include <pragmas/dos_pragmas.h>
  39. #include <clib/exec_protos.h>
  40. #include <pragmas/exec_pragmas.h>
  41. #include <clib/gadtools_protos.h>
  42. #include <pragmas/gadtools_pragmas.h>
  43. #include <clib/graphics_protos.h>
  44. #include <pragmas/graphics_pragmas.h>
  45. #include <clib/intuition_protos.h>
  46. #include <pragmas/intuition_pragmas.h>
  47. #include <clib/utility_protos.h>
  48. #include <pragmas/utility_pragmas.h>
  49.  
  50. #ifdef DEBUG
  51. #define printf KPrintF
  52. #include <clib/dlib_protos.h>
  53. #endif
  54.  
  55. /*
  56.  *  prototypes
  57.  */
  58. long openwindow(void);
  59. struct Gadget *createallgadgets(struct Gadget **glist, APTR vi, struct Screen *scr, ULONG *height, ULONG *width);
  60. struct Library *myopenlibrary(char *name, unsigned long version);
  61. void __saveds accelerator(CxMsg *cxm);
  62. void closewindow(void);
  63. void processmessages(short window);
  64.  
  65. /*
  66.  *  global data defined in other moduls
  67.  *
  68.  *  libraries opened by startup code; basepointers needed by function pragmas
  69.  */
  70. extern struct Library *DOSBase;
  71. extern struct Library *SysBase;
  72.  
  73. /*
  74.  *  Disable SAS/C CTRL/C handling
  75.  */
  76. void chkabort(void) {}
  77.  
  78. /********************************************************************
  79.  *                             global data                          *
  80.  ********************************************************************/
  81.  
  82. /*
  83.  *  definition of all messages (multi language support not completed yet)
  84.  */
  85. #ifdef GERMAN
  86.  
  87. #define RETRY_GADGETS           "Wiederholen|Abbrechen"
  88. #define RESUME_GADGETS          "Weiter"
  89. #define MSG_LIBRARY_OPENERR     "Die %s (V%ld+) kann nicht geöffnet werden!"
  90. #define COM_NAME                "Mausbeschleuniger"
  91. #define COM_DESCR               "Beschleunigt Mausbewegungen"
  92. #define MSG_ACC                 "Beschleunigungsfaktor: %-lu  "
  93. #define MSG_THRESH              "Beschleunigungsminimum: %-lu  "
  94. #define MSG_HIDE                "_Verstecken"
  95. #define MSG_HIDE_SCC            'V'
  96. #define MSG_QUIT                "_Beenden"
  97. #define MSG_QUIT_SCC            'B'
  98. #define YES                     "JA"
  99. #define NO                      "NEIN"
  100. #define TT_ACC                  "FAKTOR"
  101. #define TT_THRESH               "MINIMUM"
  102.  
  103. #else
  104.  
  105. #define RETRY_GADGETS           "Retry|Cancel"
  106. #define RESUME_GADGETS          "Resume"
  107. #define MSG_LIBRARY_OPENERR     "%s (V%ld+) can't be opened!"
  108. #define COM_NAME                "MouseAccelerator"
  109. #define COM_DESCR               "Accelerates mouse movements"
  110. #define MSG_ACC                 "Acceleration: %-lu  "
  111. #define MSG_THRESH              "Threshold: %-lu  "
  112. #define MSG_HIDE                "_Hide"
  113. #define MSG_HIDE_SCC            'H'
  114. #define MSG_QUIT                "_Quit"
  115. #define MSG_QUIT_SCC            'Q'
  116. #define YES                     "YES"
  117. #define NO                      "NO"
  118. #define TT_ACC                  "ACCELERATION"
  119. #define TT_THRESH               "THRESHOLD"
  120.  
  121. #endif
  122.  
  123. #define COM_TITLE           COM_NAME " " VERSION
  124. #define CX_PRIORITY         "CX_PRIORITY"
  125. #define DEF_CX_PRIORITY     0
  126. #define CX_POPKEY           "CX_POPKEY"
  127. #define DEF_CX_POPKEY       ""
  128. #define CX_POPUP            "CX_POPUP"
  129. #define DEF_CX_POPUP        NO
  130. #define DEF_TT_ACC          5
  131. #define DEF_TT_THRESH       4
  132.  
  133. #define MAX_ACC             20
  134. #define MAX_THRESH          50
  135.  
  136. #define POP_KEY_ID          100
  137.  
  138. #define CCMD_NOP                0
  139. #define CCMD_HIDE               1
  140. #define CCMD_QUIT               2
  141.  
  142. #define CASE_DIFF   ('A' - 'a')
  143.  
  144. /*
  145.  *  data for cback.o
  146.  */
  147. long _stack = 2048l;
  148. char *_procname = COM_NAME;
  149. long _priority = 0l;
  150. long _BackGroundIO = 1;
  151. extern BPTR _Backstdout;
  152.  
  153. /*
  154.  *  library base pointers
  155.  */
  156. struct IntuitionBase *IntuitionBase;
  157. struct Library *CxBase;
  158. struct Library *IconBase;
  159. struct Library *GadToolsBase;
  160. struct Library *GfxBase;
  161. struct Library *UtilityBase;
  162.  
  163. /*
  164.  *  our task
  165.  */
  166. struct Task *mytask = NULL;
  167.  
  168. /*
  169.  *  signal we AllocSignal() in main()
  170.  */
  171. long signal = -1l;
  172.  
  173. /*
  174.  *  message ports
  175.  */
  176. struct MsgPort *idcmpport   = NULL;
  177. struct MsgPort *cxport      = NULL;
  178.  
  179. /*
  180.  *  signal flags
  181.  */
  182. unsigned long cxsigflag = 0l;
  183. unsigned long idcmpsigflag = 0l;
  184.  
  185. /*
  186.  *  programtitle and version for Version command
  187.  */
  188. char versionstring[] ="\0$VER: " COM_NAME " " VERSION;
  189.  
  190. /*
  191.  *  helpstring
  192.  */
  193. #ifdef GERMAN
  194. char helpstring[] = "\033[1m" COM_NAME "\033[0m " VERSION " (Public Domain) von Stefan Sticht\n"\
  195.                     "Aufruf: " COM_NAME " [" CX_PRIORITY "=<n>] [" CX_POPKEY "=<hotkey>] ["
  196.                     CX_POPUP "=" YES "|" NO "] [" TT_ACC "=<n>] [" TT_THRESH "=<n>]\n";
  197. #else
  198. char helpstring[] = "\033[1m" COM_NAME "\033[0m " VERSION " (Public Domain) by Stefan Sticht\n"
  199.                     "Usage: " COM_NAME " [" CX_PRIORITY "=<n>] [" CX_POPKEY "=<hotkey>] ["
  200.                     CX_POPUP "=" YES "|" NO "] [" TT_ACC "=<n>] [" TT_THRESH "=<n>]\n";
  201. #endif
  202.  
  203. /*
  204.  *  the tooltypearray
  205.  */
  206. char **tooltypes;
  207.  
  208. /*
  209.  *  our broker
  210.  */
  211. CxObj *broker = NULL;
  212. CxObj *mousefilter;
  213. CxObj *hotkeyfilter;
  214.  
  215. struct NewBroker newbroker = {
  216.     NB_VERSION,                         /* BYTE nb_Version               */
  217.     COM_NAME,                           /* BYTE *nb_Name                 */
  218.     COM_TITLE,                          /* BYTE *nb_Title                */
  219.     COM_DESCR,                          /* BYTE *nb_Descr                */
  220.     NBU_NOTIFY | NBU_UNIQUE,            /* SHORT nb_Unique               */
  221.     COF_SHOW_HIDE,                      /* SHORT nb_Flags                */
  222.     0,                                  /* BYTE nb_Pri                   */
  223.     NULL,                               /* struct MsgPort nb_Port        */
  224.     0                                   /* WORD nb_ReservedChannel       */
  225. };
  226.  
  227. IX mouseix = {
  228.     IX_VERSION,                         /* UBYTE ix_version     */
  229.     IECLASS_RAWMOUSE,                   /* UBYTE ix_Class       */
  230.     0,                                  /* UWORD ix_Code        */
  231.     0,                                  /* UWORD ix_CodeMask    */
  232.     IEQUALIFIER_RELATIVEMOUSE,          /* UWORD ix_Qualifier   */
  233.     IEQUALIFIER_RELATIVEMOUSE,          /* UWORD ix_Qualmask    */
  234.     0                                   /* UWORD ix_QualSame    */
  235.     };
  236.  
  237. /*
  238.  *  acceleration and threshold
  239.  */
  240. unsigned short acceleration;
  241. unsigned short threshold;
  242.  
  243. /*
  244.  *  data for our window
  245.  */
  246. struct Window *win          = NULL;
  247. APTR vi                     = NULL;
  248. struct Gadget *gadgetlist   = NULL;
  249. struct Screen *scr          = NULL;
  250. #define WINDOWTITLE_LEN 63
  251. char windowtitle[WINDOWTITLE_LEN + 1] = COM_TITLE;
  252.  
  253. /*
  254.  *  space for zoomed window pos & size
  255.  */
  256. WORD zoompos[4];
  257.  
  258. #define P_WA_Left       0
  259. #define P_WA_Top        1
  260. #define P_WA_Width      2
  261. #define P_WA_Height     3
  262. #define P_WA_Title      6
  263. #define P_WA_PubScreen  7
  264. #define P_WA_Gadgets    8
  265. struct TagItem mywindowtag[] = {
  266.     WA_Left,        0l,
  267.     WA_Top,         20l,
  268.     WA_Width,       400l,
  269.     WA_Height,      150l,
  270.     WA_IDCMP,       IDCMP_CLOSEWINDOW | BUTTONIDCMP | SLIDERIDCMP | IDCMP_REFRESHWINDOW |
  271.                     IDCMP_VANILLAKEY,
  272.     WA_Flags,       WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET | WFLG_SMART_REFRESH |
  273.                     WFLG_ACTIVATE | WFLG_RMBTRAP,
  274.     WA_Title,       (ULONG)windowtitle,
  275.     WA_PubScreen,   0l,
  276.     WA_Gadgets,     0l,
  277.     WA_Zoom,        (ULONG)zoompos,
  278.     TAG_END
  279.     };
  280.  
  281. char msg_acc[]    = MSG_ACC;
  282. char msg_thresh[] = MSG_THRESH;
  283. char msg_hide[]   = MSG_HIDE;
  284. char msg_quit[]   = MSG_QUIT;
  285.  
  286. /*
  287.  *  gadget definitions
  288.  */
  289. #define DBL_INTERWIDTH  (INTERWIDTH << 1)
  290. #define DBL_INTERHEIGHT (INTERHEIGHT << 1)
  291.  
  292. #define GAD_ACC     6
  293. #define GAD_THRESH  7
  294. #define GAD_HIDE    8
  295. #define GAD_QUIT    9
  296.  
  297. struct Gadget *gad_acc;
  298. struct Gadget *gad_thresh;
  299. struct Gadget *gad_hide;
  300. struct Gadget *gad_quit;
  301.  
  302. /********************************************************************
  303.  *                             functions                            *
  304.  ********************************************************************/
  305.  
  306. /*
  307.  *  request(): a glue routine to EasyRequest as simple as printf plus
  308.  *             titlestring, gadgettexts
  309.  *
  310.  *  Input: char *title:         pointer to the title of the requester
  311.  *         char *gadgets:       pointer to gadgettext
  312.  *         char *text:          text displayed in requester
  313.  *
  314.  *  Result: same as EasyrequestArgs()
  315.  *
  316.  * !!! for more info see EasyRequestArgs() in Autodocs/intuition.doc !!!
  317.  */
  318. long request(char *title, char *gadgets, char *text, ...)
  319. {
  320.     /*
  321.      *  structure textreq only needed in this function, so hide it here
  322.      *  must be static, in order to be initialized only once
  323.      */
  324.     static struct EasyStruct textreq = {
  325.         sizeof (struct EasyStruct), /* ULONG es_StructSize      */
  326.         0l,                         /* ULONG es_Flags           */
  327.         NULL,                       /* UBYTE *es_Title          */
  328.         NULL,                       /* UBYTE *es_TextFormat     */
  329.         NULL,                       /* UBYTE *es_GadgetFormat   */
  330.         };
  331.     va_list ap;
  332.     long rc;
  333.  
  334.     /*
  335.      *  get start of variable arguments
  336.      */
  337.     va_start(ap, text);
  338.  
  339.     /*
  340.      *  update textreq
  341.      */
  342.     textreq.es_Title = (UBYTE *)title;
  343.     textreq.es_TextFormat = (UBYTE *)text;
  344.     textreq.es_GadgetFormat = (UBYTE *)gadgets;
  345.  
  346.     /*
  347.      *  win may be NULL
  348.      */
  349.     rc = EasyRequestArgs(NULL, &textreq, NULL, ap);
  350.  
  351.     va_end(ap);
  352.  
  353.     return(rc);
  354. }
  355.  
  356. /*
  357.  *  myopenlibrary(): same as OpenLibrary(), but opens a retry-requester
  358.  *                   if OpenLibrary() fails, to give the user a chance to
  359.  *                   copy the library to libs: and retry
  360.  *                   requires request(), see above
  361.  */
  362. struct Library *myopenlibrary(char *name, unsigned long version)
  363. {
  364.     static char errortext[] = MSG_LIBRARY_OPENERR;
  365.     struct Library *libptr;
  366.     long ok = TRUE;
  367.  
  368.     do {
  369.         if (!(libptr = OpenLibrary((UBYTE *)name, version))) {
  370.             if (IntuitionBase) {
  371.                 ok = request(COM_NAME ":", RETRY_GADGETS, errortext, name, version);
  372.                 }
  373.             else ok = FALSE;
  374.             }
  375.         } while (!libptr && ok);
  376.  
  377.     #ifdef DEBUG
  378.     printf("myopenlibrary(%s, %ld) = 0x%lx\n", name, version, libptr);
  379.     #endif
  380.     return(libptr);
  381. }
  382.  
  383. void main(int argc, char *argv[])
  384. {
  385.     CxObj *customobj;
  386.     char *hotkey;
  387.     struct Message *msg;
  388.     short window = FALSE;
  389.  
  390.     if ((argc > 1) && (*argv[1] == '?')) {
  391.         /*
  392.          *  display help string
  393.          */
  394.         if (_Backstdout) {
  395.             Write(_Backstdout, helpstring, sizeof(helpstring) - 1l);
  396.             Close(_Backstdout);
  397.             }
  398.         return;
  399.         }
  400.     else if (argc && _Backstdout) Close(_Backstdout);
  401.  
  402.     if (IntuitionBase = (struct IntuitionBase *)myopenlibrary("intuition.library", 37l)) {
  403.  
  404.         /*
  405.          *  parse command line or tool types
  406.          *
  407.          *  we need icon.library therefore
  408.          */
  409.         if (IconBase = myopenlibrary("icon.library", 37l)) {
  410.  
  411.             long value;
  412.  
  413.             /*
  414.              * create tooltypes array (requires icon.library open!!!)
  415.              */
  416.             tooltypes = (char **)ArgArrayInit(argc, argv);
  417.  
  418.             newbroker.nb_Pri = ArgInt(tooltypes, CX_PRIORITY, DEF_CX_PRIORITY);
  419.  
  420.             /*
  421.              *  acceleration
  422.              */
  423.             value = ArgInt(tooltypes, TT_ACC, DEF_TT_ACC);
  424.             acceleration = (value > 0l) ? value : 1l;
  425.             if (acceleration > MAX_ACC) acceleration = MAX_ACC;
  426.  
  427.             /*
  428.              *  acceleration
  429.              */
  430.             value = ArgInt(tooltypes, TT_THRESH, DEF_TT_THRESH);
  431.             threshold = (value > 0l) ? value : 1l;
  432.             if (threshold > MAX_THRESH) threshold = MAX_THRESH;
  433.  
  434.             /*
  435.              *  check for a hotkey
  436.              */
  437.             hotkey = ArgString(tooltypes, CX_POPKEY, DEF_CX_POPKEY);
  438.  
  439.             if (UtilityBase = myopenlibrary("utility.library", 37l)) {
  440.  
  441.                 if (Stricmp(ArgString(tooltypes, CX_POPUP, DEF_CX_POPUP), YES) == 0l)
  442.                     window = TRUE;
  443.  
  444.                 CloseLibrary(UtilityBase);
  445.  
  446.                 } /* if UtilityBase */
  447.  
  448.             if (CxBase = myopenlibrary("commodities.library", 37l)) {
  449.  
  450.                 if (GfxBase = myopenlibrary("graphics.library", 37l)) {
  451.  
  452.                     if (GadToolsBase = myopenlibrary("gadtools.library", 37l)) {
  453.  
  454.                         /*
  455.                          *  create our message port
  456.                          */
  457.                         if (cxport = CreateMsgPort()) {
  458.  
  459.                             cxsigflag = 1l << cxport->mp_SigBit;
  460.                             newbroker.nb_Port = cxport;
  461.  
  462.                             if (broker = CxBroker(&newbroker, NULL)) {
  463.  
  464.                                 if (mousefilter = CxFilter(NULL)) {
  465.  
  466.                                     AttachCxObj(broker, mousefilter);
  467.  
  468.                                     SetFilterIX(mousefilter, &mouseix);
  469.  
  470.                                     if (customobj = CxCustom(accelerator, 0l)) {
  471.  
  472.                                         AttachCxObj(mousefilter, customobj);
  473.  
  474.                                         if (*hotkey) {
  475.                                             unsigned long len;
  476.  
  477.                                             if (hotkeyfilter = HotKey(hotkey, cxport, POP_KEY_ID)) {
  478.                                                 AttachCxObj(broker, hotkeyfilter);
  479.                                                 len = strlen(windowtitle);
  480.                                                 strncpy(windowtitle + len, ": HotKey=", WINDOWTITLE_LEN - len);
  481.                                                 len += sizeof(": HotKey=") - 1;
  482.                                                 strncpy(windowtitle + len, hotkey, WINDOWTITLE_LEN - len);
  483.                                                 }
  484.  
  485.                                             } /* if hotkey */
  486.  
  487.                                         if (!CxObjError(mousefilter) &&
  488.                                             !(hotkeyfilter && CxObjError(hotkeyfilter))) {
  489.  
  490.                                             /*
  491.                                              *  activate our commodity
  492.                                              */
  493.                                             ActivateCxObj(broker, 1l);
  494.                                             /*
  495.                                              *  now watch our numerous ports
  496.                                              */
  497.                                             processmessages(window);
  498.  
  499.                                             } /* if !CxObjError() */
  500.  
  501.                                         } /* if customobj */
  502.  
  503.                                     } /* if mousefilter */
  504.  
  505.                                 DeleteCxObjAll(broker);
  506.  
  507.                                 } /* if broker */
  508.  
  509.                             #ifdef DEBUG
  510.                             else printf("main(): CxBroker() failed!\n");
  511.                             #endif
  512.  
  513.                             /*
  514.                              *  delete our message port after replying all pending messages
  515.                              */
  516.                             while (msg = GetMsg(cxport)) ReplyMsg(msg);
  517.                             DeleteMsgPort(cxport);
  518.                             } /* if cxport */
  519.  
  520.                         #ifdef DEBUG
  521.                         else printf("main(): CraeteMsgPort() failed!\n");
  522.                         #endif
  523.  
  524.                         CloseLibrary(GadToolsBase);
  525.                         } /* if GadToolsBase */
  526.  
  527.                     CloseLibrary(GfxBase);
  528.                     } /* if GfxBase */
  529.  
  530.                 CloseLibrary(CxBase);
  531.                 } /* if CxBase */
  532.  
  533.             /*
  534.              *  free memory allocated by ArgArrayInit()
  535.              */
  536.             ArgArrayDone();
  537.  
  538.             CloseLibrary(IconBase);
  539.             } /* if IconBase */
  540.  
  541.         CloseLibrary((struct Library *)IntuitionBase);
  542.         } /* if IntuitionBase */
  543.  
  544. } /* main() */
  545.  
  546. void processmessages(short window)
  547. {
  548.     struct Message *msg;
  549.     unsigned long sigreceived;
  550.     unsigned long msgtype;
  551.     unsigned long msgid;
  552.     unsigned short quit = FALSE;
  553.     unsigned short windowopen = FALSE;
  554.     unsigned char command = CCMD_NOP;
  555.  
  556.     if (window) {
  557.         if (openwindow()) windowopen = TRUE;
  558.         }
  559.  
  560.     while (!quit) {
  561.  
  562.         sigreceived = Wait(SIGBREAKF_CTRL_C | cxsigflag | idcmpsigflag);
  563.  
  564.         #ifdef DEBUG
  565.         printf("processmessages(): signal received\n");
  566.         #endif
  567.  
  568.         if (sigreceived & SIGBREAKF_CTRL_C) quit = TRUE;
  569.  
  570.         if (sigreceived & cxsigflag) {
  571.  
  572.             #ifdef DEBUG
  573.             printf("processmessages(): message at cxport\n");
  574.             #endif
  575.  
  576.             while (msg = (struct Message *)GetMsg(cxport)) {
  577.  
  578.                 msgid = CxMsgID((CxMsg *)msg);
  579.                 msgtype = CxMsgType((CxMsg *)msg);
  580.  
  581.                 ReplyMsg(msg);
  582.  
  583.                 switch (msgtype) {
  584.  
  585.                     case CXM_IEVENT:
  586.                         if (msgid == POP_KEY_ID) {
  587.                             if (openwindow()) windowopen = TRUE;
  588.                             }
  589.                         break;
  590.  
  591.                     case CXM_COMMAND:
  592.                         switch (msgid) {
  593.  
  594.                             case CXCMD_KILL:
  595.                                 quit = TRUE;
  596.  
  597.                             case CXCMD_DISABLE:
  598.                                 ActivateCxObj(broker, 0l);
  599.                                 #ifdef DEBUG
  600.                                 printf("processmessages(): broker disabled\n");
  601.                                 #endif
  602.                                 break;
  603.  
  604.                             case CXCMD_ENABLE:
  605.                                 ActivateCxObj(broker, 1l);
  606.                                 #ifdef DEBUG
  607.                                 printf("processmessages(): broker enabled\n");
  608.                                 #endif
  609.                                 break;
  610.  
  611.                             case CXCMD_UNIQUE:
  612.                             case CXCMD_APPEAR:
  613.                                 if (openwindow()) windowopen = TRUE;
  614.                                 break;
  615.  
  616.                             case CXCMD_DISAPPEAR:
  617.                                 windowopen = FALSE;
  618.                                 closewindow();
  619.                                 break;
  620.  
  621.                             }
  622.                         break;
  623.  
  624.                     } /* switch msgtype */
  625.  
  626.                 } /* while CxMsg */
  627.  
  628.             } /* if (sigreceived & cxsigflag) */
  629.  
  630.         if (sigreceived & idcmpsigflag) {
  631.  
  632.             APTR *object;
  633.             ULONG class;
  634.             UWORD code;
  635.  
  636.             #ifdef DEBUG
  637.             printf("processmessages(): message at idcmpport\n");
  638.             #endif
  639.  
  640.             while (windowopen && (msg = (struct Message *)GT_GetIMsg(idcmpport))) {
  641.                 /*
  642.                  *  handle IDCMP messages
  643.                  */
  644.                 class    = ((struct IntuiMessage *)msg)->Class;
  645.                 code     = ((struct IntuiMessage *)msg)->Code;
  646.                 object   = ((struct IntuiMessage *)msg)->IAddress;
  647.                 GT_ReplyIMsg((struct IntuiMessage *)msg);
  648.  
  649.                 switch (class) {
  650.  
  651.                     case CLOSEWINDOW:
  652.                         command = CCMD_HIDE;
  653.                         break;
  654.  
  655.                     case REFRESHWINDOW:
  656.                         GT_BeginRefresh(win);
  657.                         GT_EndRefresh(win, TRUE);
  658.                         break;
  659.  
  660.                     case GADGETUP:
  661.                         if (object) command = (unsigned char)((struct Gadget *)object)->UserData;
  662.                         break;
  663.  
  664.                     case MOUSEMOVE:
  665.                         if (object) {
  666.                             switch(((struct Gadget *)object)->GadgetID & GADTOOLMASK) {
  667.  
  668.                                 case GAD_ACC:
  669.                                     acceleration = code;
  670.                                     break;
  671.  
  672.                                 case GAD_THRESH:
  673.                                     threshold = code;
  674.                                     break;
  675.  
  676.                                 }
  677.                             }
  678.                         break;
  679.  
  680.                     case VANILLAKEY:
  681.                         switch (code) {
  682.  
  683.                             case 27:
  684.                             case MSG_HIDE_SCC:
  685.                             case MSG_HIDE_SCC - CASE_DIFF:
  686.                                         command = CCMD_HIDE;
  687.                                         break;
  688.  
  689.                             case MSG_QUIT_SCC:
  690.                             case MSG_QUIT_SCC - CASE_DIFF:
  691.                                         command = CCMD_QUIT;
  692.                                         break;
  693.  
  694.                             }
  695.                         break;
  696.  
  697.                     } /* switch class */
  698.  
  699.                 } /* while idcmp message */
  700.  
  701.             } /* if (sigreceived & idcmpsigflag) */
  702.  
  703.         #ifdef DEBUG
  704.         printf("processmessages(): command = %ld\n", command);
  705.         #endif
  706.  
  707.         switch(command) {
  708.  
  709.             case CCMD_NOP:
  710.                 break;
  711.  
  712.             case CCMD_HIDE:
  713.                 closewindow();
  714.                 break;
  715.  
  716.             case CCMD_QUIT:
  717.                 quit = TRUE;
  718.                 break;
  719.  
  720.             } /* switch (command) */
  721.  
  722.         command = CCMD_NOP;
  723.  
  724.         } /* while !quit */
  725.  
  726.     ActivateCxObj(broker, 0l);
  727.     #ifdef DEBUG
  728.     printf("processmessages(): broker disabled\n");
  729.     #endif
  730.     closewindow();
  731. }
  732.  
  733. /*
  734.  *  commodity functions
  735.  */
  736. void __saveds accelerator(CxMsg *cxm)
  737. {
  738.     register struct InputEvent *ie;
  739.     register short n;
  740.     register short s;
  741.  
  742.     if ((ie = (struct InputEvent *)CxMsgData(cxm)) && (acceleration > 1)) {
  743.  
  744.         n = ie->ie_X;
  745.         s = 1;
  746.  
  747.         if (n < 0) {
  748.             n = -n;
  749.             s = -1;
  750.             }
  751.  
  752.         if (n > threshold)
  753.             ie->ie_X = s * (short)((n - threshold - 1) * acceleration + threshold + 1);
  754.  
  755.         n = ie->ie_Y;
  756.         s = 1;
  757.         if (n < 0) {
  758.             n = -n;
  759.             s = -1;
  760.             }
  761.  
  762.         if (n > threshold)
  763.             ie->ie_Y = s * (short)((n - threshold - 1) * acceleration + threshold + 1);
  764.  
  765.         }
  766. }
  767.  
  768.  
  769. /*
  770.  *  window functions
  771.  */
  772. long openwindow(void)
  773. {
  774.     struct DimensionInfo di;
  775.     struct Rectangle *rect;
  776.     unsigned long lock;
  777.     unsigned long vpmid;
  778.     long ok;
  779.  
  780.     if (win) {
  781.         #ifdef DEBUG
  782.         printf("openwindow(): window already open\n");
  783.         #endif
  784.  
  785.         /*
  786.          *  dont't open window but pop it to front, unzip it
  787.          *
  788.          *  unzip window if zipped
  789.          */
  790.         if (win->Height < mywindowtag[P_WA_Height].ti_Data) ZipWindow(win);
  791.  
  792.         /*
  793.          *  window to front
  794.          */
  795.         WindowToFront(win);
  796.  
  797.         /*
  798.          *  activate window
  799.          */
  800.         lock = LockIBase(0l);
  801.         if (win != IntuitionBase->ActiveWindow) {
  802.             UnlockIBase(lock);
  803.             ActivateWindow(win);
  804.             }
  805.         else UnlockIBase(lock);
  806.  
  807.         /*
  808.          *  screen to front
  809.          */
  810.         lock = LockIBase(0l);
  811.         if (win->WScreen != IntuitionBase->FirstScreen) {
  812.             UnlockIBase(lock);
  813.             ScreenToFront(win->WScreen);
  814.             }
  815.         else UnlockIBase(lock);
  816.  
  817.         ok = TRUE;
  818.  
  819.         }
  820.  
  821.     else {
  822.         /*
  823.          *  lock the default public screen
  824.          */
  825.         if (scr = LockPubScreen(NULL)) {
  826.             /*
  827.              *  GetVisualInfo() for gadtools
  828.              */
  829.             if (vi = GetVisualInfo(scr, TAG_DONE)) {
  830.                 /*
  831.                  *  update some window information
  832.                  */
  833.                 mywindowtag[P_WA_Width].ti_Data = zoompos[2] =
  834.                     TextLength(&scr->RastPort, (STRPTR)windowtitle, strlen(windowtitle)) + 100;
  835.                 mywindowtag[P_WA_Height].ti_Data = zoompos[3] =
  836.                     scr->WBorTop + scr->RastPort.TxHeight + 1;
  837.                 /*
  838.                  *  create all gadgets:
  839.                  *
  840.                  *  this function may also change the width and height of our window
  841.                  */
  842.                 if (createallgadgets(&gadgetlist, vi, scr,
  843.                                      &mywindowtag[P_WA_Height].ti_Data,
  844.                                      &mywindowtag[P_WA_Width].ti_Data)) {
  845.                     /*
  846.                      *  center the window in the visible box of the screen
  847.                      */
  848.                     if ((vpmid = GetVPModeID(&scr->ViewPort )) != INVALID_ID) {
  849.  
  850.                         GetDisplayInfoData(0, (UBYTE *)&di, sizeof(struct DimensionInfo), DTAG_DIMS, vpmid);
  851.                         rect = &di.TxtOScan;
  852.                         zoompos[0] = mywindowtag[P_WA_Left].ti_Data =
  853.                             (scr->LeftEdge < 0 ? -scr->LeftEdge : 0) +
  854.                             ((min((rect->MaxX - rect->MinX + 1), scr->Width) -
  855.                               mywindowtag[P_WA_Width].ti_Data) >> 1);
  856.                         zoompos[1] = mywindowtag[P_WA_Top].ti_Data =
  857.                             (scr->TopEdge < 0 ? -scr->TopEdge : 0) +
  858.                             ((min((rect->MaxY - rect->MinY + 1), scr->Height) -
  859.                               mywindowtag[P_WA_Height].ti_Data) >> 1);
  860.  
  861.                         }
  862.  
  863.                     #ifdef DEBUG
  864.                     else printf("openwindow(): GetVPModeID() == INVALID_ID\n");
  865.                     #endif
  866.  
  867.                     mywindowtag[P_WA_PubScreen].ti_Data = (ULONG)scr;
  868.                     mywindowtag[P_WA_Gadgets].ti_Data = (ULONG)gadgetlist;
  869.  
  870.                     if (win = OpenWindowTagList(NULL, mywindowtag)) {
  871.                         /*
  872.                          *  save IDCMP port
  873.                          */
  874.                         idcmpport = win->UserPort;
  875.                         idcmpsigflag = 1L << idcmpport->mp_SigBit;
  876.                 
  877.                         GT_RefreshWindow(win, NULL);
  878.                 
  879.                         /*
  880.                          *  switch screen to front
  881.                          */
  882.                         lock = LockIBase(0l);
  883.                         if (win->WScreen != IntuitionBase->FirstScreen) {
  884.                             UnlockIBase(lock);
  885.                             ScreenToFront(win->WScreen);
  886.                             }
  887.                         else UnlockIBase(lock);
  888.  
  889.                         ok = TRUE;
  890.  
  891.                         } /* if (win = OpenWindowTagList(NULL, mywindowtag)) */
  892.  
  893.                     #ifdef DEBUG
  894.                     else printf("openwindow(): OpenWindowTagList() failed\n");
  895.                     #endif
  896.  
  897.                     } /* if (createallgadgets() */
  898.  
  899.                 #ifdef DEBUG
  900.                 else printf("openwindow(): createallgadgets() failed\n");
  901.                 #endif
  902.  
  903.                 } /*  if (vi = GetVisualInfo(scr, TAG_DONE)) */
  904.  
  905.             #ifdef DEBUG
  906.             else printf("openwindow(): GetVisualInfo() failed\n");
  907.             #endif
  908.  
  909.             } /* if (scr = LockPubScreen(NULL)) */
  910.  
  911.         #ifdef DEBUG
  912.         else printf("openwindow(): could LockPubScreen(NULL)\n");
  913.         #endif
  914.  
  915.         if (!ok) {
  916.                 /*
  917.                  *  window could not be opened - free all resources
  918.                  */
  919.                 closewindow();
  920.                 }
  921.  
  922.         } /* if (!win) */
  923.         
  924.     return(ok);
  925. }
  926.  
  927. void closewindow(void)
  928. {
  929.  
  930.     if (win) {
  931.         CloseWindow(win);
  932.         win = NULL;
  933.         idcmpport = NULL;
  934.         idcmpsigflag = 0l;
  935.         }
  936.  
  937.     if (gadgetlist) {
  938.         FreeGadgets(gadgetlist);
  939.         gadgetlist = NULL;
  940.         }
  941.  
  942.     if (vi) {
  943.         FreeVisualInfo(vi);
  944.         vi = NULL;
  945.         }
  946.  
  947.     if (scr) {
  948.         UnlockPubScreen(NULL, scr);
  949.         scr = NULL;
  950.         }
  951. }
  952.  
  953. #define TAG_Max         1
  954. #define TAG_Level       2
  955. #define TAG_LevelFormat 3
  956. #define TAG_MaxLevelLen 4
  957. struct TagItem slidertags[] = {
  958.     GTSL_Min, 1l,
  959.     GTSL_Max, 0l,
  960.     GTSL_Level, 0l,
  961.     GTSL_LevelFormat, 0l,
  962.     GTSL_MaxLevelLen, 0l,
  963.     GTSL_LevelPlace, PLACETEXT_ABOVE,
  964.     TAG_END
  965.     };
  966.  
  967. /*
  968.  *  createallgadgets(): create all gadgets and put required width and height
  969.  *                      of window in height and width
  970.  */
  971. struct Gadget *
  972. createallgadgets(struct Gadget **glist, APTR vi, struct Screen *scr, ULONG *height, ULONG *width)
  973. {
  974.     static struct NewGadget ng;
  975.     struct Gadget *gad;
  976.     struct RastPort *rp;
  977.     short buttonwidth;
  978.     short accwidth;
  979.     short threshwidth;
  980.     short dummy;
  981.  
  982.     /*
  983.      *  first get RastPort of screen to determine some TextLength()
  984.      */
  985.     rp = &scr->RastPort;
  986.  
  987.     /*
  988.      *  calculate width 
  989.      */    
  990.     accwidth = TextLength(rp, msg_acc, strlen(msg_acc));
  991.     *width = max(accwidth + DBL_INTERWIDTH, *width);
  992.     threshwidth = TextLength(rp, msg_thresh, strlen(msg_thresh));
  993.     *width = max(threshwidth + DBL_INTERWIDTH, *width);
  994.  
  995.     buttonwidth = TextLength(rp, (STRPTR)&msg_hide[1], strlen(msg_hide) - 1l);
  996.     dummy       = TextLength(rp, (STRPTR)&msg_quit[1], strlen(msg_quit) - 1l);
  997.     buttonwidth = max(buttonwidth, dummy);
  998.     buttonwidth += DBL_INTERWIDTH;
  999.     /*
  1000.      *  check out if the window's width has to be enlarged
  1001.      */
  1002.     *width = max((buttonwidth << 1) + (DBL_INTERWIDTH + INTERWIDTH), *width);
  1003.  
  1004.     /*
  1005.      *  now create the gadgets
  1006.      */
  1007.     gad = CreateContext(glist);
  1008.  
  1009.     /*
  1010.      *  Acceleration gadget:
  1011.      */
  1012.     ng.ng_TopEdge       = scr->WBorTop + (rp->TxHeight << 1) + 1 + DBL_INTERHEIGHT;
  1013.     ng.ng_Width         = *width - DBL_INTERWIDTH;
  1014.     ng.ng_LeftEdge      = INTERWIDTH;
  1015.     ng.ng_Height        = rp->TxHeight + 4;
  1016.     ng.ng_TextAttr      = scr->Font;
  1017.     ng.ng_GadgetID      = GAD_ACC;
  1018.     ng.ng_VisualInfo    = vi;
  1019.     slidertags[TAG_Max].ti_Data = (ULONG)MAX_ACC;
  1020.     slidertags[TAG_Level].ti_Data = (ULONG)acceleration;
  1021.     slidertags[TAG_LevelFormat].ti_Data = (ULONG)msg_acc;
  1022.     slidertags[TAG_MaxLevelLen].ti_Data = strlen(msg_acc);
  1023.     gad_acc = gad = CreateGadgetA(SLIDER_KIND, gad, &ng, slidertags);
  1024.  
  1025.     /*
  1026.      *  threshold gadget
  1027.      */
  1028.     ng.ng_TopEdge      += ng.ng_Height + DBL_INTERHEIGHT + rp->TxHeight;
  1029.     ng.ng_GadgetID      = GAD_THRESH;
  1030.     slidertags[TAG_Max].ti_Data = (ULONG)MAX_THRESH;
  1031.     slidertags[TAG_Level].ti_Data = (ULONG)threshold;
  1032.     slidertags[TAG_LevelFormat].ti_Data = (ULONG)msg_thresh;
  1033.     slidertags[TAG_MaxLevelLen].ti_Data = strlen(msg_thresh);
  1034.     gad_thresh = gad = CreateGadgetA(SLIDER_KIND, gad, &ng, slidertags);
  1035.  
  1036.     /*
  1037.      *  dummy now gets the spacing between the button gadgets
  1038.      */
  1039.     dummy = (*width - (buttonwidth << 1)) / 3;
  1040.  
  1041.     /*
  1042.      *  Hide gadget
  1043.      */    
  1044.     ng.ng_TopEdge      += ng.ng_Height + DBL_INTERHEIGHT;
  1045.     ng.ng_Width         = buttonwidth;
  1046.     ng.ng_LeftEdge      = dummy;
  1047.     ng.ng_GadgetText    = (UBYTE *)msg_hide;
  1048.     ng.ng_GadgetID      = GAD_HIDE;
  1049.     ng.ng_Flags         = 0l;
  1050.     ng.ng_UserData      = (APTR)CCMD_HIDE;
  1051.  
  1052.     gad_hide = gad = CreateGadget(BUTTON_KIND, gad, &ng, GT_Underscore, '_', TAG_DONE);
  1053.  
  1054.     /*
  1055.      *  Quit gadget
  1056.      */    
  1057.     ng.ng_LeftEdge     += ng.ng_Width + dummy;
  1058.     ng.ng_GadgetText    = (UBYTE *)msg_quit;
  1059.     ng.ng_GadgetID      = GAD_QUIT;
  1060.     ng.ng_UserData      = (APTR)CCMD_QUIT;
  1061.  
  1062.     gad_quit = gad = CreateGadget(BUTTON_KIND, gad, &ng, GT_Underscore, '_', TAG_DONE);
  1063.  
  1064.     *height = gad->TopEdge + gad->Height + DBL_INTERHEIGHT;
  1065.  
  1066.     return(gad);
  1067. }
  1068.