ControlStripSample.c

/*
    File:       ControlStrip Sample.c
 
    Contains:   This sample shows how to call the ControlStrip functions
 
    Written by: Matthew Xavier Mora 
 
    Copyright:  Copyright © 1996-1999 by Apple Computer, Inc., All Rights Reserved.
 
                You may incorporate this Apple sample source code into your program(s) without
                restriction. This Apple sample source code has been provided "AS IS" and the
                responsibility for its operation is yours. You are not permitted to redistribute
                this Apple sample source code as "Apple sample source code" after having made
                changes. If you're going to re-distribute the source, we require that you make
                it clear in the source that the code was descended from Apple sample source
                code, but that you've made changes.
 
    Change History (most recent first):
                7/19/1999   Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
                
 
*/
 
//------------------------------------------------------------------
#pragma mark Includes
//------------------------------------------------------------------
 
#include <ControlStrip.h>
#include <Gestalt.h>
#include <string.h>
#include <Script.h>
#include <Resources.h>
 
#include "SAL_Public.h"
 
// Key definitions
enum {
    returnKeyCode       = 36,
    tabKeyCode          = 48,
    spaceKeyCode        = 49,
    deleteKeyCode       = 51,   
    escapeKeyCode       = 53,
    clearKeyCode        = 71,
    enterKeyCode        = 76,
    f5KeyCode           = 96,
    f6KeyCode           = 97,
    f7KeyCode           = 98,   
    f3KeyCode           = 99,
    f8KeyCode           = 100,
    f9KeyCode           = 101,  
    f11KeyCode          = 103,
    f13KeyCode          = 105,  
    f14KeyCode          = 107,
    f10KeyCode          = 109,
    f12KeyCode          = 111,
    f15KeyCode          = 113,
    helpKeyCode         = 114,
    homeKeyCode         = 115,
    pageUpKeyCode       = 116,
    forwardDelKeyCode   = 117,
    f4KeyCode           = 118,
    endKeyCode          = 119,
    f2KeyCode           = 120,
    pageDownKeyCode     = 121,  
    f1KeyCode           = 122,
    leftArrowKeyCode    = 123,
    rightArrowKeyCode   = 124,
    downArrowKeyCode    = 125,
    upArrowKeyCode      = 126
};
 
 
#define kNumberofSpecialKeys 32
struct KeyTable {
    short keyCode;
    char  name[14];
};
 
typedef struct KeyTable KeyTable;
 
 
KeyTable KeyCodeTable[kNumberofSpecialKeys] = {
    {escapeKeyCode ,"Escape"},
    {f1KeyCode      ,"F1"},
    {f2KeyCode      ,"F2"},
    {f3KeyCode      ,"F3"},
    {f4KeyCode      ,"F4"},
    {f5KeyCode      ,"F5"},
    {f6KeyCode      ,"F6"},
    {f7KeyCode      ,"F7"},
    {f8KeyCode      ,"F8"},
    {f9KeyCode      ,"F9"},
    {f10KeyCode     ,"F10"},
    {f11KeyCode     ,"F11"},
    {f12KeyCode     ,"F12"},
    {f13KeyCode     ,"F13"},
    {f14KeyCode     ,"F14"},
    {f15KeyCode         ,"F15"},
    {upArrowKeyCode     ,"Up Arrow"},
    {downArrowKeyCode   ,"Down Arrow"},
    {leftArrowKeyCode   ,"Left Arrow"},
    {rightArrowKeyCode  ,"Right Arrow"},
    {helpKeyCode        ,"Help"},
    {homeKeyCode        ,"Home"},
    {pageUpKeyCode      ,"Page Up"},
    {forwardDelKeyCode  ,"Forward Delete"},
    {endKeyCode         ,"End"},
    {pageDownKeyCode    ,"Page Down"},
    {deleteKeyCode      ,"Delete"},
    {returnKeyCode      ,"Return"},
    {enterKeyCode       ,"Enter"},
    {clearKeyCode       ,"Clear"},
    {spaceKeyCode       ,"Space"},
    {tabKeyCode         ,"Tab"}
};
 
 
//------------------------------------------------------------------
#pragma mark Defines
//------------------------------------------------------------------
#define     kDefaultTextSize  9
#define     kMaxSpecs 25        
 
//------------------------------------------------------------------
#pragma mark Globals
//------------------------------------------------------------------
 
Boolean     gHasControlStrip        = false;
Boolean     gCSSupportsUserFont     = false;
Boolean     gCSSupportsUserHotKey   = false;
 
//------------------------------------------------------------------
#pragma mark Prototypes
//------------------------------------------------------------------
 
pascal short DoIdle(EventRecord *evt);
pascal short DoButton(ButtonItemRef me,long m);
pascal short MyUpdate(long m);  
 
#pragma mark -
 
//------------------------------------------------------------------
pascal short DoButton(const ButtonItemRef me,const long refcon)
//------------------------------------------------------------------
{
#pragma unused (me,refcon)
 
    Boolean isVisable = SBIsControlStripVisible();
    
    SBShowHideControlStrip(!isVisable);
    
    return noErr;
}
 
//------------------------------------------------------------------
static Boolean HasControlStrip(void)
//------------------------------------------------------------------
{
    short err;
    long response;
    
    gHasControlStrip        = false;    // make sure the globals are set
    gCSSupportsUserFont     = false;
    gCSSupportsUserHotKey   = false;
 
    if (gSAL_Mac.systemVersion >= 0x0700) {
        err  = Gestalt(gestaltControlStripAttr,&response);
        if (err == noErr) {
            gHasControlStrip        = (response & (1 << gestaltControlStripExists));
            gCSSupportsUserFont     = (response & (1 << gestaltControlStripUserFont));
            gCSSupportsUserHotKey   = (response & (1 << gestaltControlStripUserHotKey));
        }
    } 
    
    return gHasControlStrip;
}
 
//------------------------------------------------------------------
    static SInt8 MyLockHandle(Handle h)
//------------------------------------------------------------------
{
    SInt8 handleState;
    
    handleState = HGetState(h);
    HLock(h);
    return handleState;
}
 
//------------------------------------------------------------------
static IsSpecialKey(short KeyCode ,char *name)
//------------------------------------------------------------------
{
    short i;
    
    for (i = 0 ;i < kNumberofSpecialKeys;i++) {
        if (KeyCodeTable[i].keyCode == KeyCode ) {
            strcpy(name,KeyCodeTable[i].name);
            
            return true;
        }
    }
     
    return false;
}
 
 
//------------------------------------------------------------------
    static char GetCharFromKeyCode(UInt16 keyCode)
//------------------------------------------------------------------
{
    static  UInt32  state = 0;              // should be 0 first time thru
    Handle  keyboardHandle = nil;           // Handle to keyboard resource if needed
    Ptr     kCharCachePtr;                  // Pointer to kCharCache
    char    theChar = 0x00;                 // the char to return
//  UInt8   handleState;
        
    kCharCachePtr = (Ptr)GetScriptManagerVariable(smKCHRCache);
    
    if (kCharCachePtr == nil ) {                                    // should never happen
        long keyboardID = GetScriptManagerVariable(smKeyScript);
 
        keyboardHandle  = GetResource('KCHR',keyboardID);
        
        if (keyboardHandle) {
            //handleState = MyLockHandle(keyboardHandle); // tech note x says we don't have to lock it
            kCharCachePtr = *keyboardHandle;
        }
    }
    
    if (kCharCachePtr) {
        UInt32  result;                         // result from KeyTranslate
 
        result = KeyTranslate(kCharCachePtr,keyCode,&state);        
        theChar = result & charCodeMask;
    }
    
    if (keyboardHandle) {                   // if we got the resource lets release it
        ReleaseResource(keyboardHandle);    // tech note x does this so we will too.
    }
    
    return theChar;
}
 
 
//------------------------------------------------------------------
    pascal short MyUpdate(long refcon)
//------------------------------------------------------------------
{
#pragma unused (refcon)
 
    Boolean         hotKey;
    unsigned char   keyCode;
//  char            theChar;
    short           modifiers;
    short           err;
    char            name[32];
    
    MoveTo(10,100);
 
    if (gHasControlStrip) {             // if Control strip is installed
        DrawString("\pControl Strip is installed.");
        MoveTo(10,120);
        DrawString("\pClick the button to toggle the state of the control strip.");
        MoveTo(10,140);
        if (gCSSupportsUserHotKey){                 // if we have a version that supports Hot keys
            SBIsShowHideHotKeyEnabled(&hotKey);     // is hotkey enabled?
             
            if (hotKey) {
                DrawString("\pHot Key is enabled.");
            } else {
                DrawString("\pHot key is not enabled.");
            }
            MoveTo(10,160);
            
            err = SBGetShowHideHotKey(&modifiers, &keyCode);    // get the hot key combo
            if (err == noErr) {
                DrawString ("\pHot Key is: ");                  // print the modifiers
                
                if (modifiers & cmdKey) {
                    DrawString ("\pCommand + ");
                }
                if (modifiers & shiftKey) {
                    DrawString ("\pShift + ");
                }
                if (modifiers & optionKey) {
                    DrawString ("\pOption + ");
                }
                if (modifiers & controlKey) {
                    DrawString ("\pControl + ");
                }
                
                if (IsSpecialKey(keyCode,name)) {
                    DrawText(name,0,strlen(name));              
                } else {
                    char theChar = GetCharFromKeyCode(keyCode);
                    DrawChar(theChar);                              // print the char
                }
            }
         }
     } else { // if gHasControlStrip
        DrawString("\pControlStrip is not installed.");
     }
     
    return noErr;
}
 
 
//------------------------------------------------------------------
    void main(void)
//------------------------------------------------------------------
{
    short       gMyWindowID;
    short       err;
    Rect        r ;
    short       buttonBottom;
 
    long buttonId = 1;
    
    SAL_InitSimpleApp(2,kSAL_UseStandardMenu);      // Simple App Sets up the Tool Box For us 
    gMyWindowID = SAL_GetDocumentWindow(128,nil);   // Get our stored window 
 
    SAL_SetRectDimensions(&r, 170, 20);         // This sets a rect's size without changing it position
    SAL_SetRectLocation(&r, 10, 30);            // This sets a rect's anchor point
 
    SAL_SetWindowUpdateProc(gSAL_CurrentWindow,MyUpdate ); //gSAL_CurrentWindow for now, its a Kludge
        
    err = SAL_InstallPushButton(0,gSAL_CurrentWindow,"\pToggle Control Strip",&r,0,DoButton,nil);
    buttonBottom = r.bottom;
    
    if (!HasControlStrip()) {           // No control strip so dim the button
        SAL_DisableMe();                // disables the current button which is the one we just created
    }
 
    SAL_GetPrintArea(gSAL_CurrentWindow,&r);    //Set the print area top coordinate
    r.top = buttonBottom + 1 ;          //so that you don't scroll the button out of view
    SAL_SetPrintArea(gSAL_CurrentWindow,&r);
    SAL_Run();                              //Let SimpleApp handle the rest
}