home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 3 / CDPDIII.bin / pd / commodities / leftymouse / leftymouse.c < prev    next >
C/C++ Source or Header  |  1991-08-25  |  13KB  |  444 lines

  1. /*
  2.  *  LeftyMouse.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.01   initial release
  13.  *  V1.02   recompiled with main.c V1.02
  14.  *  V1.03   completly rewritten; shared commodity code thrown away; smaller, uses less CPU time
  15.  *  V1.04   some really minor changes
  16.  *  V1.05   recompiled with changed (for 68040 compatiblity) cback.o
  17.  *  V1.06   removed filter for rawmouse-events, because mousebutton-qualifiers have to be changed
  18.  *          in not-rawmouse-events, too; no one reported me this; anyone using it?
  19.  *          made faults in the change-the-buttons-code;
  20.  *          changed default priority in commodities list to 1 for better
  21.  *          usability with ClickToFront or toBack&Front
  22.  */
  23.  
  24. #define VERSION "V1.06"
  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 <libraries/commodities.h>
  39.  
  40. #include <clib/alib_protos.h>
  41. #include <clib/commodities_protos.h>
  42. #include <pragmas/commodities_pragmas.h>
  43. #include <clib/dos_protos.h>
  44. #include <pragmas/dos_pragmas.h>
  45. #include <clib/exec_protos.h>
  46. #include <pragmas/exec_pragmas.h>
  47. #include <clib/intuition_protos.h>
  48. #include <pragmas/intuition_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 __saveds leftymouse(register CxMsg *cxm);
  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                "LeftyMouse"
  89. #define COM_DESCR               "Vertauscht linke und rechte Maustaste"
  90.  
  91. #else
  92.  
  93. #define RETRY_GADGETS           "Retry|Cancel"
  94. #define RESUME_GADGETS          "Resume"
  95. #define MSG_LIBRARY_OPENERR     "%s (V%ld+) can't be opened!"
  96. #define COM_NAME                "LeftyMouse"
  97. #define COM_DESCR               "Swaps left and right mousebutton"
  98.  
  99. #endif
  100.  
  101. #define COM_TITLE           COM_NAME " " VERSION
  102. #define CX_PRIORITY         "CX_PRIORITY"
  103. #define DEF_CX_PRIORITY     1
  104.  
  105. /*
  106.  *  data for cback.o
  107.  */
  108. long _stack = 2048l;
  109. char *_procname = COM_NAME;
  110. long _priority = 0l;
  111. long _BackGroundIO = 1;
  112. extern BPTR _Backstdout;
  113.  
  114. /*
  115.  *  library base pointers
  116.  */
  117. struct Library *IntuitionBase;
  118. struct Library *CxBase;
  119. struct Library *IconBase;
  120.  
  121. /*
  122.  *  message port
  123.  */
  124. struct MsgPort *cxport = NULL;
  125.  
  126. /*
  127.  *  signal flag
  128.  */
  129. unsigned long cxsigflag = 0l;
  130.  
  131. /*
  132.  *  programtitle and version for Version command
  133.  */
  134. char versionstring[] ="\0$VER: " COM_NAME " " VERSION;
  135.  
  136. /*
  137.  *  helpstring
  138.  */
  139. #ifdef GERMAN
  140. char helpstring[] = "\033[1m" COM_NAME "\033[0m " VERSION " (Public Domain) von Stefan Sticht\n"\
  141.                     "Aufruf: " COM_NAME " [" CX_PRIORITY "=<Zahl>]\n";
  142. #else
  143. char helpstring[] = "\033[1m" COM_NAME "\033[0m " VERSION " (Public Domain) by Stefan Sticht\n"
  144.                     "Usage: " COM_NAME " [" CX_PRIORITY "=<number>]\n";
  145. #endif
  146.  
  147. /*
  148.  *  the tooltypearray
  149.  */
  150. char **tooltypes;
  151.  
  152. /*
  153.  *  our broker
  154.  */
  155. CxObj *broker = NULL;
  156.  
  157. struct NewBroker newbroker = {
  158.     NB_VERSION,                         /* BYTE nb_Version               */
  159.     COM_NAME,                           /* BYTE *nb_Name                 */
  160.     COM_TITLE,                          /* BYTE *nb_Title                */
  161.     COM_DESCR,                          /* BYTE *nb_Descr                */
  162.     NBU_NOTIFY | NBU_UNIQUE,            /* SHORT nb_Unique               */
  163.     0,                                  /* SHORT nb_Flags                */
  164.     0,                                  /* BYTE nb_Pri                   */
  165.     NULL,                               /* struct MsgPort nb_Port        */
  166.     0                                   /* WORD nb_ReservedChannel       */
  167. };
  168.  
  169. /********************************************************************
  170.  *                             functions                            *
  171.  ********************************************************************/
  172.  
  173. /*
  174.  *  request(): a glue routine to EasyRequest as simple as printf plus
  175.  *             titlestring, gadgettexts
  176.  *
  177.  *  Input: char *title:         pointer to the title of the requester
  178.  *         char *gadgets:       pointer to gadgettext
  179.  *         char *text:          text displayed in requester
  180.  *
  181.  *  Result: same as EasyrequestArgs()
  182.  *
  183.  * !!! for more info see EasyRequestArgs() in Autodocs/intuition.doc !!!
  184.  */
  185. long request(char *title, char *gadgets, char *text, ...)
  186. {
  187.     /*
  188.      *  structure textreq only needed in this function, so hide it here
  189.      *  must be static, in order to be initialized only once
  190.      */
  191.     static struct EasyStruct textreq = {
  192.         sizeof (struct EasyStruct), /* ULONG es_StructSize      */
  193.         0l,                         /* ULONG es_Flags           */
  194.         NULL,                       /* UBYTE *es_Title          */
  195.         NULL,                       /* UBYTE *es_TextFormat     */
  196.         NULL,                       /* UBYTE *es_GadgetFormat   */
  197.         };
  198.     va_list ap;
  199.     long rc;
  200.  
  201.     /*
  202.      *  get start of variable arguments
  203.      */
  204.     va_start(ap, text);
  205.  
  206.     /*
  207.      *  update textreq
  208.      */
  209.     textreq.es_Title = (UBYTE *)title;
  210.     textreq.es_TextFormat = (UBYTE *)text;
  211.     textreq.es_GadgetFormat = (UBYTE *)gadgets;
  212.  
  213.     /*
  214.      *  win may be NULL
  215.      */
  216.     rc = EasyRequestArgs(NULL, &textreq, NULL, ap);
  217.  
  218.     va_end(ap);
  219.  
  220.     return(rc);
  221. }
  222.  
  223. /*
  224.  *  myopenlibrary(): same as OpenLibrary(), but opens a retry-requester
  225.  *                   if OpenLibrary() fails, to give the user a chance to
  226.  *                   copy the library to libs: and retry
  227.  *                   requires request(), see above
  228.  */
  229. struct Library *myopenlibrary(char *name, unsigned long version)
  230. {
  231.     static char errortext[] = MSG_LIBRARY_OPENERR;
  232.     struct Library *libptr;
  233.     long ok = TRUE;
  234.  
  235.     do {
  236.         if (!(libptr = OpenLibrary((UBYTE *)name, version))) {
  237.             if (IntuitionBase) ok = request(COM_NAME ":", RETRY_GADGETS, errortext, name, version);
  238.             else ok = FALSE;
  239.             }
  240.         } while (!libptr && ok);
  241.  
  242.     return(libptr);
  243. }
  244.  
  245. void main(int argc, char *argv[])
  246. {
  247.     CxObj *customobj;
  248.     struct Message *msg;
  249.  
  250.     if ((argc > 1) && (*argv[1] == '?')) {
  251.         /*
  252.          *  display help string
  253.          */
  254.         if (_Backstdout) {
  255.             Write(_Backstdout, helpstring, sizeof(helpstring) - 1l);
  256.             Close(_Backstdout);
  257.             }
  258.         return;
  259.         }
  260.     else if (argc && _Backstdout) Close(_Backstdout);
  261.  
  262.     if (IntuitionBase = myopenlibrary("intuition.library", 37l)) {
  263.         /*
  264.          *  parse command line or tool types
  265.          *
  266.          *  we need icon.library therefore
  267.          */
  268.         if (IconBase = myopenlibrary("icon.library", 37l)) {
  269.  
  270.             /*
  271.              * create tooltypes array (requires icon.library open!!!)
  272.              */
  273.             tooltypes = (char **)ArgArrayInit(argc, argv);
  274.  
  275.             newbroker.nb_Pri = ArgInt(tooltypes, CX_PRIORITY, DEF_CX_PRIORITY);
  276.  
  277.             ArgArrayDone();
  278.  
  279.             CloseLibrary(IconBase);
  280.  
  281.             if (CxBase = myopenlibrary("commodities.library", 37l)) {
  282.  
  283.                 /*
  284.                  *  create our message port
  285.                  */
  286.                 if (cxport = CreateMsgPort()) {
  287.  
  288.                     cxsigflag = 1l << cxport->mp_SigBit;
  289.                     newbroker.nb_Port = cxport;
  290.  
  291.                     if (broker = CxBroker(&newbroker, NULL)) {
  292.  
  293.                         if (customobj = CxCustom(leftymouse, 0l)) {
  294.  
  295.                             AttachCxObj(broker, customobj);
  296.  
  297.                             if (!CxObjError(broker)) {
  298.                                 /*
  299.                                  *  activate our commodity
  300.                                  */
  301.                                 ActivateCxObj(broker, 1l);
  302.                                 /*
  303.                                  *  now watch our numerous ports
  304.                                  */
  305.                                 processmessages();
  306.  
  307.                                 } /* if !CxObjError() */
  308.  
  309.                             } /* if customobj */
  310.  
  311.                         DeleteCxObjAll(broker);
  312.  
  313.                         } /* if broker */
  314.  
  315.                         #ifdef DEBUG
  316.                         else printf("main(): CxBroker() failed!\n");
  317.                         #endif
  318.  
  319.                     /*
  320.                      *  delete our message port after replying all pending messages
  321.                      */
  322.                     while (msg = GetMsg(cxport)) ReplyMsg(msg);
  323.                     DeleteMsgPort(cxport);
  324.                     } /* if cxport */
  325.  
  326.                     #ifdef DEBUG
  327.                     else printf("main(): CraeteMsgPort() failed!\n");
  328.                     #endif
  329.  
  330.                 CloseLibrary(CxBase);
  331.                 } /* if CxBase */
  332.  
  333.             } /* if IconBase */
  334.  
  335.         CloseLibrary(IntuitionBase);
  336.         } /* if IntuitionBase */
  337.  
  338. } /* main() */
  339.  
  340. void processmessages(void)
  341. {
  342.     struct Message *msg;
  343.     unsigned long msgid;
  344.     unsigned long msgtype;
  345.     unsigned long sigreceived;
  346.     unsigned short quit = FALSE;
  347.  
  348.     while (!quit) {
  349.  
  350.         sigreceived = Wait(SIGBREAKF_CTRL_C | cxsigflag);
  351.  
  352.         #ifdef DEBUG
  353.         printf("processmessages(): signal received\n");
  354.         #endif
  355.  
  356.         if (sigreceived & SIGBREAKF_CTRL_C) quit = TRUE;
  357.  
  358.         if (sigreceived & cxsigflag) {
  359.  
  360.             while (msg = (struct Message *)GetMsg(cxport)) {
  361.  
  362.                 msgid = CxMsgID((CxMsg *)msg);
  363.                 msgtype = CxMsgType((CxMsg *)msg);
  364.  
  365.                 ReplyMsg(msg);
  366.  
  367.                 switch (msgtype) {
  368.  
  369.                     case CXM_COMMAND:
  370.                         switch (msgid) {
  371.  
  372.                             case CXCMD_UNIQUE:
  373.                             case CXCMD_KILL:
  374.                                 quit = TRUE;
  375.                                 break;
  376.  
  377.                             case CXCMD_DISABLE:
  378.                                 ActivateCxObj(broker, 0l);
  379.                                 break;
  380.  
  381.                             case CXCMD_ENABLE:
  382.                                 ActivateCxObj(broker, 1l);
  383.                                 break;
  384.  
  385.                             }
  386.                         break;
  387.  
  388.                     } /* switch msgtype */
  389.  
  390.                 } /* while CxMsg */
  391.  
  392.             } /* if (sigreceived & cxsigflag) */
  393.  
  394.         } /* while !quit */
  395.  
  396.     ActivateCxObj(broker, 0l);
  397. }
  398.  
  399. void __saveds leftymouse(CxMsg *cxm)
  400. {
  401.     /*
  402.      *  this function is called directly from somewhere,
  403.      *  so set up base register A4 with __saveds
  404.      */
  405.     register struct InputEvent *ie;
  406.     register UWORD code;
  407.  
  408.     if (ie = (struct InputEvent *)CxMsgData(cxm)) {
  409.  
  410.         if (ie->ie_Class == IECLASS_RAWMOUSE && ie->ie_Code != IECODE_NOBUTTON) {
  411.             code = ie->ie_Code & 0x7f;
  412.             if (code == IECODE_LBUTTON || code == IECODE_RBUTTON) {
  413.                 /*
  414.                  *  IECODE_LBUTTON <-> IECODE_RBUTTON
  415.                  *  IECODE_LBUTTON | IECODE_UP_PREFIX <-> IECODE_RBUTTON | IECODE_UP_PREFIX
  416.                  */
  417.                 #ifdef DEBUG
  418.                 printf("Class: %lx Original code: %lx ", ie->ie_Class, ie->ie_Code);
  419.                 #endif
  420.                 ie->ie_Code ^= 0x0001;
  421.                 #ifdef DEBUG
  422.                 printf("changed to %lx\n", ie->ie_Code);
  423.                 #endif
  424.                 }
  425.             }
  426.  
  427.         /*
  428.          *  IEQUALIFIER_LEFTBUTTON | IEQUALIFIER_RELATIVEMOUSE <->
  429.          *  IEQUALIFIER_RBUTTON | IEQUALIFIER_RELATIVEMOUSE
  430.          */
  431.         if (ie->ie_Qualifier & 0x6000) {
  432.             #ifdef DEBUG
  433.             printf("Class: %lx Original qualifier: %lx ", ie->ie_Class, ie->ie_Qualifier);
  434.             #endif
  435.             ie->ie_Qualifier ^= 0x6000;
  436.             #ifdef DEBUG
  437.             printf("changed to %lx\n", ie->ie_Qualifier);
  438.             #endif
  439.             }
  440.  
  441.         }
  442.  
  443. }
  444.