Path: utzoo!attcan!uunet!seismo!sundc!pitstop!sun!decwrl!thundr.dec.com!minow
From: minow@thundr.dec.com (Fortran for Precedent)
Newsgroups: comp.sys.mac.programmer
Subject: Problem setting KCHR resource
Message-ID: <8810141852.AA00712@decwrl.dec.com>
Date: 14 Oct 88 21:17:00 GMT
Organization: Digital Equipment Corporation
Lines: 114
(This didn't seem to get out the first time: apologies if you see it twice)
I'm writing a VT200 terminal emulator that implements the Dec LK201 keyboard.
This means that my "option" character set is completely different from Apple's
(I use a private font), and I have to handle the Option overstrikes
differently. Because of a bug in the operating system, this isn't possible
to do cleanly (e passes through deadkey processing before my event
handler sees it). I thought I could fix this by creating my own KCHR
resource (following Tech Note 160). My private resource is identical to
the system resource except that all handling points to the "standard"
eyboard.
The code seems to run correctly, except for three problems:
-- KeyTrans doesn't put the SICN resource in the menu bar.
-- GetScript(... smScriptIcon) returns zero, not my resource id (however
GetScript(... smScriptKeys) returns the correct value.
-- The keyboard action doesn't change.
I can live with the first two, but the last problem is driving me batty.
Any suggestions as to what I'm doing wrong would be greatly appreciated.
Martin Minow
minow%thundr.dec@decwrl.dec.com
/*
* This hack is called at program startup. It finds the current keyboard
* mapping resource (KCHR) and creates a new KCHR that does not have any
* deadkeys. This allows our LK201 compose routine to work without
* interference from the system keyboard translator. I suppose creating a
* proper KCHR resource (with our mapping) would be somewhat better, but it's
* a pain. The associated SICN resource is in the resource file.
*/
void
setup_KCHR_resource()
{
register int i;
int KCHR_resource_id;
Handle kchr, new, sicn;
union {
unsigned char *c;
short int *i;
} table;
int n_tables;
long size;
OSErr status;
KCHR_resource_id = GetScript(smScriptKeys, GetEnvirons(smKeyScript));
kchr = GetResource('KCHR', KCHR_resource_id);
if (kchr == NIL) {
error_message("No KCHR?", ResError());
return;
}
HLock(kchr);
table.c = (unsigned char *) *kchr;
n_tables = table.i[1 + (256 / sizeof (short))];
/*
* n_tables has the number of keyboard mapping tables (8 for US).
* Build a resource just big enough.
*/
size =
sizeof (short) /* Version number */
+ 256 /* Table indexes */
+ sizeof (short) /* number of tables */
+ (n_tables * 128) /* the actual tables */
+ sizeof (short); /* Number of deadkeys */
new = NewHandle((long) size); /* Get the resource */
if (new == NIL) {
error_message("No room for KCHR?", (int) size);
HUnlock(kchr);
return;
}
HLock(new);
BlockMove(*kchr, *new, size);
HUnlock(kchr); /* Done with kchr */
table.c = (unsigned char *) *new; /* table -> new KCHR */
table.i[1 + 128 + 1 + (n_tables * 64)] = 0; /* No deadkeys */
table.c += sizeof (short); /* -> table @ indexes */
/*
* Walk through the table_index entries. When we find one
* with optionKey set, change it to point to the table without
* option key (but with the same arrangements of shift/caps/control).
* Not that this will leave some dangling (unused) tables. Can't
* win 'em all.
*/
#define OPT (optionKey >> 8)
for (i = 0; i < 256; i++) {
if ((i & OPT) != 0)
table.c[i] = table.c[i & ~OPT];
}
HUnlock(new);
AddResource(new, 'KCHR', KCHR_resource_id, "\pLK201 KCHR");
if (ResError() != noErr) {
error_message("Can't add KCHR resource", ResError());
return;
}
SetResAttrs(new, 0); /* Clear "changed" bit */
if (GetResource('SICN', KCHR_id) == NIL) {
error_message("No SICN?", ResError());
return;
}
status = SetScript(smRoman, smScriptKeys, KCHR_id);
if (status != noErr)
status = SetScript(smRoman, smScriptIcon, KCHR_id);
if (status != noErr)
error_message("Can't SetScript", status);
KeyScript(smRoman);
Debugger();
status = GetScript(GetEnvirons(smKeyScript), smScriptKeys);
/* This returns the expected value (KCHR_id) */
status = GetScript(GetEnvirons(smKeyScript), smScriptIcon);
/* This returns zero and "my" keyboard isn't enabled and the */
/* icon doesn't show */
}