2017-05-30 03:38:38 +02:00
|
|
|
/*
|
2022-11-13 16:37:58 -05:00
|
|
|
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
|
|
|
|
* running old operating systems and software designed for IBM
|
|
|
|
|
* PC systems and compatibles from 1981 through fairly recent
|
|
|
|
|
* system designs based on the PCI bus.
|
2017-05-30 03:38:38 +02:00
|
|
|
*
|
2022-11-13 16:37:58 -05:00
|
|
|
* This file is part of the 86Box distribution.
|
2017-05-30 03:38:38 +02:00
|
|
|
*
|
2022-11-13 16:37:58 -05:00
|
|
|
* General keyboard driver interface.
|
2017-05-30 03:38:38 +02:00
|
|
|
*
|
2020-03-25 00:46:02 +02:00
|
|
|
*
|
2017-05-30 03:38:38 +02:00
|
|
|
*
|
2023-01-06 15:36:29 -05:00
|
|
|
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
|
2022-11-13 16:37:58 -05:00
|
|
|
* Miran Grca, <mgrca8@gmail.com>
|
|
|
|
|
* Fred N. van Kempen, <decwiz@yahoo.com>
|
2017-10-10 03:07:29 -04:00
|
|
|
*
|
2022-11-13 16:37:58 -05:00
|
|
|
* Copyright 2008-2019 Sarah Walker.
|
|
|
|
|
* Copyright 2015-2019 Miran Grca.
|
|
|
|
|
* Copyright 2017-2019 Fred N. van Kempen.
|
2017-05-30 03:38:38 +02:00
|
|
|
*/
|
2017-09-25 04:31:20 -04:00
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <wchar.h>
|
2020-03-29 14:24:42 +02:00
|
|
|
#include <86box/86box.h>
|
|
|
|
|
#include <86box/machine.h>
|
|
|
|
|
#include <86box/keyboard.h>
|
2024-08-07 06:11:50 +02:00
|
|
|
#include <86box/plat.h>
|
2016-06-26 00:34:39 +02:00
|
|
|
|
2021-12-19 20:00:27 +01:00
|
|
|
#include "cpu.h"
|
|
|
|
|
|
2024-12-31 00:48:50 +01:00
|
|
|
uint16_t scancode_map[768] = { 0 };
|
|
|
|
|
|
|
|
|
|
int keyboard_scan;
|
2023-10-12 04:52:53 +02:00
|
|
|
|
2024-09-02 13:23:00 -07:00
|
|
|
/* F8+F12 */
|
2023-10-12 05:08:11 +02:00
|
|
|
uint16_t key_prefix_1_1 = 0x042; /* F8 */
|
|
|
|
|
uint16_t key_prefix_1_2 = 0x000; /* Invalid */
|
|
|
|
|
uint16_t key_prefix_2_1 = 0x000; /* Invalid */
|
|
|
|
|
uint16_t key_prefix_2_2 = 0x000; /* Invalid */
|
2023-10-12 04:52:53 +02:00
|
|
|
uint16_t key_uncapture_1 = 0x058; /* F12 */
|
|
|
|
|
uint16_t key_uncapture_2 = 0x000; /* Invalid */
|
|
|
|
|
|
2022-09-18 17:13:28 -04:00
|
|
|
void (*keyboard_send)(uint16_t val);
|
2017-09-25 04:31:20 -04:00
|
|
|
|
2024-08-07 06:11:50 +02:00
|
|
|
static int recv_key[512] = { 0 }; /* keyboard input buffer */
|
|
|
|
|
static int recv_key_ui[512] = { 0 }; /* keyboard input buffer */
|
2022-09-18 17:13:28 -04:00
|
|
|
static int oldkey[512];
|
2018-02-10 01:19:31 +01:00
|
|
|
#if 0
|
2022-11-13 16:38:48 -05:00
|
|
|
static int keydelay[512];
|
2018-02-10 01:19:31 +01:00
|
|
|
#endif
|
2022-09-18 17:13:28 -04:00
|
|
|
static scancode *scan_table; /* scancode table for keyboard */
|
2018-01-13 22:56:13 +01:00
|
|
|
|
2022-09-18 17:13:28 -04:00
|
|
|
static uint8_t caps_lock = 0;
|
|
|
|
|
static uint8_t num_lock = 0;
|
|
|
|
|
static uint8_t scroll_lock = 0;
|
|
|
|
|
static uint8_t shift = 0;
|
2017-10-24 22:10:21 -04:00
|
|
|
|
|
|
|
|
void
|
|
|
|
|
keyboard_init(void)
|
|
|
|
|
{
|
|
|
|
|
memset(recv_key, 0x00, sizeof(recv_key));
|
|
|
|
|
|
|
|
|
|
keyboard_scan = 1;
|
2022-09-18 17:13:28 -04:00
|
|
|
scan_table = NULL;
|
2016-06-26 00:34:39 +02:00
|
|
|
|
2017-10-24 22:10:21 -04:00
|
|
|
memset(keyboard_set3_flags, 0x00, sizeof(keyboard_set3_flags));
|
|
|
|
|
keyboard_set3_all_repeat = 0;
|
2022-09-18 17:13:28 -04:00
|
|
|
keyboard_set3_all_break = 0;
|
2017-10-24 22:10:21 -04:00
|
|
|
}
|
|
|
|
|
|
2017-11-05 01:57:04 -05:00
|
|
|
void
|
2018-03-19 08:01:13 +01:00
|
|
|
keyboard_set_table(const scancode *ptr)
|
2017-11-05 01:57:04 -05:00
|
|
|
{
|
2018-03-19 08:01:13 +01:00
|
|
|
scan_table = (scancode *) ptr;
|
2017-11-05 01:57:04 -05:00
|
|
|
}
|
|
|
|
|
|
2018-01-13 22:56:13 +01:00
|
|
|
static uint8_t
|
|
|
|
|
fake_shift_needed(uint16_t scan)
|
|
|
|
|
{
|
2022-09-18 17:13:28 -04:00
|
|
|
switch (scan) {
|
2023-04-10 13:45:55 +02:00
|
|
|
case 0x137: /* Yes, Print Screen requires the fake shifts. */
|
2022-09-18 17:13:28 -04:00
|
|
|
case 0x147:
|
|
|
|
|
case 0x148:
|
|
|
|
|
case 0x149:
|
|
|
|
|
case 0x14a:
|
|
|
|
|
case 0x14b:
|
|
|
|
|
case 0x14d:
|
|
|
|
|
case 0x14f:
|
|
|
|
|
case 0x150:
|
|
|
|
|
case 0x151:
|
|
|
|
|
case 0x152:
|
|
|
|
|
case 0x153:
|
|
|
|
|
return 1;
|
|
|
|
|
default:
|
|
|
|
|
return 0;
|
2018-01-13 22:56:13 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-24 22:10:21 -04:00
|
|
|
void
|
2018-02-10 01:19:31 +01:00
|
|
|
key_process(uint16_t scan, int down)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2023-07-20 18:58:26 -04:00
|
|
|
const scancode *codes = scan_table;
|
|
|
|
|
int c;
|
2017-10-24 22:10:21 -04:00
|
|
|
|
2023-05-16 00:20:09 +02:00
|
|
|
if (!codes)
|
|
|
|
|
return;
|
|
|
|
|
|
PIC rewrite, proper SMRAM API, complete SiS 471 rewrite and addition of 40x, 460, and 461, changes to mem.c/h, disabled Voodoo memory dumping on exit, bumped SDL Hardware scale quality to 2, bumped IDE/ATAPI drives to ATA-6, finally bumped emulator version to 3.0, redid the bus type ID's to allow for planned ATAPI hard disks, made SST flash set its high mappings to the correct address if the CPU is 16-bit, and added the SiS 401 AMI 486 Clone, AOpen Vi15G, and the Soyo 4SA2 (486 with SiS 496/497 that can boot from CD-ROM), assorted 286+ protected mode fixes (for slightly more accuracy), and fixes to 808x emulation (MS Word 1.0 and 1.10 for DOS now work correctly from floppy).
2020-10-14 23:15:01 +02:00
|
|
|
if (!keyboard_scan || (keyboard_send == NULL))
|
2022-09-18 17:13:28 -04:00
|
|
|
return;
|
2016-06-26 00:34:39 +02:00
|
|
|
|
2018-02-10 01:19:31 +01:00
|
|
|
oldkey[scan] = down;
|
2023-05-16 00:20:09 +02:00
|
|
|
|
|
|
|
|
if (down && (codes[scan].mk[0] == 0))
|
2022-09-18 17:13:28 -04:00
|
|
|
return;
|
2017-10-24 22:10:21 -04:00
|
|
|
|
2023-05-16 00:20:09 +02:00
|
|
|
if (!down && (codes[scan].brk[0] == 0))
|
2022-09-18 17:13:28 -04:00
|
|
|
return;
|
2017-10-24 22:10:21 -04:00
|
|
|
|
2021-12-19 20:00:27 +01:00
|
|
|
/* TODO: The keyboard controller needs to report the AT flag to us here. */
|
|
|
|
|
if (is286 && ((keyboard_mode & 3) == 3)) {
|
2022-09-18 17:13:28 -04:00
|
|
|
if (!keyboard_set3_all_break && !down && !(keyboard_set3_flags[codes[scan].mk[0]] & 2))
|
|
|
|
|
return;
|
2017-10-24 22:10:21 -04:00
|
|
|
}
|
|
|
|
|
|
2018-02-10 01:19:31 +01:00
|
|
|
c = 0;
|
|
|
|
|
if (down) {
|
2022-09-18 17:13:28 -04:00
|
|
|
/* Send the special code indicating an opening fake shift might be needed. */
|
|
|
|
|
if (fake_shift_needed(scan))
|
|
|
|
|
keyboard_send(0x100);
|
|
|
|
|
while (codes[scan].mk[c] != 0)
|
|
|
|
|
keyboard_send(codes[scan].mk[c++]);
|
2018-02-10 01:19:31 +01:00
|
|
|
} else {
|
2022-09-18 17:13:28 -04:00
|
|
|
while (codes[scan].brk[c] != 0)
|
|
|
|
|
keyboard_send(codes[scan].brk[c++]);
|
|
|
|
|
/* Send the special code indicating a closing fake shift might be needed. */
|
|
|
|
|
if (fake_shift_needed(scan))
|
|
|
|
|
keyboard_send(0x101);
|
2017-10-24 22:10:21 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Handle a keystroke event from the UI layer. */
|
|
|
|
|
void
|
|
|
|
|
keyboard_input(int down, uint16_t scan)
|
|
|
|
|
{
|
2023-04-09 04:57:48 +02:00
|
|
|
/* Special case for E1 1D, translate it to 0100 - special case. */
|
|
|
|
|
if ((scan >> 8) == 0xe1) {
|
|
|
|
|
if ((scan & 0xff) == 0x1d)
|
|
|
|
|
scan = 0x0100;
|
2018-01-13 22:56:13 +01:00
|
|
|
/* Translate E0 xx scan codes to 01xx because we use 512-byte arrays for states
|
|
|
|
|
and scan code sets. */
|
2023-04-09 04:57:48 +02:00
|
|
|
} else if ((scan >> 8) == 0xe0) {
|
2022-09-18 17:13:28 -04:00
|
|
|
scan &= 0x00ff;
|
|
|
|
|
scan |= 0x0100; /* extended key code */
|
2018-01-13 22:56:13 +01:00
|
|
|
} else if ((scan >> 8) != 0x01)
|
2022-09-18 17:13:28 -04:00
|
|
|
scan &= 0x00ff; /* we can receive a scan code whose upper byte is 0x01,
|
|
|
|
|
this means we're the Win32 version running on windows
|
|
|
|
|
that already sends us preprocessed scan codes, which
|
|
|
|
|
means we then use the scan code as is, and need to
|
|
|
|
|
make sure we do not accidentally strip that upper byte */
|
2018-01-13 22:56:13 +01:00
|
|
|
|
|
|
|
|
if (recv_key[scan & 0x1ff] ^ down) {
|
2022-09-18 17:13:28 -04:00
|
|
|
if (down) {
|
|
|
|
|
switch (scan & 0x1ff) {
|
2022-10-31 04:04:47 +01:00
|
|
|
case 0x01d: /* Left Ctrl */
|
2022-09-18 17:13:28 -04:00
|
|
|
shift |= 0x01;
|
|
|
|
|
break;
|
2022-10-31 04:04:47 +01:00
|
|
|
case 0x11d: /* Right Ctrl */
|
2022-09-18 17:13:28 -04:00
|
|
|
shift |= 0x10;
|
|
|
|
|
break;
|
|
|
|
|
case 0x02a: /* Left Shift */
|
|
|
|
|
shift |= 0x02;
|
|
|
|
|
break;
|
|
|
|
|
case 0x036: /* Right Shift */
|
|
|
|
|
shift |= 0x20;
|
|
|
|
|
break;
|
|
|
|
|
case 0x038: /* Left Alt */
|
|
|
|
|
shift |= 0x04;
|
|
|
|
|
break;
|
|
|
|
|
case 0x138: /* Right Alt */
|
|
|
|
|
shift |= 0x40;
|
|
|
|
|
break;
|
2023-08-07 03:32:56 +02:00
|
|
|
case 0x15b: /* Left Windows */
|
|
|
|
|
shift |= 0x08;
|
|
|
|
|
break;
|
|
|
|
|
case 0x15c: /* Right Windows */
|
|
|
|
|
shift |= 0x80;
|
|
|
|
|
break;
|
2023-06-26 22:31:03 -04:00
|
|
|
|
2023-06-26 12:47:04 -04:00
|
|
|
default:
|
|
|
|
|
break;
|
2022-09-18 17:13:28 -04:00
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
switch (scan & 0x1ff) {
|
2022-10-31 04:04:47 +01:00
|
|
|
case 0x01d: /* Left Ctrl */
|
2022-09-18 17:13:28 -04:00
|
|
|
shift &= ~0x01;
|
|
|
|
|
break;
|
2022-10-31 04:04:47 +01:00
|
|
|
case 0x11d: /* Right Ctrl */
|
2022-09-18 17:13:28 -04:00
|
|
|
shift &= ~0x10;
|
|
|
|
|
break;
|
|
|
|
|
case 0x02a: /* Left Shift */
|
|
|
|
|
shift &= ~0x02;
|
|
|
|
|
break;
|
|
|
|
|
case 0x036: /* Right Shift */
|
|
|
|
|
shift &= ~0x20;
|
|
|
|
|
break;
|
|
|
|
|
case 0x038: /* Left Alt */
|
|
|
|
|
shift &= ~0x04;
|
|
|
|
|
break;
|
|
|
|
|
case 0x138: /* Right Alt */
|
|
|
|
|
shift &= ~0x40;
|
|
|
|
|
break;
|
2023-08-07 03:32:56 +02:00
|
|
|
case 0x15b: /* Left Windows */
|
|
|
|
|
shift &= ~0x08;
|
|
|
|
|
break;
|
|
|
|
|
case 0x15c: /* Right Windows */
|
|
|
|
|
shift &= ~0x80;
|
|
|
|
|
break;
|
2022-09-18 17:13:28 -04:00
|
|
|
case 0x03a: /* Caps Lock */
|
|
|
|
|
caps_lock ^= 1;
|
|
|
|
|
break;
|
|
|
|
|
case 0x045:
|
|
|
|
|
num_lock ^= 1;
|
|
|
|
|
break;
|
|
|
|
|
case 0x046:
|
|
|
|
|
scroll_lock ^= 1;
|
|
|
|
|
break;
|
2023-06-26 22:31:03 -04:00
|
|
|
|
2023-06-26 12:47:04 -04:00
|
|
|
default:
|
|
|
|
|
break;
|
2022-09-18 17:13:28 -04:00
|
|
|
}
|
|
|
|
|
}
|
2018-01-13 22:56:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* pclog("Received scan code: %03X (%s)\n", scan & 0x1ff, down ? "down" : "up"); */
|
2024-08-07 06:11:50 +02:00
|
|
|
recv_key_ui[scan & 0x1ff] = down;
|
2018-02-10 01:19:31 +01:00
|
|
|
|
2024-08-07 06:11:50 +02:00
|
|
|
if (mouse_capture || !kbd_req_capture || video_fullscreen) {
|
|
|
|
|
recv_key[scan & 0x1ff] = down;
|
|
|
|
|
key_process(scan & 0x1ff, down);
|
|
|
|
|
}
|
2018-01-13 22:56:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static uint8_t
|
|
|
|
|
keyboard_do_break(uint16_t scan)
|
|
|
|
|
{
|
2023-07-20 18:58:26 -04:00
|
|
|
const scancode *codes = scan_table;
|
2018-01-13 22:56:13 +01:00
|
|
|
|
2021-12-19 20:00:27 +01:00
|
|
|
/* TODO: The keyboard controller needs to report the AT flag to us here. */
|
|
|
|
|
if (is286 && ((keyboard_mode & 3) == 3)) {
|
2022-09-18 17:13:28 -04:00
|
|
|
if (!keyboard_set3_all_break && !recv_key[scan] && !(keyboard_set3_flags[codes[scan].mk[0]] & 2))
|
|
|
|
|
return 0;
|
|
|
|
|
else
|
|
|
|
|
return 1;
|
2018-01-13 22:56:13 +01:00
|
|
|
} else
|
2022-09-18 17:13:28 -04:00
|
|
|
return 1;
|
2018-01-13 22:56:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Also called by the emulated keyboard controller to update the states of
|
|
|
|
|
Caps Lock, Num Lock, and Scroll Lock when receving the "Set keyboard LEDs"
|
|
|
|
|
command. */
|
|
|
|
|
void
|
|
|
|
|
keyboard_update_states(uint8_t cl, uint8_t nl, uint8_t sl)
|
|
|
|
|
{
|
2022-09-18 17:13:28 -04:00
|
|
|
caps_lock = cl;
|
|
|
|
|
num_lock = nl;
|
|
|
|
|
scroll_lock = sl;
|
2018-01-13 22:56:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint8_t
|
|
|
|
|
keyboard_get_shift(void)
|
|
|
|
|
{
|
2022-09-18 17:13:28 -04:00
|
|
|
return shift;
|
2018-01-13 22:56:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
keyboard_get_states(uint8_t *cl, uint8_t *nl, uint8_t *sl)
|
|
|
|
|
{
|
2022-09-18 17:13:28 -04:00
|
|
|
if (cl)
|
|
|
|
|
*cl = caps_lock;
|
|
|
|
|
if (nl)
|
|
|
|
|
*nl = num_lock;
|
|
|
|
|
if (sl)
|
|
|
|
|
*sl = scroll_lock;
|
2018-01-13 22:56:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Called by the UI to update the states of Caps Lock, Num Lock, and Scroll Lock. */
|
|
|
|
|
void
|
|
|
|
|
keyboard_set_states(uint8_t cl, uint8_t nl, uint8_t sl)
|
|
|
|
|
{
|
2023-07-20 18:58:26 -04:00
|
|
|
const scancode *codes = scan_table;
|
2018-01-13 22:56:13 +01:00
|
|
|
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
if (caps_lock != cl) {
|
2022-09-18 17:13:28 -04:00
|
|
|
i = 0;
|
|
|
|
|
while (codes[0x03a].mk[i] != 0)
|
|
|
|
|
keyboard_send(codes[0x03a].mk[i++]);
|
|
|
|
|
if (keyboard_do_break(0x03a)) {
|
|
|
|
|
i = 0;
|
|
|
|
|
while (codes[0x03a].brk[i] != 0)
|
|
|
|
|
keyboard_send(codes[0x03a].brk[i++]);
|
|
|
|
|
}
|
2018-01-13 22:56:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (num_lock != nl) {
|
2022-09-18 17:13:28 -04:00
|
|
|
i = 0;
|
|
|
|
|
while (codes[0x045].mk[i] != 0)
|
|
|
|
|
keyboard_send(codes[0x045].mk[i++]);
|
|
|
|
|
if (keyboard_do_break(0x045)) {
|
|
|
|
|
i = 0;
|
|
|
|
|
while (codes[0x045].brk[i] != 0)
|
|
|
|
|
keyboard_send(codes[0x045].brk[i++]);
|
|
|
|
|
}
|
2018-01-13 22:56:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (scroll_lock != sl) {
|
2022-09-18 17:13:28 -04:00
|
|
|
i = 0;
|
|
|
|
|
while (codes[0x046].mk[i] != 0)
|
|
|
|
|
keyboard_send(codes[0x046].mk[i++]);
|
|
|
|
|
if (keyboard_do_break(0x046)) {
|
|
|
|
|
i = 0;
|
|
|
|
|
while (codes[0x046].brk[i] != 0)
|
|
|
|
|
keyboard_send(codes[0x046].brk[i++]);
|
|
|
|
|
}
|
2018-01-13 22:56:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
keyboard_update_states(cl, nl, sl);
|
2017-10-24 22:10:21 -04:00
|
|
|
}
|
|
|
|
|
|
2017-12-31 06:37:19 +01:00
|
|
|
int
|
|
|
|
|
keyboard_recv(uint16_t key)
|
|
|
|
|
{
|
2022-09-18 17:13:28 -04:00
|
|
|
return recv_key[key];
|
2017-12-31 06:37:19 +01:00
|
|
|
}
|
|
|
|
|
|
2024-08-07 06:11:50 +02:00
|
|
|
int
|
|
|
|
|
keyboard_recv_ui(uint16_t key)
|
|
|
|
|
{
|
|
|
|
|
return recv_key_ui[key];
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-13 22:47:42 +02:00
|
|
|
/* Do we have Control-Alt-PgDn in the keyboard buffer? */
|
|
|
|
|
int
|
|
|
|
|
keyboard_isfsenter(void)
|
|
|
|
|
{
|
2024-08-07 06:11:50 +02:00
|
|
|
return ((recv_key_ui[0x01d] || recv_key_ui[0x11d]) && (recv_key_ui[0x038] || recv_key_ui[0x138]) && (recv_key_ui[0x049] || recv_key_ui[0x149]));
|
2023-04-13 22:47:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
2023-07-24 15:07:08 -03:00
|
|
|
keyboard_isfsenter_up(void)
|
2023-04-13 22:47:42 +02:00
|
|
|
{
|
2024-08-07 06:11:50 +02:00
|
|
|
return (!recv_key_ui[0x01d] && !recv_key_ui[0x11d] && !recv_key_ui[0x038] && !recv_key_ui[0x138] && !recv_key_ui[0x049] && !recv_key_ui[0x149]);
|
2023-04-13 22:47:42 +02:00
|
|
|
}
|
|
|
|
|
|
2017-10-24 22:10:21 -04:00
|
|
|
/* Do we have Control-Alt-PgDn in the keyboard buffer? */
|
|
|
|
|
int
|
|
|
|
|
keyboard_isfsexit(void)
|
|
|
|
|
{
|
2024-08-07 06:11:50 +02:00
|
|
|
return ((recv_key_ui[0x01d] || recv_key_ui[0x11d]) && (recv_key_ui[0x038] || recv_key_ui[0x138]) && (recv_key_ui[0x051] || recv_key_ui[0x151]));
|
2023-04-13 22:47:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
2023-07-24 15:07:08 -03:00
|
|
|
keyboard_isfsexit_up(void)
|
2023-04-13 22:47:42 +02:00
|
|
|
{
|
2024-08-07 06:11:50 +02:00
|
|
|
return (!recv_key_ui[0x01d] && !recv_key_ui[0x11d] && !recv_key_ui[0x038] && !recv_key_ui[0x138] && !recv_key_ui[0x051] && !recv_key_ui[0x151]);
|
2017-10-24 22:10:21 -04:00
|
|
|
}
|
|
|
|
|
|
2023-10-12 04:52:53 +02:00
|
|
|
/* Do we have the mouse uncapture combination in the keyboard buffer? */
|
2017-10-24 22:10:21 -04:00
|
|
|
int
|
|
|
|
|
keyboard_ismsexit(void)
|
|
|
|
|
{
|
2023-10-12 05:08:11 +02:00
|
|
|
if ((key_prefix_2_1 != 0x000) || (key_prefix_2_2 != 0x000))
|
2024-08-07 06:11:50 +02:00
|
|
|
return ((recv_key_ui[key_prefix_1_1] || recv_key_ui[key_prefix_1_2]) &&
|
|
|
|
|
(recv_key_ui[key_prefix_2_1] || recv_key_ui[key_prefix_2_2]) &&
|
|
|
|
|
(recv_key_ui[key_uncapture_1] || recv_key_ui[key_uncapture_2]));
|
2023-10-12 05:08:11 +02:00
|
|
|
else
|
2024-08-07 06:11:50 +02:00
|
|
|
return ((recv_key_ui[key_prefix_1_1] || recv_key_ui[key_prefix_1_2]) &&
|
|
|
|
|
(recv_key_ui[key_uncapture_1] || recv_key_ui[key_uncapture_2]));
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
2024-12-31 00:48:50 +01:00
|
|
|
|
|
|
|
|
/* This is so we can disambiguate scan codes that would otherwise conflict and get
|
|
|
|
|
passed on incorrectly. */
|
|
|
|
|
uint16_t
|
|
|
|
|
convert_scan_code(uint16_t scan_code)
|
|
|
|
|
{
|
|
|
|
|
if ((scan_code & 0xff00) == 0xe000)
|
|
|
|
|
scan_code = (scan_code & 0xff) | 0x0100;
|
|
|
|
|
|
|
|
|
|
if (scan_code == 0xE11D)
|
|
|
|
|
scan_code = 0x0100;
|
|
|
|
|
/* E0 00 is sent by some USB keyboards for their special keys, as it is an
|
|
|
|
|
invalid scan code (it has no untranslated set 2 equivalent), we mark it
|
|
|
|
|
appropriately so it does not get passed through. */
|
|
|
|
|
else if ((scan_code > 0x01FF) || (scan_code == 0x0100))
|
|
|
|
|
scan_code = 0xFFFF;
|
|
|
|
|
|
|
|
|
|
return scan_code;
|
|
|
|
|
}
|