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.
break;
case CONFITEM_KEYBOARD:
get_next_string(parse_line, cur_cmd, &str_pos, ' ');
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];
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, ' ');
break;
case CONFITEM_KBFILE:
get_next_string(parse_line, cur_cmd, &str_pos, ' ');
char *mouse_file, *keyboard_file;
char mouse_toggle_key, keyboard_toggle_key;
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;
unsigned int loop_cycles;
unsigned int mapped_low, mapped_high;
# 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.
# 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.
+# 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.
# 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.
}
void *keyboard_task() {
}
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");
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;
- 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;
}
// 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;
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;
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);
if (queue_keypress(c_code, c_type, cfg->platform->id) && int2_enabled && last_irq != 2) {
//last_irq = 0;
//M68K_SET_IRQ(2);
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
queued_keypresses--;
return;
}
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;
+}
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 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);