utilmac.c #1

  • //
  • guest/
  • grant_glouser/
  • jam/
  • utilmac.c
  • View
  • Commits
  • Open Download .zip Download (6 KB)
/*
========================================================================
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);
}
# Change User Description Committed
#1 419 Grant Glouser Mac support - spinning cursor and cancel with command-period.