home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / commod / autoacti.lzh / AutoActivate.c < prev    next >
C/C++ Source or Header  |  1991-11-19  |  16KB  |  537 lines

  1. /*
  2.  *  AutoActivate.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.03   handlecustomsignal(): activate only if !ActiveWindow->FirstRequest
  14.  *  V1.04   recompiled with main.c V1.02
  15.  *  V1.05   fixed code to find window under mouse pointer
  16.  *  V1.06   completly rewritten; shared commodity code thrown away; smaller, uses less CPU time
  17.  *  V1.07   changed priority to 21
  18.  *  V1.08   added a LockIBase()
  19.  *  V1.09   recompiled with changed (for 68040 compatiblity) cback.o
  20.  *  V1.10   added changing of priority if started from WB; thanks to Uwe Röhm
  21.  *  V1.11   reduced CPU-usage by changing autoix, removed a LockIBase()-Error
  22.  *          now using SAS/C 5.10b cback.o instead of my own one; SAS has fixed it
  23.  */
  24.  
  25. #define VERSION "V1.11"
  26.  
  27. /********************************************************************
  28.  *                             interfacing                          *
  29.  ********************************************************************/
  30.  
  31. /*
  32.  *  include files
  33.  */
  34.  
  35. #include <stdarg.h>
  36. #include <stdlib.h>
  37. #include <string.h>
  38. #include <devices/inputevent.h>
  39. #include <intuition/intuitionbase.h>
  40. #include <libraries/commodities.h>
  41.  
  42. #include <clib/alib_protos.h>
  43. #include <clib/commodities_protos.h>
  44. #include <pragmas/commodities_pragmas.h>
  45. #include <clib/dos_protos.h>
  46. #include <pragmas/dos_pragmas.h>
  47. #include <clib/exec_protos.h>
  48. #include <pragmas/exec_pragmas.h>
  49. #include <clib/intuition_protos.h>
  50. #include <pragmas/intuition_pragmas.h>
  51. #include <clib/layers_protos.h>
  52. #include <pragmas/layers_pragmas.h>
  53.  
  54. #ifdef DEBUG
  55. #define printf KPrintF
  56. #include <clib/dlib_protos.h>
  57. #endif
  58.  
  59. /*
  60.  *  prototypes
  61.  */
  62. long request(char *title, char *gadgets, char *text, ...);
  63. struct Library *myopenlibrary(char *name, unsigned long version);
  64. void activate(void);
  65. void processmessages(void);
  66.  
  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. #if defined(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                "AutoActivate"
  91. #define COM_DESCR               "Aktiviert Fenster unter Maus bei Tasten"
  92. #define NO                      "NEIN"
  93. #define TT_TIMEOUT              "SEKUNDEN"
  94.  
  95. /*
  96. #elif defined(???)  insert your language here!
  97.  */
  98.  
  99. #else
  100.  
  101. #define RETRY_GADGETS           "Retry|Cancel"
  102. #define RESUME_GADGETS          "Resume"
  103. #define MSG_LIBRARY_OPENERR     "%s (V%ld+) can't be opened!"
  104. #define COM_NAME                "AutoActivate"
  105. #define COM_DESCR               "Activate window under mouse by key"
  106. #define NO                      "NO"
  107. #define TT_TIMEOUT              "SECONDS"
  108.  
  109. #endif
  110.  
  111. #define COM_TITLE               COM_NAME " " VERSION
  112. #define CX_PRIORITY             "CX_PRIORITY"
  113. #define DEF_CX_PRIORITY         0
  114.  
  115. /*
  116.  *  data for cback.o
  117.  */
  118. #define PRIORITY 21l
  119. long _stack = 2048l;
  120. char *_procname = COM_NAME;
  121. long _priority = PRIORITY;
  122. long _BackGroundIO = 1;
  123. extern BPTR _Backstdout;
  124.  
  125. /*
  126.  *  library base pointers
  127.  */
  128. struct IntuitionBase *IntuitionBase;
  129. struct Library *CxBase;
  130. struct Library *IconBase;
  131. struct Library *LayersBase;
  132.  
  133. /*
  134.  *  message port
  135.  */
  136. struct MsgPort *cxport = NULL;
  137.  
  138. /*
  139.  *  pointer to our task
  140.  */
  141. struct Task *mytask = NULL;
  142.  
  143. /*
  144.  *  signal flags
  145.  */
  146. unsigned long customsigflag = 0l;
  147. unsigned long cxsigflag = 0l;
  148.  
  149. /*
  150.  *  programtitle and version for Version command
  151.  */
  152. char versionstring[] ="\0$VER: " COM_NAME " " VERSION;
  153.  
  154. /*
  155.  *  helpstring
  156.  */
  157. #ifdef GERMAN
  158. char helpstring[] = "\033[1m" COM_NAME "\033[0m " VERSION " (Public Domain) von Stefan Sticht\n"\
  159.                     "Aufruf: " COM_NAME " [" CX_PRIORITY "=<Zahl>]\n";
  160. #else
  161. char helpstring[] = "\033[1m" COM_NAME "\033[0m " VERSION " (Public Domain) by Stefan Sticht\n"
  162.                     "Usage: " COM_NAME " [" CX_PRIORITY "=<number>]\n";
  163. #endif
  164.  
  165. /*
  166.  *  the tooltypearray
  167.  */
  168. char **tooltypes;
  169.  
  170. /*
  171.  *  our broker
  172.  */
  173. CxObj *broker = NULL;
  174.  
  175. struct NewBroker newbroker = {
  176.     NB_VERSION,                         /* BYTE nb_Version               */
  177.     COM_NAME,                           /* BYTE *nb_Name                 */
  178.     COM_TITLE,                          /* BYTE *nb_Title                */
  179.     COM_DESCR,                          /* BYTE *nb_Descr                */
  180.     NBU_NOTIFY | NBU_UNIQUE,            /* SHORT nb_Unique               */
  181.     0,                                  /* SHORT nb_Flags                */
  182.     0,                                  /* BYTE nb_Pri                   */
  183.     NULL,                               /* struct MsgPort nb_Port        */
  184.     0                                   /* WORD nb_ReservedChannel       */
  185. };
  186.  
  187. /*
  188.  *  we only want to know of rawkey events which are not UP_PREFIX
  189.  *  and not REPEAT
  190.  */
  191. IX autoix = {
  192.     IX_VERSION,                         /* UBYTE ix_version     */
  193.     IECLASS_RAWKEY,                     /* UBYTE ix_Class       */
  194.     0,                                  /* UWORD ix_Code        */
  195.     IECODE_UP_PREFIX,                   /* UWORD ix_CodeMask    */
  196.     0,                                  /* UWORD ix_Qualifier   */
  197.     IEQUALIFIER_REPEAT,                 /* UWORD ix_Qualmask    */
  198.     0                                   /* UWORD ix_QualSame    */
  199.     };
  200.  
  201. /********************************************************************
  202.  *                             functions                            *
  203.  ********************************************************************/
  204.  
  205. /*
  206.  *  request(): a glue routine to EasyRequest as simple as printf plus
  207.  *             titlestring, gadgettexts
  208.  *
  209.  *  Input: char *title:         pointer to the title of the requester
  210.  *         char *gadgets:       pointer to gadgettext
  211.  *         char *text:          text displayed in requester
  212.  *
  213.  *  Result: same as EasyrequestArgs()
  214.  *
  215.  * !!! for more info see EasyRequestArgs() in Autodocs/intuition.doc !!!
  216.  */
  217. long request(char *title, char *gadgets, char *text, ...)
  218. {
  219.     /*
  220.      *  structure textreq only needed in this function, so hide it here
  221.      *  must be static, in order to be initialized only once
  222.      */
  223.     static struct EasyStruct textreq = {
  224.         sizeof (struct EasyStruct), /* ULONG es_StructSize      */
  225.         0l,                         /* ULONG es_Flags           */
  226.         NULL,                       /* UBYTE *es_Title          */
  227.         NULL,                       /* UBYTE *es_TextFormat     */
  228.         NULL,                       /* UBYTE *es_GadgetFormat   */
  229.         };
  230.     va_list ap;
  231.     long rc;
  232.  
  233.     /*
  234.      *  get start of variable arguments
  235.      */
  236.     va_start(ap, text);
  237.  
  238.     /*
  239.      *  update textreq
  240.      */
  241.     textreq.es_Title = (UBYTE *)title;
  242.     textreq.es_TextFormat = (UBYTE *)text;
  243.     textreq.es_GadgetFormat = (UBYTE *)gadgets;
  244.  
  245.     /*
  246.      *  win may be NULL
  247.      */
  248.     rc = EasyRequestArgs(NULL, &textreq, NULL, ap);
  249.  
  250.     va_end(ap);
  251.  
  252.     return(rc);
  253. }
  254.  
  255. /*
  256.  *  myopenlibrary(): same as OpenLibrary(), but opens a retry-requester
  257.  *                   if OpenLibrary() fails, to give the user a chance to
  258.  *                   copy the library to libs: and retry
  259.  *                   requires request(), see above
  260.  */
  261. struct Library *myopenlibrary(char *name, unsigned long version)
  262. {
  263.     static char errortext[] = MSG_LIBRARY_OPENERR;
  264.     struct Library *libptr;
  265.     long ok = TRUE;
  266.  
  267.     do {
  268.         if (!(libptr = OpenLibrary((UBYTE *)name, version))) {
  269.             if (IntuitionBase) ok = request(COM_NAME ":", RETRY_GADGETS, errortext, name, version);
  270.             else ok = FALSE;
  271.             }
  272.         } while (!libptr && ok);
  273.  
  274.     return(libptr);
  275. }
  276.  
  277. void main(int argc, char *argv[])
  278. {
  279.     CxObj *autofilter;
  280.     CxObj *signalobj;
  281.     struct Message *msg;
  282.     long signal;
  283.  
  284.     if ((argc > 1) && (*argv[1] == '?')) {
  285.         /*
  286.          *  display help string
  287.          */
  288.         if (_Backstdout) {
  289.             Write(_Backstdout, helpstring, sizeof(helpstring) - 1l);
  290.             Close(_Backstdout);
  291.             }
  292.         return;
  293.         }
  294.     else if (argc && _Backstdout) Close(_Backstdout);
  295.     #if PRIORITY != 0
  296.     else if (!argc) {
  297.         /*
  298.          *  started from Workbench: cback.o doesn't change our priority,
  299.          *  so we do here
  300.          */
  301.         #ifdef DEBUG
  302.         printf("AutoActivate: changing priority to %ld\n", PRIORITY);
  303.         #endif
  304.         if (mytask = FindTask(NULL)) SetTaskPri(mytask, PRIORITY);
  305.         }
  306.     #endif
  307.  
  308.     /*
  309.      *  open required libraries first
  310.      */
  311.     if (IntuitionBase = (struct IntuitionBase *)myopenlibrary("intuition.library", 37l)) {
  312.  
  313.         if (CxBase = myopenlibrary("commodities.library", 37l)) {
  314.  
  315.             if (IconBase = myopenlibrary("icon.library", 37l)) {
  316.  
  317.                 if (LayersBase = myopenlibrary("layers.library", 37l)) {
  318.                     /*
  319.                      * create tooltypes array (requires icon.library open!!!)
  320.                      */
  321.                     tooltypes = (char **)ArgArrayInit(argc, argv);
  322.                     /*
  323.                      *  create our message port
  324.                      */
  325.                     if (cxport = CreateMsgPort()) {
  326.  
  327.                         cxsigflag = 1l << cxport->mp_SigBit;
  328.                         /*
  329.                          * set up some broker data
  330.                          */
  331.                         newbroker.nb_Pri = ArgInt(tooltypes, CX_PRIORITY, DEF_CX_PRIORITY);
  332.                         newbroker.nb_Port = cxport;
  333.  
  334.                         if (broker = CxBroker(&newbroker, NULL)) {
  335.  
  336.                             if (autofilter = CxFilter(NULL)) {
  337.  
  338.                                 SetFilterIX(autofilter, &autoix);
  339.                                 AttachCxObj(broker, autofilter);
  340.  
  341.                                 if ((signal = (long)AllocSignal(-1)) != -1) {
  342.  
  343.                                     customsigflag = 1 << signal;
  344.  
  345.                                     if (mytask = FindTask(NULL)) {
  346.  
  347.                                         if (signalobj = CxSignal(mytask, signal)) {
  348.  
  349.                                             AttachCxObj(autofilter, signalobj);
  350.  
  351.                                             if (!CxObjError(autofilter)) {
  352.                                                 /*
  353.                                                  *  activate our commodity
  354.                                                  */
  355.                                                 ActivateCxObj(broker, 1l);
  356.                                                 /*
  357.                                                  *  now watch our numerous ports
  358.                                                  */
  359.                                                 processmessages();
  360.  
  361.                                                 } /* if !CxObjError() */
  362.  
  363.                                             } /* if signalobj */
  364.  
  365.                                         } /* if mytask */
  366.  
  367.                                     customsigflag = 0l;
  368.                                     FreeSignal(signal);
  369.  
  370.                                     } /* if signal */
  371.  
  372.                                 } /* if autofilter */
  373.  
  374.                             #ifdef DEBUG
  375.                             else printf("main(): autofilter = CxFilter() failed!\n");
  376.                             #endif
  377.  
  378.                             DeleteCxObjAll(broker);
  379.  
  380.                             } /* if broker */
  381.  
  382.                         #ifdef DEBUG
  383.                         else printf("main(): CxBroker() failed!\n");
  384.                         #endif
  385.  
  386.                         /*
  387.                          *  delete our message port after replying all pending messages
  388.                          */
  389.                         while (msg = GetMsg(cxport)) ReplyMsg(msg);
  390.                         DeleteMsgPort(cxport);
  391.                         } /* if cxport */
  392.  
  393.                     #ifdef DEBUG
  394.                     else printf("main(): CraeteMsgPort() failed!\n");
  395.                     #endif
  396.  
  397.                     ArgArrayDone();
  398.  
  399.                     CloseLibrary(LayersBase);
  400.                     } /* if LayersBase */
  401.  
  402.                 CloseLibrary(IconBase);
  403.                 } /* if IconBase */
  404.  
  405.             CloseLibrary(CxBase);
  406.             } /* if CxBase */
  407.  
  408.     CloseLibrary((struct Library *)IntuitionBase);
  409.     } /* if IntuitionBase */
  410.  
  411. } /* main() */
  412.  
  413. void processmessages(void)
  414. {
  415.     struct Message *msg;
  416.     unsigned long sigreceived;
  417.     unsigned long msgtype;
  418.     unsigned long msgid;
  419.     unsigned short quit = FALSE;
  420.  
  421.     while (!quit) {
  422.  
  423.         sigreceived = Wait(SIGBREAKF_CTRL_C | cxsigflag | customsigflag);
  424.  
  425.         #ifdef DEBUG
  426.         printf("processmessages(): signal received\n");
  427.         #endif
  428.  
  429.         if (sigreceived & customsigflag) activate();
  430.         if (sigreceived & SIGBREAKF_CTRL_C) quit = TRUE;
  431.  
  432.         if (sigreceived & cxsigflag) {
  433.  
  434.             while (msg = (struct Message *)GetMsg(cxport)) {
  435.  
  436.                 msgid = CxMsgID((CxMsg *)msg);
  437.                 msgtype = CxMsgType((CxMsg *)msg);
  438.  
  439.                 ReplyMsg(msg);
  440.  
  441.                 switch (msgtype) {
  442.  
  443.                     case CXM_COMMAND:
  444.                         switch (msgid) {
  445.  
  446.                             case CXCMD_UNIQUE:
  447.                             case CXCMD_KILL:
  448.                                 quit = TRUE;
  449.                                 break;
  450.  
  451.                             case CXCMD_DISABLE:
  452.                                 ActivateCxObj(broker, 0l);
  453.                                 break;
  454.  
  455.                             case CXCMD_ENABLE:
  456.                                 ActivateCxObj(broker, 1l);
  457.                                 break;
  458.  
  459.                             }
  460.                         break;
  461.  
  462.                     } /* switch msgtype */
  463.  
  464.                 } /* while CxMsg */
  465.  
  466.             } /* if (sigreceived & cxsigflag) */
  467.  
  468.         } /* while !quit */
  469.  
  470.     ActivateCxObj(broker, 0l);
  471. }
  472.  
  473. /*
  474.  *  commodity functions
  475.  */
  476. void activate(void)
  477. {
  478.     register struct Screen *scr;
  479.     register struct Window *win;
  480.     register struct Layer *layer;
  481.     unsigned long lock;
  482.  
  483.     /*
  484.      *  here we go: find screen
  485.      */
  486.     lock = LockIBase(0l);
  487.  
  488.     for (scr = IntuitionBase->FirstScreen;
  489.          scr && (scr->TopEdge > 0) && (scr->MouseY < 0);
  490.          scr = scr->NextScreen);
  491.  
  492.     if (scr) {
  493.  
  494.         #ifdef DEBUG
  495.         printf("AutoActivate(): scr = 0x%lx\n", scr);
  496.         #endif
  497.  
  498.         /*
  499.          *  get layer
  500.          */
  501.         layer = WhichLayer(&scr->LayerInfo, (long)scr->MouseX, (long)scr->MouseY);
  502.  
  503.         #ifdef DEBUG
  504.         printf("AutoActivate(): layer = 0x%lx\n", layer);
  505.         #endif
  506.  
  507.         if (layer && layer != scr->BarLayer) {
  508.  
  509.             /*
  510.              *  get window ptr
  511.              */
  512.             win = (struct Window *)layer->Window;
  513.  
  514.             #ifdef DEBUG
  515.             printf("AutoActivate(): win = 0x%lx\n", win);
  516.             #endif
  517.  
  518.             if (win &&
  519.                 win != IntuitionBase->ActiveWindow &&
  520.                 !IntuitionBase->ActiveWindow->FirstRequest) {
  521.  
  522.                 #ifdef DEBUG
  523.                 printf("AutoActivate(): ActivateWindow(0x%lx)\n", win);
  524.                 #endif
  525.  
  526.                 ActivateWindow(win);
  527.  
  528.                 } /* if win */
  529.  
  530.             } /* if layer */
  531.  
  532.         } /* if scr */
  533.  
  534.     UnlockIBase(lock);
  535.  
  536. }
  537.