home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 1.2 / amidev_cd_12.iso / reference_library / devices / dev_examples / swap_buttons.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-20  |  7.6 KB  |  229 lines

  1. /*
  2.  * Swap_Buttons.c
  3.  *
  4.  * This example swaps the function of the left and right mouse buttons
  5.  * The C code is just the wrapper that installs and removes the
  6.  * input.device handler that does the work.
  7.  *
  8.  * The handler is written in assembly code since it is important that
  9.  * handlers be as fast as possible while processing the input events.
  10.  *
  11.  * Compile and link as follows:
  12.  *
  13.  * SAS C 5.10:
  14.  *  LC -b1 -cfirst -v -w Swap_Buttons.c
  15.  *
  16.  * Adapt assemble:
  17.  *  HX68 InputHandler.a to InputHandler.o
  18.  *
  19.  * BLink:
  20.  *  BLink from LIB:c.o+Swap_Buttons.o+InputHandler.o LIB LIB:lc.lib
  21.  *  LIB:amiga.lib TO Swap_Buttons
  22.  *
  23.  */
  24.  
  25. #include <exec/types.h>
  26. #include <exec/memory.h>
  27. #include <exec/interrupts.h>
  28. #include <devices/input.h>
  29. #include <intuition/intuition.h>
  30.  
  31. #include <clib/exec_protos.h>
  32. #include <clib/alib_protos.h>
  33. #include <clib/intuition_protos.h>
  34.  
  35. #include <stdio.h>
  36.  
  37. #ifdef LATTICE
  38. int CXBRK(void) { return(0); }     /* Disable SAS CTRL/C handling */
  39. int chkabort(void) { return(0); }  /* really */
  40. #endif
  41.  
  42. UBYTE NameString[]="Swap Buttons";
  43.  
  44. struct NewWindow mywin={50,40,124,18,0,1,CLOSEWINDOW,
  45.                       WINDOWDRAG|WINDOWCLOSE|SIMPLE_REFRESH|NOCAREREFRESH,
  46.                       NULL,NULL,NameString,NULL,NULL,0,0,0,0,WBENCHSCREEN};
  47.  
  48. extern VOID ButtonSwap();
  49.  
  50. extern struct IntuitionBase *IntuitionBase;
  51.  
  52. /*
  53.  * This routine opens a window and waits for the one event that
  54.  * can happen (CLOSEWINDOW)  This is just to let the user play with
  55.  * the swapped buttons and then close the program...
  56.  */
  57. VOID WaitForUser(VOID)
  58. {
  59. struct Window  *win;
  60.  
  61. if (IntuitionBase=(struct IntuitionBase *)
  62.                                 OpenLibrary("intuition.library",33L))
  63.     {
  64.     if (win=OpenWindow(&mywin))
  65.         {
  66.         WaitPort(win->UserPort);
  67.         ReplyMsg(GetMsg(win->UserPort));
  68.  
  69.         CloseWindow(win);
  70.         }
  71.     CloseLibrary((struct Library *)IntuitionBase);
  72.     }
  73. }
  74.  
  75. VOID main(VOID)
  76. {
  77. struct IOStdReq  *inputReqBlk;
  78. struct MsgPort   *inputPort;
  79. struct Interrupt *inputHandler;
  80.  
  81. if (inputPort=CreatePort(NULL,NULL))
  82.     {
  83.     if (inputHandler=AllocMem(sizeof(struct Interrupt),
  84.                                MEMF_PUBLIC|MEMF_CLEAR))
  85.         {
  86.         if (inputReqBlk=(struct IOStdReq *)CreateExtIO(inputPort,
  87.                                                  sizeof(struct IOStdReq)))
  88.             {
  89.             if (!OpenDevice("input.device",NULL,
  90.                              (struct IORequest *)inputReqBlk,NULL))
  91.                 {
  92.                 inputHandler->is_Code=ButtonSwap;
  93.                 inputHandler->is_Data=NULL;
  94.                 inputHandler->is_Node.ln_Pri=100;
  95.                 inputHandler->is_Node.ln_Name=NameString;
  96.                 inputReqBlk->io_Data=(APTR)inputHandler;
  97.                 inputReqBlk->io_Command=IND_ADDHANDLER;
  98.                 DoIO((struct IORequest *)inputReqBlk);
  99.  
  100.                 WaitForUser();
  101.  
  102.                 inputReqBlk->io_Data=(APTR)inputHandler;
  103.                 inputReqBlk->io_Command=IND_REMHANDLER;
  104.                 DoIO((struct IORequest *)inputReqBlk);
  105.  
  106.                 CloseDevice((struct IORequest *)inputReqBlk);
  107.                 }
  108.             else
  109.                 printf("Error: Could not open input.device\n");
  110.  
  111.             DeleteExtIO((struct IORequest *)inputReqBlk);
  112.             }
  113.         else
  114.             printf("Error: Could not create I/O request\n");
  115.  
  116.         FreeMem(inputHandler,sizeof(struct Interrupt));
  117.         }
  118.     else
  119.         printf("Error: Could not allocate interrupt struct memory\n");
  120.  
  121.     DeletePort(inputPort);
  122.     }
  123. else
  124.     printf("Error: Could not create message port\n");
  125. }
  126.  
  127. ************************************************************************
  128. *       InputHandler.a
  129. *
  130. * InputHandler that does a Left/Right mouse button swap...
  131. *
  132. * See Swap_Buttons.c for details on how to compile/assemble/link...
  133. *
  134. ************************************************************************
  135. *
  136. * Required includes...
  137. *
  138.         INCDIR  "include:"
  139.         INCLUDE "exec/types.i"
  140.         INCLUDE "exec/io.i"
  141.         INCLUDE "devices/inputevent.i"
  142. *
  143. ************************************************************************
  144. *
  145. * Make the entry point external...
  146. *
  147.         xdef    _ButtonSwap
  148. *
  149. ************************************************************************
  150. *
  151. * This is the input handler that will swap the
  152. * mouse buttons for left handed use.
  153. *
  154. * The event list gets passed to you in  a0.
  155. * The is_Data field is passed to you in a1.
  156. * This example does not use the is_Data field...
  157. *
  158. * On exit you must return the event list in d0.  In this way
  159. * you could add or remove items from the event list.
  160. *
  161. * The handler gets called here...
  162. *
  163. *
  164. _ButtonSwap:    move.l  a0,-(sp)        ; Save the event list
  165. *
  166. * Since the event list could be a linked list, we start a loop
  167. * here to handle all of the events passed to us.
  168. *
  169. CheckLoop:      move.w  ie_Qualifier(a0),d1             ; Get qualifiers...
  170.                 move.w  d1,d0                           ; Two places...
  171. *
  172. * Since we are changing left and right mouse buttons, we need to make
  173. * sure that we change the qualifiers on all of the messages.  The
  174. * left and right mouse buttons are tracked in the message qualifiers
  175. * for use in such things as dragging.  To make sure that we continue
  176. * to drag correctly, we change the qualifiers.
  177. *
  178. CheckRight:     btst    #IEQUALIFIERB_RBUTTON,d1        ; Check for right
  179.                 beq.s   NoRight
  180.                 bset    #IEQUALIFIERB_LEFTBUTTON,d0     ; Set the left...
  181.                 beq.s   CheckLeft
  182. NoRight:        bclr    #IEQUALIFIERB_LEFTBUTTON,d0     ; Clear the left...
  183. *
  184. CheckLeft:      btst    #IEQUALIFIERB_LEFTBUTTON,d1     ; Check for left
  185.                 beq.s   NoLeft
  186.                 bset    #IEQUALIFIERB_RBUTTON,d0        ; Set the right...
  187.                 beq.s   SaveQual
  188. NoLeft:         bclr    #IEQUALIFIERB_RBUTTON,d0        ; Clear the right..
  189. *
  190. SaveQual:       move.w  d0,ie_Qualifier(a0)             ; Save back...
  191. *
  192. * The actual button up/down events are transmitted as the
  193. * code field in RAWMOUSE events.  The code field must the be
  194. * checked and modified when needed on RAWMOUSE events.  If the
  195. * event is not a RAWMOUSE, we are done with it.
  196. *
  197.                 cmp.b   #IECLASS_RAWMOUSE,ie_Class(a0)  ; Check for mouse
  198.                 bne.s   NextEvent                       ; If not, next...
  199. *
  200.                 move.w  ie_Code(a0),d0                  ; Get code...
  201.                 move.w  d0,d1                           ; Save...
  202.                 and.w   #$7F,d0                         ; Mask UP_PREFIX
  203.                 cmp.w   #IECODE_LBUTTON,d0              ; Check for Left...
  204.                 beq.s   SwapThem                        ; If so, swap...
  205.                 cmp.w   #IECODE_RBUTTON,d0              ; Check for Right..
  206.                 bne.s   NextEvent                       ; If not, next...
  207. *
  208. SwapThem:       eor.w   #1,d1                           ; Flip bottom bit
  209.                 move.w  d1,ie_Code(a0)                  ; Save it...
  210. *
  211. * The event list is linked via a pointer to the next event
  212. * in the first element of the structure.  That is why it is not
  213. * nessesary to use:  move.l ie_NextEvent(a0),d0
  214. *
  215. * The reason I move to d0 first is that this also checks for zero.
  216. * The last event in the list will have a NULL ie_NextEvent field.
  217. * This is NOT as standard EXEC list where the node after the last
  218. * node is NULL.  Input events are single-linked for performance.
  219. *
  220. NextEvent:      move.l  (a0),d0                         ; Get next event
  221.                 move.l  d0,a0                           ; into a0...
  222.                 bne.s   CheckLoop                       ; Do some more.
  223. *
  224. * All done, just return the event list...  (in d0)
  225. *
  226.                 move.l  (sp)+,d0        ; Get event list back...
  227.                 rts                     ; return from handler...
  228.  
  229.