mirror of
https://github.com/captain-amygdala/pistorm.git
synced 2026-01-28 04:37:39 +00:00
support stealing the keyboard from the input layer
this change uses an ioctl to disconnect the keyboard event device from the input layer, meaning input no longer affects the pi and will entirely be consumed by the pistorm emulator process.
This commit is contained in:
@@ -355,9 +355,11 @@ struct emulator_config *load_config_file(char *filename) {
|
||||
break;
|
||||
case CONFITEM_KEYBOARD:
|
||||
get_next_string(parse_line, cur_cmd, &str_pos, ' ');
|
||||
cfg->keyboard_file = (char *)calloc(1, strlen(cur_cmd) + 1);
|
||||
cfg->keyboard_toggle_key = cur_cmd[0];
|
||||
printf("Enabled keyboard event forwarding, toggle key %c.\n", cfg->keyboard_toggle_key);
|
||||
get_next_string(parse_line, cur_cmd, &str_pos, ' ');
|
||||
cfg->keyboard_grab = (strcmp(cur_cmd, "grab") == 0) ? 1 : 0;
|
||||
printf("Enabled keyboard event forwarding, toggle key %c, %slocking from host.\n",
|
||||
cfg->keyboard_toggle_key, cfg->keyboard_grab ? "" : "not ");
|
||||
break;
|
||||
case CONFITEM_KBFILE:
|
||||
get_next_string(parse_line, cur_cmd, &str_pos, ' ');
|
||||
|
||||
@@ -68,7 +68,7 @@ struct emulator_config {
|
||||
char *mouse_file, *keyboard_file;
|
||||
|
||||
char mouse_toggle_key, keyboard_toggle_key;
|
||||
unsigned char mouse_enabled, keyboard_enabled;
|
||||
unsigned char mouse_enabled, keyboard_enabled, keyboard_grab;
|
||||
|
||||
unsigned int loop_cycles;
|
||||
unsigned int mapped_low, mapped_high;
|
||||
|
||||
@@ -46,7 +46,9 @@ platform amiga
|
||||
# Syntax is mouse [device] [toggle key]
|
||||
#mouse /dev/input/mouse0 m
|
||||
# Forward keyboard events to host system, defaults to off unless toggle key is pressed, toggled off using F12.
|
||||
#keyboard k
|
||||
# Add the keyword "grab" to steal the keyboard from the Pi, so Amiga input does not appear on the console or in X11.
|
||||
# (also helps prevent sending any ctrl-alt-del to the Amiga from resetting the Pi)
|
||||
keyboard k grab
|
||||
# Select a specific filename for the keyboard event source.
|
||||
# This is typically /dev/input/event1 or event0, but it may be event3 with for instance a wireless keyboard.
|
||||
# Use ls /dev/input/event* to check which event files are available and try until you find the one that works.
|
||||
|
||||
42
emulator.c
42
emulator.c
@@ -263,39 +263,53 @@ cpu_loop:
|
||||
}
|
||||
|
||||
void *keyboard_task() {
|
||||
struct pollfd kbdfd[1];
|
||||
int kpoll;
|
||||
struct pollfd kbdpoll[1];
|
||||
int kpollrc;
|
||||
char grab_message[] = "[KBD] Grabbing keyboard from input layer\n",
|
||||
ungrab_message[] = "[KBD] Ungrabbing keyboard\n";
|
||||
|
||||
printf("[KBD] Keyboard thread started\n");
|
||||
|
||||
kbdfd[0].fd = keyboard_fd;
|
||||
kbdfd[0].events = POLLIN;
|
||||
// because we permit the keyboard to be grabbed on startup, quickly check if we need to grab it
|
||||
if (kb_hook_enabled && cfg->keyboard_grab) {
|
||||
printf(grab_message);
|
||||
grab_device(keyboard_fd);
|
||||
}
|
||||
|
||||
kbdpoll[0].fd = keyboard_fd;
|
||||
kbdpoll[0].events = POLLIN;
|
||||
|
||||
key_loop:
|
||||
kpoll = poll(kbdfd, 1, KEY_POLL_INTERVAL_MSEC);
|
||||
if ((kpoll > 0) && (kbdfd[0].revents & POLLHUP)) {
|
||||
kpollrc = poll(kbdpoll, 1, KEY_POLL_INTERVAL_MSEC);
|
||||
if ((kpollrc > 0) && (kbdpoll[0].revents & POLLHUP)) {
|
||||
// in the event that a keyboard is unplugged, keyboard_task will whiz up to 100% utilisation
|
||||
// this is undesired, so if the keyboard HUPs, end the thread without ending the emulation
|
||||
printf("[KBD] Keyboard node returned HUP (unplugged?)\n");
|
||||
goto key_end;
|
||||
}
|
||||
|
||||
// if kpoll > 0 then it contains number of events to pull, also check if POLLIN is set in revents
|
||||
if ((kpoll <= 0) || !(kbdfd[0].revents & POLLIN)) {
|
||||
// if kpollrc > 0 then it contains number of events to pull, also check if POLLIN is set in revents
|
||||
if ((kpollrc <= 0) || !(kbdpoll[0].revents & POLLIN)) {
|
||||
goto key_loop;
|
||||
}
|
||||
|
||||
while (get_key_char(&c, &c_code, &c_type)) {
|
||||
if (c && c == cfg->keyboard_toggle_key && !kb_hook_enabled) {
|
||||
kb_hook_enabled = 1;
|
||||
printf("Keyboard hook enabled.\n");
|
||||
}
|
||||
else if (kb_hook_enabled) {
|
||||
printf("[KBD] Keyboard hook enabled.\n");
|
||||
if (cfg->keyboard_grab) {
|
||||
grab_device(keyboard_fd);
|
||||
printf(grab_message);
|
||||
}
|
||||
} else if (kb_hook_enabled) {
|
||||
if (c == 0x1B && c_type) {
|
||||
kb_hook_enabled = 0;
|
||||
printf("Keyboard hook disabled.\n");
|
||||
}
|
||||
else {
|
||||
printf("[KBD] Keyboard hook disabled.\n");
|
||||
if (cfg->keyboard_grab) {
|
||||
release_device(keyboard_fd);
|
||||
printf(ungrab_message);
|
||||
}
|
||||
} else {
|
||||
if (queue_keypress(c_code, c_type, cfg->platform->id) && int2_enabled && last_irq != 2) {
|
||||
//last_irq = 0;
|
||||
//M68K_SET_IRQ(2);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <linux/input.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -211,3 +212,15 @@ void pop_queued_key(uint8_t *c, uint8_t *t) {
|
||||
queued_keypresses--;
|
||||
return;
|
||||
}
|
||||
|
||||
int grab_device(int fd) {
|
||||
int rc = 0;
|
||||
rc = ioctl(fd, EVIOCGRAB, (void *)1);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int release_device(int fd) {
|
||||
int rc = 0;
|
||||
rc = ioctl(fd, EVIOCGRAB, (void *)0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -11,3 +11,5 @@ int get_key_char(char *c, char *code, char *event_type);
|
||||
int queue_keypress(uint8_t keycode, uint8_t event_type, uint8_t platform);
|
||||
int get_num_kb_queued();
|
||||
void pop_queued_key(uint8_t *c, uint8_t *t);
|
||||
int grab_device(int fd);
|
||||
int release_device(int fd);
|
||||
|
||||
Reference in New Issue
Block a user