/**************************************************************************** OSK - The OnScreen Keyboard © Copyright 1989 by Jonathan Potter Ever been caught without your keyboard? This program is for you! Not public domain, but as always, freely redistributable. ****************************************************************************/ /* To make from Manx cc +L main cc +L data cc +L image ln +Cd -O OSK main data image -Lc32 */ /* Not using pre-compiled includes? Work them out yourself, then */ #include "OSK.h" main(argc,argv) int argc; char *argv[]; { ULONG class; USHORT code,gadgetid,qual=0; int a,x,y; struct Gadget *gad; port=CreatePort(0,0); request=CreateStdIO(port); OpenDevice("input.device",0,request,0); IntuitionBase=(struct IntuitionBase *) OpenLibrary("intuition.library",0); GfxBase=(struct GfxBase *) OpenLibrary("graphics.library",0); Window=NULL; fakewindow=IntuitionBase->ActiveWindow; if (argc>1 && strncmp(argv[1],"-i",2)==0) iconify(); else setupall(); FOREVER { Wait(1<UserPort->mp_SigBit); while (Msg=(struct IntuiMessage *) GetMsg(Window->UserPort)) { class=Msg->Class; code=Msg->Code; if (class==GADGETUP || class==GADGETDOWN) { gad=(struct Gadget *) Msg->IAddress; gadgetid=gad->GadgetID; } ReplyMsg((struct Message *) Msg); switch (class) { case CLOSEWINDOW: quit(); case GADGETUP: case GADGETDOWN: if (gadgetid==999) { /* Choose a new window */ hilitegad(gad); while (mousebutton()); while (!mousebutton()); Delay(5); /* Give Intuition a chance to catch up */ if (IntuitionBase->ActiveWindow) /* Make sure it was a window, not just an empty screen */ fakewindow=IntuitionBase->ActiveWindow; hilitegad(gad); break; } /* Work out qualifiers */ if (gadgetid==0x63) { if (qual&IEQUALIFIER_CONTROL) qual-=IEQUALIFIER_CONTROL; else qual+=IEQUALIFIER_CONTROL; } else if (gadgetid==0x62) { if (qual&IEQUALIFIER_CAPSLOCK) qual-=IEQUALIFIER_CAPSLOCK; else qual+=IEQUALIFIER_CAPSLOCK; } else if (gadgetid==0x60) { if (qual&IEQUALIFIER_LSHIFT) qual-=IEQUALIFIER_LSHIFT; else qual+=IEQUALIFIER_LSHIFT; } else if (gadgetid==0x61) { if (qual&IEQUALIFIER_RSHIFT) qual-=IEQUALIFIER_RSHIFT; else qual+=IEQUALIFIER_RSHIFT; } else if (gadgetid==0x64) { if (qual&IEQUALIFIER_LALT) qual-=IEQUALIFIER_LALT; else qual+=IEQUALIFIER_LALT; } else if (gadgetid==0x65) { if (qual&IEQUALIFIER_RALT) qual-=IEQUALIFIER_RALT; else qual+=IEQUALIFIER_RALT; } else if (gadgetid==0x66) { if (qual&IEQUALIFIER_LCOMMAND) qual-=IEQUALIFIER_LCOMMAND; else qual+=IEQUALIFIER_LCOMMAND; } else if (gadgetid==0x67) { if (qual&IEQUALIFIER_RCOMMAND) qual-=IEQUALIFIER_RCOMMAND; else qual+=IEQUALIFIER_RCOMMAND; } else if (gadgetid==1000) iconify(); else { /* Activate window so key presses will be sent to it */ ActivateWindow(fakewindow); hilitegad(gad); FakeKey(gadgetid,qual); if (!mousebutton()) { hilitegad(gad); break; } Delay(5); if (!mousebutton()) { hilitegad(gad); break; } FOREVER { FakeKey(gadgetid,qual); if (!mousebutton()) { hilitegad(gad); break; } Delay(1); } } break; } } } } quit() { freekeys(); /* De-allocate key gadgets */ if (Window) CloseWindow(Window); if (GfxBase) CloseLibrary((struct Library *) GfxBase); if (IntuitionBase) CloseLibrary((struct IntuitionBase *) IntuitionBase); CloseDevice(request); DeleteStdIO(request); DeletePort(port); exit(0); } setupall() { int a; char buf[80]; if (!(Window=OpenWindow(&win))) quit(); rp=Window->RPort; SetAPen(rp,1); RectFill(rp,4,11,499,103); SetAPen(rp,2); first=NULL; gadget=NULL; AddGList(Window,&iconGadget,1,1,NULL); RefreshGList(&iconGadget,Window,NULL,1); /* Setup keyboard */ addkey("ESC",10,15,26,0,0x45); /* <-- last value is GadgetID. We use the rawkey code for that key to make things much easier */ for (a=0;a<10;a++) { sprintf(buf,"F%d",a+1); addkey(buf,50+(a*32),15,26,0,0x50+a); } addkey("DEL",378,15,26,0,0x46); addkey("`",10,30,27,0,0); for (a=0;a<10;a++) { if (a<9) sprintf(buf,"%d",a+1); else strcpy(buf,"0"); addkey(buf,45+(a*22),30,15,0,a+1); } addkey("-",265,30,15,0,0xb); addkey("=",287,30,15,0,0xc); addkey("\\",309,30,15,0,0xd); addkey("BACKSPACE",331,30,73,0,0x41); addkey("TAB",10,45,37,0,0x42); addkey("q",55,45,15,0,0x10); addkey("w",77,45,15,0,0x11); addkey("e",99,45,15,0,0x12); addkey("r",121,45,15,0,0x13); addkey("t",143,45,15,0,0x14); addkey("y",165,45,15,0,0x15); addkey("u",187,45,15,0,0x16); addkey("i",209,45,15,0,0x17); addkey("o",231,45,15,0,0x18); addkey("p",253,45,15,0,0x19); addkey("[",275,45,15,0,0x1a); addkey("]",297,45,15,0,0x1b); addkey("CR",319,45,43,0,0x44); addkey("HELP",369,45,35,0,0x5f); addkey("CT",10,60,18,1,0x63); addkey("CP",35,60,18,1,0x62); addkey("a",60,60,15,0,0x20); addkey("s",82,60,15,0,0x21); addkey("d",104,60,15,0,0x22); addkey("f",126,60,15,0,0x23); addkey("g",148,60,15,0,0x24); addkey("h",170,60,15,0,0x25); addkey("j",192,60,15,0,0x26); addkey("k",214,60,15,0,0x27); addkey("l",236,60,15,0,0x28); addkey(";",258,60,15,0,0x29); addkey("'",280,60,15,0,0x2a); addkey("CR",302,60,60,0,0x44); addkey("/\\",369,60,35,0,0x4c); addkey("SHIFT",10,75,50,1,0x60); addkey("z",67,75,15,0,0x31); addkey("x",89,75,15,0,0x32); addkey("c",111,75,15,0,0x33); addkey("v",133,75,15,0,0x34); addkey("b",155,75,15,0,0x35); addkey("n",177,75,15,0,0x36); addkey("m",199,75,15,0,0x37); addkey(",",221,75,15,0,0x38); addkey(".",243,75,15,0,0x39); addkey("/",265,75,15,0,0x3a); addkey("SHIFT",287,75,50,1,0x61); addkey("<-",344,75,35,0,0x4f); addkey("->",386,75,35,0,0x4e); addkey("ALT",30,90,30,1,0x64); addkey("A",67,90,30,1,0x66); addkey("SPACE",104,90,146,0,0x40); addkey("A",257,90,30,1,0x67); addkey("ALT",294,90,30,1,0x65); addkey("\\/",369,90,35,0,0x4d); addkey("7",435,30,15,0,0x3d); addkey("8",457,30,15,0,0x3e); addkey("9",479,30,15,0,0x3f); addkey("4",435,45,15,0,0x2d); addkey("5",457,45,15,0,0x2e); addkey("6",479,45,15,0,0x2f); addkey("1",435,60,15,0,0x1d); addkey("2",457,60,15,0,0x1e); addkey("3",479,60,15,0,0x1f); addkey("0",435,75,37,0,0xf); addkey(".",479,75,15,0,0x3c); addkey("-",435,90,15,0,0x4a); addkey("CR",457,90,37,0,0x43); addkey("Window",435,15,59,0,999); /* <-- This is the only non-key gadget and lets us choose a new window */ } iconify() { ULONG prevsec=0,prevmic=0,sec,mic; freekeys(); if (Window) { win.LeftEdge=Window->LeftEdge; win.TopEdge=Window->TopEdge; CloseWindow(Window); } Window=(struct Window *) OpenWindow(&iconwin); FOREVER { Wait(1<UserPort->mp_SigBit); while (Msg=(struct IntuiMessage *) GetMsg(Window->UserPort)) { sec=Msg->Seconds; mic=Msg->Micros; ReplyMsg((struct Message *) Msg); if (DoubleClick(prevsec,prevmic,sec,mic)) { iconwin.LeftEdge=Window->LeftEdge; iconwin.TopEdge=Window->TopEdge; CloseWindow(Window); setupall(); return(0); } prevsec=sec; prevmic=mic; } } } /* A routine to generate gadgets.. shorter than having data for hundreds of gadgets */ addkey(str,x,y,w,t,id) char *str; SHORT x,y,w,t; USHORT id; { temp=(struct GList *) AllocMem(sizeof(struct GList),MEMF_CLEAR); if (first==NULL) first=temp; else gadget->next=temp; gadget=temp; gadget->next=NULL; gadget->text.FrontPen=0; gadget->text.BackPen=0; gadget->text.DrawMode=JAM1; gadget->text.LeftEdge=(w-(strlen(str)*8))/2; gadget->text.TopEdge=1; gadget->text.ITextFont=NULL; gadget->text.IText=(UBYTE *) str; gadget->text.NextText=NULL; gadget->gadget.NextGadget=NULL; gadget->gadget.LeftEdge=x; gadget->gadget.TopEdge=y; gadget->gadget.Width=w; gadget->gadget.Height=10; gadget->gadget.Flags=GADGHCOMP; if (t==0) gadget->gadget.Activation=GADGIMMEDIATE; else gadget->gadget.Activation=GADGIMMEDIATE|TOGGLESELECT; gadget->gadget.GadgetType=BOOLGADGET; gadget->gadget.GadgetRender=NULL; gadget->gadget.SelectRender=NULL; gadget->gadget.GadgetText=&gadget->text; gadget->gadget.MutualExclude=NULL; gadget->gadget.SpecialInfo=NULL; gadget->gadget.GadgetID=id; gadget->gadget.UserData=NULL; AddGList(Window,&gadget->gadget,-1,1,NULL); RefreshGList(&gadget->gadget,Window,NULL,1); /* Draw the border ourselves */ Move(rp,x-1,y-1); Draw(rp,x+w,y-1); Draw(rp,x+w,y+10); Draw(rp,x-1,y+10); Draw(rp,x-1,y-1); } /* Deallocate gadget structures */ freekeys() { gadget=first; while (gadget) { temp=gadget->next; if (gadget) FreeMem(gadget,sizeof(struct GList)); gadget=temp; } } /* Generate a fake key press */ FakeKey(key,qual) USHORT key,qual; { request->io_Command=IND_WRITEEVENT; request->io_Flags=0; request->io_Length=sizeof(struct InputEvent); request->io_Data=(APTR)&Event; Event.ie_NextEvent=NULL; Event.ie_Class=IECLASS_RAWKEY; Event.ie_TimeStamp.tv_secs=0; Event.ie_TimeStamp.tv_micro=0; Event.ie_Code=key; Event.ie_Qualifier=qual; Event.ie_X=0; Event.ie_Y=0; DoIO(request); } /* Return state of left mousebutton */ mousebutton() { return(!((USHORT)ciaa.ciapra>>6&1)); } hilitegad(gad) struct Gadget *gad; { SetDrMd(rp,COMPLEMENT); RectFill(rp,gad->LeftEdge,gad->TopEdge, gad->LeftEdge+gad->Width-1,gad->TopEdge+gad->Height-1); SetDrMd(rp,JAM1); }