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