home *** CD-ROM | disk | FTP | other *** search
- /* kcapApp */
- /* demonstration keyboard drawing from KCAP resource */
-
- /* Greg Robbins 12/91 */
- /* Matthew Mora 12/93 */
- /* includes code stolen from Bo3b's TubeTest */
-
- /* version 1.1, 2/92: uses RGetResource rather than GetResource for KCAP;
- gets KCHR number from script manager */
-
- /* version 1.2, 2/92: adds menu of KCAP IDs, displays virtual keycodes */
-
- /* version 2.0 , 12/93: adds color and modifer keys MXM */
-
-
- #include <Types.h>
- #include <Memory.h>
- #include <Quickdraw.h>
- #include <Fonts.h>
- #include <Events.h>
- #include <Menus.h>
- #include <Windows.h>
- #include <Resources.h>
- #include <Dialogs.h>
- #include <Desk.h>
- #include <Scrap.h>
- #include <OSUtils.h>
- #include <ToolUtils.h>
- #include <SegLoad.h>
- #include <SysEqu.h>
- #include <Script.h>
- #include <Packages.h>
- #include <String.h>
- //#include <Strings.h>
- #include <Folders.h>
-
- /* Constants */
- #define appleID 1000 /* resource IDs/menu IDs for Apple, */
- #define fileID 1001 /* File and */
- #define editID 1002 /* Edit menus */
- #define displayID 1003
-
- #define appleM 0 /* Index for each menu in myMenus (array of menu handles) */
- #define fileM 1
- #define editM 2
- #define displayM 3
-
- #define menuCount 4 /* Total number of menus */
-
- #define windowID 1000 /* Resource ID for main window */
- #define aboutMeDLOG 1000 /* And Resource ID for About box dialog. */
-
- #define quitItem 1 /* Quit in the File menu */
-
- #define aboutMeCommand 1 /* Menu item in apple menu for About */
-
- typedef struct {
- Rect keyRect;
- char keyCode;
- char Ascii;
- } KeyDataRec;
-
- #pragma mark /* Globals */
- RGBColor backGroundGray,liteGray,drkGray,tinge;
- MenuHandle myMenus[menuCount];
- Rect dragRect;
- Boolean doneFlag;
- EventRecord myEvent;
- WindowPtr myWindow, whichWindow;
- char theChar;
- TEHandle gMyTE;
-
- Boolean gKeycodesFlag = false;
- short gKcapNum, gCurrDisplayItem;
- KeyDataRec myKeys[256];
- short gNumberOfKeys=0;
- long oldModifiers = 0;
-
-
- void SetUpMenus();
- void DoCommand(long int mResult);
- void DrawKeyCaps(short modifiers, short kcharNum, short kcapNum, Boolean keycodesFlag);
-
- //--------------------------------------
- void InitMac()
- //--------------------------------------
-
-
- {
- SysEnvRec gMac;
-
- InitGraf(&qd.thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(nil);
- InitCursor();
- SysEnvirons(2,&gMac);
- if (!gMac.hasColorQD)
- ExitToShell();
-
- }
- //--------------------------------------
- void InitApp()
- //--------------------------------------
- {
- Rect r;
- SetRect(&dragRect, 4, 24, qd.screenBits.bounds.right - 4, qd.screenBits.bounds.bottom - 4);
- doneFlag = false; /* flag to detect when Quit command is chosen */
-
- myWindow = GetNewCWindow(windowID, nil, (WindowPtr) -1);
- SetPort(myWindow);
-
- SetRect(&r,0,0,100,20);
- gMyTE = TENew(&r,&r);
-
- TEActivate(gMyTE);
- liteGray.red =
- liteGray.green =
- liteGray.blue = 56797;
-
- tinge.red =
- tinge.green =
- tinge.blue = 61166L;
-
- backGroundGray.red =
- backGroundGray.green =
- backGroundGray.blue = 52428L;
-
- drkGray.red =
- drkGray.green =
- drkGray.blue = 34592L;
-
- }
-
- //--------------------------------------
- CheckForKeyPress(Point pt)
- //--------------------------------------
- {
- short i;
-
- GlobalToLocal(&pt);
- for (i=0;i<gNumberOfKeys;i++){
- if (PtInRect(pt,&myKeys[i].keyRect)) {
- Rect r = myKeys[i].keyRect;
- InsetRect(&r,1,1);
- InvertRect(&r);
- while (Button()) ;
- InvertRect(&r);
- TEKey(myKeys[i].Ascii,gMyTE);
- i=gNumberOfKeys;
-
-
- }
- }
- }
- //--------------------------------------
- CheckForKeyTyped(char theChar)
- //--------------------------------------
- {
- short i;
- long n;
-
-
- for (i=0;i<gNumberOfKeys;i++){
- if (myKeys[i].keyCode == theChar) {
- Rect r = myKeys[i].keyRect;
- InsetRect(&r,1,1);
- InvertRect(&r);
- Delay(5,&n);
- InvertRect(&r);
- TEKey(myKeys[i].Ascii,gMyTE);
- i=gNumberOfKeys;
-
-
- }
- }
- }
-
- //--------------------------------------
- main()
- //--------------------------------------
- {
- Str255 tempStr, tempStr2;
- StringHandle tempStrHandle;
-
- InitMac();
- InitApp();
-
- SetUpMenus();
-
- /*
- ** Main Event Loop
- */
- do {
- if (WaitNextEvent(everyEvent, &myEvent, 50, nil)) {
-
- switch (myEvent.what) { /* case on event type */
-
- case mouseDown:
- switch (FindWindow(myEvent.where, &whichWindow)) {
-
- case inSysWindow: /* desk accessory window: call Desk Manager to handle it */
- SystemClick(&myEvent, whichWindow);
- break;
-
- case inMenuBar: /* Menu bar: learn which command, then execute it. */
- DoCommand(MenuSelect(myEvent.where));
- break;
-
- case inDrag: /* title bar: call Window Manager to drag */
- DragWindow(whichWindow, myEvent.where, &dragRect);
- break;
-
- case inContent: /* body of application window: */
- if (whichWindow != FrontWindow())
- SelectWindow(whichWindow); /* and make it active if not */
- CheckForKeyPress(myEvent.where);
- break;
- }
- break;
-
- case updateEvt: /* Update the window. */
- if ((WindowPtr) myEvent.message == myWindow) {
- BeginUpdate((WindowPtr) myEvent.message);
-
- /* draw keyboard using current keyboard modifiers,
- current KCHR, current keyboard KCAP
-
- see Tech Note 263 for a better way to get the
- KCHR data under System 7 */
-
- DrawKeyCaps(myEvent.modifiers,
- GetScript(GetEnvirons(smKeyScript), smScriptKeys),
- gKcapNum, gKeycodesFlag);
- TEUpdate(&myWindow->portRect,gMyTE);
- EndUpdate((WindowPtr) myEvent.message);
-
- /* set window title */
- NumToString(gKcapNum, tempStr);
-
- if (gKeycodesFlag) {
- /* set window title to "Virtual Keycodes for KCAP ID _" */
- tempStrHandle = GetString(128);
- if (tempStrHandle) {
- p2cstr(*tempStrHandle);
- strcpy((char*)tempStr2, (char*)*tempStrHandle);
- strcat((char*)tempStr2, p2cstr(tempStr));
- SetWTitle(myWindow, c2pstr((char*)tempStr2));
- ReleaseResource((Handle)tempStrHandle);
- }
- }
- else {
- tempStrHandle = GetString(129);
- if (tempStrHandle) {
-
- /* set window title to "Key Labels for KCAP ID _ and KCHR _" */
- p2cstr(*tempStrHandle);
- strcpy((char*)tempStr2, (char*)*tempStrHandle); /* string */
- strcat((char*)tempStr2, p2cstr(tempStr)); /* KCAP # */
- ReleaseResource((Handle)tempStrHandle);
- tempStrHandle = GetString(130);
- if (tempStrHandle) {
- p2cstr(*tempStrHandle);
- strcat((char*)tempStr2, (char*)*tempStrHandle); /* string */
-
- /* get current KCHR number */
- NumToString(GetScript(GetEnvirons(smKeyScript), smScriptKeys), tempStr);
- strcat((char*)tempStr2, p2cstr(tempStr)); /* KCHR # */
- SetWTitle(myWindow, c2pstr((char*)tempStr2));
- ReleaseResource((Handle)tempStrHandle);
- }
- }
- }
- }
- break;
-
- case keyDown:
- case autoKey: /* key pressed once or held down to repeat */
- if (myWindow == FrontWindow()) {
- theChar = (myEvent.message & charCodeMask); /* get the char */
- /*
- ** If Command key down, do it as a Menu Command.
- */
- if (myEvent.modifiers & cmdKey)
- DoCommand(MenuKey(theChar));
- else {
- theChar = (myEvent.message & keyCodeMask) >> 8;
- CheckForKeyTyped(theChar);
- }
- }
- break;
-
- }
- }
- if ((myEvent.what != mouseDown) && oldModifiers != myEvent.modifiers ) {
- DrawKeyCaps(myEvent.modifiers,
- GetScript(GetEnvirons(smKeyScript), smScriptKeys),
- gKcapNum, gKeycodesFlag);
- oldModifiers = myEvent.modifiers;
- }
- TEIdle(gMyTE);
- } while (!doneFlag);
-
- DisposeWindow (myWindow);
- }
-
-
- void SetUpMenus()
- {
- short i, kcapMaxCount, tempInt;
- Handle kcapHandle;
- Str255 tempStr, kcapStr;
- ResType tempResType;
-
- myMenus[appleM] = GetMenu(appleID); /* read Apple menu from resource file */
- AddResMenu(myMenus[appleM], 'DRVR'); /* add desk accessory names to Apple menu */
- myMenus[fileM] = GetMenu(fileID); /* read file menu from resource file */
- myMenus[editM] = GetMenu(editID); /* read edit menu from resource file */
- DisableItem(myMenus[editM], 0);
- myMenus[displayM] = GetMenu(displayID); /* read display menu from resource file */
-
- /* add IDs of KCAP resources to display menu */
- gKcapNum = *((char *) KbdType); /* KCAP ID of current keyboard */
-
- *(short *)RomMapInsert = 0x0100; /* use ROM resources, SetResLoad(false) */
-
- kcapMaxCount = CountResources('KCAP');
- if (kcapMaxCount > 0) AppendMenu(myMenus[displayM], "\p(-!");
-
- /* add KCAP menu items */
- for (i = 1; i <= kcapMaxCount; i++) {
- *(short *)RomMapInsert = 0x0100;
- kcapHandle = GetIndResource('KCAP', i);
- if (kcapHandle) {
- GetResInfo(kcapHandle, &tempInt, &tempResType, tempStr);
- NumToString(tempInt, tempStr);
- AppendMenu(myMenus[displayM],
- c2pstr(strcat(strcpy((char*)kcapStr, "KCAP "), p2cstr(tempStr))));
- ReleaseResource(kcapHandle);
-
- if (tempInt == gKcapNum) {
- CheckItem(myMenus[displayM], i+2, true);
- gCurrDisplayItem = i+2;
- }
- }
- }
- gKeycodesFlag = false; /* not displaying keycodes on keys initially */
- CheckItem(myMenus[displayM], 1, !gKeycodesFlag); /* mark that key labels are displayed */
-
- for (i = 0; i < menuCount; i++)
- InsertMenu(myMenus[i], 0); /* install menus in menu bar */
-
-
- DrawMenuBar(); /* and draw menu bar */
- }
-
-
- void ShowAboutMeDialog()
- {
- DialogPtr theDialog;
- short itemHit;
-
- theDialog = GetNewDialog(aboutMeDLOG, nil, (WindowPtr) -1);
- ModalDialog(nil, &itemHit);
- DisposDialog(theDialog);
- }
-
-
- /* DrawKeyCaps draws the key caps, given a set of
- modifiers (in the high byte of the short) and
- KCHR and KCAP resource IDs, using the current pen in
- the current GrafPort
-
- if keycodesFlag is true, the virtual keycodes are drawn
- rather than the key labels.
-
- kcapPtr just bounces along the resource data as we
- parse it
- */
-
- /* see resource type definition on p. 14-101 of IM VI */
-
- //------------------------------------------------------
- void FrameSunkenRect(Rect *r1)
- //------------------------------------------------------
- {
- short h,v;
- Rect r =*r1;
-
- h = r.left;
- v = r.top;
-
- RGBForeColor(&drkGray);
- MoveTo(h,v);v = r.bottom;LineTo(h,v); //left edge
- v=r.top;
- MoveTo(h,v);h = r.right;LineTo(h,v); //top edge
-
- RGBForeColor(&liteGray);
- h = r.right;
- v = r.top;
- MoveTo(h,v);v = r.bottom;LineTo(h,v); //right edge
- h = r.left;
- MoveTo(h,v);h = r.right;LineTo(h,v); //bottom edge
- InsetRect(&r,1,1);
- RGBForeColor((RGBColor*)RGBBlack);
- FrameRect(&r);
- }
- //------------------------------------------------------
- void FrameBumpRect(Rect *r1)
- //------------------------------------------------------
- {
- short h,v,i;
- Rect r = *r1;
-
-
- InsetRect(&r,3,3);
- for (i=0;i<2;i++){
- h = r.left;
- v = r.top;
-
- if (i==0)
- RGBForeColor(&tinge);
- else
- RGBForeColor(&liteGray);
-
- MoveTo(h,v);v = r.bottom;LineTo(h,v); //left edge
- v=r.top;
- MoveTo(h,v);h = r.right;LineTo(h,v); //top edge
-
- RGBForeColor(&drkGray);
- h = r.right;
- v = r.top;
- MoveTo(h,v);v = r.bottom;LineTo(h,v); //right edge
- h = r.left;
- MoveTo(h,v);h = r.right;LineTo(h,v); //bottom edge
- InsetRect(&r,-1,-1);
- }
- InsetRect(&r,-1,-1);
- RGBForeColor((RGBColor*)RGBBlack);
- FrameRect(&r);
- }
-
- //--------------------------------------------------------
- void AdjustTE(Rect r)
- //--------------------------------------------------------
- {
- InsetRect(&r,4,3);
- (**gMyTE).destRect = r;
- (**gMyTE).viewRect = r;
- TECalText(gMyTE);
- TEUpdate(&r,gMyTE);
- }
-
- //--------------------------------------------------------
- void DrawKeyCaps(short modifiers, short kchrNum, short kcapNum, Boolean keycodesFlag)
- //--------------------------------------------------------
- {
- typedef struct {
- char modifierMask;
- char keyCode;
- short deltaV;
- short deltaH;
- } KeyEntryRec;
-
- #define SHAPEMAXPTS 10 /* hopefully, fewer than 10 points per shape */
-
- Rect tempRect;
- Point penPoint, currPoint, swapPoint;
- Point shapePoint[SHAPEMAXPTS];
- Handle kcapResHandle;
- Ptr kcapPtr;
-
-
- KeyEntryRec thisKeyEntryRec;
- short mainIndex, shapeIndex, keyIndex, shapeTotal, shapeCount;
- short modifiedKeyCode;
-
- FontInfo theFontInfo;
- short fontHeight;
- Point charLoc;
- char theChar;
-
- RgnHandle keyshapeRgnHandle;
-
- Handle kchrResHandle;
- long state;
-
- Str255 keycodeStr;
- short saveTextSize;
- //---------------------
-
- gNumberOfKeys =0;
- GetFontInfo(&theFontInfo);
- fontHeight = theFontInfo.ascent + theFontInfo.descent;
- saveTextSize = myWindow->txSize;
- RGBBackColor(&backGroundGray);
- kchrResHandle = RGetResource('KCHR', kchrNum);
- if (ResError() == noErr && kchrResHandle != nil) {
- state = 0;
-
- kcapResHandle = RGetResource('KCAP', kcapNum);
- if (ResError() == noErr && kcapResHandle != nil) {
-
- keyshapeRgnHandle = NewRgn();
-
- MoveHHi(kcapResHandle);
- HLock(kcapResHandle);
- kcapPtr = *kcapResHandle;
-
- /* draw boundary from origin */
- tempRect = *((Rect *) kcapPtr);
- OffsetRect(&tempRect, - tempRect.left, -tempRect.top);
- EraseRect(&tempRect);
- FrameBumpRect(&tempRect);
-
- kcapPtr += sizeof(Rect);
-
- /* draw textedit area */
- tempRect = *((Rect *) kcapPtr);
- FrameSunkenRect(&tempRect);
- //FrameRect(&tempRect);
- AdjustTE(tempRect);
- kcapPtr += sizeof(Rect);
-
- /* loop through main array */
- mainIndex = *((short *) kcapPtr);
- kcapPtr += sizeof(short);
- for ( ; mainIndex>0; mainIndex--) {
-
- /* loop through shape array - build array of points for this shape */
- shapeIndex = *((short *) kcapPtr);
- kcapPtr += sizeof(short);
-
- shapeTotal = (shapeIndex < SHAPEMAXPTS ? shapeIndex + 1 : SHAPEMAXPTS);
- for (shapeCount=0; shapeIndex>-1; shapeIndex--, shapeCount++) {
- shapePoint[shapeCount] = *((Point *) kcapPtr);
- kcapPtr += sizeof(Point);
- }
-
- /* start drawing keys of this shape from 0,0 */
- MoveTo(0,0);
-
- /* loop through key array */
- keyIndex = *((short *) kcapPtr);
- kcapPtr += sizeof(short);
- for ( ; keyIndex>-1; keyIndex--) {
-
- /* get modifier mask, keyCode, and offset from previous key */
- thisKeyEntryRec = *((KeyEntryRec *) kcapPtr);
- kcapPtr += sizeof(KeyEntryRec);
-
- /* move the pen to the start of the key */
- Move(thisKeyEntryRec.deltaH, thisKeyEntryRec.deltaV);
-
- /* draw the key, composed of one or more rects */
- SetPt(&currPoint, 0, 0);
- //OpenRgn();
-
- for (shapeCount=0, shapeIndex=shapeTotal; shapeIndex;
- shapeIndex--, shapeCount++) {
-
- /* set the rect, then reverse coordinates if necessary
- to ensure it is not empty */
- SetRect(&tempRect, currPoint.h, currPoint.v,
- shapePoint[shapeCount].h, shapePoint[shapeCount].v);
-
- if (tempRect.top > tempRect.bottom) {
- swapPoint.v = tempRect.top;
- tempRect.top = tempRect.bottom;
- tempRect.bottom = swapPoint.v;
- }
- if (tempRect.left > tempRect.right) {
- swapPoint.h = tempRect.left;
- tempRect.left = tempRect.right;
- tempRect.right = swapPoint.h;
- }
-
- /* move the rect to the pen location and add it to the region */
- currPoint = shapePoint[shapeCount];
- GetPen(&penPoint);
- OffsetRect(&tempRect, penPoint.h, penPoint.v);
- FrameBumpRect(&tempRect);
- }
-
- /* draw the key frame */
- myKeys[gNumberOfKeys].keyRect = tempRect;
-
- //CloseRgn(keyshapeRgnHandle);
- //FrameRgn(keyshapeRgnHandle);
- SetEmptyRgn(keyshapeRgnHandle);
-
- /* convert the keyCode to a character code */
- /* mask out high bit of keyCode and add masked modifiers;
- KeyTrans stroke bit taken from modifier parameter */
-
-
- if (thisKeyEntryRec.keyCode & 0x80)
- modifiers &= (((short) thisKeyEntryRec.modifierMask) << 8);
- else modifiers |= (((short) thisKeyEntryRec.modifierMask) << 8);
-
- modifiedKeyCode =
- ((thisKeyEntryRec.keyCode & 0x007F) | (modifiers & 0xFF80));
-
- myKeys[gNumberOfKeys].keyCode = modifiedKeyCode & 0x7F;
- theChar = KeyTrans(*kchrResHandle, modifiedKeyCode, &state);
- myKeys[gNumberOfKeys].Ascii = theChar;
-
- if (!keycodesFlag) {
- /* center and draw the character */
- charLoc.v =
- ((tempRect.top + tempRect.bottom) / 2) - (fontHeight / 2);
- charLoc.v += theFontInfo.ascent;
- charLoc.h =
- ((tempRect.left + tempRect.right) / 2) - (CharWidth(theChar) / 2);
- MoveTo(charLoc.h, charLoc.v);
- DrawChar(theChar);
- } else {
- /* draw the virtual keycode instead of the key label */
- TextSize(9);
- NumToString(modifiedKeyCode & 0x7F, keycodeStr);
- charLoc.v =
- ((tempRect.top + tempRect.bottom) / 2) - (fontHeight / 2);
- charLoc.v += theFontInfo.ascent;
- charLoc.h =
- ((tempRect.left + tempRect.right) / 2) - (StringWidth(keycodeStr) / 2);
- MoveTo(charLoc.h, charLoc.v);
- DrawString(keycodeStr);
- }
- gNumberOfKeys++;
- /* reposition pen for next key */
- MoveTo(penPoint.h, penPoint.v);
- }
- }
- HUnlock(kcapResHandle);
- DisposeRgn(keyshapeRgnHandle);
-
- /* release the KCAP and KCHR unless they're System resources */
- if (HomeResFile(kcapResHandle) > 1) ReleaseResource(kcapResHandle);
- }
- if (HomeResFile(kchrResHandle) > 1) ReleaseResource(kchrResHandle);
-
- TextSize(saveTextSize);
- }
- }
-
-
- void DoCommand(long int mResult)
- {
- short theItem, /* menu item number from mResult low-order word */
- theMenu; /* menu number from mResult high-order word */
- Str255 name; /* desk accessory name */
- int tempInt;
- ResType tempResType;
- Str255 tempStr;
-
- Handle kcapHandle;
- theItem = LoWord(mResult); /* call Toolbox Utility routines to */
- theMenu = HiWord(mResult); /* set menu item number and menu */
-
- switch (theMenu) { /* switch on menu ID */
-
- case appleID:
- if (theItem == aboutMeCommand)
- ShowAboutMeDialog();
- else {
- GetItem(myMenus[appleM], theItem, name);
- tempInt = OpenDeskAcc(name);
- SetPort(myWindow);
- }
- break;
-
- case fileID:
- if (theItem == quitItem)
- doneFlag = true;
- break;
-
- case editID:
- if (!SystemEdit(theItem - 1)) { /* Pass the command on to the Desk Manager. */
- ; /* do nothing */
- };
- break;
-
- case displayID:
-
- if (gCurrDisplayItem != theItem) {
-
- if (theItem == 1) {
-
- /* display key labels */
- gKeycodesFlag = !gKeycodesFlag;
- CheckItem(myMenus[displayM], 1, !gKeycodesFlag);
-
- } else {
-
- *(short *)RomMapInsert = 0x0100; /* use ROM resources, SetResLoad(false) */
- kcapHandle = GetIndResource('KCAP', theItem - 2);
-
- if (kcapHandle) {
- /* find the ID of the chosen KCAP */
- GetResInfo(kcapHandle, &gKcapNum, &tempResType, tempStr);
- ReleaseResource(kcapHandle);
-
- CheckItem(myMenus[displayM], gCurrDisplayItem, false);
- CheckItem(myMenus[displayM], theItem, true);
-
- gCurrDisplayItem = theItem;
- }
- }
-
-
- EraseRect(&myWindow->portRect);
- InvalRect(&myWindow->portRect);
- }
-
- break;
- }
-
- HiliteMenu(0); /* Unhighlight menu title */
- /* (highlighted by MenuSelect) */
- }
-