|
|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 9272 (0x2438)
Types: TextFile
Notes: UNIX file
Names: »kev.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
└─⟦2d53db1df⟧ UNIX Filesystem
└─⟦this⟧ »hr/src/smgr/kev.c«
#include <stdio.h>
#include <errno.h>
#include <smgr.h>
/*
* Keyboard/display driver.
*/
#define SPC 0376 /* Special encoding */
#define XXX 0377 /* Non-character */
#define KBDATA 0x60 /* Keyboard data */
#define KBCTRL 0x61 /* Keyboard control */
#define KBFLAG 0x80 /* Keyboard reset flag */
#define KEYUP 0x80 /* Key up change */
#define KEYSC 0x7F /* Key scan code mask */
#define LSHIFT 0x2A-1 /* Left shift key */
#define LSHIFTA 0x2B-1 /* Alternate left-shift key */
#define RSHIFT 0x36-1 /* Right shift key */
#define CTRL 0x1D-1 /* Control key */
#define ALT 0x38-1 /* Alt key */
#define CAPLOCK 0x3A-1 /* Caps lock key */
#define DELETE 0x53-1 /* Del, as in CTRL-ALT-DEL */
#define BACKSP 0x0E-1 /* Back space */
#define SCRLOCK 0x46-1 /* Scroll lock */
/* Shift flags */
#define SRS 0x01 /* Right shift key on */
#define SLS 0x02 /* Left shift key on */
#define CTS 0x04 /* Ctrl key on */
#define ALS 0x08 /* Alt key on */
#define CPLS 0x10 /* Caps lock on */
#define NMLS 0x20 /* Num lock on */
#define AKPS 0x40 /* Alternate keypad shift */
#define SHFT 0x80 /* Shift key flag */
/* Function key information */
#define NFKEY 40 /* Number of settable functions */
#define NFCHAR 600 /* Number of characters settable */
#define NFBUF (NFKEY*2+NFCHAR+1) /* Size of buffer */
/* ASCII codes */
#define DEL 0x7f /* delete code */
/*
* State variables.
*/
static char shift; /* Overall shift state */
static char lshift = LSHIFT; /* Left shift alternate state */
static int kbd_wid;
extern int myfd;
extern POINT SM_Mouse_Pos;
/*
* Tables for converting key code to ASCII.
* lmaptab specifies unshifted conversion,
* umaptab specifies shifted conversion,
* smaptab specifies the shift states which are active.
* An entry of XXX says the key is dead.
* An entry of SPC requires further processing.
*
* Key codes:
* ESC .. <- == 1 .. 14
* -> .. \n == 15 .. 28
* CTRL .. ` == 29 .. 41
* ^Shift .. PrtSc == 42 .. 55
* ALT .. CapsLock == 56 .. 58
* F1 .. F10 == 59 .. 68
* NumLock .. Del == 69 .. 83
*/
static unsigned char lmaptab[] ={
'\33', '1', '2', '3', '4', '5', '6', /* 1 - 7 */
'7', '8', '9', '0', '-', '=', '\b', '\t', /* 8 - 15 */
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', /* 16 - 23 */
'o', 'p', '[', ']', '\r', XXX, 'a', 's', /* 24 - 31 */
'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* 32 - 39 */
'\'', '`', XXX, '\\', 'z', 'x', 'c', 'v', /* 40 - 47 */
'b', 'n', 'm', ',', '.', '/', XXX, SPC, /* 48 - 55 */
XXX, ' ', XXX, SPC, SPC, SPC, SPC, SPC, /* 56 - 63 */
SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC, /* 64 - 71 */
SPC, SPC, '-', SPC, SPC, SPC, '+', SPC, /* 72 - 79 */
SPC, SPC, SPC, SPC, SPC, DEL, SPC, SPC, /* 80 - 87 */
SPC, SPC, SPC, SPC, SPC, SPC, '\r', SPC, /* 88 - 95 */
SPC, SPC, SPC, XXX, XXX /* 96 - 100*/
};
static unsigned char umaptab[] ={
'\33', '!', '@', '#', '$', '%', '^', /* 1 - 7 */
'&', '*', '(', ')', '_', '+', '\b', '\t', /* 8 - 15 */
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', /* 16 - 23 */
'O', 'P', '{', '}', '\r', XXX, 'A', 'S', /* 24 - 31 */
'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', /* 32 - 39 */
'"', '~', XXX, '|', 'Z', 'X', 'C', 'V', /* 40 - 47 */
'B', 'N', 'M', '<', '>', '?', XXX, SPC, /* 48 - 55 */
XXX, ' ', XXX, SPC, SPC, SPC, SPC, SPC, /* 56 - 63 */
SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC, /* 64 - 71 */
SPC, SPC, '-', SPC, SPC, SPC, '+', SPC, /* 72 - 79 */
SPC, SPC, SPC, SPC, SPC, DEL, SPC, SPC, /* 80 - 87 */
SPC, SPC, SPC, SPC, SPC, SPC, '\r', SPC, /* 88 - 95 */
SPC, SPC, SPC, XXX, XXX /* 96 - 100*/
};
#define SS0 0 /* No shift */
#define SS1 (SLS|SRS|CTS) /* Shift, Ctrl */
#define SES (SLS|SRS) /* Shift */
#define LET (SLS|SRS|CPLS|CTS) /* Shift, Caps, Ctrl */
#define KEY (SLS|SRS|NMLS|AKPS) /* Shift, Num, Alt keypad */
static unsigned char smaptab[] ={
SS0, SES, SS1, SES, SES, SES, SS1, /* 1 - 7 */
SES, SES, SES, SES, SS1, SES, SS0, SS0, /* 8 - 15 */
LET, LET, LET, LET, LET, LET, LET, LET, /* 16 - 23 */
LET, LET, SS1, SS1, SS0, SHFT, LET, LET, /* 24 - 31 */
LET, LET, LET, LET, LET, LET, LET, SES, /* 32 - 39 */
SES, SS1, SHFT, SS1, LET, LET, LET, LET, /* 40 - 47 */
LET, LET, LET, SES, SES, SES, SHFT, SS0, /* 48 - 55 */
SHFT, SS1, SHFT, SS0, SS0, SS0, SS0, SS0, /* 56 - 63 */
SS0, SS0, SS0, SS0, SS0, SS0, KEY, KEY, /* 64 - 71 */
KEY, KEY, SS0, KEY, KEY, KEY, SS0, KEY, /* 72 - 79 */
KEY, KEY, KEY, KEY, SS0, SS0, SS0, SS0, /* 80 - 87 */
SS0, SS0, SS0, SS0, SS0, SS0, SS0, SS0, /* 88 - 95 */
SS0, SS0, SS0, LET, LET /* 96 - 100*/
};
/*
** When the keyboard interrupt routine sends a key position to
** the screen manager sm_key routine is called. This routine checks
** the key position to decide if the key was for screen manager or
** or for an active window and then calls an appropriate routine
** to do the work.
*/
SM_Keyboard()
{
register int c;
register int s;
register int r;
r = msgData1 & 0xFF;
if (r == 0xFF)
return; /* Overrun */
c = (r & KEYSC) - 1;
#ifdef DEBUG
if ( ~(r&KEYUP) )
printf("KEY:\t0x%x %d\n", r, r);
#endif
/*
* Track "shift" keys.
*/
s = smaptab[c];
if (s&SHFT)
{
if (r&KEYUP)
{ /* "shift" released */
if (c == RSHIFT)
shift &= ~SRS;
else if (c == lshift)
shift &= ~SLS;
else if (c == CTRL)
shift &= ~CTS;
else if (c == ALT)
shift &= ~ALS;
}
else
{ /* "shift" pressed */
if (c == lshift)
shift |= SLS;
else if (c == RSHIFT)
shift |= SRS;
else if (c == CTRL)
shift |= CTS;
else if (c == ALT)
shift |= ALS;
else if (c == CAPLOCK)
shift ^= CPLS; /* toggle cap lock */
#ifdef NUMLOCK
else if (c == NUMLOCK)
shift ^= NMLS; /* toggle num lock */
#endif
}
return;
}
/*
* No other key up codes of interest.
*/
if (r&KEYUP)
return;
/*
* If no window to receive the character, then toss it.
*/
kbd_wid = who_top_at(SM_Mouse_Pos);
if ( kbd_wid == NO_WINDOW )
return;
if ( not ( wtbl[kbd_wid]->wn_Evmask & KBD_ENABLE ) )
return;
/*
* Map character, based on the
* current state of the shift, control,
* meta and lock flags.
*/
if (shift & CTS)
{
if (s==SS1 || s==LET) /* Normal Ctrl map */
c = umaptab[c]&0x1F; /* Clear bits 5-6 */
else
return; /* Ignore this char */
}
else if (s &= shift)
{
if (shift & SES)
{ /* if shift on */
if (s & (CPLS|NMLS)) /* if caps/num lock */
c = lmaptab[c]; /* use unshifted */
else
c = umaptab[c]; /* use shifted */
}
else
{ /* if shift not on */
if (s & (CPLS|NMLS)) /* if caps/num lock */
c = umaptab[c]; /* use shifted */
else
c = lmaptab[c]; /* use unshifted */
}
}
else
c = lmaptab[c]; /* use unshifted */
/*
* Act on character.
*/
if (c == XXX)
return; /* char to ignore */
if (c != SPC)
{ /* not special char? */
#ifdef DOALT
if (shift & ALS) /* ALT (meta bit)? */
c |= 0x80; /* set meta */
#endif
gen_msg(r, c, shift);
}
else
isspecial(r); /* special chars */
}
/*
* Handle special input sequences.
* The character passed is the key number.
*
* The keypad is translated by the following table,
* the first entry is the normal sequence, the second the shifted,
* and the third the alternate keypad sequence.
*/
static char keypad[] = {
'*', /* 55 */
'\0', /* 88 */
',', /* 89 */
'/', /* 90 */
'7', /* 71 */
'8', /* 72 */
'9', /* 73 */
'4', /* 75 */
'5', /* 76 */
'6', /* 77 */
'1', /* 79 */
'2', /* 80 */
'3', /* 81 */
'0', /* 82 */
'.' /* 83 */
};
isspecial(key)
register int key;
{
register int c;
c = key;
switch (key) {
case 59: case 60: case 61: case 62: case 63: /* F1 - F5 */
case 64: case 65: case 66: case 67: case 68: /* F6 - F10 */
case 84: case 86: case 87: case 69: /* HELP, F12, F13, F14 */
case 70: /* F15 (Scroll Lock)*/
case 91: case 92: case 93: /* W1 - W3 */
case 95: case 96: case 97: case 98: /* cursor keys */
gen_msg(key, 0, shift);
return;
case 55: /* PF3 */
c = 87;
case 88: case 89: case 90: /* PF1, PF2, PF4 */
c -= 18;
case 79: /* 1/End */
case 80: /* 2/DOWN */
case 81: /* 3/PgDn */
case 82: /* 0/Ins */
case 83: /* ./Del */
--c; /* adjust code */
case 75: /* 4/LEFT */
case 76: /* 5 */
case 77: /* 6/RIGHT */
--c; /* adjust code */
case 71: /* 7/Home/Clear */
case 72: /* 8/UP */
case 73: /* 9/PgUp */
#ifndef TRACE
if ( (shift&NMLS) || (shift&SES) ||
(!(shift&NMLS) && !(shift&SES) && (shift&AKPS)) )
c = 0;
else
c = keypad[c-67];
break;
#else
DB_dump();
break;
#endif
default:
c = 0;
break;
}
gen_msg(key, c, shift);
}
/*
** generate message to the active window manager
*/
gen_msg(kpos, kval, mod)
unsigned kpos, kval, mod;
{
MESSAGE m;
m.msg_Receiver = wtbl[kbd_wid]->wn_Wmgr;
m.msg_Cmd = WM_CHARACTER;
m.msg_Data[0] = kbd_wid << 8;
m.msg_Data[0] |= kval;
m.msg_Data[1] = kpos;
m.msg_Data[2] = mod;
sendmsg( &m );
}