home *** CD-ROM | disk | FTP | other *** search
- /*
- * © Pierre Dak Baillargeon 1991,1992
- *
- *
- * NAME
- * KGB -- control the gadgets via the keyboard.
- *
- * SYNOPSIS
- * KGB
- *
- * FUNCTION
- * Let the user browse and select windows, screens and gadgets
- * via the keyboard.
- *
- * DESCRIPTION
- * Process all events that go through the system and search for
- * keyboard event with LALT and LCOMMAND qualifier.
- *
- * When a LALT key down event is catched, arrows key let you browse
- * through the list of windows and screens in the system.
- *
- * While the LATL key is down, if the LCOMMAND key goes down, the
- * arrow keys let you browse through the gadgets of the active
- * window and select them with the return key.
- *
- * NOTE
- * If a window, screen or gadget goes away while the user is using
- * them, anything can happen, from nothing at all to crash.
- *
- */
-
-
- /*
- * Data passed to the input handler.
- */
-
- struct Box
- {
- WORD x,y,w,h;
- };
-
- struct Data
- {
- struct IntuitionBase * IntuitionBase;
- struct GfxBase * GfxBase;
- UWORD Flags;
- struct Window * Window;
- struct Gadget * Gadget;
- struct Box Box;
- };
-
-
-
- /*
- * Function prototypes.
- */
-
- void main(void);
- struct InputEvent * __asm Handler (register __a0 struct InputEvent *, register __a1 struct Data *);
-
- void UpGadget (struct Data *);
- void DownGadget (struct Data *);
- void LeftGadget (struct Data *);
- void RightGadget (struct Data *);
-
- BOOL InBox (struct Box *Box, WORD x, WORD y);
- void GetGad (struct Data *Data);
- void BoxMiddle (struct Box *);
- void GetBox (struct Window *, struct Gadget *, struct Box *);
-
- void PopScreen (struct Data *);
- void PushScreen (struct Data *);
- void PopWindow (struct Data *);
- void PushWindow (struct Data *);
-
-
- /*
- * main
- *
- * Open all the needed datas and ressources and wait for a ctrl-c.
- */
-
- void main(void)
- {
- struct Data Data;
- struct MsgPort * InputPort = NULL;
- struct Interrupt * InputHandler = NULL;
- struct IOStdReq * InputReq = NULL;
-
- if ((Data.IntuitionBase = (struct IntuitionBase *)OpenLibrary ("intuition.library", 0L)))
- {
- if ((Data.GfxBase = (struct GfxBase *)OpenLibrary ("graphics.library", 0L)))
- {
- if ((InputPort = CreatePort (0L, 0L)))
- {
- if ( (InputReq = (struct IOStdReq *)CreateExtIO (InputPort, sizeof (struct IOStdReq))))
- {
- if (!OpenDevice ("input.device", NULL, InputReq, NULL))
- {
- if ( (InputHandler = AllocMem (sizeof (struct Interrupt), MEMF_PUBLIC|MEMF_CLEAR)))
- {
- Data.Window = NULL;
- Data.Gadget = NULL;
- Data.Flags = 0;
-
- InputHandler->is_Code = (void (*__far)(void))Handler;
- InputHandler->is_Data = (APTR)&Data;
- InputHandler->is_Node.ln_Pri = 100;
- InputHandler->is_Node.ln_Name = "Keyboard Gadget";
-
- InputReq->io_Command = IND_ADDHANDLER;
- InputReq->io_Data = (APTR)InputHandler;
- DoIO (InputReq);
-
- if (Output ())
- Write (Output(), "KGB 2.0: Keyboard gadget control, © Pierre Dak Baillargeon 1992.\n", 65);
-
- Wait (SIGBREAKF_CTRL_C);
-
- InputReq->io_Command = IND_REMHANDLER;
- InputReq->io_Data = (APTR)InputHandler;
- DoIO (InputReq);
-
- FreeMem (InputHandler, sizeof (struct Interrupt));
- }
- CloseDevice (InputReq);
- }
- DeleteExtIO (InputReq);
- }
- DeletePort (InputPort);
- }
- CloseLibrary (Data.GfxBase);
- }
- CloseLibrary (Data.IntuitionBase);
- }
- }
-
-
- /*
- * key and qualifer values.
- */
-
- #define RETURN 0x44
- #define UP 0x4C
- #define DOWN 0x4D
- #define RIGHT 0x4E
- #define LEFT 0x4F
- #define LEFT_ALT 0x64
- #define LEFT_AMIGA 0x66
-
- #define KEY_UP 0x80
-
- #define LALT IEQUALIFIER_LALT
- #define LCOM IEQUALIFIER_LCOMMAND
-
- #define MOVE 0x01
- #define RETURNED 0x02
-
- #define IntuitionBase Data->IntuitionBase
- #define GfxBase Data->GfxBase
-
-
- struct InputEvent * __asm Handler (register __a0 struct InputEvent *chain, register __a1 struct Data *Data)
- {
- struct InputEvent *ie = chain;
-
- while (ie)
- {
- if (ie->ie_Class == IECLASS_RAWKEY)
- {
- switch (ie->ie_Code)
- {
- case RETURN:
- if (Data->Flags & LCOM && Data->Gadget)
- {
- ie->ie_Class = IECLASS_RAWMOUSE;
- ie->ie_Code = IECODE_LBUTTON;
- ie->ie_Qualifier = IEQUALIFIER_RELATIVEMOUSE;
- ie->ie_X = 0;
- ie->ie_Y = 0;
- if ((Data->Gadget->GadgetType & ~GADGETTYPE) == SIZING
- || (Data->Gadget->GadgetType & ~GADGETTYPE) == WDRAGGING
- || (Data->Gadget->GadgetType & ~GADGETTYPE) == PROPGADGET)
- {
- Data->Flags |= MOVE;
- }
- Data->Flags |= RETURNED;
- }
- break;
- case RETURN+KEY_UP:
- if (Data->Flags & LCOM && Data->Gadget)
- {
- ie->ie_Class = IECLASS_RAWMOUSE;
- ie->ie_Code = IECODE_LBUTTON + IECODE_UP_PREFIX;
- ie->ie_Qualifier = IEQUALIFIER_RELATIVEMOUSE;
- ie->ie_X = 0;
- ie->ie_Y = 0;
- Data->Flags &= ~(MOVE+RETURNED);
- if ((Data->Gadget->GadgetType & ~GADGETTYPE) == CLOSE)
- {
- Data->Window = NULL;
- Data->Gadget = NULL;
- }
- }
- break;
- case UP:
- if (Data->Flags & MOVE)
- {
- /* nothing ! */
- }
- else if (Data->Flags & LCOM)
- {
- UpGadget (Data);
- GetBox (Data->Window, Data->Gadget, &Data->Box);
- BoxMiddle (&Data->Box);
- ie->ie_Class = IECLASS_POINTERPOS;
- ie->ie_Code = 0;
- ie->ie_Qualifier = 0;
- ie->ie_X = Data->Box.x;
- ie->ie_Y = Data->Box.y;
- }
- else if (Data->Flags & LALT)
- {
- PushScreen (Data);
- ie->ie_Class = IECLASS_NULL;
- }
- break;
- case DOWN:
- if (Data->Flags & MOVE)
- {
- /* nothing ! */
- }
- else if (Data->Flags & LCOM)
- {
- DownGadget (Data);
- GetBox (Data->Window, Data->Gadget, &Data->Box);
- BoxMiddle (&Data->Box);
- ie->ie_Class = IECLASS_POINTERPOS;
- ie->ie_Code = 0;
- ie->ie_Qualifier = 0;
- ie->ie_X = Data->Box.x;
- ie->ie_Y = Data->Box.y;
- }
- else if (Data->Flags & LALT)
- {
- PopScreen (Data);
- ie->ie_Class = IECLASS_NULL;
- }
- break;
- case RIGHT:
- if (Data->Flags & MOVE)
- {
- /* nothing ! */
- }
- else if (Data->Flags & LCOM)
- {
- RightGadget (Data);
- GetBox (Data->Window, Data->Gadget, &Data->Box);
- BoxMiddle (&Data->Box);
- ie->ie_Class = IECLASS_POINTERPOS;
- ie->ie_Code = 0;
- ie->ie_Qualifier = 0;
- ie->ie_X = Data->Box.x;
- ie->ie_Y = Data->Box.y;
- }
- else if (Data->Flags & LALT)
- {
- PushWindow (Data);
- ie->ie_Class = IECLASS_NULL;
- }
- break;
- case LEFT:
- if (Data->Flags & MOVE)
- {
- /* nothing ! */
- }
- else if (Data->Flags & LCOM)
- {
- LeftGadget (Data);
- GetBox (Data->Window, Data->Gadget, &Data->Box);
- BoxMiddle (&Data->Box);
- ie->ie_Class = IECLASS_POINTERPOS;
- ie->ie_Code = 0;
- ie->ie_Qualifier = 0;
- ie->ie_X = Data->Box.x;
- ie->ie_Y = Data->Box.y;
- }
- else if (Data->Flags & LALT)
- {
- PopWindow (Data);
- ie->ie_Class = IECLASS_NULL;
- }
- break;
- case LEFT_ALT:
- if (!(ie->ie_Qualifier & (0xff & ~LALT)))
- {
- Data->Flags |= LALT;
- ie->ie_Class = IECLASS_NULL;
- }
- break;
- case LEFT_ALT+KEY_UP:
- if (Data->Flags & LALT)
- {
- Data->Flags &= ~(LALT+LCOM);
- if (Data->Flags & (MOVE | RETURNED))
- {
- ie->ie_Class = IECLASS_RAWMOUSE;
- ie->ie_Code = IECODE_LBUTTON + IECODE_UP_PREFIX;
- ie->ie_Qualifier = IEQUALIFIER_RELATIVEMOUSE;
- ie->ie_X = 0;
- ie->ie_Y = 0;
- Data->Flags &= ~(MOVE | RETURNED);
- }
- else
- {
- ie->ie_Class = IECLASS_NULL;
- }
- }
- break;
- case LEFT_AMIGA:
- if (Data->Flags & LALT)
- {
- Data->Window = IntuitionBase->ActiveWindow;
- GetGad (Data);
- Data->Flags |= LCOM;
- ie->ie_Class = IECLASS_POINTERPOS;
- ie->ie_Code = 0;
- ie->ie_Qualifier = 0;
- ie->ie_X = Data->Box.x;
- ie->ie_Y = Data->Box.y;
- }
- break;
- case LEFT_AMIGA+KEY_UP:
- if (Data->Flags & LCOM)
- {
- Data->Flags &= ~LCOM;
- if (Data->Flags & (MOVE | RETURNED))
- {
- ie->ie_Class = IECLASS_RAWMOUSE;
- ie->ie_Code = IECODE_LBUTTON + IECODE_UP_PREFIX;
- ie->ie_Qualifier = IEQUALIFIER_RELATIVEMOUSE;
- ie->ie_X = 0;
- ie->ie_Y = 0;
- Data->Flags &= ~(MOVE | RETURNED);
- }
- else
- {
- ie->ie_Class = IECLASS_NULL;
- }
- }
- break;
- default:
- break;
- }
- }
- ie = ie->ie_NextEvent;
- }
- return chain;
- }
-
-
-
- void GetGad (struct Data *Data)
- {
- Data->Gadget = NULL;
- Data->Box.x = -20000;
- Data->Box.y = -20000;
-
- if (Data->Window)
- {
- struct Gadget *g;
- WORD dd, ndx, ndy;
- struct Box NewBox;
-
- g = Data->Window->FirstGadget;
- dd = 20000;
-
- while (g)
- {
- GetBox (Data->Window, g, &NewBox);
- if (InBox (&NewBox, IntuitionBase->MouseX, IntuitionBase->MouseY))
- {
- Data->Gadget = g;
- Data->Box.x = IntuitionBase->MouseX;
- Data->Box.y = IntuitionBase->MouseY;
- break;
- }
- else
- {
- BoxMiddle (&NewBox);
- ndx = NewBox.x - IntuitionBase->MouseX;
- ndy = NewBox.y - IntuitionBase->MouseY;
- if (abs (ndx) + abs (ndy) < dd)
- {
- dd = abs (ndx) + abs (ndy);
- Data->Gadget = g;
- Data->Box.x = ndx + IntuitionBase->MouseX;
- Data->Box.y = ndy + IntuitionBase->MouseY;
- }
- }
- g = g->NextGadget;
- }
- }
- }
-
-
-
- BOOL InBox (struct Box *Box, WORD x, WORD y)
- {
- if (x >= Box->x && x < Box->x + Box->w && y >= Box->y && y < Box->y + Box->h)
- return 1;
- else
- return 0;
- }
-
-
- void BoxMiddle (struct Box *Box)
- {
- Box->x += Box->w/2;
- Box->y += Box->h/2;
- }
-
-
- void GetBox (struct Window *Window, struct Gadget *Gadget, struct Box *Box)
- {
- Box->x = Window->LeftEdge;
- Box->x += Gadget->LeftEdge;
- if (Gadget->Flags & GRELRIGHT)
- Box->x += Window->Width - 1;
-
- Box->w = Gadget->Width;
- if (Gadget->Flags & GRELWIDTH)
- Box->w += Window->Width;
-
- if (!(Window->WScreen->ViewPort.Modes & HIRES))
- {
- Box->x *= 2;
- Box->w *= 2;
- }
-
- Box->y = Window->TopEdge;
- Box->y += Gadget->TopEdge;
- if (Gadget->Flags & GRELBOTTOM)
- Box->y += Window->Height - 1;
-
- Box->h = Gadget->Height;
- if (Gadget->Flags & GRELHEIGHT)
- Box->h += Window->Height;
-
- if (!(Window->WScreen->ViewPort.Modes & LACE))
- {
- Box->y *= 2;
- Box->h *= 2;
- }
- }
-
-
-
- void UpGadget (struct Data *Data)
- {
- struct Gadget *g;
-
- if (Data->Window)
- {
- g = Data->Window->FirstGadget;
- while (g && g->NextGadget && g->NextGadget != Data->Gadget)
- {
- g = g->NextGadget;
- }
- Data->Gadget = g;
- }
- }
-
-
-
- void DownGadget (struct Data *Data)
- {
- if (Data->Gadget)
- {
- Data->Gadget = Data->Gadget->NextGadget;
- }
-
- if (Data->Gadget == NULL)
- {
- if (Data->Window)
- {
- Data->Gadget = Data->Window->FirstGadget;
- }
- }
- }
-
-
-
- void LeftGadget (struct Data *Data)
- {
- struct Gadget *g;
-
- if (Data->Window)
- {
- g = Data->Window->FirstGadget;
- while (g && g->NextGadget && g->NextGadget != Data->Gadget)
- {
- g = g->NextGadget;
- }
- Data->Gadget = g;
- }
- }
-
-
-
- void RightGadget (struct Data *Data)
- {
- if (Data->Gadget)
- {
- Data->Gadget = Data->Gadget->NextGadget;
- }
-
- if (Data->Gadget == NULL)
- {
- if (Data->Window)
- {
- Data->Gadget = Data->Window->FirstGadget;
- }
- }
- }
-
-
-
- void PopScreen (struct Data *Data)
- {
- struct Screen *s = IntuitionBase->ActiveScreen;
-
- if (s != NULL)
- {
- while (s->NextScreen)
- s = s->NextScreen;
- ScreenToFront (s);
- if (s->FirstWindow)
- ActivateWindow (s->FirstWindow);
- }
- }
-
-
-
- void PushScreen (struct Data *Data)
- {
- struct Screen *s = IntuitionBase->ActiveScreen;
-
- if (s)
- {
- ScreenToBack (s);
- s = IntuitionBase->FirstScreen;
- if (s)
- {
- if (s->FirstWindow)
- {
- ActivateWindow (s->FirstWindow);
- }
- }
- }
- }
-
-
-
- void PopWindow (struct Data *Data)
- {
- struct Window *w = IntuitionBase->ActiveWindow;
- struct Window *nw;
-
- if (w)
- {
- nw = IntuitionBase->ActiveScreen->FirstWindow;
- while (nw->NextWindow != NULL && nw->NextWindow != w)
- nw = nw->NextWindow;
- if (nw != w)
- {
- WindowToFront (nw);
- ActivateWindow (nw);
- }
- }
- }
-
-
-
- void PushWindow (struct Data *Data)
- {
- struct Window *w = IntuitionBase->ActiveWindow;
- struct Window *nw;
-
- if (w)
- {
- if ((nw = w->NextWindow) == NULL)
- nw = IntuitionBase->ActiveScreen->FirstWindow;
- if (nw != w)
- {
- WindowToBack (w);
- ActivateWindow (nw);
- }
- }
- }
-