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