/*
========================================================================
Copyright (c) 1999-2000 Palm, Inc. or its subsidiaries. All rights reserved.
========================================================================
Portions derived from Apple Tool Chest sample code. Other portions derived from GUSI 2:
Copyright (C) 1992-1999 Matthias Neeracher
*/
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <Resources.h>
#include <Script.h>
#include <LowMem.h>
#include <CursorCtl.h>
#include "utilmac.h"
void SetFileTypeCreator(const char * cname, unsigned long type, unsigned long creator)
{
Str255 pname;
FSSpec spec;
FInfo fi;
OSErr err;
strncpy((char*)&pname[1], cname, 255);
pname[0] = (unsigned char)strlen(cname);
err = FSMakeFSSpec(0, 0, pname, &spec);
if ((err != noErr) && (err != fnfErr))
return;
if (FSpGetFInfo(&spec, &fi) != noErr)
return;
fi.fdType = type;
fi.fdCreator = creator;
FSpSetFInfo(&spec, &fi);
}
/* Is any portion (folder or file name) too long for the Mac HFS(+) file-system? */
int MacFilenameTooLong(const char * name)
{
const char * pos;
const int MAX = 31;
if (!name)
return 0;
if (strlen(name) < MAX)
return 0;
pos=name;
for(;;) {
const char * colon = strchr(pos, ':');
if (colon) {
if ((colon-pos) > MAX)
return 1;
pos = colon + 1;
} else {
if (strlen(pos) > MAX)
return 1;
break;
}
}
return 0;
}
/* The following logic is borrowed from the Apple Tool Chest code snippets and GUSI 2
(which also had adapted it from the snippet, and added the constants and PSN logic).
*/
/******************************************************************************\
* Public: CmdPeriodEvent
*
* This routine uses the technique documented in Macintosh Technical Note #263
* to determine whether the event passed in the anEvent parameter contains a
* command-period event or not, regardless of the current keyboard layout.
*
* The problem that this routine solves is that some keyboards (mainly some
* European keyboards) require the shift key to be pressed to generate the
* period, but the command key turns off the shift key, making it impossible to
* see the period. To fix this, this routine calls the KeyTranslate routine which
* maps a virtual keycode and modifier keys to the ASCII code of the typed
* character. The modifier keys passed to KeyTranslate are the same as in the
* event record, but the command key modifier bit is stripped out. This makes
* KeyTranslate think the command key wasnt held down, and so the influence of other
* modifier keys is unaffected.
\******************************************************************************/
const long kMaskModifiers = 0xFE00; // we need the modifiers without the
// command key for KeyTrans
const long kMaskVirtualKey = 0x0000FF00; // get virtual key from event message
// for KeyTrans
const long kUpKeyMask = 0x0080;
const long kShiftWord = 8; // we shift the virtual key to mask it
// into the keyCode for KeyTrans
const long kMaskASCII1 = 0x00FF0000; // get the key out of the ASCII1 byte
const long kMaskASCII2 = 0x000000FF; // get the key out of the ASCII2 byte
static
Boolean CmdPeriodEvent(
EventRecord *anEvent) /* Event being tested */
{
long lowChar; /* Low character of keyInfo */
long highChar; /* High character of keyInfo */
Handle hKCHR; /* Handle to the currently-used KCHR */
long keyInfo; /* Key information returned from KeyTranslate */
long keyScript; /* Script of the current keyboard */
unsigned long state; /* State used for KeyTranslate */
short virtualKey; /* Virtual keycode of the character-generating key */
short keyCode; /* Keycode of the character-generating key */
Boolean gotCmdPeriod; /* True if detected command-. */
gotCmdPeriod = false;
if (anEvent->what == keyDown || anEvent->what == autoKey)
{
if (anEvent->modifiers & cmdKey)
{
/* Get the virtual keycode of the code-generating key */
virtualKey = (anEvent->message & keyCodeMask) >> 8;
/* Get a copy of the current KCHR */
keyScript = GetScriptVariable( GetScriptManagerVariable( smKeyScript ), smScriptKeys);
hKCHR = GetResource('KCHR', keyScript);
if (hKCHR != nil)
{
/* AND out the command key and OR in the virtualKey */
keyCode = (anEvent->modifiers & kMaskModifiers) | virtualKey;
/* Get key information */
state = 0;
keyInfo = KeyTranslate( *hKCHR, keyCode, &state );
}
else
keyInfo = anEvent->message;
/* Check both low and high bytes of keyInfo for period */
lowChar = keyInfo & kMaskASCII2;
highChar = (keyInfo & kMaskASCII1) >> 16;
if (lowChar == '.' || highChar == '.')
gotCmdPeriod = true;
}
}
return gotCmdPeriod;
}
void CheckInterrupt()
{
EvQElPtr eventQ;
ProcessSerialNumber front;
Boolean same;
static ProcessSerialNumber thisProcess;
static int gotThisProcess = 0;
if (!gotThisProcess) {
gotThisProcess = 1;
GetCurrentProcess(&thisProcess);
}
if (GetFrontProcess(&front) && !SameProcess(&front, &thisProcess, &same) && same)
for (eventQ = (EvQElPtr) LMGetEventQueue()->qHead; eventQ; ) {
EventRecord * pEvent = (EventRecord *)(&eventQ->evtQWhat);
if (CmdPeriodEvent(pEvent)) {
FlushEvents(-1, 0);
raise(SIGINT);
break;
} else
eventQ = (EvQElPtr)eventQ->qLink;
}
}
static void onInt(int sigNo)
{
fprintf(stderr, "\nUser break, cancelled...\n");
exit(255);
}
void InitMPWTool(void)
{
InitCursorCtl(NULL);
signal(SIGINT, onInt);
}
void ShowProgress(int count)
{
CheckInterrupt();
if (count)
RotateCursor(count);
}