home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Elysian Archive
/
AmigaElysianArchive.iso
/
wp_dtp
/
xdme1821.lha
/
XDME
/
keycodes.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-25
|
21KB
|
954 lines
/******************************************************************************
MODUL
keycodes.c
DESCRIPTION
Lowlevel module for evaluation of keycodes and qualifiers
NOTES
highly amiga - specific
BUGS
no use of dead-keys
TODO
deadkey - checking
qual2iqual
EXAMPLES
SEE ALSO
INDEX
HISTORY
14-Dez-92 b_null created
14-Jan-93 b_null added UP
15-Jan-92 b_null added DeadKeyConvert, removed exit_kb - it caused a GURU
******************************************************************************/
/**************************************
Includes
**************************************/
#include "defs.h"
#include <devices/keymap.h>
#include <devices/console.h>
extern UBYTE CtlC;
/**************************************
Globale Variable
**************************************/
Prototype int get_codequal (const UBYTE * str, UBYTE * pcode, USHORT * pqual);
Prototype char * cqtoa (int code, int qual);
Prototype USHORT iqual2qual (unsigned long qual, int blen, char * buf, int code);
Prototype long qual2iqual (USHORT qual);
Prototype int a2iqual (char * str, long * piqual);
Prototype char * iqual2a (long iqual);
Prototype char CtoA (char c);
Prototype void keyboard_init (void);
Prototype void init_kb (void);
Prototype void exit_kb (void);
Prototype struct Library * ConsoleDevice;
/**************************************
Interne Defines & Strukturen
**************************************/
typedef struct IOStdReq CIO;
/* format of entries in lname[] */
#define LN(a,b,c,d) ((a<<24)|(b<<16)|(c<<8)|d)
/* important numbers in lname[] */
#define F1_START 0
#define SP_START 10
#define CS_START 20
#define N0_START 24
#define NS_START N0_START+10
#define MB_START 41
/* internal representation for qualifiers */
#define QUAL_SHIFT 0x0001
#define QUAL_CTRL 0x0002
#define QUAL_AMIGA 0x0004
#define QUAL_ALT 0x0008
#define QUAL_LMB 0x0010
#define QUAL_MMB 0x0020
#define QUAL_RMB 0x0040
#define QUAL_UP 0x0080 /* currently this MUST be 0x80 - that value is used in im.Code */
#define QUAL_XTX 0x0100 /* Extended Qualifiers for multi-key strokes */
#define QUAL_XTY 0x0200
#define QUAL_XTZ 0x0400
/* additional pseudo-intuition qualifiers - referring to the Quals above */
#define EXTQUALIFIER_X 0x00100000
#define EXTQUALIFIER_Y 0x00200000
#define EXTQUALIFIER_Z 0x00400000
#define EXTQUALIFIER_UP 0x00800000 /* this one is not used yet */
/* some hardcoded keys on Amiga Keyboard */
#define CSPC 0x40 /* Spacebar */
#define CB_S 0x41 /* BackSpace */
#define CENT 0x43 /* Enter */
#define CRET 0x44 /* Return */
/**************************************
Interne Variable
**************************************/
static UBYTE ctoa[128]; /* code to ascii */
static UBYTE cstoa[128]; /* code shifted to ascii */
static long lname[] = {
/* FuncKeys */
LN('f','1', 0 , 0 ), LN('f','2', 0 , 0 ), LN('f','3', 0 , 0 ),
LN('f','4', 0 , 0 ), LN('f','5', 0 , 0 ), LN('f','6', 0 , 0 ),
LN('f','7', 0 , 0 ), LN('f','8', 0 , 0 ), LN('f','9', 0 , 0 ),
LN('f','1','0', 0 ),
/* Specials */
LN('h','e','l', 0 ), LN('e','s','c', 0 ), LN('d','e','l', 0 ),
LN('b','a','c', 0 ), LN('b','s', 0 , 0 ), LN('t','a','b', 0 ),
LN('r','e','t',CRET), LN('e','n','t',CENT), LN('s','p','c',CSPC),
LN('s','p','a',CSPC),
/* Cursor */
LN('u','p', 0 , 0 ), LN('d','o','w', 0 ), LN('r','i','g', 0 ),
LN('l','e','f', 0 ),
/* Numeric digits */
LN('n','k','0', 0 ), LN('n','k','1', 0 ), LN('n','k','2', 0 ),
LN('n','k','3', 0 ), LN('n','k','4', 0 ), LN('n','k','5', 0 ),
LN('n','k','6', 0 ), LN('n','k','7', 0 ), LN('n','k','8', 0 ),
LN('n','k','9', 0 ),
/* Numeric Specials */
LN('n','k', 0 , 0 ), LN('n','k', 0 , 0 ), LN('n','k','/', 0 ),
LN('n','k','*', 0 ), LN('n','k','+', 0 ), LN('n','k','-', 0 ),
LN('n','k','.', 0 ),
/* Mouse Buttons */
LN('l','m','b',0x68), LN('m','m','b',0x6A), LN('r','m','b',0x69),
LN('m','m','o',0x6B)
};
struct Library * ConsoleDevice;
static struct Library * KC_ConsoleDevice = NULL; /* obsolete */
static int KC_Used = 0; /* obsolete */
/**************************************
Interne Prototypes
**************************************/
/*****************************************************************************
NAME
keyboard_init
PARAMETER
void
RESULT
-/-
RETURN
void
DESCRIPTION
initializes the variables used in the current Module
NOTES
That functon MUST be called before any other call to any
other functions of the key-modules
BUGS
if a dead- and a deadable-key are next to each other,
tables may be corrupt
EXAMPLES
SEE ALSO
INTERNALS
HISTORY
14-Dec-92 b_null included & modified
******************************************************************************/
void keyboard_init (void)
{
static struct InputEvent ievent = {
NULL,
IECLASS_RAWKEY,
0, 0, 0, NULL,
};
UBYTE buf[32];
short i,
len;
/* printf ("keyboard_init\n"); */
for (i = 0; i < 128; ++i) {
ievent.ie_Code = i;
ievent.ie_Qualifier = 0;
ievent.ie_position.ie_addr = NULL;
len = RawKeyConvert (&ievent, buf, 32, NULL);
switch(len) {
case 1: /* ESC/DEL/BS/TAB/NKx */
if ((buf[0] & 0x7F) >= 32 && (buf[0] & 0x7F) < 127)
ctoa[i] = buf[0];
switch(buf[0]) {
case 0x1B: lname[SP_START+1] |= i; break;
case 0x7F: lname[SP_START+2] |= i; break;
case 0x08: lname[SP_START+3] |= i;
lname[SP_START+4] |= i; break;
case 0x09: lname[SP_START+5] |= i; break;
case '@': /* for setmap cdn */
case '[': /* for setmap d,f,i,n */
case '(': if (i > 0x3A) lname[NS_START+0] |= LN(0,0,*buf,i); break; /* for setmap usa/gb */
case '°': /* for setmap cdn */
case ']': /* for setmap d,i,f,n */
case ')': if (i > 0x3A) lname[NS_START+1] |= LN(0,0,*buf,i); break; /* for setmap usa/gb */
case '/': if (i > 0x3A) lname[NS_START+2] |= i; break;
case '*': if (i > 0x3A) lname[NS_START+3] |= i; break;
case '+': if (i > 0x3A) lname[NS_START+4] |= i; break;
case '-': if (i > 0x3A) lname[NS_START+5] |= i; break;
case '.': if (i > 0x3A) lname[NS_START+6] |= i; break;
default:
if (i >= 0x0F && isdigit (buf[0]))
lname[N0_START+buf[0]-'0'] |= i;
} /* switch */
break;
case 2: /* cursor */
if (buf[0] == 0x9B)
{
switch(buf[1]) {
case 0x41: lname[CS_START+0] |= i; break;
case 0x42: lname[CS_START+1] |= i; break;
case 0x43: lname[CS_START+2] |= i; break;
case 0x44: lname[CS_START+3] |= i; break;
}
}
break;
case 3: /* function/help */
if (buf[0] == 0x9B && buf[2] == 0x7E)
{
if (buf[1] == 0x3F)
lname[SP_START+0] |= i;
if (buf[1] >= 0x30 && buf[1] <= 0x39)
lname[buf[1]-0x30+F1_START] |= i;
}
break;
} /* switch */
} /* for */
for (i = 0; i < 128; ++i)
{
ievent.ie_Code = i;
ievent.ie_Qualifier = IEQUALIFIER_LSHIFT;
ievent.ie_position.ie_addr = NULL;
len = RawKeyConvert (&ievent,buf,32,NULL);
if (len == 1)
cstoa[i] = buf[0];
} /* for */
{
UBYTE code;
USHORT qual;
get_codequal ("c", &code, &qual);
CtlC = code;
} /* block */
} /* keyboard_init */
/*****************************************************************************
NAME
cqtoa
PARAMETER
VAL (int, code)
VAL (int, qual)
RESULT
a ptr to the string that is the readable
form of that key-stroke (static)
RETURN
char *
DESCRIPTION
NOTES
we return a ptr to a static array of char
for only use of Qualifiers simply use code == -1
BUGS
(none known)
EXAMPLES
SEE ALSO
INTERNALS
HISTORY
14-Dez-92 b_null created
14-Jan-93 b_null added UP
******************************************************************************/
char * cqtoa (int code, int qual)
{
static char buf[32];
char * ptr = buf;
int i;
if (qual & QUAL_SHIFT)
*ptr++ = 's';
if (qual & QUAL_CTRL)
*ptr++ = 'c';
if (qual & QUAL_ALT)
*ptr++ = 'a';
if (qual & QUAL_AMIGA)
*ptr++ = 'A';
if (qual & QUAL_LMB)
*ptr++ = 'L';
if (qual & QUAL_MMB)
*ptr++ = 'M';
if (qual & QUAL_RMB)
*ptr++ = 'R';
if (qual & QUAL_XTX)
*ptr++ = 'x';
if (qual & QUAL_XTY)
*ptr++ = 'y';
if (qual & QUAL_XTZ)
*ptr++ = 'z';
if (qual & QUAL_UP)
*ptr++ = 'u';
/*
** --- That little fragment was added
** to be able to get the extended qualifiers with already existing functions
** U might uncomment it, if U wanna get information about
** which quals have been set with QUALIFIER
*/
if (code == (-1)) {
/* printf("U used a wrong undef\n"); */
*ptr++ = 0;
return(buf);
} /* if */
// if (qual) /* commented out for better readable keyfiles */
*ptr++ = '-';
for (i = 0; i < sizeof(lname)/sizeof(lname[0]); ++i) {
if ((lname[i]&0xFF) == code) {
*ptr++ = (lname[i]>>24);
*ptr++ = (lname[i]>>16);
*ptr++ = (lname[i]>>8);
break;
}
}
if (i == sizeof(lname)/sizeof(lname[0])) {
*ptr = ctoa[code];
if (*ptr) {
ptr ++;
/* PATCH_NULL [14 Feb 1993] : direct access to rawcodes ... */
} else {
sprintf (ptr, "0x%02x",code);
ptr += 4;
} /* if */
/* PATCH_NULL [14 Feb 1993] : ... direct access to rawcodes */
} /* if no spcname */
*ptr++ = 0;
return(buf);
} /* cqtoa */
/*****************************************************************************
NAME
get_codequal
PARAMETER
VAL (char *, string)
VAR (UBYTE, pcode)
VAR (USHORT, pqual)
RESULT
success: 1 == ok; 0 == error (unknown string)
RETURN
int
DESCRIPTION
we try to extract Qualifier- and Keycode -information
from an ascii-String and put the found values into
pcode and pqual
NOTES
for only use of Qualifiers simply use code == -1
BUGS
(none known)
EXAMPLES
SEE ALSO
INTERNALS
HISTORY
14-Dec-92 b_null included & modified
14-Jan-93 b_null added UP
******************************************************************************/
int get_codequal (const UBYTE * str, UBYTE * pcode, USHORT * pqual)
{
const char * base = str;
USHORT qual;
short i;
qual = 0;
if (strlen(str) > 1) {
for (; *str && *str != '-'; ++str) {
if (*str == 's')
qual |= QUAL_SHIFT;
if (*str == 'c')
qual |= QUAL_CTRL;
if (*str == 'a')
qual |= QUAL_ALT;
if (*str == 'A')
qual |= QUAL_AMIGA;
if (*str == 'L')
qual |= QUAL_LMB;
if (*str == 'M')
qual |= QUAL_MMB;
if (*str == 'R')
qual |= QUAL_RMB;
if (*str == 'x')
qual |= QUAL_XTX;
if (*str == 'y')
qual |= QUAL_XTY;
if (*str == 'z')
qual |= QUAL_XTZ;
if (*str == 'u')
qual |= QUAL_UP;
if (!qual)
goto notqual;
}
if (*str == 0) {
qual = 0;
str = base;
} else {
++str;
}
}
notqual:
if (strlen(str) != 1) { /* long name */
short shift = 24;
long mult = 0;
UBYTE c;
UBYTE * ptr = str; /* PATCH_NULL [14 Feb 1993] : added */
*pqual = qual;
while ((c = *str) && shift >= 8) {
c = tolower (c);
mult |= c << shift;
shift -= 8;
++str;
}
for (i = 0; lname[i]; ++i) {
if (mult == (lname[i] & 0xFFFFFF00)) {
*pcode = lname[i] & 0xFF;
return (1);
}
}
/* PATCH_NULL [14 Feb 1993] : direct access to raw-codes ... */
/* NOTE : we cannot save that value yet!!! */
/* printf ("testing %s with hex\n", str); */
if ((*ptr == '0') && ((ptr[1]|0x20) == 'x')) {
i = (strtol (ptr, &str, 0x10) & 0xff);
if (ptr != (UBYTE *)str) {
*pcode = i;
return (1);
} /* if scanned */
} /* if */
/* PATCH_NULL [14 Feb 1993] : ... direct access to raw-codes */
} else { /* single character keycap */
for (i = 0; i < sizeof(ctoa); ++i) {
if (*str == ctoa[i]) {
*pcode = i;
*pqual = qual;
return (1);
}
}
for (i = 0; i < sizeof(cstoa); ++i) {
if (*str == cstoa[i]) {
*pcode = i;
*pqual = qual|QUAL_SHIFT;
return (1);
}
}
}
return (0);
} /* get_codequal */
/*****************************************************************************
NAME
iqual2qual
PARAMETER
VAL (ULONG, qual)
VAL (int, blen)
VAL (char *, buf)
VAL (int, code)
RESULT
the [X]DME-internal qualifier referred by the intuition qualifier qual;
RETURN
USHORT
DESCRIPTION
transform the different intuition - Qualifiers to [X]DME-Qualifiers
(if we have caps-lock and buffer contains
one lower char, it is used like shift)
NOTES
BUGS
(none known)
EXAMPLES
SEE ALSO
INTERNALS
HISTORY
14-Dec-92 b_null included & modified
14-Jan-93 b_null added UP
******************************************************************************/
USHORT iqual2qual (unsigned long qual, int blen, char * buf, int code)
{
USHORT q2 = 0;
if (qual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
q2 |= QUAL_SHIFT;
if (qual & (IEQUALIFIER_CONTROL))
q2 |= QUAL_CTRL;
if (qual & (IEQUALIFIER_LCOMMAND|IEQUALIFIER_RCOMMAND))
q2 |= QUAL_AMIGA;
if (qual & (IEQUALIFIER_LALT|IEQUALIFIER_RALT))
q2 |= QUAL_ALT;
if ((qual & IEQUALIFIER_CAPSLOCK) && blen == 1 && islower (buf[1]))
q2 |= QUAL_SHIFT;
if (qual & IEQUALIFIER_LEFTBUTTON)
q2 |= QUAL_LMB;
if (qual & IEQUALIFIER_MIDBUTTON)
q2 |= QUAL_MMB;
if (qual & (IEQUALIFIER_RBUTTON))
q2 |= QUAL_RMB;
if (qual & (EXTQUALIFIER_X))
q2 |= QUAL_XTX;
if (qual & (EXTQUALIFIER_Y))
q2 |= QUAL_XTY;
if (qual & (EXTQUALIFIER_Z))
q2 |= QUAL_XTZ;
if (qual & (EXTQUALIFIER_UP))
q2 |= QUAL_XTZ;
q2 |= (QUAL_UP & code);
return(q2);
} /* iqual2qual */
/*****************************************************************************
NAME
qual2iqual
PARAMETER
VAL (USHORT, qual)
RESULT
Intuition Qualifiers, which represent the [X]DME - qualifiers
RETURN
long
DESCRIPTION
simple transformation of internal representation for
Qualifiers to a possible Amiga-representation
NOTES
very slow
!ATTN! there is currently no possibility to
transform the UP-Qualifier
BUGS
(none known)
EXAMPLES
SEE ALSO
iqual2qual
INTERNALS
HISTORY
14-Dez-92 b_null created
14-Jan-93 b_null added UP
******************************************************************************/
long qual2iqual (USHORT qual)
{
long q2 = 0;
if (qual & QUAL_XTX)
q2 |= EXTQUALIFIER_X;
if (qual & QUAL_XTY)
q2 |= EXTQUALIFIER_Y;
if (qual & QUAL_XTZ)
q2 |= EXTQUALIFIER_Z;
if (qual & QUAL_UP)
q2 |= EXTQUALIFIER_UP;
if (qual & QUAL_SHIFT)
q2 |= IEQUALIFIER_LSHIFT;
if (qual & QUAL_CTRL)
q2 |= IEQUALIFIER_CONTROL;
if (qual & QUAL_AMIGA)
q2 |= IEQUALIFIER_LCOMMAND;
if (qual & QUAL_ALT)
q2 |= IEQUALIFIER_LALT;
if (qual & QUAL_LMB)
q2 |= IEQUALIFIER_LEFTBUTTON;
if (qual & QUAL_MMB)
q2 |= IEQUALIFIER_MIDBUTTON;
if (qual & QUAL_RMB)
q2 |= IEQUALIFIER_RBUTTON;
return (q2);
} /* qual2iqual */
/*****************************************************************************
NAME
a2iqual
PARAMETER
VAL (char *, str)
VAR (long, piqual)
RESULT
success: 1 == ok; 0 == any error
RETURN
int
DESCRIPTION
convert an ascii string into Input-Qualifiers
we check each char of the string and set the according bit
the string may be NULL-terminated or "-"-terminated
any unknown char causes "return (0)"
NOTES
BUGS
(none known)
EXAMPLES
SEE ALSO
INTERNALS
HISTORY
14-Dez-92 null created
14-Jan-93 b_null added UP
******************************************************************************/
int a2iqual (char * str, long * piqual)
{
*piqual = 0;
for (; *str; str++) {
switch (*str) {
case 'a': *piqual |= IEQUALIFIER_LALT; break;
case 'A': *piqual |= IEQUALIFIER_LCOMMAND; break;
case 's': *piqual |= IEQUALIFIER_LSHIFT; break;
case 'L': *piqual |= IEQUALIFIER_LEFTBUTTON; break;
case 'M': *piqual |= IEQUALIFIER_MIDBUTTON; break;
case 'R': *piqual |= IEQUALIFIER_RBUTTON; break;
case 'u': *piqual |= EXTQUALIFIER_UP; break;
case 'x': *piqual |= EXTQUALIFIER_X; break;
case 'y': *piqual |= EXTQUALIFIER_Y; break;
case 'z': *piqual |= EXTQUALIFIER_Z; break;
case '-': return (1);
default: return (0);
} /* switch */
} /* for */
return (1);
} /* a2iqual */
/*****************************************************************************
NAME
iqual2a
PARAMETER
VAL (long, iqual)
RESULT
the string that corresponds to iqual (static)
RETURN
char *
DESCRIPTION
create a string representing the readble form of Intuition Qualifiers
NOTES
this is a slow routine, as we do not
immediately evaluated the string, but
use iqual2qual and cqtoa (but it works :-)
BUGS
(none known)
EXAMPLES
SEE ALSO
iqual2qual(), cqtoa
INTERNALS
HISTORY
14-Dez-92 null created
******************************************************************************/
char * iqual2a (long iqual)
{
return (cqtoa (-1, iqual2qual (iqual, 0, NULL, 0)));
} /* iqual2a */
/*****************************************************************************
NAME
init_kb
(exit_kb - obsolete)
PARAMETER
void
RESULT
-/-
RETURN
void
DESCRIPTION
entry and exit- code for Keyboard Control
NOTES
this is the lowest level on Amiga Software, we use
exit_kb is obsolete, so user cannot call it any more
init_kb is "__AUTOINIT" so user need not call it
(he must indeed, if his compiler does not support __autoinit)
BUGS
for unknown reasons, we must not close ConsoleDevice
EXAMPLES
SEE ALSO
INTERNALS
HISTORY
15-Dez-92 b_null created
15-Jan-93 b_null removed exit_kb
******************************************************************************/
/* Das war teil von reset_hash... */
/* es ist extremer Amiga - lowlevel - wohin?? */
/*
** Achtung: keine Ahnung wieso,
** aber wir DUERFEN ConsoleDevice nicht schliessen
** es ist jedenfalls so, dass wir sonst ziemlich abkacken
** zwischenspeichern nuetzt nix ...
** daher koennen wir diesen ganzen kram mit KC_... weglassen
*/
__autoinit
void init_kb (void)
{
struct IOStdReq cio;
/* printf ("init_kb\n"); */
if (!KC_Used) {
OpenDevice ("console.device", -1, (struct IORequest *)&cio, 0);
ConsoleDevice = (struct Library *)cio.io_Device;
keyboard_init ();
} /* if */
KC_Used = 1;
} /* init_kb */
/*****************************************************************************
NAME
CtoA
PARAMETER
char c
RESULT
ctoa[c]
RETURN
char
DESCRIPTION
this function was created to hide the stucture ctoa
ctoa is designed to check, IF a code c represents a
single ascii character and WHICH one
NOTES
a macro might be possible, too;
but then You have to declare ctoa non-static
ctoa is initialized by keyboard_init(), so
any call to CtoA before keyboard initialisation is undefined
BUGS
none known
EXAMPLES
SEE ALSO
ctoa
INTERNALS
HISTORY
30-Dez-92 b_null created
15-Jan-93 b_null documented
******************************************************************************/
char CtoA (char c)
{
return (ctoa[c]);
} /* CtoA */
/*****************************************************************************
NAME
DeadKeyConvert
PARAMETER
struct IntuiMessage * msg
UBYTE * buf
int bufsize
struct KeyMap * keymap
RESULT
actual - the number of characters in the buffer, -2 if no
RawKey was given or -1 if a buffer overflow was about to occur.
RETURN
int
DESCRIPTION
convert any RawKey-Code to (VanillaKey) an ASCII-String
NOTES
this function is only used by keycontrol.keyctl
but it for itself uses ConsoleDevice, so I could not
decide where to pu it.
BUGS
EXAMPLES
SEE ALSO
console.device/RawKeyConvert
INTERNALS
ereuge eine iorequest mit den allernotwendigsten eintraegen
und lasse sie auswerten
HISTORY
15-Dez-92 b_null moved to keycontrol.c
16.Dez.92 b_null documented
15-Jan-93 b_null moved to keycodes.c
******************************************************************************/
Prototype int DeadKeyConvert (struct IntuiMessage * msg, UBYTE * buf, int bufsize, struct KeyMap * keymap);
int DeadKeyConvert (struct IntuiMessage * msg, UBYTE * buf, int bufsize, struct KeyMap * keymap)
{
static struct InputEvent ievent = {
NULL, IECLASS_RAWKEY
};
if (msg->Class != RAWKEY)
return(-2);
ievent.ie_Code = msg->Code;
ievent.ie_Qualifier = msg->Qualifier;
ievent.ie_position.ie_addr = *((APTR *)msg->IAddress);
return (RawKeyConvert (&ievent, (char *)buf, bufsize, keymap));
} /* DeadKeyConvert */
/******************************************************************************
***** ENDE keycodes.c
******************************************************************************/