home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 634.lha / KGB_v2.0 / KGB.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-15  |  11.9 KB  |  601 lines

  1. /*
  2.  *                        © Pierre Dak Baillargeon 1991,1992
  3.  *
  4.  *
  5.  *  NAME
  6.  *        KGB -- control the gadgets via the keyboard.
  7.  *
  8.  *  SYNOPSIS
  9.  *        KGB
  10.  *
  11.  *  FUNCTION
  12.  *        Let the user browse and select windows, screens and gadgets
  13.  *        via the keyboard.
  14.  *
  15.  *  DESCRIPTION
  16.  *        Process all events that go through the system and search for
  17.  *        keyboard event with LALT and LCOMMAND qualifier.
  18.  *
  19.  *        When a LALT key down event is catched, arrows key let you browse
  20.  *        through the list of windows and screens in the system.
  21.  *
  22.  *        While the LATL key is down, if the LCOMMAND key goes down, the
  23.  *        arrow keys let you browse through the gadgets of the active
  24.  *        window and select them with the return key.
  25.  *
  26.  *  NOTE
  27.  *        If a window, screen or gadget goes away while the user is using
  28.  *        them, anything can happen, from nothing at all to crash.
  29.  *
  30.  */
  31.  
  32.  
  33. /*
  34.  *    Data passed to the input handler.
  35.  */
  36.  
  37. struct Box
  38. {
  39.     WORD                    x,y,w,h;
  40. };
  41.  
  42. struct Data
  43. {
  44.     struct IntuitionBase *    IntuitionBase;
  45.     struct GfxBase *        GfxBase;
  46.     UWORD                     Flags;
  47.     struct Window *            Window;
  48.     struct Gadget *            Gadget;
  49.     struct Box                Box;
  50. };
  51.  
  52.  
  53.  
  54. /*
  55.  *    Function prototypes.
  56.  */
  57.  
  58. void main(void);
  59. struct InputEvent * __asm Handler (register __a0 struct InputEvent *, register __a1 struct Data *);
  60.  
  61. void UpGadget (struct Data *);
  62. void DownGadget (struct Data *);
  63. void LeftGadget (struct Data *);
  64. void RightGadget (struct Data *);
  65.  
  66. BOOL InBox (struct Box *Box, WORD x, WORD y);
  67. void GetGad (struct Data *Data);
  68. void BoxMiddle (struct Box *);
  69. void GetBox (struct Window *, struct Gadget *, struct Box *);
  70.  
  71. void PopScreen (struct Data *);
  72. void PushScreen (struct Data *);
  73. void PopWindow (struct Data *);
  74. void PushWindow (struct Data *);
  75.  
  76.  
  77. /*
  78.  *    main
  79.  *
  80.  *        Open all the needed datas and ressources and wait for a ctrl-c.
  81.  */
  82.  
  83. void main(void)
  84. {
  85.     struct Data                Data;
  86.     struct MsgPort *        InputPort = NULL;
  87.     struct Interrupt *        InputHandler = NULL;
  88.     struct IOStdReq *        InputReq = NULL;
  89.  
  90.     if ((Data.IntuitionBase = (struct IntuitionBase *)OpenLibrary ("intuition.library", 0L)))
  91.     {
  92.         if ((Data.GfxBase = (struct GfxBase *)OpenLibrary ("graphics.library", 0L)))
  93.         {
  94.             if ((InputPort = CreatePort (0L, 0L)))
  95.             {
  96.                 if ( (InputReq = (struct IOStdReq *)CreateExtIO (InputPort, sizeof (struct IOStdReq))))
  97.                 {
  98.                     if (!OpenDevice ("input.device", NULL, InputReq, NULL))
  99.                     {
  100.                         if ( (InputHandler = AllocMem (sizeof (struct Interrupt), MEMF_PUBLIC|MEMF_CLEAR)))
  101.                         {
  102.                             Data.Window = NULL;
  103.                             Data.Gadget = NULL;
  104.                             Data.Flags = 0;
  105.  
  106.                             InputHandler->is_Code = (void (*__far)(void))Handler;
  107.                             InputHandler->is_Data = (APTR)&Data;
  108.                             InputHandler->is_Node.ln_Pri = 100;
  109.                             InputHandler->is_Node.ln_Name = "Keyboard Gadget";
  110.  
  111.                             InputReq->io_Command = IND_ADDHANDLER;
  112.                             InputReq->io_Data = (APTR)InputHandler;
  113.                             DoIO (InputReq);
  114.  
  115.                             if (Output ())
  116.                                 Write (Output(), "KGB 2.0: Keyboard gadget control, © Pierre Dak Baillargeon 1992.\n", 65);
  117.  
  118.                             Wait (SIGBREAKF_CTRL_C);
  119.  
  120.                             InputReq->io_Command = IND_REMHANDLER;
  121.                             InputReq->io_Data = (APTR)InputHandler;
  122.                             DoIO (InputReq);
  123.  
  124.                             FreeMem (InputHandler, sizeof (struct Interrupt));
  125.                         }
  126.                         CloseDevice (InputReq);
  127.                     }
  128.                     DeleteExtIO (InputReq);
  129.                 }
  130.                 DeletePort (InputPort);
  131.             }
  132.             CloseLibrary (Data.GfxBase);
  133.         }
  134.         CloseLibrary (Data.IntuitionBase);
  135.     }
  136. }
  137.  
  138.  
  139. /*
  140.  *    key and qualifer values.
  141.  */
  142.  
  143. #define RETURN        0x44
  144. #define UP            0x4C
  145. #define DOWN        0x4D
  146. #define RIGHT        0x4E
  147. #define LEFT        0x4F
  148. #define LEFT_ALT    0x64
  149. #define LEFT_AMIGA    0x66
  150.  
  151. #define KEY_UP        0x80
  152.  
  153. #define LALT        IEQUALIFIER_LALT
  154. #define LCOM        IEQUALIFIER_LCOMMAND
  155.  
  156. #define MOVE        0x01
  157. #define RETURNED    0x02
  158.  
  159. #define IntuitionBase Data->IntuitionBase
  160. #define GfxBase Data->GfxBase
  161.  
  162.  
  163. struct InputEvent * __asm Handler (register __a0 struct InputEvent *chain, register __a1 struct Data *Data)
  164. {
  165.     struct InputEvent *ie = chain;
  166.  
  167.     while (ie)
  168.     {
  169.         if (ie->ie_Class == IECLASS_RAWKEY)
  170.         {
  171.             switch (ie->ie_Code)
  172.             {
  173.                 case RETURN:
  174.                     if (Data->Flags & LCOM && Data->Gadget)
  175.                     {
  176.                         ie->ie_Class = IECLASS_RAWMOUSE;
  177.                         ie->ie_Code = IECODE_LBUTTON;
  178.                         ie->ie_Qualifier = IEQUALIFIER_RELATIVEMOUSE;
  179.                         ie->ie_X = 0;
  180.                         ie->ie_Y = 0;
  181.                         if ((Data->Gadget->GadgetType & ~GADGETTYPE) == SIZING
  182.                             || (Data->Gadget->GadgetType & ~GADGETTYPE) == WDRAGGING
  183.                             || (Data->Gadget->GadgetType & ~GADGETTYPE) == PROPGADGET)
  184.                         {
  185.                             Data->Flags |= MOVE;
  186.                         }
  187.                         Data->Flags |= RETURNED;
  188.                     }
  189.                     break;
  190.                 case RETURN+KEY_UP:
  191.                     if (Data->Flags & LCOM && Data->Gadget)
  192.                     {
  193.                         ie->ie_Class = IECLASS_RAWMOUSE;
  194.                         ie->ie_Code = IECODE_LBUTTON + IECODE_UP_PREFIX;
  195.                         ie->ie_Qualifier = IEQUALIFIER_RELATIVEMOUSE;
  196.                         ie->ie_X = 0;
  197.                         ie->ie_Y = 0;
  198.                         Data->Flags &= ~(MOVE+RETURNED);
  199.                         if ((Data->Gadget->GadgetType & ~GADGETTYPE) == CLOSE)
  200.                         {
  201.                             Data->Window = NULL;
  202.                             Data->Gadget = NULL;
  203.                         }
  204.                     }
  205.                     break;
  206.                 case UP:
  207.                     if (Data->Flags & MOVE)
  208.                     {
  209.                         /* nothing ! */
  210.                     }
  211.                     else if (Data->Flags & LCOM)
  212.                     {
  213.                         UpGadget (Data);
  214.                         GetBox (Data->Window, Data->Gadget, &Data->Box);
  215.                         BoxMiddle (&Data->Box);
  216.                         ie->ie_Class = IECLASS_POINTERPOS;
  217.                         ie->ie_Code = 0;
  218.                         ie->ie_Qualifier = 0;
  219.                         ie->ie_X = Data->Box.x;
  220.                         ie->ie_Y = Data->Box.y;
  221.                     }
  222.                     else if (Data->Flags & LALT)
  223.                     {
  224.                         PushScreen (Data);
  225.                         ie->ie_Class = IECLASS_NULL;
  226.                     }
  227.                     break;
  228.                 case DOWN:
  229.                     if (Data->Flags & MOVE)
  230.                     {
  231.                         /* nothing ! */
  232.                     }
  233.                     else if (Data->Flags & LCOM)
  234.                     {
  235.                         DownGadget (Data);
  236.                         GetBox (Data->Window, Data->Gadget, &Data->Box);
  237.                         BoxMiddle (&Data->Box);
  238.                         ie->ie_Class = IECLASS_POINTERPOS;
  239.                         ie->ie_Code = 0;
  240.                         ie->ie_Qualifier = 0;
  241.                         ie->ie_X = Data->Box.x;
  242.                         ie->ie_Y = Data->Box.y;
  243.                     }
  244.                     else if (Data->Flags & LALT)
  245.                     {
  246.                         PopScreen (Data);
  247.                         ie->ie_Class = IECLASS_NULL;
  248.                     }
  249.                     break;
  250.                 case RIGHT:
  251.                     if (Data->Flags & MOVE)
  252.                     {
  253.                         /* nothing ! */
  254.                     }
  255.                     else if (Data->Flags & LCOM)
  256.                     {
  257.                         RightGadget (Data);
  258.                         GetBox (Data->Window, Data->Gadget, &Data->Box);
  259.                         BoxMiddle (&Data->Box);
  260.                         ie->ie_Class = IECLASS_POINTERPOS;
  261.                         ie->ie_Code = 0;
  262.                         ie->ie_Qualifier = 0;
  263.                         ie->ie_X = Data->Box.x;
  264.                         ie->ie_Y = Data->Box.y;
  265.                     }
  266.                     else if (Data->Flags & LALT)
  267.                     {
  268.                         PushWindow (Data);
  269.                         ie->ie_Class = IECLASS_NULL;
  270.                     }
  271.                     break;
  272.                 case LEFT:
  273.                     if (Data->Flags & MOVE)
  274.                     {
  275.                         /* nothing ! */
  276.                     }
  277.                     else if (Data->Flags & LCOM)
  278.                     {
  279.                         LeftGadget (Data);
  280.                         GetBox (Data->Window, Data->Gadget, &Data->Box);
  281.                         BoxMiddle (&Data->Box);
  282.                         ie->ie_Class = IECLASS_POINTERPOS;
  283.                         ie->ie_Code = 0;
  284.                         ie->ie_Qualifier = 0;
  285.                         ie->ie_X = Data->Box.x;
  286.                         ie->ie_Y = Data->Box.y;
  287.                     }
  288.                     else if (Data->Flags & LALT)
  289.                     {
  290.                         PopWindow (Data);
  291.                         ie->ie_Class = IECLASS_NULL;
  292.                     }
  293.                     break;
  294.                 case LEFT_ALT:
  295.                     if (!(ie->ie_Qualifier & (0xff & ~LALT)))
  296.                     {
  297.                         Data->Flags |= LALT;
  298.                         ie->ie_Class = IECLASS_NULL;
  299.                     }
  300.                     break;
  301.                 case LEFT_ALT+KEY_UP:
  302.                     if (Data->Flags & LALT)
  303.                     {
  304.                         Data->Flags &= ~(LALT+LCOM);
  305.                         if (Data->Flags & (MOVE | RETURNED))
  306.                         {
  307.                             ie->ie_Class = IECLASS_RAWMOUSE;
  308.                             ie->ie_Code = IECODE_LBUTTON + IECODE_UP_PREFIX;
  309.                             ie->ie_Qualifier = IEQUALIFIER_RELATIVEMOUSE;
  310.                             ie->ie_X = 0;
  311.                             ie->ie_Y = 0;
  312.                             Data->Flags &= ~(MOVE | RETURNED);
  313.                         }
  314.                         else
  315.                         {
  316.                             ie->ie_Class = IECLASS_NULL;
  317.                         }
  318.                     }
  319.                     break;
  320.                 case LEFT_AMIGA:
  321.                     if (Data->Flags & LALT)
  322.                     {
  323.                         Data->Window = IntuitionBase->ActiveWindow;
  324.                         GetGad (Data);
  325.                         Data->Flags  |= LCOM;
  326.                         ie->ie_Class = IECLASS_POINTERPOS;
  327.                         ie->ie_Code = 0;
  328.                         ie->ie_Qualifier = 0;
  329.                         ie->ie_X = Data->Box.x;
  330.                         ie->ie_Y = Data->Box.y;
  331.                     }
  332.                     break;
  333.                 case LEFT_AMIGA+KEY_UP:
  334.                     if (Data->Flags & LCOM)
  335.                     {
  336.                         Data->Flags &= ~LCOM;
  337.                         if (Data->Flags & (MOVE | RETURNED))
  338.                         {
  339.                             ie->ie_Class = IECLASS_RAWMOUSE;
  340.                             ie->ie_Code = IECODE_LBUTTON + IECODE_UP_PREFIX;
  341.                             ie->ie_Qualifier = IEQUALIFIER_RELATIVEMOUSE;
  342.                             ie->ie_X = 0;
  343.                             ie->ie_Y = 0;
  344.                             Data->Flags &= ~(MOVE | RETURNED);
  345.                         }
  346.                         else
  347.                         {
  348.                             ie->ie_Class = IECLASS_NULL;
  349.                         }
  350.                     }
  351.                     break;
  352.                 default:
  353.                     break;
  354.             }
  355.         }
  356.         ie = ie->ie_NextEvent;
  357.     }
  358.     return chain;
  359. }
  360.  
  361.  
  362.  
  363. void GetGad (struct Data *Data)
  364. {
  365.     Data->Gadget = NULL;
  366.     Data->Box.x = -20000;
  367.     Data->Box.y = -20000;
  368.  
  369.     if (Data->Window)
  370.     {
  371.         struct Gadget *g;
  372.         WORD dd, ndx, ndy;
  373.         struct Box NewBox;
  374.  
  375.         g = Data->Window->FirstGadget;
  376.         dd = 20000;
  377.  
  378.         while (g)
  379.         {
  380.             GetBox (Data->Window, g, &NewBox);
  381.             if (InBox (&NewBox, IntuitionBase->MouseX, IntuitionBase->MouseY))
  382.             {
  383.                 Data->Gadget = g;
  384.                 Data->Box.x = IntuitionBase->MouseX;
  385.                 Data->Box.y = IntuitionBase->MouseY;
  386.                 break;
  387.             }
  388.             else
  389.             {
  390.                 BoxMiddle (&NewBox);
  391.                 ndx = NewBox.x - IntuitionBase->MouseX;
  392.                 ndy = NewBox.y - IntuitionBase->MouseY;
  393.                 if (abs (ndx) + abs (ndy) < dd)
  394.                 {
  395.                     dd = abs (ndx) + abs (ndy);
  396.                     Data->Gadget = g;
  397.                     Data->Box.x = ndx + IntuitionBase->MouseX;
  398.                     Data->Box.y = ndy + IntuitionBase->MouseY;
  399.                 }
  400.             }
  401.             g = g->NextGadget;
  402.         }
  403.     }
  404. }
  405.  
  406.  
  407.  
  408. BOOL InBox (struct Box *Box, WORD x, WORD y)
  409. {
  410.     if (x >= Box->x && x < Box->x + Box->w && y >= Box->y && y < Box->y + Box->h)
  411.         return 1;
  412.     else
  413.         return 0;
  414. }
  415.  
  416.  
  417. void BoxMiddle (struct Box *Box)
  418. {
  419.     Box->x += Box->w/2;
  420.     Box->y += Box->h/2;
  421. }
  422.  
  423.  
  424. void GetBox (struct Window *Window, struct Gadget *Gadget, struct Box *Box)
  425. {
  426.     Box->x = Window->LeftEdge;
  427.     Box->x += Gadget->LeftEdge;
  428.     if (Gadget->Flags & GRELRIGHT)
  429.         Box->x += Window->Width - 1;
  430.  
  431.     Box->w = Gadget->Width;
  432.     if (Gadget->Flags & GRELWIDTH)
  433.         Box->w += Window->Width;
  434.  
  435.     if (!(Window->WScreen->ViewPort.Modes & HIRES))
  436.     {
  437.         Box->x *= 2;
  438.         Box->w *= 2;
  439.     }
  440.  
  441.     Box->y = Window->TopEdge;
  442.     Box->y += Gadget->TopEdge;
  443.     if (Gadget->Flags & GRELBOTTOM)
  444.         Box->y += Window->Height - 1;
  445.  
  446.     Box->h = Gadget->Height;
  447.     if (Gadget->Flags & GRELHEIGHT)
  448.         Box->h += Window->Height;
  449.  
  450.     if (!(Window->WScreen->ViewPort.Modes & LACE))
  451.     {
  452.         Box->y *= 2;
  453.         Box->h *= 2;
  454.     }
  455. }
  456.  
  457.  
  458.  
  459. void UpGadget (struct Data *Data)
  460. {
  461.     struct Gadget *g;
  462.  
  463.     if (Data->Window)
  464.     {
  465.         g = Data->Window->FirstGadget;
  466.         while (g && g->NextGadget && g->NextGadget != Data->Gadget)
  467.         {
  468.             g = g->NextGadget;
  469.         }
  470.         Data->Gadget = g;
  471.     }
  472. }
  473.  
  474.  
  475.  
  476. void DownGadget (struct Data *Data)
  477. {
  478.     if (Data->Gadget)
  479.     {
  480.         Data->Gadget = Data->Gadget->NextGadget;
  481.     }
  482.  
  483.     if (Data->Gadget == NULL)
  484.     {
  485.         if (Data->Window)
  486.         {
  487.             Data->Gadget = Data->Window->FirstGadget;
  488.         }
  489.     }
  490. }
  491.  
  492.  
  493.  
  494. void LeftGadget (struct Data *Data)
  495. {
  496.     struct Gadget *g;
  497.  
  498.     if (Data->Window)
  499.     {
  500.         g = Data->Window->FirstGadget;
  501.         while (g && g->NextGadget && g->NextGadget != Data->Gadget)
  502.         {
  503.             g = g->NextGadget;
  504.         }
  505.         Data->Gadget = g;
  506.     }
  507. }
  508.  
  509.  
  510.  
  511. void RightGadget (struct Data *Data)
  512. {
  513.     if (Data->Gadget)
  514.     {
  515.         Data->Gadget = Data->Gadget->NextGadget;
  516.     }
  517.  
  518.     if (Data->Gadget == NULL)
  519.     {
  520.         if (Data->Window)
  521.         {
  522.             Data->Gadget = Data->Window->FirstGadget;
  523.         }
  524.     }
  525. }
  526.  
  527.  
  528.  
  529. void PopScreen (struct Data *Data)
  530. {
  531.     struct Screen *s = IntuitionBase->ActiveScreen;
  532.  
  533.     if (s != NULL)
  534.     {
  535.         while (s->NextScreen)
  536.             s = s->NextScreen;
  537.         ScreenToFront (s);
  538.         if (s->FirstWindow)
  539.             ActivateWindow (s->FirstWindow);
  540.     }
  541. }
  542.  
  543.  
  544.  
  545. void PushScreen (struct Data *Data)
  546. {
  547.     struct Screen *s = IntuitionBase->ActiveScreen;
  548.  
  549.     if (s)
  550.     {
  551.         ScreenToBack (s);
  552.         s = IntuitionBase->FirstScreen;
  553.         if (s)
  554.         {
  555.             if (s->FirstWindow)
  556.             {
  557.                 ActivateWindow (s->FirstWindow);
  558.             }
  559.         }
  560.     }
  561. }
  562.  
  563.  
  564.  
  565. void PopWindow (struct Data *Data)
  566. {
  567.     struct Window *w = IntuitionBase->ActiveWindow;
  568.     struct Window *nw;
  569.  
  570.     if (w)
  571.     {
  572.         nw = IntuitionBase->ActiveScreen->FirstWindow;
  573.         while (nw->NextWindow != NULL && nw->NextWindow != w)
  574.                 nw = nw->NextWindow;
  575.         if (nw != w)
  576.         {
  577.             WindowToFront (nw);
  578.             ActivateWindow (nw);
  579.         }
  580.     }
  581. }
  582.  
  583.  
  584.  
  585. void PushWindow (struct Data *Data)
  586. {
  587.     struct Window *w = IntuitionBase->ActiveWindow;
  588.     struct Window *nw;
  589.  
  590.     if (w)
  591.     {
  592.         if ((nw = w->NextWindow) == NULL)
  593.             nw = IntuitionBase->ActiveScreen->FirstWindow;
  594.         if (nw != w)
  595.         {
  596.             WindowToBack (w);
  597.             ActivateWindow (nw);
  598.         }
  599.     }
  600. }
  601.