dxx-rebirth/arch/linux/svgalib/key.c
Bradley Bell 9bd1ba7c47 This commit was generated by cvs2svn to compensate for changes in r2,
which included commits to RCS files with non-trunk default branches.
2001-01-19 03:30:16 +00:00

384 lines
9.8 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/// SDL keyboard input support
#include <stdio.h>
#include <stdlib.h>
#include <vgakeyboard.h>
#include "event.h"
#include "error.h"
#include "key.h"
#include "timer.h"
//added on 9/3/98 by Matt Mueller to free some cpu instead of hogging during menus and such
#include "d_delay.h"
//end this section addition - Matt Mueller
#define KEY_BUFFER_SIZE 16
static unsigned char Installed = 0;
//-------- Variable accessed by outside functions ---------
unsigned char keyd_buffer_type; // 0=No buffer, 1=buffer ASCII, 2=buffer scans
unsigned char keyd_repeat;
unsigned char keyd_editor_mode;
volatile unsigned char keyd_last_pressed;
volatile unsigned char keyd_last_released;
volatile unsigned char keyd_pressed[256];
volatile int keyd_time_when_last_pressed;
typedef struct Key_info {
ubyte state; // state of key 1 == down, 0 == up
ubyte last_state; // previous state of key
int counter; // incremented each time key is down in handler
fix timewentdown; // simple counter incremented each time in interrupt and key is down
fix timehelddown; // counter to tell how long key is down -- gets reset to 0 by key routines
ubyte downcount; // number of key counts key was down
ubyte upcount; // number of times key was released
} Key_info;
typedef struct keyboard {
unsigned short keybuffer[KEY_BUFFER_SIZE];
Key_info keys[256];
fix time_pressed[KEY_BUFFER_SIZE];
unsigned int keyhead, keytail;
} keyboard;
static /*volatile*/ keyboard key_data;
char * key_text[256] = {
"","ESC","1","2","3","4","5","6","7","8","9","0","-",
"=","BSPC","TAB","Q","W","E","R","T","Y","U","I","O",
"P","[","]","ƒ","LCTRL","A","S","D","F",
"G","H","J","K","L",";","'","`",
"LSHFT","\\","Z","X","C","V","B","N","M",",",
".","/","RSHFT","PAD*","LALT","SPC",
"CPSLK","F1","F2","F3","F4","F5","F6","F7","F8","F9",
"F10","NMLCK","SCLK","PAD7","PAD8","PAD9","PAD-",
"PAD4","PAD5","PAD6","PAD+","PAD1","PAD2","PAD3","PAD0",
"PAD.","","","","F11","F12","","","","","","","","","",
"","","","","","","","","","","","","","","","","","","","",
"","","","","","","","","","","","","","","","","","","","",
"","","","","","","","","","","","","","","","","","",
"PADƒ","RCTRL","","","","","","","","","","","","","",
"","","","","","","","","","","PAD/","","","RALT","",
"","","","","","","","","","","","","","HOME","","PGUP",
"","<EFBFBD>","","","","END","","PGDN","INS",
"DEL","","","","","","","","","","","","","","","","","",
"","","","","","","","","","","","","","","","","","","","",
"","","","","","","" };
unsigned char ascii_table[128] =
{ 255, 255, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=',255,255,
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 255, 255,
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', 39, '`',
255, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 255,'*',
255, ' ', 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,255,255,
255, 255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255 };
unsigned char shifted_ascii_table[128] =
{ 255, 255, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+',255,255,
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 255, 255,
'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~',
255, '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', 255,255,
255, ' ', 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,255,255,
255, 255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255 };
//killed on 10/03/98 by Matt Mueller
//unsigned char key_to_ascii(int a)
//{
// if (!isprint(a)) return 255;
// if (a & KEY_SHIFTED) {
// return (toupper((unsigned char) a));
// } else {
// return ((unsigned char) a);
// }
//}
//end kill -MM
//added on 10/03/98 by Matt Mueller to fix shifted keys (copied from dos/key.c)
unsigned char key_to_ascii(int keycode)
{
int shifted;
shifted = keycode & KEY_SHIFTED;
keycode &= 0xFF;
if ( keycode>=127 )
return 255;
if (shifted)
return shifted_ascii_table[keycode];
else
return ascii_table[keycode];
}
//end addition -MM
void key_handler(int scancode, int press)
{
ubyte state, key_state;
int i, keycode, event_key;
Key_info *key;
unsigned char temp;
if (press == KEY_EVENTPRESS)
key_state = 1;
else if (press == KEY_EVENTRELEASE)
key_state = 0;
else
return;
event_key = scancode;
//=====================================================
//Here a translation from win keycodes to mac keycodes!
//=====================================================
for (i = 255; i >= 0; i--) {
keycode = i;
key = &(key_data.keys[keycode]);
if (i == event_key)
state = key_state;
else
state = key->last_state;
if ( key->last_state == state ) {
if (state) {
key->counter++;
keyd_last_pressed = keycode;
keyd_time_when_last_pressed = timer_get_fixed_seconds();
}
} else {
if (state) {
keyd_last_pressed = keycode;
keyd_pressed[keycode] = 1;
key->downcount += state;
key->state = 1;
key->timewentdown = keyd_time_when_last_pressed = timer_get_fixed_seconds();
key->counter++;
} else {
keyd_pressed[keycode] = 0;
keyd_last_released = keycode;
key->upcount += key->state;
key->state = 0;
key->counter = 0;
key->timehelddown += timer_get_fixed_seconds() - key->timewentdown;
}
}
if ( (state && !key->last_state) || (state && key->last_state && (key->counter > 30) && (key->counter & 0x01)) ) {
if ( keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT])
keycode |= KEY_SHIFTED;
if ( keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT])
keycode |= KEY_ALTED;
if ( keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL])
keycode |= KEY_CTRLED;
if ( keyd_pressed[KEY_DELETE] )
keycode |= KEY_DEBUGGED;
temp = key_data.keytail+1;
if ( temp >= KEY_BUFFER_SIZE ) temp=0;
if (temp!=key_data.keyhead) {
key_data.keybuffer[key_data.keytail] = keycode;
key_data.time_pressed[key_data.keytail] = keyd_time_when_last_pressed;
key_data.keytail = temp;
}
}
key->last_state = state;
}
}
void key_close()
{
Installed = 0;
keyboard_close();
}
void key_init()
{
if (keyboard_init())
Error ("SVGAlib Keyboard Init Failed");
Installed=1;
keyboard_seteventhandler (key_handler);
keyd_time_when_last_pressed = timer_get_fixed_seconds();
keyd_buffer_type = 1;
keyd_repeat = 1;
// Clear the keyboard array
key_flush();
atexit(key_close);
}
void key_flush()
{
int i;
fix curtime;
if (!Installed)
key_init();
key_data.keyhead = key_data.keytail = 0;
//Clear the keyboard buffer
for (i=0; i<KEY_BUFFER_SIZE; i++ ) {
key_data.keybuffer[i] = 0;
key_data.time_pressed[i] = 0;
}
//use gettimeofday here:
curtime = timer_get_fixed_seconds();
for (i=0; i<256; i++ ) {
keyd_pressed[i] = 0;
key_data.keys[i].state = 1;
key_data.keys[i].last_state = 0;
key_data.keys[i].timewentdown = curtime;
key_data.keys[i].downcount=0;
key_data.keys[i].upcount=0;
key_data.keys[i].timehelddown = 0;
key_data.keys[i].counter = 0;
}
}
int add_one(int n)
{
n++;
if ( n >= KEY_BUFFER_SIZE ) n=0;
return n;
}
int key_checkch()
{
int is_one_waiting = 0;
event_poll();
if (key_data.keytail!=key_data.keyhead)
is_one_waiting = 1;
return is_one_waiting;
}
int key_inkey()
{
int key = 0;
if (!Installed)
key_init();
event_poll();
if (key_data.keytail!=key_data.keyhead) {
key = key_data.keybuffer[key_data.keyhead];
key_data.keyhead = add_one(key_data.keyhead);
}
//added 9/3/98 by Matt Mueller to free cpu time instead of hogging during menus and such
// else d_delay(1);
//end addition - Matt Mueller
return key;
}
int key_inkey_time(fix * time)
{
int key = 0;
if (!Installed)
key_init();
event_poll();
if (key_data.keytail!=key_data.keyhead) {
key = key_data.keybuffer[key_data.keyhead];
*time = key_data.time_pressed[key_data.keyhead];
key_data.keyhead = add_one(key_data.keyhead);
}
return key;
}
int key_peekkey()
{
int key = 0;
event_poll();
if (key_data.keytail!=key_data.keyhead)
key = key_data.keybuffer[key_data.keyhead];
return key;
}
int key_getch()
{
int dummy=0;
if (!Installed)
return 0;
// return getch();
while (!key_checkch())
dummy++;
return key_inkey();
}
unsigned int key_get_shift_status()
{
unsigned int shift_status = 0;
if ( keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT] )
shift_status |= KEY_SHIFTED;
if ( keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT] )
shift_status |= KEY_ALTED;
if ( keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL] )
shift_status |= KEY_CTRLED;
#ifndef NDEBUG
if (keyd_pressed[KEY_DELETE])
shift_status |=KEY_DEBUGGED;
#endif
return shift_status;
}
// Returns the number of seconds this key has been down since last call.
fix key_down_time(int scancode)
{
fix time_down, time;
event_poll();
if ((scancode<0)|| (scancode>255)) return 0;
if (!keyd_pressed[scancode]) {
time_down = key_data.keys[scancode].timehelddown;
key_data.keys[scancode].timehelddown = 0;
} else {
time = timer_get_fixed_seconds();
time_down = time - key_data.keys[scancode].timewentdown;
key_data.keys[scancode].timewentdown = time;
}
return time_down;
}
unsigned int key_down_count(int scancode)
{
int n;
event_poll();
if ((scancode<0)|| (scancode>255)) return 0;
n = key_data.keys[scancode].downcount;
key_data.keys[scancode].downcount = 0;
return n;
}
unsigned int key_up_count(int scancode)
{
int n;
event_poll();
if ((scancode<0)|| (scancode>255)) return 0;
n = key_data.keys[scancode].upcount;
key_data.keys[scancode].upcount = 0;
return n;
}