diff options
author | wdenk <wdenk> | 2002-11-19 11:04:11 +0000 |
---|---|---|
committer | wdenk <wdenk> | 2002-11-19 11:04:11 +0000 |
commit | c7de829c796978e519984df2f1c8cfcf921a39a4 (patch) | |
tree | 43e42aa9a09f5265783c1622a5cea080471ef50e /board/MAI/bios_emulator/scitech/src/pm/common/keyboard.c | |
parent | 2262cfeef91458b01a1bfe3812ccbbfdf8b82807 (diff) |
* Patch by Thomas Frieden, 13 Nov 2002:
Add code for AmigaOne board
(preliminary merge to U-Boot, still WIP)
* Patch by Jon Diekema, 12 Nov 2002:
- Adding URL for IEEE OUI lookup
- Making the autoboot #defines dependent on CONFIG_AUTOBOOT_KEYED
being defined.
- In the CONFIG_EXTRA_ENV_SETTINGS #define, the root-on-initrd and
root-on-nfs macros are designed to switch how the default boot
method gets defined.
Diffstat (limited to 'board/MAI/bios_emulator/scitech/src/pm/common/keyboard.c')
-rw-r--r-- | board/MAI/bios_emulator/scitech/src/pm/common/keyboard.c | 450 |
1 files changed, 450 insertions, 0 deletions
diff --git a/board/MAI/bios_emulator/scitech/src/pm/common/keyboard.c b/board/MAI/bios_emulator/scitech/src/pm/common/keyboard.c new file mode 100644 index 00000000000..79b4040ac1a --- /dev/null +++ b/board/MAI/bios_emulator/scitech/src/pm/common/keyboard.c @@ -0,0 +1,450 @@ +/**************************************************************************** +* +* SciTech OS Portability Manager Library +* +* ======================================================================== +* +* The contents of this file are subject to the SciTech MGL Public +* License Version 1.0 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.scitechsoft.com/mgl-license.txt +* +* Software distributed under the License is distributed on an +* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc. +* +* The Initial Developer of the Original Code is SciTech Software, Inc. +* All Rights Reserved. +* +* ======================================================================== +* +* Language: ANSI C +* Environment: Any +* +* Description: Direct keyboard event handling module. This module contains +* code to process raw scan code information, convert it to +* virtual scan codes and do code page translation to ASCII +* for different international keyboard layouts. +* +****************************************************************************/ + +/*---------------------------- Implementation -----------------------------*/ + +/**************************************************************************** +PARAMETERS: +scanCode - Keyboard scan code to translate +table - Code page table to search +count - Number of entries in the code page table + +REMARKS: +This function translates the scan codes from keyboard scan codes to ASCII +codes using a binary search on the code page table. +****************************************************************************/ +static uchar translateScan( + uchar scanCode, + codepage_entry_t *table, + int count) +{ + codepage_entry_t *test; + int n,pivot,val; + + for (n = count; n > 0; ) { + pivot = n >> 1; + test = table + pivot; + val = scanCode - test->scanCode; + if (val < 0) + n = pivot; + else if (val == 0) + return test->asciiCode; + else { + table = test + 1; + n -= pivot + 1; + } + } + return 0; +} + +/**************************************************************************** +REMARKS: +This macro/function is used to converts the scan codes reported by the +keyboard to our event libraries normalised format. We only have one scan +code for the 'A' key, and use shift modifiers to determine if it is a +Ctrl-F1, Alt-F1 etc. The raw scan codes from the keyboard work this way, +but the OS gives us 'cooked' scan codes, we have to translate them back +to the raw format. +{secret} +****************************************************************************/ +void _EVT_maskKeyCode( + event_t *evt) +{ + int ascii,scan = EVT_scanCode(evt->message); + + evt->message &= ~0xFF; + if (evt->modifiers & EVT_NUMLOCK) { + if ((ascii = translateScan(scan,EVT.codePage->numPad,EVT.codePage->numPadLen)) != 0) { + evt->message |= ascii; + return; + } + } + if (evt->modifiers & EVT_CTRLSTATE) { + evt->message |= translateScan(scan,EVT.codePage->ctrl,EVT.codePage->ctrlLen); + return; + } + if (evt->modifiers & EVT_CAPSLOCK) { + if (evt->modifiers & EVT_SHIFTKEY) { + if ((ascii = translateScan(scan,EVT.codePage->shiftCaps,EVT.codePage->shiftCapsLen)) != 0) { + evt->message |= ascii; + return; + } + } + else { + if ((ascii = translateScan(scan,EVT.codePage->caps,EVT.codePage->capsLen)) != 0) { + evt->message |= ascii; + return; + } + } + } + if (evt->modifiers & EVT_SHIFTKEY) { + if ((ascii = translateScan(scan,EVT.codePage->shift,EVT.codePage->shiftLen)) != 0) { + evt->message |= ascii; + return; + } + } + evt->message |= translateScan(scan,EVT.codePage->normal,EVT.codePage->normalLen); +} + +/**************************************************************************** +REMARKS: +Returns true if the key with the specified scan code is being held down. +****************************************************************************/ +static ibool _EVT_isKeyDown( + uchar scanCode) +{ + if (scanCode > 0x7F) + return false; + else + return EVT.keyTable[scanCode] != 0; +} + +/**************************************************************************** +PARAMETERS: +what - Event code +message - Event message (ASCII code and scan code) + +REMARKS: +Adds a new keyboard event to the event queue. This routine is called from +within the keyboard interrupt subroutine! + +NOTE: Interrupts are OFF when this routine is called by the keyboard ISR, + and we leave them OFF the entire time. +****************************************************************************/ +static void addKeyEvent( + uint what, + uint message) +{ + event_t evt; + + if (EVT.count < EVENTQSIZE) { + /* Save information in event record */ + evt.when = _EVT_getTicks(); + evt.what = what; + evt.message = message | 0x10000UL; + evt.where_x = 0; + evt.where_y = 0; + evt.relative_x = 0; + evt.relative_y = 0; + evt.modifiers = EVT.keyModifiers; + if (evt.what == EVT_KEYREPEAT) { + if (EVT.oldKey != -1) + EVT.evtq[EVT.oldKey].message += 0x10000UL; + else { + EVT.oldKey = EVT.freeHead; + addEvent(&evt); /* Add to tail of event queue */ + } + } + else { +#ifdef __QNX__ + _EVT_maskKeyCode(&evt); +#endif + addEvent(&evt); /* Add to tail of event queue */ + } + EVT.oldMove = -1; + } +} + +/**************************************************************************** +REMARKS: +This function waits for the keyboard controller to set the ready-for-write +bit. +****************************************************************************/ +static int kbWaitForWriteReady(void) +{ + int timeout = 8192; + while ((timeout > 0) && (PM_inpb(0x64) & 0x02)) + timeout--; + return (timeout > 0); +} + +/**************************************************************************** +REMARKS: +This function waits for the keyboard controller to set the ready-for-read +bit. +****************************************************************************/ +static int kbWaitForReadReady(void) +{ + int timeout = 8192; + while ((timeout > 0) && (!(PM_inpb(0x64) & 0x01))) + timeout--; + return (timeout > 0); +} + +/**************************************************************************** +PARAMETERS: +data - Data to send to the keyboard + +REMARKS: +This function sends a data byte to the keyboard controller. +****************************************************************************/ +static int kbSendData( + uchar data) +{ + int resends = 4; + int timeout, temp; + + do { + if (!kbWaitForWriteReady()) + return 0; + PM_outpb(0x60,data); + timeout = 8192; + while (--timeout > 0) { + if (!kbWaitForReadReady()) + return 0; + temp = PM_inpb(0x60); + if (temp == 0xFA) + return 1; + if (temp == 0xFE) + break; + } + } while ((resends-- > 0) && (timeout > 0)); + return 0; +} + +/**************************************************************************** +PARAMETERS: +modifiers - Keyboard modifier flags + +REMARKS: +This function re-programs the LED's on the keyboard to the values stored +in the passed in modifier flags. If the 'allowLEDS' flag is false, this +function does nothing. +****************************************************************************/ +static void setLEDS( + uint modifiers) +{ + if (EVT.allowLEDS) { + if (!kbSendData(0xED) || !kbSendData((modifiers>>9) & 7)) { + kbSendData(0xF4); + } + } +} + +/**************************************************************************** +REMARKS: +Function to process raw scan codes read from the keyboard controller. + +NOTE: Interrupts are OFF when this routine is called by the keyboard ISR, + and we leave them OFF the entire time. +{secret} +****************************************************************************/ +void processRawScanCode( + int scan) +{ + static int pauseLoop = 0; + static int extended = 0; + int what; + + if (pauseLoop) { + /* Skip scan codes until the pause key sequence has been read */ + pauseLoop--; + } + else if (scan == 0xE0) { + /* This signals the start of an extended scan code sequence */ + extended = 1; + } + else if (scan == 0xE1) { + /* The Pause key sends a strange scan code sequence, which is: + * + * E1 1D 52 E1 9D D2 + * + * However there is never any release code nor any auto-repeat for + * this key. For this reason we simply ignore the key and skip the + * next 5 scan codes read from the keyboard. + */ + pauseLoop = 5; + } + else { + /* Process the scan code normally (it may be an extended code + * however!). Bit 7 means key was released, and bits 0-6 are the + * scan code. + */ + what = (scan & 0x80) ? EVT_KEYUP : EVT_KEYDOWN; + scan &= 0x7F; + if (extended) { + extended = 0; + if (scan == 0x2A || scan == 0x36) { + /* Ignore these extended scan code sequences. These are + * used by the keyboard controller to wrap around certain + * key sequences for the keypad (and when NUMLOCK is down + * internally). + */ + return; + } + + /* Convert extended codes for key sequences that we map to + * virtual scan codes so the user can detect them in their + * code. + */ + switch (scan) { + case KB_leftCtrl: scan = KB_rightCtrl; break; + case KB_leftAlt: scan = KB_rightAlt; break; + case KB_divide: scan = KB_padDivide; break; + case KB_enter: scan = KB_padEnter; break; + case KB_padTimes: scan = KB_sysReq; break; + } + } + else { + /* Convert regular scan codes for key sequences that we map to + * virtual scan codes so the user can detect them in their + * code. + */ + switch (scan) { + case KB_left: scan = KB_padLeft; break; + case KB_right: scan = KB_padRight; break; + case KB_up: scan = KB_padUp; break; + case KB_down: scan = KB_padDown; break; + case KB_insert: scan = KB_padInsert; break; + case KB_delete: scan = KB_padDelete; break; + case KB_home: scan = KB_padHome; break; + case KB_end: scan = KB_padEnd; break; + case KB_pageUp: scan = KB_padPageUp; break; + case KB_pageDown: scan = KB_padPageDown; break; + } + } + + /* Determine if the key is an UP, DOWN or REPEAT and maintain the + * up/down status of all keys in our global key array. + */ + if (what == EVT_KEYDOWN) { + if (EVT.keyTable[scan]) + what = EVT_KEYREPEAT; + else + EVT.keyTable[scan] = scan; + } + else { + EVT.keyTable[scan] = 0; + } + + /* Handle shift key modifiers */ + if (what != EVT_KEYREPEAT) { + switch (scan) { + case KB_capsLock: + if (what == EVT_KEYDOWN) + EVT.keyModifiers ^= EVT_CAPSLOCK; + setLEDS(EVT.keyModifiers); + break; + case KB_numLock: + if (what == EVT_KEYDOWN) + EVT.keyModifiers ^= EVT_NUMLOCK; + setLEDS(EVT.keyModifiers); + break; + case KB_scrollLock: + if (what == EVT_KEYDOWN) + EVT.keyModifiers ^= EVT_SCROLLLOCK; + setLEDS(EVT.keyModifiers); + break; + case KB_leftShift: + if (what == EVT_KEYUP) + EVT.keyModifiers &= ~EVT_LEFTSHIFT; + else + EVT.keyModifiers |= EVT_LEFTSHIFT; + break; + case KB_rightShift: + if (what == EVT_KEYUP) + EVT.keyModifiers &= ~EVT_RIGHTSHIFT; + else + EVT.keyModifiers |= EVT_RIGHTSHIFT; + break; + case KB_leftCtrl: + if (what == EVT_KEYUP) + EVT.keyModifiers &= ~EVT_LEFTCTRL; + else + EVT.keyModifiers |= EVT_LEFTCTRL; + break; + case KB_rightCtrl: + if (what == EVT_KEYUP) + EVT.keyModifiers &= ~EVT_RIGHTCTRL; + else + EVT.keyModifiers |= EVT_RIGHTCTRL; + break; + case KB_leftAlt: + if (what == EVT_KEYUP) + EVT.keyModifiers &= ~EVT_LEFTALT; + else + EVT.keyModifiers |= EVT_LEFTALT; + break; + case KB_rightAlt: + if (what == EVT_KEYUP) + EVT.keyModifiers &= ~EVT_RIGHTALT; + else + EVT.keyModifiers |= EVT_RIGHTALT; + break; +#ifdef SUPPORT_CTRL_ALT_DEL + case KB_delete: + if ((EVT.keyModifiers & EVT_CTRLSTATE) && (EVT.keyModifiers & EVT_ALTSTATE)) + Reboot(); + break; +#endif + } + } + + /* Add the untranslated key code to the event queue. All + * translation to ASCII from the key codes occurs when the key + * is extracted from the queue, saving time in the low level + * interrupt handler. + */ + addKeyEvent(what,scan << 8); + } +} + +/**************************************************************************** +DESCRIPTION: +Enables/disables the update of the keyboard LED status indicators. + +HEADER: +event.h + +PARAMETERS: +enable - True to enable, false to disable + +REMARKS: +Enables the update of the keyboard LED status indicators. Sometimes it may +be convenient in the application to turn off the updating of the LED +status indicators (such as if a game is using the CAPSLOCK key for some +function). Passing in a value of FALSE to this function will turn off all +the LEDS, and stop updating them when the internal status changes (note +however that internally we still keep track of the toggle key status!). +****************************************************************************/ +void EVTAPI EVT_allowLEDS( + ibool enable) +{ + EVT.allowLEDS = true; + if (enable) + setLEDS(EVT.keyModifiers); + else + setLEDS(0); + EVT.allowLEDS = enable; +} + |