#include <time.h>
extern int vga_passthrough;
+extern int kbd_passthrough;
static void dom0_driver_state_change(const char *path, void *opaque);
static void dom0_driver_command(const char *path, void *opaque);
static void dom0_read(void *opaque);
static void dom0_driver_reset_keyboard(void);
+static void dom0_read_secure(void *opaque);
struct dom0_driver
{
int mouse_button_state;
QEMUTimer *xs_timer;
uint8_t scroll_lock_count;
- int windows_down;
int key_status[256];
};
return strtol(str, NULL, 10);
}
+static void dom0_driver_redirect_fds(IOHandler *callback)
+{
+ int *fd = 0;
+
+ fd = driver.keyboard_fds;
+ while (*fd != -1)
+ {
+ qemu_set_fd_handler(*fd, callback, NULL, fd);
+ fd++;
+ }
+ fd = driver.mouse_fds;
+ while (*fd != -1)
+ {
+ qemu_set_fd_handler(*fd, callback, NULL, fd);
+ fd++;
+ }
+}
+
static void dom0_driver_read_xs_info(struct dom0_driver_xs_info *info,
int controller)
{
if (info.state == 0)
return 0;
- if (driver.windows_down && keycode != KEY_LEFTCTRL)
+ if (driver.key_status[KEY_LEFTCTRL] && keycode != KEY_LEFTCTRL)
{
- driver.windows_down = 0;
switch (keycode)
{
case KEY_1:
return 1;
}
- if (keycode == KEY_LEFTCTRL)
- {
- if (code == 1)
- {
- DEBUG("left ctrl key is down\n");
- driver.windows_down = 1;
- }
- else
- driver.windows_down = 0;
- }
return 0;
}
static void dom0_key_inject(int code, uint32_t keycode)
{
+ int first = 0;
+
+ driver.key_status[keycode] = code;
+
switch (keycode)
{
case KEY_F11: keycode = 0X57; break; /* F11 */
case KEY_LEFT: keycode = 0X4B; break;
case KEY_DOWN: keycode = 0X50; break;
case KEY_RIGHT: keycode = 0X4D; break;
- case KEY_RIGHTALT: keycode = 0x38 | 0x80; break;
- case KEY_LEFTMETA: keycode = 0x5B | 0x80; break;
- case KEY_RIGHTMETA: keycode = 0x5C | 0x80; break;
+ case KEY_RIGHTALT: keycode = 0x38; first = 0xe0; break;
+ case KEY_LEFTMETA: keycode = 0x5B; first = 0xe0; break;
+ case KEY_RIGHTMETA: keycode = 0x5C; first = 0xe0; break;
}
- if (keycode & 0x80)
- kbd_put_keycode(0xe0);
+ if (first)
+ kbd_put_keycode(first);
- if (code == 1)
- kbd_put_keycode(keycode & 0x7f);
- else
+ if (code == 0)
kbd_put_keycode(keycode | 0x80);
+ else
+ kbd_put_keycode(keycode & 0x7f);
+}
+
+static void dom0_driver_detect_secure_auth(int keycode)
+{
+ if ((driver.key_status[KEY_LEFTCTRL] || driver.key_status[KEY_RIGHTCTRL]) &&
+ (driver.key_status[KEY_LEFTALT] || driver.key_status[KEY_RIGHTALT]) &&
+ (driver.key_status[KEY_BACKSPACE]))
+ {
+ struct stat s;
+
+ DEBUG("Received SAS keystroke\n");
+ if (stat("/var/lib/xenmgr/keys", &s) != 0)
+ dom0_driver_redirect_fds(dom0_read_secure);
+ else
+ DEBUG("xenmgr file is not there\n");
+ }
}
static void dom0_key_event(int code, uint32_t keycode)
{
int shift_keys = 0;
uint8_t esc = 0;
-
- driver.key_status[keycode] = code == 1;
+ struct dom0_driver_xs_info keyboard;
if (code != 2)
- dom0_windows_key_switch(code, keycode);
+ {
+ if (dom0_windows_key_switch(code, keycode))
+ return;
+ if (vga_passthrough)
+ dom0_driver_detect_secure_auth(keycode);
+ }
dom0_key_inject(code, keycode);
}
free(domids);
}
+static const int ascii2keycode_table[] =
+{
+ KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, KEY_H, KEY_I, KEY_J, KEY_K,
+ KEY_L, KEY_M, KEY_N, KEY_M, KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U,
+ KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z
+};
+
+static char keycode2ascii(int keycode)
+{
+ int i = 0;
+
+ for (i = 0; i < sizeof (ascii2keycode_table) / sizeof (int); i++)
+ if (ascii2keycode_table[i] == keycode)
+ return i + 'a';
+ return 0;
+}
+
+static int ascii2keycode(char ascii)
+{
+ return ascii2keycode_table[ascii - 'a'];
+}
+
+static void dom0_read_secure(void *opaque)
+{
+ int fd = *(int *)opaque;
+ struct input_event event[5];
+ int read_sz, i;
+ char ascii = 0;
+
+ read_sz = read(fd, event, sizeof (event));
+ for (i = 0; i < read_sz / sizeof (struct input_event); i++)
+ if (event[i].type == EV_KEY && event[i].value)
+ {
+ switch (event[i].code)
+ {
+ case KEY_ESC: ascii = 27; break;
+ case KEY_BACKSPACE: ascii = 8; break;
+ case KEY_ENTER: ascii = 10; break;
+ case KEY_LEFT: ascii = 17; break;
+ case KEY_RIGHT: ascii = 18; break;
+ case KEY_DELETE: ascii = 127; break;
+ case KEY_HOME: ascii = 2; break;
+ case KEY_END: ascii = 3; break;
+ case KEY_INSERT: ascii = 19; break;
+ case KEY_SPACE: ascii = 20; break;
+ default:
+ ascii = keycode2ascii(event[i].code);
+ }
+ DEBUG("Send %d to xenmgr (keycode was %d)\n", ascii, event[i].code);
+ if (event[i].code == KEY_ESC)
+ break;
+ }
+ if (read_sz <= 0 || event[i].code == KEY_ESC)
+ {
+ dom0_driver_reset_keyboard();
+ dom0_driver_redirect_fds(dom0_read);
+ return;
+ }
+}
+
static void dom0_read(void *opaque)
{
struct input_event event[5];
{
static int last_x = 1, last_y = 1;
int px = 0, py = 0, l = 50;
- char *str = xenstore_read_dom0_driver("touchpad-limit");
+ double div = 1;
+ char *str = NULL;
+ str = xenstore_read_dom0_driver("touchpad-limit");
if (str)
l = strtol(str, NULL, 10);
+ str = xenstore_read_dom0_driver("touchpad-div");
+ if (str)
+ div = strtol(str, NULL, 10) / 1000.;
switch (event[i].code)
{
last_y = y;
}
- x = ABS(px) < l ? px : 0;
- y = ABS(py) < l ? py : 0;
+ x = (ABS(px) < l ? px : 0) / div;
+ y = (ABS(py) < l ? py : 0) / div;
}
kbd_mouse_event(x, y, z, driver.mouse_button_state);
}
}
+int pt_i8042_grab(int aux, int grab);
+int kbd_host_grab(int aux, int grab);
static void dom0_gr_devices(int grab, int controller)
{
- char *tmp;
- int id;
- int *fd = NULL;
+ int st = 0;
+ int *fd = 0;
+ int (*fn_grab)(int, int) = NULL;
- if (controller == DOM0_MOUSE)
- fd = driver.mouse_fds;
- if (controller == DOM0_KEYBOARD)
- fd = driver.keyboard_fds;
- assert(fd != NULL);
+ if (kbd_passthrough == 2)
+ fn_grab = pt_i8042_grab;
+ else if (kbd_passthrough == 1)
+ fn_grab = kbd_host_grab;
- for (; *fd != -1; fd++)
+ if (fn_grab)
{
- if (ioctl(*fd, EVIOCGRAB, grab) == -1)
- {
- DEBUG("Try to %s on %d\n", 1 ? "grab" : "release", *fd);
- return;
- }
- DEBUG("%s succed %d\n", grab ? "grab" : "release", *fd);
-
- if (grab)
- qemu_set_fd_handler(*fd, dom0_read, NULL, fd);
+ if (controller == DOM0_MOUSE)
+ st = fn_grab(1, grab);
else
- qemu_set_fd_handler(*fd, NULL, NULL, fd);
+ st = fn_grab(0, grab);
}
-
- if (controller == DOM0_MOUSE)
+ else
{
- if (!vga_passthrough)
+ if (controller == DOM0_MOUSE)
+ fd = driver.mouse_fds;
+ if (controller == DOM0_KEYBOARD)
+ fd = driver.keyboard_fds;
+ assert(fd != NULL);
+
+ while (*fd != -1)
{
- struct dom0_driver_xs_info info;
+ if (ioctl(*fd, EVIOCGRAB, grab) == -1)
+ {
+ DEBUG("Try to %s on %d\n", 1 ? "grab" : "release", *fd);
+ return;
+ }
+ DEBUG("%s succed %d\n", grab ? "grab" : "release", *fd);
- dom0_driver_read_xs_info(&info, DOM0_MOUSE);
- if (!vga_passthrough &&
- dom0_driver_xs_read_dom0("natif") != info.domid)
- intel_focus(!grab);
+ if (grab)
+ qemu_set_fd_handler(*fd, dom0_read, NULL, fd);
+ else
+ qemu_set_fd_handler(*fd, NULL, NULL, fd);
+ fd++;
}
}
+ if (controller == DOM0_MOUSE && !vga_passthrough)
+ {
+ struct dom0_driver_xs_info info;
+
+ dom0_driver_read_xs_info(&info, DOM0_MOUSE);
+ if (!vga_passthrough &&
+ dom0_driver_xs_read_dom0("natif") != info.domid)
+ intel_focus(!grab);
+ }
+
dom0_driver_reset_keyboard();
dom0_driver_xs_write("state", grab ? 1 : 2, controller);
dom0_driver_xs_write("domid", domid, controller);
{
DEBUG("steal the focus from %d\n", mouse.domid);
dom0_gr_devices(1, DOM0_KEYBOARD);
- dom0_gr_devices(1, DOM0_MOUSE);
- goto out;
- }
-
- /* The domain is still alive but nobody grab the device
- ** on the other side after 3 secondes */
- if (keyboard.state == 0 && keyboard.timestamp != -1 &&
- (time(NULL) - keyboard.timestamp) > 3)
- dom0_gr_devices(1, DOM0_KEYBOARD);
- if (mouse.state == 0 && keyboard.timestamp == -1 &&
- (time(NULL) - mouse.timestamp) > 3)
- {
dom0_gr_devices(1, DOM0_MOUSE);
xenstore_write_dom0_driver("blank", "0");
+ goto out;
}
ret = 0;
if (info.state == 1 && blank == 2)
{
- sleep(1);
if (!vga_passthrough)
intel_focus(info.domid == domid);
}
dom0_driver_read_xs_info(&mouse, DOM0_MOUSE);
dom0_driver_read_xs_info(&keyboard, DOM0_KEYBOARD);
- if (vga_passthrough && mouse.state == 1 && keyboard.state == 1)
+ if (mouse.state == 1 && keyboard.state == 1)
{
char str[20];
- sprintf(str, "%d", !(mouse.domid == domid));
- xenstore_write_dom0_driver("blank", str);
+ if (!vga_passthrough && intel_getfocus()) {
+ intel_focus(0);
+ sprintf(str, "%d", !(mouse.domid == dom0_driver_xs_read_dom0("natif")));
+ xenstore_write_dom0_driver("blank", str);
+ } else if (vga_passthrough && mouse.domid != dom0_driver_xs_read_dom0("natif")) {
+ sprintf(str, "%d", !(mouse.domid == domid));
+ xenstore_write_dom0_driver("blank", str);
+ }
}
}
}
memset(&driver, 0, sizeof (driver));
dom0_driver_event_init(position);
dom0_driver_failover_switch(NULL);
+ DEBUG("done\n");
}