virtio-keyboard: add virtio-keyboard device.
authorKitae Kim <kt920.kim@samsung.com>
Fri, 26 Oct 2012 07:01:03 +0000 (16:01 +0900)
committerKitae Kim <kt920.kim@samsung.com>
Fri, 26 Oct 2012 07:11:04 +0000 (16:11 +0900)
Implement virtio-keyboard to replace usb-keyboard module,
because of performance issue on emulator.
However, virtio-keyboard menu has not enabled yet.
It needs to test a lot.

Signed-off-by: Kitae Kim <kt920.kim@samsung.com>
17 files changed:
hw/pci-hotplug.c
hw/virtio-pci.c
input.c
tizen/src/Makefile.tizen
tizen/src/hw/maru_device_ids.h
tizen/src/hw/maru_virtio_keyboard.c [new file with mode: 0644]
tizen/src/hw/maru_virtio_keyboard.h [new file with mode: 0644]
tizen/src/hw/maru_virtio_touchscreen.c
tizen/src/mloop_event.c
tizen/src/mloop_event.h
tizen/src/skin/client/resource/icons/host_keyboard.png [new file with mode: 0644]
tizen/src/skin/client/src/org/tizen/emulator/skin/EmulatorSkin.java
tizen/src/skin/client/src/org/tizen/emulator/skin/comm/ICommunicator.java
tizen/src/skin/client/src/org/tizen/emulator/skin/image/ImageRegistry.java
tizen/src/skin/maruskin_operation.c
tizen/src/skin/maruskin_operation.h
tizen/src/skin/maruskin_server.c

index 12f61fe..f7d8d6f 100644 (file)
@@ -232,6 +232,35 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon,
     return dev;
 }
 
+#ifdef CONFIG_MARU
+static PCIDevice *qemu_pci_hot_add_keyboard(Monitor *mon,
+                                           const char *devaddr,
+                                           const char *opts)
+{
+    PCIDevice *dev;
+    PCIBus *bus;
+    int devfn;
+
+    bus = pci_get_bus_devfn(&devfn, devaddr);
+    if (!bus) {
+        monitor_printf(mon, "Invalid PCI device address %s\n", devaddr);
+        return NULL;
+    }
+
+    if (!((BusState*)bus)->allow_hotplug) {
+        monitor_printf(mon, "PCI bus doesn't support hotplug\n");
+        return NULL;
+    }
+
+    dev = pci_create(bus, devfn, "virtio-keyboard-pci");
+    if (qdev_init(&dev->qdev) < 0) {
+        dev = NULL;
+    }
+
+    return dev;
+}
+#endif /* CONFIG_MARU */
+
 void pci_device_hot_add(Monitor *mon, const QDict *qdict)
 {
     PCIDevice *dev = NULL;
@@ -255,6 +284,12 @@ void pci_device_hot_add(Monitor *mon, const QDict *qdict)
         dev = qemu_pci_hot_add_nic(mon, pci_addr, opts);
     } else if (strcmp(type, "storage") == 0) {
         dev = qemu_pci_hot_add_storage(mon, pci_addr, opts);
+#ifdef CONFIG_MARU
+    } else if (strcmp(type, "keyboard") == 0) {
+        printf("virtio-keyboard: pci_addr %s, type %s, opts %s\n",
+                pci_addr, type, opts);
+        dev = qemu_pci_hot_add_keyboard(mon, pci_addr, opts);
+#endif
     } else {
         monitor_printf(mon, "invalid type: %s\n", type);
     }
index 8645edd..b14a77d 100644 (file)
@@ -31,6 +31,7 @@
 #include "range.h"
 #ifdef CONFIG_MARU
 #include "../tizen/src/hw/maru_device_ids.h"
+#include "../tizen/src/mloop_event.h"
 #endif
 
 /* from Linux's linux/virtio_pci.h */
@@ -287,10 +288,10 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
 
     switch (addr) {
     case VIRTIO_PCI_GUEST_FEATURES:
-       /* Guest does not negotiate properly?  We have to assume nothing. */
-       if (val & (1 << VIRTIO_F_BAD_FEATURE)) {
+    /* Guest does not negotiate properly?  We have to assume nothing. */
+    if (val & (1 << VIRTIO_F_BAD_FEATURE)) {
             val = vdev->bad_features ? vdev->bad_features(vdev) : 0;
-       }
+    }
         virtio_set_features(vdev, val);
         break;
     case VIRTIO_PCI_QUEUE_PFN:
@@ -823,6 +824,31 @@ static int maru_virtio_touchscreen_exit_pci(PCIDevice *pci_dev)
 }
 #endif
 
+#ifdef CONFIG_MARU
+static int virtio_keyboard_init_pci(PCIDevice *pci_dev)
+{
+    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
+    VirtIODevice *vdev;
+
+    mloop_evcmd_set_hostkbd(pci_dev);
+    vdev = virtio_keyboard_init(&pci_dev->qdev);
+    if (!vdev) {
+        return -1;
+    }
+    virtio_init_pci(proxy, vdev);
+    return 0;
+}
+
+static int virtio_keyboard_exit_pci(PCIDevice *pci_dev)
+{
+    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
+
+    virtio_pci_stop_ioeventfd(proxy);
+    virtio_keyboard_exit(proxy->vdev);
+    return virtio_exit_pci(pci_dev);
+}
+#endif
+
 
 static PCIDeviceInfo virtio_info[] = {
     {
@@ -910,20 +936,20 @@ static PCIDeviceInfo virtio_info[] = {
         .qdev.reset = virtio_pci_reset,
     },{
 #if defined(CONFIG_MARU) && (!defined(CONFIG_DARWIN))
-               .qdev.name = "virtio-gl-pci",
+        .qdev.name = "virtio-gl-pci",
         .qdev.alias = "virtio-gl",
-               .qdev.size = sizeof(VirtIOPCIProxy),
-               .init      = virtio_gl_init_pci,
-               .exit      = virtio_exit_pci,
+        .qdev.size = sizeof(VirtIOPCIProxy),
+        .init      = virtio_gl_init_pci,
+        .exit      = virtio_exit_pci,
         .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
         .device_id = PCI_DEVICE_ID_VIRTIO_GL,
         .revision  = VIRTIO_PCI_ABI_VERSION,
         .class_id  = PCI_CLASS_OTHERS,
-               .qdev.props = (Property[]) {
-                       DEFINE_PROP_END_OF_LIST(),
-               },
-               .qdev.reset = virtio_pci_reset,
-       },{
+        .qdev.props = (Property[]) {
+            DEFINE_PROP_END_OF_LIST(),
+        },
+        .qdev.reset = virtio_pci_reset,
+    },{
 #endif
 
 #ifdef CONFIG_MARU
@@ -943,6 +969,22 @@ static PCIDeviceInfo virtio_info[] = {
     },{
 #endif
 
+#ifdef CONFIG_MARU
+        .qdev.name = "virtio-keyboard-pci",
+        .qdev.alias = "virtio-keyboard",
+        .qdev.size = sizeof(VirtIOPCIProxy),
+        .init      = virtio_keyboard_init_pci,
+        .exit      = virtio_keyboard_exit_pci,
+        .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
+        .device_id = PCI_DEVICE_ID_VIRTIO_KEYBOARD,
+        .revision  = VIRTIO_PCI_ABI_VERSION,
+        .class_id  = PCI_CLASS_OTHERS,
+        .qdev.props = (Property[]) {
+            DEFINE_PROP_END_OF_LIST(),
+        },
+        .qdev.reset = virtio_pci_reset,
+    },{
+#endif
         /* end of list */
     }
 };
diff --git a/input.c b/input.c
index ad57eb4..c3bb673 100644 (file)
--- a/input.c
+++ b/input.c
@@ -57,7 +57,7 @@ void qemu_remove_kbd_event_handler(void)
 }
 
 #ifdef CONFIG_MARU
-
+/* use ps2kbd device as a hardkey device. */
 void qemu_add_ps2kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
 {
     qemu_put_ps2kbd_event_opaque = opaque;
@@ -76,7 +76,6 @@ void ps2kbd_put_keycode(int keycode)
         qemu_put_ps2kbd_event(qemu_put_ps2kbd_event_opaque, keycode);
     }
 }
-
 #endif
 
 static void check_mode_change(void)
index d4596c9..f898cd0 100755 (executable)
@@ -89,6 +89,7 @@ obj-i386-y += maru_pm.o
 obj-i386-y += maru_vga.o
 obj-i386-y += maru_brightness.o
 obj-i386-y += maru_usb_touchscreen.o maru_virtio_touchscreen.o
+obj-i386-y += maru_virtio_keyboard.o
 
 # FIXME: camera disabled
 ifndef CONFIG_DARWIN
index 9d61c6e..0049917 100644 (file)
@@ -47,8 +47,9 @@
 #define PCI_DEVICE_ID_VIRTUAL_BRIGHTNESS 0x1014
 #define PCI_DEVICE_ID_VIRTUAL_CAMERA     0x1018
 #define PCI_DEVICE_ID_VIRTUAL_CODEC      0x101C
-// Device ID 0x1000 through 0x103F inclusive is a virtio device
+/* Device ID 0x1000 through 0x103F inclusive is a virtio device */
 #define PCI_DEVICE_ID_VIRTIO_TOUCHSCREEN 0x101D
+#define PCI_DEVICE_ID_VIRTIO_KEYBOARD   0x1020
 
 /* Virtio */
 /*
@@ -77,7 +78,7 @@
 |         10           |   mac80211 wlan    |       -       |
 +----------------------+--------------------+---------------+
 */
-#define VIRTIO_ID_TOUCHSCREEN 11
-
+#define VIRTIO_ID_TOUCHSCREEN   11
+#define VIRTIO_ID_KEYBOARD      12
 
 #endif /* MARU_DEVICE_IDS_H_ */
diff --git a/tizen/src/hw/maru_virtio_keyboard.c b/tizen/src/hw/maru_virtio_keyboard.c
new file mode 100644 (file)
index 0000000..28ba0d9
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Virtio Keyboard Device
+ *
+ * Copyright (c) 2011 - 2012 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  Kitae Kim <kt920.kim@samsung.com>
+ *  SeokYeon Hwang <syeon.hwang@samsung.com>
+ *  YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include "console.h"
+#include "mloop_event.h"
+#include "maru_device_ids.h"
+#include "maru_virtio_keyboard.h"
+#include "tizen/src/debug_ch.h"
+
+MULTI_DEBUG_CHANNEL(qemu, virtio-kbd);
+
+#define VIRTIO_KBD_DEVICE_NAME "virtio-keyboard"
+
+typedef struct EmulKbdEvent
+{
+       uint16_t code;
+       uint16_t type;
+} EmulKbdEvent;
+
+typedef struct VirtIOKeyboard
+{
+    VirtIODevice    vdev;
+    VirtQueue       *vq;
+    DeviceState     *qdev;
+       EmulKbdEvent    kbdevent;
+} VirtIOKeyboard;
+
+VirtQueueElement elem;
+
+static void virtio_keyboard_handle (VirtIODevice *vdev, VirtQueue *vq)
+{
+       VirtIOKeyboard *vkbd = (VirtIOKeyboard *)vdev;
+
+       INFO("virtqueue keyboard handler.\n");
+       if (virtio_queue_empty(vkbd->vq)) {
+               INFO("virtio_keyboard: virtqueue is empty.\n");
+               return;
+       }
+
+       /* Get a queue buffer which is written by guest side. */
+       virtqueue_pop(vq, &elem);
+}
+
+void virtio_keyboard_notify (void *opaque)
+{
+       VirtIOKeyboard *vkbd = (VirtIOKeyboard *)opaque;
+       int len = 0;
+
+       len = sizeof(EmulKbdEvent);
+
+       INFO("virtio_keyboard_notify: code:%d, type:%d\n",
+               vkbd->kbdevent.code, vkbd->kbdevent.type);
+
+       if (!virtio_queue_ready(vkbd->vq)) {
+               INFO("virtio_keyboard: virtqueue is not ready.\n");
+               return;
+       }
+
+       /* Copy keyboard data into guest side. */
+       memcpy(elem.in_sg[0].iov_base, &vkbd->kbdevent, len);
+
+       virtqueue_push(vkbd->vq, &elem, len);
+       virtio_notify(&vkbd->vdev, vkbd->vq);
+}
+
+static void virtio_keyboard_event (void *opaque, int keycode)
+{
+       VirtIOKeyboard *vkbd = opaque;
+
+       if (!(keycode & 0x80)) {
+               vkbd->kbdevent.type = 1;        /* KEY_PRESSED */
+       } else {
+               vkbd->kbdevent.type = 0;        /* KEY_RELEASED */
+       }
+       vkbd->kbdevent.code = keycode & 0x7f;
+
+       INFO("virito_keycode_event: keycode:%d, type:%d\n",
+               vkbd->kbdevent.code, vkbd->kbdevent.type);
+       
+       mloop_evcmd_keyboard(vkbd);
+}
+
+static uint32_t virtio_keyboard_get_features (VirtIODevice *vdev,
+                                                 uint32_t request_feature)
+{
+       INFO("virito_keycode_get_features.\n");
+    return 0;
+}
+
+VirtIODevice *virtio_keyboard_init(DeviceState *dev)
+{
+    VirtIOKeyboard *kbd;
+    INFO("initialize virtio keyboard device\n");
+
+    kbd = (VirtIOKeyboard *)virtio_common_init(VIRTIO_KBD_DEVICE_NAME,
+               VIRTIO_ID_KEYBOARD, 0, sizeof(VirtIOKeyboard));
+
+    if (kbd == NULL) {
+        ERR("failed to initialize the touchscreen device\n");
+        return NULL;
+    }
+
+    kbd->vdev.get_features = virtio_keyboard_get_features;
+    kbd->vq = virtio_add_queue(&kbd->vdev, 64, virtio_keyboard_handle);
+    kbd->qdev = dev;
+
+       /* register keyboard handler */
+       qemu_add_kbd_event_handler(virtio_keyboard_event, kbd);
+
+    return &kbd->vdev;
+}
+
+void virtio_keyboard_exit(VirtIODevice *vdev)
+{
+    INFO("destroy virtio keyboard device\n");
+    virtio_cleanup(vdev);
+}
diff --git a/tizen/src/hw/maru_virtio_keyboard.h b/tizen/src/hw/maru_virtio_keyboard.h
new file mode 100644 (file)
index 0000000..0e4196e
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Virtio Keyboard Device
+ *
+ * Copyright (c) 2011 - 2012 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  Kitae Kim <kt920.kim@samsung.com>
+ *  SeokYeon Hwang <syeon.hwang@samsung.com>
+ *  YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#ifndef VIRTIO_KEYBOARD_H_
+#define VIRTIO_KEYBOARD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "hw.h"
+#include "virtio.h"
+
+VirtIODevice *virtio_keyboard_init(DeviceState *dev);
+
+void virtio_keyboard_exit(VirtIODevice *vdev);
+
+void virtio_keyboard_notify (void *opaque);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* VIRTIO_KEYBOARD_H_ */
index 42b11df..e7b1f4e 100644 (file)
@@ -152,6 +152,8 @@ static void maru_virtio_touchscreen_handle(VirtIODevice *vdev, VirtQueue *vq)
     int sg_index = 0;
     ElementEntry *elem_entry = NULL;
 
+       TRACE("maru_virtio_touchscreen_handle\n");
+
     if (unlikely(virtio_queue_empty(ts->vq))) {
         TRACE("virtqueue is empty\n");
         return;
index aadb33a..ee17346 100644 (file)
 #include "mloop_event.h"
 #include "console.h"
 #include "emul_state.h"
+#include "tizen/src/debug_ch.h"
+#include "monitor.h"
+#include "pci.h"
 
-#define error_report(x, ...)
+MULTI_DEBUG_CHANNEL(qemu, mloop_event);
 
 struct mloop_evsock {
     int sockno;
@@ -69,7 +72,9 @@ struct mloop_evpack {
 #define MLOOP_EVTYPE_INTR_DOWN  4
 #define MLOOP_EVTYPE_HWKEY      5
 #define MLOOP_EVTYPE_TOUCH      6
-
+#define MLOOP_EVTYPE_KEYBOARD   7
+#define MLOOP_EVTYPE_KBD_ADD    8
+#define MLOOP_EVTYPE_KBD_DEL    9
 
 static struct mloop_evsock mloop = {-1, 0, 0};
 
@@ -81,13 +86,13 @@ static int mloop_evsock_create(struct mloop_evsock *ev)
     unsigned long nonblock = 1;
 
     if (ev == NULL) {
-        error_report("mloop_evsock: null point");
+        ERR("null pointer\n");
         return -1;
     }
 
     ev->sockno = socket(AF_INET, SOCK_DGRAM, 0);
-    if( ev->sockno == -1 ) {
-        error_report("mloop_evsock: socket() failed");
+    if ( ev->sockno == -1 ) {
+        ERR("socket() failed\n");
         return -1;
     }
 
@@ -108,7 +113,7 @@ static int mloop_evsock_create(struct mloop_evsock *ev)
 
     ret = bind(ev->sockno, &sa, sa_size);
     if (ret) {
-        error_report("mloop_evsock: bind() failed");
+        ERR("bind() failed\n");
         goto mloop_evsock_init_cleanup;
     }
 
@@ -120,7 +125,7 @@ static int mloop_evsock_create(struct mloop_evsock *ev)
 
     ret = connect(ev->sockno, (struct sockaddr *) &sa, sa_size);
     if (ret) {
-        error_report("mloop_evsock: connect() failed");
+        ERR("connect() failed\n");
         goto mloop_evsock_init_cleanup;
     }
 
@@ -162,12 +167,12 @@ static int mloop_evsock_send(struct mloop_evsock *ev, struct mloop_evpack *p)
     int ret;
 
     if (ev == NULL || ev->sockno == -1) {
-        error_report("invalid mloop_evsock");
+        ERR("invalid mloop_evsock\n");
         return -1;
     }
 
     if (p == NULL || p->size <= 0) {
-        error_report("invalid mloop_evpack");
+        ERR("invalid mloop_evpack\n");
         return -1;
     }
 
@@ -184,30 +189,34 @@ static int mloop_evsock_send(struct mloop_evsock *ev, struct mloop_evpack *p)
 
 static USBDevice *usbkbd = NULL;
 static USBDevice *usbdisk = NULL;
+static PCIDevice *hostkbd = NULL;
+
 static void mloop_evhandle_usb_add(char *name)
 {
     if (name == NULL) {
+        ERR("Packet data for usb device is NULL\n");
         return;
     }
 
     if (strcmp(name, "keyboard") == 0) {
         if (usbkbd == NULL) {
             usbkbd = usbdevice_create(name);
-        }
-        else if (usbkbd->attached == 0) {
+        } else if (usbkbd->attached == 0) {
             usb_device_attach(usbkbd);
         }
-    }
-    else if (strncmp(name, "disk:", 5) == 0) {
+    } else if (strncmp(name, "disk:", 5) == 0) {
         if (usbdisk == NULL) {
             usbdisk = usbdevice_create(name);
         }
-    }
+    } else {
+        WARN("There is no usb-device for %s.\n", name);
+     }
 }
 
 static void mloop_evhandle_usb_del(char *name)
 {
     if (name == NULL) {
+        ERR("Packet data for usb device is NULL\n");
         return;
     }
 
@@ -215,11 +224,12 @@ static void mloop_evhandle_usb_del(char *name)
         if (usbkbd && usbkbd->attached != 0) {
             usb_device_detach(usbkbd);
         }
-    }
-    else if (strncmp(name, "disk:", 5) == 0) {
+    } else if (strncmp(name, "disk:", 5) == 0) {
         if (usbdisk) {
             qdev_free(&usbdisk->qdev);
         }
+    } else {
+        WARN("There is no usb-device for %s.\n", name);
     }
 }
 
@@ -267,6 +277,77 @@ static void mloop_evhandle_touch(struct mloop_evpack* pack)
     maru_virtio_touchscreen_notify();
 }
 
+static void mloop_evhandle_keyboard(long data)
+{
+    virtio_keyboard_notify((void*)data);
+}
+
+static void mloop_evhandle_kbd_add(char *name)
+{
+    TRACE("mloop_evhandle_kbd_add\n");
+
+    if (name == NULL) {
+        ERR("packet data is NULL.\n");
+        return;
+    }
+
+    if (strcmp(name, "keyboard") == 0) {
+        QDict *qdict = qdict_new();
+
+        qdict_put(qdict, "pci_addr", qstring_from_str("auto"));
+        qdict_put(qdict, "type", qstring_from_str(name));
+
+        TRACE("hot_add keyboard device.\n");
+        pci_device_hot_add(cur_mon, qdict);
+
+        if (hostkbd) {
+            TRACE("virtio-keyboard device: domain %d, bus %d, slot %d, function %d\n",
+                    pci_find_domain(hostkbd->bus), pci_bus_num(hostkbd->bus),
+                    PCI_SLOT(hostkbd->devfn), PCI_FUNC(hostkbd->devfn));
+        } else {
+            ERR("failed to hot_add keyboard device.\n");
+        }
+
+        QDECREF(qdict);
+    } else {
+        WARN("There is no %s device.\n", name);
+    }
+}
+
+static void mloop_evhandle_kbd_del(char *name)
+{
+    TRACE("mloop_evhandle_kbd_del\n");
+
+    if (name == NULL) {
+        ERR("packet data is NULL.\n");
+        return;
+    }
+
+    if (strcmp(name, "keyboard") == 0) {
+        QDict *qdict = qdict_new();
+        int slot = 0;
+        char slotbuf[4] = {0,};
+
+        if (hostkbd) {
+            slot = PCI_SLOT(hostkbd->devfn);
+            snprintf(slotbuf, sizeof(slotbuf), "%x", slot);
+            TRACE("virtio-keyboard slot %s.\n", slotbuf);
+        } else {
+            ERR("failed to hot_remove keyboard because hostkbd is NULL.\n");
+            return;
+        }
+
+        qdict_put(qdict, "pci_addr", qstring_from_str(slotbuf));
+
+        TRACE("hot_remove keyboard.\n");
+        do_pci_device_hot_remove(cur_mon, qdict);
+
+        QDECREF(qdict);
+    } else {
+        WARN("There is no %s device.\n", name);
+    }
+}
+
 static void mloop_evcb_recv(struct mloop_evsock *ev)
 {
     struct mloop_evpack pack;
@@ -310,6 +391,15 @@ static void mloop_evcb_recv(struct mloop_evsock *ev)
     case MLOOP_EVTYPE_TOUCH:
         mloop_evhandle_touch(&pack);
         break;
+    case MLOOP_EVTYPE_KEYBOARD:
+        mloop_evhandle_keyboard(ntohl(*(long*)&pack.data[0]));
+        break;
+    case MLOOP_EVTYPE_KBD_ADD:
+        mloop_evhandle_kbd_add(pack.data);
+        break;
+    case MLOOP_EVTYPE_KBD_DEL:
+        mloop_evhandle_kbd_del(pack.data);
+        break;
     default:
         break;
     }
@@ -337,6 +427,16 @@ void mloop_evcmd_usbkbd(int on)
     mloop_evsock_send(&mloop, &pack);
 }
 
+void mloop_evcmd_hostkbd(int on)
+{
+    struct mloop_evpack pack
+        = {htons(MLOOP_EVTYPE_KBD_ADD), htons(13), "keyboard"};
+    if (on == 0) {
+        pack.type = htons(MLOOP_EVTYPE_KBD_DEL);
+    }
+    mloop_evsock_send(&mloop, &pack);
+}
+
 void mloop_evcmd_usbdisk(char *img)
 {
     struct mloop_evpack pack;
@@ -349,8 +449,7 @@ void mloop_evcmd_usbdisk(char *img)
 
         pack.type = htons(MLOOP_EVTYPE_USB_ADD);
         pack.size = htons(5 + sprintf(pack.data, "disk:%s", img));
-    }
-    else {
+    } else {
         pack.type = htons(MLOOP_EVTYPE_USB_DEL);
         pack.size = htons(5 + sprintf(pack.data, "disk:"));
     }
@@ -373,6 +472,11 @@ void mloop_evcmd_set_usbdisk(void *dev)
     usbdisk = (USBDevice *)dev;
 }
 
+void mloop_evcmd_set_hostkbd(void *dev)
+{
+    hostkbd = (PCIDevice *)dev;
+}
+
 void mloop_evcmd_raise_intr(void *irq)
 {
     struct mloop_evpack pack;
@@ -417,3 +521,13 @@ void mloop_evcmd_touch(void)
     mloop_evsock_send(&mloop, &pack);
 }
 
+void mloop_evcmd_keyboard(void *data)
+{
+    struct mloop_evpack pack;
+    memset(&pack, 0, sizeof(struct mloop_evpack));
+
+    pack.type = htons(MLOOP_EVTYPE_KEYBOARD);
+    pack.size = htons(8);
+    *(long*)&pack.data[0] = htonl((long)data);
+    mloop_evsock_send(&mloop, &pack);
+}
index 7fb8434..d7f6954 100644 (file)
@@ -37,17 +37,20 @@ void mloop_ev_stop(void);
 
 void mloop_evcmd_usbkbd(int on);
 void mloop_evcmd_usbdisk(char *img);
+void mloop_evcmd_hostkbd(int on);
 
 int mloop_evcmd_get_usbkbd_status(void);
 
 void mloop_evcmd_set_usbkbd(void *dev);
 void mloop_evcmd_set_usbdisk(void *dev);
+void mloop_evcmd_set_hostkbd(void *dev);
 
 void mloop_evcmd_raise_intr(void *irq);
 void mloop_evcmd_lower_intr(void *irq);
 
 void mloop_evcmd_hwkey(int event_type, int keycode);
 void mloop_evcmd_touch(void);
+void mloop_evcmd_keyboard(void *data);
 
 #ifdef __cplusplus
 }
diff --git a/tizen/src/skin/client/resource/icons/host_keyboard.png b/tizen/src/skin/client/resource/icons/host_keyboard.png
new file mode 100644 (file)
index 0000000..69a87f3
Binary files /dev/null and b/tizen/src/skin/client/resource/icons/host_keyboard.png differ
index 6eaaa75..3c4acca 100644 (file)
@@ -105,7 +105,7 @@ import org.tizen.emulator.skin.util.SkinUtil;
 import org.tizen.emulator.skin.util.SwtUtil;
 
 /**
- * 
+ *
  *
  */
 public class EmulatorSkin {
@@ -133,7 +133,7 @@ public class EmulatorSkin {
        public static final String GTK_OS_CLASS = "org.eclipse.swt.internal.gtk.OS";
        public static final String WIN32_OS_CLASS = "org.eclipse.swt.internal.win32.OS";
        public static final String COCOA_OS_CLASS = "org.eclipse.swt.internal.cocoa.OS";
-       
+
        private Logger logger = SkinLogger.getSkinLogger( EmulatorSkin.class ).getLogger();
 
        protected EmulatorConfig config;
@@ -163,7 +163,7 @@ public class EmulatorSkin {
        private boolean isAboutToReopen;
        private boolean isOnTop;
        private boolean isScreenShotOpened;
-       private boolean isOnUsbKbd;
+       private boolean isOnKbd;
 
        private ScreenShotDialog screenShotDialog;
        private Menu contextMenu;
@@ -238,7 +238,7 @@ public class EmulatorSkin {
        }
 
        private void composeInternal( Canvas lcdCanvas, int x, int y, int lcdWidth, int lcdHeight, int scale,
-                       short rotationId, boolean isOnUsbKbd ) {
+                       short rotationId, boolean isOnKbd ) {
 
                lcdCanvas.setBackground( shell.getDisplay().getSystemColor( SWT.COLOR_BLACK ) );
 
@@ -268,7 +268,7 @@ public class EmulatorSkin {
 
                seteHoverColor();
 
-               this.isOnUsbKbd = isOnUsbKbd;
+               this.isOnKbd = isOnKbd;
                setMenu();
        }
 
@@ -294,7 +294,7 @@ public class EmulatorSkin {
 //
 //             sourceSkin.reopenSkin.composeInternal( sourceSkin.lcdCanvas, previousLocation.x, previousLocation.y,
 //                             sourceSkin.currentLcdWidth, sourceSkin.currentLcdHeight, sourceSkin.currentScale,
-//                             sourceSkin.currentRotationId, sourceSkin.isOnUsbKbd );
+//                             sourceSkin.currentRotationId, sourceSkin.isOnKbd );
 //
 //             sourceSkin.reopenSkin.windowHandleId = sourceSkin.windowHandleId;
 //
@@ -1973,7 +1973,6 @@ public class EmulatorSkin {
                                                        break;
                                                }
                                        }
-                                       // /////////
 
                                        SkinUtil.openMessage( shell, null, "Rotation is not ready.\nPlease, wait.", SWT.ICON_WARNING,
                                                        config );
@@ -2144,51 +2143,99 @@ public class EmulatorSkin {
                        }
                } );
 
-               /* USB Keyboard menu */
-               final MenuItem usbKeyboardItem = new MenuItem( menu, SWT.CASCADE );
-               usbKeyboardItem.setText( "&USB Keyboard" );
-               usbKeyboardItem.setImage( imageRegistry.getIcon( IconName.USB_KEBOARD ) );
+               // USB Keyboard menu
+               final MenuItem usbKeyboardItem = new MenuItem(menu, SWT.CASCADE);
+               usbKeyboardItem.setText("&USB Keyboard");
+               usbKeyboardItem.setImage(imageRegistry.getIcon(IconName.USB_KEYBOARD));
 
-               Menu usbKeyBoardMenu = new Menu( shell, SWT.DROP_DOWN );
+               Menu usbKeyBoardMenu = new Menu(shell, SWT.DROP_DOWN);
 
-               final MenuItem usbOnItem = new MenuItem( usbKeyBoardMenu, SWT.RADIO );
-               usbOnItem.setText( "On" );
-               usbOnItem.setSelection( isOnUsbKbd );
-               
-               final MenuItem usbOffItem = new MenuItem( usbKeyBoardMenu, SWT.RADIO );
-               usbOffItem.setText( "Off" );
-               usbOffItem.setSelection( !isOnUsbKbd );
+               final MenuItem usbOnItem = new MenuItem(usbKeyBoardMenu, SWT.RADIO);
+               usbOnItem.setText("On");
+               usbOnItem.setSelection( isOnKbd );
+
+               final MenuItem usbOffItem = new MenuItem(usbKeyBoardMenu, SWT.RADIO);
+               usbOffItem.setText("Off");
+               usbOffItem.setSelection(!isOnKbd);
 
                SelectionAdapter usbSelectionAdaptor = new SelectionAdapter() {
                        @Override
-                       public void widgetSelected( SelectionEvent e ) {
+                       public void widgetSelected(SelectionEvent e) {
                                if (!communicator.isSensorDaemonStarted()) {
                                        SkinUtil.openMessage(shell, null,
                                                        "USB is not ready.\nPlease wait until the emulator is completely boot up.",
                                                        SWT.ICON_WARNING, config);
-                                       usbOnItem.setSelection(isOnUsbKbd);
-                                       usbOffItem.setSelection(!isOnUsbKbd);
+                                       usbOnItem.setSelection(isOnKbd);
+                                       usbOffItem.setSelection(!isOnKbd);
 
                                        return;
                                }
 
                                MenuItem item = (MenuItem) e.getSource();
                                if ( item.getSelection() ) {
-                                       boolean on = item.equals( usbOnItem );
-                                       isOnUsbKbd = on;
-                                       logger.info("USB keyboard " + isOnUsbKbd);
+                                       boolean on = item.equals(usbOnItem);
+                                       isOnKbd = on;
+                                       logger.info("USB keyboard " + isOnKbd);
+
+                                       communicator.sendToQEMU(
+                                                       SendCommand.USB_KBD, new BooleanData(on, SendCommand.USB_KBD.toString()));
+                               }
+
+                       }
+               };
+
+               usbOnItem.addSelectionListener(usbSelectionAdaptor);
+               usbOffItem.addSelectionListener(usbSelectionAdaptor);
+
+               usbKeyboardItem.setMenu(usbKeyBoardMenu);
+
+               /*
+               // VirtIO Keyboard Menu
+               final MenuItem hostKeyboardItem = new MenuItem(menu, SWT.CASCADE);
+               hostKeyboardItem.setText("&Host Keyboard");
+               hostKeyboardItem.setImage(imageRegistry.getIcon(IconName.HOST_KEYBOARD));
+
+               Menu hostKeyboardMenu = new Menu(shell, SWT.DROP_DOWN);
+
+               final MenuItem kbdOnItem = new MenuItem(hostKeyboardMenu, SWT.RADIO);
+               kbdOnItem.setText("On");
+               kbdOnItem.setSelection( isOnKbd );
+
+               final MenuItem kbdOffItem = new MenuItem(hostKeyboardMenu, SWT.RADIO);
+               kbdOffItem.setText("Off");
+               kbdOffItem.setSelection(!isOnKbd);
+
+               SelectionAdapter kbdSelectionAdaptor = new SelectionAdapter() {
+                       @Override
+                       public void widgetSelected(SelectionEvent e) {
+                               if (!communicator.isSensorDaemonStarted()) {
+                                       SkinUtil.openMessage(shell, null,
+                                                       "Host Keyboard is not ready.\nPlease wait until the emulator is completely boot up.",
+                                                       SWT.ICON_WARNING, config);
+                                       kbdOnItem.setSelection(isOnKbd);
+                                       kbdOffItem.setSelection(!isOnKbd);
+
+                                       return;
+                               }
+
+                               MenuItem item = (MenuItem) e.getSource();
+                               if (item.getSelection()) {
+                                       boolean on = item.equals(kbdOnItem);
+                                       isOnKbd = on;
+                                       logger.info("Host Keyboard " + isOnKbd);
 
                                        communicator.sendToQEMU(
-                                                       SendCommand.USB_KBD, new BooleanData(on, SendCommand.USB_KBD.toString()) );
+                                                       SendCommand.HOST_KBD, new BooleanData(on, SendCommand.HOST_KBD.toString()));
                                }
 
                        }
                };
 
-               usbOnItem.addSelectionListener( usbSelectionAdaptor );
-               usbOffItem.addSelectionListener( usbSelectionAdaptor );
+               kbdOnItem.addSelectionListener(kbdSelectionAdaptor);
+               kbdOffItem.addSelectionListener(kbdSelectionAdaptor);
 
-               usbKeyboardItem.setMenu( usbKeyBoardMenu );
+               hostKeyboardItem.setMenu(hostKeyboardMenu);
+               */
 
                /* Diagnosis menu */
                if (SwtUtil.isLinuxPlatform()) { //TODO: windows
index e806738..66b4c4d 100644 (file)
@@ -207,6 +207,7 @@ public interface ICommunicator extends Runnable {
                DETAIL_INFO( (short)17 ),
                RAM_DUMP( (short)18 ),
                GUEST_DUMP( (short)19 ),
+               HOST_KBD( (short)20 ),
                
                RESPONSE_HEART_BEAT( (short)900 ),
                CLOSE( (short)998 ),
index 75d058a..f855f85 100644 (file)
@@ -78,7 +78,8 @@ public class ImageRegistry {
                ADVANCED( "advanced.png" ),
                CLOSE( "close.png" ),
                SCREENSHOT( "screenshot.png" ),
-               USB_KEBOARD( "usb_keyboard.png" ),
+               USB_KEYBOARD( "usb_keyboard.png" ),
+               HOST_KEYBOARD( "host_keyboard.png" ),
                DIAGNOSIS( "diagnosis.png" ),
                ABOUT( "about.png" ),
 
index 36652e2..1ff78d6 100644 (file)
@@ -189,9 +189,11 @@ void do_key_event(int event_type, int keycode, int state_mask, int key_location)
     }
 #endif
 
+#if 0
     if (!mloop_evcmd_get_usbkbd_status()) {
         return;
     }
+#endif
 
     scancode = javakeycode_to_scancode(event_type, keycode, state_mask, key_location);
     TRACE("javakeycode_to_scancode : %d\n", scancode);
@@ -202,8 +204,10 @@ void do_key_event(int event_type, int keycode, int state_mask, int key_location)
     }
 
     if (KEY_PRESSED == event_type) {
+               INFO("key pressed: %d\n", scancode);
         kbd_put_keycode(scancode);
     } else if (KEY_RELEASED == event_type) {
+               INFO("key released: %d\n", scancode);
         kbd_put_keycode(scancode | 0x80);
     }
 }
@@ -414,13 +418,18 @@ void open_shell( void ) {
     INFO("open shell\n");
 }
 
-void onoff_usb_kbd( int on )
+void onoff_usb_kbd(int on)
 {
-    INFO( "usb kbd on/off:%d\n", on );
-    //TODO
+    INFO("usb kbd on/off:%d\n", on);
     mloop_evcmd_usbkbd(on);
 }
 
+void onoff_host_kbd(int on)
+{
+    INFO("host kbd on/off: %d.\n", on);
+    mloop_evcmd_hostkbd(on);
+}
+
 #define MAX_PATH 256
 static void dump_ram( void )
 {
index 9fada43..3197cfa 100644 (file)
@@ -71,6 +71,8 @@ void open_shell(void);
 
 void onoff_usb_kbd(int on);
 
+void onoff_host_kbd(int on);
+
 void ram_dump(void);
 
 void request_close(void);
index 3e44d78..f38a30f 100644 (file)
@@ -104,6 +104,7 @@ enum {
     RECV_DETAIL_INFO = 17,
     RECV_RAM_DUMP = 18,
     RECV_GUESTMEMORY_DUMP = 19,
+    RECV_HOST_KBD = 20,
     RECV_RESPONSE_HEART_BEAT = 900,
     RECV_CLOSE = 998,
     RECV_RESPONSE_SHUTDOWN = 999,
@@ -809,19 +810,36 @@ static void* run_skin_server( void* args ) {
                     break;
                 }
                 case RECV_USB_KBD: {
-                    log_cnt += sprintf( log_buf + log_cnt, "RECV_USB_KBD ==\n" );
-                    TRACE( log_buf );
+                    char on = 0;
 
-                    if ( 0 >= length ) {
-                        INFO( "there is no data looking at 0 length." );
+                    log_cnt += sprintf(log_buf + log_cnt, "RECV_USB_KBD ==\n");
+                    TRACE(log_buf);
+
+                    if (length <= 0) {
+                        INFO("there is no data looking at 0 length.\n");
                         continue;
                     }
 
+                    memcpy(&on, recvbuf, sizeof(on));
+                    onoff_usb_kbd(on);
+                    break;
+                }
+                case RECV_HOST_KBD: {
                     char on = 0;
-                    memcpy( &on, recvbuf, sizeof( on ) );
-                    onoff_usb_kbd( on );
+
+                    log_cnt += sprintf(log_buf + log_cnt, "RECV_HOST_KBD ==\n");
+                    TRACE(log_buf);
+
+                    if (length <= 0) {
+                        INFO("there is no data looking at 0 length.\n");
+                        continue;
+                    }
+
+                    memcpy(&on, recvbuf, sizeof(on));
+                                       onoff_host_kbd(on);
                     break;
                 }
+
                 case RECV_CLOSE: {
                     log_cnt += sprintf( log_buf + log_cnt, "RECV_CLOSE ==\n" );
                     TRACE( log_buf );