home *** CD-ROM | disk | FTP | other *** search
- /*
- Copyright (c) 1988 Commodore-Amiga, Inc.
-
- Executables based on this information may be used in software
- for Commodore Amiga computers. All other rights reserved.
-
- This information is provided "as is"; no warranties are made.
- All use is at your own risk, and no liability or responsibility is assumed.
- */
-
- #include "exec/types.h"
- #include "exec/memory.h"
- #include "devices/keymap.h"
- #include "devices/console.h"
- #include "libraries/dosextens.h"
-
- #ifdef MANX
- #include "functions.h"
- #endif
-
- ULONG *AllocMem();
- struct Task *FindTask();
-
- struct KeyMapResource *OpenResource();
- struct KeyMapNode *FindName();
-
- struct KeyMap *
- FindKeyMap(name)
- char *name;
- {
- struct KeyMapResource *kmr;
- struct KeyMapNode *kmn;
-
- kmr = (struct KeyMapResource *) OpenResource("keymap.resource");
- if (kmr == NULL) return(NULL);
- kmn = (struct KeyMapNode *) FindName(&kmr->kr_List, name);
- return(&kmn->kn_KeyMap);
- }
-
- int QualifierOnesCount[] = {
- /* number of bits set in a nibble */
- 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
- };
- int QualifierExtraBytes[] = {
- /* number of extra bytes associated with non-special qualifier patterns */
- 0, 0, 0, 0, 0, 0, 0, 0, /* the last is the special VANILLA case */
- 0, 0, 0, 8, 0, 8, 8, 16
- };
-
- int DeadFactor; /* to determine size of lookup tables at end */
- int DoubleDeadFactor; /* (only used for double dead keys) */
-
-
- MaxDeadIndex(type, entry)
- UBYTE type;
- UBYTE *entry; /* if it needs to be looked at, it's a pointer */
- {
- int count;
- int i;
-
- if ((type & KCF_DEAD) && (!(type & KCF_NOP))) {
- /* dead or deadable */
- /* there are 2 bytes for each qualifier combination at *entry */
- count = 1<<(QualifierOnesCount[type & 0xf]+1);
- for (i = 0; i < count; i+=2) {
- if (entry[i] & DPF_DEAD) {
- /* see if this index is a maximum */
- if (DeadFactor < (entry[i+1] & DP_2DINDEXMASK))
- DeadFactor = entry[i+1] & DP_2DINDEXMASK;
- if ((entry[i+1] >> DP_2DFACSHIFT) &&
- /* this index participates in double dead keys */
- (DoubleDeadFactor < (entry[i+1] & DP_2DINDEXMASK)))
- /* this participant in double dead keys is a maximum */
- DoubleDeadFactor = entry[i+1] & DP_2DINDEXMASK;
- }
- }
- }
- }
-
-
- int
- SizeType(type, entry)
- UBYTE type;
- UBYTE *entry; /* if it needs to be looked at, it's a pointer */
- {
- int count, size, subtype;
- int i, j;
-
- if (type & KCF_NOP) {
- /* NOP */
- return(0);
- }
-
- if (type & KCF_DEAD) {
- /* dead or deadable */
- /* there are 2 bytes for each qualifier combination at *entry */
- count = 1<<(QualifierOnesCount[type & 0xf]+1);
- /* add the deadHead and data bytes for each of the deads */
- size = count;
- for (i = 0; i < count; i+=2) {
- /* find any more interesting references */
- subtype = entry[i];
- if (subtype & DPF_DEAD) {
- continue;
- }
- if (subtype & DPF_MOD) {
- /* one byte for every dead combination */
- size += DeadFactor;
- continue;
- }
- }
- return(size);
- }
-
- if (type & KCF_STRING) {
- /* string */
- /* there are 2 bytes for each qualifier combination at *entry */
- count = 1<<(QualifierOnesCount[type & 0xf]+1);
- /* add the length and offset bytes for each of the strings */
- size = count;
- for (i = 0; i < count; i+=2) {
- /* add this string's length */
- size += entry[i];
- }
- return(size);
- }
-
- /* number of extra bytes needed to index all the qualifiers set */
- return(QualifierExtraBytes[type & 0xf]);
- }
-
- /* SizeKeyMap does a KeyMap, not a KeyMapNode */
- int
- SizeKeyMap(km, newLo, newHi)
- struct KeyMap *km;
- UBYTE *newLo, *newHi;
- {
- UBYTE type;
- int size;
- int i;
-
- /*
- * fixed byte size associated with
- * Keymap structure itself
- * (8 pointers) 32
- * Lo entries for 64 codes
- * km_LoKeyMapTypes 64
- * km_LoKeyMap 256
- * km_LoCapsable 8
- * km_LoRepeatable 8
- * Hi entries for 56 codes
- * km_HiKeyMapTypes 56
- * km_HiKeyMap 224
- * km_HiCapsable 7
- * km_HiRepeatable 7
- * ---
- * total 662
- */
- size = 662;
-
- /* first need to find the number of dead keys */
- DeadFactor = DoubleDeadFactor = 0;
- for (i = 0; i < 64; i++) {
- MaxDeadIndex(km->km_LoKeyMapTypes[i], km->km_LoKeyMap[i]);
- }
- for (i = 0; i < 56; i++) {
- MaxDeadIndex(km->km_HiKeyMapTypes[i], km->km_HiKeyMap[i]);
- }
- if (DeadFactor) DeadFactor++;
- if (DoubleDeadFactor) DeadFactor *= DoubleDeadFactor;
-
- /* now accumulate all applicable keymap trails */
- for (i = 0; i < 64; i++) {
- if (!(newLo[i/8] & (1<<(i&7))))
- size += SizeType(km->km_LoKeyMapTypes[i], km->km_LoKeyMap[i]);
- }
- for (i = 0; i < 56; i++) {
- if (!(newHi[i/8] & (1<<(i&7))))
- size += SizeType(km->km_HiKeyMapTypes[i], km->km_HiKeyMap[i]);
- }
-
- return(size);
- }
-
- UBYTE *NextNewMapEntry;
-
- CopyEntry(type, oentry, nentry)
- UBYTE type;
- UBYTE *oentry;
- UBYTE **nentry;
- {
- UBYTE *suboentry, *subnentry;
- int count, length, subtype;
- int i, j, k;
-
- if (type & KCF_NOP) {
- /* NOP */
- return;
- }
-
- if (type & KCF_DEAD) {
- /* dead or deadable */
- /* there are 2 bytes for each qualifier combination at *entry */
- count = 1<<(QualifierOnesCount[type & 0xf]+1);
- *nentry = NextNewMapEntry;
- NextNewMapEntry += count;
- /* initialize the deadHead and data bytes for each of the deads */
- for (i = 0; i < count; i+=2) {
- subtype = oentry[i];
- (*nentry)[i] = subtype;
- (*nentry)[i+1] = oentry[i+1]; /* default */
-
- /* find any more interesting references */
- if (subtype & DPF_MOD) {
- (*nentry)[i+1] = NextNewMapEntry - *nentry;
- /* one byte for every dead combination */
- suboentry = &oentry[oentry[i+1]];
- for (j = 0; j < DeadFactor; j++) {
- *NextNewMapEntry++ = suboentry[j];
- }
- }
- }
- return;
- }
-
- if (type & KCF_STRING) {
- /* string */
- /* there are 2 bytes for each qualifier combination at *entry */
- count = 1<<(QualifierOnesCount[type & 0xf]+1);
- *nentry = NextNewMapEntry;
- NextNewMapEntry += count;
- /* initialize the length and offset bytes for each of the strings */
- for (i = 0; i < count; i+=2) {
- /* clone this string's length */
- length = oentry[i];
- (*nentry)[i] = length;
-
- /* clone this string's data */
- (*nentry)[i+1] = NextNewMapEntry - *nentry;
- for (j = 0; j < length; j++) {
- *NextNewMapEntry++ = oentry[oentry[i+1]+j];
- }
- }
- return;
- }
-
- /* check if all the qualified bytes fit in the entry longword */
- count = QualifierExtraBytes[type & 0xf];
- if (count > 0) {
- /* clone a new array for all the qualified bytes */
- *nentry = NextNewMapEntry;
- for (i = 0; i < count; i++) {
- *NextNewMapEntry++ = oentry[i];
- }
- }
- }
-
-
- struct KeyMap *
- NewKeyMap(okm, newLo, newHi)
- struct KeyMap *okm;
- UBYTE *newLo, *newHi;
- {
- ULONG *memChunk;
- struct KeyMap *nkm;
- int size;
- int i;
-
- size = SizeKeyMap(okm, newLo, newHi);
-
- /* NewKeyMap has a longword header describing the size */
- memChunk = (ULONG *) AllocMem(size+4, MEMF_PUBLIC);
- if (memChunk == NULL)
- return(NULL);
- *memChunk++ = size;
- nkm = (struct KeyMap *) memChunk;
-
- /* parcel out space for fixed size tables in allocated memory */
- nkm->km_LoKeyMapTypes = ((UBYTE *) nkm) + sizeof(struct KeyMap);
- nkm->km_LoKeyMap = (ULONG *) &nkm->km_LoKeyMapTypes[64];
- nkm->km_LoCapsable = (UBYTE *) &nkm->km_LoKeyMap[64];
- nkm->km_LoRepeatable = &nkm->km_LoCapsable[8];
- nkm->km_HiKeyMapTypes = &nkm->km_LoRepeatable[8];
- nkm->km_HiKeyMap = (ULONG *) &nkm->km_HiKeyMapTypes[56];
- nkm->km_HiCapsable = (UBYTE *) &nkm->km_HiKeyMap[56];
- nkm->km_HiRepeatable = &nkm->km_HiCapsable[7];
- NextNewMapEntry = &nkm->km_HiRepeatable[7];
-
- /* copy the fixed size keymap data to the new keymap copy */
- for (i = 0; i < 64; i++) {
- nkm->km_LoKeyMapTypes[i] = okm->km_LoKeyMapTypes[i];
- nkm->km_LoKeyMap[i] = okm->km_LoKeyMap[i];
- }
- for (i = 0; i < 8; i++) {
- nkm->km_LoCapsable[i] = okm->km_LoCapsable[i];
- nkm->km_LoRepeatable[i] = okm->km_LoRepeatable[i];
- }
- for (i = 0; i < 56; i++) {
- nkm->km_HiKeyMapTypes[i] = okm->km_HiKeyMapTypes[i];
- nkm->km_HiKeyMap[i] = okm->km_HiKeyMap[i];
- }
- for (i = 0; i < 7; i++) {
- nkm->km_HiCapsable[i] = okm->km_HiCapsable[i];
- nkm->km_HiRepeatable[i] = okm->km_HiRepeatable[i];
- }
-
- /* now follow all applicable keymap trails */
- for (i = 0; i < 64; i++) {
- if (!(newLo[i/8] & (1<<(i&7))))
- CopyEntry(okm->km_LoKeyMapTypes[i], okm->km_LoKeyMap[i],
- &nkm->km_LoKeyMap[i]);
- }
- for (i = 0; i < 56; i++) {
- if (!(newHi[i/8] & (1<<(i&7))))
- CopyEntry(okm->km_HiKeyMapTypes[i], okm->km_HiKeyMap[i],
- &nkm->km_HiKeyMap[i]);
- }
- return(nkm);
- }
-
- DisposeKeyMap(km)
- ULONG *km;
- {
- km--;
- FreeMem(km, (*km)+4);
- }
-
- struct MsgPort IORP = {
- {0, 0, NT_MSGPORT, 0, 0}, 0, SIGF_SINGLE, 0, { 0, 0, 0, 0, 0 }
- };
-
- struct IOStdReq IOR = {
- { {0, 0, NT_MESSAGE, 0, 0}, /* Message Succ, Pred, Type, Pri, Name */
- &IORP, 0 }, /* Message ReplyPort, Length */
- 0, 0, CMD_READ, 0, 0, /* IO Device, Unit, Command, Flags, Error */
- 0, 0, 0, 0 /* IO Actual, Length, Data, Offset */
- };
-
- /*
- * indicate replacement of function keys (0x50-0x59) will occur
- */
- UBYTE NoNew[] = {
- 0, 0, 0, 0, 0, 0, 0, 0
- };
- UBYTE NewHi[] = {
- 0, 0, 0xff, 0x03, 0, 0, 0, 0
- };
- UBYTE NewFncTypes[] = {
- KC_NOQUAL, KCF_SHIFT, KCF_SHIFT+KCF_ALT, KC_VANILLA,
- KCF_SHIFT+KCF_ALT+KCF_CONTROL+KCF_DOWNUP,
- KCF_STRING, KCF_SHIFT+KCF_STRING,
- KCF_SHIFT+KCF_ALT+KCF_CONTROL+KCF_DOWNUP+KCF_STRING,
- KCF_SHIFT+KCF_ALT+KCF_DEAD, KCF_STRING
- };
- UBYTE NewFnc1_4[] = {
- 0, 0, 0, '1',
- 0, 0, 0xb2, '2',
- 'F', 'f', 0xb3, '3',
- 'm', '!', 'i', 'h'
- };
- UWORD NewFncOff5_10[] = {
- /* offsets into the NewFncData area */
- 0, 16, 20, 108, 204, 224
- };
- BYTE NewFncData[] = {
- /* 0 :f5 */
- 'a','b','c','d','e','f','g','h','A','B','C','D','E','F','G','H',
- /* 16:f6 */
- 2,2,'f','6',
- /* 20:f7 */
- 2,4,2,6,'f','7','F','7',
- /*108:f8 */
- /* more than 128 bytes of data, so some data must be a negative */
- /* offset from the length/offset pairs */
- 'D','o','w','n',
- 'S','h','i','f','t','D','o','w','n',
- 'A','l','t','D','o','w','n',
- 'S','h','i','f','t','A','l','t','D','o','w','n',
- 'C','t','r','l','D','o','w','n',
- 'C','t','r','l','S','h','i','f','t','D','o','w','n',
- 'C','t','r','l','A','l','t','D','o','w','n',
- 'C','t','r','l','S','h','i','f','t','A','l','t','D','o','w','n',
- /* length/offset pairs for strings for f8 */
- 4,-80, 9,-76, 7,-67, 12,-60, 8,-48, 13,-40, 11,-27, 16,-16,
- 2,32, 7,34, 5,41, 10,46, 6,56, 11,62, 9,73, 14,82,
- /* more data for strings for f8 */
- 'U','p',
- 'S','h','i','f','t','U','p',
- 'A','l','t','U','p',
- 'S','h','i','f','t','A','l','t','U','p',
- 'C','t','r','l','U','p',
- 'C','t','r','l','S','h','i','f','t','U','p',
- 'C','t','r','l','A','l','t','U','p',
- 'C','t','r','l','S','h','i','f','t','A','l','t','U','p',
- /*204:f9 */
- DPF_MOD,8, DPF_MOD,14, DPF_DEAD, 2, 0, '@',
- 'a',0xe1,0xe0,0xe2,0xe3,0xe4,
- 'A',0xc1,0xc0,0xc2,0xc3,0xc4,
- /*224:f10*/
- 4, 2, 0x18, 0x0c, 0x08, 0x0d
- };
- UBYTE NewFncCapsable[] = {
- 0x04, 0x00
- };
- UBYTE NewFncRepeatable[] = {
- 0x00, 0x00
- };
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- struct KeyMap *ukm; /* usa keymap */
- struct KeyMap ckm; /* console keymap */
- struct KeyMap *nkm; /* new keymap */
- int uSize, cSize;
- struct MsgPort *con;
- struct StandardPacket *packet;
- struct InfoData *id;
- BYTE *f;
- int i;
-
- ukm = FindKeyMap("usa");
- if (ukm == NULL) {
- printf("usa map not found\n");
- exit(20);
- }
- uSize = SizeKeyMap(ukm, NoNew, NoNew);
- printf("usa map size %ld (0x%lx)\n", uSize, uSize);
-
- NewList(&IORP.mp_MsgList);
- IORP.mp_SigTask = (struct Task *) FindTask((char *) NULL);
- con = (struct MsgPort *)
- ((struct Process *) IORP.mp_SigTask) -> pr_ConsoleTask;
- if (con != NULL) {
- packet = (struct StandardPacket *)
- AllocMem(sizeof(*packet), MEMF_CLEAR);
- if (packet != NULL) {
- id = (struct InfoData *) AllocMem(sizeof(*id), MEMF_CLEAR);
- if (id != NULL) {
- /* this is the console handlers packet port */
- packet->sp_Msg.mn_Node.ln_Name = (char *) &(packet->sp_Pkt);
- packet->sp_Pkt.dp_Link = &(packet->sp_Msg);
- packet->sp_Pkt.dp_Port = &IORP;
- packet->sp_Pkt.dp_Type = ACTION_DISK_INFO;
- packet->sp_Pkt.dp_Arg1 = ((ULONG) id) >> 2;
- PutMsg(con, packet);
- WaitPort(&IORP);
- if (id->id_InUse) {
- /* clone iorequest and get keymap */
- IOR.io_Unit =
- ((struct IOStdReq *) id->id_InUse)->io_Unit;
- IOR.io_Device =
- ((struct IOStdReq *) id->id_InUse)->io_Device;
- IOR.io_Command = CD_ASKKEYMAP;
- IOR.io_Data = (APTR) &ckm;
- IOR.io_Length = sizeof(struct KeyMap);
- DoIO(&IOR);
-
- cSize = SizeKeyMap(&ckm, NoNew, NoNew);
- printf("current map size %ld (0x%lx)\n", cSize, cSize);
-
- /* default: go back to the usa keymap */
- nkm = ukm;
- /*
- * if cSize == uSize, assume this is a usa keymap
- * else assume this has already been modified
- * (crude, but this is demo code)
- */
- if (cSize == uSize) {
- f = (BYTE *)
- AllocMem(sizeof(NewFncData), MEMF_PUBLIC);
- if (f) {
- /* make a new keymap */
- nkm = NewKeyMap(ukm, NoNew, NewHi);
-
- /* replace the function key descriptions */
- for (i = 0; i < 10; i++)
- nkm->km_HiKeyMapTypes[i+0x10] =
- NewFncTypes[i];
- for (i = 0; i < 4; i++)
- nkm->km_HiKeyMap[i+0x10] =
- ((ULONG *) NewFnc1_4)[i];
- for (i = 0; i < 6; i++)
- nkm->km_HiKeyMap[i+0x14] =
- (ULONG) (f + NewFncOff5_10[i]);
- for (i = 0; i < 2; i++) {
- nkm->km_HiCapsable[i+2] = ((~NewHi[i+2]) &
- nkm->km_HiCapsable[i+2]) |
- NewFncCapsable[i];
- nkm->km_HiRepeatable[i+2] = ((~NewHi[i+2]) &
- nkm->km_HiRepeatable[i+2]) |
- NewFncRepeatable[i];
- }
- for (i = 0; i < sizeof(NewFncData); i++)
- f[i] = NewFncData[i];
- }
- }
- if (nkm == ukm)
- printf("installing usa keymap\n");
- else
- printf("installing custom KeyMap\n");
- /* set the keymap */
- IOR.io_Command = CD_SETKEYMAP;
- IOR.io_Data = (APTR) nkm;
- IOR.io_Length = sizeof(struct KeyMap);
- DoIO(&IOR);
-
- if (cSize != uSize) {
- /* release the old keymap: oh, this IS demo code! */
- DisposeKeyMap(ckm.km_LoKeyMapTypes -
- sizeof(struct KeyMap));
- }
- }
- FreeMem(id, sizeof(*id));
- }
- FreeMem(packet, sizeof(*packet));
- }
- }
- }
-