From: grobbins@Apple.COM (Grobbins)
Newsgroups: comp.sys.mac.programmer
Subject: Re: Option key madness
Date: 13 Oct 92 21:06:28 GMT
Organization: Really Weird Future Mac Department, Apple Computer, Inc.

In article <1992Oct12.161745.8323@netcom.com> leonardr@netcom.com (Leonard Rosenthol) writes:
>In article <1992Oct12.040750.20383@muddcs.claremont.edu> wprice@pomona.claremont.edu writes:
>>I am trying to read option keys from the Mac keyboard, and of course have  
>>noticed that various keys will not even send an event when initially typed  
>>such as Option-E and Option-U, and Option-'. How do I override this system so 
>>that Option can be used normally for those special characters?
>
>The wrong way is...
>to require the user to use THEIR KCHR resource, which requires the user to 
>do a bit of ResEditting of the System file, since KCHR's must live in the 
>System under System 7.

Not exactly.  Under System 6, using a custom application KCHR is easier
since it can reside in the application's own resource fork.  Just be sure
to set back to the standard system KCHR on suspends and when quitting.

While System 7 does require that the KCHR be installed in the System, this
can be done by having the user drag a keyboard file to the System suitcase.
(See Inside Mac VI, page 14-96.)  This is the recommended route, and is
discussed in the Q&A Stack; I'll paste the appropriate entry below.

>	The right way to do it (which MicroPhone II & Smartcom do) is to 
>first patch _KeyTrans to map the option modiifier to something else (in the
>cases above, the control modifieir).  However, since the process manager
>swaps patches on even minor context switches, you could STILL get the wrong
>characters.  So you have to do some on-the-fly munging of the KCHR (after
>copying the orignal!!) - BUT remember to restore the original KCHR on 
>suspend/resumes!!

Modifying the system KCHR on-the-fly sounds awfully unappealing, as
does searching for certain key combinations in a patch.  A cleaner
patch, one which must be done from an INIT because of the automatic
patch-table swapping that Leonard refers to, would be to set bit 7 of
the keycode parameter to KeyTrans, since dead keys are not processed on
keyups.

Grobbins               grobbins@apple.com

Usual disclaimers apply.

---
from the Q&A Stack:

I would like to use the Macintosh Option key as the Control key for
keyboards that lack a Control key, such as for Macintosh Plus keyboards. How
can I find the ASCII value that would have been returned if the Option key
weren't pressed, in a way that would be compatible with other keyboards?

There are a couple of clean ways to ignore the Option key. One is to
"reprocess" the keyboard event. The fourth byte of the event message is the
ASCII code, but the third byte is the virtual key code. The system calls the
trap KeyTrans to map the virtual key code to ASCII according to a 'KCHR'
resource. You can do the same, and since the high byte of the modifiers are
part of the input to KeyTrans, you can strip out the Option key, call
KeyTrans on the third byte of the event message, and get back the "true"
ASCII keypress. KeyTrans and 'KCHR' resources are documented in Chapter 10
of Inside Macintosh Volume V, Chapter 14 of Inside Macintosh Volume VI
(pages 14-23 and 14-96), and Macintosh Technical Note #160, "Key Mapping."
In Pascal, these steps would look something like:


    keycode := BAND(event.message, keyCodeMask);{ get virtual code }
    keycode := BSR(keycode, 8); { move to low byte }
    { now combine with modifiers }
    keycode := BOR(keycode, BAND($FF00, event.modifiers));
    keycode := BAND(keycode, $FFFF - optionKey); { strip option }
    newkey := KeyTrans(KCHRHandle^, keyCode, state);


The resource ID of the current KCHR is available as
GetScript(GetEnvirons(smKeyScript), smScriptKeys). Alternatively, a pointer
to the KCHR data is available under System 7 as GetEnvirons(smKCHRCache), as
discussed in Tech Note #263, "International Canceling."

This method may work for you, but there is a possible problem: dead keys.
Since dead keys are processed before your application gets the event, your
application will not see (for example) the first Option-e typed. However,
the dead keys are specified in the 'KCHR' resource, so you can create a KCHR
(ResEdit 2.1.1 includes a template) to omit dead keys (and, if you choose,
option characters) and include it with your application. Call SetScript to
get the system to use your 'KCHR' (see Tech Note #160, IM V-313, and IM VI
14-40).

Another problem is that System 7 ignores a 'KCHR' in the application's
resources, so an application's 'KCHR' has to be installed in the system. You
can install the 'KCHR' with an installer program, or provide a keyboard file
users can drag to the System file. (To create a keyboard file, use ResEdit
to put the 'KCHR' in the System file, and then drag it out with the System 7
Finder.)