Sources/UserTermination.cp

/*
    File:       UserTermination.cp
 
    Contains:   TUserTermination is a command dot tracking class, used for finding out if the end user wants to stop
                an action. Most of the code is based on earlier snippet by Dave Radcliffe/DTS.
                TUserTermination.cp contains class body information for the TUserTermination class.
 
    Written by: Kent Sandvik    
 
    Copyright:  Copyright © 1992-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):
                8/18/1999   Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
                
 
*/
#ifndef _USERTERMINATION_
#include "UserTermination.h"
#endif
 
 
// _________________________________________________________________________________________________________ //
// TGDevice class member function implementations
 
//  CONSTRUCTORS & DESTRUCTORS
#pragma segment UserTermination
TUserTermination::TUserTermination(char ASCIIValue)
// The default constructor wants an ASCII char, such as '.' as value (that is default).
// It will call the initialize function that will map the ASCII value to a virtual key code.
{
    long auxVersion = 0;
 
    // Initialize fields to known values
    fChar = ASCIIValue;
    fKeyCode = 0;
 
    // Test if A/UX is present or not, needed later for the event handling code
    OSErr anErr = Gestalt(gestaltAUXVersion, &auxVersion);
    if (anErr == gestaltUnknownErr || auxVersion == 0)
        fAUX = false;
    else
        fAUX = true;
 
    // Do any other dynamic initialization
    this->Initialize();
}
 
 
#pragma segment UserTermination
TUserTermination::~TUserTermination()
// Default constructor, nothing just now.
{
}
 
 
//  INITIALIZATION ROUTINES 
#pragma segment UserTermination
void TUserTermination::Initialize()
// Initialize will fetch the KCHR handle, and convert the ASCII character to
// a real virtual key code.
{
    Handle hKCHR = NULL;
    Ptr pKCHR;
    short KCHRId;
    Boolean notDone;
    unsigned long state;
    long ktResult;
 
    pKCHR = (Ptr)GetScriptManagerVariable(smKCHRCache);     // try to get the pointer directly
    if (!pKCHR)                                 // maybe pre-System7
    {
        KCHRId = (short)GetScriptVariable(short(GetScriptManagerVariable(smKeyScript)), smScriptKeys);
        hKCHR = GetResource('KCHR', KCHRId);    // get the KCHR resource
        pKCHR = *hKCHR;                         // get the pointer
    }
    notDone = true;
 
    if (pKCHR)
    {
        state = 0;
 
        while ((fKeyCode <= 0x7F) && notDone)
            // loop through all possible keycodes
            {
                ktResult = KeyTrans((pKCHR), fKeyCode, &state);// get the ASCII value
                if (((ktResult & ktAscii1Mask) == fChar) || ((ktResult & ktAscii2Mask) == fChar))// check result for desited real char
                    notDone = false;
                else
                    fKeyCode++;                 // keep looking
            }
    }
    // Clean up
    if (hKCHR)
        ReleaseResource(hKCHR);
 
    if (notDone)
        fKeyCode = -1;                          // set an insane value
 
    return;                                     // job done 
}
 
 
//  MAIN INTERFACE
 
#pragma segment UserTermination
Boolean TUserTermination::Abort()
//  Abort returns true if the user has pressed Command-Period.
//  It does this by walking the event queue.  Walking the event queue is not
//  recommended, but since we want a Command-Period event to take priority over
//  any other events in the queue, looking ahead in the queue is the only way.
//
//  Note that for A/UX, this technique does not work as A/UX does not support
//  the Macintosh event queue structure.  In that case, we will call CheckAUXEventQueue
//  to find the result.
{
    Boolean foundEvent = false;
    EvQElPtr eventQPtr;
    QHdrPtr eventQHdr;
 
 
    eventQHdr = GetEvQHdr();                // get the event queue
    eventQPtr = (EvQElPtr)eventQHdr->qHead; // get the first element
 
    while (eventQPtr &&!foundEvent)
    {
        foundEvent = (((eventQPtr->evtQMessage & keyCodeMask) >> 8) == fKeyCode && (eventQPtr->evtQModifiers & cmdKey));// the event we want + cmd key?
 
        if (!foundEvent)
            eventQPtr = (EvQElPtr)eventQPtr->qLink;// get the next element in the queue
    }
    return foundEvent;
}
 
 
//  PRIVATE INTERNAL FUNCTIONS
 
/*#pragma segment UserTermination
Boolean TUserTermination::CheckAUXEventQueue(char keyCode,
                                             short modifiers)
{
    struct
    {
        EventRecord mask;
        EventRecord value;
    } eventFilter;
 
    eventFilter.mask.what = everyEvent;
    eventFilter.value.what = keyDown;           // look for a keydown event
    eventFilter.mask.message = keyCodeMask;
    eventFilter.value.message = keyCode << 8;   // Set keyCode
    eventFilter.mask.modifiers = modifiers;
    eventFilter.value.modifiers = modifiers;    // Set modifiers
    eventFilter.mask.when = 0;
    eventFilter.mask.where.v = 0;               // Zero out other stuff
    eventFilter.mask.where.h = 0;
    return ((AUXDispatch(kAUXFindEvent, (char*) & eventFilter) > 0) && (eventFilter.value.what != nullEvent));// Have A/UX look for us
}*/
 
 
// _________________________________________________________________________________________________________ //
 
/*  Change History (most recent last):
  No        Init.   Date        Comment
  1         khs     9/26/92     New file
*/