]> xenbits.xensource.com Git - xenclient/ioemu.git/commitdiff
- Improve dom0_driver for the switching.
authorJean Guyader <jean.guyader@eu.citrix.com>
Tue, 9 Dec 2008 01:41:12 +0000 (01:41 +0000)
committerJean Guyader <jean.guyader@eu.citrix.com>
Tue, 9 Dec 2008 01:41:12 +0000 (01:41 +0000)
 - Add xenmgr support for SAS.

dom0_driver.c

index 3ce5a4750acde3c74e512104549b609c68acdb41..ed2bf9d0c2c74790b20994e64712c36b0c67203d 100644 (file)
@@ -43,6 +43,7 @@
 #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);
@@ -67,6 +68,7 @@ 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
 {
@@ -75,7 +77,6 @@ struct dom0_driver
     int mouse_button_state;
     QEMUTimer *xs_timer;
     uint8_t scroll_lock_count;
-    int windows_down;
     int key_status[256];
 };
 
@@ -102,6 +103,24 @@ static int dom0_driver_xs_read_dom0(const char *key)
     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)
 {
@@ -166,9 +185,8 @@ static int dom0_windows_key_switch(int code, int keycode)
     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:
@@ -198,21 +216,15 @@ static int dom0_windows_key_switch(int code, int keycode)
         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 */
@@ -227,29 +239,49 @@ static void dom0_key_inject(int code, uint32_t keycode)
         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);
 }
@@ -289,6 +321,66 @@ static void dom0_get_positions(int *positions)
     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];
@@ -339,10 +431,15 @@ static void dom0_read(void *opaque)
             {
                 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)
                 {
@@ -361,8 +458,8 @@ static void dom0_read(void *opaque)
                     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);
@@ -370,46 +467,61 @@ static void dom0_read(void *opaque)
     }
 }
 
+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);
@@ -455,20 +567,9 @@ static int dom0_driver_failover_switch(void *opaque)
     {
         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;
@@ -642,7 +743,6 @@ static void dom0_driver_blank_done(void)
 
     if (info.state == 1 && blank == 2)
     {
-        sleep(1);
         if (!vga_passthrough)
             intel_focus(info.domid == domid);
     }
@@ -664,12 +764,18 @@ static void dom0_driver_state_change(const char *path, void *opaque)
         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);
+            }
         }
     }
 }
@@ -679,4 +785,5 @@ void dom0_driver_init(const char *position)
     memset(&driver, 0, sizeof (driver));
     dom0_driver_event_init(position);
     dom0_driver_failover_switch(NULL);
+    DEBUG("done\n");
 }