From: Kitae Kim Date: Fri, 26 Oct 2012 07:01:03 +0000 (+0900) Subject: virtio-keyboard: add virtio-keyboard device. X-Git-Tag: Tizen_Studio_1.3_Release_p2.3.1~1410 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=af07aba3e0339340d0fbaaf0fcfda63098265cdb;p=sdk%2Femulator%2Fqemu.git virtio-keyboard: add virtio-keyboard device. 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 --- diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c index 12f61fea6e..f7d8d6f1b2 100644 --- a/hw/pci-hotplug.c +++ b/hw/pci-hotplug.c @@ -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); } diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index 8645eddcb4..b14a77ddd7 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -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 ad57eb4699..c3bb673db9 100644 --- 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) diff --git a/tizen/src/Makefile.tizen b/tizen/src/Makefile.tizen index d4596c91d7..f898cd08bf 100755 --- a/tizen/src/Makefile.tizen +++ b/tizen/src/Makefile.tizen @@ -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 diff --git a/tizen/src/hw/maru_device_ids.h b/tizen/src/hw/maru_device_ids.h index 9d61c6e3e0..0049917684 100644 --- a/tizen/src/hw/maru_device_ids.h +++ b/tizen/src/hw/maru_device_ids.h @@ -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 index 0000000000..28ba0d9c66 --- /dev/null +++ b/tizen/src/hw/maru_virtio_keyboard.c @@ -0,0 +1,143 @@ +/* + * Virtio Keyboard Device + * + * Copyright (c) 2011 - 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: + * Kitae Kim + * SeokYeon Hwang + * YeongKyoon Lee + * + * 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 index 0000000000..0e4196e8f2 --- /dev/null +++ b/tizen/src/hw/maru_virtio_keyboard.h @@ -0,0 +1,50 @@ +/* + * Virtio Keyboard Device + * + * Copyright (c) 2011 - 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: + * Kitae Kim + * SeokYeon Hwang + * YeongKyoon Lee + * + * 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_ */ diff --git a/tizen/src/hw/maru_virtio_touchscreen.c b/tizen/src/hw/maru_virtio_touchscreen.c index 42b11df7e0..e7b1f4e16f 100644 --- a/tizen/src/hw/maru_virtio_touchscreen.c +++ b/tizen/src/hw/maru_virtio_touchscreen.c @@ -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; diff --git a/tizen/src/mloop_event.c b/tizen/src/mloop_event.c index aadb33a97b..ee17346d2d 100644 --- a/tizen/src/mloop_event.c +++ b/tizen/src/mloop_event.c @@ -41,8 +41,11 @@ #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); +} diff --git a/tizen/src/mloop_event.h b/tizen/src/mloop_event.h index 7fb8434110..d7f69549c7 100644 --- a/tizen/src/mloop_event.h +++ b/tizen/src/mloop_event.h @@ -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 index 0000000000..69a87f3207 Binary files /dev/null and b/tizen/src/skin/client/resource/icons/host_keyboard.png differ diff --git a/tizen/src/skin/client/src/org/tizen/emulator/skin/EmulatorSkin.java b/tizen/src/skin/client/src/org/tizen/emulator/skin/EmulatorSkin.java index 6eaaa75b05..3c4accac57 100644 --- a/tizen/src/skin/client/src/org/tizen/emulator/skin/EmulatorSkin.java +++ b/tizen/src/skin/client/src/org/tizen/emulator/skin/EmulatorSkin.java @@ -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 diff --git a/tizen/src/skin/client/src/org/tizen/emulator/skin/comm/ICommunicator.java b/tizen/src/skin/client/src/org/tizen/emulator/skin/comm/ICommunicator.java index e806738f68..66b4c4da7a 100644 --- a/tizen/src/skin/client/src/org/tizen/emulator/skin/comm/ICommunicator.java +++ b/tizen/src/skin/client/src/org/tizen/emulator/skin/comm/ICommunicator.java @@ -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 ), diff --git a/tizen/src/skin/client/src/org/tizen/emulator/skin/image/ImageRegistry.java b/tizen/src/skin/client/src/org/tizen/emulator/skin/image/ImageRegistry.java index 75d058aa1a..f855f857b4 100644 --- a/tizen/src/skin/client/src/org/tizen/emulator/skin/image/ImageRegistry.java +++ b/tizen/src/skin/client/src/org/tizen/emulator/skin/image/ImageRegistry.java @@ -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" ), diff --git a/tizen/src/skin/maruskin_operation.c b/tizen/src/skin/maruskin_operation.c index 36652e260f..1ff78d6432 100644 --- a/tizen/src/skin/maruskin_operation.c +++ b/tizen/src/skin/maruskin_operation.c @@ -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 ) { diff --git a/tizen/src/skin/maruskin_operation.h b/tizen/src/skin/maruskin_operation.h index 9fada43239..3197cfa923 100644 --- a/tizen/src/skin/maruskin_operation.h +++ b/tizen/src/skin/maruskin_operation.h @@ -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); diff --git a/tizen/src/skin/maruskin_server.c b/tizen/src/skin/maruskin_server.c index 3e44d7881e..f38a30f7c1 100644 --- a/tizen/src/skin/maruskin_server.c +++ b/tizen/src/skin/maruskin_server.c @@ -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 );